从wts文件中读取anhor信息,并传入yololayer plugin (#215)
* 修改图片地址为URL * get Anchor values from wts * get anchor values form wts * get anchor values from wts * get anchor values from wts * 1 using space 2 release heap mem * 1 Using 4 space 2 Delete Chinese comment 3 Load all variables 4 Release heap mem * 1 Using 4 space 2 Delete Chinese comment 3 Load all variables 4 Release heap mem * 1. 函数模块化 2. 格式化代码 3. 同步为最新的yolov5代码
This commit is contained in:
parent
7cd9368fb6
commit
8bdbb47dfa
@ -32,8 +32,9 @@ cv::Mat preprocess_img(cv::Mat& img) {
|
||||
h = r_w * img.rows;
|
||||
x = 0;
|
||||
y = (Yolo::INPUT_H - h) / 2;
|
||||
} else {
|
||||
w = r_h* img.cols;
|
||||
}
|
||||
else {
|
||||
w = r_h * img.cols;
|
||||
h = Yolo::INPUT_H;
|
||||
x = (Yolo::INPUT_W - w) / 2;
|
||||
y = 0;
|
||||
@ -50,40 +51,41 @@ cv::Rect get_rect(cv::Mat& img, float bbox[4]) {
|
||||
float r_w = Yolo::INPUT_W / (img.cols * 1.0);
|
||||
float r_h = Yolo::INPUT_H / (img.rows * 1.0);
|
||||
if (r_h > r_w) {
|
||||
l = bbox[0] - bbox[2]/2.f;
|
||||
r = bbox[0] + bbox[2]/2.f;
|
||||
t = bbox[1] - bbox[3]/2.f - (Yolo::INPUT_H - r_w * img.rows) / 2;
|
||||
b = bbox[1] + bbox[3]/2.f - (Yolo::INPUT_H - r_w * img.rows) / 2;
|
||||
l = bbox[0] - bbox[2] / 2.f;
|
||||
r = bbox[0] + bbox[2] / 2.f;
|
||||
t = bbox[1] - bbox[3] / 2.f - (Yolo::INPUT_H - r_w * img.rows) / 2;
|
||||
b = bbox[1] + bbox[3] / 2.f - (Yolo::INPUT_H - r_w * img.rows) / 2;
|
||||
l = l / r_w;
|
||||
r = r / r_w;
|
||||
t = t / r_w;
|
||||
b = b / r_w;
|
||||
} else {
|
||||
l = bbox[0] - bbox[2]/2.f - (Yolo::INPUT_W - r_h * img.cols) / 2;
|
||||
r = bbox[0] + bbox[2]/2.f - (Yolo::INPUT_W - r_h * img.cols) / 2;
|
||||
t = bbox[1] - bbox[3]/2.f;
|
||||
b = bbox[1] + bbox[3]/2.f;
|
||||
}
|
||||
else {
|
||||
l = bbox[0] - bbox[2] / 2.f - (Yolo::INPUT_W - r_h * img.cols) / 2;
|
||||
r = bbox[0] + bbox[2] / 2.f - (Yolo::INPUT_W - r_h * img.cols) / 2;
|
||||
t = bbox[1] - bbox[3] / 2.f;
|
||||
b = bbox[1] + bbox[3] / 2.f;
|
||||
l = l / r_h;
|
||||
r = r / r_h;
|
||||
t = t / r_h;
|
||||
b = b / r_h;
|
||||
}
|
||||
return cv::Rect(l, t, r-l, b-t);
|
||||
return cv::Rect(l, t, r - l, b - t);
|
||||
}
|
||||
|
||||
float iou(float lbox[4], float rbox[4]) {
|
||||
float interBox[] = {
|
||||
std::max(lbox[0] - lbox[2]/2.f , rbox[0] - rbox[2]/2.f), //left
|
||||
std::min(lbox[0] + lbox[2]/2.f , rbox[0] + rbox[2]/2.f), //right
|
||||
std::max(lbox[1] - lbox[3]/2.f , rbox[1] - rbox[3]/2.f), //top
|
||||
std::min(lbox[1] + lbox[3]/2.f , rbox[1] + rbox[3]/2.f), //bottom
|
||||
(std::max)(lbox[0] - lbox[2] / 2.f , rbox[0] - rbox[2] / 2.f), //left
|
||||
(std::min)(lbox[0] + lbox[2] / 2.f , rbox[0] + rbox[2] / 2.f), //right
|
||||
(std::max)(lbox[1] - lbox[3] / 2.f , rbox[1] - rbox[3] / 2.f), //top
|
||||
(std::min)(lbox[1] + lbox[3] / 2.f , rbox[1] + rbox[3] / 2.f), //bottom
|
||||
};
|
||||
|
||||
if(interBox[2] > interBox[3] || interBox[0] > interBox[1])
|
||||
if (interBox[2] > interBox[3] || interBox[0] > interBox[1])
|
||||
return 0.0f;
|
||||
|
||||
float interBoxS =(interBox[1]-interBox[0])*(interBox[3]-interBox[2]);
|
||||
return interBoxS/(lbox[2]*lbox[3] + rbox[2]*rbox[3] -interBoxS);
|
||||
float interBoxS = (interBox[1] - interBox[0])*(interBox[3] - interBox[2]);
|
||||
return interBoxS / (lbox[2] * lbox[3] + rbox[2] * rbox[3] - interBoxS);
|
||||
}
|
||||
|
||||
bool cmp(const Yolo::Detection& a, const Yolo::Detection& b) {
|
||||
@ -109,7 +111,7 @@ void nms(std::vector<Yolo::Detection>& res, float *output, float conf_thresh, fl
|
||||
res.push_back(item);
|
||||
for (size_t n = m + 1; n < dets.size(); ++n) {
|
||||
if (iou(item.bbox, dets[n].bbox) > nms_thresh) {
|
||||
dets.erase(dets.begin()+n);
|
||||
dets.erase(dets.begin() + n);
|
||||
--n;
|
||||
}
|
||||
}
|
||||
@ -134,7 +136,7 @@ std::map<std::string, Weights> loadWeights(const std::string file) {
|
||||
|
||||
while (count--)
|
||||
{
|
||||
Weights wt{DataType::kFLOAT, nullptr, 0};
|
||||
Weights wt{ DataType::kFLOAT, nullptr, 0 };
|
||||
uint32_t size;
|
||||
|
||||
// Read name and type of blob
|
||||
@ -149,7 +151,7 @@ std::map<std::string, Weights> loadWeights(const std::string file) {
|
||||
input >> std::hex >> val[x];
|
||||
}
|
||||
wt.values = val;
|
||||
|
||||
|
||||
wt.count = size;
|
||||
weightMap[name] = wt;
|
||||
}
|
||||
@ -168,19 +170,19 @@ IScaleLayer* addBatchNorm2d(INetworkDefinition *network, std::map<std::string, W
|
||||
for (int i = 0; i < len; i++) {
|
||||
scval[i] = gamma[i] / sqrt(var[i] + eps);
|
||||
}
|
||||
Weights scale{DataType::kFLOAT, scval, len};
|
||||
|
||||
Weights scale{ DataType::kFLOAT, scval, len };
|
||||
|
||||
float *shval = reinterpret_cast<float*>(malloc(sizeof(float) * len));
|
||||
for (int i = 0; i < len; i++) {
|
||||
shval[i] = beta[i] - mean[i] * gamma[i] / sqrt(var[i] + eps);
|
||||
}
|
||||
Weights shift{DataType::kFLOAT, shval, len};
|
||||
Weights shift{ DataType::kFLOAT, shval, len };
|
||||
|
||||
float *pval = reinterpret_cast<float*>(malloc(sizeof(float) * len));
|
||||
for (int i = 0; i < len; i++) {
|
||||
pval[i] = 1.0;
|
||||
}
|
||||
Weights power{DataType::kFLOAT, pval, len};
|
||||
Weights power{ DataType::kFLOAT, pval, len };
|
||||
|
||||
weightMap[lname + ".scale"] = scale;
|
||||
weightMap[lname + ".shift"] = shift;
|
||||
@ -191,12 +193,12 @@ IScaleLayer* addBatchNorm2d(INetworkDefinition *network, std::map<std::string, W
|
||||
}
|
||||
|
||||
ILayer* convBlock(INetworkDefinition *network, std::map<std::string, Weights>& weightMap, ITensor& input, int outch, int ksize, int s, int g, std::string lname) {
|
||||
Weights emptywts{DataType::kFLOAT, nullptr, 0};
|
||||
Weights emptywts{ DataType::kFLOAT, nullptr, 0 };
|
||||
int p = ksize / 2;
|
||||
IConvolutionLayer* conv1 = network->addConvolutionNd(input, outch, DimsHW{ksize, ksize}, weightMap[lname + ".conv.weight"], emptywts);
|
||||
IConvolutionLayer* conv1 = network->addConvolutionNd(input, outch, DimsHW{ ksize, ksize }, weightMap[lname + ".conv.weight"], emptywts);
|
||||
assert(conv1);
|
||||
conv1->setStrideNd(DimsHW{s, s});
|
||||
conv1->setPaddingNd(DimsHW{p, p});
|
||||
conv1->setStrideNd(DimsHW{ s, s });
|
||||
conv1->setPaddingNd(DimsHW{ p, p });
|
||||
conv1->setNbGroups(g);
|
||||
IScaleLayer* bn1 = addBatchNorm2d(network, weightMap, *conv1->getOutput(0), lname + ".bn", 1e-3);
|
||||
|
||||
@ -211,11 +213,11 @@ ILayer* convBlock(INetworkDefinition *network, std::map<std::string, Weights>& w
|
||||
}
|
||||
|
||||
ILayer* focus(INetworkDefinition *network, std::map<std::string, Weights>& weightMap, ITensor& input, int inch, int outch, int ksize, std::string lname) {
|
||||
ISliceLayer *s1 = network->addSlice(input, Dims3{0, 0, 0}, Dims3{inch, Yolo::INPUT_H / 2, Yolo::INPUT_W / 2}, Dims3{1, 2, 2});
|
||||
ISliceLayer *s2 = network->addSlice(input, Dims3{0, 1, 0}, Dims3{inch, Yolo::INPUT_H / 2, Yolo::INPUT_W / 2}, Dims3{1, 2, 2});
|
||||
ISliceLayer *s3 = network->addSlice(input, Dims3{0, 0, 1}, Dims3{inch, Yolo::INPUT_H / 2, Yolo::INPUT_W / 2}, Dims3{1, 2, 2});
|
||||
ISliceLayer *s4 = network->addSlice(input, Dims3{0, 1, 1}, Dims3{inch, Yolo::INPUT_H / 2, Yolo::INPUT_W / 2}, Dims3{1, 2, 2});
|
||||
ITensor* inputTensors[] = {s1->getOutput(0), s2->getOutput(0), s3->getOutput(0), s4->getOutput(0)};
|
||||
ISliceLayer *s1 = network->addSlice(input, Dims3{ 0, 0, 0 }, Dims3{ inch, Yolo::INPUT_H / 2, Yolo::INPUT_W / 2 }, Dims3{ 1, 2, 2 });
|
||||
ISliceLayer *s2 = network->addSlice(input, Dims3{ 0, 1, 0 }, Dims3{ inch, Yolo::INPUT_H / 2, Yolo::INPUT_W / 2 }, Dims3{ 1, 2, 2 });
|
||||
ISliceLayer *s3 = network->addSlice(input, Dims3{ 0, 0, 1 }, Dims3{ inch, Yolo::INPUT_H / 2, Yolo::INPUT_W / 2 }, Dims3{ 1, 2, 2 });
|
||||
ISliceLayer *s4 = network->addSlice(input, Dims3{ 0, 1, 1 }, Dims3{ inch, Yolo::INPUT_H / 2, Yolo::INPUT_W / 2 }, Dims3{ 1, 2, 2 });
|
||||
ITensor* inputTensors[] = { s1->getOutput(0), s2->getOutput(0), s3->getOutput(0), s4->getOutput(0) };
|
||||
auto cat = network->addConcatenation(inputTensors, 4);
|
||||
auto conv = convBlock(network, weightMap, *cat->getOutput(0), outch, ksize, 1, 1, lname + ".conv");
|
||||
return conv;
|
||||
@ -232,18 +234,18 @@ ILayer* bottleneck(INetworkDefinition *network, std::map<std::string, Weights>&
|
||||
}
|
||||
|
||||
ILayer* bottleneckCSP(INetworkDefinition *network, std::map<std::string, Weights>& weightMap, ITensor& input, int c1, int c2, int n, bool shortcut, int g, float e, std::string lname) {
|
||||
Weights emptywts{DataType::kFLOAT, nullptr, 0};
|
||||
Weights emptywts{ DataType::kFLOAT, nullptr, 0 };
|
||||
int c_ = (int)((float)c2 * e);
|
||||
auto cv1 = convBlock(network, weightMap, input, c_, 1, 1, 1, lname + ".cv1");
|
||||
auto cv2 = network->addConvolutionNd(input, c_, DimsHW{1, 1}, weightMap[lname + ".cv2.weight"], emptywts);
|
||||
auto cv2 = network->addConvolutionNd(input, c_, DimsHW{ 1, 1 }, weightMap[lname + ".cv2.weight"], emptywts);
|
||||
ITensor *y1 = cv1->getOutput(0);
|
||||
for (int i = 0; i < n; i++) {
|
||||
auto b = bottleneck(network, weightMap, *y1, c_, c_, shortcut, g, 1.0, lname + ".m." + std::to_string(i));
|
||||
y1 = b->getOutput(0);
|
||||
}
|
||||
auto cv3 = network->addConvolutionNd(*y1, c_, DimsHW{1, 1}, weightMap[lname + ".cv3.weight"], emptywts);
|
||||
auto cv3 = network->addConvolutionNd(*y1, c_, DimsHW{ 1, 1 }, weightMap[lname + ".cv3.weight"], emptywts);
|
||||
|
||||
ITensor* inputTensors[] = {cv3->getOutput(0), cv2->getOutput(0)};
|
||||
ITensor* inputTensors[] = { cv3->getOutput(0), cv2->getOutput(0) };
|
||||
auto cat = network->addConcatenation(inputTensors, 2);
|
||||
|
||||
IScaleLayer* bn = addBatchNorm2d(network, weightMap, *cat->getOutput(0), lname + ".bn", 1e-4);
|
||||
@ -258,17 +260,17 @@ ILayer* SPP(INetworkDefinition *network, std::map<std::string, Weights>& weightM
|
||||
int c_ = c1 / 2;
|
||||
auto cv1 = convBlock(network, weightMap, input, c_, 1, 1, 1, lname + ".cv1");
|
||||
|
||||
auto pool1 = network->addPoolingNd(*cv1->getOutput(0), PoolingType::kMAX, DimsHW{k1, k1});
|
||||
pool1->setPaddingNd(DimsHW{k1 / 2, k1 / 2});
|
||||
pool1->setStrideNd(DimsHW{1, 1});
|
||||
auto pool2 = network->addPoolingNd(*cv1->getOutput(0), PoolingType::kMAX, DimsHW{k2, k2});
|
||||
pool2->setPaddingNd(DimsHW{k2 / 2, k2 / 2});
|
||||
pool2->setStrideNd(DimsHW{1, 1});
|
||||
auto pool3 = network->addPoolingNd(*cv1->getOutput(0), PoolingType::kMAX, DimsHW{k3, k3});
|
||||
pool3->setPaddingNd(DimsHW{k3 / 2, k3 / 2});
|
||||
pool3->setStrideNd(DimsHW{1, 1});
|
||||
auto pool1 = network->addPoolingNd(*cv1->getOutput(0), PoolingType::kMAX, DimsHW{ k1, k1 });
|
||||
pool1->setPaddingNd(DimsHW{ k1 / 2, k1 / 2 });
|
||||
pool1->setStrideNd(DimsHW{ 1, 1 });
|
||||
auto pool2 = network->addPoolingNd(*cv1->getOutput(0), PoolingType::kMAX, DimsHW{ k2, k2 });
|
||||
pool2->setPaddingNd(DimsHW{ k2 / 2, k2 / 2 });
|
||||
pool2->setStrideNd(DimsHW{ 1, 1 });
|
||||
auto pool3 = network->addPoolingNd(*cv1->getOutput(0), PoolingType::kMAX, DimsHW{ k3, k3 });
|
||||
pool3->setPaddingNd(DimsHW{ k3 / 2, k3 / 2 });
|
||||
pool3->setStrideNd(DimsHW{ 1, 1 });
|
||||
|
||||
ITensor* inputTensors[] = {cv1->getOutput(0), pool1->getOutput(0), pool2->getOutput(0), pool3->getOutput(0)};
|
||||
ITensor* inputTensors[] = { cv1->getOutput(0), pool1->getOutput(0), pool2->getOutput(0), pool3->getOutput(0) };
|
||||
auto cat = network->addConcatenation(inputTensors, 4);
|
||||
|
||||
auto cv2 = convBlock(network, weightMap, *cat->getOutput(0), c2, 1, 1, 1, lname + ".cv2");
|
||||
@ -284,7 +286,7 @@ int read_files_in_dir(const char *p_dir_name, std::vector<std::string> &file_nam
|
||||
struct dirent* p_file = nullptr;
|
||||
while ((p_file = readdir(p_dir)) != nullptr) {
|
||||
if (strcmp(p_file->d_name, ".") != 0 &&
|
||||
strcmp(p_file->d_name, "..") != 0) {
|
||||
strcmp(p_file->d_name, "..") != 0) {
|
||||
//std::string cur_file_name(p_dir_name);
|
||||
//cur_file_name += "/";
|
||||
//cur_file_name += p_file->d_name;
|
||||
@ -297,5 +299,71 @@ int read_files_in_dir(const char *p_dir_name, std::vector<std::string> &file_nam
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<float> GetAnchors(std::map<std::string, Weights>& weightMap)
|
||||
{
|
||||
std::vector<float> anchors_yolo;
|
||||
Weights Yolo_Anchors = weightMap["model.24.anchor_grid"];
|
||||
assert(Yolo_Anchors.count == 18);
|
||||
int each_yololayer_anchorsnum = Yolo_Anchors.count / 3;
|
||||
const float* tempAnchors = (const float*)(Yolo_Anchors.values);
|
||||
for (int i = 0; i < Yolo_Anchors.count; i++)
|
||||
{
|
||||
if (i < each_yololayer_anchorsnum)
|
||||
{
|
||||
anchors_yolo.push_back(const_cast<float*>(tempAnchors)[i]);
|
||||
}
|
||||
if ((i >= each_yololayer_anchorsnum) && (i < (2 * each_yololayer_anchorsnum)))
|
||||
{
|
||||
anchors_yolo.push_back(const_cast<float*>(tempAnchors)[i]);
|
||||
}
|
||||
if (i >= (2 * each_yololayer_anchorsnum))
|
||||
{
|
||||
anchors_yolo.push_back(const_cast<float*>(tempAnchors)[i]);
|
||||
}
|
||||
}
|
||||
return anchors_yolo;
|
||||
}
|
||||
|
||||
IPluginV2Layer* addYoLoLayer(INetworkDefinition *network, std::map<std::string, Weights>& weightMap, IConvolutionLayer* det0, IConvolutionLayer* det1, IConvolutionLayer* det2)
|
||||
{
|
||||
auto creator = getPluginRegistry()->getPluginCreator("YoloLayer_TRT", "1");
|
||||
std::vector<float> anchors_yolo = GetAnchors(weightMap);
|
||||
PluginField pluginMultidata[4];
|
||||
int* NetData = new int[4];
|
||||
NetData[0] = Yolo::CLASS_NUM;
|
||||
NetData[1] = Yolo::INPUT_W;
|
||||
NetData[2] = Yolo::INPUT_H;
|
||||
NetData[3] = Yolo::MAX_OUTPUT_BBOX_COUNT;
|
||||
pluginMultidata[0].data = NetData;
|
||||
pluginMultidata[0].length = 3;
|
||||
std::string name = "netdata";
|
||||
pluginMultidata[0].name = new char[name.size() + 1];
|
||||
strcpy(const_cast<char*>(pluginMultidata[0].name), name.c_str());
|
||||
pluginMultidata[0].type = PluginFieldType::kFLOAT32;
|
||||
int scale[3] = { 8, 16, 32 };
|
||||
for (int k = 1; k < 4; k++)
|
||||
{
|
||||
int* plugindata = new int[8];
|
||||
plugindata[0] = Yolo::INPUT_W / scale[k - 1];
|
||||
plugindata[1] = Yolo::INPUT_H / scale[k - 1];
|
||||
for (int i = 2; i < 8; i++)
|
||||
{
|
||||
plugindata[i] = int(anchors_yolo[(k - 1) * 6 + i - 2]);
|
||||
}
|
||||
pluginMultidata[k].data = plugindata;
|
||||
pluginMultidata[k].length = 8;
|
||||
std::string name = "yolodata" + std::to_string(k);
|
||||
pluginMultidata[k].name = new char[name.size() + 1];
|
||||
strcpy(const_cast<char*>(pluginMultidata[k].name), name.c_str());
|
||||
pluginMultidata[k].type = PluginFieldType::kFLOAT32;
|
||||
}
|
||||
PluginFieldCollection pluginData;
|
||||
pluginData.nbFields = 4;
|
||||
pluginData.fields = pluginMultidata;
|
||||
IPluginV2 *pluginObj = creator->createPlugin("yololayer", &pluginData);
|
||||
ITensor* inputTensors_yolo[] = { det2->getOutput(0), det1->getOutput(0), det0->getOutput(0) };
|
||||
auto yolo = network->addPluginV2(inputTensors_yolo, 3, *pluginObj);
|
||||
return yolo;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -6,29 +6,27 @@ using namespace Yolo;
|
||||
|
||||
namespace nvinfer1
|
||||
{
|
||||
YoloLayerPlugin::YoloLayerPlugin()
|
||||
YoloLayerPlugin::YoloLayerPlugin(int classCount, int netWidth, int netHeight, int maxOut, const std::vector<Yolo::YoloKernel>& vYoloKernel)
|
||||
{
|
||||
mClassCount = CLASS_NUM;
|
||||
mYoloKernel.clear();
|
||||
mYoloKernel.push_back(yolo1);
|
||||
mYoloKernel.push_back(yolo2);
|
||||
mYoloKernel.push_back(yolo3);
|
||||
|
||||
mKernelCount = mYoloKernel.size();
|
||||
mClassCount = classCount;
|
||||
mYoloV5NetWidth = netWidth;
|
||||
mYoloV5NetHeight = netHeight;
|
||||
mMaxOutObject = maxOut;
|
||||
mYoloKernel = vYoloKernel;
|
||||
mKernelCount = vYoloKernel.size();
|
||||
|
||||
CUDA_CHECK(cudaMallocHost(&mAnchor, mKernelCount * sizeof(void*)));
|
||||
size_t AnchorLen = sizeof(float)* CHECK_COUNT*2;
|
||||
for(int ii = 0; ii < mKernelCount; ii ++)
|
||||
size_t AnchorLen = sizeof(float)* CHECK_COUNT * 2;
|
||||
for (int ii = 0; ii < mKernelCount; ii++)
|
||||
{
|
||||
CUDA_CHECK(cudaMalloc(&mAnchor[ii],AnchorLen));
|
||||
CUDA_CHECK(cudaMalloc(&mAnchor[ii], AnchorLen));
|
||||
const auto& yolo = mYoloKernel[ii];
|
||||
CUDA_CHECK(cudaMemcpy(mAnchor[ii], yolo.anchors, AnchorLen, cudaMemcpyHostToDevice));
|
||||
}
|
||||
}
|
||||
|
||||
YoloLayerPlugin::~YoloLayerPlugin()
|
||||
{
|
||||
for(int ii = 0; ii < mKernelCount; ii ++)
|
||||
for (int ii = 0; ii < mKernelCount; ii++)
|
||||
{
|
||||
CUDA_CHECK(cudaFree(mAnchor[ii]));
|
||||
}
|
||||
@ -43,20 +41,21 @@ namespace nvinfer1
|
||||
read(d, mClassCount);
|
||||
read(d, mThreadCount);
|
||||
read(d, mKernelCount);
|
||||
read(d, mYoloV5NetWidth);
|
||||
read(d, mYoloV5NetHeight);
|
||||
read(d, mMaxOutObject);
|
||||
mYoloKernel.resize(mKernelCount);
|
||||
auto kernelSize = mKernelCount*sizeof(YoloKernel);
|
||||
memcpy(mYoloKernel.data(),d,kernelSize);
|
||||
auto kernelSize = mKernelCount * sizeof(YoloKernel);
|
||||
memcpy(mYoloKernel.data(), d, kernelSize);
|
||||
d += kernelSize;
|
||||
|
||||
CUDA_CHECK(cudaMallocHost(&mAnchor, mKernelCount * sizeof(void*)));
|
||||
size_t AnchorLen = sizeof(float)* CHECK_COUNT*2;
|
||||
for(int ii = 0; ii < mKernelCount; ii ++)
|
||||
size_t AnchorLen = sizeof(float)* CHECK_COUNT * 2;
|
||||
for (int ii = 0; ii < mKernelCount; ii++)
|
||||
{
|
||||
CUDA_CHECK(cudaMalloc(&mAnchor[ii],AnchorLen));
|
||||
CUDA_CHECK(cudaMalloc(&mAnchor[ii], AnchorLen));
|
||||
const auto& yolo = mYoloKernel[ii];
|
||||
CUDA_CHECK(cudaMemcpy(mAnchor[ii], yolo.anchors, AnchorLen, cudaMemcpyHostToDevice));
|
||||
}
|
||||
|
||||
assert(d == a + length);
|
||||
}
|
||||
|
||||
@ -67,27 +66,30 @@ namespace nvinfer1
|
||||
write(d, mClassCount);
|
||||
write(d, mThreadCount);
|
||||
write(d, mKernelCount);
|
||||
auto kernelSize = mKernelCount*sizeof(YoloKernel);
|
||||
memcpy(d,mYoloKernel.data(),kernelSize);
|
||||
write(d, mYoloV5NetWidth);
|
||||
write(d, mYoloV5NetHeight);
|
||||
write(d, mMaxOutObject);
|
||||
auto kernelSize = mKernelCount * sizeof(YoloKernel);
|
||||
memcpy(d, mYoloKernel.data(), kernelSize);
|
||||
d += kernelSize;
|
||||
|
||||
assert(d == a + getSerializationSize());
|
||||
}
|
||||
|
||||
|
||||
size_t YoloLayerPlugin::getSerializationSize() const
|
||||
{
|
||||
return sizeof(mClassCount) + sizeof(mThreadCount) + sizeof(mKernelCount) + sizeof(Yolo::YoloKernel) * mYoloKernel.size();
|
||||
{
|
||||
return sizeof(mClassCount) + sizeof(mThreadCount) + sizeof(mKernelCount) + sizeof(Yolo::YoloKernel) * mYoloKernel.size() + sizeof(mYoloV5NetWidth) + sizeof(mYoloV5NetHeight) + sizeof(mMaxOutObject);
|
||||
}
|
||||
|
||||
int YoloLayerPlugin::initialize()
|
||||
{
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Dims YoloLayerPlugin::getOutputDimensions(int index, const Dims* inputs, int nbInputDims)
|
||||
{
|
||||
//output the result to channel
|
||||
int totalsize = MAX_OUTPUT_BBOX_COUNT * sizeof(Detection) / sizeof(float);
|
||||
int totalsize = mMaxOutObject * sizeof(Detection) / sizeof(float);
|
||||
|
||||
return Dims3(totalsize + 1, 1, 1);
|
||||
}
|
||||
@ -151,25 +153,29 @@ namespace nvinfer1
|
||||
// Clone the plugin
|
||||
IPluginV2IOExt* YoloLayerPlugin::clone() const
|
||||
{
|
||||
YoloLayerPlugin *p = new YoloLayerPlugin();
|
||||
//YoloLayerPlugin *p = nullptr;
|
||||
//p = new YoloLayerPlugin();
|
||||
YoloLayerPlugin* p = new YoloLayerPlugin(mClassCount, mYoloV5NetWidth, mYoloV5NetHeight, mMaxOutObject, mYoloKernel);
|
||||
p->setPluginNamespace(mPluginNamespace);
|
||||
return p;
|
||||
}
|
||||
|
||||
__device__ float Logist(float data){ return 1.0f / (1.0f + expf(-data)); };
|
||||
__device__ float Logist(float data) { return 1.0f / (1.0f + expf(-data)); };
|
||||
|
||||
__global__ void CalDetection(const float *input, float *output, int noElements,
|
||||
const int netwidth, const int netheight, int maxoutobject, int yoloWidth, int yoloHeight, const float anchors[CHECK_COUNT * 2], int classes, int outputElem)
|
||||
{
|
||||
|
||||
__global__ void CalDetection(const float *input, float *output,int noElements,
|
||||
int yoloWidth,int yoloHeight,const float anchors[CHECK_COUNT*2],int classes,int outputElem) {
|
||||
|
||||
int idx = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if (idx >= noElements) return;
|
||||
|
||||
int total_grid = yoloWidth * yoloHeight;
|
||||
int bnIdx = idx / total_grid;
|
||||
idx = idx - total_grid*bnIdx;
|
||||
idx = idx - total_grid * bnIdx;
|
||||
int info_len_i = 5 + classes;
|
||||
const float* curInput = input + bnIdx * (info_len_i * total_grid * CHECK_COUNT);
|
||||
|
||||
|
||||
for (int k = 0; k < 3; ++k) {
|
||||
float box_prob = Logist(curInput[idx + k * info_len_i * total_grid + 4 * total_grid]);
|
||||
if (box_prob < IGNORE_THRESH) continue;
|
||||
@ -182,45 +188,53 @@ namespace nvinfer1
|
||||
class_id = i - 5;
|
||||
}
|
||||
}
|
||||
float *res_count = output + bnIdx*outputElem;
|
||||
float *res_count = output + bnIdx * outputElem;
|
||||
int count = (int)atomicAdd(res_count, 1);
|
||||
if (count >= MAX_OUTPUT_BBOX_COUNT) return;
|
||||
if (count >= maxoutobject) return;
|
||||
char* data = (char *)res_count + sizeof(float) + count * sizeof(Detection);
|
||||
Detection* det = (Detection*)(data);
|
||||
Detection* det = (Detection*)(data);
|
||||
|
||||
int row = idx / yoloWidth;
|
||||
int col = idx % yoloWidth;
|
||||
|
||||
//Location
|
||||
det->bbox[0] = (col - 0.5f + 2.0f * Logist(curInput[idx + k * info_len_i * total_grid + 0 * total_grid])) * INPUT_W / yoloWidth;
|
||||
det->bbox[1] = (row - 0.5f + 2.0f * Logist(curInput[idx + k * info_len_i * total_grid + 1 * total_grid])) * INPUT_H / yoloHeight;
|
||||
// pytorch:
|
||||
// y = x[i].sigmoid()
|
||||
// y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i].to(x[i].device)) * self.stride[i] # xy
|
||||
// y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh
|
||||
//X: (sigmoid(tx) + cx)/FeaturemapW * netwidth
|
||||
det->bbox[0] = (col - 0.5f + 2.0f * Logist(curInput[idx + k * info_len_i * total_grid + 0 * total_grid])) * netwidth / yoloWidth;
|
||||
det->bbox[1] = (row - 0.5f + 2.0f * Logist(curInput[idx + k * info_len_i * total_grid + 1 * total_grid])) * netheight / yoloHeight;
|
||||
|
||||
// W: (Pw * e^tw) / FeaturemapW * netwidth
|
||||
// v5:https://github.com/ultralytics/yolov5/issues/471
|
||||
det->bbox[2] = 2.0f * Logist(curInput[idx + k * info_len_i * total_grid + 2 * total_grid]);
|
||||
det->bbox[2] = det->bbox[2] * det->bbox[2] * anchors[2*k];
|
||||
det->bbox[2] = det->bbox[2] * det->bbox[2] * anchors[2 * k]; //
|
||||
det->bbox[3] = 2.0f * Logist(curInput[idx + k * info_len_i * total_grid + 3 * total_grid]);
|
||||
det->bbox[3] = det->bbox[3] * det->bbox[3] * anchors[2*k + 1];
|
||||
det->bbox[3] = det->bbox[3] * det->bbox[3] * anchors[2 * k + 1];
|
||||
det->conf = box_prob * max_cls_prob;
|
||||
det->class_id = class_id;
|
||||
}
|
||||
}
|
||||
|
||||
void YoloLayerPlugin::forwardGpu(const float *const * inputs, float* output, cudaStream_t stream, int batchSize) {
|
||||
|
||||
int outputElem = 1 + MAX_OUTPUT_BBOX_COUNT * sizeof(Detection) / sizeof(float);
|
||||
|
||||
for(int idx = 0 ; idx < batchSize; ++idx) {
|
||||
CUDA_CHECK(cudaMemset(output + idx*outputElem, 0, sizeof(float)));
|
||||
void YoloLayerPlugin::forwardGpu(const float *const * inputs, float* output, cudaStream_t stream, int batchSize)
|
||||
{
|
||||
int outputElem = 1 + mMaxOutObject * sizeof(Detection) / sizeof(float);
|
||||
for (int idx = 0; idx < batchSize; ++idx) {
|
||||
CUDA_CHECK(cudaMemset(output + idx * outputElem, 0, sizeof(float)));
|
||||
}
|
||||
int numElem = 0;
|
||||
for (unsigned int i = 0; i < mYoloKernel.size(); ++i)
|
||||
{
|
||||
const auto& yolo = mYoloKernel[i];
|
||||
numElem = yolo.width*yolo.height*batchSize;
|
||||
numElem = yolo.width*yolo.height*batchSize;
|
||||
if (numElem < mThreadCount)
|
||||
mThreadCount = numElem;
|
||||
CalDetection<<< (yolo.width*yolo.height*batchSize + mThreadCount - 1) / mThreadCount, mThreadCount>>>
|
||||
(inputs[i], output, numElem, yolo.width, yolo.height, (float *)mAnchor[i], mClassCount, outputElem);
|
||||
}
|
||||
|
||||
//printf("Net: %d %d \n", mYoloV5NetWidth, mYoloV5NetHeight);
|
||||
CalDetection << < (yolo.width*yolo.height*batchSize + mThreadCount - 1) / mThreadCount, mThreadCount >> >
|
||||
(inputs[i], output, numElem, mYoloV5NetWidth, mYoloV5NetWidth, mMaxOutObject, yolo.width, yolo.height, (float *)mAnchor[i], mClassCount, outputElem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -243,22 +257,81 @@ namespace nvinfer1
|
||||
|
||||
const char* YoloPluginCreator::getPluginName() const
|
||||
{
|
||||
return "YoloLayer_TRT";
|
||||
return "YoloLayer_TRT";
|
||||
}
|
||||
|
||||
const char* YoloPluginCreator::getPluginVersion() const
|
||||
{
|
||||
return "1";
|
||||
return "1";
|
||||
}
|
||||
|
||||
const PluginFieldCollection* YoloPluginCreator::getFieldNames()
|
||||
{
|
||||
return &mFC;
|
||||
return &mFC;
|
||||
}
|
||||
|
||||
IPluginV2IOExt* YoloPluginCreator::createPlugin(const char* name, const PluginFieldCollection* fc)
|
||||
{
|
||||
YoloLayerPlugin* obj = new YoloLayerPlugin();
|
||||
int ClassCount;
|
||||
int YoloV5NetWidth;
|
||||
int YoloV5NetHeight;
|
||||
int MaxOutObject;
|
||||
std::vector<Yolo::YoloKernel> vYoloKernel;
|
||||
|
||||
int* floatdata0;
|
||||
int* floatdata1;
|
||||
int* floatdata2;
|
||||
int* floatdata3;
|
||||
const PluginField* fields = fc->fields;
|
||||
for (int i = 0; i < fc->nbFields; i++) {
|
||||
|
||||
if (strcmp(fields[i].name, "netdata") == 0) {
|
||||
assert(fields[i].type == PluginFieldType::kFLOAT32);
|
||||
floatdata0 = (int*)(fields[i].data);
|
||||
ClassCount = floatdata0[0];
|
||||
YoloV5NetWidth = floatdata0[1];
|
||||
YoloV5NetHeight = floatdata0[2];
|
||||
MaxOutObject = floatdata0[3];
|
||||
}
|
||||
if (strcmp(fields[i].name, "yolodata1") == 0) {
|
||||
assert(fields[i].type == PluginFieldType::kFLOAT32);
|
||||
floatdata1 = (int*)(fields[i].data);
|
||||
YoloKernel kernel;
|
||||
kernel.width = floatdata1[0];
|
||||
kernel.height = floatdata1[1];
|
||||
for (int j = 0; j < fields[i].length - 2; j++)
|
||||
{
|
||||
kernel.anchors[j] = floatdata1[j + 2];
|
||||
}
|
||||
vYoloKernel.push_back(kernel);
|
||||
}
|
||||
if (strcmp(fields[i].name, "yolodata2") == 0) {
|
||||
assert(fields[i].type == PluginFieldType::kFLOAT32);
|
||||
floatdata2 = (int*)(fields[i].data);
|
||||
YoloKernel kernel;
|
||||
kernel.width = floatdata2[0];
|
||||
kernel.height = floatdata2[1];
|
||||
for (int j = 0; j < fields[i].length - 2; j++)
|
||||
{
|
||||
kernel.anchors[j] = floatdata2[j + 2];
|
||||
}
|
||||
vYoloKernel.push_back(kernel);
|
||||
}
|
||||
if (strcmp(fields[i].name, "yolodata3") == 0) {
|
||||
assert(fields[i].type == PluginFieldType::kFLOAT32);
|
||||
floatdata3 = (int*)(fields[i].data);
|
||||
YoloKernel kernel;
|
||||
kernel.width = floatdata3[0];
|
||||
kernel.height = floatdata3[1];
|
||||
for (int j = 0; j < fields[i].length - 2; j++)
|
||||
{
|
||||
kernel.anchors[j] = floatdata3[j + 2];
|
||||
}
|
||||
vYoloKernel.push_back(kernel);
|
||||
}
|
||||
}
|
||||
std::reverse(vYoloKernel.begin(), vYoloKernel.end());
|
||||
YoloLayerPlugin* obj = new YoloLayerPlugin(ClassCount, YoloV5NetWidth, YoloV5NetHeight, MaxOutObject, vYoloKernel);
|
||||
obj->setPluginNamespace(mNamespace.c_str());
|
||||
return obj;
|
||||
}
|
||||
@ -271,5 +344,5 @@ namespace nvinfer1
|
||||
obj->setPluginNamespace(mNamespace.c_str());
|
||||
return obj;
|
||||
}
|
||||
|
||||
REGISTER_TENSORRT_PLUGIN(YoloPluginCreator);
|
||||
}
|
||||
|
||||
@ -9,36 +9,19 @@ namespace Yolo
|
||||
{
|
||||
static constexpr int CHECK_COUNT = 3;
|
||||
static constexpr float IGNORE_THRESH = 0.1f;
|
||||
struct YoloKernel
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
float anchors[CHECK_COUNT * 2];
|
||||
};
|
||||
static constexpr int MAX_OUTPUT_BBOX_COUNT = 1000;
|
||||
static constexpr int CLASS_NUM = 80;
|
||||
static constexpr int INPUT_H = 608;
|
||||
static constexpr int INPUT_W = 608;
|
||||
|
||||
struct YoloKernel
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
float anchors[CHECK_COUNT*2];
|
||||
};
|
||||
|
||||
static constexpr YoloKernel yolo1 = {
|
||||
INPUT_W / 32,
|
||||
INPUT_H / 32,
|
||||
{116,90, 156,198, 373,326}
|
||||
};
|
||||
static constexpr YoloKernel yolo2 = {
|
||||
INPUT_W / 16,
|
||||
INPUT_H / 16,
|
||||
{30,61, 62,45, 59,119}
|
||||
};
|
||||
static constexpr YoloKernel yolo3 = {
|
||||
INPUT_W / 8,
|
||||
INPUT_H / 8,
|
||||
{10,13, 16,30, 33,23}
|
||||
};
|
||||
|
||||
static constexpr int LOCATIONS = 4;
|
||||
struct alignas(float) Detection{
|
||||
struct alignas(float) Detection {
|
||||
//center_x center_y w h
|
||||
float bbox[LOCATIONS];
|
||||
float conf; // bbox_conf * cls_conf
|
||||
@ -48,105 +31,106 @@ namespace Yolo
|
||||
|
||||
namespace nvinfer1
|
||||
{
|
||||
class YoloLayerPlugin: public IPluginV2IOExt
|
||||
class YoloLayerPlugin : public IPluginV2IOExt
|
||||
{
|
||||
public:
|
||||
explicit YoloLayerPlugin();
|
||||
YoloLayerPlugin(const void* data, size_t length);
|
||||
public:
|
||||
YoloLayerPlugin(int classCount, int netWidth, int netHeight, int maxOut, const std::vector<Yolo::YoloKernel>& vYoloKernel);
|
||||
YoloLayerPlugin(const void* data, size_t length);
|
||||
~YoloLayerPlugin();
|
||||
|
||||
~YoloLayerPlugin();
|
||||
int getNbOutputs() const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int getNbOutputs() const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override;
|
||||
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override;
|
||||
int initialize() override;
|
||||
|
||||
int initialize() override;
|
||||
virtual void terminate() override {};
|
||||
|
||||
virtual void terminate() override {};
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override { return 0; }
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override { return 0;}
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override;
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override;
|
||||
virtual size_t getSerializationSize() const override;
|
||||
|
||||
virtual size_t getSerializationSize() const override;
|
||||
virtual void serialize(void* buffer) const override;
|
||||
|
||||
virtual void serialize(void* buffer) const override;
|
||||
bool supportsFormatCombination(int pos, const PluginTensorDesc* inOut, int nbInputs, int nbOutputs) const override {
|
||||
return inOut[pos].format == TensorFormat::kLINEAR && inOut[pos].type == DataType::kFLOAT;
|
||||
}
|
||||
|
||||
bool supportsFormatCombination(int pos, const PluginTensorDesc* inOut, int nbInputs, int nbOutputs) const override {
|
||||
return inOut[pos].format == TensorFormat::kLINEAR && inOut[pos].type == DataType::kFLOAT;
|
||||
}
|
||||
const char* getPluginType() const override;
|
||||
|
||||
const char* getPluginType() const override;
|
||||
const char* getPluginVersion() const override;
|
||||
|
||||
const char* getPluginVersion() const override;
|
||||
void destroy() override;
|
||||
|
||||
void destroy() override;
|
||||
IPluginV2IOExt* clone() const override;
|
||||
|
||||
IPluginV2IOExt* clone() const override;
|
||||
void setPluginNamespace(const char* pluginNamespace) override;
|
||||
|
||||
void setPluginNamespace(const char* pluginNamespace) override;
|
||||
const char* getPluginNamespace() const override;
|
||||
|
||||
const char* getPluginNamespace() const override;
|
||||
DataType getOutputDataType(int index, const nvinfer1::DataType* inputTypes, int nbInputs) const override;
|
||||
|
||||
DataType getOutputDataType(int index, const nvinfer1::DataType* inputTypes, int nbInputs) const override;
|
||||
bool isOutputBroadcastAcrossBatch(int outputIndex, const bool* inputIsBroadcasted, int nbInputs) const override;
|
||||
|
||||
bool isOutputBroadcastAcrossBatch(int outputIndex, const bool* inputIsBroadcasted, int nbInputs) const override;
|
||||
bool canBroadcastInputAcrossBatch(int inputIndex) const override;
|
||||
|
||||
bool canBroadcastInputAcrossBatch(int inputIndex) const override;
|
||||
void attachToContext(
|
||||
cudnnContext* cudnnContext, cublasContext* cublasContext, IGpuAllocator* gpuAllocator) override;
|
||||
|
||||
void attachToContext(
|
||||
cudnnContext* cudnnContext, cublasContext* cublasContext, IGpuAllocator* gpuAllocator) override;
|
||||
void configurePlugin(const PluginTensorDesc* in, int nbInput, const PluginTensorDesc* out, int nbOutput) override;
|
||||
|
||||
void configurePlugin(const PluginTensorDesc* in, int nbInput, const PluginTensorDesc* out, int nbOutput) override;
|
||||
void detachFromContext() override;
|
||||
|
||||
void detachFromContext() override;
|
||||
|
||||
private:
|
||||
void forwardGpu(const float *const * inputs,float * output, cudaStream_t stream,int batchSize = 1);
|
||||
int mClassCount;
|
||||
int mKernelCount;
|
||||
std::vector<Yolo::YoloKernel> mYoloKernel;
|
||||
int mThreadCount = 256;
|
||||
void** mAnchor;
|
||||
const char* mPluginNamespace;
|
||||
private:
|
||||
void forwardGpu(const float *const * inputs, float * output, cudaStream_t stream, int batchSize = 1);
|
||||
int mThreadCount = 256;
|
||||
const char* mPluginNamespace;
|
||||
int mKernelCount;
|
||||
int mClassCount;
|
||||
int mYoloV5NetWidth;
|
||||
int mYoloV5NetHeight;
|
||||
int mMaxOutObject;
|
||||
std::vector<Yolo::YoloKernel> mYoloKernel;
|
||||
void** mAnchor;
|
||||
};
|
||||
|
||||
class YoloPluginCreator : public IPluginCreator
|
||||
{
|
||||
public:
|
||||
YoloPluginCreator();
|
||||
public:
|
||||
YoloPluginCreator();
|
||||
|
||||
~YoloPluginCreator() override = default;
|
||||
~YoloPluginCreator() override = default;
|
||||
|
||||
const char* getPluginName() const override;
|
||||
const char* getPluginName() const override;
|
||||
|
||||
const char* getPluginVersion() const override;
|
||||
const char* getPluginVersion() const override;
|
||||
|
||||
const PluginFieldCollection* getFieldNames() override;
|
||||
const PluginFieldCollection* getFieldNames() override;
|
||||
|
||||
IPluginV2IOExt* createPlugin(const char* name, const PluginFieldCollection* fc) override;
|
||||
IPluginV2IOExt* createPlugin(const char* name, const PluginFieldCollection* fc) override;
|
||||
|
||||
IPluginV2IOExt* deserializePlugin(const char* name, const void* serialData, size_t serialLength) override;
|
||||
IPluginV2IOExt* deserializePlugin(const char* name, const void* serialData, size_t serialLength) override;
|
||||
|
||||
void setPluginNamespace(const char* libNamespace) override
|
||||
{
|
||||
mNamespace = libNamespace;
|
||||
}
|
||||
void setPluginNamespace(const char* libNamespace) override
|
||||
{
|
||||
mNamespace = libNamespace;
|
||||
}
|
||||
|
||||
const char* getPluginNamespace() const override
|
||||
{
|
||||
return mNamespace.c_str();
|
||||
}
|
||||
const char* getPluginNamespace() const override
|
||||
{
|
||||
return mNamespace.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string mNamespace;
|
||||
static PluginFieldCollection mFC;
|
||||
static std::vector<PluginField> mPluginAttributes;
|
||||
private:
|
||||
std::string mNamespace;
|
||||
static PluginFieldCollection mFC;
|
||||
static std::vector<PluginField> mPluginAttributes;
|
||||
};
|
||||
REGISTER_TENSORRT_PLUGIN(YoloPluginCreator);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -19,21 +19,23 @@
|
||||
// stuff we know about the network and the input/output blobs
|
||||
static const int INPUT_H = Yolo::INPUT_H;
|
||||
static const int INPUT_W = Yolo::INPUT_W;
|
||||
static const int CLASS_NUM = Yolo::CLASS_NUM;
|
||||
static const int OUTPUT_SIZE = Yolo::MAX_OUTPUT_BBOX_COUNT * sizeof(Yolo::Detection) / sizeof(float) + 1; // we assume the yololayer outputs no more than 1000 boxes that conf >= 0.1
|
||||
const char* INPUT_BLOB_NAME = "data";
|
||||
const char* OUTPUT_BLOB_NAME = "prob";
|
||||
static Logger gLogger;
|
||||
|
||||
|
||||
// Creat the engine using only the API and not any parser.
|
||||
ICudaEngine* createEngine_s(unsigned int maxBatchSize, IBuilder* builder, IBuilderConfig* config, DataType dt) {
|
||||
INetworkDefinition* network = builder->createNetworkV2(0U);
|
||||
|
||||
// Create input tensor of shape {3, INPUT_H, INPUT_W} with name INPUT_BLOB_NAME
|
||||
ITensor* data = network->addInput(INPUT_BLOB_NAME, dt, Dims3{3, INPUT_H, INPUT_W});
|
||||
ITensor* data = network->addInput(INPUT_BLOB_NAME, dt, Dims3{ 3, INPUT_H, INPUT_W });
|
||||
assert(data);
|
||||
|
||||
std::map<std::string, Weights> weightMap = loadWeights("../yolov5s.wts");
|
||||
Weights emptywts{DataType::kFLOAT, nullptr, 0};
|
||||
Weights emptywts{ DataType::kFLOAT, nullptr, 0 };
|
||||
|
||||
// yolov5 backbone
|
||||
auto focus0 = focus(network, weightMap, *data, 3, 32, 3, "model.0");
|
||||
@ -54,46 +56,40 @@ ICudaEngine* createEngine_s(unsigned int maxBatchSize, IBuilder* builder, IBuild
|
||||
for (int i = 0; i < 256 * 2 * 2; i++) {
|
||||
deval[i] = 1.0;
|
||||
}
|
||||
Weights deconvwts11{DataType::kFLOAT, deval, 256 * 2 * 2};
|
||||
IDeconvolutionLayer* deconv11 = network->addDeconvolutionNd(*conv10->getOutput(0), 256, DimsHW{2, 2}, deconvwts11, emptywts);
|
||||
deconv11->setStrideNd(DimsHW{2, 2});
|
||||
Weights deconvwts11{ DataType::kFLOAT, deval, 256 * 2 * 2 };
|
||||
IDeconvolutionLayer* deconv11 = network->addDeconvolutionNd(*conv10->getOutput(0), 256, DimsHW{ 2, 2 }, deconvwts11, emptywts);
|
||||
deconv11->setStrideNd(DimsHW{ 2, 2 });
|
||||
deconv11->setNbGroups(256);
|
||||
weightMap["deconv11"] = deconvwts11;
|
||||
|
||||
ITensor* inputTensors12[] = {deconv11->getOutput(0), bottleneck_csp6->getOutput(0)};
|
||||
ITensor* inputTensors12[] = { deconv11->getOutput(0), bottleneck_csp6->getOutput(0) };
|
||||
auto cat12 = network->addConcatenation(inputTensors12, 2);
|
||||
auto bottleneck_csp13 = bottleneckCSP(network, weightMap, *cat12->getOutput(0), 512, 256, 1, false, 1, 0.5, "model.13");
|
||||
auto conv14 = convBlock(network, weightMap, *bottleneck_csp13->getOutput(0), 128, 1, 1, 1, "model.14");
|
||||
|
||||
Weights deconvwts15{DataType::kFLOAT, deval, 128 * 2 * 2};
|
||||
IDeconvolutionLayer* deconv15 = network->addDeconvolutionNd(*conv14->getOutput(0), 128, DimsHW{2, 2}, deconvwts15, emptywts);
|
||||
deconv15->setStrideNd(DimsHW{2, 2});
|
||||
Weights deconvwts15{ DataType::kFLOAT, deval, 128 * 2 * 2 };
|
||||
IDeconvolutionLayer* deconv15 = network->addDeconvolutionNd(*conv14->getOutput(0), 128, DimsHW{ 2, 2 }, deconvwts15, emptywts);
|
||||
deconv15->setStrideNd(DimsHW{ 2, 2 });
|
||||
deconv15->setNbGroups(128);
|
||||
//weightMap["deconv15"] = deconvwts15;
|
||||
|
||||
ITensor* inputTensors16[] = {deconv15->getOutput(0), bottleneck_csp4->getOutput(0)};
|
||||
ITensor* inputTensors16[] = { deconv15->getOutput(0), bottleneck_csp4->getOutput(0) };
|
||||
auto cat16 = network->addConcatenation(inputTensors16, 2);
|
||||
auto bottleneck_csp17 = bottleneckCSP(network, weightMap, *cat16->getOutput(0), 256, 128, 1, false, 1, 0.5, "model.17");
|
||||
IConvolutionLayer* det0 = network->addConvolutionNd(*bottleneck_csp17->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{1, 1}, weightMap["model.24.m.0.weight"], weightMap["model.24.m.0.bias"]);
|
||||
IConvolutionLayer* det0 = network->addConvolutionNd(*bottleneck_csp17->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.0.weight"], weightMap["model.24.m.0.bias"]);
|
||||
|
||||
auto conv18 = convBlock(network, weightMap, *bottleneck_csp17->getOutput(0), 128, 3, 2, 1, "model.18");
|
||||
ITensor* inputTensors19[] = {conv18->getOutput(0), conv14->getOutput(0)};
|
||||
ITensor* inputTensors19[] = { conv18->getOutput(0), conv14->getOutput(0) };
|
||||
auto cat19 = network->addConcatenation(inputTensors19, 2);
|
||||
auto bottleneck_csp20 = bottleneckCSP(network, weightMap, *cat19->getOutput(0), 256, 256, 1, false, 1, 0.5, "model.20");
|
||||
IConvolutionLayer* det1 = network->addConvolutionNd(*bottleneck_csp20->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{1, 1}, weightMap["model.24.m.1.weight"], weightMap["model.24.m.1.bias"]);
|
||||
IConvolutionLayer* det1 = network->addConvolutionNd(*bottleneck_csp20->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.1.weight"], weightMap["model.24.m.1.bias"]);
|
||||
|
||||
auto conv21 = convBlock(network, weightMap, *bottleneck_csp20->getOutput(0), 256, 3, 2, 1, "model.21");
|
||||
ITensor* inputTensors22[] = {conv21->getOutput(0), conv10->getOutput(0)};
|
||||
ITensor* inputTensors22[] = { conv21->getOutput(0), conv10->getOutput(0) };
|
||||
auto cat22 = network->addConcatenation(inputTensors22, 2);
|
||||
auto bottleneck_csp23 = bottleneckCSP(network, weightMap, *cat22->getOutput(0), 512, 512, 1, false, 1, 0.5, "model.23");
|
||||
IConvolutionLayer* det2 = network->addConvolutionNd(*bottleneck_csp23->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{1, 1}, weightMap["model.24.m.2.weight"], weightMap["model.24.m.2.bias"]);
|
||||
|
||||
auto creator = getPluginRegistry()->getPluginCreator("YoloLayer_TRT", "1");
|
||||
const PluginFieldCollection* pluginData = creator->getFieldNames();
|
||||
IPluginV2 *pluginObj = creator->createPlugin("yololayer", pluginData);
|
||||
ITensor* inputTensors_yolo[] = {det2->getOutput(0), det1->getOutput(0), det0->getOutput(0)};
|
||||
auto yolo = network->addPluginV2(inputTensors_yolo, 3, *pluginObj);
|
||||
IConvolutionLayer* det2 = network->addConvolutionNd(*bottleneck_csp23->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.2.weight"], weightMap["model.24.m.2.bias"]);
|
||||
|
||||
auto yolo = addYoLoLayer(network, weightMap, det0, det1, det2);
|
||||
yolo->getOutput(0)->setName(OUTPUT_BLOB_NAME);
|
||||
network->markOutput(*yolo->getOutput(0));
|
||||
|
||||
@ -113,9 +109,9 @@ ICudaEngine* createEngine_s(unsigned int maxBatchSize, IBuilder* builder, IBuild
|
||||
// Release host memory
|
||||
for (auto& mem : weightMap)
|
||||
{
|
||||
free((void*) (mem.second.values));
|
||||
}
|
||||
free((void*)(mem.second.values));
|
||||
|
||||
}
|
||||
return engine;
|
||||
}
|
||||
|
||||
@ -166,38 +162,25 @@ ICudaEngine* createEngine_m(unsigned int maxBatchSize, IBuilder* builder, IBuild
|
||||
|
||||
ITensor* inputTensors16[] = { deconv15->getOutput(0), bottleneck_csp4->getOutput(0) };
|
||||
auto cat16 = network->addConcatenation(inputTensors16, 2);
|
||||
|
||||
auto bottleneck_csp17 = bottleneckCSP(network, weightMap, *cat16->getOutput(0), 384, 192, 2, false, 1, 0.5, "model.17");
|
||||
|
||||
//yolo layer 0
|
||||
IConvolutionLayer* det0 = network->addConvolutionNd(*bottleneck_csp17->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.0.weight"], weightMap["model.24.m.0.bias"]);
|
||||
|
||||
auto conv18 = convBlock(network, weightMap, *bottleneck_csp17->getOutput(0), 192, 3, 2, 1, "model.18");
|
||||
|
||||
ITensor* inputTensors19[] = {conv18->getOutput(0), conv14->getOutput(0)};
|
||||
ITensor* inputTensors19[] = { conv18->getOutput(0), conv14->getOutput(0) };
|
||||
auto cat19 = network->addConcatenation(inputTensors19, 2);
|
||||
|
||||
auto bottleneck_csp20 = bottleneckCSP(network, weightMap, *cat19->getOutput(0), 384, 384, 2, false, 1, 0.5, "model.20");
|
||||
|
||||
//yolo layer 1
|
||||
IConvolutionLayer* det1 = network->addConvolutionNd(*bottleneck_csp20->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.1.weight"], weightMap["model.24.m.1.bias"]);
|
||||
|
||||
auto conv21 = convBlock(network, weightMap, *bottleneck_csp20->getOutput(0), 384, 3, 2, 1, "model.21");
|
||||
|
||||
ITensor* inputTensors22[] = { conv21->getOutput(0), conv10->getOutput(0) };
|
||||
auto cat22 = network->addConcatenation(inputTensors22, 2);
|
||||
|
||||
auto bottleneck_csp23 = bottleneckCSP(network, weightMap, *cat22->getOutput(0), 768, 768, 2, false, 1, 0.5, "model.23");
|
||||
|
||||
// yolo layer 2
|
||||
IConvolutionLayer* det2 = network->addConvolutionNd(*bottleneck_csp23->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.2.weight"], weightMap["model.24.m.2.bias"]);
|
||||
|
||||
auto creator = getPluginRegistry()->getPluginCreator("YoloLayer_TRT", "1");
|
||||
const PluginFieldCollection* pluginData = creator->getFieldNames();
|
||||
IPluginV2 *pluginObj = creator->createPlugin("yololayer", pluginData);
|
||||
ITensor* inputTensors_yolo[] = {det2->getOutput(0), det1->getOutput(0), det0->getOutput(0)};
|
||||
auto yolo = network->addPluginV2(inputTensors_yolo, 3, *pluginObj);
|
||||
|
||||
auto yolo = addYoLoLayer(network, weightMap, det0, det1, det2);
|
||||
yolo->getOutput(0)->setName(OUTPUT_BLOB_NAME);
|
||||
network->markOutput(*yolo->getOutput(0));
|
||||
|
||||
@ -267,39 +250,26 @@ ICudaEngine* createEngine_l(unsigned int maxBatchSize, IBuilder* builder, IBuild
|
||||
IDeconvolutionLayer* deconv15 = network->addDeconvolutionNd(*conv14->getOutput(0), 256, DimsHW{ 2, 2 }, deconvwts15, emptywts);
|
||||
deconv15->setStrideNd(DimsHW{ 2, 2 });
|
||||
deconv15->setNbGroups(256);
|
||||
ITensor* inputTensors16[] = {deconv15->getOutput(0), bottleneck_csp4->getOutput(0)};
|
||||
ITensor* inputTensors16[] = { deconv15->getOutput(0), bottleneck_csp4->getOutput(0) };
|
||||
auto cat16 = network->addConcatenation(inputTensors16, 2);
|
||||
|
||||
auto bottleneck_csp17 = bottleneckCSP(network, weightMap, *cat16->getOutput(0), 512, 256, 3, false, 1, 0.5, "model.17");
|
||||
|
||||
// yolo layer 0
|
||||
IConvolutionLayer* det0 = network->addConvolutionNd(*bottleneck_csp17->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.0.weight"], weightMap["model.24.m.0.bias"]);
|
||||
|
||||
auto conv18 = convBlock(network, weightMap, *bottleneck_csp17->getOutput(0), 256, 3, 2, 1, "model.18");
|
||||
|
||||
ITensor* inputTensors19[] = {conv18->getOutput(0), conv14->getOutput(0)};
|
||||
ITensor* inputTensors19[] = { conv18->getOutput(0), conv14->getOutput(0) };
|
||||
auto cat19 = network->addConcatenation(inputTensors19, 2);
|
||||
|
||||
auto bottleneck_csp20 = bottleneckCSP(network, weightMap, *cat19->getOutput(0), 512, 512, 3, false, 1, 0.5, "model.20");
|
||||
|
||||
//yolo layer 1
|
||||
IConvolutionLayer* det1 = network->addConvolutionNd(*bottleneck_csp20->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.1.weight"], weightMap["model.24.m.1.bias"]);
|
||||
|
||||
auto conv21 = convBlock(network, weightMap, *bottleneck_csp20->getOutput(0), 512, 3, 2, 1, "model.21");
|
||||
|
||||
ITensor* inputTensors22[] = {conv21->getOutput(0), conv10->getOutput(0)};
|
||||
ITensor* inputTensors22[] = { conv21->getOutput(0), conv10->getOutput(0) };
|
||||
auto cat22 = network->addConcatenation(inputTensors22, 2);
|
||||
|
||||
auto bottleneck_csp23 = bottleneckCSP(network, weightMap, *cat22->getOutput(0), 1024, 1024, 3, false, 1, 0.5, "model.23");
|
||||
|
||||
IConvolutionLayer* det2 = network->addConvolutionNd(*bottleneck_csp23->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.2.weight"], weightMap["model.24.m.2.bias"]);
|
||||
|
||||
auto creator = getPluginRegistry()->getPluginCreator("YoloLayer_TRT", "1");
|
||||
const PluginFieldCollection* pluginData = creator->getFieldNames();
|
||||
IPluginV2 *pluginObj = creator->createPlugin("yololayer", pluginData);
|
||||
ITensor* inputTensors_yolo[] = {det2->getOutput(0), det1->getOutput(0), det0->getOutput(0)};
|
||||
auto yolo = network->addPluginV2(inputTensors_yolo, 3, *pluginObj);
|
||||
|
||||
auto yolo = addYoLoLayer(network, weightMap, det0, det1, det2);
|
||||
yolo->getOutput(0)->setName(OUTPUT_BLOB_NAME);
|
||||
network->markOutput(*yolo->getOutput(0));
|
||||
|
||||
@ -377,33 +347,20 @@ ICudaEngine* createEngine_x(unsigned int maxBatchSize, IBuilder* builder, IBuild
|
||||
|
||||
// yolo layer 0
|
||||
IConvolutionLayer* det0 = network->addConvolutionNd(*bottleneck_csp17->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.0.weight"], weightMap["model.24.m.0.bias"]);
|
||||
|
||||
auto conv18 = convBlock(network, weightMap, *bottleneck_csp17->getOutput(0), 320, 3, 2, 1, "model.18");
|
||||
|
||||
ITensor* inputTensors19[] = { conv18->getOutput(0), conv14->getOutput(0) };
|
||||
auto cat19 = network->addConcatenation(inputTensors19, 2);
|
||||
|
||||
auto bottleneck_csp20 = bottleneckCSP(network, weightMap, *cat19->getOutput(0), 640, 640, 4, false, 1, 0.5, "model.20");
|
||||
|
||||
// yolo layer 1
|
||||
IConvolutionLayer* det1 = network->addConvolutionNd(*bottleneck_csp20->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.1.weight"], weightMap["model.24.m.1.bias"]);
|
||||
|
||||
auto conv21 = convBlock(network, weightMap, *bottleneck_csp20->getOutput(0), 640, 3, 2, 1, "model.21");
|
||||
|
||||
ITensor* inputTensors22[] = { conv21->getOutput(0), conv10->getOutput(0) };
|
||||
auto cat22 = network->addConcatenation(inputTensors22, 2);
|
||||
|
||||
auto bottleneck_csp23 = bottleneckCSP(network, weightMap, *cat22->getOutput(0), 1280, 1280, 4, false, 1, 0.5, "model.23");
|
||||
|
||||
// yolo layer 2
|
||||
IConvolutionLayer* det2 = network->addConvolutionNd(*bottleneck_csp23->getOutput(0), 3 * (Yolo::CLASS_NUM + 5), DimsHW{ 1, 1 }, weightMap["model.24.m.2.weight"], weightMap["model.24.m.2.bias"]);
|
||||
|
||||
auto creator = getPluginRegistry()->getPluginCreator("YoloLayer_TRT", "1");
|
||||
const PluginFieldCollection* pluginData = creator->getFieldNames();
|
||||
IPluginV2 *pluginObj = creator->createPlugin("yololayer", pluginData);
|
||||
ITensor* inputTensors_yolo[] = { det2->getOutput(0), det1->getOutput(0), det0->getOutput(0) };
|
||||
auto yolo = network->addPluginV2(inputTensors_yolo, 3, *pluginObj);
|
||||
|
||||
auto yolo = addYoLoLayer(network, weightMap, det0, det1, det2);
|
||||
yolo->getOutput(0)->setName(OUTPUT_BLOB_NAME);
|
||||
network->markOutput(*yolo->getOutput(0));
|
||||
|
||||
@ -458,12 +415,12 @@ void doInference(IExecutionContext& context, cudaStream_t& stream, void **buffer
|
||||
int main(int argc, char** argv) {
|
||||
cudaSetDevice(DEVICE);
|
||||
// create a model using the API directly and serialize it to a stream
|
||||
char *trtModelStream{nullptr};
|
||||
size_t size{0};
|
||||
char *trtModelStream{ nullptr };
|
||||
size_t size{ 0 };
|
||||
std::string engine_name = STR2(NET);
|
||||
engine_name = "yolov5" + engine_name + ".engine";
|
||||
if (argc == 2 && std::string(argv[1]) == "-s") {
|
||||
IHostMemory* modelStream{nullptr};
|
||||
IHostMemory* modelStream{ nullptr };
|
||||
APIToModel(BATCH_SIZE, &modelStream);
|
||||
assert(modelStream != nullptr);
|
||||
std::ofstream p(engine_name, std::ios::binary);
|
||||
@ -474,7 +431,8 @@ int main(int argc, char** argv) {
|
||||
p.write(reinterpret_cast<const char*>(modelStream->data()), modelStream->size());
|
||||
modelStream->destroy();
|
||||
return 0;
|
||||
} else if (argc == 3 && std::string(argv[1]) == "-d") {
|
||||
}
|
||||
else if (argc == 3 && std::string(argv[1]) == "-d") {
|
||||
std::ifstream file(engine_name, std::ios::binary);
|
||||
if (file.good()) {
|
||||
file.seekg(0, file.end);
|
||||
@ -485,7 +443,8 @@ int main(int argc, char** argv) {
|
||||
file.read(trtModelStream, size);
|
||||
file.close();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
std::cerr << "arguments not right!" << std::endl;
|
||||
std::cerr << "./yolov5 -s // serialize model to plan file" << std::endl;
|
||||
std::cerr << "./yolov5 -d ../samples // deserialize plan file and run inference" << std::endl;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user