mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge pull request #12082 from dkurt:dnn_ie_faster_rcnn
This commit is contained in:
@@ -258,6 +258,17 @@ PERF_TEST_P_(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", "", Mat(cv::Size(320, 240), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, Inception_v2_Faster_RCNN)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/faster_rcnn_inception_v2_coco_2018_01_28.pb",
|
||||
"dnn/faster_rcnn_inception_v2_coco_2018_01_28.pbtxt", "",
|
||||
Mat(cv::Size(800, 600), CV_32FC3));
|
||||
}
|
||||
|
||||
const tuple<DNNBackend, DNNTarget> testCases[] = {
|
||||
#ifdef HAVE_HALIDE
|
||||
tuple<DNNBackend, DNNTarget>(DNN_BACKEND_HALIDE, DNN_TARGET_CPU),
|
||||
|
||||
+20
-19
@@ -1408,7 +1408,7 @@ struct Net::Impl
|
||||
bool fused = ld.skip;
|
||||
|
||||
Ptr<Layer> layer = ld.layerInstance;
|
||||
if (!layer->supportBackend(preferableBackend))
|
||||
if (!fused && !layer->supportBackend(preferableBackend))
|
||||
{
|
||||
addInfEngineNetOutputs(ld);
|
||||
net = Ptr<InfEngineBackendNet>();
|
||||
@@ -2050,10 +2050,10 @@ struct Net::Impl
|
||||
TickMeter tm;
|
||||
tm.start();
|
||||
|
||||
if (preferableBackend == DNN_BACKEND_OPENCV ||
|
||||
!layer->supportBackend(preferableBackend))
|
||||
if( !ld.skip )
|
||||
{
|
||||
if( !ld.skip )
|
||||
std::map<int, Ptr<BackendNode> >::iterator it = ld.backendNodes.find(preferableBackend);
|
||||
if (preferableBackend == DNN_BACKEND_OPENCV || it == ld.backendNodes.end() || it->second.empty())
|
||||
{
|
||||
if (preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget))
|
||||
{
|
||||
@@ -2196,24 +2196,25 @@ struct Net::Impl
|
||||
}
|
||||
}
|
||||
else
|
||||
tm.reset();
|
||||
}
|
||||
else if (!ld.skip)
|
||||
{
|
||||
Ptr<BackendNode> node = ld.backendNodes[preferableBackend];
|
||||
if (preferableBackend == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
forwardHalide(ld.outputBlobsWrappers, node);
|
||||
}
|
||||
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
{
|
||||
forwardInfEngine(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "Unknown backend identifier");
|
||||
Ptr<BackendNode> node = it->second;
|
||||
CV_Assert(!node.empty());
|
||||
if (preferableBackend == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
forwardHalide(ld.outputBlobsWrappers, node);
|
||||
}
|
||||
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
{
|
||||
forwardInfEngine(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "Unknown backend identifier");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
tm.reset();
|
||||
|
||||
tm.stop();
|
||||
layersTimings[ld.id] = tm.getTimeTicks();
|
||||
|
||||
@@ -196,7 +196,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && !_locPredTransposed && _bboxesNormalized;
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && !_locPredTransposed && _bboxesNormalized && !_clip;
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
||||
@@ -48,9 +48,8 @@ public:
|
||||
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine();
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && axis == 1;
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
|
||||
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && sliceRanges.size() == 1;
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && sliceRanges.size() == 1 && sliceRanges[0].size() == 4;
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
||||
@@ -307,15 +307,17 @@ public:
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> >&) CV_OVERRIDE
|
||||
virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> >& inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
InferenceEngine::DataPtr input = infEngineDataNode(inputs[0]);
|
||||
|
||||
InferenceEngine::LayerParams lp;
|
||||
lp.name = name;
|
||||
lp.type = "SoftMax";
|
||||
lp.precision = InferenceEngine::Precision::FP32;
|
||||
std::shared_ptr<InferenceEngine::SoftMaxLayer> ieLayer(new InferenceEngine::SoftMaxLayer(lp));
|
||||
ieLayer->axis = axisRaw;
|
||||
ieLayer->axis = clamp(axisRaw, input->dims.size());
|
||||
return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
|
||||
#endif // HAVE_INF_ENGINE
|
||||
return Ptr<BackendNode>();
|
||||
|
||||
@@ -954,6 +954,13 @@ void TFImporter::populateNet(Net dstNet)
|
||||
{
|
||||
CV_Assert(layer.input_size() == 2);
|
||||
|
||||
// For the object detection networks, TensorFlow Object Detection API
|
||||
// predicts deltas for bounding boxes in yxYX (ymin, xmin, ymax, xmax)
|
||||
// order. We can manage it at DetectionOutput layer parsing predictions
|
||||
// or shuffle last Faster-RCNN's matmul weights.
|
||||
bool locPredTransposed = hasLayerAttr(layer, "loc_pred_transposed") &&
|
||||
getLayerAttr(layer, "loc_pred_transposed").b();
|
||||
|
||||
layerParams.set("bias_term", false);
|
||||
layerParams.blobs.resize(1);
|
||||
|
||||
@@ -970,6 +977,17 @@ void TFImporter::populateNet(Net dstNet)
|
||||
blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs[1]);
|
||||
ExcludeLayer(net, weights_layer_index, 0, false);
|
||||
layers_to_ignore.insert(next_layers[0].first);
|
||||
|
||||
if (locPredTransposed)
|
||||
{
|
||||
const int numWeights = layerParams.blobs[1].total();
|
||||
float* biasData = reinterpret_cast<float*>(layerParams.blobs[1].data);
|
||||
CV_Assert(numWeights % 4 == 0);
|
||||
for (int i = 0; i < numWeights; i += 2)
|
||||
{
|
||||
std::swap(biasData[i], biasData[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int kernel_blob_index = -1;
|
||||
@@ -983,6 +1001,16 @@ void TFImporter::populateNet(Net dstNet)
|
||||
}
|
||||
|
||||
layerParams.set("num_output", layerParams.blobs[0].size[0]);
|
||||
if (locPredTransposed)
|
||||
{
|
||||
CV_Assert(layerParams.blobs[0].dims == 2);
|
||||
for (int i = 0; i < layerParams.blobs[0].size[0]; i += 2)
|
||||
{
|
||||
cv::Mat src = layerParams.blobs[0].row(i);
|
||||
cv::Mat dst = layerParams.blobs[0].row(i + 1);
|
||||
std::swap_ranges(src.begin<float>(), src.end<float>(), dst.begin<float>());
|
||||
}
|
||||
}
|
||||
|
||||
int id = dstNet.addLayer(name, "InnerProduct", layerParams);
|
||||
layer_id[name] = id;
|
||||
@@ -1010,6 +1038,7 @@ void TFImporter::populateNet(Net dstNet)
|
||||
layer_id[permName] = permId;
|
||||
connect(layer_id, dstNet, inpId, permId, 0);
|
||||
inpId = Pin(permName);
|
||||
inpLayout = DATA_LAYOUT_NCHW;
|
||||
}
|
||||
else if (newShape.total() == 4 && inpLayout == DATA_LAYOUT_NHWC)
|
||||
{
|
||||
@@ -1024,7 +1053,7 @@ void TFImporter::populateNet(Net dstNet)
|
||||
|
||||
// one input only
|
||||
connect(layer_id, dstNet, inpId, id, 0);
|
||||
data_layouts[name] = newShape.total() == 2 ? DATA_LAYOUT_PLANAR : DATA_LAYOUT_UNKNOWN;
|
||||
data_layouts[name] = newShape.total() == 2 ? DATA_LAYOUT_PLANAR : inpLayout;
|
||||
}
|
||||
else if (type == "Flatten" || type == "Squeeze")
|
||||
{
|
||||
@@ -1696,41 +1725,6 @@ void TFImporter::populateNet(Net dstNet)
|
||||
connect(layer_id, dstNet, parsePin(layer.input(1)), id, 1);
|
||||
data_layouts[name] = DATA_LAYOUT_UNKNOWN;
|
||||
}
|
||||
else if (type == "DetectionOutput")
|
||||
{
|
||||
// op: "DetectionOutput"
|
||||
// input_0: "locations"
|
||||
// input_1: "classifications"
|
||||
// input_2: "prior_boxes"
|
||||
if (hasLayerAttr(layer, "num_classes"))
|
||||
layerParams.set("num_classes", getLayerAttr(layer, "num_classes").i());
|
||||
if (hasLayerAttr(layer, "share_location"))
|
||||
layerParams.set("share_location", getLayerAttr(layer, "share_location").b());
|
||||
if (hasLayerAttr(layer, "background_label_id"))
|
||||
layerParams.set("background_label_id", getLayerAttr(layer, "background_label_id").i());
|
||||
if (hasLayerAttr(layer, "nms_threshold"))
|
||||
layerParams.set("nms_threshold", getLayerAttr(layer, "nms_threshold").f());
|
||||
if (hasLayerAttr(layer, "top_k"))
|
||||
layerParams.set("top_k", getLayerAttr(layer, "top_k").i());
|
||||
if (hasLayerAttr(layer, "code_type"))
|
||||
layerParams.set("code_type", getLayerAttr(layer, "code_type").s());
|
||||
if (hasLayerAttr(layer, "keep_top_k"))
|
||||
layerParams.set("keep_top_k", getLayerAttr(layer, "keep_top_k").i());
|
||||
if (hasLayerAttr(layer, "confidence_threshold"))
|
||||
layerParams.set("confidence_threshold", getLayerAttr(layer, "confidence_threshold").f());
|
||||
if (hasLayerAttr(layer, "loc_pred_transposed"))
|
||||
layerParams.set("loc_pred_transposed", getLayerAttr(layer, "loc_pred_transposed").b());
|
||||
if (hasLayerAttr(layer, "clip"))
|
||||
layerParams.set("clip", getLayerAttr(layer, "clip").b());
|
||||
if (hasLayerAttr(layer, "variance_encoded_in_target"))
|
||||
layerParams.set("variance_encoded_in_target", getLayerAttr(layer, "variance_encoded_in_target").b());
|
||||
|
||||
int id = dstNet.addLayer(name, "DetectionOutput", layerParams);
|
||||
layer_id[name] = id;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
connect(layer_id, dstNet, parsePin(layer.input(i)), id, i);
|
||||
data_layouts[name] = DATA_LAYOUT_UNKNOWN;
|
||||
}
|
||||
else if (type == "Softmax")
|
||||
{
|
||||
if (hasLayerAttr(layer, "axis"))
|
||||
|
||||
@@ -323,7 +323,7 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
|
||||
TEST_P(Test_TensorFlow_nets, Inception_v2_Faster_RCNN)
|
||||
{
|
||||
checkBackend();
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE ||
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user