Skip to content

Commit 4b2ef40

Browse files
authored
tensorRT RefineDet (wang-xinyu#443)
1 parent 1336337 commit 4b2ef40

File tree

9 files changed

+1885
-0
lines changed

9 files changed

+1885
-0
lines changed

refinedet/CMakeLists.txt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
cmake_minimum_required(VERSION 2.6)
2+
3+
project(refinedet)
4+
5+
add_definitions(-std=c++11)
6+
7+
option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
8+
set(CMAKE_CXX_STANDARD 11)
9+
set(CMAKE_BUILD_TYPE Debug)
10+
11+
# tensorrt
12+
include_directories(/data_2/tensorrt/TensorRT-7.0.0.11/include/) #include_directories(/usr/include/x86_64-linux-gnu/)
13+
link_directories(/data_2/tensorrt/TensorRT-7.0.0.11/lib/) #link_directories(/usr/lib/x86_64-linux-gnu/)
14+
15+
16+
find_package(CUDA REQUIRED)
17+
18+
include_directories(${PROJECT_SOURCE_DIR}/include)
19+
# include and link dirs of cuda and tensorrt, you need adapt them if yours are different
20+
# cuda
21+
include_directories(/usr/local/cuda/include)
22+
link_directories(/usr/local/cuda/lib64)
23+
24+
#find_package(OpenCV)
25+
#include_directories(OpenCV_INCLUDE_DIRS)
26+
27+
include_directories(/home/software_install/opencv3.4.6/include)
28+
link_directories(/home/software_install/opencv3.4.6/lib)
29+
30+
31+
set(CMAKE_PREFIX_PATH "/data_1/torch1.1.0") ###torch1.1.0
32+
find_package(Torch REQUIRED)
33+
34+
include_directories(/data_1/torch1.1.0/include)
35+
link_directories(/data_1/torch1.1.0/lib)
36+
37+
38+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Ofast -Wfatal-errors -D_MWAITXINTRIN_H_INCLUDED")
39+
40+
41+
add_executable(refinedet ${PROJECT_SOURCE_DIR}/calibrator.cpp ${PROJECT_SOURCE_DIR}/refinedet.cpp)
42+
target_link_libraries(refinedet nvinfer)
43+
target_link_libraries(refinedet cudart)
44+
target_link_libraries(refinedet "${TORCH_LIBRARIES}")
45+
target_link_libraries(refinedet opencv_calib3d opencv_core opencv_dnn opencv_imgproc opencv_highgui opencv_imgcodecs caffe2)
46+
47+
add_definitions(-O2 -pthread)
48+

refinedet/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# RefineDet
2+
3+
For the Pytorch implementation, you can refer to [luuuyi/RefineDet.PyTorch](https://github.com/luuuyi/RefineDet.PyTorch)
4+
5+
## How to run
6+
```
7+
1. generate wts file. from pytorch
8+
python gen_wts_refinedet.py
9+
// a file 'refinedet.wts' will be generated.
10+
11+
2. build tensorrtx/RefineDet and run or Using clion to open a project(recommend)
12+
Configuration file in configure.h
13+
You need configure your own paths and modes(SERIALIZE or INFER)
14+
Detailed information reference configure.h
15+
mkdir build
16+
cd build
17+
cmake ..
18+
make
19+
```
20+
21+
## dependence
22+
```
23+
TensorRT7.0.0.11
24+
OpenCV >= 3.4
25+
libtorch >=1.1.0
26+
```
27+
28+
29+
## feature
30+
1.tensorrt Multi output
31+
2.L2norm
32+
3.Postprocessing with libtorch
33+
34+
35+
## More Information
36+
37+
See the readme in [home page.](https://github.com/wang-xinyu/tensorrtx)
38+
[tensorrt tutorials](https://github.com/wang-xinyu/tensorrtx/tree/master/tutorials)
39+
For more detailed guidance, see [yhl blog](https://www.cnblogs.com/yanghailin/p/14525128.html)

refinedet/calibrator.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include <iostream>
2+
#include <iterator>
3+
#include <fstream>
4+
#include <opencv2/dnn/dnn.hpp>
5+
#include "calibrator.h"
6+
#include "cuda_runtime_api.h"
7+
#include "utils.h"
8+
9+
Int8EntropyCalibrator2::Int8EntropyCalibrator2(int batchsize, int input_w, int input_h, const char* img_dir, const char* calib_table_name, const char* input_blob_name, bool read_cache)
10+
: batchsize_(batchsize)
11+
, input_w_(input_w)
12+
, input_h_(input_h)
13+
, img_idx_(0)
14+
, img_dir_(img_dir)
15+
, calib_table_name_(calib_table_name)
16+
, input_blob_name_(input_blob_name)
17+
, read_cache_(read_cache)
18+
{
19+
input_count_ = 3 * input_w * input_h * batchsize;
20+
CUDA_CHECK(cudaMalloc(&device_input_, input_count_ * sizeof(float)));
21+
read_files_in_dir(img_dir, img_files_);
22+
}
23+
24+
Int8EntropyCalibrator2::~Int8EntropyCalibrator2()
25+
{
26+
CUDA_CHECK(cudaFree(device_input_));
27+
}
28+
29+
int Int8EntropyCalibrator2::getBatchSize() const
30+
{
31+
return batchsize_;
32+
}
33+
34+
bool Int8EntropyCalibrator2::getBatch(void* bindings[], const char* names[], int nbBindings)
35+
{
36+
if (img_idx_ + batchsize_ > (int)img_files_.size()) {
37+
return false;
38+
}
39+
40+
std::vector<cv::Mat> input_imgs_;
41+
for (int i = img_idx_; i < img_idx_ + batchsize_; i++) {
42+
std::cout << img_files_[i] << " " << i << std::endl;
43+
cv::Mat temp = cv::imread(img_dir_ + img_files_[i]);
44+
if (temp.empty()){
45+
std::cerr << "Fatal error: image cannot open!" << std::endl;
46+
return false;
47+
}
48+
// cv::Mat pr_img = preprocess_img(temp, input_w_, input_h_);
49+
input_imgs_.push_back(temp);
50+
}
51+
img_idx_ += batchsize_;
52+
cv::Mat blob = cv::dnn::blobFromImages(input_imgs_, 1.0, cv::Size(input_w_, input_h_), cv::Scalar(123.0, 117.0, 104.0), true, false);
53+
// cv::Mat blob = cv::dnn::blobFromImages(input_imgs_, 1.0 / 255.0, cv::Size(input_w_, input_h_), cv::Scalar(0, 0, 0), true, false);
54+
55+
CUDA_CHECK(cudaMemcpy(device_input_, blob.ptr<float>(0), input_count_ * sizeof(float), cudaMemcpyHostToDevice));
56+
assert(!strcmp(names[0], input_blob_name_));
57+
bindings[0] = device_input_;
58+
return true;
59+
}
60+
61+
const void* Int8EntropyCalibrator2::readCalibrationCache(size_t& length)
62+
{
63+
std::cout << "reading calib cache: " << calib_table_name_ << std::endl;
64+
calib_cache_.clear();
65+
std::ifstream input(calib_table_name_, std::ios::binary);
66+
input >> std::noskipws;
67+
if (read_cache_ && input.good())
68+
{
69+
std::copy(std::istream_iterator<char>(input), std::istream_iterator<char>(), std::back_inserter(calib_cache_));
70+
}
71+
length = calib_cache_.size();
72+
return length ? calib_cache_.data() : nullptr;
73+
}
74+
75+
void Int8EntropyCalibrator2::writeCalibrationCache(const void* cache, size_t length)
76+
{
77+
std::cout << "writing calib cache: " << calib_table_name_ << " size: " << length << std::endl;
78+
std::ofstream output(calib_table_name_, std::ios::binary);
79+
output.write(reinterpret_cast<const char*>(cache), length);
80+
}
81+

refinedet/calibrator.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef ENTROPY_CALIBRATOR_H
2+
#define ENTROPY_CALIBRATOR_H
3+
4+
#include "NvInfer.h"
5+
#include <string>
6+
#include <vector>
7+
8+
//! \class Int8EntropyCalibrator2
9+
//!
10+
//! \brief Implements Entropy calibrator 2.
11+
//! CalibrationAlgoType is kENTROPY_CALIBRATION_2.
12+
//!
13+
class Int8EntropyCalibrator2 : public nvinfer1::IInt8EntropyCalibrator2
14+
{
15+
public:
16+
Int8EntropyCalibrator2(int batchsize, int input_w, int input_h, const char* img_dir, const char* calib_table_name, const char* input_blob_name, bool read_cache = true);
17+
18+
virtual ~Int8EntropyCalibrator2();
19+
int getBatchSize() const override;
20+
bool getBatch(void* bindings[], const char* names[], int nbBindings) override;
21+
const void* readCalibrationCache(size_t& length) override;
22+
void writeCalibrationCache(const void* cache, size_t length) override;
23+
24+
private:
25+
int batchsize_;
26+
int input_w_;
27+
int input_h_;
28+
int img_idx_;
29+
std::string img_dir_;
30+
std::vector<std::string> img_files_;
31+
size_t input_count_;
32+
std::string calib_table_name_;
33+
const char* input_blob_name_;
34+
bool read_cache_;
35+
void* device_input_;
36+
std::vector<char> calib_cache_;
37+
};
38+
39+
#endif // ENTROPY_CALIBRATOR_H

refinedet/configure.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
#define USE_FP32 // set USE_INT8 or USE_FP16 or USE_FP32
3+
4+
const int num_class = 25; //num_class + 1 //Including background class
5+
6+
//SERIALIZE: It indicates that to generate engin by serialization, the following path needs to be set,path_wts_ and path_save_engine
7+
//INFER: It shows that it is a reasoning mode,the following path needs to be set,path_engine
8+
#define INFER //SERIALIZE INFER
9+
10+
const std::string path_engine = "/data_2//cmake-build-debug/refinedet_0312-now.engine";
11+
const std::string path_wts = "/data_1/refinedet/pytorch_refinedet-master/refinedet0312.wts";
12+
const std::string path_save_engine = "./refinedet_0312-now.engine";
13+
14+
//Picture folder to be detected
15+
const char *p_dir_name = "/data_1/img/";
16+
17+
const float TH = 0.2; //Confidence threshold
18+
const int T_show = 1; //1:Show the effect 0:Test map to generate TXT
19+
//The path to save the generated TXT when testing the map
20+
std::string save_path_txt = "/data_1/txt/";
21+
22+
#define DEVICE 0 // GPU id
23+
24+
// stuff we know about the network and the input/output blobs
25+
static const int INPUT_H = 320;
26+
static const int INPUT_W = 320;
27+
const char* INPUT_BLOB_NAME = "data";
28+
const char* OUTPUT_BLOB_NAME_arm_loc = "arm_loc";
29+
const char* OUTPUT_BLOB_NAME_arm_conf = "arm_conf";
30+
const char* OUTPUT_BLOB_NAME_odm_loc = "odm_loc";
31+
const char* OUTPUT_BLOB_NAME_odm_conf = "odm_conf";
32+
33+
std::string label_map[] =
34+
{
35+
"background",
36+
"aa",
37+
"bb",
38+
"cc",
39+
"dd",
40+
"ee",
41+
"ff",
42+
"gg",
43+
"hh",
44+
"ii",
45+
"jj",
46+
"kk",
47+
"ll",
48+
"mm",
49+
"nn",
50+
"oo",
51+
"pp",
52+
"qq",
53+
"rr",
54+
"ss",
55+
"tt",
56+
"uu",
57+
"vv",
58+
"ww",
59+
"xx"
60+
};

refinedet/gen_wts_refinedet.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import torch
2+
import torch.nn as nn
3+
import struct
4+
from models.refinedet import build_refinedet
5+
6+
7+
8+
num_classes = 25
9+
path_model = "/data_2/project_2021/pytorch_refinedet/2021/20210308.pth"
10+
path_save_wts = "./refinedet0312.wts"
11+
input_size = 320
12+
13+
net = build_refinedet('test', input_size, num_classes) # initialize net
14+
net.load_state_dict(torch.load(path_model))
15+
net.eval()
16+
17+
18+
f = open(path_save_wts, 'w')
19+
f.write('{}\n'.format(len(net.state_dict().keys())))
20+
for k, v in net.state_dict().items():
21+
vr = v.reshape(-1).cpu().numpy()
22+
f.write('{} {} '.format(k, len(vr)))
23+
for vv in vr:
24+
f.write(' ')
25+
f.write(struct.pack('>f',float(vv)).hex())
26+
f.write('\n')
27+
28+
print("success generate wts!")

0 commit comments

Comments
 (0)