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.
8 // This tests doesn't require any external data. They just compare outputs of
9 // layers using different computation backends. Input and parameters are random.
11 #include "test_precomp.hpp"
13 namespace opencv_test { namespace {
16 using namespace cv::dnn;
17 using namespace testing;
19 static void test(Mat& input, Net& net, Backend backendId, Target targetId, bool skipCheck = false)
21 DNNTestLayer::checkBackend(backendId, targetId);
22 randu(input, -1.0f, 1.0f);
25 net.setPreferableBackend(DNN_BACKEND_OPENCV);
26 Mat outputDefault = net.forward().clone();
28 net.setPreferableBackend(backendId);
29 net.setPreferableTarget(targetId);
30 Mat outputHalide = net.forward().clone();
36 DNNTestLayer::getDefaultThresholds(backendId, targetId, &l1, &lInf);
37 normAssert(outputDefault, outputHalide, "", l1, lInf);
40 static void test(LayerParams& params, Mat& input, Backend backendId, Target targetId, bool skipCheck = false)
43 net.addLayerToPrev(params.name, params.type, params);
44 test(input, net, backendId, targetId, skipCheck);
47 static inline testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargetsWithHalide()
49 return dnnBackendsAndTargets(true, true, false); // OpenCV/CPU is used as reference
52 class Test_Halide_layers : public DNNTestLayer {};
54 ////////////////////////////////////////////////////////////////////////////////
56 ////////////////////////////////////////////////////////////////////////////////
57 TEST_P(Test_Halide_layers, Padding)
59 static const int kNumRuns = 10;
60 std::vector<int> paddings(8);
61 cv::RNG& rng = cv::theRNG();
62 for (int t = 0; t < kNumRuns; ++t)
64 for (int i = 0; i < paddings.size(); ++i)
68 lp.set("paddings", DictValue::arrayInt<int*>(&paddings[0], paddings.size()));
70 lp.name = "testLayer";
72 int sz[] = {1 + (int)rng(10), 1 + (int)rng(10), 1 + (int)rng(10), 1 + (int)rng(10)};
73 Mat input(4, &sz[0], CV_32F);
74 test(lp, input, backend, target);
78 ////////////////////////////////////////////////////////////////////////////////
80 ////////////////////////////////////////////////////////////////////////////////
81 typedef TestWithParam<tuple<Vec3i, Size, Size, Size, Size, Size, bool, tuple<Backend, Target> > > Convolution;
82 TEST_P(Convolution, Accuracy)
84 int inChannels = get<0>(GetParam())[0];
85 int outChannels = get<0>(GetParam())[1];
86 int group = get<0>(GetParam())[2];
87 Size inSize = get<1>(GetParam());
88 Size kernel = get<2>(GetParam());
89 Size stride = get<3>(GetParam());
90 Size pad = get<4>(GetParam());
91 Size dilation = get<5>(GetParam());
92 bool hasBias = get<6>(GetParam());
93 Backend backendId = get<0>(get<7>(GetParam()));
94 Target targetId = get<1>(get<7>(GetParam()));
96 bool skipCheck = false;
98 int sz[] = {outChannels, inChannels / group, kernel.height, kernel.width};
99 Mat weights(4, &sz[0], CV_32F);
100 randu(weights, -1.0f, 1.0f);
103 lp.set("kernel_w", kernel.width);
104 lp.set("kernel_h", kernel.height);
105 lp.set("pad_w", pad.width);
106 lp.set("pad_h", pad.height);
107 lp.set("stride_w", stride.width);
108 lp.set("stride_h", stride.height);
109 lp.set("dilation_w", dilation.width);
110 lp.set("dilation_h", dilation.height);
111 lp.set("num_output", outChannels);
112 lp.set("group", group);
113 lp.set("bias_term", hasBias);
114 lp.type = "Convolution";
115 lp.name = "testLayer";
116 lp.blobs.push_back(weights);
119 Mat bias(1, outChannels, CV_32F);
120 randu(bias, -1.0f, 1.0f);
121 lp.blobs.push_back(bias);
123 int inpSz[] = {1, inChannels, inSize.height, inSize.width};
124 Mat input(4, &inpSz[0], CV_32F);
125 test(lp, input, backendId, targetId, skipCheck);
127 throw SkipTestException("Skip checks in unstable test");
130 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Convolution, Combine(
131 /*in channels, out channels, group*/
132 Values(Vec3i(6, 4, 1), Vec3i(6, 9, 1),
133 Vec3i(6, 4, 2), Vec3i(6, 9, 3)),
134 /*in size*/ Values(Size(5, 6)),
135 /*kernel*/ Values(Size(3, 1), Size(1, 3)),
136 /*stride*/ Values(Size(1, 1), Size(2, 2)),
137 /*pad*/ Values(Size(1, 0), Size(0, 1)),
138 /*dilation*/ Values(Size(1, 1), Size(2, 2)),
140 dnnBackendsAndTargetsWithHalide()
143 ////////////////////////////////////////////////////////////////////////////////
145 ////////////////////////////////////////////////////////////////////////////////
146 typedef TestWithParam<tuple<Vec3i, Size, Size, Size, Size, Vec4i, bool, tuple<Backend, Target> > > Deconvolution;
147 TEST_P(Deconvolution, Accuracy)
149 int inChannels = get<0>(GetParam())[0];
150 int outChannels = get<0>(GetParam())[1];
151 int group = get<0>(GetParam())[2];
152 Size inSize = get<1>(GetParam());
153 Size kernel = get<2>(GetParam());
154 Size pad = get<3>(GetParam());
155 Size dilation = get<4>(GetParam());
156 Size stride = Size(get<5>(GetParam())[0], get<5>(GetParam())[1]);
157 Size adjPad = Size(get<5>(GetParam())[2], get<5>(GetParam())[3]);
158 bool hasBias = get<6>(GetParam());
159 Backend backendId = get<0>(get<7>(GetParam()));
160 Target targetId = get<1>(get<7>(GetParam()));
162 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
163 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
164 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
165 && inChannels == 6 && outChannels == 4 && group == 1
166 && kernel == Size(1, 3) && pad == Size(1, 0)
167 && stride == Size(1, 1) && dilation == Size(1, 1))
168 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
171 int sz[] = {inChannels, outChannels / group, kernel.height, kernel.width};
172 Mat weights(4, &sz[0], CV_32F);
173 randu(weights, -1.0f, 1.0f);
176 lp.set("kernel_w", kernel.width);
177 lp.set("kernel_h", kernel.height);
178 lp.set("pad_w", pad.width);
179 lp.set("pad_h", pad.height);
180 lp.set("stride_w", stride.width);
181 lp.set("stride_h", stride.height);
182 lp.set("dilation_w", dilation.width);
183 lp.set("dilation_h", dilation.height);
184 lp.set("adj_w", adjPad.width);
185 lp.set("adj_h", adjPad.height);
186 lp.set("num_output", outChannels);
187 lp.set("group", group);
188 lp.set("bias_term", hasBias);
189 lp.type = "Deconvolution";
190 lp.name = "testLayer";
191 lp.blobs.push_back(weights);
194 Mat bias(1, outChannels, CV_32F);
195 randu(bias, -1.0f, 1.0f);
196 lp.blobs.push_back(bias);
198 int inpSz[] = {1, inChannels, inSize.height, inSize.width};
199 Mat input(4, &inpSz[0], CV_32F);
200 test(lp, input, backendId, targetId);
203 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Deconvolution, Combine(
204 /*in channels, out channels, group*/
205 Values(Vec3i(6, 4, 1), Vec3i(6, 9, 3)),
206 /*in size*/ Values(Size(5, 6)),
207 /*kernel*/ Values(Size(3, 1), Size(1, 3)),
208 /*pad*/ Values(Size(1, 0), Size(0, 1)),
209 /*dilation*/ Values(Size(1, 1)),
210 /*stride, adj. pad*/ Values(Vec4i(1,1, 0,0), Vec4i(2,2, 1,0), Vec4i(1,2, 0,1)),
212 dnnBackendsAndTargetsWithHalide()
215 ////////////////////////////////////////////////////////////////////////////////
217 ////////////////////////////////////////////////////////////////////////////////
218 typedef TestWithParam<tuple<Vec3i, int, Vec3f, bool, std::string, tuple<Backend, Target> > > LRN;
219 TEST_P(LRN, Accuracy)
221 int inChannels = get<0>(GetParam())[0];
222 Size inSize = Size(get<0>(GetParam())[1], get<0>(GetParam())[2]);
223 int localSize = get<1>(GetParam());
224 float alpha = get<2>(GetParam())[0];
225 float beta = get<2>(GetParam())[1];
226 float bias = get<2>(GetParam())[2];
227 bool normBySize = get<3>(GetParam());
228 std::string nrmType = get<4>(GetParam());
229 Backend backendId = get<0>(get<5>(GetParam()));
230 Target targetId = get<1>(get<5>(GetParam()));
232 if ((inSize.width == 5 || inSize.height == 5) && targetId == DNN_TARGET_MYRIAD &&
233 nrmType == "ACROSS_CHANNELS")
234 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
237 lp.set("norm_region", nrmType);
238 lp.set("local_size", localSize);
239 lp.set("alpha", alpha);
240 lp.set("beta", beta);
241 lp.set("bias", bias);
242 lp.set("norm_by_size", normBySize);
244 lp.name = "testLayer";
246 int sz[] = {1, inChannels, inSize.height, inSize.width};
247 Mat input(4, &sz[0], CV_32F);
248 test(lp, input, backendId, targetId);
251 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, LRN, Combine(
252 /*input ch,w,h*/ Values(Vec3i(6, 5, 8), Vec3i(7, 11, 6)),
253 /*local size*/ Values(3, 5),
254 Values(Vec3f(0.9f, 1.0f, 1.1f), Vec3f(0.9f, 1.1f, 1.0f),
255 /*alpha, beta, bias*/ Vec3f(1.0f, 0.9f, 1.1f), Vec3f(1.0f, 1.1f, 0.9f),
256 Vec3f(1.1f, 0.9f, 1.0f), Vec3f(1.1f, 1.0f, 0.9f)),
257 /*norm_by_size*/ Bool(),
258 /*norm_type*/ Values("ACROSS_CHANNELS", "WITHIN_CHANNEL"),
259 dnnBackendsAndTargetsWithHalide()
262 ////////////////////////////////////////////////////////////////////////////////
264 ////////////////////////////////////////////////////////////////////////////////
265 typedef TestWithParam<tuple<int, Size, Size, Size, tuple<Backend, Target> > > AvePooling;
266 TEST_P(AvePooling, Accuracy)
268 int inChannels = get<0>(GetParam());
269 Size outSize = get<1>(GetParam());; // Input size will be computed from parameters.
270 Size kernel = get<2>(GetParam());
271 Size stride = get<3>(GetParam());
272 Backend backendId = get<0>(get<4>(GetParam()));
273 Target targetId = get<1>(get<4>(GetParam()));
275 #if defined(INF_ENGINE_RELEASE)
276 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
277 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
278 && kernel == Size(1, 1) && (stride == Size(1, 1) || stride == Size(2, 2)))
279 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
282 const int inWidth = (outSize.width - 1) * stride.width + kernel.width;
283 const int inHeight = (outSize.height - 1) * stride.height + kernel.height;
286 lp.set("pool", "ave");
287 lp.set("kernel_w", kernel.width);
288 lp.set("kernel_h", kernel.height);
289 lp.set("stride_w", stride.width);
290 lp.set("stride_h", stride.height);
292 lp.name = "testLayer";
294 int sz[] = {1, inChannels, inHeight, inWidth};
295 Mat input(4, &sz[0], CV_32F);
296 test(lp, input, backendId, targetId);
299 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, AvePooling, Combine(
300 /*in channels*/ Values(3, 4),
301 /*out size*/ Values(Size(1, 1), Size(2, 2), Size(3, 2), Size(4, 7)),
302 /*kernel*/ Values(Size(1, 1), Size(2, 2), Size(3, 3), Size(3, 2)),
303 /*stride*/ Values(Size(1, 1), Size(2, 2), Size(3, 2)),
304 dnnBackendsAndTargetsWithHalide()
307 ////////////////////////////////////////////////////////////////////////////////
309 ////////////////////////////////////////////////////////////////////////////////
310 typedef TestWithParam<tuple<int, Size, Size, Size, Size, tuple<Backend, Target> > > MaxPooling;
311 TEST_P(MaxPooling, Accuracy)
313 int inChannels = get<0>(GetParam());
314 Size inSize = get<1>(GetParam());
315 Size kernel = get<2>(GetParam());
316 Size stride = get<3>(GetParam());
317 Size pad = get<4>(GetParam());
318 Backend backendId = get<0>(get<5>(GetParam()));
319 Target targetId = get<1>(get<5>(GetParam()));
321 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
322 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
323 && inSize == Size(7, 6) && kernel == Size(3, 2)
324 && (stride == Size(1, 1) || stride == Size(2, 2))
325 && (pad == Size(0, 1) || pad == Size(1, 1))
327 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_2018R5);
330 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
331 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
332 && (kernel == Size(2, 2) || kernel == Size(3, 2))
333 && stride == Size(1, 1) && (pad == Size(0, 0) || pad == Size(0, 1))
335 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_2018R5);
338 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
339 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
340 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
341 && (stride == Size(1, 1) || stride == Size(2, 2))
342 && (pad == Size(0, 1) || pad == Size(1, 1))
344 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_2019R1, CV_TEST_TAG_DNN_SKIP_IE_2019R1_1);
348 lp.set("pool", "max");
349 lp.set("kernel_w", kernel.width);
350 lp.set("kernel_h", kernel.height);
351 lp.set("stride_w", stride.width);
352 lp.set("stride_h", stride.height);
353 lp.set("pad_w", pad.width);
354 lp.set("pad_h", pad.height);
356 lp.name = "testLayer";
358 int sz[] = {1, inChannels, inSize.height, inSize.width};
359 Mat input(4, &sz[0], CV_32F);
360 test(lp, input, backendId, targetId);
363 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, MaxPooling, Combine(
364 /*in channels*/ Values(3, 4),
365 /*in size*/ Values(Size(5, 5), Size(7, 6)),
366 /*kernel*/ Values(Size(2, 2), Size(3, 3), Size(3, 2)),
367 /*stride*/ Values(Size(1, 1), Size(2, 2), Size(3, 2)),
368 /*pad*/ Values(Size(0, 0), Size(1, 1), Size(0, 1)),
369 dnnBackendsAndTargetsWithHalide()
372 ////////////////////////////////////////////////////////////////////////////////
374 ////////////////////////////////////////////////////////////////////////////////
375 typedef TestWithParam<tuple<int, Size, int, bool, tuple<Backend, Target> > > FullyConnected;
376 TEST_P(FullyConnected, Accuracy)
378 int inChannels = get<0>(GetParam());
379 Size inSize = get<1>(GetParam());
380 int outChannels = get<2>(GetParam());
381 bool hasBias = get<3>(GetParam());
382 Backend backendId = get<0>(get<4>(GetParam()));
383 Target targetId = get<1>(get<4>(GetParam()));
384 if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
385 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
387 Mat weights(outChannels, inChannels * inSize.height * inSize.width, CV_32F);
388 randu(weights, -1.0f, 1.0f);
390 Mat bias(1, outChannels, CV_32F);
391 randu(bias, -1.0f, 1.0f);
394 lp.set("num_output", outChannels);
395 lp.set("bias_term", hasBias);
396 lp.blobs.push_back(weights);
397 lp.blobs.push_back(bias);
398 lp.type = "InnerProduct";
399 lp.name = "testLayer";
401 int sz[] = {1, inChannels, inSize.height, inSize.width};
402 Mat input(4, &sz[0], CV_32F);
403 test(lp, input, backendId, targetId);
406 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, FullyConnected, Combine(
407 /*in channels*/ Values(3, 4),
408 /*in size*/ Values(Size(5, 4), Size(4, 5), Size(1, 1)),
409 /*out channels*/ Values(3, 4),
411 dnnBackendsAndTargetsWithHalide()
414 ////////////////////////////////////////////////////////////////////////////////
416 ////////////////////////////////////////////////////////////////////////////////
417 typedef TestWithParam<tuple<int, tuple<Backend, Target> > > SoftMax;
418 TEST_P(SoftMax, Accuracy)
420 int inChannels = get<0>(GetParam());
421 Backend backendId = get<0>(get<1>(GetParam()));
422 Target targetId = get<1>(get<1>(GetParam()));
425 lp.name = "testLayer";
427 int sz[] = {1, inChannels, 1, 1};
428 Mat input(4, &sz[0], CV_32F);
429 test(lp, input, backendId, targetId);
432 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, SoftMax, Combine(
433 Values(3, 4, 5, 1024),
434 dnnBackendsAndTargetsWithHalide()
437 //////////////////////////////////////////////////////////////////////////////
438 // Max pooling - unpooling
439 //////////////////////////////////////////////////////////////////////////////
440 TEST_P(Test_Halide_layers, MaxPoolUnpool)
442 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
443 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
446 pool.set("pool", "max");
447 pool.set("kernel_w", 2);
448 pool.set("kernel_h", 2);
449 pool.set("stride_w", 2);
450 pool.set("stride_h", 2);
451 pool.set("pad_w", 0);
452 pool.set("pad_h", 0);
453 pool.type = "Pooling";
454 pool.name = "testPool";
457 unpool.set("pool_k_w", 2);
458 unpool.set("pool_k_h", 2);
459 unpool.set("pool_stride_w", 2);
460 unpool.set("pool_stride_h", 2);
461 unpool.set("pool_pad_w", 0);
462 unpool.set("pool_pad_h", 0);
463 unpool.type = "MaxUnpool";
464 unpool.name = "testUnpool";
467 int poolId = net.addLayer(pool.name, pool.type, pool);
468 net.connect(0, 0, poolId, 0);
470 int unpoolId = net.addLayer(unpool.name, unpool.type, unpool);
471 net.connect(poolId, 0, unpoolId, 0);
472 net.connect(poolId, 1, unpoolId, 1);
474 int sz[] = {1, 1, 4, 4};
475 Mat input(4, &sz[0], CV_32F);
476 test(input, net, backend, target);
479 ////////////////////////////////////////////////////////////////////////////////
480 // AvePooling + in-place layers
481 ////////////////////////////////////////////////////////////////////////////////
482 static const int kNumChannels = 3;
484 void testInPlaceActivation(LayerParams& lp, Backend backendId, Target targetId)
486 EXPECT_FALSE(lp.name.empty());
489 pool.set("pool", "ave");
490 pool.set("kernel_w", 2);
491 pool.set("kernel_h", 2);
492 pool.set("stride_w", 2);
493 pool.set("stride_h", 2);
494 pool.type = "Pooling";
495 pool.name = "ave_pool";
498 int poolId = net.addLayer(pool.name, pool.type, pool);
499 net.connect(0, 0, poolId, 0);
500 net.addLayerToPrev(lp.name, lp.type, lp);
502 int sz[] = {1, kNumChannels, 10, 10};
503 Mat input(4, &sz[0], CV_32F);
504 test(input, net, backendId, targetId);
507 typedef TestWithParam<tuple<bool, bool, float, tuple<Backend, Target> > > BatchNorm;
508 TEST_P(BatchNorm, Accuracy)
510 bool hasWeights = get<0>(GetParam());
511 bool hasBias = get<1>(GetParam());
512 float epsilon = get<2>(GetParam());
513 Backend backendId = get<0>(get<3>(GetParam()));
514 Target targetId = get<1>(get<3>(GetParam()));
517 lp.set("has_weight", hasWeights);
518 lp.set("has_bias", hasBias);
519 lp.set("eps", epsilon);
520 lp.type = "BatchNorm";
521 lp.name = "testLayer";
524 for (int i = 0; i < 3; ++i)
525 lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
526 if (hasBias || hasWeights)
527 lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
529 for (int i = 0; i < lp.blobs.size(); ++i)
530 randu(lp.blobs[i], 0.0f, 1.0f);
532 testInPlaceActivation(lp, backendId, targetId);
535 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, BatchNorm, Combine(
536 /*has weights*/ Bool(),
538 /*epsilon*/ Values(1e-3f, 1e-5f),
539 dnnBackendsAndTargetsWithHalide()
542 typedef TestWithParam<tuple<float, tuple<Backend, Target> > > ReLU;
543 TEST_P(ReLU, Accuracy)
545 float negativeSlope = get<0>(GetParam());
546 Backend backendId = get<0>(get<1>(GetParam()));
547 Target targetId = get<1>(get<1>(GetParam()));
550 lp.set("negative_slope", negativeSlope);
552 lp.name = "testLayer";
553 testInPlaceActivation(lp, backendId, targetId);
556 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, ReLU, Combine(
557 /*negative slope*/ Values(2.0f, 0.3f, -0.1f, 0.0f),
558 dnnBackendsAndTargetsWithHalide()
561 typedef TestWithParam<tuple<std::string, tuple<Backend, Target> > > NoParamActivation;
562 TEST_P(NoParamActivation, Accuracy)
564 Backend backendId = get<0>(get<1>(GetParam()));
565 Target targetId = get<1>(get<1>(GetParam()));
568 lp.type = get<0>(GetParam());
569 lp.name = "testLayer";
570 testInPlaceActivation(lp, backendId, targetId);
572 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, NoParamActivation, Combine(
573 /*type*/ Values("TanH", "Sigmoid", "AbsVal", "BNLL"),
574 dnnBackendsAndTargetsWithHalide()
577 typedef TestWithParam<tuple<Vec3f, tuple<Backend, Target> > > Power;
578 TEST_P(Power, Accuracy)
580 float power = get<0>(GetParam())[0];
581 float scale = get<0>(GetParam())[1];
582 float shift = get<0>(GetParam())[2];
583 Backend backendId = get<0>(get<1>(GetParam()));
584 Target targetId = get<1>(get<1>(GetParam()));
587 lp.set("power", power);
588 lp.set("scale", scale);
589 lp.set("shift", shift);
591 lp.name = "testLayer";
592 testInPlaceActivation(lp, backendId, targetId);
595 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Power, Combine(
596 /*power, scale, shift*/ Values(Vec3f(0.9f, 1.0f, 1.1f), Vec3f(0.9f, 1.1f, 1.0f),
597 Vec3f(1.0f, 0.9f, 1.1f), Vec3f(1.0f, 1.1f, 0.9f),
598 Vec3f(1.1f, 0.9f, 1.0f), Vec3f(1.1f, 1.0f, 0.9f)),
599 dnnBackendsAndTargetsWithHalide()
602 TEST_P(Test_Halide_layers, ChannelsPReLU)
605 lp.type = "ChannelsPReLU";
606 lp.name = "testLayer";
607 lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
608 randu(lp.blobs[0], -1.0f, 1.0f);
610 testInPlaceActivation(lp, backend, target);
613 typedef TestWithParam<tuple<bool, tuple<Backend, Target> > > Scale;
614 TEST_P(Scale, Accuracy)
616 bool hasBias = get<0>(GetParam());
617 Backend backendId = get<0>(get<1>(GetParam()));
618 Target targetId = get<1>(get<1>(GetParam()));
621 lp.set("bias_term", hasBias);
623 lp.name = "testLayer";
624 lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
625 randu(lp.blobs[0], -1.0f, 1.0f);
628 lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
629 randu(lp.blobs[1], -1.0f, 1.0f);
631 testInPlaceActivation(lp, backendId, targetId);
634 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Scale, Combine(
636 dnnBackendsAndTargetsWithHalide()
639 ////////////////////////////////////////////////////////////////////////////////
641 ////////////////////////////////////////////////////////////////////////////////
643 // input --- conv --- concat --- output
644 // `--- conv ----^ ^ ^
645 // `---- ... ------' '
646 // `-----------------'
647 typedef TestWithParam<tuple<Vec3i, Vec3i, tuple<Backend, Target> > > Concat;
648 TEST_P(Concat, Accuracy)
650 Vec3i inSize = get<0>(GetParam());
651 Vec3i numChannels = get<1>(GetParam());
652 Backend backendId = get<0>(get<2>(GetParam()));
653 Target targetId = get<1>(get<2>(GetParam()));
655 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
656 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
657 && inSize == Vec3i(1, 4, 5) && numChannels == Vec3i(1, 6, 2)
659 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_2018R5); // crash
662 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
663 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU
664 && inSize == Vec3i(1, 4, 5) && numChannels == Vec3i(1, 6, 2)
666 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R1, CV_TEST_TAG_DNN_SKIP_IE_2019R1_1); // TODO: IE_CPU
671 std::vector<int> convLayerIds;
672 convLayerIds.reserve(numChannels.channels);
673 for (int i = 0, n = numChannels.channels; i < n; ++i)
678 int sz[] = {numChannels[i], inSize[0], 1, 1};
679 Mat weights(4, &sz[0], CV_32F);
680 randu(weights, -1.0f, 1.0f);
682 LayerParams convParam;
683 convParam.set("kernel_w", 1);
684 convParam.set("kernel_h", 1);
685 convParam.set("num_output", numChannels[i]);
686 convParam.set("bias_term", false);
687 convParam.type = "Convolution";
688 std::ostringstream ss;
689 ss << "convLayer" << i;
690 convParam.name = ss.str();
691 convParam.blobs.push_back(weights);
693 int layerId = net.addLayer(convParam.name, convParam.type, convParam);
694 convLayerIds.push_back(layerId);
695 net.connect(0, 0, layerId, 0);
698 LayerParams concatParam;
699 concatParam.type = "Concat";
700 concatParam.name = "testLayer";
701 int concatId = net.addLayer(concatParam.name, concatParam.type, concatParam);
702 net.connect(0, 0, concatId, 0);
703 for (int i = 0; i < convLayerIds.size(); ++i)
705 net.connect(convLayerIds[i], 0, concatId, i + 1);
708 int sz[] = {1, inSize[0], inSize[1], inSize[2]};
709 Mat input(4, &sz[0], CV_32F);
710 test(input, net, backendId, targetId);
713 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Concat, Combine(
714 /*input size*/ Values(Vec3i(1, 4, 5), Vec3i(2, 8, 6)),
715 /*channels*/ Values(Vec3i(2, 0, 0), Vec3i(3, 4, 0), Vec3i(1, 6, 2)),
716 dnnBackendsAndTargetsWithHalide()
719 ////////////////////////////////////////////////////////////////////////////////
720 // Element-wise layers
721 ////////////////////////////////////////////////////////////////////////////////
723 // input --- conv --- eltwise --- output
724 // `--- conv ----^ ^ ^
725 // `---- ... ------' '
726 // `-----------------'
727 typedef TestWithParam<tuple<Vec3i, std::string, int, bool, tuple<Backend, Target> > > Eltwise;
728 TEST_P(Eltwise, Accuracy)
730 Vec3i inSize = get<0>(GetParam());
731 std::string op = get<1>(GetParam());
732 int numConv = get<2>(GetParam());
733 bool weighted = get<3>(GetParam());
734 Backend backendId = get<0>(get<4>(GetParam()));
735 Target targetId = get<1>(get<4>(GetParam()));
737 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
738 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD &&
739 inSize == Vec3i(1, 4, 5))
740 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_2018R5);
743 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
744 if (backendId == DNN_BACKEND_INFERENCE_ENGINE && numConv > 1)
745 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R1, CV_TEST_TAG_DNN_SKIP_IE_2019R1_1);
750 std::vector<int> convLayerIds(numConv);
751 for (int i = 0; i < numConv; ++i)
753 int sz[] = {inSize[0], inSize[0], 1, 1};
754 Mat weights(4, &sz[0], CV_32F);
755 randu(weights, -1.0f, 1.0f);
757 LayerParams convParam;
758 convParam.set("kernel_w", 1);
759 convParam.set("kernel_h", 1);
760 convParam.set("num_output", inSize[0]);
761 convParam.set("bias_term", false);
762 convParam.type = "Convolution";
763 std::ostringstream ss;
764 ss << "convLayer" << i;
765 convParam.name = ss.str();
766 convParam.blobs.push_back(weights);
768 convLayerIds[i] = net.addLayer(convParam.name, convParam.type, convParam);
769 net.connect(0, 0, convLayerIds[i], 0);
772 LayerParams eltwiseParam;
773 eltwiseParam.set("operation", op);
774 if (op == "sum" && weighted)
776 RNG& rng = cv::theRNG();
777 std::vector<float> coeff(1 + numConv);
778 for (int i = 0; i < coeff.size(); ++i)
780 coeff[i] = rng.uniform(-2.0f, 2.0f);
782 eltwiseParam.set("coeff", DictValue::arrayReal<float*>(&coeff[0], coeff.size()));
784 eltwiseParam.type = "Eltwise";
785 eltwiseParam.name = "testLayer";
786 int eltwiseId = net.addLayer(eltwiseParam.name, eltwiseParam.type, eltwiseParam);
787 net.connect(0, 0, eltwiseId, 0);
788 for (int i = 0; i < numConv; ++i)
790 net.connect(convLayerIds[i], 0, eltwiseId, i + 1);
793 int sz[] = {1, inSize[0], inSize[1], inSize[2]};
794 Mat input(4, &sz[0], CV_32F);
795 test(input, net, backendId, targetId);
798 INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Eltwise, Combine(
799 /*input size*/ Values(Vec3i(1, 4, 5), Vec3i(2, 8, 6)),
800 /*operation*/ Values("prod", "sum", "max"),
801 /*num convs*/ Values(1, 2, 3),
802 /*weighted(for sum only)*/ Bool(),
803 dnnBackendsAndTargetsWithHalide()
806 ////////////////////////////////////////////////////////////////////////////
808 ////////////////////////////////////////////////////////////////////////////
810 TEST(MixedBackends_Halide_Default_Halide, Accuracy)
812 // Just a layer that supports Halide backend.
815 lrn.name = "testLRN";
817 // Some of layers that doesn't supports Halide backend yet.
820 mvn.name = "testMVN";
822 // Halide layer again.
825 lrn2.name = "testLRN2";
828 int lrnId = net.addLayer(lrn.name, lrn.type, lrn);
829 net.connect(0, 0, lrnId, 0);
830 net.addLayerToPrev(mvn.name, mvn.type, mvn);
831 net.addLayerToPrev(lrn2.name, lrn2.type, lrn2);
833 int sz[] = {4, 3, 5, 6};
834 Mat input(4, &sz[0], CV_32F);
835 randu(input, -1.0f, 1.0f);
837 net.setPreferableBackend(DNN_BACKEND_OPENCV);
838 Mat outputDefault = net.forward().clone();
840 net.setPreferableBackend(DNN_BACKEND_HALIDE);
842 Mat outputHalide = net.forward().clone();
843 normAssert(outputDefault, outputHalide);
845 net.setPreferableTarget(DNN_TARGET_OPENCL);
847 outputHalide = net.forward().clone();
848 normAssert(outputDefault, outputHalide);
850 #endif // HAVE_HALIDE
852 INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_Halide_layers, dnnBackendsAndTargetsWithHalide());