Add support to YOLOv5 v4.0 and v5.0

This commit is contained in:
Marcos Luciano
2022-04-08 17:13:05 -03:00
parent 2aa52a8e8c
commit 7bcc9b62fa
6 changed files with 102 additions and 63 deletions

View File

@@ -61,7 +61,7 @@ SRCFILES:= nvdsinfer_yolo_engine.cpp \
layers/upsample_layer.cpp \ layers/upsample_layer.cpp \
layers/maxpool_layer.cpp \ layers/maxpool_layer.cpp \
layers/activation_layer.cpp \ layers/activation_layer.cpp \
layers/reorg_r_layer.cpp \ layers/reorgv5_layer.cpp \
utils.cpp \ utils.cpp \
yolo.cpp \ yolo.cpp \
yoloForward.cu \ yoloForward.cu \

View File

@@ -3,9 +3,9 @@
* https://www.github.com/marcoslucianops * https://www.github.com/marcoslucianops
*/ */
#include "reorg_r_layer.h" #include "reorgv5_layer.h"
nvinfer1::ILayer* reorgRLayer( nvinfer1::ILayer* reorgV5Layer(
int layerIdx, int layerIdx,
nvinfer1::ITensor* input, nvinfer1::ITensor* input,
nvinfer1::INetworkDefinition* network) nvinfer1::INetworkDefinition* network)

View File

@@ -3,8 +3,8 @@
* https://www.github.com/marcoslucianops * https://www.github.com/marcoslucianops
*/ */
#ifndef __REORG_R_LAYER_H__ #ifndef __REORGV5_LAYER_H__
#define __REORG_R_LAYER_H__ #define __REORGV5_LAYER_H__
#include <map> #include <map>
#include <vector> #include <vector>
@@ -12,7 +12,7 @@
#include "NvInfer.h" #include "NvInfer.h"
nvinfer1::ILayer* reorgRLayer( nvinfer1::ILayer* reorgV5Layer(
int layerIdx, int layerIdx,
nvinfer1::ITensor* input, nvinfer1::ITensor* input,
nvinfer1::INetworkDefinition* network); nvinfer1::INetworkDefinition* network);

View File

