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.
5 // Copyright (C) 2017-2019, Intel Corporation, all rights reserved.
6 // Third party copyrights are property of their respective owners.
9 Test for Tensorflow models loading
12 #include "test_precomp.hpp"
13 #include "npy_blob.hpp"
15 #include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
21 using namespace cv::dnn;
23 template<typename TString>
24 static std::string _tf(TString filename)
26 return (getOpenCVExtraDir() + "/dnn/") + filename;
29 TEST(Test_TensorFlow, read_inception)
33 const string model = findDataFile("dnn/tensorflow_inception_graph.pb", false);
34 net = readNetFromTensorflow(model);
35 ASSERT_FALSE(net.empty());
37 net.setPreferableBackend(DNN_BACKEND_OPENCV);
39 Mat sample = imread(_tf("grace_hopper_227.png"));
40 ASSERT_TRUE(!sample.empty());
42 resize(sample, input, Size(224, 224));
43 input -= Scalar::all(117); // mean sub
45 Mat inputBlob = blobFromImage(input);
47 net.setInput(inputBlob, "input");
48 Mat out = net.forward("softmax2");
50 std::cout << out.dims << std::endl;
53 TEST(Test_TensorFlow, inception_accuracy)
57 const string model = findDataFile("dnn/tensorflow_inception_graph.pb", false);
58 net = readNetFromTensorflow(model);
59 ASSERT_FALSE(net.empty());
61 net.setPreferableBackend(DNN_BACKEND_OPENCV);
63 Mat sample = imread(_tf("grace_hopper_227.png"));
64 ASSERT_TRUE(!sample.empty());
65 Mat inputBlob = blobFromImage(sample, 1.0, Size(224, 224), Scalar(), /*swapRB*/true);
67 net.setInput(inputBlob, "input");
68 Mat out = net.forward("softmax2");
70 Mat ref = blobFromNPY(_tf("tf_inception_prob.npy"));
75 static std::string path(const std::string& file)
77 return findDataFile("dnn/tensorflow/" + file);
80 class Test_TensorFlow_layers : public DNNTestLayer
83 void runTensorFlowNet(const std::string& prefix, bool hasText = false,
84 double l1 = 0.0, double lInf = 0.0, bool memoryLoad = false)
86 std::string netPath = path(prefix + "_net.pb");
87 std::string netConfig = (hasText ? path(prefix + "_net.pbtxt") : "");
88 std::string inpPath = path(prefix + "_in.npy");
89 std::string outPath = path(prefix + "_out.npy");
91 cv::Mat input = blobFromNPY(inpPath);
92 cv::Mat ref = blobFromNPY(outPath);
93 checkBackend(&input, &ref);
98 // Load files into a memory buffers
99 std::vector<char> dataModel;
100 readFileContent(netPath, dataModel);
102 std::vector<char> dataConfig;
105 readFileContent(netConfig, dataConfig);
108 net = readNetFromTensorflow(dataModel.data(), dataModel.size(),
109 dataConfig.data(), dataConfig.size());
112 net = readNetFromTensorflow(netPath, netConfig);
114 ASSERT_FALSE(net.empty());
116 net.setPreferableBackend(backend);
117 net.setPreferableTarget(target);
119 cv::Mat output = net.forward();
120 normAssert(ref, output, "", l1 ? l1 : default_l1, lInf ? lInf : default_lInf);
124 TEST_P(Test_TensorFlow_layers, conv)
126 runTensorFlowNet("single_conv");
127 runTensorFlowNet("atrous_conv2d_valid");
128 runTensorFlowNet("atrous_conv2d_same");
129 runTensorFlowNet("depthwise_conv2d");
130 runTensorFlowNet("keras_atrous_conv2d_same");
131 runTensorFlowNet("conv_pool_nchw");
134 TEST_P(Test_TensorFlow_layers, Convolution3D)
136 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
137 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_VERSION);
139 if (backend == DNN_BACKEND_CUDA)
143 else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
144 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); // Only CPU on DLIE backend is supported
145 else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
146 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // Only CPU on DLIE backend is supported
147 else if (target != DNN_TARGET_CPU)
148 throw SkipTestException("Only CPU is supported");
150 runTensorFlowNet("conv3d");
153 TEST_P(Test_TensorFlow_layers, padding)
155 runTensorFlowNet("padding_valid");
156 runTensorFlowNet("spatial_padding");
157 runTensorFlowNet("mirror_pad");
158 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019020000)
159 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
161 if (target == DNN_TARGET_MYRIAD)
162 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
163 if (target == DNN_TARGET_OPENCL_FP16)
164 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
167 runTensorFlowNet("keras_pad_concat");
170 TEST_P(Test_TensorFlow_layers, padding_same)
172 // Reference output values are in range [0.0006, 2.798]
173 runTensorFlowNet("padding_same");
176 TEST_P(Test_TensorFlow_layers, eltwise)
178 runTensorFlowNet("eltwise_add_mul");
179 runTensorFlowNet("eltwise_sub");
182 TEST_P(Test_TensorFlow_layers, pad_and_concat)
184 runTensorFlowNet("pad_and_concat");
187 TEST_P(Test_TensorFlow_layers, concat_axis_1)
189 runTensorFlowNet("concat_axis_1");
192 TEST_P(Test_TensorFlow_layers, batch_norm)
194 runTensorFlowNet("batch_norm");
195 runTensorFlowNet("batch_norm", false, 0.0, 0.0, true);
196 runTensorFlowNet("fused_batch_norm");
197 runTensorFlowNet("fused_batch_norm", false, 0.0, 0.0, true);
198 runTensorFlowNet("batch_norm_text", true);
199 runTensorFlowNet("batch_norm_text", true, 0.0, 0.0, true);
200 runTensorFlowNet("unfused_batch_norm");
201 runTensorFlowNet("fused_batch_norm_no_gamma");
202 runTensorFlowNet("unfused_batch_norm_no_gamma");
203 runTensorFlowNet("mvn_batch_norm");
204 runTensorFlowNet("mvn_batch_norm_1x1");
205 runTensorFlowNet("switch_identity");
206 runTensorFlowNet("keras_batch_norm_training");
209 TEST_P(Test_TensorFlow_layers, batch_norm3D)
211 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
213 if (target == DNN_TARGET_OPENCL_FP16) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
214 if (target == DNN_TARGET_OPENCL) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
215 if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
216 throw SkipTestException("");
218 runTensorFlowNet("batch_norm3d");
221 TEST_P(Test_TensorFlow_layers, slim_batch_norm)
223 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
224 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
225 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
226 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
227 // Output values range: [-40.0597, 207.827]
228 double l1 = default_l1, lInf = default_lInf;
229 if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
234 else if (target == DNN_TARGET_CUDA_FP16)
239 runTensorFlowNet("slim_batch_norm", false, l1, lInf);
242 TEST_P(Test_TensorFlow_layers, pooling)
244 runTensorFlowNet("max_pool_even");
245 runTensorFlowNet("max_pool_odd_valid");
246 runTensorFlowNet("max_pool_odd_same");
247 runTensorFlowNet("reduce_mean"); // an average pooling over all spatial dimensions.
250 TEST_P(Test_TensorFlow_layers, max_pool_grad)
252 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
253 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
254 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
255 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
256 runTensorFlowNet("max_pool_grad");
259 // TODO: fix tests and replace to pooling
260 TEST_P(Test_TensorFlow_layers, ave_pool_same)
262 // Reference output values are in range [-0.519531, 0.112976]
263 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
264 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
265 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
267 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
269 runTensorFlowNet("ave_pool_same");
272 TEST_P(Test_TensorFlow_layers, MaxPooling3D)
274 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
275 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_VERSION);
277 if (backend == DNN_BACKEND_CUDA)
281 else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
282 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); // Only CPU on DLIE backend is supported
283 else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
284 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // Only CPU on DLIE backend is supported
285 else if (target != DNN_TARGET_CPU)
286 throw SkipTestException("Only CPU is supported");
288 runTensorFlowNet("max_pool3d");
291 TEST_P(Test_TensorFlow_layers, AvePooling3D)
293 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
294 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_VERSION);
296 if (backend == DNN_BACKEND_CUDA)
300 else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
301 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); // Only CPU on DLIE backend is supported
302 else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
303 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // Only CPU on DLIE backend is supported
304 else if (target != DNN_TARGET_CPU)
305 throw SkipTestException("Only CPU is supported");
307 runTensorFlowNet("ave_pool3d");
310 TEST_P(Test_TensorFlow_layers, deconvolution)
312 if (backend == DNN_BACKEND_CUDA)
313 applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA);
314 runTensorFlowNet("deconvolution");
315 runTensorFlowNet("deconvolution_same");
316 runTensorFlowNet("deconvolution_stride_2_same");
317 runTensorFlowNet("deconvolution_adj_pad_valid");
318 runTensorFlowNet("deconvolution_adj_pad_same");
319 runTensorFlowNet("keras_deconv_valid");
320 runTensorFlowNet("keras_deconv_same");
321 runTensorFlowNet("keras_deconv_same_v2");
324 TEST_P(Test_TensorFlow_layers, matmul)
326 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
327 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
328 runTensorFlowNet("matmul");
329 runTensorFlowNet("nhwc_transpose_reshape_matmul");
330 // Reference output values are in range [-5.688, 4.484]
331 double l1 = target == DNN_TARGET_MYRIAD ? 6.1e-3 : default_l1;
332 runTensorFlowNet("nhwc_reshape_matmul", false, l1);
333 runTensorFlowNet("matmul_layout");
336 TEST_P(Test_TensorFlow_layers, reshape)
338 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
339 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
340 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
341 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
342 runTensorFlowNet("shift_reshape_no_reorder");
343 runTensorFlowNet("reshape_no_reorder");
344 runTensorFlowNet("reshape_reduce");
345 runTensorFlowNet("reshape_as_shape");
348 TEST_P(Test_TensorFlow_layers, flatten)
350 #if defined(INF_ENGINE_RELEASE)
351 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
352 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
354 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
357 runTensorFlowNet("flatten", true);
360 TEST_P(Test_TensorFlow_layers, unfused_flatten)
362 runTensorFlowNet("unfused_flatten");
363 runTensorFlowNet("unfused_flatten_unknown_batch");
366 TEST_P(Test_TensorFlow_layers, leaky_relu)
368 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
369 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
370 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
372 runTensorFlowNet("leaky_relu_order1");
373 runTensorFlowNet("leaky_relu_order2");
374 runTensorFlowNet("leaky_relu_order3");
377 TEST_P(Test_TensorFlow_layers, l2_normalize)
379 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
380 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
381 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
383 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
386 runTensorFlowNet("l2_normalize");
389 // TODO: fix it and add to l2_normalize
390 TEST_P(Test_TensorFlow_layers, l2_normalize_3d)
392 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
393 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019
394 && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)
396 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
397 CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
399 #if defined(INF_ENGINE_RELEASE)
400 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
401 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
404 runTensorFlowNet("l2_normalize_3d");
407 class Test_TensorFlow_nets : public DNNTestLayer {};
409 TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
411 #if defined(INF_ENGINE_RELEASE)
412 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
414 #if INF_ENGINE_VER_MAJOR_GE(2019020000)
415 if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
416 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
422 std::string imgPath = findDataFile("dnn/street.png");
423 std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt");
424 std::string netPath = findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false);
427 resize(imread(imgPath), inp, Size(300, 300));
428 inp = blobFromImage(inp, 1.0f / 127.5, Size(), Scalar(127.5, 127.5, 127.5), true);
430 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco.detection_out.npy"));
432 Net net = readNetFromTensorflow(netPath, netConfig);
433 net.setPreferableBackend(backend);
434 net.setPreferableTarget(target);
437 Mat out = net.forward();
439 double scoreDiff = default_l1, iouDiff = default_lInf;
440 if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
445 else if (target == DNN_TARGET_CUDA_FP16)
449 normAssertDetections(ref, out, "", 0.2, scoreDiff, iouDiff);
450 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2019010000
451 expectNoFallbacksFromIE(net);
455 TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
457 applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
458 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000)
459 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD &&
460 getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
461 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
465 Mat img = imread(findDataFile("dnn/street.png"));
466 std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt");
467 std::string model = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pb", false);
469 Net net = readNetFromTensorflow(model, proto);
470 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
472 net.setPreferableBackend(backend);
473 net.setPreferableTarget(target);
476 // Output has shape 1x1xNx7 where N - number of detections.
477 // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
478 Mat out = net.forward();
479 Mat ref = (Mat_<float>(5, 7) << 0, 1, 0.90176028, 0.19872092, 0.36311883, 0.26461923, 0.63498729,
480 0, 3, 0.93569964, 0.64865261, 0.45906419, 0.80675775, 0.65708131,
481 0, 3, 0.75838411, 0.44668293, 0.45907149, 0.49459291, 0.52197015,
482 0, 10, 0.95932811, 0.38349164, 0.32528657, 0.40387636, 0.39165527,
483 0, 10, 0.93973452, 0.66561931, 0.37841269, 0.68074018, 0.42907384);
485 double scoreDiff = default_l1, iouDiff = default_lInf;
486 if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
491 else if (target == DNN_TARGET_CUDA_FP16)
496 normAssertDetections(ref, out, "", 0.5, scoreDiff, iouDiff);
497 expectNoFallbacksFromIE(net);
500 TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD)
503 std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt");
504 std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false);
506 Net net = readNetFromTensorflow(model, proto);
507 Mat img = imread(findDataFile("dnn/dog416.png"));
508 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
510 net.setPreferableBackend(backend);
511 net.setPreferableTarget(target);
514 Mat out = net.forward();
516 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco_2017_11_17.detection_out.npy"));
517 float scoreDiff = 1.5e-5, iouDiff = 1e-3;
518 float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.35 : 0.3;
519 if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
524 else if (target == DNN_TARGET_CUDA_FP16)
529 #if defined(INF_ENGINE_RELEASE)
530 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD &&
531 getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
535 detectionConfThresh = 0.36;
538 normAssertDetections(ref, out, "", detectionConfThresh, scoreDiff, iouDiff);
539 expectNoFallbacksFromIE(net);
542 TEST_P(Test_TensorFlow_nets, Faster_RCNN)
546 (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
548 CV_TEST_TAG_DEBUG_VERYLONG
550 static std::string names[] = {"faster_rcnn_inception_v2_coco_2018_01_28",
551 "faster_rcnn_resnet50_coco_2018_01_28"};
553 #ifdef INF_ENGINE_RELEASE
554 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 &&
555 (INF_ENGINE_VER_MAJOR_LT(2019020000) || target != DNN_TARGET_CPU))
556 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
558 // segfault: inference-engine/thirdparty/clDNN/src/gpu/detection_output_cpu.cpp:111:
559 // Assertion `prior_height > 0' failed.
560 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
561 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
563 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
564 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
566 if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
567 applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
571 double scoresDiff = backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ? 2.9e-5 : 1e-5;
572 for (int i = 0; i < 2; ++i)
574 std::string proto = findDataFile("dnn/" + names[i] + ".pbtxt");
575 std::string model = findDataFile("dnn/" + names[i] + ".pb", false);
577 Net net = readNetFromTensorflow(model, proto);
578 net.setPreferableBackend(backend);
579 net.setPreferableTarget(target);
580 Mat img = imread(findDataFile("dnn/dog416.png"));
581 Mat blob = blobFromImage(img, 1.0f, Size(800, 600), Scalar(), true, false);
584 Mat out = net.forward();
586 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/" + names[i] + ".detection_out.npy"));
587 normAssertDetections(ref, out, names[i].c_str(), 0.3, scoresDiff);
591 TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
593 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
594 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
595 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
596 CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
599 std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt");
600 std::string model = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pb", false);
602 Net net = readNetFromTensorflow(model, proto);
603 Mat img = imread(findDataFile("dnn/dog416.png"));
604 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_ppn_coco.detection_out.npy"));
605 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
607 net.setPreferableBackend(backend);
608 net.setPreferableTarget(target);
611 Mat out = net.forward();
613 double scoreDiff = 1.1e-5, iouDiff = default_lInf;
614 if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
619 else if (target == DNN_TARGET_CUDA_FP16)
624 normAssertDetections(ref, out, "", 0.45, scoreDiff, iouDiff);
625 expectNoFallbacksFromIE(net);
628 TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
631 std::string proto = findDataFile("dnn/opencv_face_detector.pbtxt");
632 std::string model = findDataFile("dnn/opencv_face_detector_uint8.pb", false);
634 Net net = readNetFromTensorflow(model, proto);
635 Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
636 Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
638 net.setPreferableBackend(backend);
639 net.setPreferableTarget(target);
641 // Output has shape 1x1xNx7 where N - number of detections.
642 // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
643 Mat out = net.forward();
645 // References are from test for Caffe model.
646 Mat ref = (Mat_<float>(6, 7) << 0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631,
647 0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168,
648 0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290,
649 0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477,
650 0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494,
651 0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801);
652 double scoreDiff = 3.4e-3, iouDiff = 1e-2;
653 if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
658 else if (target == DNN_TARGET_CUDA_FP16)
663 normAssertDetections(ref, out, "", 0.9, scoreDiff, iouDiff);
664 expectNoFallbacksFromIE(net);
667 // inp = cv.imread('opencv_extra/testdata/cv/ximgproc/sources/08.png')
668 // inp = inp[:,:,[2, 1, 0]].astype(np.float32).reshape(1, 512, 512, 3)
669 // outs = sess.run([sess.graph.get_tensor_by_name('feature_fusion/Conv_7/Sigmoid:0'),
670 // sess.graph.get_tensor_by_name('feature_fusion/concat_3:0')],
671 // feed_dict={'input_images:0': inp})
672 // scores = np.ascontiguousarray(outs[0].transpose(0, 3, 1, 2))
673 // geometry = np.ascontiguousarray(outs[1].transpose(0, 3, 1, 2))
674 // np.save('east_text_detection.scores.npy', scores)
675 // np.save('east_text_detection.geometry.npy', geometry)
676 TEST_P(Test_TensorFlow_nets, EAST_text_detection)
679 (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB),
680 CV_TEST_TAG_DEBUG_LONG
683 #if defined(INF_ENGINE_RELEASE)
684 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
685 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
687 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL_FP16 &&
688 INF_ENGINE_VER_MAJOR_EQ(2019020000))
689 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
694 std::string netPath = findDataFile("dnn/frozen_east_text_detection.pb", false);
695 std::string imgPath = findDataFile("cv/ximgproc/sources/08.png");
696 std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy");
697 std::string refGeometryPath = findDataFile("dnn/east_text_detection.geometry.npy");
699 Net net = readNet(netPath);
701 net.setPreferableBackend(backend);
702 net.setPreferableTarget(target);
704 Mat img = imread(imgPath);
705 Mat inp = blobFromImage(img, 1.0, Size(), Scalar(123.68, 116.78, 103.94), true, false);
708 std::vector<Mat> outs;
709 std::vector<String> outNames(2);
710 outNames[0] = "feature_fusion/Conv_7/Sigmoid";
711 outNames[1] = "feature_fusion/concat_3";
712 net.forward(outs, outNames);
714 Mat scores = outs[0];
715 Mat geometry = outs[1];
717 // Scores are in range [0, 1]. Geometry values are in range [-0.23, 290]
718 double l1_scores = default_l1, lInf_scores = default_lInf;
719 double l1_geometry = default_l1, lInf_geometry = default_lInf;
720 if (target == DNN_TARGET_OPENCL_FP16)
722 lInf_scores = backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ? 0.16 : 0.11;
723 l1_geometry = 0.28; lInf_geometry = 5.94;
725 else if (target == DNN_TARGET_MYRIAD)
728 l1_geometry = 0.28; lInf_geometry = 5.94;
730 else if (target == DNN_TARGET_CUDA_FP16)
733 l1_geometry = 0.3; lInf_geometry = 7;
737 l1_geometry = 1e-4, lInf_geometry = 3e-3;
739 normAssert(scores, blobFromNPY(refScoresPath), "scores", l1_scores, lInf_scores);
740 normAssert(geometry, blobFromNPY(refGeometryPath), "geometry", l1_geometry, lInf_geometry);
741 expectNoFallbacksFromIE(net);
744 INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, dnnBackendsAndTargets());
746 TEST_P(Test_TensorFlow_layers, fp16_weights)
750 runTensorFlowNet("fp16_single_conv", false, l1, lInf);
751 runTensorFlowNet("fp16_max_pool_odd_same", false, l1, lInf);
752 runTensorFlowNet("fp16_eltwise_add_mul", false, l1, lInf);
753 runTensorFlowNet("fp16_pad_and_concat", false, l1, lInf);
754 runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
755 // Reference output values are in range [0.0889, 1.651]
756 runTensorFlowNet("fp16_max_pool_even", false, (target == DNN_TARGET_MYRIAD) ? 0.003 : l1, lInf);
757 if (target == DNN_TARGET_MYRIAD)
762 // Reference output values are in range [0, 10.75]
763 runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
764 // Reference output values are in range [0.418, 2.297]
765 runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
768 TEST_P(Test_TensorFlow_layers, fp16_padding_same)
770 // Reference output values are in range [-3.504, -0.002]
771 runTensorFlowNet("fp16_padding_same", false, 7e-4, 4e-3);
774 TEST_P(Test_TensorFlow_layers, defun)
776 runTensorFlowNet("defun_dropout");
779 TEST_P(Test_TensorFlow_layers, quantized)
781 runTensorFlowNet("uint8_single_conv");
784 TEST_P(Test_TensorFlow_layers, lstm)
786 if(backend == DNN_BACKEND_CUDA)
787 applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA); /* not supported */
788 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
789 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
790 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
791 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
792 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
793 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
794 runTensorFlowNet("lstm", true);
795 runTensorFlowNet("lstm", true, 0.0, 0.0, true);
798 TEST_P(Test_TensorFlow_layers, split)
800 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
801 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
802 runTensorFlowNet("split");
805 TEST_P(Test_TensorFlow_layers, split_equals)
807 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
808 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
809 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
810 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
811 runTensorFlowNet("split_equals");
814 TEST_P(Test_TensorFlow_layers, resize_nearest_neighbor)
816 runTensorFlowNet("resize_nearest_neighbor");
817 runTensorFlowNet("keras_upsampling2d");
820 TEST_P(Test_TensorFlow_layers, slice)
822 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 &&
823 (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
824 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
825 CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
826 runTensorFlowNet("slice_4d");
827 runTensorFlowNet("strided_slice");
830 TEST_P(Test_TensorFlow_layers, softmax)
832 runTensorFlowNet("keras_softmax");
833 runTensorFlowNet("slim_softmax");
836 TEST_P(Test_TensorFlow_layers, slim_softmax_v2)
838 #if defined(INF_ENGINE_RELEASE)
839 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD &&
840 getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
842 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
844 runTensorFlowNet("slim_softmax_v2");
847 TEST_P(Test_TensorFlow_layers, relu6)
849 runTensorFlowNet("keras_relu6");
850 runTensorFlowNet("keras_relu6", /*hasText*/ true);
853 TEST_P(Test_TensorFlow_layers, subpixel)
855 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
856 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
857 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
858 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
859 runTensorFlowNet("subpixel");
862 TEST_P(Test_TensorFlow_layers, keras_mobilenet_head)
864 runTensorFlowNet("keras_mobilenet_head");
865 runTensorFlowNet("keras_learning_phase");
868 TEST_P(Test_TensorFlow_layers, resize_bilinear)
870 runTensorFlowNet("resize_bilinear");
871 runTensorFlowNet("resize_bilinear_factor");
874 TEST_P(Test_TensorFlow_layers, squeeze)
876 #if defined(INF_ENGINE_RELEASE)
877 if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
878 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
880 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
882 int inpShapes[][4] = {{1, 3, 4, 2}, {1, 3, 1, 2}, {1, 3, 4, 1}, {1, 3, 4, 1}}; // TensorFlow's shape (NHWC)
883 int outShapes[][3] = {{3, 4, 2}, {1, 3, 2}, {1, 3, 4}, {1, 3, 4}};
884 int squeeze_dims[] = {0, 2, 3, -1};
885 for (int i = 0; i < 4; ++i)
887 SCOPED_TRACE(format("i=%d", i));
889 "node { name: \"input\" op: \"Placeholder\""
890 "attr { key: \"data_format\" value { s: \"NHWC\" } } }"
891 "node { name: \"squeeze\" op: \"Squeeze\" input: \"input\""
892 "attr { key: \"squeeze_dims\" value { list { i:" + format("%d", squeeze_dims[i]) + "}}}}";
893 Net net = readNetFromTensorflow(0, 0, pbtxt.c_str(), pbtxt.size());
894 net.setPreferableBackend(backend);
895 net.setPreferableTarget(target);
896 Mat tfInp(4, &inpShapes[i][0], CV_32F);
900 CV_Assert(inpShapes[i][0] == 1);
901 std::swap(inpShapes[i][2], inpShapes[i][3]);
902 std::swap(inpShapes[i][1], inpShapes[i][2]);
903 Mat cvInp = tfInp.reshape(1, tfInp.total() / inpShapes[i][1]).t();
904 cvInp = cvInp.reshape(1, 4, &inpShapes[i][0]);
907 Mat out = net.forward();
908 normAssert(tfInp.reshape(1, 3, &outShapes[i][0]), out, "", default_l1, default_lInf);
912 INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_layers, dnnBackendsAndTargets());
914 TEST(Test_TensorFlow, two_inputs)
916 Net net = readNet(path("two_inputs_net.pbtxt"));
917 net.setPreferableBackend(DNN_BACKEND_OPENCV);
919 Mat firstInput(2, 3, CV_32FC1), secondInput(2, 3, CV_32FC1);
920 randu(firstInput, -1, 1);
921 randu(secondInput, -1, 1);
923 net.setInput(firstInput, "first_input");
924 net.setInput(secondInput, "second_input");
925 Mat out = net.forward();
927 normAssert(out, firstInput + secondInput);
930 TEST(Test_TensorFlow, Mask_RCNN)
932 applyTestTag(CV_TEST_TAG_MEMORY_1GB, CV_TEST_TAG_DEBUG_VERYLONG);
933 Mat img = imread(findDataFile("dnn/street.png"));
934 std::string proto = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt");
935 std::string model = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pb", false);
937 Net net = readNetFromTensorflow(model, proto);
938 Mat refDetections = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_out.npy"));
939 Mat refMasks = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_masks.npy"));
940 Mat blob = blobFromImage(img, 1.0f, Size(800, 800), Scalar(), true, false);
942 net.setPreferableBackend(DNN_BACKEND_OPENCV);
946 // Mask-RCNN predicts bounding boxes and segmentation masks.
947 std::vector<String> outNames(2);
948 outNames[0] = "detection_out_final";
949 outNames[1] = "detection_masks";
951 std::vector<Mat> outs;
952 net.forward(outs, outNames);
954 Mat outDetections = outs[0];
955 Mat outMasks = outs[1];
956 normAssertDetections(refDetections, outDetections, "", /*threshold for zero confidence*/1e-5);
958 // Output size of masks is NxCxHxW where
959 // N - number of detected boxes
960 // C - number of classes (excluding background)
961 // HxW - segmentation shape
962 const int numDetections = outDetections.size[2];
964 int masksSize[] = {1, numDetections, outMasks.size[2], outMasks.size[3]};
965 Mat masks(4, &masksSize[0], CV_32F);
967 std::vector<cv::Range> srcRanges(4, cv::Range::all());
968 std::vector<cv::Range> dstRanges(4, cv::Range::all());
970 outDetections = outDetections.reshape(1, outDetections.total() / 7);
971 for (int i = 0; i < numDetections; ++i)
973 // Get a class id for this bounding box and copy mask only for that class.
974 int classId = static_cast<int>(outDetections.at<float>(i, 1));
975 srcRanges[0] = dstRanges[1] = cv::Range(i, i + 1);
976 srcRanges[1] = cv::Range(classId, classId + 1);
977 outMasks(srcRanges).copyTo(masks(dstRanges));
979 cv::Range topRefMasks[] = {Range::all(), Range(0, numDetections), Range::all(), Range::all()};
980 normAssert(masks, refMasks(&topRefMasks[0]));