Merge pull request #17185 from l-bat:yolo_v4

* Support Yolov4

* Skip Mish on OpenVINO 2020.2

* Revert Mish

* Refactoring
pull/17198/head
Liubov Batanina 5 years ago committed by GitHub
parent 0b439bcd08
commit a5696da9ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      modules/dnn/src/darknet/darknet_io.cpp
  2. 17
      modules/dnn/src/layers/region_layer.cpp
  3. 5
      modules/dnn/test/test_darknet_importer.cpp

@ -229,6 +229,10 @@ namespace cv {
{
activation_param.type = "Swish";
}
else if (type == "mish")
{
activation_param.type = "Mish";
}
else if (type == "logistic")
{
activation_param.type = "Sigmoid";
@ -436,7 +440,7 @@ namespace cv {
fused_layer_names.push_back(last_layer);
}
void setYolo(int classes, const std::vector<int>& mask, const std::vector<float>& anchors, float thresh, float nms_threshold)
void setYolo(int classes, const std::vector<int>& mask, const std::vector<float>& anchors, float thresh, float nms_threshold, float scale_x_y)
{
cv::dnn::LayerParams region_param;
region_param.name = "Region-name";
@ -449,6 +453,7 @@ namespace cv {
region_param.set<bool>("logistic", true);
region_param.set<float>("thresh", thresh);
region_param.set<float>("nms_threshold", nms_threshold);
region_param.set<float>("scale_x_y", scale_x_y);
std::vector<float> usedAnchors(numAnchors * 2);
for (int i = 0; i < numAnchors; ++i)
@ -786,6 +791,7 @@ namespace cv {
int num_of_anchors = getParam<int>(layer_params, "num", -1);
float thresh = getParam<float>(layer_params, "thresh", 0.2);
float nms_threshold = getParam<float>(layer_params, "nms_threshold", 0.4);
float scale_x_y = getParam<float>(layer_params, "scale_x_y", 1.0);
std::string anchors_values = getParam<std::string>(layer_params, "anchors", std::string());
CV_Assert(!anchors_values.empty());
@ -798,7 +804,7 @@ namespace cv {
CV_Assert(classes > 0 && num_of_anchors > 0 && (num_of_anchors * 2) == anchors_vec.size());
setParams.setPermute(false);
setParams.setYolo(classes, mask_vec, anchors_vec, thresh, nms_threshold);
setParams.setYolo(classes, mask_vec, anchors_vec, thresh, nms_threshold, scale_x_y);
}
else {
CV_Error(cv::Error::StsParseError, "Unknown layer type: " + layer_type);
@ -813,6 +819,10 @@ namespace cv {
{
setParams.setActivation("swish");
}
else if (activation == "mish")
{
setParams.setActivation("mish");
}
else if (activation == "logistic")
{
setParams.setActivation("logistic");
@ -935,8 +945,8 @@ namespace cv {
}
std::string activation = getParam<std::string>(layer_params, "activation", "linear");
if(activation == "leaky" || activation == "swish" || activation == "logistic")
++cv_layers_counter; // For ReLU, Swish, Sigmoid
if(activation == "leaky" || activation == "swish" || activation == "mish" || activation == "logistic")
++cv_layers_counter; // For ReLU, Swish, Mish, Sigmoid
if(!darknet_layers_counter)
tensor_shape.resize(1);

@ -63,7 +63,7 @@ class RegionLayerImpl CV_FINAL : public RegionLayer
{
public:
int coords, classes, anchors, classfix;
float thresh, nmsThreshold;
float thresh, nmsThreshold, scale_x_y;
bool useSoftmax, useLogistic;
#ifdef HAVE_OPENCL
UMat blob_umat;
@ -82,6 +82,7 @@ public:
useSoftmax = params.get<bool>("softmax", false);
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
CV_Assert(nmsThreshold >= 0.);
CV_Assert(coords == 4);
@ -292,8 +293,10 @@ public:
if (classfix == -1 && scale < .5) scale = 0; // if(t0 < 0.5) t0 = 0;
int box_index = index_sample_offset + index * cell_size;
dstData[box_index + 0] = (x + logistic_activate(srcData[box_index + 0])) / cols;
dstData[box_index + 1] = (y + logistic_activate(srcData[box_index + 1])) / rows;
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;
@ -406,6 +409,8 @@ public:
auto shape_3d = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{boxes_shape.size()}, boxes_shape.data());
ngraph::Shape box_broad_shape{1, (size_t)anchors, (size_t)h, (size_t)w};
auto scale_x_y_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, &scale_x_y);
auto shift_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, std::vector<float>{0.5});
std::shared_ptr<ngraph::Node> box_x;
{
@ -413,6 +418,9 @@ public:
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{1, cols});
box_x = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
box_x = std::make_shared<ngraph::op::Sigmoid>(box_x);
box_x = std::make_shared<ngraph::op::v1::Subtract>(box_x, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
box_x = std::make_shared<ngraph::op::v1::Multiply>(box_x, scale_x_y_node, ngraph::op::AutoBroadcastType::NUMPY);
box_x = std::make_shared<ngraph::op::v1::Add>(box_x, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
box_x = std::make_shared<ngraph::op::v1::Reshape>(box_x, shape_3d, true);
std::vector<float> x_indices(w * h * anchors);
@ -439,6 +447,9 @@ public:
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{2, cols});
box_y = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
box_y = std::make_shared<ngraph::op::Sigmoid>(box_y);
box_y = std::make_shared<ngraph::op::v1::Subtract>(box_y, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
box_y = std::make_shared<ngraph::op::v1::Multiply>(box_y, scale_x_y_node, ngraph::op::AutoBroadcastType::NUMPY);
box_y = std::make_shared<ngraph::op::v1::Add>(box_y, shift_node, ngraph::op::AutoBroadcastType::NUMPY);
box_y = std::make_shared<ngraph::op::v1::Reshape>(box_y, shape_3d, true);
std::vector<float> y_indices(h * anchors);

@ -523,6 +523,11 @@ TEST_P(Test_Darknet_layers, upsample)
testDarknetLayer("upsample");
}
TEST_P(Test_Darknet_layers, mish)
{
testDarknetLayer("mish", true);
}
TEST_P(Test_Darknet_layers, avgpool_softmax)
{
testDarknetLayer("avgpool_softmax");

Loading…
Cancel
Save