1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Merge pull request #20671 from rogday:yolov4x-mish

Add support for YOLOv4x-mish

* backport to 3.4 for supporting yolov4x-mish

* add YOLOv4x-mish test

* address review comments

Co-authored-by: Guo Xu <guoxu@1school.com.cn>
This commit is contained in:
rogday
2021-09-14 20:49:49 +03:00
committed by GitHub
parent 6fa63dcc0c
commit c410d7a97d
3 changed files with 135 additions and 31 deletions
+59 -29
View File
@@ -64,6 +64,7 @@ class RegionLayerImpl CV_FINAL : public RegionLayer
public:
int coords, classes, anchors, classfix;
float thresh, nmsThreshold, scale_x_y;
int new_coords;
bool useSoftmax, useLogistic;
#ifdef HAVE_OPENCL
UMat blob_umat;
@@ -83,6 +84,7 @@ public:
useLogistic = params.get<bool>("logistic", false);
nmsThreshold = params.get<float>("nms_threshold", 0.4);
scale_x_y = params.get<float>("scale_x_y", 1.0); // Yolov4
new_coords = params.get<int>("new_coords", 0); // Yolov4x-mish
CV_Assert(nmsThreshold >= 0.);
CV_Assert(coords == 4);
@@ -113,7 +115,7 @@ public:
{
#ifdef HAVE_DNN_NGRAPH
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
return INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2) && preferableTarget != DNN_TARGET_MYRIAD;
return INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2) && preferableTarget != DNN_TARGET_MYRIAD && new_coords == 0;
#endif
return backendId == DNN_BACKEND_OPENCV;
}
@@ -259,26 +261,28 @@ public:
const float *srcData = inpBlob.ptr<float>();
float *dstData = outBlob.ptr<float>();
// logistic activation for t0, for each grid cell (X x Y x Anchor-index)
for (int i = 0; i < batch_size*rows*cols*anchors; ++i) {
int index = cell_size*i;
float x = srcData[index + 4];
dstData[index + 4] = logistic_activate(x); // logistic activation
}
if (useSoftmax) { // Yolo v2
if (new_coords == 0) {
// logistic activation for t0, for each grid cell (X x Y x Anchor-index)
for (int i = 0; i < batch_size*rows*cols*anchors; ++i) {
int index = cell_size*i;
softmax_activate(srcData + index + 5, classes, 1, dstData + index + 5);
float x = srcData[index + 4];
dstData[index + 4] = logistic_activate(x); // logistic activation
}
}
else if (useLogistic) { // Yolo v3
for (int i = 0; i < batch_size*rows*cols*anchors; ++i){
int index = cell_size*i;
const float* input = srcData + index + 5;
float* output = dstData + index + 5;
for (int c = 0; c < classes; ++c)
output[c] = logistic_activate(input[c]);
if (useSoftmax) { // Yolo v2
for (int i = 0; i < batch_size*rows*cols*anchors; ++i) {
int index = cell_size*i;
softmax_activate(srcData + index + 5, classes, 1, dstData + index + 5);
}
}
else if (useLogistic) { // Yolo v3
for (int i = 0; i < batch_size*rows*cols*anchors; ++i){
int index = cell_size*i;
const float* input = srcData + index + 5;
float* output = dstData + index + 5;
for (int c = 0; c < classes; ++c)
output[c] = logistic_activate(input[c]);
}
}
}
for (int b = 0; b < batch_size; ++b)
@@ -290,20 +294,46 @@ public:
int index = (y*cols + x)*anchors + a; // index for each grid-cell & anchor
int p_index = index_sample_offset + index * cell_size + 4;
float scale = dstData[p_index];
if (classfix == -1 && scale < .5) scale = 0; // if(t0 < 0.5) t0 = 0;
if (classfix == -1 && scale < .5)
{
scale = 0; // if(t0 < 0.5) t0 = 0;
}
int box_index = index_sample_offset + index * cell_size;
float x_tmp = (logistic_activate(srcData[box_index + 0]) - 0.5f) * scale_x_y + 0.5f;
float y_tmp = (logistic_activate(srcData[box_index + 1]) - 0.5f) * scale_x_y + 0.5f;
dstData[box_index + 0] = (x + x_tmp) / cols;
dstData[box_index + 1] = (y + y_tmp) / rows;
dstData[box_index + 2] = exp(srcData[box_index + 2]) * biasData[2 * a] / wNorm;
dstData[box_index + 3] = exp(srcData[box_index + 3]) * biasData[2 * a + 1] / hNorm;
if (new_coords == 1) {
float x_tmp = (srcData[box_index + 0] - 0.5f) * scale_x_y + 0.5f;
float y_tmp = (srcData[box_index + 1] - 0.5f) * scale_x_y + 0.5f;
dstData[box_index + 0] = (x + x_tmp) / cols;
dstData[box_index + 1] = (y + y_tmp) / rows;
dstData[box_index + 2] = (srcData[box_index + 2]) * (srcData[box_index + 2]) * 4 * biasData[2 * a] / wNorm;
dstData[box_index + 3] = (srcData[box_index + 3]) * (srcData[box_index + 3]) * 4 * biasData[2 * a + 1] / hNorm;
int class_index = index_sample_offset + index * cell_size + 5;
for (int j = 0; j < classes; ++j) {
float prob = scale*dstData[class_index + j]; // prob = IoU(box, object) = t0 * class-probability
dstData[class_index + j] = (prob > thresh) ? prob : 0; // if (IoU < threshold) IoU = 0;
scale = srcData[p_index];
if (classfix == -1 && scale < thresh)
{
scale = 0; // if(t0 < 0.5) t0 = 0;
}
int class_index = index_sample_offset + index * cell_size + 5;
for (int j = 0; j < classes; ++j) {
float prob = scale*srcData[class_index + j]; // prob = IoU(box, object) = t0 * class-probability
dstData[class_index + j] = (prob > thresh) ? prob : 0; // if (IoU < threshold) IoU = 0;
}
}
else
{
float x_tmp = (logistic_activate(srcData[box_index + 0]) - 0.5f) * scale_x_y + 0.5f;
float y_tmp = (logistic_activate(srcData[box_index + 1]) - 0.5f) * scale_x_y + 0.5f;
dstData[box_index + 0] = (x + x_tmp) / cols;
dstData[box_index + 1] = (y + y_tmp) / rows;
dstData[box_index + 2] = exp(srcData[box_index + 2]) * biasData[2 * a] / wNorm;
dstData[box_index + 3] = exp(srcData[box_index + 3]) * biasData[2 * a + 1] / hNorm;
int class_index = index_sample_offset + index * cell_size + 5;
for (int j = 0; j < classes; ++j) {
float prob = scale*dstData[class_index + j]; // prob = IoU(box, object) = t0 * class-probability
dstData[class_index + j] = (prob > thresh) ? prob : 0; // if (IoU < threshold) IoU = 0;
}
}
}
if (nmsThreshold > 0) {