fix max_unpool missing attributes, add default value of keepdims in reducemean/max/sum, add support for keepdims=true in full reduction branch, add new padding type to Pad

pull/21259/head
Smirnov Egor 3 years ago
parent 35f27d0d3e
commit e97c7e042b
  1. 9
      modules/dnn/src/layers/padding_layer.cpp
  2. 48
      modules/dnn/src/onnx/onnx_importer.cpp
  3. 5
      modules/dnn/test/test_onnx_conformance_layer_parser_denylist.inl.hpp

@ -130,12 +130,13 @@ public:
outputs[0].setTo(paddingValue);
inputs[0].copyTo(outputs[0](dstRanges));
}
else if (paddingType == "reflect")
else if (paddingType == "reflect" || paddingType == "edge")
{
CV_Assert(inputs.size() == 1);
CV_Assert(outputs.size() == 1);
CV_Assert(inputs[0].dims == 4);
CV_Assert(outputs[0].dims == 4);
int borderType = paddingType == "reflect" ? BORDER_REFLECT_101 : BORDER_REPLICATE;
if (inputs[0].size[0] != outputs[0].size[0] || inputs[0].size[1] != outputs[0].size[1])
CV_Error(Error::StsNotImplemented, "Only spatial reflection padding is supported.");
@ -148,8 +149,8 @@ public:
const int padBottom = outHeight - dstRanges[2].end;
const int padLeft = dstRanges[3].start;
const int padRight = outWidth - dstRanges[3].end;
CV_CheckLT(padTop, inpHeight, ""); CV_CheckLT(padBottom, inpHeight, "");
CV_CheckLT(padLeft, inpWidth, ""); CV_CheckLT(padRight, inpWidth, "");
CV_CheckLE(padTop, inpHeight, ""); CV_CheckLE(padBottom, inpHeight, "");
CV_CheckLE(padLeft, inpWidth, ""); CV_CheckLE(padRight, inpWidth, "");
for (size_t n = 0; n < inputs[0].size[0]; ++n)
{
@ -158,7 +159,7 @@ public:
copyMakeBorder(getPlane(inputs[0], n, ch),
getPlane(outputs[0], n, ch),
padTop, padBottom, padLeft, padRight,
BORDER_REFLECT_101);
borderType);
}
}
}

@ -131,6 +131,7 @@ private:
typedef void (ONNXImporter::*ONNXImporterNodeParser)(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
typedef std::map<std::string, ONNXImporterNodeParser> DispatchMap;
void parseMaxUnpool (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
void parseMaxPool (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
void parseAveragePool (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
void parseReduce (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
@ -625,6 +626,41 @@ void setCeilMode(LayerParams& layerParams)
}
}
void ONNXImporter::parseMaxUnpool(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
{
layerParams.type = "MaxUnpool";
DictValue kernel_shape = layerParams.get("kernel_size");
CV_Assert(kernel_shape.size() == 2);
layerParams.set("pool_k_w", kernel_shape.get<int>(0));
layerParams.set("pool_k_h", kernel_shape.get<int>(1));
int pool_pad_w = 0, pool_pad_h = 0;
if (layerParams.has("pad"))
{
DictValue pads = layerParams.get("pad");
CV_CheckEQ(pads.size(), 2, "");
pool_pad_w = pads.get<int>(0);
pool_pad_h = pads.get<int>(1);
}
layerParams.set("pool_pad_w", pool_pad_w);
layerParams.set("pool_pad_h", pool_pad_h);
int pool_stride_w = 1, pool_stride_h = 1;
if (layerParams.has("stride"))
{
DictValue strides = layerParams.get("stride");
CV_CheckEQ(strides.size(), 2, "");
pool_stride_w = strides.get<int>(0);
pool_stride_h = strides.get<int>(1);
}
layerParams.set("pool_stride_w", pool_stride_w);
layerParams.set("pool_stride_h", pool_stride_h);
addLayer(layerParams, node_proto);
}
void ONNXImporter::parseMaxPool(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
{
layerParams.type = "Pooling";
@ -659,11 +695,11 @@ void ONNXImporter::parseReduce(LayerParams& layerParams, const opencv_onnx::Node
pool = "AVE";
layerParams.set("pool", pool);
layerParams.set("global_pooling", !layerParams.has("axes"));
bool keepdims = layerParams.get<int>("keepdims", 1) == 1;
if (layerParams.has("axes") && (layer_type == "ReduceMean" || layer_type == "ReduceSum" || layer_type == "ReduceMax"))
{
MatShape inpShape = outShapes[node_proto.input(0)];
DictValue axes = layerParams.get("axes");
bool keepdims = layerParams.get<int>("keepdims");
MatShape targetShape;
std::vector<bool> shouldDelete(inpShape.size(), false);
for (int i = 0; i < axes.size(); i++) {
@ -771,7 +807,10 @@ void ONNXImporter::parseReduce(LayerParams& layerParams, const opencv_onnx::Node
}
else if (!layerParams.has("axes") && (layer_type == "ReduceMean" || layer_type == "ReduceSum" || layer_type == "ReduceMax"))
{
CV_CheckEQ(layerParams.get<int>("keepdims"), 0, "layer only supports keepdims = false");
IterShape_t shapeIt = outShapes.find(node_proto.input(0));
CV_Assert(shapeIt != outShapes.end());
const size_t dims = keepdims ? shapeIt->second.size() : 1;
LayerParams reshapeLp;
reshapeLp.name = layerParams.name + "/reshape";
reshapeLp.type = "Reshape";
@ -793,8 +832,8 @@ void ONNXImporter::parseReduce(LayerParams& layerParams, const opencv_onnx::Node
addLayer(poolLp, node_proto);
layerParams.type = "Reshape";
int targetShape[] = {1};
layerParams.set("dim", DictValue::arrayInt(&targetShape[0], 1));
std::vector<int> targetShape(dims, 1);
layerParams.set("dim", DictValue::arrayInt(targetShape.data(), targetShape.size()));
node_proto.set_input(0, node_proto.output(0));
node_proto.set_output(0, layerParams.name);
@ -2341,6 +2380,7 @@ const ONNXImporter::DispatchMap ONNXImporter::buildDispatchMap()
{
DispatchMap dispatch;
dispatch["MaxUnpool"] = &ONNXImporter::parseMaxUnpool;
dispatch["MaxPool"] = &ONNXImporter::parseMaxPool;
dispatch["AveragePool"] = &ONNXImporter::parseAveragePool;
dispatch["GlobalAveragePool"] = dispatch["GlobalMaxPool"] = dispatch["ReduceMean"] = dispatch["ReduceSum"] =

@ -277,7 +277,6 @@
"test_max_uint8",
"test_maxpool_2d_uint8",
"test_maxunpool_export_with_output_shape",
"test_maxunpool_export_without_output_shape",
"test_mean_example",
"test_mean_one_input",
"test_mean_two_inputs",
@ -436,10 +435,6 @@
"test_reduce_log_sum_exp_negative_axes_keepdims_example",
"test_reduce_log_sum_exp_negative_axes_keepdims_random",
"test_reduce_log_sum_negative_axes",
"test_reduce_max_default_axes_keepdim_example",
"test_reduce_max_default_axes_keepdims_random",
"test_reduce_mean_default_axes_keepdims_example",
"test_reduce_mean_default_axes_keepdims_random",
"test_reduce_min_default_axes_keepdims_example",
"test_reduce_min_default_axes_keepdims_random",
"test_reduce_min_do_not_keepdims_example",

Loading…
Cancel
Save