From ca1ba7a53dd197c54e60d6f8e6654e7855ab1992 Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Mon, 2 Dec 2019 16:25:21 +0300 Subject: [PATCH] Backport for dnn input shape estimation --- modules/dnn/src/caffe/caffe_importer.cpp | 30 ++++++++++++++++++++++++ modules/dnn/src/dnn.cpp | 21 +++++++++++++++++ modules/dnn/test/test_caffe_importer.cpp | 11 +++++++++ modules/dnn/test/test_ie_models.cpp | 16 +------------ 4 files changed, 63 insertions(+), 15 deletions(-) diff --git a/modules/dnn/src/caffe/caffe_importer.cpp b/modules/dnn/src/caffe/caffe_importer.cpp index 6c4d79499d..a911f959d9 100644 --- a/modules/dnn/src/caffe/caffe_importer.cpp +++ b/modules/dnn/src/caffe/caffe_importer.cpp @@ -424,6 +424,36 @@ public: } dstNet.setInputsNames(netInputs); + std::vector inp_shapes; + if (net.input_shape_size() > 0 || (layersSize > 0 && net.layer(0).has_input_param() && + net.layer(0).input_param().shape_size() > 0)) { + + int size = (net.input_shape_size() > 0) ? net.input_shape_size() : + net.layer(0).input_param().shape_size(); + for (int inp_id = 0; inp_id < size; inp_id++) + { + const caffe::BlobShape &_input_shape = (net.input_shape_size() > 0) ? + net.input_shape(inp_id) : + net.layer(0).input_param().shape(inp_id); + MatShape shape; + for (int i = 0; i < _input_shape.dim_size(); i++) { + shape.push_back((int)_input_shape.dim(i)); + } + inp_shapes.push_back(shape); + } + } + else if (net.input_dim_size() > 0) { + MatShape shape; + for (int dim = 0; dim < net.input_dim_size(); dim++) { + shape.push_back(net.input_dim(dim)); + } + inp_shapes.push_back(shape); + } + + for (int inp_id = 0; inp_id < inp_shapes.size(); inp_id++) { + dstNet.setInput(Mat(inp_shapes[inp_id], CV_32F), netInputs[inp_id]); + } + addedBlobs.clear(); } diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index ad2e52766b..407cbf2c0d 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -2772,6 +2772,18 @@ struct Net::Impl { std::vector& inputLayerIds = layers[id].inputBlobsId; + if (inOutShapes[0].in[0].empty() && !layers[0].outputBlobs.empty()) + { + ShapesVec shapes; + for (int i = 0; i < layers[0].outputBlobs.size(); i++) + { + Mat& inp = layers[0].outputBlobs[i]; + CV_Assert(inp.total()); + shapes.push_back(shape(inp)); + } + inOutShapes[0].in = shapes; + } + if (inOutShapes[id].in.empty()) { for(int i = 0; i < inputLayerIds.size(); i++) @@ -2934,14 +2946,23 @@ Net Net::readFromModelOptimizer(const String& xml, const String& bin) #endif std::vector inputsNames; + std::vector inp_shapes; for (auto& it : ieNet.getInputsInfo()) { inputsNames.push_back(it.first); + std::vector dims = it.second->getTensorDesc().getDims(); + inp_shapes.push_back(std::vector(dims.begin(), dims.end())); } Net cvNet; cvNet.setInputsNames(inputsNames); + // set empty input to determine input shapes + for (int inp_id = 0; inp_id < inputsNames.size(); ++inp_id) + { + cvNet.setInput(Mat(inp_shapes[inp_id], CV_32F), inputsNames[inp_id]); + } + Ptr backendNode; #ifdef HAVE_DNN_NGRAPH if (DNN_BACKEND_INFERENCE_ENGINE_NGRAPH == getInferenceEngineBackendTypeParam()) diff --git a/modules/dnn/test/test_caffe_importer.cpp b/modules/dnn/test/test_caffe_importer.cpp index 3ec6f948d7..22e31db5ec 100644 --- a/modules/dnn/test/test_caffe_importer.cpp +++ b/modules/dnn/test/test_caffe_importer.cpp @@ -182,6 +182,17 @@ TEST_P(Reproducibility_AlexNet, Accuracy) ASSERT_FALSE(net.empty()); } + // Test input layer size + std::vector inLayerShapes; + std::vector outLayerShapes; + net.getLayerShapes(MatShape(), 0, inLayerShapes, outLayerShapes); + ASSERT_FALSE(inLayerShapes.empty()); + ASSERT_EQ(inLayerShapes[0].size(), 4); + ASSERT_EQ(inLayerShapes[0][0], 1); + ASSERT_EQ(inLayerShapes[0][1], 3); + ASSERT_EQ(inLayerShapes[0][2], 227); + ASSERT_EQ(inLayerShapes[0][3], 227); + const float l1 = 1e-5; const float lInf = (targetId == DNN_TARGET_OPENCL_FP16) ? 3e-3 : 1e-4; diff --git a/modules/dnn/test/test_ie_models.cpp b/modules/dnn/test/test_ie_models.cpp index 592d87c9fa..8d94543067 100644 --- a/modules/dnn/test/test_ie_models.cpp +++ b/modules/dnn/test/test_ie_models.cpp @@ -254,20 +254,6 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath infRequest.Infer(); } -std::vector getOutputsNames(const Net& net) -{ - std::vector names; - if (names.empty()) - { - std::vector outLayers = net.getUnconnectedOutLayers(); - std::vector layersNames = net.getLayerNames(); - names.resize(outLayers.size()); - for (size_t i = 0; i < outLayers.size(); ++i) - names[i] = layersNames[outLayers[i] - 1]; - } - return names; -} - void runCV(Backend backendId, Target targetId, const std::string& xmlPath, const std::string& binPath, const std::map& inputsMap, std::map& outputsMap) @@ -279,7 +265,7 @@ void runCV(Backend backendId, Target targetId, const std::string& xmlPath, const net.setPreferableBackend(backendId); net.setPreferableTarget(targetId); - std::vector outNames = getOutputsNames(net); + std::vector outNames = net.getUnconnectedOutLayersNames(); std::vector outs; net.forward(outs, outNames);