From 7eba3a7c9638c8a3f008e3595d60cbba1391b290 Mon Sep 17 00:00:00 2001 From: Liubov Batanina Date: Thu, 9 Jan 2020 13:59:35 +0300 Subject: [PATCH] Add pack description --- .../dnn/include/opencv2/dnn/all_layers.hpp | 2 +- modules/dnn/src/layers/layers_common.cpp | 20 +++++++-- modules/dnn/src/layers/layers_common.hpp | 2 +- modules/dnn/src/layers/pooling_layer.cpp | 42 +++++++------------ modules/dnn/src/tensorflow/tf_importer.cpp | 16 +++---- 5 files changed, 43 insertions(+), 39 deletions(-) diff --git a/modules/dnn/include/opencv2/dnn/all_layers.hpp b/modules/dnn/include/opencv2/dnn/all_layers.hpp index 73c85cad1c..2b9de0b663 100644 --- a/modules/dnn/include/opencv2/dnn/all_layers.hpp +++ b/modules/dnn/include/opencv2/dnn/all_layers.hpp @@ -250,7 +250,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN std::vector pads_begin, pads_end; CV_DEPRECATED_EXTERNAL Size kernel, stride, pad; CV_DEPRECATED_EXTERNAL int pad_l, pad_t, pad_r, pad_b; - bool globalPooling; + CV_DEPRECATED_EXTERNAL bool globalPooling; std::vector isGlobalPooling; bool computeMaxIdx; String padMode; diff --git a/modules/dnn/src/layers/layers_common.cpp b/modules/dnn/src/layers/layers_common.cpp index f119c12ac0..266d2cf45f 100644 --- a/modules/dnn/src/layers/layers_common.cpp +++ b/modules/dnn/src/layers/layers_common.cpp @@ -144,14 +144,26 @@ void getStrideAndPadding(const LayerParams ¶ms, std::vector& pads_be } } -void getPoolingKernelParams(const LayerParams ¶ms, std::vector& kernel, bool &globalPooling, +void getPoolingKernelParams(const LayerParams ¶ms, std::vector& kernel, std::vector& globalPooling, std::vector& pads_begin, std::vector& pads_end, std::vector& strides, cv::String &padMode) { - globalPooling = params.has("global_pooling") && - params.get("global_pooling"); + bool is_global = params.get("global_pooling", false); + globalPooling = std::vector(3, is_global); + if (params.has("global_d")) + { + globalPooling[0] = params.get("global_d"); + } + else if (params.has("global_h")) + { + globalPooling[1] = params.get("global_h"); + } + else if (params.has("global_w")) + { + globalPooling[2] = params.get("global_w"); + } - if (globalPooling) + if (is_global) { util::getStrideAndPadding(params, pads_begin, pads_end, strides, padMode); if(params.has("kernel_h") || params.has("kernel_w") || params.has("kernel_size")) diff --git a/modules/dnn/src/layers/layers_common.hpp b/modules/dnn/src/layers/layers_common.hpp index b574d7eed0..81e7bdd11c 100644 --- a/modules/dnn/src/layers/layers_common.hpp +++ b/modules/dnn/src/layers/layers_common.hpp @@ -63,7 +63,7 @@ void getConvolutionKernelParams(const LayerParams ¶ms, std::vector& std::vector& pads_end, std::vector& strides, std::vector& dilations, cv::String &padMode, std::vector& adjust_pads); -void getPoolingKernelParams(const LayerParams ¶ms, std::vector& kernel, bool &globalPooling, +void getPoolingKernelParams(const LayerParams ¶ms, std::vector& kernel, std::vector& globalPooling, std::vector& pads_begin, std::vector& pads_end, std::vector& strides, cv::String &padMode); void getConvPoolOutParams(const std::vector& inp, const std::vector& kernel, diff --git a/modules/dnn/src/layers/pooling_layer.cpp b/modules/dnn/src/layers/pooling_layer.cpp index aae9730c1a..c881cc7c8d 100644 --- a/modules/dnn/src/layers/pooling_layer.cpp +++ b/modules/dnn/src/layers/pooling_layer.cpp @@ -79,6 +79,7 @@ public: { computeMaxIdx = true; globalPooling = false; + isGlobalPooling = std::vector(3, false); stride = Size(1, 1); pad_t = pad_l = pad_b = pad_r = 0; @@ -95,7 +96,8 @@ public: else CV_Error(Error::StsBadArg, "Unknown pooling type \"" + pool + "\""); - getPoolingKernelParams(params, kernel_size, globalPooling, pads_begin, pads_end, strides, padMode); + getPoolingKernelParams(params, kernel_size, isGlobalPooling, pads_begin, pads_end, strides, padMode); + globalPooling = std::accumulate(isGlobalPooling.begin(), isGlobalPooling.end(), 0) == 3; if (kernel_size.size() == 2) { kernel = Size(kernel_size[1], kernel_size[0]); stride = Size(strides[1], strides[0]); @@ -125,14 +127,7 @@ public: setParamsFrom(params); ceilMode = params.get("ceil_mode", true); - if (params.has("is_global_pooling")) - { - const DictValue &global_axis = params.get("is_global_pooling"); - int size = global_axis.size(); - isGlobalPooling.resize(size); - for (int i = 0; i < size; i++) - isGlobalPooling[i] = global_axis.get(i); - } + spatialScale = params.get("spatial_scale", 1); avePoolPaddedArea = params.get("ave_pool_padded_area", true); } @@ -155,17 +150,14 @@ public: inp.push_back(inputs[0].size[i]); out.push_back(outputs[0].size[i]); } - if (globalPooling) { - kernel = Size(inp[1], inp[0]); - kernel_size = std::vector(inp.begin(), inp.end()); - } else if (!isGlobalPooling.empty()) { - for (int i = 0; i < isGlobalPooling.size(); i++) - { - if (isGlobalPooling[i]) - kernel_size[i] = inp[i]; - } - kernel = Size(kernel_size[1], kernel_size[0]); + kernel_size.resize(out.size()); + int diff_size = isGlobalPooling.size() - kernel_size.size(); + for (int i = 0; i < kernel_size.size(); i++) + { + if (isGlobalPooling[i + diff_size]) + kernel_size[i] = inp[i]; } + kernel = Size(kernel_size[1], kernel_size[0]); getConvPoolPaddings(inp, kernel_size, strides, padMode, pads_begin, pads_end); if (pads_begin.size() == 2) { @@ -1053,14 +1045,12 @@ virtual Ptr initNgraph(const std::vector >& inp outShape[0] = inputs[1][0]; // Number of proposals; outShape[1] = psRoiOutChannels; } - else if (!isGlobalPooling.empty()) + + int diff_size = isGlobalPooling.size() - (outShape.size() - 2); + for (int i = 2; i < outShape.size(); i++) { - CV_Assert(isGlobalPooling.size() == inpShape.size()); - for (int i = 0; i < isGlobalPooling.size(); i++) - { - if (isGlobalPooling[i]) - outShape[2 + i] = 1; - } + if (isGlobalPooling[i - 2 + diff_size]) + outShape[i] = 1; } int numOutputs = requiredOutputs ? requiredOutputs : (type == MAX ? 2 : 1); diff --git a/modules/dnn/src/tensorflow/tf_importer.cpp b/modules/dnn/src/tensorflow/tf_importer.cpp index f757efef5c..565002d637 100644 --- a/modules/dnn/src/tensorflow/tf_importer.cpp +++ b/modules/dnn/src/tensorflow/tf_importer.cpp @@ -1961,8 +1961,7 @@ void TFImporter::populateNet(Net dstNet) CV_Assert(layer_id.find(avgName) == layer_id.end()); avgLp.set("pool", "ave"); // pooling kernel H x 1 - bool isGlobalPooling[] = {true, false}; - avgLp.set("is_global_pooling", DictValue::arrayInt(&isGlobalPooling[0], 2)); + avgLp.set("global_h", true); avgLp.set("kernel_size", 1); int avgId = dstNet.addLayer(avgName, "Pooling", avgLp); layer_id[avgName] = avgId; @@ -2025,6 +2024,12 @@ void TFImporter::populateNet(Net dstNet) } else if (type == "Pack") { + // op: tf.stack(list of tensors, axis=0) + // Join a list of inputs along a new axis. + // The "axis" specifies the index of the new axis in the dimensions of the output. + // Example: given a list with "N" tensors of shape (C, H, W): + // if axis == 0 then the output tensor will have the shape (N, C, H, W), + // if axis == 1 then the output tensor will have the shape (C, N, H, W). CV_Assert(hasLayerAttr(layer, "axis")); int dim = (int)getLayerAttr(layer, "axis").i(); if (dim != 0) @@ -2054,11 +2059,8 @@ void TFImporter::populateNet(Net dstNet) int id = dstNet.addLayer(name, "Concat", layerParams); layer_id[name] = id; - for (int li = 0; li < num; li++) { - Pin inp = parsePin(reshape_names[li]); - connect(layer_id, dstNet, inp, id, li); - } - + for (int li = 0; li < num; li++) + connect(layer_id, dstNet, Pin(reshape_names[li]), id, li); } else if (type == "ClipByValue") {