mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 22:44:02 +08:00
Merge pull request #17185 from l-bat:yolo_v4
* Support Yolov4 * Skip Mish on OpenVINO 2020.2 * Revert Mish * Refactoring
This commit is contained in:
parent
0b439bcd08
commit
a5696da9ec
@ -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…
Reference in New Issue
Block a user