Skip to content

Commit cc2ee92

Browse files
committed
Merge pull request opencv#10164 from pengli:dnn
2 parents f5dba12 + 1f465a0 commit cc2ee92

File tree

4 files changed

+219
-7
lines changed

4 files changed

+219
-7
lines changed

modules/dnn/src/dnn.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,8 @@ struct Net::Impl
11961196
// some other layers.
11971197

11981198
// TODO: OpenCL target support more fusion styles.
1199-
if ( preferableTarget == DNN_TARGET_OPENCL && ld.layerInstance->type.compare("Convolution") )
1199+
if ( preferableTarget == DNN_TARGET_OPENCL &&
1200+
(!cv::ocl::useOpenCL() || ld.layerInstance->type.compare("Convolution")) )
12001201
continue;
12011202

12021203
Ptr<Layer>& currLayer = ld.layerInstance;
@@ -1214,7 +1215,10 @@ struct Net::Impl
12141215
{
12151216
printf_(("\tfused with %s\n", nextBNormLayer->name.c_str()));
12161217
bnormData->skipFlags[DNN_BACKEND_DEFAULT] = true;
1217-
ld.outputBlobs = layers[lpNext.lid].outputBlobs;
1218+
if ( preferableTarget == DNN_TARGET_OPENCL )
1219+
ld.umat_outputBlobs = layers[lpNext.lid].umat_outputBlobs;
1220+
else
1221+
ld.outputBlobs = layers[lpNext.lid].outputBlobs;
12181222
if( bnormData->consumers.size() == 1 )
12191223
{
12201224
nextData = &layers[bnormData->consumers[0].lid];
@@ -1234,7 +1238,10 @@ struct Net::Impl
12341238
{
12351239
printf_(("\tfused with %s\n", nextScaleLayer->name.c_str()));
12361240
scaleData->skipFlags[DNN_BACKEND_DEFAULT] = true;
1237-
ld.outputBlobs = layers[lpNext.lid].outputBlobs;
1241+
if ( preferableTarget == DNN_TARGET_OPENCL )
1242+
ld.umat_outputBlobs = layers[lpNext.lid].umat_outputBlobs;
1243+
else
1244+
ld.outputBlobs = layers[lpNext.lid].outputBlobs;
12381245
if( scaleData->consumers.size() == 1 )
12391246
{
12401247
nextData = &layers[scaleData->consumers[0].lid];
@@ -1263,7 +1270,10 @@ struct Net::Impl
12631270
LayerData *activData = nextData;
12641271
printf_(("\tfused with %s\n", nextActivLayer->name.c_str()));
12651272
activData->skipFlags[DNN_BACKEND_DEFAULT] = true;
1266-
ld.outputBlobs = layers[lpNext.lid].outputBlobs;
1273+
if ( preferableTarget == DNN_TARGET_OPENCL )
1274+
ld.umat_outputBlobs = layers[lpNext.lid].umat_outputBlobs;
1275+
else
1276+
ld.outputBlobs = layers[lpNext.lid].outputBlobs;
12671277

12681278
if ( preferableTarget == DNN_TARGET_OPENCL )
12691279
{
@@ -1325,13 +1335,13 @@ struct Net::Impl
13251335
!nextData->type.compare("Power")) &&
13261336
currLayer->setActivation(nextActivLayer) )
13271337
{
1328-
CV_Assert(firstConvLayerData->outputBlobs.size() == 1 && ld.inputBlobs.size() == 1);
1329-
ld.inputBlobs.push_back(&firstConvLayerData->outputBlobs[0]);
1338+
CV_Assert(firstConvLayerData->umat_outputBlobs.size() == 1 && ld.umat_inputBlobs.size() == 1);
1339+
ld.umat_inputBlobs.push_back(firstConvLayerData->umat_outputBlobs[0]);
13301340
printf_(("\tfused with %s\n", nextEltwiseLayer->name.c_str()));
13311341
printf_(("\tfused with %s\n", nextActivLayer->name.c_str()));
13321342
eltwiseData->skipFlags[DNN_BACKEND_DEFAULT] = true;
13331343
nextData->skipFlags[DNN_BACKEND_DEFAULT] = true;
1334-
ld.outputBlobs = layers[lpNext.lid].outputBlobs;
1344+
ld.umat_outputBlobs = layers[lpNext.lid].umat_outputBlobs;
13351345
}
13361346
}
13371347
}

modules/dnn/test/test_caffe_importer.cpp

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#include "test_precomp.hpp"
4343
#include "npy_blob.hpp"
4444
#include <opencv2/dnn/shape_utils.hpp>
45+
#include <opencv2/core/ocl.hpp>
46+
#include <opencv2/ts/ocl_test.hpp>
4547

4648
namespace cvtest
4749
{
@@ -119,6 +121,43 @@ TEST_P(Reproducibility_AlexNet, Accuracy)
119121

120122
INSTANTIATE_TEST_CASE_P(Test_Caffe, Reproducibility_AlexNet, testing::Values(true, false));
121123

124+
typedef testing::TestWithParam<tuple<bool> > Reproducibility_OCL_AlexNet;
125+
OCL_TEST_P(Reproducibility_OCL_AlexNet, Accuracy)
126+
{
127+
bool readFromMemory = get<0>(GetParam());
128+
Net net;
129+
{
130+
const string proto = findDataFile("dnn/bvlc_alexnet.prototxt", false);
131+
const string model = findDataFile("dnn/bvlc_alexnet.caffemodel", false);
132+
if (readFromMemory)
133+
{
134+
string dataProto;
135+
ASSERT_TRUE(readFileInMemory(proto, dataProto));
136+
string dataModel;
137+
ASSERT_TRUE(readFileInMemory(model, dataModel));
138+
139+
net = readNetFromCaffe(dataProto.c_str(), dataProto.size(),
140+
dataModel.c_str(), dataModel.size());
141+
}
142+
else
143+
net = readNetFromCaffe(proto, model);
144+
ASSERT_FALSE(net.empty());
145+
}
146+
147+
net.setPreferableBackend(DNN_BACKEND_DEFAULT);
148+
net.setPreferableTarget(DNN_TARGET_OPENCL);
149+
150+
Mat sample = imread(_tf("grace_hopper_227.png"));
151+
ASSERT_TRUE(!sample.empty());
152+
153+
net.setInput(blobFromImage(sample, 1.0f, Size(227, 227), Scalar(), false), "data");
154+
Mat out = net.forward("prob");
155+
Mat ref = blobFromNPY(_tf("caffe_alexnet_prob.npy"));
156+
normAssert(ref, out);
157+
}
158+
159+
OCL_INSTANTIATE_TEST_CASE_P(Test_Caffe, Reproducibility_OCL_AlexNet, testing::Values(true, false));
160+
122161
#if !defined(_WIN32) || defined(_WIN64)
123162
TEST(Reproducibility_FCN, Accuracy)
124163
{
@@ -201,6 +240,38 @@ TEST(Reproducibility_MobileNet_SSD, Accuracy)
201240
}
202241
}
203242

243+
OCL_TEST(Reproducibility_MobileNet_SSD, Accuracy)
244+
{
245+
const string proto = findDataFile("dnn/MobileNetSSD_deploy.prototxt", false);
246+
const string model = findDataFile("dnn/MobileNetSSD_deploy.caffemodel", false);
247+
Net net = readNetFromCaffe(proto, model);
248+
249+
net.setPreferableBackend(DNN_BACKEND_DEFAULT);
250+
net.setPreferableTarget(DNN_TARGET_OPENCL);
251+
252+
Mat sample = imread(_tf("street.png"));
253+
254+
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
255+
net.setInput(inp);
256+
Mat out = net.forward();
257+
258+
Mat ref = blobFromNPY(_tf("mobilenet_ssd_caffe_out.npy"));
259+
normAssert(ref, out);
260+
261+
// Check that detections aren't preserved.
262+
inp.setTo(0.0f);
263+
net.setInput(inp);
264+
out = net.forward();
265+
266+
const int numDetections = out.size[2];
267+
ASSERT_NE(numDetections, 0);
268+
for (int i = 0; i < numDetections; ++i)
269+
{
270+
float confidence = out.ptr<float>(0, 0, i)[2];
271+
ASSERT_EQ(confidence, 0);
272+
}
273+
}
274+
204275
TEST(Reproducibility_ResNet50, Accuracy)
205276
{
206277
Net net = readNetFromCaffe(findDataFile("dnn/ResNet-50-deploy.prototxt", false),
@@ -216,6 +287,24 @@ TEST(Reproducibility_ResNet50, Accuracy)
216287
normAssert(ref, out);
217288
}
218289

290+
OCL_TEST(Reproducibility_ResNet50, Accuracy)
291+
{
292+
Net net = readNetFromCaffe(findDataFile("dnn/ResNet-50-deploy.prototxt", false),
293+
findDataFile("dnn/ResNet-50-model.caffemodel", false));
294+
295+
net.setPreferableBackend(DNN_BACKEND_DEFAULT);
296+
net.setPreferableTarget(DNN_TARGET_OPENCL);
297+
298+
Mat input = blobFromImage(imread(_tf("googlenet_0.png")), 1.0f, Size(224,224), Scalar(), false);
299+
ASSERT_TRUE(!input.empty());
300+
301+
net.setInput(input);
302+
Mat out = net.forward();
303+
304+
Mat ref = blobFromNPY(_tf("resnet50_prob.npy"));
305+
normAssert(ref, out);
306+
}
307+
219308
TEST(Reproducibility_SqueezeNet_v1_1, Accuracy)
220309
{
221310
Net net = readNetFromCaffe(findDataFile("dnn/squeezenet_v1.1.prototxt", false),
@@ -231,6 +320,24 @@ TEST(Reproducibility_SqueezeNet_v1_1, Accuracy)
231320
normAssert(ref, out);
232321
}
233322

323+
OCL_TEST(Reproducibility_SqueezeNet_v1_1, Accuracy)
324+
{
325+
Net net = readNetFromCaffe(findDataFile("dnn/squeezenet_v1.1.prototxt", false),
326+
findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
327+
328+
net.setPreferableBackend(DNN_BACKEND_DEFAULT);
329+
net.setPreferableTarget(DNN_TARGET_OPENCL);
330+
331+
Mat input = blobFromImage(imread(_tf("googlenet_0.png")), 1.0f, Size(227,227), Scalar(), false);
332+
ASSERT_TRUE(!input.empty());
333+
334+
net.setInput(input);
335+
Mat out = net.forward();
336+
337+
Mat ref = blobFromNPY(_tf("squeezenet_v1.1_prob.npy"));
338+
normAssert(ref, out);
339+
}
340+
234341
TEST(Reproducibility_AlexNet_fp16, Accuracy)
235342
{
236343
const float l1 = 1e-5;

modules/dnn/test/test_darknet_importer.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,68 @@ TEST(Reproducibility_TinyYoloVoc, Accuracy)
184184
normAssert(ref, detection);
185185
}
186186

187+
OCL_TEST(Reproducibility_YoloVoc, Accuracy)
188+
{
189+
Net net;
190+
{
191+
const string cfg = findDataFile("dnn/yolo-voc.cfg", false);
192+
const string model = findDataFile("dnn/yolo-voc.weights", false);
193+
net = readNetFromDarknet(cfg, model);
194+
ASSERT_FALSE(net.empty());
195+
}
196+
197+
net.setPreferableBackend(DNN_BACKEND_DEFAULT);
198+
net.setPreferableTarget(DNN_TARGET_OPENCL);
199+
200+
// dog416.png is dog.jpg that resized to 416x416 in the lossless PNG format
201+
Mat sample = imread(_tf("dog416.png"));
202+
ASSERT_TRUE(!sample.empty());
203+
204+
Size inputSize(416, 416);
205+
206+
if (sample.size() != inputSize)
207+
resize(sample, sample, inputSize);
208+
209+
net.setInput(blobFromImage(sample, 1 / 255.F), "data");
210+
Mat out = net.forward("detection_out");
211+
212+
Mat detection;
213+
const float confidenceThreshold = 0.24;
214+
215+
for (int i = 0; i < out.rows; i++) {
216+
const int probability_index = 5;
217+
const int probability_size = out.cols - probability_index;
218+
float *prob_array_ptr = &out.at<float>(i, probability_index);
219+
size_t objectClass = std::max_element(prob_array_ptr, prob_array_ptr + probability_size) - prob_array_ptr;
220+
float confidence = out.at<float>(i, (int)objectClass + probability_index);
221+
222+
if (confidence > confidenceThreshold)
223+
detection.push_back(out.row(i));
224+
}
225+
226+
// obtained by: ./darknet detector test ./cfg/voc.data ./cfg/yolo-voc.cfg ./yolo-voc.weights -thresh 0.24 ./dog416.png
227+
// There are 3 objects (6-car, 1-bicycle, 11-dog) with 25 values for each:
228+
// { relative_center_x, relative_center_y, relative_width, relative_height, unused_t0, probability_for_each_class[20] }
229+
float ref_array[] = {
230+
0.740161F, 0.214100F, 0.325575F, 0.173418F, 0.750769F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
231+
0.000000F, 0.000000F, 0.750469F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
232+
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
233+
234+
0.501618F, 0.504757F, 0.461713F, 0.481310F, 0.783550F, 0.000000F, 0.780879F, 0.000000F, 0.000000F,
235+
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
236+
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
237+
238+
0.279968F, 0.638651F, 0.282737F, 0.600284F, 0.901864F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
239+
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.901615F,
240+
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F
241+
};
242+
243+
const int number_of_objects = 3;
244+
Mat ref(number_of_objects, sizeof(ref_array) / (number_of_objects * sizeof(float)), CV_32FC1, &ref_array);
245+
246+
normAssert(ref, detection);
247+
}
248+
187249
TEST(Reproducibility_YoloVoc, Accuracy)
188250
{
189251
Net net;

modules/dnn/test/test_torch_importer.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,39 @@ TEST(Torch_Importer, FastNeuralStyle_accuracy)
382382
}
383383
}
384384

385+
OCL_TEST(Torch_Importer, FastNeuralStyle_accuracy)
386+
{
387+
std::string models[] = {"dnn/fast_neural_style_eccv16_starry_night.t7",
388+
"dnn/fast_neural_style_instance_norm_feathers.t7"};
389+
std::string targets[] = {"dnn/lena_starry_night.png", "dnn/lena_feathers.png"};
390+
391+
for (int i = 0; i < 2; ++i)
392+
{
393+
const string model = findDataFile(models[i], false);
394+
Net net = readNetFromTorch(model);
395+
396+
net.setPreferableBackend(DNN_BACKEND_DEFAULT);
397+
net.setPreferableTarget(DNN_TARGET_OPENCL);
398+
399+
Mat img = imread(findDataFile("dnn/googlenet_1.png", false));
400+
Mat inputBlob = blobFromImage(img, 1.0, Size(), Scalar(103.939, 116.779, 123.68), false);
401+
402+
net.setInput(inputBlob);
403+
Mat out = net.forward();
404+
405+
// Deprocessing.
406+
getPlane(out, 0, 0) += 103.939;
407+
getPlane(out, 0, 1) += 116.779;
408+
getPlane(out, 0, 2) += 123.68;
409+
out = cv::min(cv::max(0, out), 255);
410+
411+
Mat ref = imread(findDataFile(targets[i]));
412+
Mat refBlob = blobFromImage(ref, 1.0, Size(), Scalar(), false);
413+
414+
normAssert(out, refBlob, "", 0.5, 1.1);
415+
}
416+
}
417+
385418
}
386419

387420
#endif

0 commit comments

Comments
 (0)