diff --git a/.gitignore b/.gitignore
index b56526f..c1d362c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,5 +12,11 @@ build/
*.hdf5
*.pk
*.table
+cmake-build-release/
demo/COCO_val2017
-demo/BDD100K_val
\ No newline at end of file
+demo/BDD100K_val
+/.vs
+cmake-build-minsizerel/*
+scripts/COCO_val2017/*
+scripts/COCO_val2017.zip
+scripts/all_labels.txt
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c292300..5692979 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,15 @@
-cmake_minimum_required(VERSION 3.5)
+cmake_minimum_required(VERSION 3.15)
project (tkDNN)
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)
# project specific flags
@@ -10,7 +17,13 @@ if(DEBUG)
add_definitions(-DDEBUG)
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
@@ -28,19 +41,21 @@ include_directories(${CUDNN_INCLUDE_DIR})
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_add_library(kernels SHARED ${tkdnn_CUSRC})
+target_link_libraries(kernels ${CUDA_CUBLAS_LIBRARIES})
#-------------------------------------------------------------------------------
# External Libraries
#-------------------------------------------------------------------------------
find_package(Eigen3 REQUIRED)
+message("Eigen DIR: " ${EIGEN3_INCLUDE_DIR})
include_directories(${EIGEN3_INCLUDE_DIR})
find_package(OpenCV REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV")
# gives problems in cross-compiling, probably malformed cmake config
-#find_package(yaml-cpp REQUIRED)
+find_package(yaml-cpp REQUIRED)
#-------------------------------------------------------------------------------
# Build Libraries
@@ -48,7 +63,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV")
file(GLOB tkdnn_SRC "src/*.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})
add_library(tkDNN SHARED ${tkdnn_SRC})
target_link_libraries(tkDNN ${tkdnn_LIBS})
@@ -77,6 +92,7 @@ foreach(test_SRC ${darknet_SRC})
set(test_NAME test_${test_NAME})
add_executable(${test_NAME} ${test_SRC})
target_link_libraries(${test_NAME} tkDNN)
+ install(TARGETS ${test_NAME} DESTINATION bin)
endforeach()
# MOBILENET
@@ -136,7 +152,10 @@ target_link_libraries(seg_demo tkDNN)
message("install dir:" ${CMAKE_INSTALL_PREFIX})
install(DIRECTORY include/ DESTINATION include/)
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
DESTINATION "share/tkDNN/cmake/" # target directory
)
-
+install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests/" # source directory
+ DESTINATION "share/tkDNN/tests" # target directory
+)
diff --git a/Issues.md b/Issues.md
new file mode 100644
index 0000000..4875b13
--- /dev/null
+++ b/Issues.md
@@ -0,0 +1 @@
+1)error C2131 @ Yolo3Detection.cpp(97) -> expression doesnt evaluate to a constant caused to read of variable outside its lifetime
\ No newline at end of file
diff --git a/README.md b/README.md
index 19b98a2..ebca0dd 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,70 @@
# tkDNN
-tkDNN is a Deep Neural Network library built with cuDNN and tensorRT primitives, specifically thought to work on NVIDIA Jetson Boards. It has been tested on TK1(branch cudnn2), TX1, TX2, AGX Xavier and several discrete GPU.
+tkDNN is a Deep Neural Network library built with cuDNN and tensorRT primitives, specifically thought to work on NVIDIA Jetson Boards. It has been tested on TK1(branch cudnn2), TX1, TX2, AGX Xavier, Nano and several discrete GPUs.
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 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.
-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)
-
-Accepted paper @ ETFA 2020, will soon be published.
-M. Verucchi, G. Brilli, D. Sapienza, M. Verasani, M. Arena, F. Gatti, A. Capotondi, R. Cavicchioli, M. Bertogna, M. Solieri
-"A Systematic Assessment of Embedded Neural Networks for Object Detection", in IEEE International Conference on Emerging Technologies and Factory Automation (2020)
+@inproceedings{verucchi2020systematic,
+ 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},
+ booktitle={2020 25th IEEE International Conference on Emerging Technologies and Factory Automation (ETFA)},
+ volume={1},
+ pages={937--944},
+ year={2020},
+ organization={IEEE}
+}
```
-## Results
-Inference FPS of yolov4 with tkDNN, average of 1200 images with the same dimesion as the input size, on
+### What's new (20 July 2021)
+- [x] Support to sematic segmentation [REAME](readme/README_seg.md)
+- [] Support to TensorRT8 (WIP)
+
+## FPS Results
+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);
* 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 );
* 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 |
| :------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: |
-| 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 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 |
-| 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 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 |
-| Tx2 | yolo4 320 | 11,18 | 12,07 | 15,32 | 16,31 | - | - |
-| Tx2 | yolo4 416 | 7,30 | 7,58 | 9,45 | 9,90 | - | - |
-| Tx2 | yolo4 512 | 5,96 | 5,95 | 7,22 | 7,23 | - | - |
-| 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 | - | - |
+| 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 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 |
+| 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 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 |
+| Xavier NX | yolo4 320 | 14.56 | 16.25 | 30.14 | 41.15 | 42.13 | 53.42 |
+| Xavier NX | yolo4 416 | 10.02 | 10.60 | 22.43 | 25.59 | 29.08 | 32.94 |
+| Xavier NX | yolo4 512 | 8.10 | 8.32 | 15.78 | 17.13 | 20.51 | 22.46 |
+| Xavier NX | yolo4 608 | 5.26 | 5.18 | 11.54 | 12.06 | 15.09 | 15.82 |
+| Tx2 | yolo4 320 | 11.18 | 12.07 | 15.32 | 16.31 | - | - |
+| Tx2 | yolo4 416 | 7.30 | 7.58 | 9.45 | 9.90 | - | - |
+| Tx2 | yolo4 512 | 5.96 | 5.95 | 7.22 | 7.23 | - | - |
+| 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
+Results for COCO val 2017 (5k images), on RTX 2080Ti, with conf threshold=0.001
+
+| | CodaLab | CodaLab | CodaLab | CodaLab | tkDNN map | tkDNN map |
+| -------------------- | :-----------: | :-------: | :-----------: | :---------: | :-----------: | :-------: |
+| | **tkDNN** | **tkDNN** | **darknet** | **darknet** | **tkDNN** | **tkDNN** |
+| | MAP(0.5:0.95) | AP50 | MAP(0.5:0.95) | AP50 | MAP(0.5:0.95) | AP50 |
+| Yolov3 (416x416) | 0.381 | 0.675 | 0.380 | 0.675 | 0.372 | 0.663 |
+| yolov4 (416x416) | 0.468 | 0.705 | 0.471 | 0.710 | 0.459 | 0.695 |
+| yolov3tiny (416x416) | 0.096 | 0.202 | 0.096 | 0.201 | 0.093 | 0.198 |
+| yolov4tiny (416x416) | 0.202 | 0.400 | 0.201 | 0.400 | 0.197 | 0.395 |
+| Cnet-dla34 (512x512) | 0.366 | 0.543 | \- | \- | 0.361 | 0.535 |
+| mv2SSD (512x512) | 0.226 | 0.381 | \- | \- | 0.223 | 0.378 |
## Index
- [tkDNN](#tkdnn)
@@ -58,6 +84,14 @@ Inference FPS of yolov4 with tkDNN, average of 1200 images with the same dimesio
- [mAP demo](#map-demo)
- [Existing tests and supported networks](#existing-tests-and-supported-networks)
- [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)
+
@@ -155,7 +189,7 @@ tkDNN implement and easy parser for darknet cfg files, a network can be converte
tk::dnn::Network *net = tk::dnn::darknetParser("yolov4.cfg", "yolov4/layers", "coco.names");
net->print();
```
-All models from darknet are now parsed directly from cfg, you still need to export the weights with the descripted tools in the previus section.
+All models from darknet are now parsed directly from cfg, you still need to export the weights with the described tools in the previous section.
Supported layers
convolutional
@@ -173,19 +207,30 @@ All models from darknet are now parsed directly from cfg, you still need to expo
relu
leaky
mish
+ logistic
-## Run the demo
+## Run the demo
+This is an example using yolov4.
-To run the an object detection demo follow these steps (example with yolov3):
+To run the an object detection first create the .rt file by running:
```
-rm yolo3_fp32.rt # be sure to delete(or move) old tensorRT files
-./test_yolo3 # run the yolo test (is slow)
-./demo yolo3_fp32.rt ../demo/yolo_test.mp4 y
+rm yolo4_fp32.rt # be sure to delete(or move) old tensorRT files
+./test_yolo4 # run the yolo test (is slow)
```
-In general the demo program takes 4 parameters:
+If you get problems in the creation, try to check the error activating the debug of TensorRT in this way:
```
-./demo
+cmake .. -DDEBUG=True
+make
+```
+
+Once you have successfully created your rt file, run the demo:
+```
+./demo yolo4_fp32.rt ../demo/yolo_test.mp4 y
+```
+In general the demo program takes 7 parameters:
+```
+./demo
```
where
* `````` is the rt file generated by a test
@@ -194,9 +239,11 @@ where
* ``````is the number of classes the network is trained on
* `````` 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).
* `````` if set to 0 the demo will not show the visualization but save the video into result.mp4 (if n-batches ==1)
+* `````` confidence threshold for the detector. Only bounding boxes with threshold greater than conf-thresh will be displayed.
N.b. By default it is used FP32 inference
+

### FP16 inference
@@ -221,7 +268,7 @@ You should provide image_list.txt and label_list.txt, using training images. How
```
bash scripts/download_validation.sh COCO
```
-to automatically download COCO2017 validation (inside demo folder) and create those needed file. Use BDD insted of COCO to download BDD validation.
+to automatically download COCO2017 validation (inside demo folder) and create those needed file. Use BDD instead of COCO to download BDD validation.
Then a complete example using yolo3 and COCO dataset would be:
```
@@ -243,8 +290,8 @@ N.B.
export TKDNN_BATCHSIZE=2
# build tensorRT files
```
-This will create a TensorRT file with the desidered **max** batch size.
-The test will still run with a batch of 1, but the created tensorRT can manage the desidered batch size.
+This will create a TensorRT file with the desired **max** batch size.
+The test will still run with a batch of 1, but the created tensorRT can manage the desired batch size.
### Test batch Inference
This will test the network with random input and check if the output of each batch is the same.
@@ -290,7 +337,7 @@ cd build
./map_demo dla34_cnet_FP32.rt c ../demo/COCO_val2017/all_labels.txt ../demo/config.yaml
```
-This demo also creates a json file named ```net_name_COCO_res.json``` containing all the detections computed. The detections are in COCO format, the correct format to subit the results to [CodaLab COCO detection challenge](https://competitions.codalab.org/competitions/20794#participate).
+This demo also creates a json file named ```net_name_COCO_res.json``` containing all the detections computed. The detections are in COCO format, the correct format to submit the results to [CodaLab COCO detection challenge](https://competitions.codalab.org/competitions/20794#participate).
## Existing tests and supported networks
@@ -317,6 +364,98 @@ This demo also creates a json file named ```net_name_COCO_res.json``` containing
| resnet101_cnet | Centernet (Resnet101 backend)4 | [COCO 2017](http://cocodataset.org/) | 80 | 512x512 | [weights](https://cloud.hipert.unimore.it/s/5BTjHMWBcJk8g3i/download) |
| csresnext50-panet-spp | Cross Stage Partial Network 7 | [COCO 2014](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/Kcs4xBozwY4wFx8/download) |
| yolo4 | Yolov4 8 | [COCO 2017](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/d97CFzYqCPCp5Hg/download) |
+| yolo4_berkeley | Yolov4 8 | [BDD100K ](https://bair.berkeley.edu/blog/2018/05/30/bdd/) | 10 | 540x320 | [weights](https://cloud.hipert.unimore.it/s/nkWFa5fgb4NTdnB/download) |
+| yolo4tiny | Yolov4 tiny 9 | [COCO 2017](http://cocodataset.org/) | 80 | 416x416 | [weights](https://cloud.hipert.unimore.it/s/iRnc4pSqmx78gJs/download) |
+| yolo4x | Yolov4x-mish 9 | [COCO 2017](http://cocodataset.org/) | 80 | 640x640 | [weights](https://cloud.hipert.unimore.it/s/5MFjtNtgbDGdJEo/download) |
+| yolo4x-cps | Scaled Yolov4 10 | [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
@@ -329,3 +468,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.
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).
+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).
diff --git a/demo/config.yaml b/demo/config.yaml
index e6f91a7..31ac599 100644
--- a/demo/config.yaml
+++ b/demo/config.yaml
@@ -3,5 +3,5 @@ map_points : 101 #number of recall points (0 for all, 101 for COCO, 11 Pascal
map_levels : 10 #number of IoU step for the AP
map_step : 0.05 #step of IoU
IoU_thresh : 0.5 #starting IoU threshold
-conf_thresh : 0.0 #threshold on the condifence of the bbox
+conf_thresh : 0.001 #threshold on the condifence of the bbox
verbose : false #print on screen information
diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp
index 76b451d..317a574 100644
--- a/demo/demo/demo.cpp
+++ b/demo/demo/demo.cpp
@@ -1,7 +1,7 @@
#include
#include
#include /* srand, rand */
-#include
+//#include
#include
#include "CenternetDetection.h"
@@ -22,10 +22,15 @@ int main(int argc, char *argv[]) {
signal(SIGINT, sig_handler);
- std::string net = "yolo3_berkeley.rt";
+ std::string net = "yolo4tiny_fp32.rt";
if(argc > 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)
input = argv[2];
char ntype = 'y';
@@ -40,6 +45,9 @@ int main(int argc, char *argv[]) {
bool show = true;
if(argc > 6)
show = atoi(argv[6]);
+ float conf_thresh=0.3;
+ if(argc > 7)
+ conf_thresh = atof(argv[7]);
if(n_batch < 1 || n_batch > 64)
FatalError("Batch dim not supported");
@@ -69,7 +77,7 @@ int main(int argc, char *argv[]) {
FatalError("Network type not allowed (3rd parameter)\n");
}
- detNN->init(net, n_classes, n_batch);
+ detNN->init(net, n_classes, n_batch, conf_thresh);
gRun = true;
@@ -128,7 +136,7 @@ int main(int argc, char *argv[]) {
double mean = 0;
std::cout<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";
for(int i=0; istats.size(); i++) mean += detNN->stats[i]; mean /= detNN->stats.size();
std::cout<<"Avg: "<
#include
#include /* srand, rand */
+#ifdef __linux__
#include
+#endif
+
#include
#include "utils.h"
@@ -105,7 +108,7 @@ int main(int argc, char *argv[])
default:
FatalError("Network type not allowed (3rd parameter)\n");
}
- detNN->init(net, n_classes);
+ detNN->init(net, n_classes, 1, conf_thresh);
//read images
std::ifstream all_labels(labels_path);
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 0000000..3c9fb61
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,7 @@
+FROM ceccocats/tkdnn:latest
+LABEL maintainer "Francesco Gatti"
+
+RUN cd && git clone https://github.com/ceccocats/tkDNN.git && cd tkDNN && mkdir build && cd build \
+ && cmake .. && make -j12
+
+
diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base
new file mode 100644
index 0000000..e61b0d3
--- /dev/null
+++ b/docker/Dockerfile.base
@@ -0,0 +1,57 @@
+FROM nvidia/cuda:10.2-cudnn7-devel-ubuntu18.04
+LABEL maintainer "Francesco Gatti"
+
+ADD nv-tensorrt-repo-ubuntu1804-cuda10.2-trt7.0.0.11-ga-20191216_1-1_amd64.deb /tmp/trt.deb
+RUN apt-get update && dpkg -i /tmp/trt.deb && rm /tmp/trt.deb && apt-get update
+RUN apt install -y libnvinfer7=7.0.0-1+cuda10.2 libnvinfer-dev=7.0.0-1+cuda10.2
+RUN DEBIAN_FRONTEND=noninteractive apt install -y git wget libeigen3-dev libyaml-cpp-dev
+RUN cd /tmp && \
+ wget https://github.com/Kitware/CMake/releases/download/v3.17.3/cmake-3.17.3-Linux-x86_64.sh && \
+ chmod +x cmake-3.17.3-Linux-x86_64.sh && \
+ ./cmake-3.17.3-Linux-x86_64.sh --prefix=/usr/local --exclude-subdir --skip-license && \
+ rm ./cmake-3.17.3-Linux-x86_64.sh
+
+RUN echo "INSTALL OPENCV"
+RUN apt-get install -y build-essential \
+ unzip \
+ pkg-config \
+ libjpeg-dev \
+ libpng-dev \
+ libtiff-dev \
+ libavcodec-dev \
+ libavformat-dev \
+ libswscale-dev \
+ libv4l-dev \
+ libxvidcore-dev \
+ libx264-dev \
+ libgtk-3-dev \
+ libatlas-base-dev \
+ gfortran \
+ libgstreamer1.0-dev \
+ libgstreamer-plugins-base1.0-dev \
+ libdc1394-22-dev \
+ libavresample-dev
+RUN cd && wget https://github.com/opencv/opencv/archive/4.3.0.tar.gz && tar -xf 4.3.0.tar.gz && rm *.tar.gz
+RUN cd && wget https://github.com/opencv/opencv_contrib/archive/4.3.0.tar.gz && tar -xf 4.3.0.tar.gz && rm *.tar.gz
+RUN cd && \
+ cd opencv-4.3.0 && mkdir build && cd build && \
+ cmake -D CMAKE_BUILD_TYPE=RELEASE \
+ -D CMAKE_INSTALL_PREFIX=/usr/local \
+ -D INSTALL_PYTHON_EXAMPLES=OFF \
+ -D INSTALL_C_EXAMPLES=OFF \
+ -D OPENCV_EXTRA_MODULES_PATH='~/opencv_contrib-4.3.0/modules' \
+ -D BUILD_EXAMPLES=OFF \
+ -D WITH_CUDA=ON \
+ -D CUDA_ARCH_BIN=7.2 \
+ -D CUDA_ARCH_PTX="" \
+ -D ENABLE_FAST_MATH=ON \
+ -D CUDA_FAST_MATH=ON \
+ -D WITH_CUBLAS=ON \
+ -D WITH_LIBV4L=ON \
+ -D WITH_GSTREAMER=ON \
+ -D WITH_GSTREAMER_0_10=OFF \
+ -D WITH_TBB=ON \
+ ../ && make -j12 && make install
+RUN apt clean
+
+
diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 0000000..aec202a
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,21 @@
+# Use the prebuilt image
+```
+# build image
+docker build -t tkdnn:build -f Dockerfile .
+```
+
+# Build Base Docker image
+```
+# make nvidia docker working
+# follow this guide: https://github.com/NVIDIA/nvidia-docker
+
+# dowload tensorrt
+# from: https://developer.nvidia.com/compute/machine-learning/tensorrt/secure/7.0/7.0.0.11/local_repo/nv-tensorrt-repo-ubuntu1804-cuda10.2-trt7.0.0.11-ga-20191216_1-1_amd64.deb
+
+# build image
+docker build -t ceccocats/tkdnn:latest -f Dockerfile.base .
+
+# run image
+docker run -ti --gpus all --rm ceccocats/tkdnn:latest bash
+```
+
diff --git a/readme/README_seg.md b/docs/README_seg.md
similarity index 100%
rename from readme/README_seg.md
rename to docs/README_seg.md
diff --git a/readme/output.gif b/docs/output.gif
similarity index 100%
rename from readme/output.gif
rename to docs/output.gif
diff --git a/include/tkDNN/CenternetDetection.h b/include/tkDNN/CenternetDetection.h
index 227cb78..3c8cfbb 100644
--- a/include/tkDNN/CenternetDetection.h
+++ b/include/tkDNN/CenternetDetection.h
@@ -73,7 +73,7 @@ public:
CenternetDetection() {};
~CenternetDetection() {};
- bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1);
+ bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1, const float conf_thresh=0.3);
void preprocess(cv::Mat &frame, const int bi=0);
void postprocess(const int bi=0,const bool mAP=false);
};
diff --git a/include/tkDNN/DarknetParser.h b/include/tkDNN/DarknetParser.h
index f36469b..089c4d6 100644
--- a/include/tkDNN/DarknetParser.h
+++ b/include/tkDNN/DarknetParser.h
@@ -11,6 +11,7 @@ namespace tk { namespace dnn {
int channels = 3;
int batch_normalize=0;
int groups = 1;
+ int group_id = 0;
int filters=1;
int size_x=1;
int size_y=1;
@@ -23,7 +24,10 @@ namespace tk { namespace dnn {
int num = 1;
int pad = 0;
int coords = 4;
+ int nms_kind = 0;
+ int new_coords= 0;
float scale_xy = 1;
+ float nms_thresh = 0.45;
std::vector layers;
std::string activation = "linear";
diff --git a/include/tkDNN/DetectionNN.h b/include/tkDNN/DetectionNN.h
index 030cf8f..a8c81f7 100644
--- a/include/tkDNN/DetectionNN.h
+++ b/include/tkDNN/DetectionNN.h
@@ -4,7 +4,10 @@
#include
#include
#include
+#ifdef __linux__
#include
+#endif
+
#include
#include "utils.h"
@@ -14,7 +17,7 @@
#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
#include
@@ -76,15 +79,15 @@ class DetectionNN {
~DetectionNN(){};
/**
- * Method used to inialize the class, allocate memory and compute
+ * Method used to initialize the class, allocate memory and compute
* needed data.
*
- * @param tensor_path path to the rt file og the NN.
+ * @param tensor_path path to the rt file of 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.
*/
- virtual bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1) = 0;
+ virtual bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1, const float conf_thresh=0.3) = 0;
/**
* This method performs the whole detection of the NN.
@@ -141,16 +144,15 @@ class DetectionNN {
}
/**
- * Method to draw boundixg boxes and labels on a frame.
+ * Method to draw bounding boxes and labels on a frame.
*
- * @param frames orginal frame to draw bounding box on.
+ * @param frames original frame to draw bounding box on.
*/
void draw(std::vector& frames) {
tk::dnn::box b;
int x0, w, x1, y0, h, y1;
int objClass;
std::string det_class;
-
int baseline = 0;
float font_scale = 0.5;
int thickness = 2;
diff --git a/include/tkDNN/ImuOdom.h b/include/tkDNN/ImuOdom.h
index 58def96..d5429a8 100644
--- a/include/tkDNN/ImuOdom.h
+++ b/include/tkDNN/ImuOdom.h
@@ -1,7 +1,14 @@
#include
#include
#include /* srand, rand */
+
+#ifdef __linux__
#include
+#elif _WIN32
+#define _USE_MATH_DEFINES
+#include
+#endif
+
#include
#include
#include "utils.h"
@@ -44,7 +51,7 @@ class ImuOdom {
virtual ~ImuOdom() {}
/**
- * Method used for inizialize the class
+ * Method used for initialize the class
*
* @return Success of the initialization
*/
@@ -141,7 +148,7 @@ class ImuOdom {
//odomPOS = odomPOS + deltaP.cast(); // V2
odomROT = odomROT * q.normalized().toRotationMatrix();
- // compute euler
+ // compute Euler
auto newEULER = odomROT.eulerAngles(0, 1, 2);
for(int i=0; i<3; i++) {
while( fabs(newEULER(i) - odomEULER(i)) > M_PI_2 ) {
diff --git a/include/tkDNN/Int8BatchStream.h b/include/tkDNN/Int8BatchStream.h
index 4349c1f..c39a11c 100644
--- a/include/tkDNN/Int8BatchStream.h
+++ b/include/tkDNN/Int8BatchStream.h
@@ -11,8 +11,11 @@
#include
#include
#include
-#include
+#include
+#ifdef __linux__
#include
+#endif
+
#include
#include "NvInfer.h"
diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h
index 4234cab..91c33ec 100644
--- a/include/tkDNN/Layer.h
+++ b/include/tkDNN/Layer.h
@@ -19,6 +19,7 @@ enum layerType_t {
LAYER_ACTIVATION_CRELU,
LAYER_ACTIVATION_LEAKY,
LAYER_ACTIVATION_MISH,
+ LAYER_ACTIVATION_LOGISTIC,
LAYER_FLATTEN,
LAYER_RESHAPE,
LAYER_RESIZE,
@@ -69,6 +70,7 @@ public:
case LAYER_ACTIVATION_CRELU: return "ActivationCReLU";
case LAYER_ACTIVATION_LEAKY: return "ActivationLeaky";
case LAYER_ACTIVATION_MISH: return "ActivationMish";
+ case LAYER_ACTIVATION_LOGISTIC: return "ActivationLogistic";
case LAYER_FLATTEN: return "Flatten";
case LAYER_RESHAPE: return "Reshape";
case LAYER_RESIZE: return "Resize";
@@ -173,7 +175,7 @@ public:
/**
- Input layer (it doesnt need weigths)
+ Input layer (it doesn't need weights)
*/
class Input : public Layer {
@@ -209,16 +211,17 @@ public:
/**
- Avaible activation functions
+ Available activation functions
*/
typedef enum {
ACTIVATION_ELU = 100,
ACTIVATION_LEAKY = 101,
- ACTIVATION_MISH = 102
+ ACTIVATION_MISH = 102,
+ ACTIVATION_LOGISTIC = 103
} tkdnnActivationMode_t;
/**
- Activation layer (it doesnt need weigths)
+ Activation layer (it doesn't need weights)
*/
class Activation : public Layer {
@@ -236,6 +239,8 @@ public:
return LAYER_ACTIVATION_LEAKY;
else if (act_mode == ACTIVATION_MISH)
return LAYER_ACTIVATION_MISH;
+ else if (act_mode == ACTIVATION_LOGISTIC)
+ return LAYER_ACTIVATION_LOGISTIC;
else
return LAYER_ACTIVATION;
};
@@ -276,8 +281,8 @@ public:
protected:
cudnnFilterDescriptor_t filterDesc;
cudnnConvolutionDescriptor_t convDesc;
- cudnnConvolutionFwdAlgo_t algo;
- cudnnConvolutionBwdDataAlgo_t bwAlgo;
+ cudnnConvolutionFwdAlgoPerf_t algo;
+ cudnnConvolutionBwdDataAlgoPerf_t bwAlgo;
cudnnTensorDescriptor_t biasTensorDesc;
void initCUDNN(bool back = false);
@@ -321,9 +326,9 @@ public:
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
const bool bidirectional = true; /**> is the net bidir */
- bool returnSeq = false; /**> if false return only the result of last timestep */
+ bool returnSeq = false; /**> if false return only the result of last timestamp */
int stateSize = 0; /**> number of hidden states */
- int seqLen = 0; /**> number of timesteps */
+ int seqLen = 0; /**> number of timestamp */
int numLayers = 1; /**> number of internal layers */
protected:
@@ -370,7 +375,7 @@ public:
/**
- Deformable Convolutionl 2d layer
+ Deformable Convolutional 2d layer
*/
class DeformConv2d : public LayerWgs {
@@ -469,7 +474,7 @@ protected:
/**
- Avaible pooling functions (padding on tkDNN is not supported)
+ Available pooling functions (padding on tkDNN is not supported)
*/
typedef enum {
POOLING_MAX = 0,
@@ -480,7 +485,7 @@ typedef enum {
/**
Pooling layer
- currenty supported only 2d pooing (also on 3d input)
+ currently supported only 2d pooing (also on 3d input)
*/
class Pooling : public Layer {
@@ -529,7 +534,7 @@ public:
class Route : public Layer {
public:
- Route(Network *net, Layer **layers, int layers_n);
+ Route(Network *net, Layer **layers, int layers_n, int groups = 1, int group_id = 0);
virtual ~Route();
virtual layerType_t getLayerType() { return LAYER_ROUTE; };
@@ -539,12 +544,14 @@ public:
static const int MAX_LAYERS = 32;
Layer *layers[MAX_LAYERS]; //ids of layers to be merged
int layers_n; //number of layers
+ int groups;
+ int group_id;
};
/**
Reorg layer
- Mantain same dimension but change C*H*W distribution
+ Maintains same dimension but change C*H*W distribution
*/
class Reorg : public Layer {
@@ -578,7 +585,7 @@ public:
/**
Upsample layer
- Mantain same dimension but change C*H*W distribution
+ Maintains same dimension but change C*H*W distribution
*/
class Upsample : public Layer {
@@ -629,24 +636,28 @@ public:
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 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 *bias_h, *bias_d; //anchors
float scaleXY;
+ double nms_thresh;
+ nmsKind_t nsm_kind;
std::vector classesNames;
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;
- static const int MAX_DETECTIONS = 8192;
+ static const int MAX_DETECTIONS = 8192*2;
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);
};
/**
diff --git a/include/tkDNN/MobilenetDetection.h b/include/tkDNN/MobilenetDetection.h
index cabd7eb..9a5fedc 100644
--- a/include/tkDNN/MobilenetDetection.h
+++ b/include/tkDNN/MobilenetDetection.h
@@ -65,7 +65,7 @@ public:
MobilenetDetection() {};
~MobilenetDetection() {};
- bool init(const std::string& tensor_path, const int n_classes, const int n_batches=1);
+ bool init(const std::string& tensor_path, const int n_classes, const int n_batches=1, const float conf_thresh=0.3);
void preprocess(cv::Mat &frame, const int bi=0);
void postprocess(const int bi=0,const bool mAP=false);
};
diff --git a/include/tkDNN/Network.h b/include/tkDNN/Network.h
index 2d95215..b78acff 100644
--- a/include/tkDNN/Network.h
+++ b/include/tkDNN/Network.h
@@ -7,12 +7,12 @@
namespace tk { namespace dnn {
/**
- Data rapresentation beetween layers
+ Data representation between layers
n = batch size
c = channels
- h = heigth (lines)
+ h = height (lines)
w = width (rows)
- l = lenght (3rd dimension)
+ l = length (3rd dimension)
*/
struct dataDim_t {
@@ -43,7 +43,7 @@ public:
void releaseLayers();
/**
- Do inferece for every added layer
+ Do inference for every added layer
*/
dnnType* infer(dataDim_t &dim, dnnType* data);
diff --git a/include/tkDNN/NetworkRT.h b/include/tkDNN/NetworkRT.h
index 3bd53d8..9892a24 100644
--- a/include/tkDNN/NetworkRT.h
+++ b/include/tkDNN/NetworkRT.h
@@ -6,6 +6,7 @@
#include "Network.h"
#include "Layer.h"
#include "NvInfer.h"
+#include
namespace tk { namespace dnn {
@@ -24,11 +25,12 @@ template T readBUF(const char*& buffer)
using namespace nvinfer1;
#include "pluginsRT/ActivationLeakyRT.h"
+#include "pluginsRT/ActivationLogisticRT.h"
#include "pluginsRT/ActivationReLUCeilingRT.h"
#include "pluginsRT/ActivationMishRT.h"
#include "pluginsRT/ReorgRT.h"
#include "pluginsRT/RegionRT.h"
-//#include "pluginsRT/RouteRT.h"
+#include "pluginsRT/RouteRT.h"
#include "pluginsRT/ShortcutRT.h"
#include "pluginsRT/YoloRT.h"
#include "pluginsRT/UpsampleRT.h"
@@ -59,6 +61,7 @@ public:
#if NV_TENSORRT_MAJOR >= 6
nvinfer1::IBuilderConfig *configRT;
#endif
+
nvinfer1::ICudaEngine *engineRT;
nvinfer1::IExecutionContext *contextRT;
@@ -91,7 +94,7 @@ public:
}
/**
- Do inferece
+ Do inference
*/
dnnType* infer(dataDim_t &dim, dnnType* data);
void enqueue(int batchSize = 1);
@@ -115,6 +118,9 @@ public:
bool serialize(const char *filename);
bool deserialize(const char *filename);
+
+
+
};
}}
diff --git a/include/tkDNN/Yolo3Detection.h b/include/tkDNN/Yolo3Detection.h
index 6d38514..100a720 100644
--- a/include/tkDNN/Yolo3Detection.h
+++ b/include/tkDNN/Yolo3Detection.h
@@ -24,7 +24,7 @@ public:
Yolo3Detection() {};
~Yolo3Detection() {};
- bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1);
+ bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1, const float conf_thresh=0.3);
void preprocess(cv::Mat &frame, const int bi=0);
void postprocess(const int bi=0,const bool mAP=false);
};
diff --git a/include/tkDNN/evaluation.h b/include/tkDNN/evaluation.h
index 8907d9d..128eba0 100644
--- a/include/tkDNN/evaluation.h
+++ b/include/tkDNN/evaluation.h
@@ -73,12 +73,12 @@ double computeMap( std::vector &images,const int classes,
* all the recall levels are evaluated, otherwise only
* map_point recall levels are used. For COCO evaluation
* 101 points are used.
- * @param map_step step used to increment IoU theshold
+ * @param map_step step used to increment IoU threshold
* @param map_levels number of IoU step to perform
* @param verbose is set to true, prints on screen additional info
* @param write_on_file if set to true, the results produced by this function
* are written on file
- * @param net name of the considerd neural network
+ * @param net name of the considered neural network
*
* @return mAP IoU_tresh:IoU_tresh+map_step*map_levels (e.g. mAP 0.5:0.95 when
* map_step=0.05 and map_levels=10)
@@ -89,7 +89,7 @@ double computeMapNIoULevels(std::vector &images,const int classes,
const int map_levels=10, const bool verbose=false,
const bool write_on_file = false, std::string net = "");
/**
- * This method computes the numper of True Positive (TP), False Positive (FP),
+ * This method computes the number of True Positive (TP), False Positive (FP),
* False Negative (FN), precision, recall and f1-score.
* Those values are computer over all the detections, over all the classes.
*
@@ -101,7 +101,7 @@ double computeMapNIoULevels(std::vector &images,const int classes,
* @param verbose is set to true, prints on screen additional info
* @param write_on_file if set to true, the results produced by this function
* are written on file
- * @param net name of the considerd neural network
+ * @param net name of the considered neural network
*/
void computeTPFPFN( std::vector &images,const int classes,
const float IoU_thresh=0.5, const float conf_thresh=0.3,
diff --git a/include/tkDNN/pluginsRT/ActivationLeakyRT.h b/include/tkDNN/pluginsRT/ActivationLeakyRT.h
index 30bed7e..330ed37 100644
--- a/include/tkDNN/pluginsRT/ActivationLeakyRT.h
+++ b/include/tkDNN/pluginsRT/ActivationLeakyRT.h
@@ -51,9 +51,9 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
- tk::dnn::writeBUF(buf, slope);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, size);
+ assert(buf == a + getSerializationSize());
}
int size;
diff --git a/include/tkDNN/pluginsRT/ActivationLogisticRT.h b/include/tkDNN/pluginsRT/ActivationLogisticRT.h
new file mode 100644
index 0000000..063931f
--- /dev/null
+++ b/include/tkDNN/pluginsRT/ActivationLogisticRT.h
@@ -0,0 +1,60 @@
+#include
+#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(inputs[0]),
+ reinterpret_cast(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(buffer);
+ tk::dnn::writeBUF(buf, size);
+ }
+
+ int size;
+};
diff --git a/include/tkDNN/pluginsRT/ActivationMishRT.h b/include/tkDNN/pluginsRT/ActivationMishRT.h
index 1744ab0..5d660af 100644
--- a/include/tkDNN/pluginsRT/ActivationMishRT.h
+++ b/include/tkDNN/pluginsRT/ActivationMishRT.h
@@ -52,8 +52,9 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, size);
+ assert(buf == a + getSerializationSize());
}
int size;
diff --git a/include/tkDNN/pluginsRT/ActivationReLUCeilingRT.h b/include/tkDNN/pluginsRT/ActivationReLUCeilingRT.h
index 286f22e..50ceb81 100644
--- a/include/tkDNN/pluginsRT/ActivationReLUCeilingRT.h
+++ b/include/tkDNN/pluginsRT/ActivationReLUCeilingRT.h
@@ -51,9 +51,10 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, ceiling);
tk::dnn::writeBUF(buf, size);
+ assert(buf = a + getSerializationSize());
}
diff --git a/include/tkDNN/pluginsRT/ActivationSigmoidRT.h b/include/tkDNN/pluginsRT/ActivationSigmoidRT.h
index 1d47136..bcc58c7 100644
--- a/include/tkDNN/pluginsRT/ActivationSigmoidRT.h
+++ b/include/tkDNN/pluginsRT/ActivationSigmoidRT.h
@@ -52,8 +52,9 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, size);
+ assert(buf == a + getSerializationSize());
}
int size;
diff --git a/include/tkDNN/pluginsRT/DeformableConvRT.h b/include/tkDNN/pluginsRT/DeformableConvRT.h
index bff6370..5cb2bab 100644
--- a/include/tkDNN/pluginsRT/DeformableConvRT.h
+++ b/include/tkDNN/pluginsRT/DeformableConvRT.h
@@ -89,7 +89,7 @@ public:
for(int b=0; b(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, chunk_dim);
tk::dnn::writeBUF(buf, kh);
tk::dnn::writeBUF(buf, kw);
@@ -163,6 +163,7 @@ public:
for(int i=0; i(buffer);
+ char *buf = reinterpret_cast(buffer),*a = buf;
tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w);
tk::dnn::writeBUF(buf, rows);
tk::dnn::writeBUF(buf, cols);
+ assert(buf == a + getSerializationSize());
}
int c, h, w;
diff --git a/include/tkDNN/pluginsRT/MaxPoolingFixedSizeRT.h b/include/tkDNN/pluginsRT/MaxPoolingFixedSizeRT.h
index 911fca2..0899a34 100644
--- a/include/tkDNN/pluginsRT/MaxPoolingFixedSizeRT.h
+++ b/include/tkDNN/pluginsRT/MaxPoolingFixedSizeRT.h
@@ -55,7 +55,7 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, this->c);
tk::dnn::writeBUF(buf, this->h);
@@ -65,6 +65,7 @@ public:
tk::dnn::writeBUF(buf, this->stride_W);
tk::dnn::writeBUF(buf, this->winSize);
tk::dnn::writeBUF(buf, this->padding);
+ assert(buf == a + getSerializationSize());
}
int n, c, h, w;
diff --git a/include/tkDNN/pluginsRT/RegionRT.h b/include/tkDNN/pluginsRT/RegionRT.h
index f0d127e..8487652 100644
--- a/include/tkDNN/pluginsRT/RegionRT.h
+++ b/include/tkDNN/pluginsRT/RegionRT.h
@@ -73,13 +73,14 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, classes);
tk::dnn::writeBUF(buf, coords);
tk::dnn::writeBUF(buf, num);
tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w);
+ assert(buf == a + getSerializationSize());
}
int c, h, w;
diff --git a/include/tkDNN/pluginsRT/ReorgRT.h b/include/tkDNN/pluginsRT/ReorgRT.h
index ee85718..c1b529a 100644
--- a/include/tkDNN/pluginsRT/ReorgRT.h
+++ b/include/tkDNN/pluginsRT/ReorgRT.h
@@ -52,11 +52,12 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, stride);
tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w);
+ assert(buf == a + getSerializationSize());
}
int c, h, w, stride;
diff --git a/include/tkDNN/pluginsRT/ReshapeRT.h b/include/tkDNN/pluginsRT/ReshapeRT.h
index 97030db..37017c7 100644
--- a/include/tkDNN/pluginsRT/ReshapeRT.h
+++ b/include/tkDNN/pluginsRT/ReshapeRT.h
@@ -50,11 +50,12 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a = buf;
tk::dnn::writeBUF(buf, n);
tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w);
+ assert(buf == a + getSerializationSize());
}
int n, c, h, w;
diff --git a/include/tkDNN/pluginsRT/ResizeLayerRT.h b/include/tkDNN/pluginsRT/ResizeLayerRT.h
index ae87dbf..cde52bf 100644
--- a/include/tkDNN/pluginsRT/ResizeLayerRT.h
+++ b/include/tkDNN/pluginsRT/ResizeLayerRT.h
@@ -52,7 +52,7 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, o_c);
tk::dnn::writeBUF(buf, o_h);
@@ -61,6 +61,7 @@ public:
tk::dnn::writeBUF(buf, i_c);
tk::dnn::writeBUF(buf, i_h);
tk::dnn::writeBUF(buf, i_w);
+ assert(buf == a + getSerializationSize());
}
int i_c, i_h, i_w, o_c, o_h, o_w;
diff --git a/include/tkDNN/pluginsRT/RouteRT.h b/include/tkDNN/pluginsRT/RouteRT.h
index 0e94a97..5a8c170 100644
--- a/include/tkDNN/pluginsRT/RouteRT.h
+++ b/include/tkDNN/pluginsRT/RouteRT.h
@@ -8,7 +8,9 @@ class RouteRT : public IPlugin {
*/
public:
- RouteRT() {
+ RouteRT(int groups, int group_id) {
+ this->groups = groups;
+ this->group_id = group_id;
}
~RouteRT(){
@@ -22,7 +24,7 @@ public:
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
int out_c = 0;
for(int i=0; i(outputs[0]);
- int offset = 0;
- for(int i=0; i(inputs[i]);
- int in_dim = c_in[i]*h*w;
- checkCuda( cudaMemcpyAsync(dstData + offset, input, in_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream) );
- offset += in_dim;
+ for(int b=0; b(inputs[i]);
+ int in_dim = c_in[i]*h*w;
+ int part_in_dim = in_dim / this->groups;
+ checkCuda( cudaMemcpyAsync(dstData + b*c*w*h + offset, input + b*c*w*h*groups + this->group_id*part_in_dim, part_in_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream) );
+ offset += part_in_dim;
+ }
}
return 0;
@@ -65,11 +71,13 @@ public:
virtual size_t getSerializationSize() override {
- return (4+MAX_INPUTS)*sizeof(int);
+ return (6+MAX_INPUTS)*sizeof(int);
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
+ tk::dnn::writeBUF(buf, groups);
+ tk::dnn::writeBUF(buf, group_id);
tk::dnn::writeBUF(buf, in);
for(int i=0; i(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, bc);
tk::dnn::writeBUF(buf, bh);
tk::dnn::writeBUF(buf, bw);
@@ -67,7 +67,8 @@ public:
tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w);
-
+ assert(buf == a + getSerializationSize());
+
}
int c, h, w;
diff --git a/include/tkDNN/pluginsRT/UpsampleRT.h b/include/tkDNN/pluginsRT/UpsampleRT.h
index 7a62abc..a11d7b4 100644
--- a/include/tkDNN/pluginsRT/UpsampleRT.h
+++ b/include/tkDNN/pluginsRT/UpsampleRT.h
@@ -54,11 +54,12 @@ public:
}
virtual void serialize(void* buffer) override {
- char *buf = reinterpret_cast(buffer);
+ char *buf = reinterpret_cast(buffer),*a=buf;
tk::dnn::writeBUF(buf, stride);
tk::dnn::writeBUF(buf, c);
tk::dnn::writeBUF(buf, h);
tk::dnn::writeBUF(buf, w);
+ assert(buf == a + getSerializationSize());
}
int c, h, w, stride;
diff --git a/include/tkDNN/pluginsRT/YoloRT.h b/include/tkDNN/pluginsRT/YoloRT.h
index f8e596c..5ffe39c 100644
--- a/include/tkDNN/pluginsRT/YoloRT.h
+++ b/include/tkDNN/pluginsRT/YoloRT.h
@@ -8,12 +8,15 @@ class YoloRT : public IPlugin {
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->num = num;
this->n_masks = n_masks;
this->scaleXY = scale_xy;
+ this->nms_thresh = nms_thresh;
+ this->nms_kind = nms_kind;
+ this->new_coords = new_coords;
mask = new dnnType[n_masks];
bias = new dnnType[num*n_masks*2];
@@ -61,17 +64,23 @@ public:
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);
-
- index = entry_index(b, n*w*h, 4);
- activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*w*h, 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);
+ 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
+
+ if (this->scaleXY != 1) scalAdd(dstData + index, 2 * w*h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
+
+ index = entry_index(b, n*w*h, 4);
+ activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*w*h, stream);
+ }
+ }
+ }
//std::cout<<"YOLO END\n";
return 0;
@@ -79,22 +88,29 @@ public:
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 {
- char *buf = reinterpret_cast(buffer);
- tk::dnn::writeBUF(buf, classes);
- tk::dnn::writeBUF(buf, num);
- tk::dnn::writeBUF(buf, n_masks);
- tk::dnn::writeBUF(buf, c);
- tk::dnn::writeBUF(buf, h);
- tk::dnn::writeBUF(buf, w);
- tk::dnn::writeBUF(buf, scaleXY);
- for(int i=0; i(buffer),*a=buf;
+ tk::dnn::writeBUF(buf, classes); //std::cout << "Classes :" << classes << std::endl;
+ tk::dnn::writeBUF(buf, num); //std::cout << "Num : " << num << std::endl;
+ tk::dnn::writeBUF(buf, n_masks); //std::cout << "N_Masks" << n_masks << std::endl;
+ tk::dnn::writeBUF(buf, scaleXY); //std::cout << "ScaleXY :" << scaleXY << std::endl;
+ tk::dnn::writeBUF(buf, nms_thresh); //std::cout << "nms_thresh :" << nms_thresh << std::endl;
+ tk::dnn::writeBUF(buf, nms_kind); //std::cout << "nms_kind : " << nms_kind << std::endl;
+ tk::dnn::writeBUF(buf, new_coords); //std::cout << "new_coords : " << new_coords << std::endl;
+ tk::dnn::writeBUF(buf, c); //std::cout << "C : " << c << std::endl;
+ tk::dnn::writeBUF(buf, h); //std::cout << "H : " << h << std::endl;
+ tk::dnn::writeBUF(buf, w); //std::cout << "C : " << c << std::endl;
+ 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
for(int i=0; i classesNames;
dnnType *mask;
diff --git a/include/tkDNN/test.h b/include/tkDNN/test.h
index 4e238ff..e842269 100644
--- a/include/tkDNN/test.h
+++ b/include/tkDNN/test.h
@@ -20,7 +20,7 @@ int testInference(std::vector input_bins, std::vector
}
if(output_bins.size() != outputs.size()) {
std::cout< input_bins, std::vector
readBinaryFile(input_bins[0], net->input_dim.tot(), &input_h, &data);
// outputs
- dnnType *cudnn_out[outputs.size()], *rt_out[outputs.size()];
+ //dnnType *cudnn_out[outputs.size()], *rt_out[outputs.size()];
+ std::vector cudnn_out,rt_out;
tk::dnn::dataDim_t dim1 = net->input_dim; //input dim
printCenteredTitle(" CUDNN inference ", '=', 30); {
@@ -39,7 +40,7 @@ int testInference(std::vector input_bins, std::vector
TKDNN_TSTOP
dim1.print();
}
- for(int i=0; idstData;
+ for(int i=0; idstData);
if(netRT != nullptr) {
tk::dnn::dataDim_t dim2 = net->input_dim;
@@ -50,7 +51,7 @@ int testInference(std::vector input_bins, std::vector
TKDNN_TSTOP
dim2.print();
}
- for(int i=0; ibuffersRT[i+1];
+ for(int i=0; ibuffersRT[i+1]);
}
int ret_cudnn = 0, ret_tensorrt = 0, ret_cudnn_tensorrt = 0;
diff --git a/include/tkDNN/utils.h b/include/tkDNN/utils.h
index 784b6b9..dd5d673 100644
--- a/include/tkDNN/utils.h
+++ b/include/tkDNN/utils.h
@@ -12,8 +12,12 @@
#include
#include
+#ifdef __linux__
#include
+#endif
+
#include
+#include
#define dnnType float
@@ -39,6 +43,7 @@
#define TKDNN_VERBOSE 1
// Simple Timer
+#ifdef __linux__
#define TKDNN_TSTART timespec start, end; \
clock_gettime(CLOCK_MONOTONIC, &start);
@@ -48,6 +53,14 @@
if(show) std::cout< duration = stop -start; \
+auto time_ms = std::chrono::duration_cast(duration);\
+double t_ns = time_ms.count();
+#endif
+
/********************************************************
* Prints the error message, and exits
diff --git a/scripts/download_validation.py b/scripts/download_validation.py
new file mode 100644
index 0000000..0e3b1d4
--- /dev/null
+++ b/scripts/download_validation.py
@@ -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")
diff --git a/scripts/test_all_tests.sh b/scripts/test_all_tests.sh
index 4eda073..f0ae161 100644
--- a/scripts/test_all_tests.sh
+++ b/scripts/test_all_tests.sh
@@ -69,12 +69,16 @@ do
echo -e "${ORANGE}Batch $TKDNN_BATCHSIZE ${NC}"
test_net mnist
- ./test_imuodom &>> $out_file
- print_output $? imuodom
+ # ./test_imuodom &>> $out_file
+ # print_output $? imuodom
test_net shelfnet
+ test_net shelfnet_berkeley
test_net yolo4
+ test_net yolo4-csp
+ test_net yolo4x
test_net yolo4_berkeley
+ test_net yolo4tiny
test_net yolo3
test_net yolo3_berkeley
test_net yolo3_coco4
diff --git a/src/Activation.cpp b/src/Activation.cpp
index c97a717..0b113a7 100644
--- a/src/Activation.cpp
+++ b/src/Activation.cpp
@@ -52,6 +52,10 @@ dnnType* Activation::infer(dataDim_t &dim, dnnType* srcData) {
else if(act_mode == ACTIVATION_MISH) {
activationMishForward(srcData, dstData, dim.tot());
+ }
+ else if(act_mode == ACTIVATION_LOGISTIC) {
+ activationLOGISTICForward(srcData, dstData, dim.tot());
+
} else {
dnnType alpha = dnnType(1);
dnnType beta = dnnType(0);
diff --git a/src/CenternetDetection.cpp b/src/CenternetDetection.cpp
index 9d8df38..46757f4 100644
--- a/src/CenternetDetection.cpp
+++ b/src/CenternetDetection.cpp
@@ -3,11 +3,12 @@
namespace tk { namespace dnn {
-bool CenternetDetection::init(const std::string& tensor_path, const int n_classes, const int n_batches){
+bool CenternetDetection::init(const std::string& tensor_path, const int n_classes, const int n_batches, const float conf_thresh){
std::cout<<(tensor_path).c_str()<<"\n";
netRT = new tk::dnn::NetworkRT(NULL, (tensor_path).c_str() );
classes = n_classes;
nBatches = n_batches;
+ confThreshold = conf_thresh;
dim = netRT->input_dim;
@@ -371,10 +372,10 @@ void CenternetDetection::postprocess(const int bi, const bool mAP){
// std::cout<<"th: "<cudnnHandle,
- filterDesc, dstTensor, convDesc, srcTensor,
- CUDNN_CONVOLUTION_BWD_DATA_PREFER_FASTEST, 0, &bwAlgo) );
+ checkCUDNN( cudnnGetConvolutionBackwardDataAlgorithm_v7(net->cudnnHandle,
+ filterDesc, dstTensor, convDesc, srcTensor, 1, &algo_count, &bwAlgo) );
checkCUDNN(cudnnGetConvolutionBackwardDataWorkspaceSize(net->cudnnHandle,
- filterDesc, dstTensor, convDesc, srcTensor,
- bwAlgo, &ws_sizeInBytes));
+ filterDesc, dstTensor, convDesc, srcTensor,
+ bwAlgo.algo, &ws_sizeInBytes));
+
// invert tensors
srcTensorDesc = dstTensor;
dstTensorDesc = srcTensor;
} else {
- checkCUDNN( cudnnGetConvolutionForwardAlgorithm(net->cudnnHandle,
- srcTensor, filterDesc, convDesc, dstTensor,
- CUDNN_CONVOLUTION_FWD_PREFER_FASTEST, 0, &algo) );
- checkCUDNN(cudnnGetConvolutionForwardWorkspaceSize(net->cudnnHandle,
- srcTensor, filterDesc, convDesc, dstTensor,
- algo, &ws_sizeInBytes));
+
+ checkCUDNN( cudnnGetConvolutionForwardAlgorithm_v7(net->cudnnHandle,
+ srcTensor, filterDesc, convDesc, dstTensor,
+ 1, &algo_count, &algo) );
+ checkCUDNN(cudnnGetConvolutionForwardWorkspaceSize(net->cudnnHandle,
+ srcTensor, filterDesc, convDesc, dstTensor,
+ algo.algo, &ws_sizeInBytes));
}
+
+ if(algo_count < 1)
+ FatalError("Cannot retrieve convolutional algo");
}
void Conv2d::inferCUDNN(dnnType* srcData, bool back) {
@@ -91,12 +96,12 @@ void Conv2d::inferCUDNN(dnnType* srcData, bool back) {
checkCUDNN(cudnnConvolutionBackwardData(net->cudnnHandle,
&alpha, filterDesc, data_d,
srcTensorDesc, srcData,
- convDesc, bwAlgo, workSpace, ws_sizeInBytes,
+ convDesc, bwAlgo.algo, workSpace, ws_sizeInBytes,
&beta, dstTensorDesc, dstData));
} else {
checkCUDNN(cudnnConvolutionForward(net->cudnnHandle,
&alpha, srcTensorDesc, srcData, filterDesc,
- data_d, convDesc, algo, workSpace, ws_sizeInBytes,
+ data_d, convDesc, algo.algo, workSpace, ws_sizeInBytes,
&beta, dstTensorDesc, dstData));
}
diff --git a/src/DarknetParser.cpp b/src/DarknetParser.cpp
index 5092595..69b6b29 100644
--- a/src/DarknetParser.cpp
+++ b/src/DarknetParser.cpp
@@ -37,7 +37,10 @@ namespace tk { namespace dnn {
std::string name,value;
if(!divideNameAndValue(line, name, value))
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);
else if(name.find("height") != std::string::npos)
fields.height = std::stoi(value);
@@ -75,8 +78,17 @@ namespace tk { namespace dnn {
fields.coords = std::stoi(value);
else if(name.find("groups") != std::string::npos)
fields.groups = std::stoi(value);
+ else if(name.find("group_id") != std::string::npos)
+ fields.group_id = std::stoi(value);
else if(name.find("scale_x_y") != std::string::npos)
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 "<getLayerName()<<"\n";
layers.push_back(netLayers[layerIdx]);
}
- netLayers.push_back(new tk::dnn::Route(net, layers.data(), layers.size()));
+ netLayers.push_back(new tk::dnn::Route(net, layers.data(), layers.size(), f.groups, f.group_id));
} else if(f.type == "reorg") {
netLayers.push_back(new tk::dnn::Reorg(net, f.stride_x));
@@ -159,7 +171,7 @@ namespace tk { namespace dnn {
} else if(f.type == "yolo") {
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);
- 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)
FatalError("Mismatch between number of classes and names");
l->classesNames = names;
@@ -175,6 +187,7 @@ namespace tk { namespace dnn {
if(f.activation == "relu") act = tkdnnActivationMode_t(CUDNN_ACTIVATION_RELU);
else if(f.activation == "leaky") act = tk::dnn::ACTIVATION_LEAKY;
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); }
netLayers[netLayers.size()-1] = new tk::dnn::Activation(net, act);
};
@@ -199,7 +212,7 @@ namespace tk { namespace dnn {
tk::dnn::Network *net = nullptr;
- // layers without activations to retrive correct id number
+ // layers without activations to retrieve correct id number
std::vector netLayers;
std::ifstream if_cfg(cfg_file);
diff --git a/src/DeformConv2d.cpp b/src/DeformConv2d.cpp
index b161a22..dbb71e1 100644
--- a/src/DeformConv2d.cpp
+++ b/src/DeformConv2d.cpp
@@ -95,7 +95,7 @@ dnnType* DeformConv2d::infer(dataDim_t &dim, dnnType* srcData) {
// split conv2d outputs into offset and mask
checkCuda(cudaMemcpy(offset, output_conv, 2*chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
checkCuda(cudaMemcpy(mask, output_conv + 2*chunk_dim, chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
- // kernel sigmoide
+ // kernel sigmoid
activationSIGMOIDForward(mask, mask, chunk_dim);
// deformable convolution
diff --git a/src/Dense.cpp b/src/Dense.cpp
index b6a9af2..4371d06 100644
--- a/src/Dense.cpp
+++ b/src/Dense.cpp
@@ -37,7 +37,7 @@ dnnType* Dense::infer(dataDim_t &dim, dnnType* srcData) {
// place bias into dstData
checkCuda( cudaMemcpy(dstData, bias_d, dim_y*sizeof(dnnType), cudaMemcpyDeviceToDevice) );
- //do matrix moltiplication
+ //do matrix multiplication
checkERROR( cublasSgemv(net->cublasHandle, CUBLAS_OP_T,
dim_x, dim_y,
&alpha,
diff --git a/src/Int8BatchStream.cpp b/src/Int8BatchStream.cpp
index dd4399f..fdc1db2 100644
--- a/src/Int8BatchStream.cpp
+++ b/src/Int8BatchStream.cpp
@@ -132,21 +132,14 @@ void BatchStream::readCVimage(std::string inputFileName, std::vector& res
void BatchStream::readLabels(std::string inputFileName, std::vector& ris) {
std::ifstream is(inputFileName.c_str());
- //read only the first number: the image sub-portion class
- while (true) {
+
+ std::string line;
+ while (std::getline(is, line))
+ {
+ std::istringstream iss(line);
float val;
- is >> val;
- if (!is) {
- break;
- }
- // insert the first number and skip all others
+ if(!(iss >> val)) { break; } // error
ris.push_back(val);
- while( true ) {
- char c;
- is >> c;
- if (is.peek() == '\n') //detect "\n"
- break;
- }
}
}
diff --git a/src/LSTM.cpp b/src/LSTM.cpp
index 511fbee..d0429e0 100644
--- a/src/LSTM.cpp
+++ b/src/LSTM.cpp
@@ -87,17 +87,22 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig
checkCUDNN(cudnnCreateRNNDescriptor(&rnnDesc));
#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
- checkCUDNN(cudnnSetRNNDescriptor(net->cudnnHandle,
-#endif
- rnnDesc, stateSize, numLayers, dropoutDesc,
+ checkCUDNN(cudnnSetRNNDescriptor(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));
+#endif
// Get temp space sizes
@@ -133,7 +138,7 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig
output_dim = input_dim;
output_dim.c = stateSize*(bidirectional ? 2 : 1);
- // if retunseq is disabled only the last timestep is returned
+ // if retunseq is disabled only the last timestamp is returned
if(!returnSeq) {
output_dim.h = 1;
output_dim.w = 1;
@@ -254,7 +259,7 @@ dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) {
rnnDesc,
seqLen, // number of time steps (nT)
x_desc_vec_.data(), // input array of desc (nT*nC_in)
- srcF, // input pointer
+ srcF, // input pointer
hx_desc_, // initial hidden state desc
hx_ptr, // initial hidden state pointer
cx_desc_, // initial cell state desc
@@ -281,7 +286,7 @@ dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) {
rnnDesc,
seqLen, // number of time steps (nT)
x_desc_vec_.data(), // input array of desc (nT*nC_in)
- srcB, // input pointer
+ srcB, // input pointer
hx_desc_, // initial hidden state desc
hx_ptr, // initial hidden state pointer
cx_desc_, // initial cell state desc
@@ -289,7 +294,7 @@ dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) {
w_desc_, // weights desc
wb_ptr, // weights pointer
y_desc_vec_.data(), // output desc (nT*nC_out)
- dstB_NR, // output pointer
+ dstB_NR, // output pointer
hy_desc_, // final hidden state desc
hy_ptr, // final hidden state pointer
cy_desc_, // final cell state desc
@@ -307,7 +312,7 @@ dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) {
one_output_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
}
- // if retunseq is disabled only the last timestep is returned
+ // if retunseq is disabled only the last timestamp is returned
if(returnSeq) {
// forward transpose
matrixTranspose(net->cublasHandle, dstF, dstData,
diff --git a/src/LayerWgs.cpp b/src/LayerWgs.cpp
index 820fb9e..ba7239a 100644
--- a/src/LayerWgs.cpp
+++ b/src/LayerWgs.cpp
@@ -106,7 +106,7 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs,
float2half(tmp_d, variance16_d, b_size);
cudaMemcpy(variance16_h, variance16_d, b_size*sizeof(__half), cudaMemcpyDeviceToHost);
- //conver scales
+ //convert scales
float2half(scales_d, scales16_d, b_size);
cudaMemcpy(scales16_h, scales16_d, b_size*sizeof(__half), cudaMemcpyDeviceToHost);
diff --git a/src/MobilenetDetection.cpp b/src/MobilenetDetection.cpp
index c905fea..3c54e28 100644
--- a/src/MobilenetDetection.cpp
+++ b/src/MobilenetDetection.cpp
@@ -126,12 +126,13 @@ float MobilenetDetection::iou(const tk::dnn::box &a, const tk::dnn::box &b){
return iou;
}
-bool MobilenetDetection::init(const std::string& tensor_path, const int n_classes, const int n_batches){
+bool MobilenetDetection::init(const std::string& tensor_path, const int n_classes, const int n_batches, const float conf_thresh){
std::cout<<(tensor_path).c_str()<<"\n";
netRT = new tk::dnn::NetworkRT(NULL, (tensor_path).c_str());
imageSize = netRT->input_dim.h;
classes = n_classes;
nBatches = n_batches;
+ confThreshold = conf_thresh;
SSDSpec specs[N_SSDSPEC];
diff --git a/src/MulAdd.cpp b/src/MulAdd.cpp
index 0c2a962..25cec8d 100644
--- a/src/MulAdd.cpp
+++ b/src/MulAdd.cpp
@@ -12,7 +12,7 @@ MulAdd::MulAdd(Network *net, dnnType mul, dnnType add) : Layer(net) {
int size = input_dim.tot();
- // create a vector with all value setted to add
+ // create a vector with all value set to add
dnnType *add_vector_h = new dnnType[size];
for(int i=0; ibuildEngineWithConfig(*networkRT, *configRT);
#else
engineRT = builderRT->buildCudaEngine(*networkRT);
+ //engineRT = std::shared_ptr(builderRT->buildCudaEngine(*networkRT));
#endif
if(engineRT == nullptr)
FatalError("cloud not build cuda engine")
@@ -163,7 +164,7 @@ NetworkRT::NetworkRT(Network *net, const char *name) {
// note that indices are guaranteed to be less than IEngine::getNbBindings()
buf_input_idx = engineRT->getBindingIndex("data");
buf_output_idx = engineRT->getBindingIndex("out");
- std::cout<<"input idex = "< output index = "< output index = "<getBindingDimensions(buf_input_idx);
@@ -226,7 +227,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Layer *l) {
return convert_layer(input, (Conv2d*) l);
if(type == LAYER_POOLING)
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);
if(type == LAYER_SOFTMAX)
return convert_layer(input, (Softmax*) l);
@@ -423,6 +424,12 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) {
checkNULL(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 {
FatalError("this Activation mode is not yet implemented");
return NULL;
@@ -451,12 +458,15 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Route *l) {
// }
// std::cout<<"\n";
}
-
- IConcatenationLayer *lRT = networkRT->addConcatenation(tens, l->layers_n);
- //IPlugin *plugin = new RouteRT();
- //IPluginLayer *lRT = networkRT->addPlugin(tens, l->layers_n, *plugin);
- checkNULL(lRT);
+ if(l->groups > 1){
+ IPlugin *plugin = new RouteRT(l->groups, l->group_id);
+ IPluginLayer *lRT = networkRT->addPlugin(tens, l->layers_n, *plugin);
+ checkNULL(lRT);
+ return lRT;
+ }
+ IConcatenationLayer *lRT = networkRT->addConcatenation(tens, l->layers_n);
+ checkNULL(lRT);
return lRT;
}
@@ -538,7 +548,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Yolo *l) {
//std::cout<<"convert 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);
checkNULL(lRT);
return lRT;
@@ -570,7 +580,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, DeformConv2d *l) {
IPluginLayer *lRT = networkRT->addPlugin(inputs, 2, *plugin);
checkNULL(lRT);
lRT->setName( ("Deformable" + std::to_string(l->id)).c_str() );
- delete(inputs);
+ delete[](inputs);
// batchnorm
void *bias_b, *power_b, *mean_b, *variance_b, *scales_b;
if(dtRT == DataType::kHALF) {
@@ -647,7 +657,7 @@ bool NetworkRT::deserialize(const char *filename) {
IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialData, size_t serialLength) {
- const char * buf = reinterpret_cast(serialData);
+ const char * buf = reinterpret_cast(serialData),*bufCheck = buf;
std::string name(layerName);
//std::cout<(buf));
a->size = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
return a;
}
if(name.find("ActivationMish") == 0) {
ActivationMishRT *a = new ActivationMishRT();
a->size = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
+ return a;
+ }
+ if(name.find("ActivationLogistic") == 0) {
+ ActivationLogisticRT *a = new ActivationLogisticRT();
+ a->size = readBUF(buf);
+ return a;
+ }
+ if(name.find("ActivationLogistic") == 0) {
+ ActivationLogisticRT *a = new ActivationLogisticRT();
+ a->size = readBUF(buf);
return a;
}
if(name.find("ActivationCReLU") == 0) {
- ActivationReLUCeiling *a = new ActivationReLUCeiling(readBUF(buf));
+ float activationReluTemp = readBUF(buf);
+ ActivationReLUCeiling* a = new ActivationReLUCeiling(activationReluTemp);
a->size = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
return a;
}
if(name.find("Region") == 0) {
- RegionRT *r = new RegionRT(readBUF(buf), //classes
- readBUF(buf), //coords
- readBUF(buf)); //num
+ int classesTemp = readBUF(buf);
+ int coordsTemp = readBUF(buf);
+ int numTemp = readBUF(buf);
+ RegionRT* r = new RegionRT(classesTemp, coordsTemp, numTemp);
r->c = readBUF(buf);
r->h = readBUF(buf);
r->w = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
return r;
}
if(name.find("Reorg") == 0) {
- ReorgRT *r = new ReorgRT(readBUF(buf)); //stride
+ int strideTemp = readBUF(buf);
+ ReorgRT *r = new ReorgRT(strideTemp);
r->c = readBUF(buf);
r->h = readBUF(buf);
r->w = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
return r;
}
@@ -699,27 +727,34 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
r->h = readBUF(buf);
r->w = readBUF(buf);
return r;
+ assert(buf == bufCheck + serialLength);
}
if(name.find("Pooling") == 0) {
- MaxPoolFixedSizeRT *r = new MaxPoolFixedSizeRT( readBUF(buf), //c
- readBUF(buf), //h
- readBUF(buf), //w
- readBUF(buf), //n
- readBUF(buf), //strideH
- readBUF(buf), //strideW
- readBUF(buf), //winSize
- readBUF(buf)); //padding
+ int cTemp = readBUF(buf);
+ int hTemp = readBUF(buf);
+ int wTemp = readBUF(buf);
+ int nTemp = readBUF(buf);
+ int strideHTemp = readBUF(buf);
+ int strideWTemp = readBUF(buf);
+ int winSizeTemp = readBUF(buf);
+ int paddingTemp = readBUF(buf);
+
+ MaxPoolFixedSizeRT* r = new MaxPoolFixedSizeRT(cTemp, hTemp, wTemp, nTemp, strideHTemp, strideWTemp, winSizeTemp, paddingTemp);
+ assert(buf == bufCheck + serialLength);
return r;
}
if(name.find("Resize") == 0) {
- ResizeLayerRT *r = new ResizeLayerRT(readBUF(buf), //o_c
- readBUF(buf), //o_h
- readBUF(buf)); //o_w
+ int o_cTemp = readBUF(buf);
+ int o_hTemp = readBUF(buf);
+ int o_wTemp = readBUF(buf);
+ ResizeLayerRT* r = new ResizeLayerRT(o_cTemp, o_hTemp, o_wTemp);
+
r->i_c = readBUF(buf);
r->i_h = readBUF(buf);
r->i_w = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
return r;
}
@@ -730,6 +765,7 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
r->w = readBUF(buf);
r->rows = readBUF(buf);
r->cols = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
return r;
}
@@ -741,19 +777,28 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
new_dim.h = readBUF(buf);
new_dim.w = readBUF(buf);
ReshapeRT *r = new ReshapeRT(new_dim);
+ assert(buf == bufCheck + serialLength);
return r;
}
if(name.find("Yolo") == 0) {
- YoloRT *r = new YoloRT(readBUF(buf), //classes
- readBUF(buf), //num
- nullptr,
- readBUF(buf)); //n_masks
+
+ int classes_temp = readBUF(buf);
+ int num_temp = readBUF(buf);
+ int n_masks_temp = readBUF(buf);
+ float scale_xy_temp = readBUF(buf);
+ float nms_thresh_temp = readBUF(buf);
+ int nms_kind_temp = readBUF(buf);
+ int new_coords_temp = readBUF(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(buf);
r->h = readBUF(buf);
r->w = readBUF(buf);
- r->scaleXY = readBUF(buf);
for(int i=0; in_masks; i++)
r->mask[i] = readBUF(buf);
for(int i=0; in_masks*2*r->num; i++)
@@ -767,36 +812,54 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
tmp[j] = readBUF(buf);
r->classesNames[i] = std::string(tmp);
}
+ assert(buf == bufCheck + serialLength);
yolos[n_yolos++] = r;
return r;
}
if(name.find("Upsample") == 0) {
- UpsampleRT *r = new UpsampleRT(readBUF(buf)); //stride
+ int strideTemp = readBUF(buf);
+ UpsampleRT* r = new UpsampleRT(strideTemp);
r->c = readBUF(buf);
r->h = readBUF(buf);
r->w = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
return r;
}
-/*
+
if(name.find("Route") == 0) {
- RouteRT *r = new RouteRT();
+ int groupsTemp = readBUF(buf);
+ int group_idTemp = readBUF(buf);
+ RouteRT* r = new RouteRT(groupsTemp, group_idTemp);
r->in = readBUF(buf);
for(int i=0; ic_in[i] = readBUF(buf);
r->c = readBUF(buf);
r->h = readBUF(buf);
r->w = readBUF(buf);
+ assert(buf == bufCheck + serialLength);
return r;
}
-*/
+
if(name.find("Deformable") == 0) {
- DeformableConvRT *r = new DeformableConvRT(readBUF(buf), readBUF(buf), readBUF(buf),
- readBUF(buf), readBUF(buf), readBUF(buf),
- readBUF(buf), readBUF(buf),
- readBUF(buf),readBUF(buf),readBUF(buf),readBUF(buf),
- readBUF(buf),readBUF(buf),readBUF(buf),readBUF(buf),
- nullptr);
+ int chuck_dimTemp = readBUF(buf);
+ int khTemp = readBUF(buf);
+ int kwTemp = readBUF(buf);
+ int shTemp = readBUF(buf);
+ int swTemp = readBUF(buf);
+ int phTemp = readBUF(buf);
+ int pwTemp = readBUF(buf);
+ int deformableGroupTemp = readBUF(buf);
+ int i_nTemp = readBUF(buf);
+ int i_cTemp = readBUF(buf);
+ int i_hTemp = readBUF(buf);
+ int i_wTemp = readBUF(buf);
+ int o_nTemp = readBUF(buf);
+ int o_cTemp = readBUF(buf);
+ int o_hTemp = readBUF(buf);
+ int o_wTemp = readBUF(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];
for(int i=0; ichunk_dim*2; i++)
aus[i] = readBUF(buf);
@@ -827,6 +890,7 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
aus[i] = readBUF(buf);
checkCuda( cudaMemcpy(r->ones_d2, aus, sizeof(dnnType)*r->dim_ones, cudaMemcpyHostToDevice) );
free(aus);
+ assert(buf == bufCheck + serialLength);
return r;
}
diff --git a/src/Region.cpp b/src/Region.cpp
index 65bb786..7c26208 100644
--- a/src/Region.cpp
+++ b/src/Region.cpp
@@ -63,7 +63,7 @@ dnnType* Region::infer(dataDim_t &dim, dnnType* srcData) {
}
-/* Intepret class */
+/* Interpret class */
RegionInterpret::RegionInterpret(dataDim_t input_dim, dataDim_t output_dim,
int classes, int coords, int num, float thresh, std::string fname_weights) {
diff --git a/src/Route.cpp b/src/Route.cpp
index 39bb14e..816566e 100644
--- a/src/Route.cpp
+++ b/src/Route.cpp
@@ -5,7 +5,7 @@
namespace tk { namespace dnn {
-Route::Route(Network *net, Layer **layers, int layers_n) : Layer(net) {
+Route::Route(Network *net, Layer **layers, int layers_n, int groups, int group_id) : Layer(net) {
// copy input layers
if(layers_n > MAX_LAYERS) {
@@ -15,6 +15,8 @@ Route::Route(Network *net, Layer **layers, int layers_n) : Layer(net) {
this->layers[i] = layers[i];
}
this->layers_n = layers_n;
+ this->groups = groups;
+ this->group_id = group_id;
//get dims
output_dim.l = 1;
@@ -32,6 +34,7 @@ Route::Route(Network *net, Layer **layers, int layers_n) : Layer(net) {
output_dim.c += layers[i]->output_dim.c;
}
+ output_dim.c /= this->groups;
input_dim = output_dim;
checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) );
@@ -49,8 +52,9 @@ dnnType* Route::infer(dataDim_t &dim, dnnType* srcData) {
for(int i=0; idstData;
int in_dim = layers[i]->output_dim.tot();
- checkCuda( cudaMemcpy(dstData + offset, input, in_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
- offset += in_dim;
+ int part_in_dim = in_dim / this->groups;
+ checkCuda( cudaMemcpy(dstData + offset, input + this->group_id*part_in_dim, part_in_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
+ offset += part_in_dim;
}
//update data dimensions
diff --git a/src/Yolo.cpp b/src/Yolo.cpp
index a4416be..eaf1de7 100644
--- a/src/Yolo.cpp
+++ b/src/Yolo.cpp
@@ -9,9 +9,10 @@
#include "Layer.h"
#include "kernels.h"
+
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) {
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->n_masks = n_masks;
this->scaleXY = scale_xy;
+ this->nms_thresh = nms_thresh;
+ this->nsm_kind = nsm_kind;
+ this->new_coords = new_coords;
// load anchors
if(fname_weights != "") {
@@ -59,12 +63,21 @@ int entry_index(int batch, int location, int entry,
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;
- b.x = (i + x[index + 0*stride]) / lw;
- 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;
+
+ if(new_coords == 0){
+ b.x = (i + x[index + 0*stride]) / lw;
+ 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;
}
@@ -75,12 +88,17 @@ dnnType* Yolo::infer(dataDim_t &dim, dnnType* srcData) {
for (int b = 0; b < dim.n; ++b){
for(int n = 0; n < n_masks; ++n){
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);
+ std::cout<<"new_coords"<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);
-
- 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);
+ 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);
+ activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*dim.w*dim.h);
+ }
}
}
@@ -116,7 +134,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)
predictions = new dnnType[output_dim.tot()];
@@ -140,7 +158,7 @@ int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int netw, int net
if(objectness <= thresh) continue;
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].classes = classes;
for(j = 0; j < classes; ++j){
@@ -193,6 +211,32 @@ float yolo_box_iou(Yolo::box a, Yolo::box 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)
{
Yolo::detection a = *(Yolo::detection *)pa;
@@ -219,8 +263,7 @@ Yolo::detection *Yolo::allocateDetections(int nboxes, int classes) {
return dets;
}
-void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes) {
- double nms_thresh = 0.45;
+void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes, double nms_thresh, nmsKind_t nsm_kind) {
int total = ndets;
int i, j, k;
@@ -246,13 +289,13 @@ void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes) {
box a = dets[i].bbox;
for(j = i+1; j < total; ++j){
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;
- }
}
}
}
-
}
}}
diff --git a/src/Yolo3Detection.cpp b/src/Yolo3Detection.cpp
index c76af20..0c638e6 100644
--- a/src/Yolo3Detection.cpp
+++ b/src/Yolo3Detection.cpp
@@ -3,13 +3,14 @@
namespace tk { namespace dnn {
-bool Yolo3Detection::init(const std::string& tensor_path, const int n_classes, const int n_batches) {
+bool Yolo3Detection::init(const std::string& tensor_path, const int n_classes, const int n_batches, const float conf_thresh) {
//convert network to tensorRT
std::cout<<(tensor_path).c_str()<<"\n";
netRT = new tk::dnn::NetworkRT(NULL, (tensor_path).c_str() );
nBatches = n_batches;
+ confThreshold = conf_thresh;
tk::dnn::dataDim_t idim = netRT->input_dim;
idim.n = nBatches;
@@ -31,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);
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]->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);
@@ -90,9 +94,10 @@ void Yolo3Detection::preprocess(cv::Mat &frame, const int bi){
void Yolo3Detection::postprocess(const int bi, const bool mAP){
//get yolo outputs
- dnnType *rt_out[netRT->pluginFactory->n_yolos];
- for(int i=0; ipluginFactory->n_yolos; i++)
- rt_out[i] = (dnnType*)netRT->buffersRT[i+1] + netRT->buffersDIM[i+1].tot()*bi;
+ std::vector rt_out;
+ //dnnType *rt_out[netRT->pluginFactory->n_yolos];
+ for(int i=0; ipluginFactory->n_yolos; i++)
+ 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 y_ratio = float(originalSize[bi].height) / float(netRT->input_dim.h);
@@ -101,46 +106,47 @@ void Yolo3Detection::postprocess(const int bi, const bool mAP){
nDets = 0;
for(int i=0; ipluginFactory->n_yolos; 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
detected.clear();
for(int j=0; j= confThreshold) {
- obj_class = c;
- prob = dets[j].prob[c];
+ int obj_class = c;
+ float prob = dets[j].prob[c];
+
+ tk::dnn::box res;
+ res.cl = obj_class;
+ res.prob = prob;
+ res.x = x0;
+ res.y = y0;
+ res.w = x1 - x0;
+ res.h = y1 - y0;
+
+ // FIXME: this shuld be useless
+ // if(mAP)
+ // for(int c=0; c= 0) {
- // convert to image coords
- x0 = x_ratio*x0;
- x1 = x_ratio*x1;
- y0 = y_ratio*y0;
- y1 = y_ratio*y1;
-
- tk::dnn::box res;
- res.cl = obj_class;
- res.prob = prob;
- res.x = x0;
- res.y = y0;
- res.w = x1 - x0;
- res.h = y1 - y0;
- if(mAP)
- for(int c=0; c