@@ -301,15 +301,15 @@ NvDsInferStatus Yolo::buildYoloNetwork(
} }
else if (m_ConfigBlocks.at(i).at("type") == "reorg") { else if (m_ConfigBlocks.at(i).at("type") == "reorg") {
if (m_NetworkType.find("yolor") != std::string::npos) { if (m_NetworkType.find("yolov5") != std::string::npos || m_NetworkType.find("yolor") != std::string::npos) {
std::string inputVol = dimsToString(previous->getDimensions()); std::string inputVol = dimsToString(previous->getDimensions());
nvinfer1::ILayer* out = reorgRLayer(i, previous, &network); nvinfer1::ILayer* out = reorgV5Layer(i, previous, &network);
previous = out->getOutput(0); previous = out->getOutput(0);
assert(previous != nullptr); assert(previous != nullptr);
channels = getNumChannels(previous); channels = getNumChannels(previous);
std::string outputVol = dimsToString(previous->getDimensions()); std::string outputVol = dimsToString(previous->getDimensions());
tensorOutputs.push_back(previous); tensorOutputs.push_back(previous);
std::string layerType = "reorgR"; std::string layerType = "reorgV5";
printLayerInfo(layerIndex, layerType, inputVol, outputVol, std::to_string(weightPtr)); printLayerInfo(layerIndex, layerType, inputVol, outputVol, std::to_string(weightPtr));
} }
else { else {

View File

@@ -34,7 +34,7 @@
#include "layers/route_layer.h" #include "layers/route_layer.h"
#include "layers/upsample_layer.h" #include "layers/upsample_layer.h"
#include "layers/maxpool_layer.h" #include "layers/maxpool_layer.h"
#include "layers/reorg_r_layer.h" #include "layers/reorgv5_layer.h"
#include "nvdsinfer_custom_impl.h" #include "nvdsinfer_custom_impl.h"

View File

@@ -21,6 +21,9 @@ class YoloLayers():
return "\n[route]\n" + \ return "\n[route]\n" + \
"layers=%s\n" % layers "layers=%s\n" % layers
def reorg(self):
return "\n[reorg]\n"
def shortcut(self, route=-1, activation="linear"): def shortcut(self, route=-1, activation="linear"):
return "\n[shortcut]\n" + \ return "\n[shortcut]\n" + \
"from=%d\n" % route + \ "from=%d\n" % route + \
@@ -120,47 +123,8 @@ model.to(device).eval()
anchors = "" anchors = ""
masks = [] masks = []
with open(wts_file, "w") as f:
wts_write = ""
conv_count = 0
cv1 = ""
cv3 = ""
cv3_idx = 0
sppf_idx = 11 if p6 else 9
for k, v in model.state_dict().items(): for k, v in model.state_dict().items():
if "num_batches_tracked" not in k and "anchors" not in k and "anchor_grid" not in k: if "anchor_grid" in k:
vr = v.reshape(-1).cpu().numpy()
idx = int(k.split(".")[1])
if ".cv1." in k and ".m." not in k and idx != sppf_idx:
cv1 += "{} {} ".format(k, len(vr))
for vv in vr:
cv1 += " "
cv1 += struct.pack(">f", float(vv)).hex()
cv1 += "\n"
conv_count += 1
elif cv1 != "" and ".m." in k:
wts_write += cv1
cv1 = ""
if ".cv3." in k:
cv3 += "{} {} ".format(k, len(vr))
for vv in vr:
cv3 += " "
cv3 += struct.pack(">f", float(vv)).hex()
cv3 += "\n"
cv3_idx = idx
conv_count += 1
elif cv3 != "" and cv3_idx != idx:
wts_write += cv3
cv3 = ""
cv3_idx = 0
if ".cv3." not in k and not (".cv1." in k and ".m." not in k and idx != sppf_idx):
wts_write += "{} {} ".format(k, len(vr))
for vv in vr:
wts_write += " "
wts_write += struct.pack(">f", float(vv)).hex()
wts_write += "\n"
conv_count += 1
elif "anchor_grid" in k:
vr = v.cpu().numpy().tolist() vr = v.cpu().numpy().tolist()
a = v.reshape(-1).cpu().numpy().astype(float).tolist() a = v.reshape(-1).cpu().numpy().astype(float).tolist()
anchors = str(a)[1:-1] anchors = str(a)[1:-1]
@@ -171,8 +135,8 @@ with open(wts_file, "w") as f:
mask.append(num) mask.append(num)
num += 1 num += 1
masks.append(mask) masks.append(mask)
f.write("{}\n".format(conv_count))
f.write(wts_write) spp_idx = 0
with open(cfg_file, "w") as c: with open(cfg_file, "w") as c:
with open(yaml_file, "r", encoding="utf-8") as f: with open(yaml_file, "r", encoding="utf-8") as f:
@@ -195,6 +159,15 @@ with open(cfg_file, "w") as c:
width_multiple = f[topic] width_multiple = f[topic]
elif topic == "backbone" or topic == "head": elif topic == "backbone" or topic == "head":
for v in f[topic]: for v in f[topic]:
if v[2] == "Focus":
layer = "\n# Focus\n"
blocks = 0
layer += yoloLayers.reorg()
blocks += 1
layer += yoloLayers.convolutional(bn=True, filters=get_width(v[3][0], width_multiple), size=v[3][1],
activation="silu")
blocks += 1
layers.append([layer, blocks])
if v[2] == "Conv": if v[2] == "Conv":
layer = "\n# Conv\n" layer = "\n# Conv\n"
blocks = 0 blocks = 0
@@ -244,7 +217,31 @@ with open(cfg_file, "w") as c:
activation="silu") activation="silu")
blocks += 1 blocks += 1
layers.append([layer, blocks]) layers.append([layer, blocks])
elif v[2] == "SPP":
spp_idx = len(layers)
layer = "\n# SPP\n"
blocks = 0
layer += yoloLayers.convolutional(bn=True, filters=get_width(v[3][0], width_multiple) / 2,
activation="silu")
blocks += 1
layer += yoloLayers.maxpool(size=v[3][1][0])
blocks += 1
layer += yoloLayers.route(layers="-2")
blocks += 1
layer += yoloLayers.maxpool(size=v[3][1][1])
blocks += 1
layer += yoloLayers.route(layers="-4")
blocks += 1
layer += yoloLayers.maxpool(size=v[3][1][2])
blocks += 1
layer += yoloLayers.route(layers="-6, -5, -3, -1")
blocks += 1
layer += yoloLayers.convolutional(bn=True, filters=get_width(v[3][0], width_multiple),
activation="silu")
blocks += 1
layers.append([layer, blocks])
elif v[2] == "SPPF": elif v[2] == "SPPF":
spp_idx = len(layers)
layer = "\n# SPPF\n" layer = "\n# SPPF\n"
blocks = 0 blocks = 0
layer += yoloLayers.convolutional(bn=True, filters=get_width(v[3][0], width_multiple) / 2, layer += yoloLayers.convolutional(bn=True, filters=get_width(v[3][0], width_multiple) / 2,
@@ -291,3 +288,45 @@ with open(cfg_file, "w") as c:
layers.append([layer, blocks]) layers.append([layer, blocks])
for layer in layers: for layer in layers:
c.write(layer[0]) c.write(layer[0])
with open(wts_file, "w") as f:
wts_write = ""
conv_count = 0
cv1 = ""
cv3 = ""
cv3_idx = 0
for k, v in model.state_dict().items():
if "num_batches_tracked" not in k and "anchors" not in k and "anchor_grid" not in k:
vr = v.reshape(-1).cpu().numpy()
idx = int(k.split(".")[1])
if ".cv1." in k and ".m." not in k and idx != spp_idx:
cv1 += "{} {} ".format(k, len(vr))
for vv in vr:
cv1 += " "
cv1 += struct.pack(">f", float(vv)).hex()
cv1 += "\n"
conv_count += 1
elif cv1 != "" and ".m." in k:
wts_write += cv1
cv1 = ""
if ".cv3." in k:
cv3 += "{} {} ".format(k, len(vr))
for vv in vr:
cv3 += " "
cv3 += struct.pack(">f", float(vv)).hex()
cv3 += "\n"
cv3_idx = idx
conv_count += 1
elif cv3 != "" and cv3_idx != idx:
wts_write += cv3
cv3 = ""
cv3_idx = 0
if ".cv3." not in k and not (".cv1." in k and ".m." not in k and idx != spp_idx):
wts_write += "{} {} ".format(k, len(vr))
for vv in vr:
wts_write += " "
wts_write += struct.pack(">f", float(vv)).hex()
wts_write += "\n"
conv_count += 1
f.write("{}\n".format(conv_count))
f.write(wts_write)