diff options
author | Dmitry Kurtaev <dmitry.kurtaev+github@gmail.com> | 2018-04-24 14:59:59 +0300 |
---|---|---|
committer | Vadim Pisarevsky <vadim.pisarevsky@gmail.com> | 2018-04-24 14:59:59 +0300 |
commit | 4ec456f0a0993457120b916b36bde1d6df93e37b (patch) | |
tree | d14b856c9fe81f789dfd6f15a32c0ba12a1b42e0 /modules/dnn/src/tensorflow/tf_importer.cpp | |
parent | 909a25571e92cfeb367f3019bbf07b1c59c88307 (diff) | |
download | opencv-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.cpp | 40 |
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); + } } } } |