summaryrefslogtreecommitdiff
path: root/modules/dnn/src/tensorflow/tf_importer.cpp
diff options
context:
space:
mode:
authorDmitry Kurtaev <dmitry.kurtaev+github@gmail.com>2018-04-24 14:59:59 +0300
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>2018-04-24 14:59:59 +0300
commit4ec456f0a0993457120b916b36bde1d6df93e37b (patch)
treed14b856c9fe81f789dfd6f15a32c0ba12a1b42e0 /modules/dnn/src/tensorflow/tf_importer.cpp
parent909a25571e92cfeb367f3019bbf07b1c59c88307 (diff)
downloadopencv-4ec456f0a0993457120b916b36bde1d6df93e37b.tar.gz
opencv-4ec456f0a0993457120b916b36bde1d6df93e37b.tar.bz2
opencv-4ec456f0a0993457120b916b36bde1d6df93e37b.zip
Custom layers for deep learning networks (#11129)
* Custom deep learning layers support * Stack custom deep learning layers
Diffstat (limited to 'modules/dnn/src/tensorflow/tf_importer.cpp')
-rw-r--r--modules/dnn/src/tensorflow/tf_importer.cpp40
1 files changed, 38 insertions, 2 deletions
diff --git a/modules/dnn/src/tensorflow/tf_importer.cpp b/modules/dnn/src/tensorflow/tf_importer.cpp
index a401f715be..ea5d1e7957 100644
--- a/modules/dnn/src/tensorflow/tf_importer.cpp
+++ b/modules/dnn/src/tensorflow/tf_importer.cpp
@@ -1564,8 +1564,44 @@ void TFImporter::populateNet(Net dstNet)
}
else
{
- printLayerAttr(layer);
- CV_Error_(Error::StsError, ("Unknown layer type %s in op %s", type.c_str(), name.c_str()));
+ // Importer does not know how to map this TensorFlow's operation onto OpenCV's layer.
+ // However we create a layer with the same type and rely that user defined a custom layer.
+
+ // All the attributes are added to LayerParams.
+ google::protobuf::Map<std::string, tensorflow::AttrValue> attr = layer.attr();
+ for (google::protobuf::Map<std::string, tensorflow::AttrValue>::const_iterator ai = attr.begin();
+ ai != attr.end(); ++ai)
+ {
+ if (ai->second.value_case() == tensorflow::AttrValue::kS) // string
+ layerParams.set(ai->first, ai->second.s());
+ if (ai->second.value_case() == tensorflow::AttrValue::kI) // int64
+ layerParams.set(ai->first, ai->second.i());
+ if (ai->second.value_case() == tensorflow::AttrValue::kF) // float
+ layerParams.set(ai->first, ai->second.f());
+ if (ai->second.value_case() == tensorflow::AttrValue::kB) // bool
+ layerParams.set(ai->first, ai->second.b());
+ }
+
+ // All the Const input nodes are added to layer's blobs.
+ std::vector<std::string> inputsNames;
+ for (int i = 0; i < layer.input_size(); ++i)
+ {
+ // Check if input is a Const node.
+ if (value_id.find(layer.input(i)) != value_id.end())
+ {
+ Mat blob = getTensorContent(getConstBlob(layer, value_id, i));
+ layerParams.blobs.push_back(blob);
+ }
+ else
+ inputsNames.push_back(layer.input(i));
+ }
+ int id = dstNet.addLayer(name, type, layerParams);
+ layer_id[name] = id;
+
+ for (int i = 0; i < inputsNames.size(); ++i)
+ {
+ connect(layer_id, dstNet, parsePin(inputsNames[i]), id, i);
+ }
}
}
}