Skip to content

Commit 6fbf6f8

Browse files
committed
Merge pull request opencv#13359 from dkurt:dnn_keras_pad_concat
2 parents e090ea3 + c9e0c77 commit 6fbf6f8

File tree

5 files changed

+101
-5
lines changed

5 files changed

+101
-5
lines changed

modules/dnn/include/opencv2/dnn/all_layers.hpp

+9
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
7777
static Ptr<Layer> create(const LayerParams &params);
7878
};
7979

80+
/**
81+
* Constant layer produces the same data blob at an every forward pass.
82+
*/
83+
class CV_EXPORTS ConstLayer : public Layer
84+
{
85+
public:
86+
static Ptr<Layer> create(const LayerParams &params);
87+
};
88+
8089
//! LSTM recurrent layer
8190
class CV_EXPORTS LSTMLayer : public Layer
8291
{

modules/dnn/src/init.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ void initializeLayerFactory()
112112
CV_DNN_REGISTER_LAYER_CLASS(Dropout, BlankLayer);
113113
CV_DNN_REGISTER_LAYER_CLASS(Identity, BlankLayer);
114114
CV_DNN_REGISTER_LAYER_CLASS(Silence, BlankLayer);
115+
CV_DNN_REGISTER_LAYER_CLASS(Const, ConstLayer);
115116

116117
CV_DNN_REGISTER_LAYER_CLASS(Crop, CropLayer);
117118
CV_DNN_REGISTER_LAYER_CLASS(Eltwise, EltwiseLayer);
+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
5+
// Copyright (C) 2018, Intel Corporation, all rights reserved.
6+
// Third party copyrights are property of their respective owners.
7+
8+
#include "../precomp.hpp"
9+
#include "layers_common.hpp"
10+
11+
#ifdef HAVE_OPENCL
12+
#include "opencl_kernels_dnn.hpp"
13+
#endif
14+
15+
namespace cv { namespace dnn {
16+
17+
class ConstLayerImpl CV_FINAL : public ConstLayer
18+
{
19+
public:
20+
ConstLayerImpl(const LayerParams& params)
21+
{
22+
setParamsFrom(params);
23+
CV_Assert(blobs.size() == 1);
24+
}
25+
26+
virtual bool getMemoryShapes(const std::vector<MatShape> &inputs,
27+
const int requiredOutputs,
28+
std::vector<MatShape> &outputs,
29+
std::vector<MatShape> &internals) const CV_OVERRIDE
30+
{
31+
CV_Assert(inputs.empty());
32+
outputs.assign(1, shape(blobs[0]));
33+
return false;
34+
}
35+
36+
#ifdef HAVE_OPENCL
37+
bool forward_ocl(InputArrayOfArrays inps, OutputArrayOfArrays outs, OutputArrayOfArrays internals)
38+
{
39+
std::vector<UMat> outputs;
40+
outs.getUMatVector(outputs);
41+
if (outs.depth() == CV_16S)
42+
convertFp16(blobs[0], outputs[0]);
43+
else
44+
blobs[0].copyTo(outputs[0]);
45+
return true;
46+
}
47+
#endif
48+
49+
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
50+
{
51+
CV_TRACE_FUNCTION();
52+
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
53+
54+
CV_OCL_RUN(IS_DNN_OPENCL_TARGET(preferableTarget),
55+
forward_ocl(inputs_arr, outputs_arr, internals_arr))
56+
57+
std::vector<Mat> outputs;
58+
outputs_arr.getMatVector(outputs);
59+
blobs[0].copyTo(outputs[0]);
60+
}
61+
};
62+
63+
Ptr<Layer> ConstLayer::create(const LayerParams& params)
64+
{
65+
return Ptr<Layer>(new ConstLayerImpl(params));
66+
}
67+
68+
}} // namespace cv::dnn

modules/dnn/src/tensorflow/tf_importer.cpp

+22-5
Original file line numberDiff line numberDiff line change
@@ -1266,14 +1266,31 @@ void TFImporter::populateNet(Net dstNet)
12661266
axis = toNCHW(axis);
12671267
layerParams.set("axis", axis);
12681268

1269-
int id = dstNet.addLayer(name, "Concat", layerParams);
1270-
layer_id[name] = id;
1271-
1272-
1269+
// input(0) or input(n-1) is concat_dim
12731270
int from = (type == "Concat" ? 1 : 0);
12741271
int to = (type == "Concat" ? layer.input_size() : layer.input_size() - 1);
12751272

1276-
// input(0) or input(n-1) is concat_dim
1273+
for (int ii = from; ii < to; ii++)
1274+
{
1275+
Pin inp = parsePin(layer.input(ii));
1276+
if (layer_id.find(inp.name) == layer_id.end())
1277+
{
1278+
// There are constant inputs.
1279+
LayerParams lp;
1280+
lp.name = inp.name;
1281+
lp.type = "Const";
1282+
lp.blobs.resize(1);
1283+
blobFromTensor(getConstBlob(layer, value_id, ii), lp.blobs.back());
1284+
CV_Assert_N(!lp.blobs[0].empty(), lp.blobs[0].type() == CV_32F);
1285+
1286+
int constInpId = dstNet.addLayer(lp.name, lp.type, lp);
1287+
layer_id[lp.name] = constInpId;
1288+
}
1289+
}
1290+
1291+
int id = dstNet.addLayer(name, "Concat", layerParams);
1292+
layer_id[name] = id;
1293+
12771294
for (int ii = from; ii < to; ii++)
12781295
{
12791296
Pin inp = parsePin(layer.input(ii));

modules/dnn/test/test_tf_importer.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ TEST_P(Test_TensorFlow_layers, padding)
136136
runTensorFlowNet("padding_same");
137137
runTensorFlowNet("padding_valid");
138138
runTensorFlowNet("spatial_padding");
139+
runTensorFlowNet("keras_pad_concat");
139140
}
140141

141142
TEST_P(Test_TensorFlow_layers, eltwise_add_mul)

0 commit comments

Comments
 (0)