merge with master

Signed-off-by: Micaela Verucchi <micaelaverucchi@gmail.com>
This commit is contained in:
Micaela Verucchi
2021-07-20 18:38:46 +02:00
68 changed files with 5577 additions and 276 deletions
+6
View File
@@ -12,5 +12,11 @@ build/
*.hdf5 *.hdf5
*.pk *.pk
*.table *.table
cmake-build-release/
demo/COCO_val2017 demo/COCO_val2017
demo/BDD100K_val demo/BDD100K_val
/.vs
cmake-build-minsizerel/*
scripts/COCO_val2017/*
scripts/COCO_val2017.zip
scripts/all_labels.txt
+38 -6
View File
@@ -1,8 +1,15 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.15)
project (tkDNN) project (tkDNN)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -Wno-deprecated-declarations -Wno-unused-variable") if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -Wno-deprecated-declarations -Wno-unused-variable ")
endif()
if(WIN32)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "/O2 /FS /EHsc")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif(WIN32)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/tkDNN) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/tkDNN)
# project specific flags # project specific flags
@@ -10,7 +17,13 @@ if(DEBUG)
add_definitions(-DDEBUG) add_definitions(-DDEBUG)
endif() endif()
add_definitions(-DTKDNN_PATH="${CMAKE_CURRENT_SOURCE_DIR}") if(TKDNN_PATH)
message("SET TKDNN_PATH:"${TKDNN_PATH})
add_definitions(-DTKDNN_PATH="${TKDNN_PATH}")
else()
add_definitions(-DTKDNN_PATH="${CMAKE_CURRENT_SOURCE_DIR}")
endif()
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# CUDA # CUDA
@@ -28,19 +41,21 @@ include_directories(${CUDNN_INCLUDE_DIR})
file(GLOB tkdnn_CUSRC "src/kernels/*.cu" "src/sorting.cu") file(GLOB tkdnn_CUSRC "src/kernels/*.cu" "src/sorting.cu")
cuda_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${CUDNN_INCLUDE_DIRS}) cuda_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${CUDNN_INCLUDE_DIRS})
cuda_add_library(kernels SHARED ${tkdnn_CUSRC}) cuda_add_library(kernels SHARED ${tkdnn_CUSRC})
target_link_libraries(kernels ${CUDA_CUBLAS_LIBRARIES})
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# External Libraries # External Libraries
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
find_package(Eigen3 REQUIRED) find_package(Eigen3 REQUIRED)
message("Eigen DIR: " ${EIGEN3_INCLUDE_DIR})
include_directories(${EIGEN3_INCLUDE_DIR}) include_directories(${EIGEN3_INCLUDE_DIR})
find_package(OpenCV REQUIRED) find_package(OpenCV REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV")
# gives problems in cross-compiling, probably malformed cmake config # gives problems in cross-compiling, probably malformed cmake config
#find_package(yaml-cpp REQUIRED) find_package(yaml-cpp REQUIRED)
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Build Libraries # Build Libraries
@@ -48,7 +63,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV")
file(GLOB tkdnn_SRC "src/*.cpp") file(GLOB tkdnn_SRC "src/*.cpp")
set(tkdnn_LIBS kernels ${CUDA_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES} ${CUDNN_LIBRARIES} ${OpenCV_LIBS} yaml-cpp) set(tkdnn_LIBS kernels ${CUDA_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES} ${CUDNN_LIBRARIES} ${OpenCV_LIBS} yaml-cpp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${OPENCV_INCLUDE_DIRS} ${NVINFER_INCLUDES}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${OPENCV_INCLUDE_DIRS} ${NVINFER_INCLUDES})
add_library(tkDNN SHARED ${tkdnn_SRC}) add_library(tkDNN SHARED ${tkdnn_SRC})
target_link_libraries(tkDNN ${tkdnn_LIBS}) target_link_libraries(tkDNN ${tkdnn_LIBS})
@@ -77,6 +92,7 @@ foreach(test_SRC ${darknet_SRC})
set(test_NAME test_${test_NAME}) set(test_NAME test_${test_NAME})
add_executable(${test_NAME} ${test_SRC}) add_executable(${test_NAME} ${test_SRC})
target_link_libraries(${test_NAME} tkDNN) target_link_libraries(${test_NAME} tkDNN)
install(TARGETS ${test_NAME} DESTINATION bin)
endforeach() endforeach()
# MOBILENET # MOBILENET
@@ -103,6 +119,16 @@ target_link_libraries(test_resnet101_cnet tkDNN)
add_executable(test_dla34_cnet tests/centernet/dla34_cnet/dla34_cnet.cpp) add_executable(test_dla34_cnet tests/centernet/dla34_cnet/dla34_cnet.cpp)
target_link_libraries(test_dla34_cnet tkDNN) target_link_libraries(test_dla34_cnet tkDNN)
# SHELFNET
add_executable(test_shelfnet tests/shelfnet/shelfnet.cpp)
target_link_libraries(test_shelfnet tkDNN)
add_executable(test_shelfnet_berkeley tests/shelfnet/shelfnet_berkeley.cpp)
target_link_libraries(test_shelfnet_berkeley tkDNN)
add_executable(test_shelfnet_mapillary tests/shelfnet/shelfnet_mapillary.cpp)
target_link_libraries(test_shelfnet_mapillary tkDNN)
# DEMOS # DEMOS
add_executable(test_rtinference tests/test_rtinference/rtinference.cpp) add_executable(test_rtinference tests/test_rtinference/rtinference.cpp)
target_link_libraries(test_rtinference tkDNN) target_link_libraries(test_rtinference tkDNN)
@@ -113,6 +139,9 @@ target_link_libraries(map_demo tkDNN)
add_executable(demo demo/demo/demo.cpp) add_executable(demo demo/demo/demo.cpp)
target_link_libraries(demo tkDNN) target_link_libraries(demo tkDNN)
add_executable(seg_demo demo/demo/seg_demo.cpp)
target_link_libraries(seg_demo tkDNN)
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Install # Install
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@@ -123,7 +152,10 @@ target_link_libraries(demo tkDNN)
message("install dir:" ${CMAKE_INSTALL_PREFIX}) message("install dir:" ${CMAKE_INSTALL_PREFIX})
install(DIRECTORY include/ DESTINATION include/) install(DIRECTORY include/ DESTINATION include/)
install(TARGETS tkDNN kernels DESTINATION lib) install(TARGETS tkDNN kernels DESTINATION lib)
install(TARGETS test_simple test_mnist test_mnistRT test_rtinference demo map_demo DESTINATION bin)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" # source directory install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" # source directory
DESTINATION "share/tkDNN/cmake/" # target directory DESTINATION "share/tkDNN/cmake/" # target directory
) )
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests/" # source directory
DESTINATION "share/tkDNN/tests" # target directory
)
+1
View File
@@ -0,0 +1 @@
1)error C2131 @ Yolo3Detection.cpp(97) -> expression doesnt evaluate to a constant caused to read of variable outside its lifetime
+151 -33
View File
@@ -3,42 +3,54 @@ tkDNN is a Deep Neural Network library built with cuDNN and tensorRT primitives,
The main goal of this project is to exploit NVIDIA boards as much as possible to obtain the best inference performance. It does not allow training. The main goal of this project is to exploit NVIDIA boards as much as possible to obtain the best inference performance. It does not allow training.
If you use tkDNN in your research, please cite one of the following papers. For use in commercial solutions, write at gattifrancesco@hotmail.it and micaela.verucchi@unimore.it or refer to https://hipert.unimore.it/ . If you use tkDNN in your research, please cite the [following paper](https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=9212130&casa_token=sQTJXi7tJNoAAAAA:BguH9xCIY48MxbtDS3LXzIXzO-9sWArm7Hd7y7BwaLmqRuM_Gx8bOYizFPNMNtpo5K0kB-P-). For use in commercial solutions, write at gattifrancesco@hotmail.it and micaela.verucchi@unimore.it or refer to https://hipert.unimore.it/ .
``` ```
Accepted paper @ IRC 2020, will soon be published. @inproceedings{verucchi2020systematic,
M. Verucchi, L. Bartoli, F. Bagni, F. Gatti, P. Burgio and M. Bertogna, "Real-Time clustering and LiDAR-camera fusion on embedded platforms for self-driving cars", in proceedings in IEEE Robotic Computing (2020) title={A Systematic Assessment of Embedded Neural Networks for Object Detection},
author={Verucchi, Micaela and Brilli, Gianluca and Sapienza, Davide and Verasani, Mattia and Arena, Marco and Gatti, Francesco and Capotondi, Alessandro and Cavicchioli, Roberto and Bertogna, Marko and Solieri, Marco},
Accepted paper @ ETFA 2020, will soon be published. booktitle={2020 25th IEEE International Conference on Emerging Technologies and Factory Automation (ETFA)},
M. Verucchi, G. Brilli, D. Sapienza, M. Verasani, M. Arena, F. Gatti, A. Capotondi, R. Cavicchioli, M. Bertogna, M. Solieri volume={1},
"A Systematic Assessment of Embedded Neural Networks for Object Detection", in IEEE International Conference on Emerging Technologies and Factory Automation (2020) pages={937--944},
year={2020},
organization={IEEE}
}
``` ```
### What's new (20 July 2021)
- [x] Support to sematic segmentation [README](docs/README_seg.md)
- [ ] Support to TensorRT8 (WIP)
## FPS Results ## FPS Results
Inference FPS of yolov4 with tkDNN, average of 1200 images with the same dimension as the input size, on Inference FPS of yolov4 with tkDNN, average of 1200 images with the same dimension as the input size, on
* RTX 2080Ti (CUDA 10.2, TensorRT 7.0.0, Cudnn 7.6.5); * RTX 2080Ti (CUDA 10.2, TensorRT 7.0.0, Cudnn 7.6.5);
* Xavier AGX, Jetpack 4.3 (CUDA 10.0, CUDNN 7.6.3, tensorrt 6.0.1 ); * Xavier AGX, Jetpack 4.3 (CUDA 10.0, CUDNN 7.6.3, tensorrt 6.0.1 );
* Xavier NX, Jetpack 4.4 (CUDA 10.2, CUDNN 8.0.0, tensorrt 7.1.0 ).
* Tx2, Jetpack 4.2 (CUDA 10.0, CUDNN 7.3.1, tensorrt 5.0.6 ); * Tx2, Jetpack 4.2 (CUDA 10.0, CUDNN 7.3.1, tensorrt 5.0.6 );
* Jetson Nano, Jetpack 4.4 (CUDA 10.2, CUDNN 8.0.0, tensorrt 7.1.0 ). * Jetson Nano, Jetpack 4.4 (CUDA 10.2, CUDNN 8.0.0, tensorrt 7.1.0 ).
| Platform | Network | FP32, B=1 | FP32, B=4 | FP16, B=1 | FP16, B=4 | INT8, B=1 | INT8, B=4 | | Platform | Network | FP32, B=1 | FP32, B=4 | FP16, B=1 | FP16, B=4 | INT8, B=1 | INT8, B=4 |
| :------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | | :------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: |
| RTX 2080Ti | yolo4 320 | 118,59 |237,31 | 207,81 | 443,32 | 262,37 | 530,93 | | RTX 2080Ti | yolo4 320 | 118.59 | 237.31 | 207.81 | 443.32 | 262.37 | 530.93 |
| RTX 2080Ti | yolo4 416 | 104,81 |162,86 | 169,06 | 293,78 | 206,93 | 353,26 | | RTX 2080Ti | yolo4 416 | 104.81 | 162.86 | 169.06 | 293.78 | 206.93 | 353.26 |
| RTX 2080Ti | yolo4 512 | 92,98 |132,43 | 140,36 | 215,17 | 165,35 | 254,96 | | RTX 2080Ti | yolo4 512 | 92.98 | 132.43 | 140.36 | 215.17 | 165.35 | 254.96 |
| RTX 2080Ti | yolo4 608 | 63,77 |81,53 | 111,39 | 152,89 | 127,79 | 184,72 | | RTX 2080Ti | yolo4 608 | 63.77 | 81.53 | 111.39 | 152.89 | 127.79 | 184.72 |
| AGX Xavier | yolo4 320 | 26,78 |32,05 | 57,14 | 79,05 | 73,15 | 97,56 | | AGX Xavier | yolo4 320 | 26.78 | 32.05 | 57.14 | 79.05 | 73.15 | 97.56 |
| AGX Xavier | yolo4 416 | 19,96 |21,52 | 41,01 | 49,00 | 50,81 | 60,61 | | AGX Xavier | yolo4 416 | 19.96 | 21.52 | 41.01 | 49.00 | 50.81 | 60.61 |
| AGX Xavier | yolo4 512 | 16,58 |16,98 | 31,12 | 33,84 | 37,82 | 41,28 | | AGX Xavier | yolo4 512 | 16.58 | 16.98 | 31.12 | 33.84 | 37.82 | 41.28 |
| AGX Xavier | yolo4 608 | 9,45 |10,13 | 21,92 | 23,36 | 27,05 | 28,93 | | AGX Xavier | yolo4 608 | 9.45 | 10.13 | 21.92 | 23.36 | 27.05 | 28.93 |
| Tx2 | yolo4 320 | 11,18 | 12,07 | 15,32 | 16,31 | - | - | | Xavier NX | yolo4 320 | 14.56 | 16.25 | 30.14 | 41.15 | 42.13 | 53.42 |
| Tx2 | yolo4 416 | 7,30 | 7,58 | 9,45 | 9,90 | - | - | | Xavier NX | yolo4 416 | 10.02 | 10.60 | 22.43 | 25.59 | 29.08 | 32.94 |
| Tx2 | yolo4 512 | 5,96 | 5,95 | 7,22 | 7,23 | - | - | | Xavier NX | yolo4 512 | 8.10 | 8.32 | 15.78 | 17.13 | 20.51 | 22.46 |
| Tx2 | yolo4 608 | 3,63 | 3,65 | 4,67 | 4,70 | - | - | | Xavier NX | yolo4 608 | 5.26 | 5.18 | 11.54 | 12.06 | 15.09 | 15.82 |
| Nano | yolo4 320 | 4,23 | 4,55 | 6,14 | 6,53 | - | - | | Tx2 | yolo4 320 | 11.18 | 12.07 | 15.32 | 16.31 | - | - |
| Nano | yolo4 416 | 2,88 | 3,00 | 3,90 | 4,04 | - | - | | Tx2 | yolo4 416 | 7.30 | 7.58 | 9.45 | 9.90 | - | - |
| Nano | yolo4 512 | 2,32 | 2,34 | 3,02 | 3,04 | - | - | | Tx2 | yolo4 512 | 5.96 | 5.95 | 7.22 | 7.23 | - | - |
| Nano | yolo4 608 | 1,40 | 1,41 | 1,92 | 1,93 | - | - | | Tx2 | yolo4 608 | 3.63 | 3.65 | 4.67 | 4.70 | - | - |
| Nano | yolo4 320 | 4.23 | 4.55 | 6.14 | 6.53 | - | - |
| Nano | yolo4 416 | 2.88 | 3.00 | 3.90 | 4.04 | - | - |
| Nano | yolo4 512 | 2.32 | 2.34 | 3.02 | 3.04 | - | - |
| Nano | yolo4 608 | 1.40 | 1.41 | 1.92 | 1.93 | - | - |
## MAP Results ## MAP Results
Results for COCO val 2017 (5k images), on RTX 2080Ti, with conf threshold=0.001 Results for COCO val 2017 (5k images), on RTX 2080Ti, with conf threshold=0.001
@@ -72,17 +84,30 @@ Results for COCO val 2017 (5k images), on RTX 2080Ti, with conf threshold=0.001
- [mAP demo](#map-demo) - [mAP demo](#map-demo)
- [Existing tests and supported networks](#existing-tests-and-supported-networks) - [Existing tests and supported networks](#existing-tests-and-supported-networks)
- [References](#references) - [References](#references)
- [tkDNN on Windows 10 (experimental)](#tkdnn-on-windows-10-experimental)
- [Dependencies-Windows](#dependencies-windows)
- [Compiling tkDNN on Windows](#compiling-tkdnn-on-windows)
- [Run the demo on Windows](#run-the-demo-on-windows)
- [FP16 inference windows](#fp16-inference-windows)
- [INT8 inference windows](#int8-inference-windows)
- [Known issues with tkDNN on Windows](#known-issues-with-tkdnn-on-windows)
## Dependencies ## Dependencies
This branch works on every NVIDIA GPU that supports the dependencies: This branch works on every NVIDIA GPU that supports the following (latest tested) dependencies:
* CUDA 10.0 * CUDA 11.0 (or >= 10)
* CUDNN 7.603 * cuDNN 8.0.4 (or >= 7.3)
* TENSORRT 6.01 * TensorRT 7.2.0 (or >=5)
* OPENCV 3.4 * OpenCV 4.5.2 (or >=4)
* yaml-cpp 0.5.2 (sudo apt install libyaml-cpp-dev) * cmake 3.21 (or >= 3.15)
* yaml-cpp 0.5.2
* eigen3 3.3.4
* curl 7.58
```
sudo apt install libyaml-cpp-dev curl libeigen3-dev
```
## About OpenCV ## About OpenCV
To compile and install OpenCV4 with contrib us the script ```install_OpenCV4.sh```. It will download and compile OpenCV in Download folder. To compile and install OpenCV4 with contrib us the script ```install_OpenCV4.sh```. It will download and compile OpenCV in Download folder.
@@ -187,6 +212,7 @@ All models from darknet are now parsed directly from cfg, you still need to expo
relu relu
leaky leaky
mish mish
logistic
</details> </details>
## Run the demo ## Run the demo
@@ -209,7 +235,7 @@ Once you have successfully created your rt file, run the demo:
``` ```
In general the demo program takes 7 parameters: In general the demo program takes 7 parameters:
``` ```
./demo <network-rt-file> <path-to-video> <kind-of-network> <number-of-classes> <n-batches> <show-flag> ./demo <network-rt-file> <path-to-video> <kind-of-network> <number-of-classes> <n-batches> <show-flag> <conf-thresh>
``` ```
where where
* ```<network-rt-file>``` is the rt file generated by a test * ```<network-rt-file>``` is the rt file generated by a test
@@ -344,7 +370,97 @@ This demo also creates a json file named ```net_name_COCO_res.json``` containing
| csresnext50-panet-spp | Cross Stage Partial Network <sup>7</sup> | [COCO 2014](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/Kcs4xBozwY4wFx8/download) | | csresnext50-panet-spp | Cross Stage Partial Network <sup>7</sup> | [COCO 2014](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/Kcs4xBozwY4wFx8/download) |
| yolo4 | Yolov4 <sup>8</sup> | [COCO 2017](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/d97CFzYqCPCp5Hg/download) | | yolo4 | Yolov4 <sup>8</sup> | [COCO 2017](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/d97CFzYqCPCp5Hg/download) |
| yolo4_berkeley | Yolov4 <sup>8</sup> | [BDD100K ](https://bair.berkeley.edu/blog/2018/05/30/bdd/) | 10 | 540x320 | [weights](https://cloud.hipert.unimore.it/s/nkWFa5fgb4NTdnB/download) | | yolo4_berkeley | Yolov4 <sup>8</sup> | [BDD100K ](https://bair.berkeley.edu/blog/2018/05/30/bdd/) | 10 | 540x320 | [weights](https://cloud.hipert.unimore.it/s/nkWFa5fgb4NTdnB/download) |
| yolo4tiny | Yolov4 tiny | [COCO 2017](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/iRnc4pSqmx78gJs/download) | | yolo4tiny | Yolov4 tiny <sup>9</sup> | [COCO 2017](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/iRnc4pSqmx78gJs/download) |
| yolo4x | Yolov4x-mish <sup>9</sup> | [COCO 2017](http://cocodataset.org/) | 80 | 640x640 | [weights](https://cloud.hipert.unimore.it/s/5MFjtNtgbDGdJEo/download) |
| yolo4x-cps | Scaled Yolov4 <sup>10</sup> | [COCO 2017](http://cocodataset.org/) | 80 | 512x512 | [weights](https://cloud.hipert.unimore.it/s/AfzHE4BfTeEm2gH/download) |
### tkDNN on Windows 10 (experimental)
### Dependencies-Windows
This branch should work on every NVIDIA GPU supported in windows with the following dependencies:
* WINDOWS 10 1803 or HIGHER
* CUDA 10.0 (Recommended CUDA 11.2 )
* CUDNN 7.6 (Recommended CUDNN 8.1.1 )
* TENSORRT 6.0.1 (Recommended TENSORRT 7.2.3.4 )
* OPENCV 3.4 (Recommended OPENCV 4.2.0 )
* MSVC 16.7
* YAML-CPP
* EIGEN3
* 7ZIP (ADD TO PATH)
* NINJA 1.10
All the above mentioned dependencies except 7ZIP can be installed using Microsoft's [VCPKG](https://github.com/microsoft/vcpkg.git) .
After bootstrapping VCPKG the dependencies can be built and installed using the following command :
```
opencv4(normal) - vcpkg.exe install opencv4[tbb,jpeg,tiff,opengl,openmp,png,ffmpeg,eigen]:x64-windows yaml-cpp:x64-windows eigen3:x64-windows --x-install-root=C:\opt --x-buildtrees-root=C:\temp_vcpkg_build
opencv4(cuda) - vcpkg.exe install opencv4[cuda,nonfree,contrib,eigen,tbb,jpeg,tiff,opengl,openmp,png,ffmpeg]:x64-windows yaml-cpp:x64-windows eigen3:x64-windows --x-install-root=C:\opt --x-buildtrees-root=C:\temp_vcpkg_build
```
To build opencv4 with cuda and cudnn version corresponding to your cuda version,vcpkg's cudnn portfile needs to be modified by adding ```$ENV{CUDA_PATH}``` at lines 16 and 17 in the portfile.cmake
After VCPKG finishes building and installing all the packages delete C:\temp_vcpkg_build and add C:\opt\x64-windows\bin and C:\opt\x64-windows\debug\bin to path
### Compiling tkDNN on Windows
tkDNN is built with cmake(3.15+) on windows along with ninja.Msbuild and NMake Makefiles are drastically slower when compiling the library compared to windows
```
git clone https://github.com/ceccocats/tkDNN.git
cd tkdnn-windows
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -G"Ninja" ..
ninja -j4
```
### Run the demo on Windows
This example uses yolo4_tiny.\
To run the object detection file create .rt file bu running:
```
.\test_yolo4tiny.exe
```
Once the rt file has been successfully create,run the demo using the following command:
```
.\demo.exe yolo4tiny_fp32.rt ..\demo\yolo_test.mp4 y
```
For general info on more demo paramters,check Run the demo section on top
To run the test_all_tests.sh on windows,use git bash or msys2
### FP16 inference windows
This is an untested feature on windows.To run the object detection demo with FP16 interference follow the below steps(example with yolo4tiny):
```
set TKDNN_MODE=FP16
del /f yolo4tiny_fp16.rt
.\test_yolo4tiny.exe
.\demo.exe yolo4tiny_fp16.rt ..\demo\yolo_test.mp4
```
### INT8 inference windows
To run object detection demo with INT8 (example with yolo4tiny):
```
set TKDNN_MODE=INT8
set TKDNN_CALIB_LABEL_PATH=..\demo\COCO_val2017\all_labels.txt
set TKDNN_CALIB_IMG_PATH=..\demo\COCO_val2017\all_images.txt
del /f yolo4tiny_int8.rt # be sure to delete(or move) old tensorRT files
.\test_yolo4tiny.exe # run the yolo test (is slow)
.\demo.exe yolo4tiny_int8.rt ..\demo\yolo_test.mp4 y
```
### Known issues with tkDNN on Windows
Mobilenet and Centernet demos work properly only when built with msvc 16.7 in Release Mode,when built in debug mode for the mentioned networks one might encounter opencv assert errors
All Darknet models work properly with demo using MSVC version(16.7-16.9)
It is recommended to use Nvidia Driver(465+),Cuda unknown errors have been observed when using older drivers on pascal(SM 61) devices.
## References ## References
@@ -357,3 +473,5 @@ This demo also creates a json file named ```net_name_COCO_res.json``` containing
6. He, Kaiming, et al. "Deep residual learning for image recognition." Proceedings of the IEEE conference on computer vision and pattern recognition. 2016. 6. He, Kaiming, et al. "Deep residual learning for image recognition." Proceedings of the IEEE conference on computer vision and pattern recognition. 2016.
7. Wang, Chien-Yao, et al. "CSPNet: A New Backbone that can Enhance Learning Capability of CNN." arXiv preprint arXiv:1911.11929 (2019). 7. Wang, Chien-Yao, et al. "CSPNet: A New Backbone that can Enhance Learning Capability of CNN." arXiv preprint arXiv:1911.11929 (2019).
8. Bochkovskiy, Alexey, Chien-Yao Wang, and Hong-Yuan Mark Liao. "YOLOv4: Optimal Speed and Accuracy of Object Detection." arXiv preprint arXiv:2004.10934 (2020). 8. Bochkovskiy, Alexey, Chien-Yao Wang, and Hong-Yuan Mark Liao. "YOLOv4: Optimal Speed and Accuracy of Object Detection." arXiv preprint arXiv:2004.10934 (2020).
9. Bochkovskiy, Alexey, "Yolo v4, v3 and v2 for Windows and Linux" (https://github.com/AlexeyAB/darknet)
10. Wang, Chien-Yao, Alexey Bochkovskiy, and Hong-Yuan Mark Liao. "Scaled-YOLOv4: Scaling Cross Stage Partial Network." arXiv preprint arXiv:2011.08036 (2020).
+9 -4
View File
@@ -1,7 +1,7 @@
#include <iostream> #include <iostream>
#include <signal.h> #include <signal.h>
#include <stdlib.h> /* srand, rand */ #include <stdlib.h> /* srand, rand */
#include <unistd.h> //#include <unistd.h>
#include <mutex> #include <mutex>
#include "CenternetDetection.h" #include "CenternetDetection.h"
@@ -22,10 +22,15 @@ int main(int argc, char *argv[]) {
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
std::string net = "yolo3_berkeley.rt"; std::string net = "yolo4tiny_fp32.rt";
if(argc > 1) if(argc > 1)
net = argv[1]; net = argv[1];
std::string input = "../demo/yolo_test.mp4"; #ifdef __linux__
std::string input = "../demo/yolo_test.mp4";
#elif _WIN32
std::string input = "..\\..\\..\\demo\\yolo_test.mp4";
#endif
if(argc > 2) if(argc > 2)
input = argv[2]; input = argv[2];
char ntype = 'y'; char ntype = 'y';
@@ -131,7 +136,7 @@ int main(int argc, char *argv[]) {
double mean = 0; double mean = 0;
std::cout<<COL_GREENB<<"\n\nTime stats:\n"; std::cout<<COL_GREENB<<"\n\nTime stats:\n";
std::cout<<"Min: "<<*std::min_element(detNN->stats.begin(), detNN->stats.end())/n_batch<<" ms\n"; std::cout<<"Min: "<<*std::min_element(detNN->stats.begin(), detNN->stats.end())/n_batch<<" ms\n";
std::cout<<"Max: "<<*std::max_element(detNN->stats.begin(), detNN->stats.end())/n_batch<<" ms\n"; std::cout<<"Max: "<<*std::max_element(detNN->stats.begin(), detNN->stats.end())/n_batch<<" ms\n";
for(int i=0; i<detNN->stats.size(); i++) mean += detNN->stats[i]; mean /= detNN->stats.size(); for(int i=0; i<detNN->stats.size(); i++) mean += detNN->stats[i]; mean /= detNN->stats.size();
std::cout<<"Avg: "<<mean/n_batch<<" ms\t"<<1000/(mean/n_batch)<<" FPS\n"<<COL_END; std::cout<<"Avg: "<<mean/n_batch<<" ms\t"<<1000/(mean/n_batch)<<" FPS\n"<<COL_END;
+3
View File
@@ -2,7 +2,10 @@
#include <iostream> #include <iostream>
#include <signal.h> #include <signal.h>
#include <stdlib.h> /* srand, rand */ #include <stdlib.h> /* srand, rand */
#ifdef __linux__
#include <unistd.h> #include <unistd.h>
#endif
#include <mutex> #include <mutex>
#include "utils.h" #include "utils.h"
+148
View File
@@ -0,0 +1,148 @@
#include <iostream>
#include <signal.h>
#include <stdlib.h> /* srand, rand */
#include <unistd.h>
#include <mutex>
#include "SegmentationNN.h"
bool gRun;
bool SAVE_RESULT = true;
void sig_handler(int signo) {
std::cout<<"request gateway stop\n";
gRun = false;
}
void writePred(const std::string& images_names, const std::string& gt_folder, const std::string& out_folder, tk::dnn::SegmentationNN& segNN, int& width, int& height, bool show=false){
std::ifstream all_gt(images_names);
std::string filename;
cv::Mat frame;
for (; std::getline(all_gt, filename); ) {
std::cout<<filename<<std::endl;
frame = cv::imread(gt_folder + filename);
height = frame.rows;
width = frame.cols;
segNN.updateOriginal(frame, false);
if(show)
segNN.draw();
cv::imwrite(out_folder + filename, segNN.segmented[0]);
}
}
int main(int argc, char *argv[]) {
std::cout<<"detection\n";
signal(SIGINT, sig_handler);
std::string net = "shelfnet_fp32.rt";
if(argc > 1)
net = argv[1];
std::string input = "../demo/yolo_test.mp4";
if(argc > 2)
input = argv[2];
int n_batch = 1;
if(argc > 3)
n_batch = atoi(argv[3]);
int n_classes = 19;
if(argc > 4)
n_classes = atoi(argv[4]);
bool resize = false;
if(argc > 5)
resize = atoi(argv[5]);
int baseline_resize = 1024;
if(argc > 6)
baseline_resize = atoi(argv[6]);
bool show = true;
if(argc > 7)
show = atoi(argv[7]);
bool write_pred = false;
if(argc > 8)
write_pred = atoi(argv[8]);
if(resize && (baseline_resize < 0 || baseline_resize > 5000))
FatalError("Problem with baseline resize")
if(n_batch < 1 || n_batch > 64)
FatalError("Batch dim not supported");
//net initialization
tk::dnn::SegmentationNN segNN;
segNN.init(net, n_classes, n_batch);
int height = 0, width = 0;
int basewidth=baseline_resize, hsize;
if(write_pred){
std::string gt_folder = "../demo/CityScapes_val/images/";
std::string images_names = "../demo/CityScapes_val/all_images.txt";
std::string out_folder = "seg/";
writePred(images_names, gt_folder, out_folder, segNN, width, height, show);
}
else{
if(!show)
SAVE_RESULT = true;
gRun = true;
cv::VideoCapture cap(input);
if(!cap.isOpened())
gRun = false;
else
std::cout<<"camera started\n";
cv::VideoWriter resultVideo;
if(SAVE_RESULT) {
int w,h;
if(resize){
w = basewidth;
h = int((float(cap.get(cv::CAP_PROP_FRAME_HEIGHT))*float(basewidth/float(cap.get(cv::CAP_PROP_FRAME_WIDTH)))));
}
else{
w = cap.get(cv::CAP_PROP_FRAME_WIDTH);
h = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
}
resultVideo.open("result.mp4", cv::VideoWriter::fourcc('M','P','4','V'), 30, cv::Size(w, h));
}
cv::Mat frame;
while(gRun) {
cap >> frame;
if(!frame.data)
break;
if(resize){
hsize = int((float(frame.rows)*float(basewidth/float(frame.cols))));
cv::resize(frame, frame, cv::Size(basewidth, hsize));
}
height = frame.rows;
width = frame.cols;
//inference
segNN.updateOriginal(frame, true);
if(show)
segNN.draw();
if(SAVE_RESULT)
resultVideo << segNN.segmented[0];
}
}
std::cout<<"segmentation end\n";
double mean = 0, mean_pre = 0, mean_post = 0;
std::cout<<COL_GREENB<<"\n\nTime stats for size ["<<width<<","<<height<<"] :\n";
for(int i=0; i<segNN.stats.size(); i++) mean += segNN.stats[i]; mean /= segNN.stats.size();
for(int i=0; i<segNN.stats_pre.size(); i++) mean_pre += segNN.stats_pre[i]; mean_pre /= segNN.stats_pre.size();
for(int i=0; i<segNN.stats_post.size(); i++) mean_post += segNN.stats_post[i]; mean_post /= segNN.stats_post.size();
std::cout<<"Avg pre:\t"<<mean_pre<<" ms\t"<<1000/(mean_pre)<<" FPS\n";
std::cout<<"Avg inf:\t"<<mean<<" ms\t"<<1000/(mean)<<" FPS\n";
std::cout<<"Avg post:\t"<<mean_post<<" ms\t"<<1000/(mean_post)<<" FPS\n\n";
std::cout<<"Avg tot:\t"<<(mean_pre + mean_post + mean) <<" ms\t"<<1000/((mean_pre + mean_post + mean))<<" FPS\n"<<COL_END;
return 0;
}
+89
View File
@@ -0,0 +1,89 @@
# Semantic Segmentation with tkDNN
Currently tkDNN supports only ShelfNet as semantic segmentation network.
## Export weights from Shelfnet
To get the weights needed to run Shelfnet tests use [this](https://git.hipert.unimore.it/mverucchi/shelfnet) fork of a Pytorch implementation of Shelfnet network.
```
git clone https://git.hipert.unimore.it/mverucchi/shelfnet
cd shelfnet
cd ShelfNet18_realtime
conda env create --file shelfnet_env.yml
conda activate shelfnet
mkdir layer debug
python export.py
```
## Run the demo
To run the semantic segmentation demo follow these steps (example with shelfnet):
```
rm shelfnet_fp32.rt # be sure to delete(or move) old tensorRT files
export TKDNN_BATCHSIZE=4 # be sure you have batch size > than 1 if you want to run inference on images bigger than 1024
./test_shelfnet # run the yolo test (is slow)
./demo shelfnet_fp32.rt ../demo/yolo_test.mp4 1 19
```
In general the demo program takes the following parameters:
```
./seg_demo <network-rt-file> <path-to-video> <n-batches> <number-of-classes> <resize-flag> <baseline-resize> <show-flag> <write-pred>
```
where
* ```<network-rt-file>``` is the rt file generated by a test
* ```<<path-to-video>``` is the path to a video file or a camera input
* ```<n-batches>``` number of batches to use in inference (N.B. you should first export TKDNN_BATCHSIZE to the required n_batches and create again the rt file for the network).
* ```<number-of-classes>```is the number of classes the network is trained on
* ```<resize-flag>``` if set to 0 the demo will not resize the input frames, but use it as it is, otherwise it will resize it.
* ```<baseline-resize>``` is ```<resize-flag>``` is set to 1, then the input frames will be proportionally resized using ```<baseline-resize>``` as width baseline.
* ```<show-flag>``` if set to 0 the demo will not show the visualization but save the video into result.mp4 (if n-batches ==1)
* ```<write-pred>``` if set to 0 (default) the demo will run, otherwise the evaluation of a dataset will run and the output of the segmentation will be saved. Attention: this is under development and paths are embedded, so change them in the code in advance.
NB) By default it is used FP32 inference
NB) The batching is not used to work on more streams, rather to work on more tiles of the same image. Shelfnet never resized the input image, therefore for images greater than 1024x1024 tiles of 1024x1024 are given in input to the network in batch.
![gif](output.gif "Results on yolo_test.mp4")
For other demo videos refer to [this playlist](https://www.youtube.com/playlist?list=PLv0nEQYDD45y5EdSiywwCGPBmJVUzIWwe).
## Existing tests and supported networks
| Test Name | Network | Dataset | N Classes | Input size | Weights |
| :---------------- | :-------------------------------------------- | :-----------------------------------------------------------: | :-------: | :-----------: | :------------------------------------------------------------------------ |
| shelfnet | ShelfNet18_realtime<sup>1</sup> | [Cityscapes](https://www.cityscapes-dataset.com/) | 19 | 1024x1024 | [weights](https://cloud.hipert.unimore.it/s/mEDZMRJaGCFWSJF/download) |
| shelfnet_berkeley | ShelfNet18_realtime<sup>1</sup> | [DeepDrive](https://bdd-data.berkeley.edu/) | 20 | 1024x1024 | [weights](https://cloud.hipert.unimore.it/s/m92e7QdD9gYMF7f/download) |
1. Zhuang, Juntang, et al. "ShelfNet for fast semantic segmentation." Proceedings of the IEEE International Conference on Computer Vision Workshops. 2019.
## FPS Results
Inference FPS of shelfnet with tkDNN, average of 1200 images on:
* RTX 2080Ti (CUDA 10.2, TensorRT 7.0.0, Cudnn 7.6.5);
* Xavier AGX, Jetpack 4.3 (CUDA 10.0, CUDNN 7.6.3, tensorrt 6.0.1 );
| Platform | Test | Phase | FP32, ms | FP32, FPS | FP16, ms | FP16, FPS | INT8, ms | INT8, FPS |
| :------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: |
| RTX 2080Ti | shelfnet 1024x1024 (B=1) | pre | 6.11863 | 163.435 | 5.81465 | 171.979 | 5.88699 | 169.866 |
| RTX 2080Ti | shelfnet 1024x1024 (B=1) | inf | 11.5464 | 86.6074 | 7.35396 | 135.981 | 6.37623 | 156.832 |
| RTX 2080Ti | shelfnet 1024x1024 (B=1) | post | 4.09058 | 244.464 | 3.91961 | 255.128 | 4.07343 | 245.493 |
| RTX 2080Ti | shelfnet 1024x1024 (B=1) | tot | 21.7556 | 45.9652 | 17.0882 | 58.5199 | 16.3366 | 61.2121 |
| RTX 2080Ti | shelfnet 2048x2048 (B=4) | pre | 25.435 | 39.3158 | 25.2953 | 39.5331 | 25.9303 | 38.565 |
| RTX 2080Ti | shelfnet 2048x2048 (B=4) | inf | 36.5015 | 27.3961 | 17.0534 | 58.6395 | 15.6061 | 64.0773 |
| RTX 2080Ti | shelfnet 2048x2048 (B=4) | post | 17.3917 | 57.4985 | 17.1649 | 58.2583 | 17.5539 | 56.9675 |
| RTX 2080Ti | shelfnet 2048x2048 (B=4) | tot | 79.3283 | 12.6058 | 59.5136 | 16.8029 | 59.0903 | 16.9233 |
| AGX Xavier | shelfnet 1024x1024 (B=1) | pre | 8.0174 | 124.729 | 7.5117 | 133.126 | 7.47333 | 133.809 |
| AGX Xavier | shelfnet 1024x1024 (B=1) | inf | 72.4173 | 13.8089 | 37.505 | 26.6631 | 31.3286 | 31.9197 |
| AGX Xavier | shelfnet 1024x1024 (B=1) | post | 8.89958 | 112.365 | 8.83576 | 113.176 | 9.42655 | 106.083 |
| AGX Xavier | shelfnet 1024x1024 (B=1) | tot | 89.3342 | 11.1939 | 53.8525 | 18.5692 | 48.2285 | 20.7346 |
| AGX Xavier | shelfnet 2048x2048 (B=4) | pre | 47.1454 | 21.211 | 21.6475 | 46.1947 | 21.4201 | 46.6851 |
| AGX Xavier | shelfnet 2048x2048 (B=4) | inf | 266.537 | 3.75183 | 128.321 | 7.79293 | 107.621 | 9.29185 |
| AGX Xavier | shelfnet 2048x2048 (B=4) | post | 44.0711 | 22.6906 | 40.1732 | 24.8922 | 39.873 | 25.0796 |
| AGX Xavier | shelfnet 2048x2048 (B=4) | tot | 357.753 | 2.79522 | 190.142 | 5.25922 | 168.914 | 5.92016 |
## Known issues
When creating the rt file all the checks returns errors. It is due to a different resize function and handling of the original ShelfNet outputs.
However, the network is supposed to work.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 MiB

+3
View File
@@ -24,7 +24,10 @@ namespace tk { namespace dnn {
int num = 1; int num = 1;
int pad = 0; int pad = 0;
int coords = 4; int coords = 4;
int nms_kind = 0;
int new_coords= 0;
float scale_xy = 1; float scale_xy = 1;
float nms_thresh = 0.45;
std::vector<int> layers; std::vector<int> layers;
std::string activation = "linear"; std::string activation = "linear";
+4 -2
View File
@@ -4,7 +4,10 @@
#include <iostream> #include <iostream>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef __linux__
#include <unistd.h> #include <unistd.h>
#endif
#include <mutex> #include <mutex>
#include "utils.h" #include "utils.h"
@@ -14,7 +17,7 @@
#include "tkdnn.h" #include "tkdnn.h"
// #define OPENCV_CUDACONTRIB //if OPENCV has been compiled with CUDA and contrib. //#define OPENCV_CUDACONTRIB //if OPENCV has been compiled with CUDA and contrib.
#ifdef OPENCV_CUDACONTRIB #ifdef OPENCV_CUDACONTRIB
#include <opencv2/cudawarping.hpp> #include <opencv2/cudawarping.hpp>
@@ -150,7 +153,6 @@ class DetectionNN {
int x0, w, x1, y0, h, y1; int x0, w, x1, y0, h, y1;
int objClass; int objClass;
std::string det_class; std::string det_class;
int baseline = 0; int baseline = 0;
float font_scale = 0.5; float font_scale = 0.5;
int thickness = 2; int thickness = 2;
+7
View File
@@ -1,7 +1,14 @@
#include <iostream> #include <iostream>
#include <signal.h> #include <signal.h>
#include <stdlib.h> /* srand, rand */ #include <stdlib.h> /* srand, rand */
#ifdef __linux__
#include <unistd.h> #include <unistd.h>
#elif _WIN32
#define _USE_MATH_DEFINES
#include <math.h>
#endif
#include <mutex> #include <mutex>
#include <Eigen/Dense> #include <Eigen/Dense>
#include "utils.h" #include "utils.h"
+3
View File
@@ -12,7 +12,10 @@
#include <iomanip> #include <iomanip>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef __linux__
#include <unistd.h> #include <unistd.h>
#endif
#include <mutex> #include <mutex>
#include "NvInfer.h" #include "NvInfer.h"
+38 -8
View File
@@ -19,8 +19,10 @@ enum layerType_t {
LAYER_ACTIVATION_CRELU, LAYER_ACTIVATION_CRELU,
LAYER_ACTIVATION_LEAKY, LAYER_ACTIVATION_LEAKY,
LAYER_ACTIVATION_MISH, LAYER_ACTIVATION_MISH,
LAYER_ACTIVATION_LOGISTIC,
LAYER_FLATTEN, LAYER_FLATTEN,
LAYER_RESHAPE, LAYER_RESHAPE,
LAYER_RESIZE,
LAYER_MULADD, LAYER_MULADD,
LAYER_POOLING, LAYER_POOLING,
LAYER_SOFTMAX, LAYER_SOFTMAX,
@@ -72,8 +74,10 @@ public:
case LAYER_ACTIVATION_CRELU: return "ActivationCReLU"; case LAYER_ACTIVATION_CRELU: return "ActivationCReLU";
case LAYER_ACTIVATION_LEAKY: return "ActivationLeaky"; case LAYER_ACTIVATION_LEAKY: return "ActivationLeaky";
case LAYER_ACTIVATION_MISH: return "ActivationMish"; case LAYER_ACTIVATION_MISH: return "ActivationMish";
case LAYER_ACTIVATION_LOGISTIC: return "ActivationLogistic";
case LAYER_FLATTEN: return "Flatten"; case LAYER_FLATTEN: return "Flatten";
case LAYER_RESHAPE: return "Reshape"; case LAYER_RESHAPE: return "Reshape";
case LAYER_RESIZE: return "Resize";
case LAYER_MULADD: return "MulAdd"; case LAYER_MULADD: return "MulAdd";
case LAYER_POOLING: return "Pooling"; case LAYER_POOLING: return "Pooling";
case LAYER_SOFTMAX: return "Softmax"; case LAYER_SOFTMAX: return "Softmax";
@@ -216,7 +220,8 @@ public:
typedef enum { typedef enum {
ACTIVATION_ELU = 100, ACTIVATION_ELU = 100,
ACTIVATION_LEAKY = 101, ACTIVATION_LEAKY = 101,
ACTIVATION_MISH = 102 ACTIVATION_MISH = 102,
ACTIVATION_LOGISTIC = 103
} tkdnnActivationMode_t; } tkdnnActivationMode_t;
/** /**
@@ -227,8 +232,9 @@ class Activation : public Layer {
public: public:
int act_mode; int act_mode;
float ceiling; float ceiling;
float slope;
Activation(Network *net, int act_mode, const float ceiling=0.0); Activation(Network *net, int act_mode, const float ceiling=0.0, const float slope=0.1);
virtual ~Activation(); virtual ~Activation();
virtual layerType_t getLayerType() { virtual layerType_t getLayerType() {
if(act_mode == CUDNN_ACTIVATION_CLIPPED_RELU) if(act_mode == CUDNN_ACTIVATION_CLIPPED_RELU)
@@ -237,6 +243,8 @@ public:
return LAYER_ACTIVATION_LEAKY; return LAYER_ACTIVATION_LEAKY;
else if (act_mode == ACTIVATION_MISH) else if (act_mode == ACTIVATION_MISH)
return LAYER_ACTIVATION_MISH; return LAYER_ACTIVATION_MISH;
else if (act_mode == ACTIVATION_LOGISTIC)
return LAYER_ACTIVATION_LOGISTIC;
else else
return LAYER_ACTIVATION; return LAYER_ACTIVATION;
}; };
@@ -431,6 +439,23 @@ public:
}; };
enum ResizeMode_t { NEAREST= 0,
LINEAR= 1};
/**
Resize layer
*/
class Resize : public Layer {
public:
Resize(Network *net, int scale_c, int scale_h, int scale_w, bool fixed=false, ResizeMode_t mode=NEAREST);
virtual ~Resize();
virtual layerType_t getLayerType() { return LAYER_RESIZE; };
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
ResizeMode_t mode;
};
/** /**
MulAdd layer MulAdd layer
@@ -551,7 +576,7 @@ public:
class Shortcut : public Layer { class Shortcut : public Layer {
public: public:
Shortcut(Network *net, Layer *backLayer); Shortcut(Network *net, Layer *backLayer, bool mul=false);
virtual ~Shortcut(); virtual ~Shortcut();
virtual layerType_t getLayerType() { return LAYER_SHORTCUT; }; virtual layerType_t getLayerType() { return LAYER_SHORTCUT; };
@@ -559,6 +584,7 @@ public:
public: public:
Layer *backLayer; Layer *backLayer;
bool mul = false;
}; };
/** /**
@@ -614,24 +640,28 @@ public:
int sort_class; int sort_class;
}; };
Yolo(Network *net, int classes, int num, std::string fname_weights,int n_masks=3, float scale_xy=1); enum nmsKind_t {GREEDY_NMS=0, DIOU_NMS=1};
Yolo(Network *net, int classes, int num, std::string fname_weights,int n_masks=3, float scale_xy=1, double nms_thresh=0.45, nmsKind_t nsm_kind=GREEDY_NMS, int new_coords=0);
virtual ~Yolo(); virtual ~Yolo();
virtual layerType_t getLayerType() { return LAYER_YOLO; }; virtual layerType_t getLayerType() { return LAYER_YOLO; };
int classes, num, n_masks; int classes, num, n_masks, new_coords;
dnnType *mask_h, *mask_d; //anchors dnnType *mask_h, *mask_d; //anchors
dnnType *bias_h, *bias_d; //anchors dnnType *bias_h, *bias_d; //anchors
float scaleXY; float scaleXY;
double nms_thresh;
nmsKind_t nsm_kind;
std::vector<std::string> classesNames; std::vector<std::string> classesNames;
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
int computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh); int computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh, int new_coords=0);
dnnType *predictions; dnnType *predictions;
static const int MAX_DETECTIONS = 8192; static const int MAX_DETECTIONS = 8192*2;
static Yolo::detection *allocateDetections(int nboxes, int classes); static Yolo::detection *allocateDetections(int nboxes, int classes);
static void mergeDetections(Yolo::detection *dets, int ndets, int classes); static void mergeDetections(Yolo::detection *dets, int ndets, int classes, double nms_thresh=0.45, nmsKind_t nsm_kind=GREEDY_NMS);
}; };
/** /**
+7
View File
@@ -6,6 +6,7 @@
#include "Network.h" #include "Network.h"
#include "Layer.h" #include "Layer.h"
#include "NvInfer.h" #include "NvInfer.h"
#include <memory>
namespace tk { namespace dnn { namespace tk { namespace dnn {
@@ -24,6 +25,7 @@ template<typename T> T readBUF(const char*& buffer)
using namespace nvinfer1; using namespace nvinfer1;
#include "pluginsRT/ActivationLeakyRT.h" #include "pluginsRT/ActivationLeakyRT.h"
#include "pluginsRT/ActivationLogisticRT.h"
#include "pluginsRT/ActivationReLUCeilingRT.h" #include "pluginsRT/ActivationReLUCeilingRT.h"
#include "pluginsRT/ActivationMishRT.h" #include "pluginsRT/ActivationMishRT.h"
#include "pluginsRT/ReorgRT.h" #include "pluginsRT/ReorgRT.h"
@@ -59,6 +61,7 @@ public:
#if NV_TENSORRT_MAJOR >= 6 #if NV_TENSORRT_MAJOR >= 6
nvinfer1::IBuilderConfig *configRT; nvinfer1::IBuilderConfig *configRT;
#endif #endif
nvinfer1::ICudaEngine *engineRT; nvinfer1::ICudaEngine *engineRT;
nvinfer1::IExecutionContext *contextRT; nvinfer1::IExecutionContext *contextRT;
@@ -105,6 +108,7 @@ public:
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Route *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Route *l);
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Flatten *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Flatten *l);
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Reshape *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Reshape *l);
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Resize *l);
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Reorg *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Reorg *l);
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Region *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Region *l);
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Shortcut *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Shortcut *l);
@@ -114,6 +118,9 @@ public:
bool serialize(const char *filename); bool serialize(const char *filename);
bool deserialize(const char *filename); bool deserialize(const char *filename);
}; };
}} }}
+2 -2
View File
@@ -5,8 +5,8 @@
namespace tk { namespace dnn { namespace tk { namespace dnn {
cv::Mat vizFloat2colorMap(cv::Mat map); cv::Mat vizFloat2colorMap(cv::Mat map, double min=0, double max=0, int classes=19);
cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int imgdim); cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int img_h, int img_w, double min=0, double max=0, int classes=19);
cv::Mat vizLayer2Mat(tk::dnn::Network *net, int layer, int imgdim = 1000); cv::Mat vizLayer2Mat(tk::dnn::Network *net, int layer, int imgdim = 1000);
}} }}
+403
View File
@@ -0,0 +1,403 @@
#ifndef SEGMENTATIONNN_H
#define SEGMENTATIONNN_H
#include <iostream>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <mutex>
#include "utils.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/hal/interface.h>
#include "tkdnn.h"
#include "NetworkViz.h"
#include "kernelsThrust.h"
namespace tk { namespace dnn {
class SegmentationNN {
protected:
tk::dnn::NetworkRT *netRT = nullptr;
int nBatches = 1;
std::vector<cv::Size> originalSize;
cv::Mat bgr[3];
dnnType *input;
dnnType *input_d;
float* confidences_h;
float * tmpInputData_d;
float *tmpOutData_d;
float *tmpOutData_h;
float *mean_d, *stddev_d;
cublasHandle_t cublasHandle;
void computeBorders(const int or_width, const int or_height, int& top, int& bottom, int& left, int&right){
top = 0;
bottom = 0;
left = 0;
right = 0;
if(or_height != or_width){
if(or_height < or_width){
top = (or_width - or_height)/2;
bottom = or_width - top - or_height;
}
else{
left = (or_height - or_width)/2;
right = or_height - left - or_width;
}
}
}
/**
* This method preprocess the image, before feeding it to the NN.
*
* @param frame original frame to adapt for inference.
* @param bi batch index
*/
void preprocess(cv::Mat &frame, const int bi=0) {
originalSize[bi] = frame.size();
frame.convertTo(frame, CV_32FC3, 1 / 255.0, 0);
int H = frame.rows;
int W = frame.cols;
cv::Mat frame_cropped;
int top, bottom, left, right;
computeBorders(W, H, top, bottom, left, right);
cv::copyMakeBorder(frame, frame_cropped, top, bottom, left, right, cv::BORDER_CONSTANT, cv::Scalar(0,0,0) );
tk::dnn::dataDim_t idim = netRT->input_dim;
resize(frame_cropped, frame_cropped, cv::Size(idim.w, idim.h));
cv::split(frame_cropped, bgr);
for (int i = 0; i < idim.c; i++){
int idx = i * frame_cropped.rows * frame_cropped.cols;
int ch = idim.c-1 -i;
memcpy((void *)&input[idx + idim.tot()*bi], (void *)bgr[ch].data, frame_cropped.rows * frame_cropped.cols * sizeof(dnnType));
}
checkCuda(cudaMemcpyAsync(input_d+ idim.tot()*bi, input + idim.tot()*bi, idim.tot() * sizeof(dnnType), cudaMemcpyHostToDevice, netRT->stream));
normalize(input_d + idim.tot()*bi, idim.c, idim.h, idim.w, mean_d, stddev_d);
}
/**
* This method postprocess the output of the NN to obtain the correct
* boundig boxes.
*
* @param bi batch index
*/
void postprocess(const int bi=0, bool appy_colormap = true) {
dnnType *rt_out = (dnnType *)netRT->buffersRT[1]+ netRT->buffersDIM[1].tot()*bi;
dataDim_t odim = netRT->output_dim;
matrixTranspose(cublasHandle, rt_out, tmpInputData_d, odim.c, odim.w*odim.h);
maxElem(tmpInputData_d, tmpOutData_d, odim.c, odim.h, odim.w);
checkCuda(cudaMemcpy(tmpOutData_h, tmpOutData_d, odim.w*odim.h * sizeof(float), cudaMemcpyDeviceToHost));
dataDim_t vdim = odim;
vdim.c = 1;
cv::Mat colored;
if(appy_colormap)
colored = vizData2Mat(tmpOutData_h, vdim, netRT->input_dim.h, netRT->input_dim.w, 0, classes, classes);
else{
cv::Mat colored_fp32 (cv::Size(odim.w, odim.h),CV_32FC1, tmpOutData_h);
colored_fp32.convertTo(colored, CV_8UC1);
}
int max_dim = (originalSize[bi].width > originalSize[bi].height) ? originalSize[bi].width : originalSize[bi].height;
resize(colored, colored, cv::Size(max_dim, max_dim));
int top, bottom, left, right;
computeBorders(originalSize[bi].width, originalSize[bi].height, top, bottom, left, right);
cv::Rect roi(left,top,originalSize[bi].width, originalSize[bi].height);
cv::Mat or_size (colored, roi);
segmented[bi] = or_size;
};
public:
int classes = 0;
std::vector<double> stats; /*keeps track of inference times (ms)*/
std::vector<double> stats_pre;
std::vector<double> stats_post;
std::vector<std::string> classesNames;
std::vector<cv::Mat> segmented;
SegmentationNN() {
checkERROR( cublasCreate(&cublasHandle) );
};
~SegmentationNN(){
checkERROR( cublasDestroy(cublasHandle) );
};
/**
* Method used to inialize the class, allocate memory and compute
* needed data.
*
* @param tensor_path path to the rt file og the NN.
* @param n_classes number of classes for the given dataset.
* @param n_batches maximum number of batches to use in inference
* @return true if everything is correct, false otherwise.
*/
bool init(const std::string& tensor_path, const int n_classes=19, const int n_batches=1){
std::cout<<(tensor_path).c_str()<<"\n";
if(!fileExist(tensor_path.c_str()))
FatalError("This file do not exists" + tensor_path );
netRT = new tk::dnn::NetworkRT(NULL, (tensor_path).c_str());
classes = n_classes;
nBatches = n_batches;
checkCuda(cudaMallocHost(&input, sizeof(dnnType) * netRT->input_dim.tot() * nBatches));
checkCuda(cudaMalloc(&input_d, sizeof(dnnType) * netRT->input_dim.tot() * nBatches));
dataDim_t odim = netRT->output_dim;
checkCuda(cudaMallocHost(&confidences_h, sizeof(float) * odim.tot()));
checkCuda(cudaMalloc(&tmpInputData_d, sizeof(float) * odim.tot()));
checkCuda(cudaMalloc(&tmpOutData_d, sizeof(float) * odim.w*odim.h));
checkCuda(cudaMallocHost(&tmpOutData_h, sizeof(float) * odim.w*odim.h));
segmented.resize(nBatches);
originalSize.resize(nBatches);
std::vector<float> mean = {0.485, 0.456, 0.406};
std::vector<float> stddev = {0.229, 0.224, 0.225};
checkCuda(cudaMalloc(&mean_d, sizeof(float) * mean.size()));
checkCuda(cudaMalloc(&stddev_d, sizeof(float) * stddev.size()));
checkCuda(cudaMemcpyAsync(mean_d, mean.data(), mean.size() * sizeof(float), cudaMemcpyHostToDevice, netRT->stream));
checkCuda(cudaMemcpyAsync(stddev_d, stddev.data(), stddev.size() * sizeof(float), cudaMemcpyHostToDevice, netRT->stream));
}
/**
* This method performs the whole detection of the NN.
*
* @param frames frames to run detection on.
* @param cur_batches number of batches to use in inference
* @param save_times if set to true, preprocess, inference and postprocess times
* are saved on a csv file, otherwise not.
* @param times pointer to the output stream where to write times
* @param mAP set to true only if all the probabilities for a bounding
* box are needed, as in some cases for the mAP calculation
*/
void update(std::vector<cv::Mat>& frames, const int cur_batches=1, bool apply_colormap=true){
if(cur_batches > nBatches)
FatalError("A batch size greater than nBatches cannot be used");
originalSize.clear();
if(TKDNN_VERBOSE) printCenteredTitle(" TENSORRT detection ", '=', 30);
{
TKDNN_TSTART
for(int bi=0; bi<cur_batches;++bi){
if(!frames[bi].data)
FatalError("No image data feed to detection");
originalSize.push_back(frames[bi].size());
preprocess(frames[bi], bi);
}
TKDNN_TSTOP
stats_pre.push_back(t_ns);
}
//do inference
tk::dnn::dataDim_t dim = netRT->input_dim;
dim.n = cur_batches;
{
if(TKDNN_VERBOSE) dim.print();
TKDNN_TSTART
netRT->infer(dim, input_d);
TKDNN_TSTOP
if(TKDNN_VERBOSE) dim.print();
stats.push_back(t_ns);
}
{
TKDNN_TSTART
for(int bi=0; bi<cur_batches;++bi)
postprocess(bi, apply_colormap);
TKDNN_TSTOP
stats_post.push_back(t_ns);
}
}
void updateOriginal(cv::Mat frame, bool apply_colormap=true){
std::vector<cv::Mat> splitted_frames;
int H, W, net_H, net_W;
int top = 0, bottom = 0, left = 0, right = 0;
std::vector<std::pair<int,int>> pos;
{
TKDNN_TSTART
cv::Size original_size = frame.size();
frame.convertTo(frame, CV_32FC3, 1 / 255.0, 0);
H = frame.rows;
W = frame.cols;
net_H = netRT->input_dim.h;
net_W = netRT->input_dim.w;
cv::Mat frame_cropped;
if( H <= net_H && W <= net_W ){ // smaller size wrt network
top = (net_H - H)/2;
bottom = net_H - H - top ;
left = (net_W - W)/2;
right = net_W - W - left ;
cv::copyMakeBorder(frame, frame_cropped, top, bottom, left, right, cv::BORDER_CONSTANT, cv::Scalar(0,0,0) );
splitted_frames.push_back(frame_cropped);
}
else{ //bigger size wrt network
if(H < net_H || W < net_W){
if(H < net_H){
top = (net_H - H)/2;
bottom = net_H - H - top ;
}
else{
left = (net_W - W)/2;
right = net_W - W - left ;
}
cv::copyMakeBorder(frame, frame_cropped, top, bottom, left, right, cv::BORDER_CONSTANT, cv::Scalar(0,0,0));
}
for(int x=0; x+net_W<=W ;){
for(int y=0; y+net_H <=H ; ){
cv::Rect roi(x, y, net_W, net_H);
cv::Mat image_roi = frame(roi);
splitted_frames.push_back(image_roi);
pos.push_back(std::make_pair(x,y));
y += net_H;
if(y == H)
break;
if(y + net_H > H) y = H - net_H;
}
x += net_W;
if(x == W)
break;
if(x + net_W > W) x = W - net_W;
}
}
tk::dnn::dataDim_t idim = netRT->input_dim;
if(splitted_frames.size()> nBatches)
FatalError(std::to_string(splitted_frames.size()) + " min batches required");
for(int bi=0; bi<splitted_frames.size();++bi){
cv::split(splitted_frames[bi], bgr);
for (int i = 0; i < idim.c; i++){
int idx = i * splitted_frames[bi].rows * splitted_frames[bi].cols;
int ch = idim.c-1 -i;
memcpy((void *)&input[idx + idim.tot()*bi], (void *)bgr[ch].data, splitted_frames[bi].rows * splitted_frames[bi].cols * sizeof(dnnType));
}
checkCuda(cudaMemcpyAsync(input_d+ idim.tot()*bi, input + idim.tot()*bi, idim.tot() * sizeof(dnnType), cudaMemcpyHostToDevice, netRT->stream));
normalize(input_d + idim.tot()*bi, idim.c, idim.h, idim.w, mean_d, stddev_d);
}
TKDNN_TSTOP
stats_pre.push_back(t_ns);
}
tk::dnn::dataDim_t dim = netRT->input_dim;
dim.n = splitted_frames.size();
{
if(TKDNN_VERBOSE) dim.print();
TKDNN_TSTART
netRT->infer(dim, input_d);
TKDNN_TSTOP
if(TKDNN_VERBOSE) dim.print();
stats.push_back(t_ns);
}
dataDim_t odim = netRT->output_dim;
std::vector<cv::Mat> out_img;
{
TKDNN_TSTART
for(int bi=0; bi<splitted_frames.size();++bi){
dnnType *rt_out = (dnnType *)netRT->buffersRT[1]+ netRT->buffersDIM[1].tot()*bi;
matrixTranspose(cublasHandle, rt_out, tmpInputData_d, odim.c, odim.w*odim.h);
maxElem(tmpInputData_d, tmpOutData_d, odim.c, odim.h, odim.w);
checkCuda(cudaMemcpy(tmpOutData_h, tmpOutData_d, odim.w*odim.h * sizeof(float), cudaMemcpyDeviceToHost));
dataDim_t vdim = odim;
vdim.c = 1;
cv::Mat colored;
if(apply_colormap)
colored = vizData2Mat(tmpOutData_h, vdim, netRT->input_dim.h, netRT->input_dim.w, 0, classes, classes);
else{
cv::Mat colored_fp32 (cv::Size(odim.w, odim.h),CV_32FC1, tmpOutData_h);
colored_fp32.convertTo(colored, CV_8UC1);
}
out_img.push_back(colored);
}
cv::Mat seg(frame.size(), out_img[0].type());
if(out_img.size() == 1)
{
cv::Rect roi(left, top, W, H);
seg = out_img[0](roi);
}
else{
int bi=0;
if(top == 0 && left == 0){
for(int i=0; i<out_img.size(); ++i){
cv::Mat roi_collage = seg(cv::Rect( pos[i].first ,pos[i].second,out_img[i].cols,out_img[i].rows));
out_img[i].copyTo(roi_collage);
}
}
else{
FatalError("Not handled case")
}
}
segmented[0] = seg;
TKDNN_TSTOP
stats_post.push_back(t_ns);
}
}
/**
* Method to draw boundixg boxes and labels on a frame.
*/
cv::Mat draw(const int cur_batches=1) {
for(int i=0; i<cur_batches; ++i){
cv::imshow("segmented", segmented[i]);
cv::resizeWindow("segmented", cv::Size(512,288));
cv::waitKey(1);
}
return segmented[0];
}
};
}}
#endif /* SEGMENTATIONNN_H*/
+2 -2
View File
@@ -4,7 +4,7 @@
#include "utils.h" #include "utils.h"
void activationELUForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0)); void activationELUForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0));
void activationLEAKYForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0)); void activationLEAKYForward(dnnType *srcData, dnnType *dstData, int size, float slope, cudaStream_t stream = cudaStream_t(0));
void activationReLUCeilingForward(dnnType *srcData, dnnType *dstData, int size, const float ceiling, cudaStream_t stream = cudaStream_t(0)); void activationReLUCeilingForward(dnnType *srcData, dnnType *dstData, int size, const float ceiling, cudaStream_t stream = cudaStream_t(0));
void activationLOGISTICForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0)); void activationLOGISTICForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0));
void activationSIGMOIDForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0)); void activationSIGMOIDForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0));
@@ -24,7 +24,7 @@ void softmaxForward(float *input, int n, int batch, int batch_offset,
int groups, int group_offset, int stride, float temp, float *output, cudaStream_t stream = cudaStream_t(0)); int groups, int group_offset, int stride, float temp, float *output, cudaStream_t stream = cudaStream_t(0));
void shortcutForward(dnnType *srcData, dnnType *dstData, int n1, int c1, int h1, int w1, int s1, void shortcutForward(dnnType *srcData, dnnType *dstData, int n1, int c1, int h1, int w1, int s1,
int n2, int c2, int h2, int w2, int s2, int n2, int c2, int h2, int w2, int s2, bool mul,
cudaStream_t stream = cudaStream_t(0)); cudaStream_t stream = cudaStream_t(0));
void upsampleForward(dnnType *srcData, dnnType *dstData, void upsampleForward(dnnType *srcData, dnnType *dstData,
+5
View File
@@ -2,6 +2,7 @@
#define KERNELSTHRUST_H #define KERNELSTHRUST_H
#include <thrust/extrema.h>
#include <thrust/sort.h> #include <thrust/sort.h>
#include <thrust/execution_policy.h> #include <thrust/execution_policy.h>
#include <thrust/functional.h> #include <thrust/functional.h>
@@ -9,6 +10,8 @@
#include <thrust/iterator/constant_iterator.h> #include <thrust/iterator/constant_iterator.h>
#include <thrust/gather.h> #include <thrust/gather.h>
#include <thrust/copy.h> #include <thrust/copy.h>
#include <thrust/device_ptr.h>
#include "tkdnn.h" #include "tkdnn.h"
@@ -36,4 +39,6 @@ void topKxyAddOffset(int * ids_begin, const int K, const int size, int *intxs_be
void bboxes(int * ids_begin, const int K, const int size, float *xs_begin, float *ys_begin, void bboxes(int * ids_begin, const int K, const int size, float *xs_begin, float *ys_begin,
dnnType *src_begin, float *bbx0, float *bbx1, float *bby0, float *bby1, float *src_out, int *ids_out); dnnType *src_begin, float *bbx0, float *bbx1, float *bby0, float *bby1, float *src_out, int *ids_out);
void maxElem(dnnType *src_begin, dnnType *dst_begin, const int c, const int h, const int w);
#endif //KERNELSTHRUST_H #endif //KERNELSTHRUST_H
+7 -6
View File
@@ -4,9 +4,8 @@
class ActivationLeakyRT : public IPlugin { class ActivationLeakyRT : public IPlugin {
public: public:
ActivationLeakyRT() { ActivationLeakyRT(float s) {
slope = s;
} }
~ActivationLeakyRT(){ ~ActivationLeakyRT(){
@@ -42,19 +41,21 @@ public:
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override { virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
activationLEAKYForward((dnnType*)reinterpret_cast<const dnnType*>(inputs[0]), activationLEAKYForward((dnnType*)reinterpret_cast<const dnnType*>(inputs[0]),
reinterpret_cast<dnnType*>(outputs[0]), batchSize*size, stream); reinterpret_cast<dnnType*>(outputs[0]), batchSize*size, slope, stream);
return 0; return 0;
} }
virtual size_t getSerializationSize() override { virtual size_t getSerializationSize() override {
return 1*sizeof(int); return 1*sizeof(int) + 1*sizeof(float);
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, size); tk::dnn::writeBUF(buf, size);
assert(buf == a + getSerializationSize());
} }
int size; int size;
float slope;
}; };
@@ -0,0 +1,60 @@
#include<cassert>
#include "../kernels.h"
class ActivationLogisticRT : public IPlugin {
public:
ActivationLogisticRT() {
}
~ActivationLogisticRT(){
}
int getNbOutputs() const override {
return 1;
}
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
return inputs[0];
}
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
size = 1;
for(int i=0; i<outputDims[0].nbDims; i++)
size *= outputDims[0].d[i];
}
int initialize() override {
return 0;
}
virtual void terminate() override {
}
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
return 0;
}
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
activationLOGISTICForward((dnnType*)reinterpret_cast<const dnnType*>(inputs[0]),
reinterpret_cast<dnnType*>(outputs[0]), batchSize*size, stream);
return 0;
}
virtual size_t getSerializationSize() override {
return 1*sizeof(int);
}
virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer);
tk::dnn::writeBUF(buf, size);
}
int size;
};
+2 -1
View File
@@ -52,8 +52,9 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, size); tk::dnn::writeBUF(buf, size);
assert(buf == a + getSerializationSize());
} }
int size; int size;
@@ -51,9 +51,10 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, ceiling); tk::dnn::writeBUF(buf, ceiling);
tk::dnn::writeBUF(buf, size); tk::dnn::writeBUF(buf, size);
assert(buf = a + getSerializationSize());
} }
@@ -52,8 +52,9 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, size); tk::dnn::writeBUF(buf, size);
assert(buf == a + getSerializationSize());
} }
int size; int size;
+2 -1
View File
@@ -116,7 +116,7 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, chunk_dim); tk::dnn::writeBUF(buf, chunk_dim);
tk::dnn::writeBUF(buf, kh); tk::dnn::writeBUF(buf, kh);
tk::dnn::writeBUF(buf, kw); tk::dnn::writeBUF(buf, kw);
@@ -163,6 +163,7 @@ public:
for(int i=0; i<dim_ones; i++) for(int i=0; i<dim_ones; i++)
tk::dnn::writeBUF(buf, aus[i]); tk::dnn::writeBUF(buf, aus[i]);
free(aus); free(aus);
assert(buf == a + getSerializationSize());
} }
cublasStatus_t stat; cublasStatus_t stat;
+2 -1
View File
@@ -65,12 +65,13 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a = buf;
tk::dnn::writeBUF(buf, c); tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h); tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w); tk::dnn::writeBUF(buf, w);
tk::dnn::writeBUF(buf, rows); tk::dnn::writeBUF(buf, rows);
tk::dnn::writeBUF(buf, cols); tk::dnn::writeBUF(buf, cols);
assert(buf == a + getSerializationSize());
} }
int c, h, w; int c, h, w;
@@ -55,7 +55,7 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, this->c); tk::dnn::writeBUF(buf, this->c);
tk::dnn::writeBUF(buf, this->h); tk::dnn::writeBUF(buf, this->h);
@@ -65,6 +65,7 @@ public:
tk::dnn::writeBUF(buf, this->stride_W); tk::dnn::writeBUF(buf, this->stride_W);
tk::dnn::writeBUF(buf, this->winSize); tk::dnn::writeBUF(buf, this->winSize);
tk::dnn::writeBUF(buf, this->padding); tk::dnn::writeBUF(buf, this->padding);
assert(buf == a + getSerializationSize());
} }
int n, c, h, w; int n, c, h, w;
+2 -1
View File
@@ -73,13 +73,14 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, classes); tk::dnn::writeBUF(buf, classes);
tk::dnn::writeBUF(buf, coords); tk::dnn::writeBUF(buf, coords);
tk::dnn::writeBUF(buf, num); tk::dnn::writeBUF(buf, num);
tk::dnn::writeBUF(buf, c); tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h); tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w); tk::dnn::writeBUF(buf, w);
assert(buf == a + getSerializationSize());
} }
int c, h, w; int c, h, w;
+2 -1
View File
@@ -52,11 +52,12 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, stride); tk::dnn::writeBUF(buf, stride);
tk::dnn::writeBUF(buf, c); tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h); tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w); tk::dnn::writeBUF(buf, w);
assert(buf == a + getSerializationSize());
} }
int c, h, w, stride; int c, h, w, stride;
+2 -1
View File
@@ -50,11 +50,12 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a = buf;
tk::dnn::writeBUF(buf, n); tk::dnn::writeBUF(buf, n);
tk::dnn::writeBUF(buf, c); tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h); tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w); tk::dnn::writeBUF(buf, w);
assert(buf == a + getSerializationSize());
} }
int n, c, h, w; int n, c, h, w;
+2 -1
View File
@@ -52,7 +52,7 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, o_c); tk::dnn::writeBUF(buf, o_c);
tk::dnn::writeBUF(buf, o_h); tk::dnn::writeBUF(buf, o_h);
@@ -61,6 +61,7 @@ public:
tk::dnn::writeBUF(buf, i_c); tk::dnn::writeBUF(buf, i_c);
tk::dnn::writeBUF(buf, i_h); tk::dnn::writeBUF(buf, i_h);
tk::dnn::writeBUF(buf, i_w); tk::dnn::writeBUF(buf, i_w);
assert(buf == a + getSerializationSize());
} }
int i_c, i_h, i_w, o_c, o_h, o_w; int i_c, i_h, i_w, o_c, o_h, o_w;
+2 -1
View File
@@ -75,7 +75,7 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, groups); tk::dnn::writeBUF(buf, groups);
tk::dnn::writeBUF(buf, group_id); tk::dnn::writeBUF(buf, group_id);
tk::dnn::writeBUF(buf, in); tk::dnn::writeBUF(buf, in);
@@ -85,6 +85,7 @@ public:
tk::dnn::writeBUF(buf, c); tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h); tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w); tk::dnn::writeBUF(buf, w);
assert(buf == a + getSerializationSize());
} }
static const int MAX_INPUTS = 4; static const int MAX_INPUTS = 4;
+8 -5
View File
@@ -4,10 +4,11 @@
class ShortcutRT : public IPlugin { class ShortcutRT : public IPlugin {
public: public:
ShortcutRT(tk::dnn::dataDim_t bdim) { ShortcutRT(tk::dnn::dataDim_t bdim, bool mul) {
this->bc = bdim.c; this->bc = bdim.c;
this->bh = bdim.h; this->bh = bdim.h;
this->bw = bdim.w; this->bw = bdim.w;
this->mul = mul;
} }
~ShortcutRT(){ ~ShortcutRT(){
@@ -47,28 +48,30 @@ public:
dnnType *dstData = reinterpret_cast<dnnType*>(outputs[0]); dnnType *dstData = reinterpret_cast<dnnType*>(outputs[0]);
checkCuda( cudaMemcpyAsync(dstData, srcData, batchSize*c*h*w*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream)); checkCuda( cudaMemcpyAsync(dstData, srcData, batchSize*c*h*w*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
for(int b=0; b < batchSize; ++b) shortcutForward(srcDataBack, dstData, batchSize, c, h, w, 1, batchSize, bc, bh, bw, 1, mul, stream);
shortcutForward(srcDataBack + b*bc*bh*bw, dstData + b*c*h*w, 1, c, h, w, 1, 1, bc, bh, bw, 1, stream);
return 0; return 0;
} }
virtual size_t getSerializationSize() override { virtual size_t getSerializationSize() override {
return 6*sizeof(int); return 6*sizeof(int) + sizeof(bool);
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, bc); tk::dnn::writeBUF(buf, bc);
tk::dnn::writeBUF(buf, bh); tk::dnn::writeBUF(buf, bh);
tk::dnn::writeBUF(buf, bw); tk::dnn::writeBUF(buf, bw);
tk::dnn::writeBUF(buf, mul);
tk::dnn::writeBUF(buf, c); tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h); tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w); tk::dnn::writeBUF(buf, w);
assert(buf == a + getSerializationSize());
} }
int c, h, w; int c, h, w;
int bc, bh, bw; int bc, bh, bw;
bool mul;
}; };
+2 -1
View File
@@ -54,11 +54,12 @@ public:
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, stride); tk::dnn::writeBUF(buf, stride);
tk::dnn::writeBUF(buf, c); tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h); tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w); tk::dnn::writeBUF(buf, w);
assert(buf == a + getSerializationSize());
} }
int c, h, w, stride; int c, h, w, stride;
+43 -23
View File
@@ -8,12 +8,15 @@ class YoloRT : public IPlugin {
public: public:
YoloRT(int classes, int num, tk::dnn::Yolo *yolo = nullptr, int n_masks=3, float scale_xy=1) { YoloRT(int classes, int num, tk::dnn::Yolo *yolo = nullptr, int n_masks=3, float scale_xy=1, float nms_thresh=0.45, int nms_kind=0, int new_coords=0) {
this->classes = classes; this->classes = classes;
this->num = num; this->num = num;
this->n_masks = n_masks; this->n_masks = n_masks;
this->scaleXY = scale_xy; this->scaleXY = scale_xy;
this->nms_thresh = nms_thresh;
this->nms_kind = nms_kind;
this->new_coords = new_coords;
mask = new dnnType[n_masks]; mask = new dnnType[n_masks];
bias = new dnnType[num*n_masks*2]; bias = new dnnType[num*n_masks*2];
@@ -61,17 +64,23 @@ public:
checkCuda( cudaMemcpyAsync(dstData, srcData, batchSize*c*h*w*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream)); checkCuda( cudaMemcpyAsync(dstData, srcData, batchSize*c*h*w*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
for (int b = 0; b < batchSize; ++b){
for(int n = 0; n < n_masks; ++n){
int index = entry_index(b, n*w*h, 0);
activationLOGISTICForward(srcData + index, dstData + index, 2*w*h, stream);
if (this->scaleXY != 1) scalAdd(dstData + index, 2 * w*h, this->scaleXY, -0.5*(this->scaleXY - 1), 1); for (int b = 0; b < batchSize; ++b){
for(int n = 0; n < n_masks; ++n){
int index = entry_index(b, n*w*h, 0);
if (new_coords == 1){
if (this->scaleXY != 1) scalAdd(dstData + index, 2 * w*h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
}
else{
activationLOGISTICForward(srcData + index, dstData + index, 2*w*h, stream); //x,y
index = entry_index(b, n*w*h, 4); if (this->scaleXY != 1) scalAdd(dstData + index, 2 * w*h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*w*h, stream);
} index = entry_index(b, n*w*h, 4);
} activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*w*h, stream);
}
}
}
//std::cout<<"YOLO END\n"; //std::cout<<"YOLO END\n";
return 0; return 0;
@@ -79,22 +88,29 @@ public:
virtual size_t getSerializationSize() override { virtual size_t getSerializationSize() override {
return 6*sizeof(int) + sizeof(float)+ n_masks*sizeof(dnnType) + num*n_masks*2*sizeof(dnnType) + YOLORT_CLASSNAME_W*classes*sizeof(char); return 8*sizeof(int) + 2*sizeof(float)+ n_masks*sizeof(dnnType) + num*n_masks*2*sizeof(dnnType) + YOLORT_CLASSNAME_W*classes*sizeof(char);
} }
virtual void serialize(void* buffer) override { virtual void serialize(void* buffer) override {
char *buf = reinterpret_cast<char*>(buffer); char *buf = reinterpret_cast<char*>(buffer),*a=buf;
tk::dnn::writeBUF(buf, classes); tk::dnn::writeBUF(buf, classes); //std::cout << "Classes :" << classes << std::endl;
tk::dnn::writeBUF(buf, num); tk::dnn::writeBUF(buf, num); //std::cout << "Num : " << num << std::endl;
tk::dnn::writeBUF(buf, n_masks); tk::dnn::writeBUF(buf, n_masks); //std::cout << "N_Masks" << n_masks << std::endl;
tk::dnn::writeBUF(buf, c); tk::dnn::writeBUF(buf, scaleXY); //std::cout << "ScaleXY :" << scaleXY << std::endl;
tk::dnn::writeBUF(buf, h); tk::dnn::writeBUF(buf, nms_thresh); //std::cout << "nms_thresh :" << nms_thresh << std::endl;
tk::dnn::writeBUF(buf, w); tk::dnn::writeBUF(buf, nms_kind); //std::cout << "nms_kind : " << nms_kind << std::endl;
tk::dnn::writeBUF(buf, scaleXY); tk::dnn::writeBUF(buf, new_coords); //std::cout << "new_coords : " << new_coords << std::endl;
for(int i=0; i<n_masks; i++) tk::dnn::writeBUF(buf, c); //std::cout << "C : " << c << std::endl;
tk::dnn::writeBUF(buf, mask[i]); tk::dnn::writeBUF(buf, h); //std::cout << "H : " << h << std::endl;
for(int i=0; i<n_masks*2*num; i++) tk::dnn::writeBUF(buf, w); //std::cout << "C : " << c << std::endl;
tk::dnn::writeBUF(buf, bias[i]); for (int i = 0; i < n_masks; i++)
{
tk::dnn::writeBUF(buf, mask[i]); //std::cout << "mask[i] : " << mask[i] << std::endl;
}
for (int i = 0; i < n_masks * 2 * num; i++)
{
tk::dnn::writeBUF(buf, bias[i]); //std::cout << "bias[i] : " << bias[i] << std::endl;
}
// save classes names // save classes names
for(int i=0; i<classes; i++) { for(int i=0; i<classes; i++) {
@@ -104,11 +120,15 @@ public:
tk::dnn::writeBUF(buf, tmp[j]); tk::dnn::writeBUF(buf, tmp[j]);
} }
} }
assert(buf == a + getSerializationSize());
} }
int c, h, w; int c, h, w;
int classes, num, n_masks; int classes, num, n_masks;
float scaleXY; float scaleXY;
float nms_thresh;
int nms_kind;
int new_coords;
std::vector<std::string> classesNames; std::vector<std::string> classesNames;
dnnType *mask; dnnType *mask;
+4 -3
View File
@@ -29,7 +29,8 @@ int testInference(std::vector<std::string> input_bins, std::vector<std::string>
readBinaryFile(input_bins[0], net->input_dim.tot(), &input_h, &data); readBinaryFile(input_bins[0], net->input_dim.tot(), &input_h, &data);
// outputs // outputs
dnnType *cudnn_out[outputs.size()], *rt_out[outputs.size()]; //dnnType *cudnn_out[outputs.size()], *rt_out[outputs.size()];
std::vector<dnnType *> cudnn_out,rt_out;
tk::dnn::dataDim_t dim1 = net->input_dim; //input dim tk::dnn::dataDim_t dim1 = net->input_dim; //input dim
printCenteredTitle(" CUDNN inference ", '=', 30); { printCenteredTitle(" CUDNN inference ", '=', 30); {
@@ -39,7 +40,7 @@ int testInference(std::vector<std::string> input_bins, std::vector<std::string>
TKDNN_TSTOP TKDNN_TSTOP
dim1.print(); dim1.print();
} }
for(int i=0; i<outputs.size(); i++) cudnn_out[i] = outputs[i]->dstData; for(int i=0; i<outputs.size(); i++) cudnn_out.push_back(outputs[i]->dstData);
if(netRT != nullptr) { if(netRT != nullptr) {
tk::dnn::dataDim_t dim2 = net->input_dim; tk::dnn::dataDim_t dim2 = net->input_dim;
@@ -50,7 +51,7 @@ int testInference(std::vector<std::string> input_bins, std::vector<std::string>
TKDNN_TSTOP TKDNN_TSTOP
dim2.print(); dim2.print();
} }
for(int i=0; i<outputs.size(); i++) rt_out[i] = (dnnType*)netRT->buffersRT[i+1]; for(int i=0; i<outputs.size(); i++) rt_out.push_back((dnnType*)netRT->buffersRT[i+1]);
} }
int ret_cudnn = 0, ret_tensorrt = 0, ret_cudnn_tensorrt = 0; int ret_cudnn = 0, ret_tensorrt = 0, ret_cudnn_tensorrt = 0;
+13
View File
@@ -12,8 +12,12 @@
#include <cublas_v2.h> #include <cublas_v2.h>
#include <cudnn.h> #include <cudnn.h>
#ifdef __linux__
#include <unistd.h> #include <unistd.h>
#endif
#include <ios> #include <ios>
#include <chrono>
#define dnnType float #define dnnType float
@@ -39,6 +43,7 @@
#define TKDNN_VERBOSE 0 #define TKDNN_VERBOSE 0
// Simple Timer // Simple Timer
#ifdef __linux__
#define TKDNN_TSTART timespec start, end; \ #define TKDNN_TSTART timespec start, end; \
clock_gettime(CLOCK_MONOTONIC, &start); clock_gettime(CLOCK_MONOTONIC, &start);
@@ -48,6 +53,14 @@
if(show) std::cout<<col<<"Time:"<<std::setw(16)<<t_ns<<" ms\n"<<COL_END; if(show) std::cout<<col<<"Time:"<<std::setw(16)<<t_ns<<" ms\n"<<COL_END;
#define TKDNN_TSTOP TKDNN_TSTOP_C(COL_CYANB, TKDNN_VERBOSE) #define TKDNN_TSTOP TKDNN_TSTOP_C(COL_CYANB, TKDNN_VERBOSE)
#elif _WIN32
#define TKDNN_TSTART auto start = std::chrono::high_resolution_clock::now();
#define TKDNN_TSTOP auto stop = std::chrono::high_resolution_clock::now(); \
std::chrono::duration<double> duration = stop -start; \
auto time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration);\
double t_ns = time_ms.count();
#endif
/******************************************************** /********************************************************
* Prints the error message, and exits * Prints the error message, and exits
+39
View File
@@ -0,0 +1,39 @@
import os
import urllib.request as dowReq
import zipfile
val = input("Enter BDD or COCO :")
if(val == "COCO"):
url = "https://cloud.hipert.unimore.it/s/LNxBDk4wzqXPL8c/download"
lib = "..\demo\COCO_val2017"
lib_zip = "COCO_val2017.zip"
elif(val == "BDD"):
url = "https://cloud.hipert.unimore.it/s/bikqk3FzCq2tg4D/download"
lib = "..\demo\BDD100k_val"
lib_zip = "BDD100k_val.zip"
dowReq.urlretrieve(url,lib_zip)
with zipfile.ZipFile(lib_zip,'r') as zip_ref:
zip_ref.extractall(lib)
labelFolder = lib + "\labels"
imageFolder = lib + "\images"
file1 = open(".\\..\\demo\\all_labels.txt","a")
path1 = os.path.realpath(labelFolder)
for file in os.listdir(labelFolder):
valTemp = path1 + "\\" + file
valTemp = valTemp + '\n'
file1.write(valTemp)
file1.close()
file2 = open(".\\..\\demo\\all_images.txt","a")
path2 = os.path.realpath(imageFolder)
for file in os.listdir(imageFolder):
pathtemp = path2 + "\\" + file
pathtemp = pathtemp + '\n'
file2.write(pathtemp)
file2.close()
print("Completed")
+11 -2
View File
@@ -69,12 +69,21 @@ do
echo -e "${ORANGE}Batch $TKDNN_BATCHSIZE ${NC}" echo -e "${ORANGE}Batch $TKDNN_BATCHSIZE ${NC}"
test_net mnist test_net mnist
./test_imuodom &>> $out_file # ./test_imuodom &>> $out_file
print_output $? imuodom # print_output $? imuodom
test_net shelfnet
test_net shelfnet_berkeley
test_net yolo4 test_net yolo4
test_net yolo4_320
test_net yolo4_320_coco2
test_net yolo4_512
test_net yolo4_608
test_net yolo4-csp
test_net yolo4x
test_net yolo4_berkeley test_net yolo4_berkeley
test_net yolo4tiny test_net yolo4tiny
test_net yolo4tiny_512
test_net yolo3 test_net yolo3
test_net yolo3_berkeley test_net yolo3_berkeley
test_net yolo3_coco4 test_net yolo3_coco4
+1 -1
View File
@@ -42,7 +42,7 @@ do
echo -e "${ORANGE}Batch $TKDNN_BATCHSIZE ${NC}" echo -e "${ORANGE}Batch $TKDNN_BATCHSIZE ${NC}"
test_inference yolo4_320 $mode test_inference yolo4_320 $mode
test_inference yolo4_416 $mode test_inference yolo4 $mode
test_inference yolo4_512 $mode test_inference yolo4_512 $mode
test_inference yolo4_608 $mode test_inference yolo4_608 $mode
test_inference yolo4tiny $mode test_inference yolo4tiny $mode
+9 -5
View File
@@ -5,11 +5,12 @@
namespace tk { namespace dnn { namespace tk { namespace dnn {
Activation::Activation(Network *net, int act_mode, const float ceiling) : Activation::Activation(Network *net, int act_mode, const float ceiling, const float slope) :
Layer(net) { Layer(net) {
this->act_mode = act_mode; this->act_mode = act_mode;
this->ceiling = ceiling; this->ceiling = ceiling;
this->slope = slope;
checkCuda( cudaMalloc(&dstData, input_dim.tot()*sizeof(dnnType)) ); checkCuda( cudaMalloc(&dstData, input_dim.tot()*sizeof(dnnType)) );
if(int(act_mode) < 100) { if(int(act_mode) < 100) {
@@ -46,12 +47,15 @@ Activation::~Activation() {
dnnType* Activation::infer(dataDim_t &dim, dnnType* srcData) { dnnType* Activation::infer(dataDim_t &dim, dnnType* srcData) {
if(act_mode == ACTIVATION_LEAKY) { if(act_mode == ACTIVATION_LEAKY) {
activationLEAKYForward(srcData, dstData, dim.tot()); activationLEAKYForward(srcData, dstData, dim.tot(), this->slope);
} }
else if(act_mode == ACTIVATION_MISH) { else if(act_mode == ACTIVATION_MISH) {
activationMishForward(srcData, dstData, dim.tot()); activationMishForward(srcData, dstData, dim.tot());
}
else if(act_mode == ACTIVATION_LOGISTIC) {
activationLOGISTICForward(srcData, dstData, dim.tot());
} else { } else {
dnnType alpha = dnnType(1); dnnType alpha = dnnType(1);
dnnType beta = dnnType(0); dnnType beta = dnnType(0);
+13 -2
View File
@@ -37,7 +37,10 @@ namespace tk { namespace dnn {
std::string name,value; std::string name,value;
if(!divideNameAndValue(line, name, value)) if(!divideNameAndValue(line, name, value))
return false; return false;
if(name.find("width") != std::string::npos)
if(name.find("new_coords") != std::string::npos)
fields.new_coords = std::stoi(value);
else if(name.find("width") != std::string::npos)
fields.width = std::stoi(value); fields.width = std::stoi(value);
else if(name.find("height") != std::string::npos) else if(name.find("height") != std::string::npos)
fields.height = std::stoi(value); fields.height = std::stoi(value);
@@ -79,6 +82,13 @@ namespace tk { namespace dnn {
fields.group_id = std::stoi(value); fields.group_id = std::stoi(value);
else if(name.find("scale_x_y") != std::string::npos) else if(name.find("scale_x_y") != std::string::npos)
fields.scale_xy = std::stof(value); fields.scale_xy = std::stof(value);
else if(name.find("beta_nms") != std::string::npos)
fields.nms_thresh = std::stof(value);
else if(name.find("nms_kind") != std::string::npos){
if(value == "greedynms") fields.nms_kind = 0;
else if(value == "diounms") fields.nms_kind = 1;
else std::cout<<"Not supported nms_kind "<<value<<", setting to greedynms"<<std::endl;
}
else if(name.find("from") != std::string::npos) else if(name.find("from") != std::string::npos)
fields.layers.push_back(std::stof(value)); fields.layers.push_back(std::stof(value));
else if(name.find("mask") != std::string::npos){ else if(name.find("mask") != std::string::npos){
@@ -161,7 +171,7 @@ namespace tk { namespace dnn {
} else if(f.type == "yolo") { } else if(f.type == "yolo") {
std::string wgs = wgs_path + "/g" + std::to_string(netLayers.size()) + ".bin"; std::string wgs = wgs_path + "/g" + std::to_string(netLayers.size()) + ".bin";
//printf("%d %d %s %d %f\n", f.classes, f.num/f.n_mask, wgs.c_str(), f.n_mask, f.scale_xy); //printf("%d %d %s %d %f\n", f.classes, f.num/f.n_mask, wgs.c_str(), f.n_mask, f.scale_xy);
tk::dnn::Yolo *l = new tk::dnn::Yolo(net, f.classes, f.num/f.n_mask, wgs, f.n_mask, f.scale_xy); tk::dnn::Yolo *l = new tk::dnn::Yolo(net, f.classes, f.num/f.n_mask, wgs, f.n_mask, f.scale_xy, f.nms_thresh, (tk::dnn::Yolo::nmsKind_t) f.nms_kind, f.new_coords);
if(names.size() != f.classes) if(names.size() != f.classes)
FatalError("Mismatch between number of classes and names"); FatalError("Mismatch between number of classes and names");
l->classesNames = names; l->classesNames = names;
@@ -177,6 +187,7 @@ namespace tk { namespace dnn {
if(f.activation == "relu") act = tkdnnActivationMode_t(CUDNN_ACTIVATION_RELU); if(f.activation == "relu") act = tkdnnActivationMode_t(CUDNN_ACTIVATION_RELU);
else if(f.activation == "leaky") act = tk::dnn::ACTIVATION_LEAKY; else if(f.activation == "leaky") act = tk::dnn::ACTIVATION_LEAKY;
else if(f.activation == "mish") act = tk::dnn::ACTIVATION_MISH; else if(f.activation == "mish") act = tk::dnn::ACTIVATION_MISH;
else if(f.activation == "logistic") act = tk::dnn::ACTIVATION_LOGISTIC;
else { FatalError("activation not supported: " + f.activation); } else { FatalError("activation not supported: " + f.activation); }
netLayers[netLayers.size()-1] = new tk::dnn::Activation(net, act); netLayers[netLayers.size()-1] = new tk::dnn::Activation(net, act);
}; };
+9 -4
View File
@@ -87,17 +87,22 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig
checkCUDNN(cudnnCreateRNNDescriptor(&rnnDesc)); checkCUDNN(cudnnCreateRNNDescriptor(&rnnDesc));
#if CUDNN_MAJOR > 7 #if CUDNN_MAJOR > 7
checkCUDNN(cudnnSetRNNDescriptor_v6(net->cudnnHandle, checkCUDNN(cudnnSetRNNDescriptor_v6(net->cudnnHandle,rnnDesc, stateSize, numLayers, dropoutDesc,
cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT,
//(bidirectional ? cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL : cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL),
cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL,
cudnnRNNMode_t::CUDNN_LSTM,
cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD,
net->dataType));
#else #else
checkCUDNN(cudnnSetRNNDescriptor(net->cudnnHandle, checkCUDNN(cudnnSetRNNDescriptor(net->cudnnHandle,rnnDesc, stateSize, numLayers, dropoutDesc,
#endif
rnnDesc, stateSize, numLayers, dropoutDesc,
cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT, cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT,
//(bidirectional ? cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL : cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL), //(bidirectional ? cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL : cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL),
cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL, cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL,
cudnnRNNMode_t::CUDNN_LSTM, cudnnRNNMode_t::CUDNN_LSTM,
cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD, cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD,
net->dataType)); net->dataType));
#endif
// Get temp space sizes // Get temp space sizes
+1
View File
@@ -32,6 +32,7 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs,
this->batchnorm = batchnorm; this->batchnorm = batchnorm;
if(batchnorm) { if(batchnorm) {
readBinaryFile(weights_path.c_str(), outputs, &scales_h, &scales_d, seek); readBinaryFile(weights_path.c_str(), outputs, &scales_h, &scales_d, seek);
seek += outputs; seek += outputs;
readBinaryFile(weights_path.c_str(), outputs, &mean_h, &mean_d, seek); readBinaryFile(weights_path.c_str(), outputs, &mean_h, &mean_d, seek);
+113 -40
View File
@@ -140,6 +140,7 @@ NetworkRT::NetworkRT(Network *net, const char *name) {
engineRT = builderRT->buildEngineWithConfig(*networkRT, *configRT); engineRT = builderRT->buildEngineWithConfig(*networkRT, *configRT);
#else #else
engineRT = builderRT->buildCudaEngine(*networkRT); engineRT = builderRT->buildCudaEngine(*networkRT);
//engineRT = std::shared_ptr<nvinfer1::ICudaEngine>(builderRT->buildCudaEngine(*networkRT));
#endif #endif
if(engineRT == nullptr) if(engineRT == nullptr)
FatalError("cloud not build cuda engine") FatalError("cloud not build cuda engine")
@@ -226,7 +227,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Layer *l) {
return convert_layer(input, (Conv2d*) l); return convert_layer(input, (Conv2d*) l);
if(type == LAYER_POOLING) if(type == LAYER_POOLING)
return convert_layer(input, (Pooling*) l); return convert_layer(input, (Pooling*) l);
if(type == LAYER_ACTIVATION || type == LAYER_ACTIVATION_CRELU || type == LAYER_ACTIVATION_LEAKY || type == LAYER_ACTIVATION_MISH) if(type == LAYER_ACTIVATION || type == LAYER_ACTIVATION_CRELU || type == LAYER_ACTIVATION_LEAKY || type == LAYER_ACTIVATION_MISH || type == LAYER_ACTIVATION_LOGISTIC)
return convert_layer(input, (Activation*) l); return convert_layer(input, (Activation*) l);
if(type == LAYER_SOFTMAX) if(type == LAYER_SOFTMAX)
return convert_layer(input, (Softmax*) l); return convert_layer(input, (Softmax*) l);
@@ -236,6 +237,8 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Layer *l) {
return convert_layer(input, (Flatten*) l); return convert_layer(input, (Flatten*) l);
if(type == LAYER_RESHAPE) if(type == LAYER_RESHAPE)
return convert_layer(input, (Reshape*) l); return convert_layer(input, (Reshape*) l);
if(type == LAYER_RESIZE)
return convert_layer(input, (Resize*) l);
if(type == LAYER_REORG) if(type == LAYER_REORG)
return convert_layer(input, (Reorg*) l); return convert_layer(input, (Reorg*) l);
if(type == LAYER_REGION) if(type == LAYER_REGION)
@@ -389,13 +392,13 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) {
#if NV_TENSORRT_MAJOR < 6 #if NV_TENSORRT_MAJOR < 6
// plugin version // plugin version
IPlugin *plugin = new ActivationLeakyRT(); IPlugin *plugin = new ActivationLeakyRT(l->slope);
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin); IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
checkNULL(lRT); checkNULL(lRT);
return lRT; return lRT;
#else #else
IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kLEAKY_RELU); IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kLEAKY_RELU);
lRT->setAlpha(0.1); lRT->setAlpha(l->slope);
checkNULL(lRT); checkNULL(lRT);
return lRT; return lRT;
#endif #endif
@@ -421,6 +424,12 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) {
checkNULL(lRT); checkNULL(lRT);
return lRT; return lRT;
} }
else if(l->act_mode == ACTIVATION_LOGISTIC) {
IPlugin *plugin = new ActivationLogisticRT();
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
checkNULL(lRT);
return lRT;
}
else { else {
FatalError("this Activation mode is not yet implemented"); FatalError("this Activation mode is not yet implemented");
return NULL; return NULL;
@@ -472,13 +481,23 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Flatten *l) {
ILayer* NetworkRT::convert_layer(ITensor *input, Reshape *l) { ILayer* NetworkRT::convert_layer(ITensor *input, Reshape *l) {
// std::cout<<"convert Reshape\n"; // std::cout<<"convert Reshape\n";
l->output_dim.print();
IPlugin *plugin = new ReshapeRT(l->output_dim); IPlugin *plugin = new ReshapeRT(l->output_dim);
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin); IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
checkNULL(lRT); checkNULL(lRT);
return lRT; return lRT;
} }
ILayer* NetworkRT::convert_layer(ITensor *input, Resize *l) {
// std::cout<<"convert Resize\n";
IResizeLayer *lRT = networkRT->addResize(*input); //default is kNEAREST
checkNULL(lRT);
Dims d{};
lRT->setResizeMode(ResizeMode(l->mode));
lRT->setOutputDimensions(DimsCHW{l->output_dim.c, l->output_dim.h, l->output_dim.w});
return lRT;
}
ILayer* NetworkRT::convert_layer(ITensor *input, Reorg *l) { ILayer* NetworkRT::convert_layer(ITensor *input, Reorg *l) {
//std::cout<<"convert Reorg\n"; //std::cout<<"convert Reorg\n";
@@ -506,7 +525,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Shortcut *l) {
ITensor *back_tens = tensors[l->backLayer]; ITensor *back_tens = tensors[l->backLayer];
if(l->backLayer->output_dim.c == l->output_dim.c) if(l->backLayer->output_dim.c == l->output_dim.c && !l->mul)
{ {
IElementWiseLayer *lRT = networkRT->addElementWise(*input, *back_tens, ElementWiseOperation::kSUM); IElementWiseLayer *lRT = networkRT->addElementWise(*input, *back_tens, ElementWiseOperation::kSUM);
checkNULL(lRT); checkNULL(lRT);
@@ -515,7 +534,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Shortcut *l) {
else else
{ {
// plugin version // plugin version
IPlugin *plugin = new ShortcutRT(l->backLayer->output_dim); IPlugin *plugin = new ShortcutRT(l->backLayer->output_dim, l->mul);
ITensor **inputs = new ITensor*[2]; ITensor **inputs = new ITensor*[2];
inputs[0] = input; inputs[0] = input;
inputs[1] = back_tens; inputs[1] = back_tens;
@@ -529,7 +548,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Yolo *l) {
//std::cout<<"convert Yolo\n"; //std::cout<<"convert Yolo\n";
//std::cout<<"New plugin YOLO\n"; //std::cout<<"New plugin YOLO\n";
IPlugin *plugin = new YoloRT(l->classes, l->num, l, l->n_masks, l->scaleXY); IPlugin *plugin = new YoloRT(l->classes, l->num, l, l->n_masks, l->scaleXY, l->nms_thresh, l->nsm_kind, l->new_coords);
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin); IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
checkNULL(lRT); checkNULL(lRT);
return lRT; return lRT;
@@ -561,7 +580,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, DeformConv2d *l) {
IPluginLayer *lRT = networkRT->addPlugin(inputs, 2, *plugin); IPluginLayer *lRT = networkRT->addPlugin(inputs, 2, *plugin);
checkNULL(lRT); checkNULL(lRT);
lRT->setName( ("Deformable" + std::to_string(l->id)).c_str() ); lRT->setName( ("Deformable" + std::to_string(l->id)).c_str() );
delete(inputs); delete[](inputs);
// batchnorm // batchnorm
void *bias_b, *power_b, *mean_b, *variance_b, *scales_b; void *bias_b, *power_b, *mean_b, *variance_b, *scales_b;
if(dtRT == DataType::kHALF) { if(dtRT == DataType::kHALF) {
@@ -638,43 +657,61 @@ bool NetworkRT::deserialize(const char *filename) {
IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialData, size_t serialLength) { IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialData, size_t serialLength) {
const char * buf = reinterpret_cast<const char*>(serialData); const char * buf = reinterpret_cast<const char*>(serialData),*bufCheck = buf;
std::string name(layerName); std::string name(layerName);
//std::cout<<name<<std::endl; //std::cout<<name<<std::endl;
if(name.find("ActivationLeaky") == 0) { if(name.find("ActivationLeaky") == 0) {
ActivationLeakyRT *a = new ActivationLeakyRT(); ActivationLeakyRT *a = new ActivationLeakyRT(readBUF<float>(buf));
a->size = readBUF<int>(buf); a->size = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return a; return a;
} }
if(name.find("ActivationMish") == 0) { if(name.find("ActivationMish") == 0) {
ActivationMishRT *a = new ActivationMishRT(); ActivationMishRT *a = new ActivationMishRT();
a->size = readBUF<int>(buf); a->size = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return a;
}
if(name.find("ActivationLogistic") == 0) {
ActivationLogisticRT *a = new ActivationLogisticRT();
a->size = readBUF<int>(buf);
return a;
}
if(name.find("ActivationLogistic") == 0) {
ActivationLogisticRT *a = new ActivationLogisticRT();
a->size = readBUF<int>(buf);
return a; return a;
} }
if(name.find("ActivationCReLU") == 0) { if(name.find("ActivationCReLU") == 0) {
ActivationReLUCeiling *a = new ActivationReLUCeiling(readBUF<float>(buf)); float activationReluTemp = readBUF<float>(buf);
ActivationReLUCeiling* a = new ActivationReLUCeiling(activationReluTemp);
a->size = readBUF<int>(buf); a->size = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return a; return a;
} }
if(name.find("Region") == 0) { if(name.find("Region") == 0) {
RegionRT *r = new RegionRT(readBUF<int>(buf), //classes int classesTemp = readBUF<int>(buf);
readBUF<int>(buf), //coords int coordsTemp = readBUF<int>(buf);
readBUF<int>(buf)); //num int numTemp = readBUF<int>(buf);
RegionRT* r = new RegionRT(classesTemp, coordsTemp, numTemp);
r->c = readBUF<int>(buf); r->c = readBUF<int>(buf);
r->h = readBUF<int>(buf); r->h = readBUF<int>(buf);
r->w = readBUF<int>(buf); r->w = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
if(name.find("Reorg") == 0) { if(name.find("Reorg") == 0) {
ReorgRT *r = new ReorgRT(readBUF<int>(buf)); //stride int strideTemp = readBUF<int>(buf);
ReorgRT *r = new ReorgRT(strideTemp);
r->c = readBUF<int>(buf); r->c = readBUF<int>(buf);
r->h = readBUF<int>(buf); r->h = readBUF<int>(buf);
r->w = readBUF<int>(buf); r->w = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
@@ -685,32 +722,39 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
bdim.w = readBUF<int>(buf); bdim.w = readBUF<int>(buf);
bdim.l = 1; bdim.l = 1;
ShortcutRT *r = new ShortcutRT(bdim); ShortcutRT *r = new ShortcutRT(bdim, readBUF<bool>(buf));
r->c = readBUF<int>(buf); r->c = readBUF<int>(buf);
r->h = readBUF<int>(buf); r->h = readBUF<int>(buf);
r->w = readBUF<int>(buf); r->w = readBUF<int>(buf);
return r; return r;
assert(buf == bufCheck + serialLength);
} }
if(name.find("Pooling") == 0) { if(name.find("Pooling") == 0) {
MaxPoolFixedSizeRT *r = new MaxPoolFixedSizeRT( readBUF<int>(buf), //c int cTemp = readBUF<int>(buf);
readBUF<int>(buf), //h int hTemp = readBUF<int>(buf);
readBUF<int>(buf), //w int wTemp = readBUF<int>(buf);
readBUF<int>(buf), //n int nTemp = readBUF<int>(buf);
readBUF<int>(buf), //strideH int strideHTemp = readBUF<int>(buf);
readBUF<int>(buf), //strideW int strideWTemp = readBUF<int>(buf);
readBUF<int>(buf), //winSize int winSizeTemp = readBUF<int>(buf);
readBUF<int>(buf)); //padding int paddingTemp = readBUF<int>(buf);
MaxPoolFixedSizeRT* r = new MaxPoolFixedSizeRT(cTemp, hTemp, wTemp, nTemp, strideHTemp, strideWTemp, winSizeTemp, paddingTemp);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
if(name.find("Resize") == 0) { if(name.find("Resize") == 0) {
ResizeLayerRT *r = new ResizeLayerRT(readBUF<int>(buf), //o_c int o_cTemp = readBUF<int>(buf);
readBUF<int>(buf), //o_h int o_hTemp = readBUF<int>(buf);
readBUF<int>(buf)); //o_w int o_wTemp = readBUF<int>(buf);
ResizeLayerRT* r = new ResizeLayerRT(o_cTemp, o_hTemp, o_wTemp);
r->i_c = readBUF<int>(buf); r->i_c = readBUF<int>(buf);
r->i_h = readBUF<int>(buf); r->i_h = readBUF<int>(buf);
r->i_w = readBUF<int>(buf); r->i_w = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
@@ -721,6 +765,7 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
r->w = readBUF<int>(buf); r->w = readBUF<int>(buf);
r->rows = readBUF<int>(buf); r->rows = readBUF<int>(buf);
r->cols = readBUF<int>(buf); r->cols = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
@@ -732,19 +777,28 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
new_dim.h = readBUF<int>(buf); new_dim.h = readBUF<int>(buf);
new_dim.w = readBUF<int>(buf); new_dim.w = readBUF<int>(buf);
ReshapeRT *r = new ReshapeRT(new_dim); ReshapeRT *r = new ReshapeRT(new_dim);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
if(name.find("Yolo") == 0) { if(name.find("Yolo") == 0) {
YoloRT *r = new YoloRT(readBUF<int>(buf), //classes
readBUF<int>(buf), //num int classes_temp = readBUF<int>(buf);
nullptr, int num_temp = readBUF<int>(buf);
readBUF<int>(buf)); //n_masks int n_masks_temp = readBUF<int>(buf);
float scale_xy_temp = readBUF<float>(buf);
float nms_thresh_temp = readBUF<float>(buf);
int nms_kind_temp = readBUF<int>(buf);
int new_coords_temp = readBUF<int>(buf);
YoloRT *r = new YoloRT(classes_temp,num_temp,nullptr,n_masks_temp,scale_xy_temp,nms_thresh_temp,nms_kind_temp,new_coords_temp);
r->c = readBUF<int>(buf); r->c = readBUF<int>(buf);
r->h = readBUF<int>(buf); r->h = readBUF<int>(buf);
r->w = readBUF<int>(buf); r->w = readBUF<int>(buf);
r->scaleXY = readBUF<float>(buf);
for(int i=0; i<r->n_masks; i++) for(int i=0; i<r->n_masks; i++)
r->mask[i] = readBUF<dnnType>(buf); r->mask[i] = readBUF<dnnType>(buf);
for(int i=0; i<r->n_masks*2*r->num; i++) for(int i=0; i<r->n_masks*2*r->num; i++)
@@ -758,36 +812,54 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
tmp[j] = readBUF<char>(buf); tmp[j] = readBUF<char>(buf);
r->classesNames[i] = std::string(tmp); r->classesNames[i] = std::string(tmp);
} }
assert(buf == bufCheck + serialLength);
yolos[n_yolos++] = r; yolos[n_yolos++] = r;
return r; return r;
} }
if(name.find("Upsample") == 0) { if(name.find("Upsample") == 0) {
UpsampleRT *r = new UpsampleRT(readBUF<int>(buf)); //stride int strideTemp = readBUF<int>(buf);
UpsampleRT* r = new UpsampleRT(strideTemp);
r->c = readBUF<int>(buf); r->c = readBUF<int>(buf);
r->h = readBUF<int>(buf); r->h = readBUF<int>(buf);
r->w = readBUF<int>(buf); r->w = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
if(name.find("Route") == 0) { if(name.find("Route") == 0) {
RouteRT *r = new RouteRT(readBUF<int>(buf),readBUF<int>(buf)); int groupsTemp = readBUF<int>(buf);
int group_idTemp = readBUF<int>(buf);
RouteRT* r = new RouteRT(groupsTemp, group_idTemp);
r->in = readBUF<int>(buf); r->in = readBUF<int>(buf);
for(int i=0; i<RouteRT::MAX_INPUTS; i++) for(int i=0; i<RouteRT::MAX_INPUTS; i++)
r->c_in[i] = readBUF<int>(buf); r->c_in[i] = readBUF<int>(buf);
r->c = readBUF<int>(buf); r->c = readBUF<int>(buf);
r->h = readBUF<int>(buf); r->h = readBUF<int>(buf);
r->w = readBUF<int>(buf); r->w = readBUF<int>(buf);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
if(name.find("Deformable") == 0) { if(name.find("Deformable") == 0) {
DeformableConvRT *r = new DeformableConvRT(readBUF<int>(buf), readBUF<int>(buf), readBUF<int>(buf), int chuck_dimTemp = readBUF<int>(buf);
readBUF<int>(buf), readBUF<int>(buf), readBUF<int>(buf), int khTemp = readBUF<int>(buf);
readBUF<int>(buf), readBUF<int>(buf), int kwTemp = readBUF<int>(buf);
readBUF<int>(buf),readBUF<int>(buf),readBUF<int>(buf),readBUF<int>(buf), int shTemp = readBUF<int>(buf);
readBUF<int>(buf),readBUF<int>(buf),readBUF<int>(buf),readBUF<int>(buf), int swTemp = readBUF<int>(buf);
nullptr); int phTemp = readBUF<int>(buf);
int pwTemp = readBUF<int>(buf);
int deformableGroupTemp = readBUF<int>(buf);
int i_nTemp = readBUF<int>(buf);
int i_cTemp = readBUF<int>(buf);
int i_hTemp = readBUF<int>(buf);
int i_wTemp = readBUF<int>(buf);
int o_nTemp = readBUF<int>(buf);
int o_cTemp = readBUF<int>(buf);
int o_hTemp = readBUF<int>(buf);
int o_wTemp = readBUF<int>(buf);
DeformableConvRT* r = new DeformableConvRT(chuck_dimTemp, khTemp, kwTemp, shTemp, swTemp, phTemp, pwTemp, deformableGroupTemp, i_nTemp, i_cTemp, i_hTemp, i_wTemp, o_nTemp, o_cTemp, o_hTemp, o_wTemp, nullptr);
dnnType *aus = new dnnType[r->chunk_dim*2]; dnnType *aus = new dnnType[r->chunk_dim*2];
for(int i=0; i<r->chunk_dim*2; i++) for(int i=0; i<r->chunk_dim*2; i++)
aus[i] = readBUF<dnnType>(buf); aus[i] = readBUF<dnnType>(buf);
@@ -818,6 +890,7 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
aus[i] = readBUF<dnnType>(buf); aus[i] = readBUF<dnnType>(buf);
checkCuda( cudaMemcpy(r->ones_d2, aus, sizeof(dnnType)*r->dim_ones, cudaMemcpyHostToDevice) ); checkCuda( cudaMemcpy(r->ones_d2, aus, sizeof(dnnType)*r->dim_ones, cudaMemcpyHostToDevice) );
free(aus); free(aus);
assert(buf == bufCheck + serialLength);
return r; return r;
} }
+380 -15
View File
@@ -6,23 +6,389 @@
namespace tk { namespace dnn { namespace tk { namespace dnn {
cv::Mat vizFloat2colorMap(cv::Mat map) { cv::Mat mapillary_15_map(cv::Mat adjMap){
// cv::imshow("test", adjMap);
// cv::waitKey(0);
cv::Mat M1(1, 256, CV_8UC1), M2(1, 256, CV_8UC1), M3(1, 256, CV_8UC1);
//animal
M3.at<uchar>(0)=165;
M2.at<uchar>(0)=42;
M1.at<uchar>(0)=45;
//curb
M3.at<uchar>(1)=196;
M2.at<uchar>(1)=196;
M1.at<uchar>(1)=196;
//barrier
M3.at<uchar>(2)=90;
M2.at<uchar>(2)=120;
M1.at<uchar>(2)=150;
//road
M3.at<uchar>(3)=128;
M2.at<uchar>(3)=64;
M1.at<uchar>(3)=128;
//building
M3.at<uchar>(4)=70;
M2.at<uchar>(4)=70;
M1.at<uchar>(4)=70;
//person
M3.at<uchar>(5)=220;
M2.at<uchar>(5)=20;
M1.at<uchar>(5)=60;
//roadmark
M3.at<uchar>(6)=255;
M2.at<uchar>(6)=255;
M1.at<uchar>(6)=255;
//nature
M3.at<uchar>(7)=107;
M2.at<uchar>(7)=142;
M1.at<uchar>(7)=35;
//sky
M3.at<uchar>(8)=70;
M2.at<uchar>(8)=130;
M1.at<uchar>(8)=180;
//billboard
M3.at<uchar>(9)=220;
M2.at<uchar>(9)=220;
M1.at<uchar>(9)=220;
//pole
M3.at<uchar>(10)=153;
M2.at<uchar>(10)=153;
M1.at<uchar>(10)=153;
//traffic sign
M3.at<uchar>(11)=128;
M2.at<uchar>(11)=128;
M1.at<uchar>(11)=128;
//bike
M3.at<uchar>(12)=119;
M2.at<uchar>(12)=11;
M1.at<uchar>(12)=32;
//vehicle
M3.at<uchar>(13)=0;
M2.at<uchar>(13)=0;
M1.at<uchar>(13)=142;
//void
for(int i=14;i<256;i++)
{
M1.at<uchar>(i)=0;
M2.at<uchar>(i)=0;
M3.at<uchar>(i)=0;
}
cv::Mat r1,r2,r3;
cv::LUT(adjMap,M1,r1);
cv::LUT(adjMap,M2,r2);
cv::LUT(adjMap,M3,r3);
std::vector<cv::Mat> planes;
planes.push_back(r1);
planes.push_back(r2);
planes.push_back(r3);
cv::Mat dst;
cv::merge(planes,dst);
return dst;
}
cv::Mat berkeley_20_map(cv::Mat adjMap){
cv::Mat M1(1, 256, CV_8UC1), M2(1, 256, CV_8UC1), M3(1, 256, CV_8UC1);
//road
M3.at<uchar>(0)=128;
M2.at<uchar>(0)=64;
M1.at<uchar>(0)=128;
//sidewalk
M3.at<uchar>(1)=244;
M2.at<uchar>(1)=35;
M1.at<uchar>(1)=232;
//building
M3.at<uchar>(2)=70;
M2.at<uchar>(2)=70;
M1.at<uchar>(2)=70;
//wall
M3.at<uchar>(3)=102;
M2.at<uchar>(3)=102;
M1.at<uchar>(3)=156;
//fence
M3.at<uchar>(4)=90;
M2.at<uchar>(4)=120;
M1.at<uchar>(4)=150;
//pole
M3.at<uchar>(5)=153;
M2.at<uchar>(5)=153;
M1.at<uchar>(5)=153;
//traffic light
M3.at<uchar>(6)=250;
M2.at<uchar>(6)=170;
M1.at<uchar>(6)=30;
//traffic sign
M3.at<uchar>(7)=128;
M2.at<uchar>(7)=128;
M1.at<uchar>(7)=128;
//nature
M3.at<uchar>(8)=107;
M2.at<uchar>(8)=142;
M1.at<uchar>(8)=35;
//ground
M3.at<uchar>(9)=0;
M2.at<uchar>(9)=192;
M1.at<uchar>(9)=0;
//sky
M3.at<uchar>(10)=70;
M2.at<uchar>(10)=130;
M1.at<uchar>(10)=180;
//person
M3.at<uchar>(11)=220;
M2.at<uchar>(11)=20;
M1.at<uchar>(11)=60;
//rider
M3.at<uchar>(12)=255;
M2.at<uchar>(12)=0;
M1.at<uchar>(12)=100;
//car
M3.at<uchar>(13)=0;
M2.at<uchar>(13)=0;
M1.at<uchar>(13)=142;
//truck
M3.at<uchar>(14)=0;
M2.at<uchar>(14)=0;
M1.at<uchar>(14)=70;
//bus
M3.at<uchar>(15)=0;
M2.at<uchar>(15)=60;
M1.at<uchar>(15)=100;
//train
M3.at<uchar>(16)=0;
M2.at<uchar>(16)=0;
M1.at<uchar>(16)=192;
//motorbike
M3.at<uchar>(17)=0;
M2.at<uchar>(17)=0;
M1.at<uchar>(17)=230;
//bike
M3.at<uchar>(18)=119;
M2.at<uchar>(18)=11;
M1.at<uchar>(18)=32;
//void
for(int i=19;i<256;i++)
{
M1.at<uchar>(i)=0;
M2.at<uchar>(i)=0;
M3.at<uchar>(i)=0;
}
cv::Mat r1,r2,r3;
cv::LUT(adjMap,M1,r1);
cv::LUT(adjMap,M2,r2);
cv::LUT(adjMap,M3,r3);
std::vector<cv::Mat> planes;
planes.push_back(r1);
planes.push_back(r2);
planes.push_back(r3);
cv::Mat dst;
cv::merge(planes,dst);
return dst;
}
cv::Mat cityscapes_19_map(cv::Mat adjMap){
cv::Mat M1(1, 256, CV_8UC1), M2(1, 256, CV_8UC1), M3(1, 256, CV_8UC1);
//road
M3.at<uchar>(0)=128;
M2.at<uchar>(0)=64;
M1.at<uchar>(0)=128;
//sidewalk
M3.at<uchar>(1)=244;
M2.at<uchar>(1)=35;
M1.at<uchar>(1)=232;
//building
M3.at<uchar>(2)=70;
M2.at<uchar>(2)=70;
M1.at<uchar>(2)=70;
//wall
M3.at<uchar>(3)=102;
M2.at<uchar>(3)=102;
M1.at<uchar>(3)=156;
//fence
M3.at<uchar>(4)=190;
M2.at<uchar>(4)=153;
M1.at<uchar>(4)=153;
//pole
M3.at<uchar>(5)=153;
M2.at<uchar>(5)=153;
M1.at<uchar>(5)=153;
//traffic light
M3.at<uchar>(6)=250;
M2.at<uchar>(6)=170;
M1.at<uchar>(6)=30;
//traffic sign
M3.at<uchar>(7)=220;
M2.at<uchar>(7)=220;
M1.at<uchar>(7)=0;
//vegetation
M3.at<uchar>(8)=107;
M2.at<uchar>(8)=142;
M1.at<uchar>(8)=35;
//terrain
M3.at<uchar>(9)=152;
M2.at<uchar>(9)=251;
M1.at<uchar>(9)=152;
//sky
M3.at<uchar>(10)=70;
M2.at<uchar>(10)=130;
M1.at<uchar>(10)=180;
//person
M3.at<uchar>(11)=220;
M2.at<uchar>(11)=20;
M1.at<uchar>(11)=60;
//rider
M3.at<uchar>(12)=255;
M2.at<uchar>(12)=0;
M1.at<uchar>(12)=0;
//car
M3.at<uchar>(13)=0;
M2.at<uchar>(13)=0;
M1.at<uchar>(13)=142;
//truck
M3.at<uchar>(14)=0;
M2.at<uchar>(14)=0;
M1.at<uchar>(14)=70;
//bus
M3.at<uchar>(15)=0;
M2.at<uchar>(15)=60;
M1.at<uchar>(15)=100;
//train
M3.at<uchar>(16)=0;
M2.at<uchar>(16)=80;
M1.at<uchar>(16)=100;
//motorcycle
M3.at<uchar>(17)=0;
M2.at<uchar>(17)=0;
M1.at<uchar>(17)=230;
//bicycle
M3.at<uchar>(18)=119;
M2.at<uchar>(18)=11;
M1.at<uchar>(18)=32;
//void
for(int i=19;i<256;i++)
{
M1.at<uchar>(i)=0;
M2.at<uchar>(i)=0;
M3.at<uchar>(i)=0;
}
cv::Mat r1,r2,r3;
cv::LUT(adjMap,M1,r1);
cv::LUT(adjMap,M2,r2);
cv::LUT(adjMap,M3,r3);
std::vector<cv::Mat> planes;
planes.push_back(r1);
planes.push_back(r2);
planes.push_back(r3);
cv::Mat dst;
cv::merge(planes,dst);
return dst;
}
cv::Mat vizFloat2colorMap(cv::Mat map,double min, double max, int classes) {
if(min == 0 && max == 0)
cv::minMaxIdx(map, &min, &max);
double min;
double max;
cv::minMaxIdx(map, &min, &max);
cv::Mat adjMap; cv::Mat adjMap;
// expand your range to 0..255. Similar to histEq();
map.convertTo(adjMap,CV_8UC1, 255 / (max-min), -min);
//return adjMap;
cv::Mat falseColorsMap; cv::Mat falseColorsMap;
applyColorMap(adjMap, falseColorsMap, cv::COLORMAP_HOT);
switch (classes)
{
case 15:
map.convertTo(adjMap,CV_8UC1);
falseColorsMap = mapillary_15_map(adjMap);
break;
case 20:
map.convertTo(adjMap,CV_8UC1);
falseColorsMap = berkeley_20_map(adjMap);
break;
case 19:
map.convertTo(adjMap,CV_8UC1);
falseColorsMap = cityscapes_19_map(adjMap);
break;
default:
// expand your range to 0..255. Similar to histEq();
map.convertTo(adjMap,CV_8UC1, 255 / (max-min), -min);
applyColorMap(adjMap, falseColorsMap, cv::COLORMAP_JET);
}
return falseColorsMap; return falseColorsMap;
} }
cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int imgdim) { cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int img_h, int img_w, double min, double max, int classes) {
dnnType *data = nullptr; dnnType *data = nullptr;
// copy to CPU // copy to CPU
@@ -38,14 +404,13 @@ cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int imgdim) {
cv::Mat grid = cv::Mat(gridSize, CV_8UC3, cv::Scalar(0)); cv::Mat grid = cv::Mat(gridSize, CV_8UC3, cv::Scalar(0));
for(int i=0; i<dim.c;i++) { for(int i=0; i<dim.c;i++) {
cv::Mat raw = vizFloat2colorMap(cv::Mat(cv::Size(dim.w, dim.h),CV_32FC1, data + dim.w*dim.h*i)); cv::Mat raw = vizFloat2colorMap(cv::Mat(cv::Size(dim.w, dim.h),CV_32FC1, data + dim.w*dim.h*i), min, max, classes);
int r = i / gridDim; int r = i / gridDim;
int c = i - r * gridDim; int c = i - r * gridDim;
raw.copyTo(grid.rowRange(r*dim.h, r*dim.h + dim.h).colRange(c*dim.w, c*dim.w + dim.w)); raw.copyTo(grid.rowRange(r*dim.h, r*dim.h + dim.h).colRange(c*dim.w, c*dim.w + dim.w));
} }
float ar = float(dim.w)/dim.h; cv::Size vdim(img_w, img_h);
cv::Size vdim(ar*imgdim, imgdim);
cv::Mat viz; cv::Mat viz;
cv::resize(grid, viz, vdim, 0, 0, 0); cv::resize(grid, viz, vdim, 0, 0, 0);
@@ -59,7 +424,7 @@ cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int imgdim) {
cv::Mat vizLayer2Mat(tk::dnn::Network *net, int layer, int imgdim) { cv::Mat vizLayer2Mat(tk::dnn::Network *net, int layer, int imgdim) {
if(layer >= net->num_layers) if(layer >= net->num_layers)
FatalError("Could not viz layer\n"); FatalError("Could not viz layer\n");
return vizData2Mat(net->layers[layer]->dstData, net->layers[layer]->output_dim, imgdim); return vizData2Mat(net->layers[layer]->dstData, net->layers[layer]->output_dim, imgdim, imgdim);
//cv::imwrite("viz/layer" + std::to_string(layer) + ".png", viz); //cv::imwrite("viz/layer" + std::to_string(layer) + ".png", viz);
//cv::imshow("layer", viz); //cv::imshow("layer", viz);
+5
View File
@@ -15,6 +15,11 @@ Reshape::Reshape(Network *net, dataDim_t new_dim) : Layer(net) {
output_dim.w = new_dim.w; output_dim.w = new_dim.w;
output_dim.l = new_dim.l; output_dim.l = new_dim.l;
output_dim = new_dim;
if(input_dim.tot() != output_dim.tot())
FatalError("Reshape dimension mismatch");
} }
Reshape::~Reshape() { Reshape::~Reshape() {
+39
View File
@@ -0,0 +1,39 @@
#include <iostream>
#include "Layer.h"
#include "kernels.h"
namespace tk { namespace dnn {
Resize::Resize(Network *net, int scale_c, int scale_h, int scale_w, bool fixed, ResizeMode_t mode) : Layer(net) {
this->mode = mode;
if(fixed){
output_dim.c = scale_c;
output_dim.h = scale_h;
output_dim.w = scale_w;
}
else{
output_dim.c *= scale_c;
output_dim.h *= scale_h;
output_dim.w *= scale_w;
}
checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) );
}
Resize::~Resize() {
checkCuda( cudaFree(dstData) );
}
dnnType* Resize::infer(dataDim_t &dim, dnnType* srcData) {
resizeForward(srcData, dstData, dim.n, dim.c, dim.h, dim.w,
output_dim.c, output_dim.h, output_dim.w);
dim = output_dim;
return dstData;
}
}}
+7 -6
View File
@@ -5,15 +5,16 @@
namespace tk { namespace dnn { namespace tk { namespace dnn {
Shortcut::Shortcut(Network *net, Layer *backLayer) : Layer(net) { Shortcut::Shortcut(Network *net, Layer *backLayer, bool mul) : Layer(net) {
this->backLayer = backLayer; this->backLayer = backLayer;
this->mul = mul;
checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) ); checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) );
if( /*backLayer->output_dim.c != input_dim.c ||*/ if( ( backLayer->output_dim.c != input_dim.c && mul ) ||
backLayer->output_dim.w != input_dim.w || (( backLayer->output_dim.w != input_dim.w || backLayer->output_dim.h != input_dim.h ) && !mul ) )
backLayer->output_dim.h != input_dim.h ) FatalError("Shortcut dim missmatch");
FatalError("Shortcut dim mismatch");
} }
Shortcut::~Shortcut() { Shortcut::~Shortcut() {
@@ -26,7 +27,7 @@ dnnType* Shortcut::infer(dataDim_t &dim, dnnType* srcData) {
dataDim_t bdim = this->backLayer->output_dim; dataDim_t bdim = this->backLayer->output_dim;
checkCuda(cudaMemcpy(dstData, srcData, dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToDevice)); checkCuda(cudaMemcpy(dstData, srcData, dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToDevice));
shortcutForward(this->backLayer->dstData, dstData, dim.n, dim.c, dim.h, dim.w, 1, bdim.n, bdim.c, bdim.h, bdim.w, 1); shortcutForward(this->backLayer->dstData, dstData, dim.n, dim.c, dim.h, dim.w, 1, bdim.n, bdim.c, bdim.h, bdim.w, 1, mul);
//update data dimensions //update data dimensions
dim = output_dim; dim = output_dim;
+60 -18
View File
@@ -9,9 +9,10 @@
#include "Layer.h" #include "Layer.h"
#include "kernels.h" #include "kernels.h"
namespace tk { namespace dnn { namespace tk { namespace dnn {
Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights, int n_masks, float scale_xy) : Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights, int n_masks, float scale_xy, double nms_thresh, nmsKind_t nsm_kind, int new_coords) :
Layer(net) { Layer(net) {
this->final = true; this->final = true;
@@ -19,6 +20,9 @@ Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights, int n_
this->num = num; this->num = num;
this->n_masks = n_masks; this->n_masks = n_masks;
this->scaleXY = scale_xy; this->scaleXY = scale_xy;
this->nms_thresh = nms_thresh;
this->nsm_kind = nsm_kind;
this->new_coords = new_coords;
// load anchors // load anchors
if(fname_weights != "") { if(fname_weights != "") {
@@ -59,12 +63,21 @@ int entry_index(int batch, int location, int entry,
entry*input_dim.w*input_dim.h + loc; entry*input_dim.w*input_dim.h + loc;
} }
Yolo::box get_yolo_box(float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, int stride) { Yolo::box get_yolo_box(float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, int stride, int new_coords) {
Yolo::box b; Yolo::box b;
b.x = (i + x[index + 0*stride]) / lw;
b.y = (j + x[index + 1*stride]) / lh; if(new_coords == 0){
b.w = exp(x[index + 2*stride]) * biases[2*n] / w; b.x = (i + x[index + 0*stride]) / lw;
b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h; b.y = (j + x[index + 1*stride]) / lh;
b.w = exp(x[index + 2*stride]) * biases[2*n] / w;
b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h;
}
else{
b.x = (i + x[index + 0 * stride] ) / lw;
b.y = (j + x[index + 1 * stride] ) / lh;
b.w = x[index + 2 * stride] * x[index + 2 * stride] * 4 * biases[2 * n] / w;
b.h = x[index + 3 * stride] * x[index + 3 * stride] * 4 * biases[2 * n + 1] / h;
}
return b; return b;
} }
@@ -75,12 +88,16 @@ dnnType* Yolo::infer(dataDim_t &dim, dnnType* srcData) {
for (int b = 0; b < dim.n; ++b){ for (int b = 0; b < dim.n; ++b){
for(int n = 0; n < n_masks; ++n){ for(int n = 0; n < n_masks; ++n){
int index = entry_index(b, n*dim.w*dim.h, 0, classes, input_dim, output_dim); int index = entry_index(b, n*dim.w*dim.h, 0, classes, input_dim, output_dim);
activationLOGISTICForward(srcData + index, dstData + index, 2*dim.w*dim.h); if (new_coords == 1){
if (this->scaleXY != 1) scalAdd(dstData + index, 2 * dim.w*dim.h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
}
else{
activationLOGISTICForward(srcData + index, dstData + index, 2*dim.w*dim.h);
if (this->scaleXY != 1) scalAdd(dstData + index, 2 * dim.w*dim.h, this->scaleXY, -0.5*(this->scaleXY - 1), 1); if (this->scaleXY != 1) scalAdd(dstData + index, 2 * dim.w*dim.h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
index = entry_index(b, n*dim.w*dim.h, 4, classes, input_dim, output_dim);
index = entry_index(b, n*dim.w*dim.h, 4, classes, input_dim, output_dim); activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*dim.w*dim.h);
activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*dim.w*dim.h); }
} }
} }
@@ -116,7 +133,7 @@ void correct_yolo_boxes(Yolo::detection *dets, int n, int w, int h, int netw, in
} }
} }
int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh) { int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh, int new_coords) {
if(predictions == nullptr) if(predictions == nullptr)
predictions = new dnnType[output_dim.tot()]; predictions = new dnnType[output_dim.tot()];
@@ -140,7 +157,7 @@ int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int netw, int net
if(objectness <= thresh) continue; if(objectness <= thresh) continue;
int box_index = entry_index(0, n*lw*lh + i, 0, classes, input_dim, output_dim); int box_index = entry_index(0, n*lw*lh + i, 0, classes, input_dim, output_dim);
dets[count].bbox = get_yolo_box(predictions, bias_h, mask_h[n], box_index, col, row, lw, lh, netw, neth, lw*lh); dets[count].bbox = get_yolo_box(predictions, bias_h, mask_h[n], box_index, col, row, lw, lh, netw, neth, lw*lh, new_coords);
dets[count].objectness = objectness; dets[count].objectness = objectness;
dets[count].classes = classes; dets[count].classes = classes;
for(j = 0; j < classes; ++j){ for(j = 0; j < classes; ++j){
@@ -193,6 +210,32 @@ float yolo_box_iou(Yolo::box a, Yolo::box b)
return yolo_box_intersection(a, b)/yolo_box_union(a, b); return yolo_box_intersection(a, b)/yolo_box_union(a, b);
} }
void box_c(const Yolo::box a, const Yolo::box b, float& top, float& bot, float& left, float& right) {
top = (std::min)(a.y - a.h / 2, b.y - b.h / 2);
bot = (std::max)(a.y + a.h / 2, b.y + b.h / 2);
left = (std::min)(a.x - a.w / 2, b.x - b.w / 2);
right = (std::max)(a.x + a.w / 2, b.x + b.w / 2);
}
// https://github.com/Zzh-tju/DIoU-darknet
// https://arxiv.org/abs/1911.08287
float yolo_box_diou(const Yolo::box a, const Yolo::box b, const float nms_thresh=0.6)
{
float top, bot, left, right;
box_c(a, b, top, bot, left, right);
float w = right - left;
float h = bot - top;
float c = w * w + h * h;
float iou = yolo_box_iou(a, b);
if (c == 0)
return iou;
float d = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
float u = pow(d / c, nms_thresh);
float diou_term = u;
return iou - diou_term;
}
int yolo_nms_comparator(const void *pa, const void *pb) int yolo_nms_comparator(const void *pa, const void *pb)
{ {
Yolo::detection a = *(Yolo::detection *)pa; Yolo::detection a = *(Yolo::detection *)pa;
@@ -219,8 +262,7 @@ Yolo::detection *Yolo::allocateDetections(int nboxes, int classes) {
return dets; return dets;
} }
void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes) { void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes, double nms_thresh, nmsKind_t nsm_kind) {
double nms_thresh = 0.45;
int total = ndets; int total = ndets;
int i, j, k; int i, j, k;
@@ -246,13 +288,13 @@ void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes) {
box a = dets[i].bbox; box a = dets[i].bbox;
for(j = i+1; j < total; ++j){ for(j = i+1; j < total; ++j){
box b = dets[j].bbox; box b = dets[j].bbox;
if (yolo_box_iou(a, b) > nms_thresh){ if (nsm_kind == GREEDY_NMS && yolo_box_iou(a, b) > nms_thresh)
dets[j].prob[k] = 0;
else if (nsm_kind == DIOU_NMS && yolo_box_diou(a, b, nms_thresh) > nms_thresh)
dets[j].prob[k] = 0; dets[j].prob[k] = 0;
}
} }
} }
} }
} }
}} }}
+8 -4
View File
@@ -32,6 +32,9 @@ bool Yolo3Detection::init(const std::string& tensor_path, const int n_classes, c
memcpy(yolo[i]->bias_h, yRT->bias, sizeof(dnnType)*num*nMasks*2); memcpy(yolo[i]->bias_h, yRT->bias, sizeof(dnnType)*num*nMasks*2);
yolo[i]->input_dim = yolo[i]->output_dim = tk::dnn::dataDim_t(1, yRT->c, yRT->h, yRT->w); yolo[i]->input_dim = yolo[i]->output_dim = tk::dnn::dataDim_t(1, yRT->c, yRT->h, yRT->w);
yolo[i]->classesNames = yRT->classesNames; yolo[i]->classesNames = yRT->classesNames;
yolo[i]->nms_thresh = yRT->nms_thresh;
yolo[i]->nsm_kind = (tk::dnn::Yolo::nmsKind_t) yRT->nms_kind;
yolo[i]->new_coords = yRT->new_coords;
} }
dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes); dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes);
@@ -91,9 +94,10 @@ void Yolo3Detection::preprocess(cv::Mat &frame, const int bi){
void Yolo3Detection::postprocess(const int bi, const bool mAP){ void Yolo3Detection::postprocess(const int bi, const bool mAP){
//get yolo outputs //get yolo outputs
dnnType *rt_out[netRT->pluginFactory->n_yolos]; std::vector<float *> rt_out;
//dnnType *rt_out[netRT->pluginFactory->n_yolos];
for(int i=0; i<netRT->pluginFactory->n_yolos; i++) for(int i=0; i<netRT->pluginFactory->n_yolos; i++)
rt_out[i] = (dnnType*)netRT->buffersRT[i+1] + netRT->buffersDIM[i+1].tot()*bi; rt_out.push_back((dnnType*)netRT->buffersRT[i+1] + netRT->buffersDIM[i+1].tot()*bi);
float x_ratio = float(originalSize[bi].width) / float(netRT->input_dim.w); float x_ratio = float(originalSize[bi].width) / float(netRT->input_dim.w);
float y_ratio = float(originalSize[bi].height) / float(netRT->input_dim.h); float y_ratio = float(originalSize[bi].height) / float(netRT->input_dim.h);
@@ -102,9 +106,9 @@ void Yolo3Detection::postprocess(const int bi, const bool mAP){
nDets = 0; nDets = 0;
for(int i=0; i<netRT->pluginFactory->n_yolos; i++) { for(int i=0; i<netRT->pluginFactory->n_yolos; i++) {
yolo[i]->dstData = rt_out[i]; yolo[i]->dstData = rt_out[i];
yolo[i]->computeDetections(dets, nDets, netRT->input_dim.w, netRT->input_dim.h, confThreshold); yolo[i]->computeDetections(dets, nDets, netRT->input_dim.w, netRT->input_dim.h, confThreshold, yolo[i]->new_coords);
} }
tk::dnn::Yolo::mergeDetections(dets, nDets, classes); tk::dnn::Yolo::mergeDetections(dets, nDets, classes, yolo[0]->nms_thresh, yolo[0]->nsm_kind);
// fill detected // fill detected
detected.clear(); detected.clear();
+4 -4
View File
@@ -1,7 +1,7 @@
#include "kernels.h" #include "kernels.h"
__global__ __global__
void activation_leaky(dnnType *input, dnnType *output, int size) { void activation_leaky(dnnType *input, dnnType *output, int size, float slope) {
int i = blockDim.x*blockIdx.x + threadIdx.x; int i = blockDim.x*blockIdx.x + threadIdx.x;
@@ -9,7 +9,7 @@ void activation_leaky(dnnType *input, dnnType *output, int size) {
if (input[i]>0) if (input[i]>0)
output[i] = input[i]; output[i] = input[i];
else else
output[i] = 0.1f*input[i]; output[i] = slope*input[i];
} }
} }
@@ -17,12 +17,12 @@ void activation_leaky(dnnType *input, dnnType *output, int size) {
/** /**
ELU activation function ELU activation function
*/ */
void activationLEAKYForward(dnnType* srcData, dnnType* dstData, int size, cudaStream_t stream) void activationLEAKYForward(dnnType* srcData, dnnType* dstData, int size, float slope, cudaStream_t stream)
{ {
int blocks = (size+255)/256; int blocks = (size+255)/256;
int threads = 256; int threads = 256;
activation_leaky<<<blocks, threads, 0, stream>>>(srcData, dstData, size); activation_leaky<<<blocks, threads, 0, stream>>>(srcData, dstData, size, slope);
} }
+1 -1
View File
@@ -18,7 +18,7 @@ inline int GET_BLOCKS(const int N)
} }
__device__ float dmcn_im2col_bilinear(const float *bottom_data, const int data_width, __device__ __host__ float dmcn_im2col_bilinear(const float *bottom_data, const int data_width,
const int height, const int width, float h, float w) { const int height, const int width, float h, float w) {
int h_low = floor(h); int h_low = floor(h);
int w_low = floor(w); int w_low = floor(w);
+19
View File
@@ -34,6 +34,25 @@ void sortAndTopKonDevice(dnnType *src_begin, int *idsrc, float *topk_scores, int
sortAndTopK_kernel<<<blocks, threads, 0>>>(src_begin, idsrc, topk_scores, topk_inds, topk_ys, topk_xs, size, K); sortAndTopK_kernel<<<blocks, threads, 0>>>(src_begin, idsrc, topk_scores, topk_inds, topk_ys, topk_xs, size, K);
} }
__global__
void maxElem_kernel(float *src_begin, float *dst_begin, const int n_classes, const int size){
int i = blockDim.x*blockIdx.x + threadIdx.x;
if (i > size)
return;
thrust::device_ptr<float> dPbeg ( &src_begin[i*n_classes] ) ;
thrust::device_ptr<float> dPend = dPbeg + n_classes;
thrust::device_ptr<float> result = thrust::max_element(thrust::device,dPbeg, dPend);
dst_begin[i] = result - dPbeg;
}
void maxElem(dnnType *src_begin, dnnType *dst_begin, const int c, const int h, const int w){
int blocks = (h*w)/32+1;
int threads = 32;
maxElem_kernel<<<blocks, threads, 0>>>(src_begin, dst_begin, c, h*w);
}
void topKxyclasses(int *ids_begin, int *ids_end, const int K, const int size, const int wh, int *clses, int *xs, int *ys){ void topKxyclasses(int *ids_begin, int *ids_end, const int K, const int size, const int wh, int *clses, int *xs, int *ys){
thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(wh), clses, thrust::divides<int>()); thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(wh), clses, thrust::divides<int>());
thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(wh), ids_begin, thrust::modulus<int>()); thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(wh), ids_begin, thrust::modulus<int>());
+14 -27
View File
@@ -1,46 +1,33 @@
#include "kernels.h" #include "kernels.h"
#include <stdio.h> #include <stdio.h>
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
__global__ void resize_kernel( int i_N,float *x, int i_w, int i_h, int i_c, __global__ void resize_kernel( int size,float *x, int i_w, int i_h, int i_c,
int o_w, int o_h, int o_c, int batch, float *out) int o_w, int o_h, int o_c, int batch, float *out)
{ {
int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
if(i >= i_N) return; if(id >= size) return;
int out_index = i; int i = id % o_w;
int out_w = i%o_w; id /= o_w;
i = i/o_w; int j = id % o_h;
int out_h = i%o_h; id /= o_h;
i = i/o_h; int k = id % o_c;
int out_c = i%o_c; id /= o_c;
i = i/o_c; int b = id % batch;
//copying last column/last row as padding int out_index = i + o_w*(j + o_h*(k + o_c*b));
int in_index = ((i*i_c + MIN(out_c,i_c-1))*i_h + MIN(out_h,i_h-1))*i_w + MIN(out_w, i_w-1); int add_index = i/(o_w/i_w) + i_w*(j/(o_h/i_h) + i_h*(k + i_c*b));
out[out_index] = x[in_index]; out[out_index] = x[add_index];
} }
void resizeForward( dnnType* srcData, dnnType* dstData, int n, int i_c, int i_h, int i_w, void resizeForward( dnnType* srcData, dnnType* dstData, int n, int i_c, int i_h, int i_w,
int o_c, int o_h, int o_w, cudaStream_t stream ) int o_c, int o_h, int o_w, cudaStream_t stream )
{ {
int i_size = n*i_c*i_h*i_w;
int o_size = n*o_c*o_h*o_w; int o_size = n*o_c*o_h*o_w;
int blocks = (o_size+255)/256; int blocks = (o_size+255)/256;
int threads = 256; int threads = 256;
if(i_c == o_c && i_h == o_h && i_w == o_w ) resize_kernel<<<blocks, threads, 0, stream>>>(o_size, srcData, i_w, i_h, i_c, o_w, o_h, o_c, n, dstData);
{
checkCuda(cudaMemcpy(dstData, srcData, i_size*sizeof(dnnType), cudaMemcpyDeviceToDevice));
}
else
{
checkCuda(cudaMemset(dstData, 0, o_size*sizeof(dnnType)));
resize_kernel<<<blocks, threads, 0, stream>>>(o_size, srcData, i_w, i_h, i_c, o_w, o_h, o_c, n, dstData);
// printDeviceVector(i_size, srcData);
// printDeviceVector(o_size, dstData);
}
} }
+48 -15
View File
@@ -21,27 +21,60 @@ __global__ void shortcut_kernel(int size, int minw, int minh, int minc, int stri
//out[out_index] += add[add_index]; //out[out_index] += add[add_index];
} }
__global__ void shortcut_mul_kernel(int size, int minw, int minh, int minc, int sample, int batch,
int w1, int h1, int c1, dnnType *mul,
int w2, int h2, int c2, float s1, float s2, dnnType *out)
{
int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
if (id >= size) return;
int i = id % minw;
id /= minw;
int j = id % minh;
id /= minh;
int k = id % minc;
id /= minc;
int b = id % batch;
int out_index = i*sample + w1*(j*sample + h1*(k + c1*b));
out[out_index] = out[out_index] * mul[k + c2*b];
}
void shortcutForward(dnnType* srcData, dnnType* dstData, int n1, int c1, int h1, int w1, int s1, void shortcutForward(dnnType* srcData, dnnType* dstData, int n1, int c1, int h1, int w1, int s1,
int n2, int c2, int h2, int w2, int s2, int n2, int c2, int h2, int w2, int s2,
cudaStream_t stream) bool mul, cudaStream_t stream)
{ {
assert(n1 == n2); assert(n1 == n2);
int batch = n1; int batch = n1;
int minw = (w1 < w2) ? w1 : w2; if(!mul){
int minh = (h1 < h2) ? h1 : h2; int minw = (w1 < w2) ? w1 : w2;
int minc = (c1 < c2) ? c1 : c2; int minh = (h1 < h2) ? h1 : h2;
int minc = (c1 < c2) ? c1 : c2;
int stride = w1/w2;
int sample = w2/w1;
assert(stride == h1/h2);
assert(sample == h2/h1);
if(stride < 1) stride = 1;
if(sample < 1) sample = 1;
int stride = w1/w2; int size = batch * minw * minh * minc;
int sample = w2/w1; int blocks = (size+255)/256;
assert(stride == h1/h2); int threads = 256;
assert(sample == h2/h1);
if(stride < 1) stride = 1;
if(sample < 1) sample = 1;
int size = batch * minw * minh * minc; shortcut_kernel<<<blocks, threads, 0, stream>>>(size, minw, minh, minc, stride, sample, batch,
int blocks = (size+255)/256; w1, h1, c1, srcData, w2, h2, c2, s1, s2, dstData);
int threads = 256; }
shortcut_kernel<<<blocks, threads, 0, stream>>>(size, minw, minh, minc, stride, sample, batch, else{
w1, h1, c1, srcData, w2, h2, c2, s1, s2, dstData); int minw = w1;
int minh = h1;
int minc = c1;
int sample = 1;
int size = batch * minw * minh * minc;
int blocks = (size+255)/256;
int threads = 256;
shortcut_mul_kernel<<<blocks, threads, 0, stream>>>(size, minw, minh, minc, sample, batch,
w1, h1, c1, srcData, w2, h2, c2, s1, s2, dstData);
}
} }
+16 -2
View File
@@ -23,14 +23,23 @@ bool fileExist(const char *fname) {
void downloadWeightsifDoNotExist(const std::string& input_bin, const std::string& test_folder, const std::string& weights_url){ void downloadWeightsifDoNotExist(const std::string& input_bin, const std::string& test_folder, const std::string& weights_url){
if(!fileExist(input_bin.c_str())){ if(!fileExist(input_bin.c_str())){
std::string mkdir_cmd = "mkdir " + test_folder; std::string mkdir_cmd = "mkdir " + test_folder;
std::string wget_cmd = "wget " + weights_url + " -O " + test_folder + "/weights.zip"; std::string wget_cmd = "curl " + weights_url + " --output " + test_folder + "/weights.zip";
#ifdef __linux__
std::string unzip_cmd = "unzip " + test_folder + "/weights.zip -d" + test_folder; std::string unzip_cmd = "unzip " + test_folder + "/weights.zip -d" + test_folder;
std::string rm_cmd = "rm " + test_folder + "/weights.zip"; std::string rm_cmd = "rm " + test_folder + "/weights.zip";
#elif _WIN32
std::string unzip_cmd = "7z x " + test_folder + "/weights.zip -o" + test_folder;
#endif
int err = 0; int err = 0;
err = system(mkdir_cmd.c_str()); err = system(mkdir_cmd.c_str());
err = system(wget_cmd.c_str()); err = system(wget_cmd.c_str());
err = system(unzip_cmd.c_str()); err = system(unzip_cmd.c_str());
#ifdef __linux__
err = system(rm_cmd.c_str()); err = system(rm_cmd.c_str());
#endif
} }
} }
@@ -102,6 +111,7 @@ int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device, int
} }
int diffs = 0; int diffs = 0;
for(int i=0; i<size; i++) { for(int i=0; i<size; i++) {
// data_h[i] = data_h[i]*1e-2;
if(data_h[i] != data_h[i] || correct_h[i] != correct_h[i] || //nan control if(data_h[i] != data_h[i] || correct_h[i] != correct_h[i] || //nan control
fabs(data_h[i] - correct_h[i]) > eps) { fabs(data_h[i] - correct_h[i]) > eps) {
diffs += 1; diffs += 1;
@@ -193,8 +203,12 @@ void getMemUsage(double& vm_usage_kb, double& resident_set_kb){
>> O >> itrealvalue >> starttime >> vsize >> rss; >> O >> itrealvalue >> starttime >> vsize >> rss;
stat_stream.close(); stat_stream.close();
#ifdef __linux__
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
#elif _WIN32
long page_size_kb = 4096/1024;
#endif
vm_usage_kb = vsize / 1024.0; vm_usage_kb = vsize / 1024.0;
resident_set_kb = rss * page_size_kb; resident_set_kb = rss * page_size_kb;
} }
File diff suppressed because it is too large Load Diff
@@ -1,12 +1,11 @@
[net] [net]
# Testing
batch=1 batch=1
subdivisions=1 subdivisions=1
# Training # Training
#batch=64 width=512
#subdivisions=8 height=512
width=416 # width=608
height=416 # height=608
channels=3 channels=3
momentum=0.949 momentum=0.949
decay=0.0005 decay=0.0005
@@ -15,11 +14,11 @@ saturation = 1.5
exposure = 1.5 exposure = 1.5
hue=.1 hue=.1
learning_rate=0.00261 learning_rate=0.0013
burn_in=1000 burn_in=1000
max_batches = 500500 max_batches = 16000
policy=steps policy=steps
steps=400000,450000 steps=12800,14400
scales=.1,.1 scales=.1,.1
#cutmix=1 #cutmix=1
@@ -959,14 +958,14 @@ activation=leaky
size=1 size=1
stride=1 stride=1
pad=1 pad=1
filters=255 filters=27
activation=linear activation=linear
[yolo] [yolo]
mask = 0,1,2 mask = 0,1,2
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
classes=80 classes=4
num=9 num=9
jitter=.3 jitter=.3
ignore_thresh = .7 ignore_thresh = .7
@@ -978,6 +977,7 @@ iou_normalizer=0.07
iou_loss=ciou iou_loss=ciou
nms_kind=greedynms nms_kind=greedynms
beta_nms=0.6 beta_nms=0.6
max_delta=5
[route] [route]
@@ -1046,14 +1046,14 @@ activation=leaky
size=1 size=1
stride=1 stride=1
pad=1 pad=1
filters=255 filters=27
activation=linear activation=linear
[yolo] [yolo]
mask = 3,4,5 mask = 3,4,5
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
classes=80 classes=4
num=9 num=9
jitter=.3 jitter=.3
ignore_thresh = .7 ignore_thresh = .7
@@ -1065,6 +1065,7 @@ iou_normalizer=0.07
iou_loss=ciou iou_loss=ciou
nms_kind=greedynms nms_kind=greedynms
beta_nms=0.6 beta_nms=0.6
max_delta=5
[route] [route]
@@ -1133,14 +1134,14 @@ activation=leaky
size=1 size=1
stride=1 stride=1
pad=1 pad=1
filters=255 filters=27
activation=linear activation=linear
[yolo] [yolo]
mask = 6,7,8 mask = 6,7,8
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
classes=80 classes=4
num=9 num=9
jitter=.3 jitter=.3
ignore_thresh = .7 ignore_thresh = .7
@@ -1153,4 +1154,5 @@ iou_normalizer=0.07
iou_loss=ciou iou_loss=ciou
nms_kind=greedynms nms_kind=greedynms
beta_nms=0.6 beta_nms=0.6
max_delta=5
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
blue-cone
yellow-cone
orange-cone
big-orange-cone
+34
View File
@@ -0,0 +1,34 @@
#include<iostream>
#include<vector>
#include "tkdnn.h"
#include "test.h"
#include "DarknetParser.h"
int main() {
std::string bin_path = "yolo4-csp";
std::vector<std::string> input_bins = {
bin_path + "/layers/input.bin"
};
std::vector<std::string> output_bins = {
bin_path + "/debug/layer144_out.bin",
bin_path + "/debug/layer159_out.bin",
bin_path + "/debug/layer174_out.bin"
};
std::string wgs_path = bin_path + "/layers";
std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo4-csp.cfg";
std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names";
downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/AfzHE4BfTeEm2gH/download");
// parse darknet network
tk::dnn::Network *net = tk::dnn::darknetParser(cfg_path, wgs_path, name_path);
net->print();
//convert network to tensorRT
tk::dnn::NetworkRT *netRT = new tk::dnn::NetworkRT(net, net->getNetworkRTName(bin_path.c_str()));
int ret = testInference(input_bins, output_bins, net, netRT);
net->releaseLayers();
delete net;
delete netRT;
return ret;
}
@@ -5,7 +5,7 @@
#include "DarknetParser.h" #include "DarknetParser.h"
int main() { int main() {
std::string bin_path = "yolo4_416"; std::string bin_path = "yolo4_mmr";
std::vector<std::string> input_bins = { std::vector<std::string> input_bins = {
bin_path + "/layers/input.bin" bin_path + "/layers/input.bin"
}; };
@@ -15,9 +15,9 @@ int main() {
bin_path + "/debug/layer161_out.bin" bin_path + "/debug/layer161_out.bin"
}; };
std::string wgs_path = bin_path + "/layers"; std::string wgs_path = bin_path + "/layers";
std::string cfg_path = "../tests/darknet/cfg/yolo4_416.cfg"; std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo4_mmr.cfg";
std::string name_path = "../tests/darknet/names/coco.names"; std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/mmr.names";
downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/982LxTQcNQfFQc4/download"); // downloadWeightsifDoNotExist(input_bins[0], bin_path, "");
// parse darknet network // parse darknet network
tk::dnn::Network *net = tk::dnn::darknetParser(cfg_path, wgs_path, name_path); tk::dnn::Network *net = tk::dnn::darknetParser(cfg_path, wgs_path, name_path);
+36
View File
@@ -0,0 +1,36 @@
#include<iostream>
#include<vector>
#include "tkdnn.h"
#include "test.h"
#include "DarknetParser.h"
int main() {
std::string bin_path = "yolo4x";
std::vector<std::string> input_bins = {
bin_path + "/layers/input.bin"
};
std::vector<std::string> output_bins = {
bin_path + "/debug/layer168_out.bin",
bin_path + "/debug/layer185_out.bin",
bin_path + "/debug/layer202_out.bin"
};
std::string wgs_path = bin_path + "/layers";
std::string cfg_path = std::string(TKDNN_PATH) + "/tests/darknet/cfg/yolo4x.cfg";
std::string name_path = std::string(TKDNN_PATH) + "/tests/darknet/names/coco.names";
downloadWeightsifDoNotExist(input_bins[0], bin_path, "https://cloud.hipert.unimore.it/s/5MFjtNtgbDGdJEo/download");
// parse darknet network
tk::dnn::Network *net = tk::dnn::darknetParser(cfg_path, wgs_path, name_path);
net->print();
//convert network to tensorRT
tk::dnn::NetworkRT *netRT = new tk::dnn::NetworkRT(net, net->getNetworkRTName(bin_path.c_str()));
int ret = testInference(input_bins, output_bins, net, netRT);
net->releaseLayers();
delete net;
delete netRT;
return ret;
}
+295
View File
@@ -0,0 +1,295 @@
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "tkdnn.h"
#include "NetworkViz.h"
const char *input_bin = "shelfnet/debug/input.bin";
const char *backbone[] = {
"shelfnet/layers/backbone-conv1.bin",
"shelfnet/layers/backbone-layer1-0-conv1.bin",
"shelfnet/layers/backbone-layer1-0-conv2.bin",
"shelfnet/layers/backbone-layer1-1-conv1.bin",
"shelfnet/layers/backbone-layer1-1-conv2.bin",
"shelfnet/layers/backbone-layer2-0-conv1.bin",
"shelfnet/layers/backbone-layer2-0-conv2.bin",
"shelfnet/layers/backbone-layer2-0-downsample-0.bin",
"shelfnet/layers/backbone-layer2-1-conv1.bin",
"shelfnet/layers/backbone-layer2-1-conv2.bin",
"shelfnet/layers/backbone-layer3-0-conv1.bin",
"shelfnet/layers/backbone-layer3-0-conv2.bin",
"shelfnet/layers/backbone-layer3-0-downsample-0.bin",
"shelfnet/layers/backbone-layer3-1-conv1.bin",
"shelfnet/layers/backbone-layer3-1-conv2.bin",
"shelfnet/layers/backbone-layer4-0-conv1.bin",
"shelfnet/layers/backbone-layer4-0-conv2.bin",
"shelfnet/layers/backbone-layer4-0-downsample-0.bin",
"shelfnet/layers/backbone-layer4-1-conv1.bin",
"shelfnet/layers/backbone-layer4-1-conv2.bin"};
const char *conv_out[] = {
"shelfnet/layers/conv_out-conv-conv.bin",
"shelfnet/layers/conv_out-conv_out.bin",
"shelfnet/layers/conv_out16-conv-conv.bin",
"shelfnet/layers/conv_out16-conv_out.bin",
"shelfnet/layers/conv_out32-conv-conv.bin",
"shelfnet/layers/conv_out32-conv_out.bin"
};
const char *decoder[] = {
"shelfnet/layers/decoder-bottom-conv1.bin",
"shelfnet/layers/decoder-bottom-conv12.bin",
"shelfnet/layers/decoder-up_conv_list-0-conv-conv.bin",
"shelfnet/layers/decoder-up_conv_list-0-conv_atten.bin",
"shelfnet/layers/decoder-up_dense_list-0-conv.bin",
"shelfnet/layers/decoder-up_conv_list-1-conv-conv.bin",
"shelfnet/layers/decoder-up_conv_list-1-conv_atten.bin",
"shelfnet/layers/decoder-up_dense_list-1-conv.bin"
};
const char *ladder[] = {
"shelfnet/layers/ladder-inconv-conv1.bin",
"shelfnet/layers/ladder-inconv-conv12.bin",
"shelfnet/layers/ladder-down_module_list-0-conv1.bin",
"shelfnet/layers/ladder-down_module_list-0-conv12.bin",
"shelfnet/layers/ladder-down_conv_list-0.bin",
"shelfnet/layers/ladder-down_module_list-1-conv1.bin",
"shelfnet/layers/ladder-down_module_list-1-conv12.bin",
"shelfnet/layers/ladder-down_conv_list-1.bin",
"shelfnet/layers/ladder-bottom-conv1.bin",
"shelfnet/layers/ladder-bottom-conv12.bin",
"shelfnet/layers/ladder-up_conv_list-0-conv-conv.bin",
"shelfnet/layers/ladder-up_conv_list-0-conv_atten.bin",
"shelfnet/layers/ladder-up_dense_list-0-conv.bin",
"shelfnet/layers/ladder-up_conv_list-1-conv-conv.bin",
"shelfnet/layers/ladder-up_conv_list-1-conv_atten.bin",
"shelfnet/layers/ladder-up_dense_list-1-conv.bin"};
const char *trans[] = {
"shelfnet/layers/trans1-conv.bin",
"shelfnet/layers/trans2-conv.bin",
"shelfnet/layers/trans3-conv.bin"};
int main()
{
downloadWeightsifDoNotExist(input_bin, "shelfnet", "https://cloud.hipert.unimore.it/s/mEDZMRJaGCFWSJF/download");
int classes = 19;
// Network layout
tk::dnn::dataDim_t dim(1, 3, 1024, 1024, 1);
tk::dnn::Network net(dim);
int bi = 0, di = 0, li = 0, ci = 0;
new tk::dnn::Conv2d(&net, 64, 7, 7, 2, 2, 3, 3, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
tk::dnn::Layer* last = new tk::dnn::Pooling (&net, 3, 3, 2, 2, 1, 1, tk::dnn::POOLING_MAX);
for(int i=0; i<2; ++i){
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
}
std::vector<tk::dnn::Layer*> features;
for(int i=0;i<3;++i){
int out_channel = pow(2,7+i);
std::cout<<out_channel<<std::endl;
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 2, 2, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
tk::dnn::Layer* bn2 = new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 2, 2, 0, 0, backbone[bi++], true);
new tk::dnn::Shortcut(&net, bn2);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
features.push_back(last);
}
for(int i=0; i<features.size(); ++i){
new tk::dnn::Route(&net, &features[i], 1);
int out_channel = pow(2,6+i);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, trans[i], true);
features[i] = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
}
//DECODER
last = features[2];
std::vector<tk::dnn::Layer*> up_out;
//bottom
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, decoder[di++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, decoder[di++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
up_out.push_back(last);
for(int i=0; i<2; ++i){
int out_channel = pow(2,7-i);
//up-conv
std::cout<<out_channel<<std::endl;
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, decoder[di++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Pooling(&net, last->output_dim.w, last->output_dim.h, last->output_dim.w, last->output_dim.h, 0, 0, tk::dnn::POOLING_AVERAGE);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, decoder[di++], true);
tk::dnn::Layer* act = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_SIGMOID);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Shortcut(&net, act, true);
//interpolate
new tk::dnn::Resize(&net, 1,2,2);
new tk::dnn::Shortcut(&net, features[1-i]);
//up-dense
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, decoder[di++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
up_out.push_back(last);
}
//LADDER
std::vector<tk::dnn::Layer*> down_out;
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
for(int i=0; i<2;++i){
int out_channel = pow(2,6+i);
tk::dnn::Layer* l_last = new tk::dnn::Shortcut(&net, up_out[2-i]);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, l_last);
l_last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
down_out.push_back(l_last);
new tk::dnn::Conv2d (&net, out_channel*2, 3, 3, 2, 2, 1, 1, ladder[li++], false);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.0f); //should be ReLU
}
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
up_out.clear();
up_out.push_back(last);
for(int i=0; i<2; ++i){
int out_channel = pow(2,7-i);
//up-conv
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Pooling(&net, last->output_dim.w, last->output_dim.h, last->output_dim.w, last->output_dim.h, 0, 0, tk::dnn::POOLING_AVERAGE);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, ladder[li++], true);
tk::dnn::Layer* act = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_SIGMOID);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Shortcut(&net, act, true);
//interpolate
new tk::dnn::Resize(&net, 1,2,2);
new tk::dnn::Shortcut(&net, down_out[1-i]);
// //up-dense
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
up_out.push_back(last);
}
// for(int i=2;i>=0;--i){
// new tk::dnn::Route(&net, &up_out[i], 1);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, conv_out[ci++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 19, 3, 3, 1, 1, 1, 1, conv_out[ci++], false);
/*up_out[i] =*/ new tk::dnn::Resize(&net, 19, net.input_dim.h, net.input_dim.w, true, tk::dnn::ResizeMode_t::LINEAR);
// }
new tk::dnn::Softmax(&net);
const char *output_bin = "shelfnet/debug/softmax.bin";
// Load input
dnnType *data;
dnnType *input_h;
readBinaryFile(input_bin, dim.tot(), &input_h, &data);
std::cout<<"Input:"<<std::endl;
//print network model
net.print();
// // convert network to tensorRT
tk::dnn::NetworkRT netRT(&net, net.getNetworkRTName("shelfnet"));
tk::dnn::dataDim_t dim1 = dim; //input dim
dnnType *cudnn_out = nullptr;
printCenteredTitle(" CUDNN inference ", '=', 30);
{
dim1.print();
TKDNN_TSTART
cudnn_out = net.infer(dim1, data);
TKDNN_TSTOP
dim1.print();
}
tk::dnn::dataDim_t dim2 = dim;
printCenteredTitle(" TENSORRT inference ", '=', 30);
{
dim2.print();
TKDNN_TSTART
netRT.infer(dim2, data);
TKDNN_TSTOP
dim2.print();
}
dnnType *rt_out1 = (dnnType *)netRT.buffersRT[1];
printCenteredTitle(std::string(" CHECK RESULTS ").c_str(), '=', 30);
dnnType *out1, *out1_h;
int odim1 = dim1.tot();
readBinaryFile(output_bin, odim1, &out1_h, &out1);
int ret_cudnn = 0, ret_tensorrt = 0, ret_cudnn_tensorrt = 0;
std::cout << "CUDNN vs correct" << std::endl;
ret_cudnn |= checkResult(odim1, cudnn_out, out1, true, 20) == 0 ? 0 : ERROR_CUDNN;
std::cout << "TRT vs correct" << std::endl;
ret_tensorrt |=checkResult(odim1, rt_out1, out1) == 0 ? 0 : ERROR_TENSORRT;
std::cout << "CUDNN vs TRT " << std::endl;
ret_cudnn_tensorrt |= checkResult(odim1, cudnn_out, rt_out1) == 0 ? 0 : ERROR_CUDNNvsTENSORRT;
cv::Mat viz = vizLayer2Mat(&net, net.num_layers-1);
cv::imwrite("test.png", viz);
return ret_cudnn | ret_tensorrt | ret_cudnn_tensorrt;
}
+295
View File
@@ -0,0 +1,295 @@
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "tkdnn.h"
#include "NetworkViz.h"
const char *input_bin = "shelfnet_berkeley/debug/input.bin";
const char *backbone[] = {
"shelfnet_berkeley/layers/backbone-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer1-0-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer1-0-conv2.bin",
"shelfnet_berkeley/layers/backbone-layer1-1-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer1-1-conv2.bin",
"shelfnet_berkeley/layers/backbone-layer2-0-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer2-0-conv2.bin",
"shelfnet_berkeley/layers/backbone-layer2-0-downsample-0.bin",
"shelfnet_berkeley/layers/backbone-layer2-1-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer2-1-conv2.bin",
"shelfnet_berkeley/layers/backbone-layer3-0-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer3-0-conv2.bin",
"shelfnet_berkeley/layers/backbone-layer3-0-downsample-0.bin",
"shelfnet_berkeley/layers/backbone-layer3-1-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer3-1-conv2.bin",
"shelfnet_berkeley/layers/backbone-layer4-0-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer4-0-conv2.bin",
"shelfnet_berkeley/layers/backbone-layer4-0-downsample-0.bin",
"shelfnet_berkeley/layers/backbone-layer4-1-conv1.bin",
"shelfnet_berkeley/layers/backbone-layer4-1-conv2.bin"};
const char *conv_out[] = {
"shelfnet_berkeley/layers/conv_out-conv-conv.bin",
"shelfnet_berkeley/layers/conv_out-conv_out.bin",
"shelfnet_berkeley/layers/conv_out16-conv-conv.bin",
"shelfnet_berkeley/layers/conv_out16-conv_out.bin",
"shelfnet_berkeley/layers/conv_out32-conv-conv.bin",
"shelfnet_berkeley/layers/conv_out32-conv_out.bin"
};
const char *decoder[] = {
"shelfnet_berkeley/layers/decoder-bottom-conv1.bin",
"shelfnet_berkeley/layers/decoder-bottom-conv12.bin",
"shelfnet_berkeley/layers/decoder-up_conv_list-0-conv-conv.bin",
"shelfnet_berkeley/layers/decoder-up_conv_list-0-conv_atten.bin",
"shelfnet_berkeley/layers/decoder-up_dense_list-0-conv.bin",
"shelfnet_berkeley/layers/decoder-up_conv_list-1-conv-conv.bin",
"shelfnet_berkeley/layers/decoder-up_conv_list-1-conv_atten.bin",
"shelfnet_berkeley/layers/decoder-up_dense_list-1-conv.bin"
};
const char *ladder[] = {
"shelfnet_berkeley/layers/ladder-inconv-conv1.bin",
"shelfnet_berkeley/layers/ladder-inconv-conv12.bin",
"shelfnet_berkeley/layers/ladder-down_module_list-0-conv1.bin",
"shelfnet_berkeley/layers/ladder-down_module_list-0-conv12.bin",
"shelfnet_berkeley/layers/ladder-down_conv_list-0.bin",
"shelfnet_berkeley/layers/ladder-down_module_list-1-conv1.bin",
"shelfnet_berkeley/layers/ladder-down_module_list-1-conv12.bin",
"shelfnet_berkeley/layers/ladder-down_conv_list-1.bin",
"shelfnet_berkeley/layers/ladder-bottom-conv1.bin",
"shelfnet_berkeley/layers/ladder-bottom-conv12.bin",
"shelfnet_berkeley/layers/ladder-up_conv_list-0-conv-conv.bin",
"shelfnet_berkeley/layers/ladder-up_conv_list-0-conv_atten.bin",
"shelfnet_berkeley/layers/ladder-up_dense_list-0-conv.bin",
"shelfnet_berkeley/layers/ladder-up_conv_list-1-conv-conv.bin",
"shelfnet_berkeley/layers/ladder-up_conv_list-1-conv_atten.bin",
"shelfnet_berkeley/layers/ladder-up_dense_list-1-conv.bin"};
const char *trans[] = {
"shelfnet_berkeley/layers/trans1-conv.bin",
"shelfnet_berkeley/layers/trans2-conv.bin",
"shelfnet_berkeley/layers/trans3-conv.bin"};
int main()
{
downloadWeightsifDoNotExist(input_bin, "shelfnet_berkeley", "https://cloud.hipert.unimore.it/s/m92e7QdD9gYMF7f/download");
int classes = 20;
// Network layout
tk::dnn::dataDim_t dim(1, 3, 736, 1280, 1);
tk::dnn::Network net(dim);
int bi = 0, di = 0, li = 0, ci = 0;
new tk::dnn::Conv2d(&net, 64, 7, 7, 2, 2, 3, 3, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
tk::dnn::Layer* last = new tk::dnn::Pooling (&net, 3, 3, 2, 2, 1, 1, tk::dnn::POOLING_MAX);
for(int i=0; i<2; ++i){
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
}
std::vector<tk::dnn::Layer*> features;
for(int i=0;i<3;++i){
int out_channel = pow(2,7+i);
std::cout<<out_channel<<std::endl;
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 2, 2, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
tk::dnn::Layer* bn2 = new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 2, 2, 0, 0, backbone[bi++], true);
new tk::dnn::Shortcut(&net, bn2);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
features.push_back(last);
}
for(int i=0; i<features.size(); ++i){
new tk::dnn::Route(&net, &features[i], 1);
int out_channel = pow(2,6+i);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, trans[i], true);
features[i] = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
}
//DECODER
last = features[2];
std::vector<tk::dnn::Layer*> up_out;
//bottom
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, decoder[di++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, decoder[di++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
up_out.push_back(last);
for(int i=0; i<2; ++i){
int out_channel = pow(2,7-i);
//up-conv
std::cout<<out_channel<<std::endl;
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, decoder[di++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Pooling(&net, last->output_dim.w, last->output_dim.h, last->output_dim.w, last->output_dim.h, 0, 0, tk::dnn::POOLING_AVERAGE);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, decoder[di++], true);
tk::dnn::Layer* act = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_SIGMOID);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Shortcut(&net, act, true);
//interpolate
new tk::dnn::Resize(&net, 1,2,2);
new tk::dnn::Shortcut(&net, features[1-i]);
//up-dense
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, decoder[di++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
up_out.push_back(last);
}
//LADDER
std::vector<tk::dnn::Layer*> down_out;
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
for(int i=0; i<2;++i){
int out_channel = pow(2,6+i);
tk::dnn::Layer* l_last = new tk::dnn::Shortcut(&net, up_out[2-i]);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, l_last);
l_last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
down_out.push_back(l_last);
new tk::dnn::Conv2d (&net, out_channel*2, 3, 3, 2, 2, 1, 1, ladder[li++], false);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.0f); //should be ReLU
}
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
up_out.clear();
up_out.push_back(last);
for(int i=0; i<2; ++i){
int out_channel = pow(2,7-i);
//up-conv
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Pooling(&net, last->output_dim.w, last->output_dim.h, last->output_dim.w, last->output_dim.h, 0, 0, tk::dnn::POOLING_AVERAGE);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, ladder[li++], true);
tk::dnn::Layer* act = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_SIGMOID);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Shortcut(&net, act, true);
//interpolate
new tk::dnn::Resize(&net, 1,2,2);
new tk::dnn::Shortcut(&net, down_out[1-i]);
// //up-dense
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
up_out.push_back(last);
}
// for(int i=2;i>=0;--i){
// new tk::dnn::Route(&net, &up_out[i], 1);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, conv_out[ci++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, classes, 3, 3, 1, 1, 1, 1, conv_out[ci++], false);
/*up_out[i] =*/ new tk::dnn::Resize(&net, classes, net.input_dim.h, net.input_dim.w, true, tk::dnn::ResizeMode_t::LINEAR);
// }
new tk::dnn::Softmax(&net);
const char *output_bin = "shelfnet_berkeley/debug/softmax.bin";
// Load input
dnnType *data;
dnnType *input_h;
readBinaryFile(input_bin, dim.tot(), &input_h, &data);
std::cout<<"Input:"<<std::endl;
//print network model
net.print();
// // convert network to tensorRT
tk::dnn::NetworkRT netRT(&net, net.getNetworkRTName("shelfnet_berkeley"));
tk::dnn::dataDim_t dim1 = dim; //input dim
dnnType *cudnn_out = nullptr;
printCenteredTitle(" CUDNN inference ", '=', 30);
{
dim1.print();
TKDNN_TSTART
cudnn_out = net.infer(dim1, data);
TKDNN_TSTOP
dim1.print();
}
tk::dnn::dataDim_t dim2 = dim;
printCenteredTitle(" TENSORRT inference ", '=', 30);
{
dim2.print();
TKDNN_TSTART
netRT.infer(dim2, data);
TKDNN_TSTOP
dim2.print();
}
dnnType *rt_out1 = (dnnType *)netRT.buffersRT[1];
printCenteredTitle(std::string(" CHECK RESULTS ").c_str(), '=', 30);
dnnType *out1, *out1_h;
int odim1 = dim1.tot();
readBinaryFile(output_bin, odim1, &out1_h, &out1);
int ret_cudnn = 0, ret_tensorrt = 0, ret_cudnn_tensorrt = 0;
std::cout << "CUDNN vs correct" << std::endl;
ret_cudnn |= checkResult(odim1, cudnn_out, out1, true, 20) == 0 ? 0 : ERROR_CUDNN;
std::cout << "TRT vs correct" << std::endl;
ret_tensorrt |=checkResult(odim1, rt_out1, out1) == 0 ? 0 : ERROR_TENSORRT;
std::cout << "CUDNN vs TRT " << std::endl;
ret_cudnn_tensorrt |= checkResult(odim1, cudnn_out, rt_out1) == 0 ? 0 : ERROR_CUDNNvsTENSORRT;
cv::Mat viz = vizLayer2Mat(&net, net.num_layers-1);
cv::imwrite("test.png", viz);
return ret_cudnn | ret_tensorrt | ret_cudnn_tensorrt;
}
+297
View File
@@ -0,0 +1,297 @@
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "tkdnn.h"
#include "NetworkViz.h"
const char *input_bin = "shelfnet_mapillary/debug/input.bin";
const char *backbone[] = {
"shelfnet_mapillary/layers/backbone-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer1-0-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer1-0-conv2.bin",
"shelfnet_mapillary/layers/backbone-layer1-1-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer1-1-conv2.bin",
"shelfnet_mapillary/layers/backbone-layer2-0-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer2-0-conv2.bin",
"shelfnet_mapillary/layers/backbone-layer2-0-downsample-0.bin",
"shelfnet_mapillary/layers/backbone-layer2-1-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer2-1-conv2.bin",
"shelfnet_mapillary/layers/backbone-layer3-0-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer3-0-conv2.bin",
"shelfnet_mapillary/layers/backbone-layer3-0-downsample-0.bin",
"shelfnet_mapillary/layers/backbone-layer3-1-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer3-1-conv2.bin",
"shelfnet_mapillary/layers/backbone-layer4-0-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer4-0-conv2.bin",
"shelfnet_mapillary/layers/backbone-layer4-0-downsample-0.bin",
"shelfnet_mapillary/layers/backbone-layer4-1-conv1.bin",
"shelfnet_mapillary/layers/backbone-layer4-1-conv2.bin"};
const char *conv_out[] = {
"shelfnet_mapillary/layers/conv_out-conv-conv.bin",
"shelfnet_mapillary/layers/conv_out-conv_out.bin",
"shelfnet_mapillary/layers/conv_out16-conv-conv.bin",
"shelfnet_mapillary/layers/conv_out16-conv_out.bin",
"shelfnet_mapillary/layers/conv_out32-conv-conv.bin",
"shelfnet_mapillary/layers/conv_out32-conv_out.bin"
};
const char *decoder[] = {
"shelfnet_mapillary/layers/decoder-bottom-conv1.bin",
"shelfnet_mapillary/layers/decoder-bottom-conv12.bin",
"shelfnet_mapillary/layers/decoder-up_conv_list-0-conv-conv.bin",
"shelfnet_mapillary/layers/decoder-up_conv_list-0-conv_atten.bin",
"shelfnet_mapillary/layers/decoder-up_dense_list-0-conv.bin",
"shelfnet_mapillary/layers/decoder-up_conv_list-1-conv-conv.bin",
"shelfnet_mapillary/layers/decoder-up_conv_list-1-conv_atten.bin",
"shelfnet_mapillary/layers/decoder-up_dense_list-1-conv.bin"
};
const char *ladder[] = {
"shelfnet_mapillary/layers/ladder-inconv-conv1.bin",
"shelfnet_mapillary/layers/ladder-inconv-conv12.bin",
"shelfnet_mapillary/layers/ladder-down_module_list-0-conv1.bin",
"shelfnet_mapillary/layers/ladder-down_module_list-0-conv12.bin",
"shelfnet_mapillary/layers/ladder-down_conv_list-0.bin",
"shelfnet_mapillary/layers/ladder-down_module_list-1-conv1.bin",
"shelfnet_mapillary/layers/ladder-down_module_list-1-conv12.bin",
"shelfnet_mapillary/layers/ladder-down_conv_list-1.bin",
"shelfnet_mapillary/layers/ladder-bottom-conv1.bin",
"shelfnet_mapillary/layers/ladder-bottom-conv12.bin",
"shelfnet_mapillary/layers/ladder-up_conv_list-0-conv-conv.bin",
"shelfnet_mapillary/layers/ladder-up_conv_list-0-conv_atten.bin",
"shelfnet_mapillary/layers/ladder-up_dense_list-0-conv.bin",
"shelfnet_mapillary/layers/ladder-up_conv_list-1-conv-conv.bin",
"shelfnet_mapillary/layers/ladder-up_conv_list-1-conv_atten.bin",
"shelfnet_mapillary/layers/ladder-up_dense_list-1-conv.bin"};
const char *trans[] = {
"shelfnet_mapillary/layers/trans1-conv.bin",
"shelfnet_mapillary/layers/trans2-conv.bin",
"shelfnet_mapillary/layers/trans3-conv.bin"};
int main()
{
// downloadWeightsifDoNotExist(input_bin, "shelfnet_mapillary", "");
// download the weights from here: https://cloud.hipert.unimore.it/f/652476
// Mapillary Vistas has originally 66 classes, but we reduced them to 15 to improve the results on the categories of our interest.
int classes = 15;
// Network layout
tk::dnn::dataDim_t dim(1, 3, 1024, 1024, 1);
tk::dnn::Network net(dim);
int bi = 0, di = 0, li = 0, ci = 0;
new tk::dnn::Conv2d(&net, 64, 7, 7, 2, 2, 3, 3, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
tk::dnn::Layer* last = new tk::dnn::Pooling (&net, 3, 3, 2, 2, 1, 1, tk::dnn::POOLING_MAX);
for(int i=0; i<2; ++i){
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
}
std::vector<tk::dnn::Layer*> features;
for(int i=0;i<3;++i){
int out_channel = pow(2,7+i);
std::cout<<out_channel<<std::endl;
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 2, 2, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
tk::dnn::Layer* bn2 = new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 2, 2, 0, 0, backbone[bi++], true);
new tk::dnn::Shortcut(&net, bn2);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, backbone[bi++], true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
features.push_back(last);
}
for(int i=0; i<features.size(); ++i){
new tk::dnn::Route(&net, &features[i], 1);
int out_channel = pow(2,6+i);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, trans[i], true);
features[i] = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
}
//DECODER
last = features[2];
std::vector<tk::dnn::Layer*> up_out;
//bottom
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, decoder[di++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, decoder[di++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
up_out.push_back(last);
for(int i=0; i<2; ++i){
int out_channel = pow(2,7-i);
//up-conv
std::cout<<out_channel<<std::endl;
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, decoder[di++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Pooling(&net, last->output_dim.w, last->output_dim.h, last->output_dim.w, last->output_dim.h, 0, 0, tk::dnn::POOLING_AVERAGE);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, decoder[di++], true);
tk::dnn::Layer* act = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_SIGMOID);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Shortcut(&net, act, true);
//interpolate
new tk::dnn::Resize(&net, 1,2,2);
new tk::dnn::Shortcut(&net, features[1-i]);
//up-dense
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, decoder[di++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
up_out.push_back(last);
}
//LADDER
std::vector<tk::dnn::Layer*> down_out;
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
for(int i=0; i<2;++i){
int out_channel = pow(2,6+i);
tk::dnn::Layer* l_last = new tk::dnn::Shortcut(&net, up_out[2-i]);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, l_last);
l_last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
down_out.push_back(l_last);
new tk::dnn::Conv2d (&net, out_channel*2, 3, 3, 2, 2, 1, 1, ladder[li++], false);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.0f); //should be ReLU
}
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, 256, 3, 3, 1, 1, 1, 1, ladder[li++], true, false, 1, true);
new tk::dnn::Shortcut(&net, last);
last = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_RELU);
up_out.clear();
up_out.push_back(last);
for(int i=0; i<2; ++i){
int out_channel = pow(2,7-i);
//up-conv
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Pooling(&net, last->output_dim.w, last->output_dim.h, last->output_dim.w, last->output_dim.h, 0, 0, tk::dnn::POOLING_AVERAGE);
new tk::dnn::Conv2d (&net, out_channel, 1, 1, 1, 1, 0, 0, ladder[li++], true);
tk::dnn::Layer* act = new tk::dnn::Activation (&net, CUDNN_ACTIVATION_SIGMOID);
new tk::dnn::Route(&net, &last, 1);
new tk::dnn::Shortcut(&net, act, true);
//interpolate
new tk::dnn::Resize(&net, 1,2,2);
new tk::dnn::Shortcut(&net, down_out[1-i]);
// //up-dense
new tk::dnn::Conv2d (&net, out_channel, 3, 3, 1, 1, 1, 1, ladder[li++], true);
last = new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
up_out.push_back(last);
}
// for(int i=2;i>=0;--i){
// new tk::dnn::Route(&net, &up_out[i], 1);
new tk::dnn::Conv2d (&net, 64, 3, 3, 1, 1, 1, 1, conv_out[ci++], true);
new tk::dnn::Activation (&net, tk::dnn::ACTIVATION_LEAKY, 0.0f, 0.01);
new tk::dnn::Conv2d (&net, classes, 3, 3, 1, 1, 1, 1, conv_out[ci++], false);
/*up_out[i] =*/ new tk::dnn::Resize(&net, classes, net.input_dim.h, net.input_dim.w, true, tk::dnn::ResizeMode_t::LINEAR);
// }
new tk::dnn::Softmax(&net);
const char *output_bin = "shelfnet_mapillary/debug/softmax.bin";
// Load input
dnnType *data;
dnnType *input_h;
readBinaryFile(input_bin, dim.tot(), &input_h, &data);
std::cout<<"Input:"<<std::endl;
//print network model
net.print();
// // convert network to tensorRT
tk::dnn::NetworkRT netRT(&net, net.getNetworkRTName("shelfnet_mapillary"));
tk::dnn::dataDim_t dim1 = dim; //input dim
dnnType *cudnn_out = nullptr;
printCenteredTitle(" CUDNN inference ", '=', 30);
{
dim1.print();
TKDNN_TSTART
cudnn_out = net.infer(dim1, data);
TKDNN_TSTOP
dim1.print();
}
tk::dnn::dataDim_t dim2 = dim;
printCenteredTitle(" TENSORRT inference ", '=', 30);
{
dim2.print();
TKDNN_TSTART
netRT.infer(dim2, data);
TKDNN_TSTOP
dim2.print();
}
dnnType *rt_out1 = (dnnType *)netRT.buffersRT[1];
printCenteredTitle(std::string(" CHECK RESULTS ").c_str(), '=', 30);
dnnType *out1, *out1_h;
int odim1 = dim1.tot();
readBinaryFile(output_bin, odim1, &out1_h, &out1);
int ret_cudnn = 0, ret_tensorrt = 0, ret_cudnn_tensorrt = 0;
std::cout << "CUDNN vs correct" << std::endl;
ret_cudnn |= checkResult(odim1, cudnn_out, out1, true, 20) == 0 ? 0 : ERROR_CUDNN;
std::cout << "TRT vs correct" << std::endl;
ret_tensorrt |=checkResult(odim1, rt_out1, out1) == 0 ? 0 : ERROR_TENSORRT;
std::cout << "CUDNN vs TRT " << std::endl;
ret_cudnn_tensorrt |= checkResult(odim1, cudnn_out, rt_out1) == 0 ? 0 : ERROR_CUDNNvsTENSORRT;
cv::Mat viz = vizLayer2Mat(&net, net.num_layers-1);
cv::imwrite("test.png", viz);
return ret_cudnn | ret_tensorrt | ret_cudnn_tensorrt;
}
+1 -1
View File
@@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {
std::vector<double> stats; std::vector<double> stats;
printCenteredTitle(" TENSORRT inference ", '=', 30); printCenteredTitle(" TENSORRT inference ", '=', 30);
float total_time = 0; float total_time = 0;
for(int i=0; i<1200; i++) { for(int i=0; i<64; i++) {
// generate input // generate input
for(int j=0; j<netRT.input_dim.tot(); j++) { for(int j=0; j<netRT.input_dim.tot(); j++) {