mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 08:13:04 +04:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
@@ -381,6 +381,16 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
/** Returns true if there are no layers in the network. */
|
||||
CV_WRAP bool empty() const;
|
||||
|
||||
/** @brief Dump net to String
|
||||
* @returns String with structure, hyperparameters, backend, target and fusion
|
||||
* To see correct backend, target and fusion run after forward().
|
||||
*/
|
||||
CV_WRAP String dump();
|
||||
/** @brief Dump net structure, hyperparameters, backend, target and fusion to dot file
|
||||
* @param path path to output file with .dot extension
|
||||
* @see dump()
|
||||
*/
|
||||
CV_WRAP void dumpToFile(const String& path);
|
||||
/** @brief Adds new layer to the net.
|
||||
* @param name unique name of the adding layer.
|
||||
* @param type typename of the adding layer (type must be registered in LayerRegister).
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define OPENCV_DNN_VERSION_HPP
|
||||
|
||||
/// Use with major OpenCV version only.
|
||||
#define OPENCV_DNN_API_VERSION 20190122
|
||||
#define OPENCV_DNN_API_VERSION 20190412
|
||||
|
||||
#if !defined CV_DOXYGEN && !defined CV_DNN_DONT_ADD_INLINE_NS
|
||||
#define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION)
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
|
||||
from tests_common import NewOpenCVTests, unittest
|
||||
|
||||
def normAssert(test, a, b, lInf=1e-5):
|
||||
test.assertLess(np.max(np.abs(a - b)), lInf)
|
||||
|
||||
def inter_area(box1, box2):
|
||||
x_min, x_max = max(box1[0], box2[0]), min(box1[2], box2[2])
|
||||
y_min, y_max = max(box1[1], box2[1]), min(box1[3], box2[3])
|
||||
return (x_max - x_min) * (y_max - y_min)
|
||||
|
||||
def area(box):
|
||||
return (box[2] - box[0]) * (box[3] - box[1])
|
||||
|
||||
def box2str(box):
|
||||
left, top = box[0], box[1]
|
||||
width, height = box[2] - left, box[3] - top
|
||||
return '[%f x %f from (%f, %f)]' % (width, height, left, top)
|
||||
|
||||
def normAssertDetections(test, ref, out, confThreshold=0.0, scores_diff=1e-5, boxes_iou_diff=1e-4):
|
||||
ref = np.array(ref, np.float32)
|
||||
refClassIds, testClassIds = ref[:, 1], out[:, 1]
|
||||
refScores, testScores = ref[:, 2], out[:, 2]
|
||||
refBoxes, testBoxes = ref[:, 3:], out[:, 3:]
|
||||
|
||||
matchedRefBoxes = [False] * len(refBoxes)
|
||||
errMsg = ''
|
||||
for i in range(len(refBoxes)):
|
||||
testScore = testScores[i]
|
||||
if testScore < confThreshold:
|
||||
continue
|
||||
|
||||
testClassId, testBox = testClassIds[i], testBoxes[i]
|
||||
matched = False
|
||||
for j in range(len(refBoxes)):
|
||||
if (not matchedRefBoxes[j]) and testClassId == refClassIds[j] and \
|
||||
abs(testScore - refScores[j]) < scores_diff:
|
||||
interArea = inter_area(testBox, refBoxes[j])
|
||||
iou = interArea / (area(testBox) + area(refBoxes[j]) - interArea)
|
||||
if abs(iou - 1.0) < boxes_iou_diff:
|
||||
matched = True
|
||||
matchedRefBoxes[j] = True
|
||||
if not matched:
|
||||
errMsg += '\nUnmatched prediction: class %d score %f box %s' % (testClassId, testScore, box2str(testBox))
|
||||
|
||||
for i in range(len(refBoxes)):
|
||||
if (not matchedRefBoxes[i]) and refScores[i] > confThreshold:
|
||||
errMsg += '\nUnmatched reference: class %d score %f box %s' % (refClassIds[i], refScores[i], box2str(refBoxes[i]))
|
||||
if errMsg:
|
||||
test.fail(errMsg)
|
||||
|
||||
|
||||
# Returns a simple one-layer network created from Caffe's format
|
||||
def getSimpleNet():
|
||||
prototxt = """
|
||||
name: "simpleNet"
|
||||
input: "data"
|
||||
layer {
|
||||
type: "Identity"
|
||||
name: "testLayer"
|
||||
top: "testLayer"
|
||||
bottom: "data"
|
||||
}
|
||||
"""
|
||||
return cv.dnn.readNetFromCaffe(bytearray(prototxt, 'utf8'))
|
||||
|
||||
|
||||
def testBackendAndTarget(backend, target):
|
||||
net = getSimpleNet()
|
||||
net.setPreferableBackend(backend)
|
||||
net.setPreferableTarget(target)
|
||||
inp = np.random.standard_normal([1, 2, 3, 4]).astype(np.float32)
|
||||
try:
|
||||
net.setInput(inp)
|
||||
net.forward()
|
||||
except BaseException as e:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
haveInfEngine = testBackendAndTarget(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_CPU)
|
||||
dnnBackendsAndTargets = [
|
||||
[cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_CPU],
|
||||
]
|
||||
|
||||
if haveInfEngine:
|
||||
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_CPU])
|
||||
if testBackendAndTarget(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_MYRIAD):
|
||||
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_MYRIAD])
|
||||
|
||||
if cv.ocl.haveOpenCL() and cv.ocl.useOpenCL():
|
||||
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_OPENCL])
|
||||
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_OPENCL_FP16])
|
||||
if haveInfEngine and cv.ocl_Device.getDefault().isIntel():
|
||||
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_OPENCL])
|
||||
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_OPENCL_FP16])
|
||||
|
||||
|
||||
def printParams(backend, target):
|
||||
backendNames = {
|
||||
cv.dnn.DNN_BACKEND_OPENCV: 'OCV',
|
||||
cv.dnn.DNN_BACKEND_INFERENCE_ENGINE: 'DLIE'
|
||||
}
|
||||
targetNames = {
|
||||
cv.dnn.DNN_TARGET_CPU: 'CPU',
|
||||
cv.dnn.DNN_TARGET_OPENCL: 'OCL',
|
||||
cv.dnn.DNN_TARGET_OPENCL_FP16: 'OCL_FP16',
|
||||
cv.dnn.DNN_TARGET_MYRIAD: 'MYRIAD'
|
||||
}
|
||||
print('%s/%s' % (backendNames[backend], targetNames[target]))
|
||||
|
||||
|
||||
class dnn_test(NewOpenCVTests):
|
||||
|
||||
def find_dnn_file(self, filename, required=True):
|
||||
return self.find_file(filename, [os.environ.get('OPENCV_DNN_TEST_DATA_PATH', os.getcwd())], required=required)
|
||||
|
||||
def test_blobFromImage(self):
|
||||
np.random.seed(324)
|
||||
|
||||
width = 6
|
||||
height = 7
|
||||
scale = 1.0/127.5
|
||||
mean = (10, 20, 30)
|
||||
|
||||
# Test arguments names.
|
||||
img = np.random.randint(0, 255, [4, 5, 3]).astype(np.uint8)
|
||||
blob = cv.dnn.blobFromImage(img, scale, (width, height), mean, True, False)
|
||||
blob_args = cv.dnn.blobFromImage(img, scalefactor=scale, size=(width, height),
|
||||
mean=mean, swapRB=True, crop=False)
|
||||
normAssert(self, blob, blob_args)
|
||||
|
||||
# Test values.
|
||||
target = cv.resize(img, (width, height), interpolation=cv.INTER_LINEAR)
|
||||
target = target.astype(np.float32)
|
||||
target = target[:,:,[2, 1, 0]] # BGR2RGB
|
||||
target[:,:,0] -= mean[0]
|
||||
target[:,:,1] -= mean[1]
|
||||
target[:,:,2] -= mean[2]
|
||||
target *= scale
|
||||
target = target.transpose(2, 0, 1).reshape(1, 3, height, width) # to NCHW
|
||||
normAssert(self, blob, target)
|
||||
|
||||
|
||||
def test_face_detection(self):
|
||||
testdata_required = bool(os.environ.get('OPENCV_DNN_TEST_REQUIRE_TESTDATA', False))
|
||||
proto = self.find_dnn_file('dnn/opencv_face_detector.prototxt2', required=testdata_required)
|
||||
model = self.find_dnn_file('dnn/opencv_face_detector.caffemodel', required=testdata_required)
|
||||
if proto is None or model is None:
|
||||
raise unittest.SkipTest("Missing DNN test files (dnn/opencv_face_detector.{prototxt/caffemodel}). Verify OPENCV_DNN_TEST_DATA_PATH configuration parameter.")
|
||||
|
||||
img = self.get_sample('gpu/lbpcascade/er.png')
|
||||
blob = cv.dnn.blobFromImage(img, mean=(104, 177, 123), swapRB=False, crop=False)
|
||||
|
||||
ref = [[0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631],
|
||||
[0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168],
|
||||
[0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290],
|
||||
[0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477],
|
||||
[0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494],
|
||||
[0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801]]
|
||||
|
||||
print('\n')
|
||||
for backend, target in dnnBackendsAndTargets:
|
||||
printParams(backend, target)
|
||||
|
||||
net = cv.dnn.readNet(proto, model)
|
||||
net.setPreferableBackend(backend)
|
||||
net.setPreferableTarget(target)
|
||||
net.setInput(blob)
|
||||
out = net.forward().reshape(-1, 7)
|
||||
|
||||
scoresDiff = 4e-3 if target in [cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD] else 1e-5
|
||||
iouDiff = 2e-2 if target in [cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD] else 1e-4
|
||||
|
||||
normAssertDetections(self, ref, out, 0.5, scoresDiff, iouDiff)
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
+201
-26
@@ -48,6 +48,7 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
@@ -1179,12 +1180,6 @@ struct Net::Impl
|
||||
continue;
|
||||
|
||||
currLayer->unsetAttached();
|
||||
|
||||
Ptr<PoolingLayer> poolingLayer = currLayer.dynamicCast<PoolingLayer>();
|
||||
if( !poolingLayer.empty() )
|
||||
{
|
||||
poolingLayer->computeMaxIdx = true;
|
||||
}
|
||||
}
|
||||
|
||||
layersTimings.clear();
|
||||
@@ -2145,30 +2140,11 @@ struct Net::Impl
|
||||
}
|
||||
}
|
||||
}
|
||||
// the optimization #2. if there is no layer that takes max pooling layer's computed
|
||||
// max indices (and only some semantical segmentation networks might need this;
|
||||
// many others only take the maximum values), then we switch the max pooling
|
||||
// layer to the faster operating mode.
|
||||
Ptr<PoolingLayer> poolingLayer = ld.layerInstance.dynamicCast<PoolingLayer>();
|
||||
if( !poolingLayer.empty() && !ld.consumers.empty() )
|
||||
{
|
||||
size_t i = 0, nconsumers = ld.consumers.size();
|
||||
for( ; i < nconsumers; i++ )
|
||||
if( ld.consumers[i].oid > 0 )
|
||||
break;
|
||||
// if there is no layer that takes the second output pin of the pooling layer
|
||||
// on input then we don't need to compute the indices
|
||||
if( i >= nconsumers )
|
||||
{
|
||||
poolingLayer->computeMaxIdx = false;
|
||||
printf_(("\tsimplified pooling layer %s\n", poolingLayer->name.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
if (preferableBackend != DNN_BACKEND_OPENCV)
|
||||
continue; // Go to the next layer.
|
||||
|
||||
// the optimization #3. if there is concat layer that concatenates channels
|
||||
// the optimization #2. if there is concat layer that concatenates channels
|
||||
// from the inputs together (i.e. axis == 1) then we make the inputs of
|
||||
// the concat layer to write to the concatenation output buffer
|
||||
// (and so we eliminate the concatenation layer, because the channels
|
||||
@@ -3022,6 +2998,205 @@ int Net::getLayerId(const String &layer)
|
||||
return impl->getLayerId(layer);
|
||||
}
|
||||
|
||||
String Net::dump()
|
||||
{
|
||||
CV_Assert(!empty());
|
||||
std::ostringstream out;
|
||||
std::map<int, LayerData>& map = impl->layers;
|
||||
int prefBackend = impl->preferableBackend;
|
||||
std::vector<std::vector<int> > skippedLayers;
|
||||
std::vector<int> skipId;
|
||||
std::vector<int> allLayers(map.size(), -1);
|
||||
int idPrev = -1;
|
||||
Ptr<BackendNode> prevNode;
|
||||
for (std::map<int, LayerData>::reverse_iterator rit = map.rbegin(); rit != map.rend(); ++rit)
|
||||
{
|
||||
std::map<int, Ptr<BackendNode> >::iterator itBackend = rit->second.backendNodes.find(prefBackend);
|
||||
if (prefBackend == DNN_BACKEND_OPENCV || itBackend == rit->second.backendNodes.end() ||
|
||||
itBackend->second.empty())
|
||||
{
|
||||
if (rit->second.skip)
|
||||
skipId.push_back(rit->first);
|
||||
else if (!skipId.empty())
|
||||
{
|
||||
if (prefBackend == DNN_BACKEND_OPENCV || prevNode.empty())
|
||||
skipId.push_back(rit->first);
|
||||
else if (idPrev != -1)
|
||||
skipId.push_back(idPrev);
|
||||
|
||||
std::sort(skipId.begin(), skipId.end());
|
||||
for (int i = 0; i < skipId.size(); i++) {
|
||||
allLayers[skipId[i]] = skippedLayers.size();
|
||||
}
|
||||
skippedLayers.push_back(skipId);
|
||||
skipId.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itBackend->second == prevNode)
|
||||
skipId.push_back(idPrev);
|
||||
else if (!skipId.empty())
|
||||
{
|
||||
skipId.push_back(idPrev);
|
||||
std::sort(skipId.begin(), skipId.end());
|
||||
for (int i = 0; i < skipId.size(); i++) {
|
||||
allLayers[skipId[i]] = skippedLayers.size();
|
||||
}
|
||||
skippedLayers.push_back(skipId);
|
||||
skipId.clear();
|
||||
}
|
||||
idPrev = rit->first;
|
||||
prevNode = itBackend->second;
|
||||
}
|
||||
}
|
||||
String colors[] = {"#ffffb3", "#fccde5", "#8dd3c7", "#bebada", "#80b1d3", "#fdb462"};
|
||||
String backend;
|
||||
switch (prefBackend) {
|
||||
case DNN_BACKEND_DEFAULT: backend = "DEFAULT/"; break;
|
||||
case DNN_BACKEND_HALIDE: backend = "HALIDE/"; break;
|
||||
case DNN_BACKEND_INFERENCE_ENGINE: backend = "DLIE/"; break;
|
||||
case DNN_BACKEND_OPENCV: backend = "OCV/"; break;
|
||||
}
|
||||
out << "digraph G {" << '\n';
|
||||
// Add nodes
|
||||
for (std::map<int, LayerData>::iterator it = map.begin(); it != map.end(); ++it)
|
||||
{
|
||||
String name = it->second.params.name;
|
||||
if (allLayers[it->first] == -1 && !name.empty()) {
|
||||
out << " " << "\"" << name << "\"" << " [label=\"";
|
||||
skipId.clear();
|
||||
skipId.push_back(it->first);
|
||||
}
|
||||
else if (name.empty() || it->first != skippedLayers[allLayers[it->first]][0])
|
||||
continue;
|
||||
else { // first node in cluster : it->first == skippedLayers[allLayers[it->first]][0]
|
||||
int cluster = allLayers[it->first];
|
||||
out << " " << "\"" << "cluster_" << cluster << "\"" << " [label=\"{";
|
||||
skipId = skippedLayers[allLayers[it->first]]; // vertices in current cluster
|
||||
}
|
||||
for (int i = 0; i < skipId.size(); i++)
|
||||
{
|
||||
LayerParams& lp = map[skipId[i]].params;
|
||||
if (!lp.name.empty()) {
|
||||
if (i > 0) {
|
||||
out << " | ";
|
||||
}
|
||||
out << lp.name << "\\n" << lp.type << "\\n";
|
||||
if (lp.has("kernel_size")) {
|
||||
DictValue size = lp.get("kernel_size");
|
||||
out << "kernel (HxW): " << size << " x " << size << "\\l";
|
||||
} else if (lp.has("kernel_h") && lp.has("kernel_w")) {
|
||||
DictValue h = lp.get("kernel_h");
|
||||
DictValue w = lp.get("kernel_w");
|
||||
out << "kernel (HxW): " << h << " x " << w << "\\l";
|
||||
}
|
||||
if (lp.has("stride")) {
|
||||
DictValue stride = lp.get("stride");
|
||||
out << "stride (HxW): " << stride << " x " << stride << "\\l";
|
||||
} else if (lp.has("stride_h") && lp.has("stride_w")) {
|
||||
DictValue h = lp.get("stride_h");
|
||||
DictValue w = lp.get("stride_w");
|
||||
out << "stride (HxW): " << h << " x " << w << "\\l";
|
||||
}
|
||||
if (lp.has("dilation")) {
|
||||
DictValue dilation = lp.get("dilation");
|
||||
out << "dilation (HxW): " << dilation << " x " << dilation << "\\l";
|
||||
} else if (lp.has("dilation_h") && lp.has("dilation_w")) {
|
||||
DictValue h = lp.get("dilation_h");
|
||||
DictValue w = lp.get("dilation_w");
|
||||
out << "dilation (HxW): " << h << " x " << w << "\\l";
|
||||
}
|
||||
if (lp.has("pad")) {
|
||||
DictValue pad = lp.get("pad");
|
||||
out << "pad (LxTxRxB): " << pad << " x " << pad << " x " << pad << " x " << pad << "\\l";
|
||||
} else if (lp.has("pad_l") && lp.has("pad_t") && lp.has("pad_r") && lp.has("pad_b")) {
|
||||
DictValue l = lp.get("pad_l");
|
||||
DictValue t = lp.get("pad_t");
|
||||
DictValue r = lp.get("pad_r");
|
||||
DictValue b = lp.get("pad_b");
|
||||
out << "pad (LxTxRxB): " << l << " x " << t << " x " << r << " x " << b << "\\l";
|
||||
}
|
||||
else if (lp.has("pooled_w") || lp.has("pooled_h")) {
|
||||
DictValue h = lp.get("pooled_h");
|
||||
DictValue w = lp.get("pooled_w");
|
||||
out << "pad (HxW): " << h << " x " << w << "\\l";
|
||||
}
|
||||
if (lp.has("pool")) {
|
||||
out << "pool: " << lp.get("pool") << "\\l";
|
||||
}
|
||||
if (lp.has("global_pooling")) {
|
||||
out << "global_pooling: " << lp.get("global_pooling") << "\\l";
|
||||
}
|
||||
if (lp.has("group")) {
|
||||
out << "group: " << lp.get("group") << "\\l";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!it->second.outputBlobs.empty())
|
||||
out << "output: " << it->second.outputBlobs[0].size << "\\l";
|
||||
|
||||
Ptr<BackendNode> layerBackend = it->second.backendNodes[prefBackend];
|
||||
out << (!layerBackend.empty() ? backend : "OCV/");
|
||||
int colorId = 0;
|
||||
switch (it->second.layerInstance->preferableTarget) {
|
||||
case DNN_TARGET_CPU: out << "CPU\\n"; colorId = layerBackend.empty() ? 0 : 5; break;
|
||||
case DNN_TARGET_OPENCL: out << "OCL\\n"; colorId = 1; break;
|
||||
case DNN_TARGET_OPENCL_FP16: out << "OCL_FP16\\n"; colorId = 2; break;
|
||||
case DNN_TARGET_MYRIAD: out << "MYRIAD\\n"; colorId = 3; break;
|
||||
case DNN_TARGET_FPGA: out << "FPGA\\n"; colorId = 4; break;
|
||||
}
|
||||
out << ((skipId.size() == 1)? "\" " : " }\" ");
|
||||
out << "fillcolor=\"" << colors[colorId] << "\" ";
|
||||
out << "style=filled ";
|
||||
out << "shape=" << ((skipId.size() == 1)? "box" : "record") << "]" << '\n';
|
||||
}
|
||||
out << '\n';
|
||||
// Add edges
|
||||
int inputsSize = impl->netInputLayer->outNames.size();
|
||||
for (std::map<int, LayerData>::iterator it = map.begin(); it != map.end(); ++it)
|
||||
{
|
||||
if (allLayers[it->first] == -1) // node
|
||||
{
|
||||
for (int i = 0; i < it->second.consumers.size(); i++)
|
||||
{
|
||||
int outId = it->second.consumers[i].lid;
|
||||
if (it == map.begin() && inputsSize > 1)
|
||||
out << " " << "\"" << it->second.name << "_" << i << "\"" << " -> ";
|
||||
else
|
||||
out << " " << "\"" << it->second.name << "\"" << " -> ";
|
||||
if (allLayers[outId] == -1) // node
|
||||
out << "\"" << map[outId].name << "\"" << '\n';
|
||||
else // cluster
|
||||
out << "\"" << "cluster_" << allLayers[outId] << "\"" << '\n';
|
||||
}
|
||||
}
|
||||
else if (it->first == skippedLayers[allLayers[it->first]].back()) // edges from last layer in cluster
|
||||
{
|
||||
for (int i = 0; i < it->second.consumers.size(); i++)
|
||||
{
|
||||
int outId = it->second.consumers[i].lid;
|
||||
if (allLayers[outId] == -1) { // node
|
||||
out << " " << "\"" << "cluster_" << allLayers[it->first] << "\"" << " -> ";
|
||||
out << "\"" << map[outId].name << "\"" << '\n';
|
||||
}
|
||||
else if (allLayers[outId] != allLayers[it->first]) { // another cluster
|
||||
out << " " << "\"" << "cluster_" << allLayers[it->first] << "\"" << " -> ";
|
||||
out << "\"" << "cluster_" << allLayers[outId] << "\"" << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void Net::dumpToFile(const String& path) {
|
||||
std::ofstream file(path.c_str());
|
||||
file << dump();
|
||||
file.close();
|
||||
}
|
||||
|
||||
Ptr<Layer> Net::getLayer(LayerId layerId)
|
||||
{
|
||||
LayerData &ld = impl->getLayerData(layerId);
|
||||
|
||||
@@ -265,8 +265,11 @@ struct ReLUFunctor
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
return slope >= 0 || !INF_ENGINE_VER_MAJOR_EQ(INF_ENGINE_RELEASE_2019R1);
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE ||
|
||||
backendId == DNN_BACKEND_VKCOM;
|
||||
}
|
||||
|
||||
@@ -793,8 +796,11 @@ struct AbsValFunctor
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE;
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
return !INF_ENGINE_VER_MAJOR_EQ(INF_ENGINE_RELEASE_2019R1);
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE;
|
||||
}
|
||||
|
||||
void apply(const float* srcptr, float* dstptr, int len, size_t planeSize, int cn0, int cn1) const
|
||||
|
||||
@@ -159,8 +159,8 @@ public:
|
||||
InferenceEngine::Builder::Layer ieLayer(name);
|
||||
ieLayer.setName(name);
|
||||
ieLayer.setType("Flatten");
|
||||
ieLayer.getParameters()["axis"] = _startAxis;
|
||||
ieLayer.getParameters()["end_axis"] = _endAxis;
|
||||
ieLayer.getParameters()["axis"] = (size_t)_startAxis;
|
||||
ieLayer.getParameters()["end_axis"] = _endAxis; // Do not cast to size_t because it might be negative.
|
||||
ieLayer.setInputPorts(std::vector<InferenceEngine::Port>(1));
|
||||
ieLayer.setOutputPorts(std::vector<InferenceEngine::Port>(1));
|
||||
return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
|
||||
|
||||
@@ -12,6 +12,7 @@ Implementation of padding layer, which adds paddings to input blob.
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace cv
|
||||
@@ -68,28 +69,36 @@ public:
|
||||
|
||||
// Compute dstRanges.
|
||||
const MatSize& inpShape = inputs[0].size;
|
||||
dstRanges.resize(paddings.size());
|
||||
|
||||
int offset = 0;
|
||||
if (inputDims != -1 && inputs[0].dims != inputDims)
|
||||
{
|
||||
dstRanges.insert(dstRanges.begin(), Range::all());
|
||||
offset = 1;
|
||||
paddings.insert(paddings.begin(), std::make_pair(0, 0));
|
||||
}
|
||||
|
||||
dstRanges.resize(paddings.size());
|
||||
for (int i = 0; i < paddings.size(); ++i)
|
||||
{
|
||||
dstRanges[offset + i].start = paddings[i].first;
|
||||
dstRanges[offset + i].end = paddings[i].first + inpShape[offset + i];
|
||||
dstRanges[i].start = paddings[i].first;
|
||||
dstRanges[i].end = paddings[i].first + inpShape[i];
|
||||
}
|
||||
|
||||
// Add the rest of dimensions.
|
||||
for (int i = dstRanges.size(); i < inputs[0].dims; ++i)
|
||||
{
|
||||
dstRanges.push_back(Range::all());
|
||||
paddings.push_back(std::make_pair(0, 0));
|
||||
}
|
||||
inputDims = -1; // Next time paddings are filled for all the dimensions.
|
||||
}
|
||||
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
return INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1) &&
|
||||
(preferableTarget != DNN_TARGET_MYRIAD ||
|
||||
(dstRanges.size() == 4 && paddings[0].first == 0 && paddings[0].second == 0));
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && dstRanges.size() == 4);
|
||||
}
|
||||
@@ -109,7 +118,7 @@ public:
|
||||
{
|
||||
std::vector<float> paddingValue_fp32(1, paddingValue);
|
||||
std::vector<int16_t> paddingValue_fp16(1);
|
||||
convertFp16(paddingValue_fp32, paddingValue_fp16);
|
||||
cv::convertFp16(paddingValue_fp32, paddingValue_fp16);
|
||||
outputs[0].setTo(paddingValue_fp16[0]);
|
||||
}
|
||||
else
|
||||
@@ -173,6 +182,32 @@ public:
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> >&) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
InferenceEngine::Builder::Layer ieLayer(name);
|
||||
ieLayer.setName(name);
|
||||
ieLayer.setType("Pad");
|
||||
|
||||
std::vector<int> begins(paddings.size(), 0), ends(paddings.size(), 0);
|
||||
for (int i = 0; i < paddings.size(); ++i)
|
||||
{
|
||||
begins[i] = paddings[i].first;
|
||||
ends[i] = paddings[i].second;
|
||||
}
|
||||
ieLayer.getParameters()["pads_begin"] = begins;
|
||||
ieLayer.getParameters()["pads_end"] = ends;
|
||||
ieLayer.getParameters()["pad_mode"] = paddingType;
|
||||
if (paddingType == "constant")
|
||||
ieLayer.getParameters()["pad_value"] = paddingValue;
|
||||
|
||||
ieLayer.setInputPorts(std::vector<InferenceEngine::Port>(1));
|
||||
ieLayer.setOutputPorts(std::vector<InferenceEngine::Port>(1));
|
||||
return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
|
||||
#endif
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<int, int> > paddings; // Pairs pad before, pad after.
|
||||
std::vector<Range> dstRanges;
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
#ifdef HAVE_OPENCL
|
||||
poolOp.release();
|
||||
#endif
|
||||
computeMaxIdx = type == MAX;
|
||||
computeMaxIdx = type == MAX && outputs.size() == 2;
|
||||
}
|
||||
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
|
||||
@@ -1509,8 +1509,8 @@ void TFImporter::populateNet(Net dstNet)
|
||||
if (layerParams.blobs.size() == 2)
|
||||
CV_Error(Error::StsNotImplemented, "Cannot determine number "
|
||||
"of parameters for batch normalization layer.");
|
||||
mean = Mat::zeros(1, layerParams.blobs[3].total(), CV_32F);
|
||||
std = Mat::ones(1, layerParams.blobs[3].total(), CV_32F);
|
||||
mean = Mat::zeros(1, layerParams.blobs[2].total(), CV_32F);
|
||||
std = Mat::ones(1, layerParams.blobs[2].total(), CV_32F);
|
||||
|
||||
// Add an extra layer: Mean-Variance normalization
|
||||
LayerParams mvnParams;
|
||||
|
||||
@@ -98,6 +98,7 @@ public:
|
||||
|
||||
TEST_P(DNNTestNetwork, AlexNet)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_1GB);
|
||||
processNet("dnn/bvlc_alexnet.caffemodel", "dnn/bvlc_alexnet.prototxt",
|
||||
Size(227, 227), "prob",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_alexnet.yml" :
|
||||
@@ -106,6 +107,7 @@ TEST_P(DNNTestNetwork, AlexNet)
|
||||
|
||||
TEST_P(DNNTestNetwork, ResNet_50)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
processNet("dnn/ResNet-50-model.caffemodel", "dnn/ResNet-50-deploy.prototxt",
|
||||
Size(224, 224), "prob",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_resnet_50.yml" :
|
||||
@@ -122,12 +124,14 @@ TEST_P(DNNTestNetwork, SqueezeNet_v1_1)
|
||||
|
||||
TEST_P(DNNTestNetwork, GoogLeNet)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
processNet("dnn/bvlc_googlenet.caffemodel", "dnn/bvlc_googlenet.prototxt",
|
||||
Size(224, 224), "prob");
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, Inception_5h)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
double l1 = default_l1, lInf = default_lInf;
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_CPU || target == DNN_TARGET_OPENCL))
|
||||
{
|
||||
@@ -142,6 +146,7 @@ TEST_P(DNNTestNetwork, Inception_5h)
|
||||
|
||||
TEST_P(DNNTestNetwork, ENet)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE) ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
@@ -153,6 +158,7 @@ TEST_P(DNNTestNetwork, ENet)
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
@@ -184,6 +190,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe_Different_Width_Height)
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
@@ -214,6 +221,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height)
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
@@ -226,6 +234,8 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
|
||||
|
||||
TEST_P(DNNTestNetwork, SSD_VGG16)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
if (backend == DNN_BACKEND_HALIDE && target == DNN_TARGET_CPU)
|
||||
throw SkipTestException("");
|
||||
double scoreThreshold = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0325 : 0.0;
|
||||
@@ -238,6 +248,8 @@ TEST_P(DNNTestNetwork, SSD_VGG16)
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_coco)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
@@ -254,6 +266,8 @@ TEST_P(DNNTestNetwork, OpenPose_pose_coco)
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
@@ -270,6 +284,7 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_MEMORY_1GB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
@@ -289,12 +304,7 @@ TEST_P(DNNTestNetwork, OpenFace)
|
||||
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#elif INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX target");
|
||||
#else
|
||||
#elif INF_ENGINE_VER_MAJOR_EQ(2018030000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("Test has been fixed in OpenVINO 2018R4");
|
||||
#endif
|
||||
@@ -318,6 +328,7 @@ TEST_P(DNNTestNetwork, opencv_face_detector)
|
||||
|
||||
TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
@@ -335,6 +346,7 @@ TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
|
||||
TEST_P(DNNTestNetwork, DenseNet_121)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
// Reference output values are in range [-3.807, 4.605]
|
||||
|
||||
@@ -112,6 +112,8 @@ TEST(Test_Caffe, read_googlenet)
|
||||
typedef testing::TestWithParam<tuple<bool, Target> > Reproducibility_AlexNet;
|
||||
TEST_P(Reproducibility_AlexNet, Accuracy)
|
||||
{
|
||||
Target targetId = get<1>(GetParam());
|
||||
applyTestTag(targetId == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
bool readFromMemory = get<0>(GetParam());
|
||||
Net net;
|
||||
{
|
||||
@@ -132,7 +134,6 @@ TEST_P(Reproducibility_AlexNet, Accuracy)
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
int targetId = get<1>(GetParam());
|
||||
const float l1 = 1e-5;
|
||||
const float lInf = (targetId == DNN_TARGET_OPENCL_FP16) ? 3e-3 : 1e-4;
|
||||
|
||||
@@ -151,9 +152,9 @@ TEST_P(Reproducibility_AlexNet, Accuracy)
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_AlexNet, Combine(testing::Bool(),
|
||||
Values(DNN_TARGET_CPU, DNN_TARGET_OPENCL, DNN_TARGET_OPENCL_FP16)));
|
||||
|
||||
#if !defined(_WIN32) || defined(_WIN64)
|
||||
TEST(Reproducibility_FCN, Accuracy)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_MEMORY_2GB);
|
||||
Net net;
|
||||
{
|
||||
const string proto = findDataFile("dnn/fcn8s-heavy-pascal.prototxt", false);
|
||||
@@ -179,10 +180,10 @@ TEST(Reproducibility_FCN, Accuracy)
|
||||
|
||||
normAssert(ref, out);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Reproducibility_SSD, Accuracy)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
Net net;
|
||||
{
|
||||
const string proto = findDataFile("dnn/ssd_vgg16.prototxt", false);
|
||||
@@ -264,10 +265,11 @@ INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_MobileNet_SSD,
|
||||
typedef testing::TestWithParam<Target> Reproducibility_ResNet50;
|
||||
TEST_P(Reproducibility_ResNet50, Accuracy)
|
||||
{
|
||||
Target targetId = GetParam();
|
||||
applyTestTag(targetId == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
Net net = readNetFromCaffe(findDataFile("dnn/ResNet-50-deploy.prototxt", false),
|
||||
findDataFile("dnn/ResNet-50-model.caffemodel", false));
|
||||
|
||||
int targetId = GetParam();
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
@@ -330,6 +332,7 @@ INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_SqueezeNet_v1_1,
|
||||
|
||||
TEST(Reproducibility_AlexNet_fp16, Accuracy)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
const float l1 = 1e-5;
|
||||
const float lInf = 3e-3;
|
||||
|
||||
@@ -375,6 +378,7 @@ TEST(Reproducibility_GoogLeNet_fp16, Accuracy)
|
||||
// https://github.com/richzhang/colorization
|
||||
TEST_P(Test_Caffe_nets, Colorization)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
checkBackend();
|
||||
|
||||
Mat inp = blobFromNPY(_tf("colorization_inp.npy"));
|
||||
@@ -405,6 +409,7 @@ TEST_P(Test_Caffe_nets, Colorization)
|
||||
|
||||
TEST_P(Test_Caffe_nets, DenseNet_121)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
checkBackend();
|
||||
const string proto = findDataFile("dnn/DenseNet_121.prototxt", false);
|
||||
const string model = findDataFile("dnn/DenseNet_121.caffemodel", false);
|
||||
@@ -520,6 +525,8 @@ INSTANTIATE_TEST_CASE_P(Test_Caffe, opencv_face_detector,
|
||||
|
||||
TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("Test is disabled for DLIE OpenCL targets"); // very slow
|
||||
@@ -536,6 +543,7 @@ TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
|
||||
|
||||
TEST_P(Test_Caffe_nets, FasterRCNN_zf)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16) ||
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
@@ -547,6 +555,7 @@ TEST_P(Test_Caffe_nets, FasterRCNN_zf)
|
||||
|
||||
TEST_P(Test_Caffe_nets, RFCN)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_2GB));
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16) ||
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
|
||||
@@ -78,6 +78,7 @@ TEST(Test_Darknet, read_yolo_voc)
|
||||
|
||||
TEST(Test_Darknet, read_yolo_voc_stream)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_1GB);
|
||||
Mat ref;
|
||||
Mat sample = imread(_tf("dog416.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0/255, Size(416, 416), Scalar(), true, false);
|
||||
@@ -267,6 +268,8 @@ public:
|
||||
|
||||
TEST_P(Test_Darknet_nets, YoloVoc)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_MEMORY_1GB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("Test is disabled");
|
||||
@@ -305,6 +308,8 @@ TEST_P(Test_Darknet_nets, YoloVoc)
|
||||
|
||||
TEST_P(Test_Darknet_nets, TinyYoloVoc)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
@@ -339,6 +344,8 @@ TEST_P(Test_Darknet_nets, TinyYoloVoc)
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv3)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
|
||||
@@ -561,12 +561,6 @@ TEST_P(ReLU, Accuracy)
|
||||
float negativeSlope = get<0>(GetParam());
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE
|
||||
&& negativeSlope < 0
|
||||
)
|
||||
throw SkipTestException("Test is disabled");
|
||||
#endif
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("negative_slope", negativeSlope);
|
||||
@@ -589,13 +583,6 @@ TEST_P(NoParamActivation, Accuracy)
|
||||
LayerParams lp;
|
||||
lp.type = get<0>(GetParam());
|
||||
lp.name = "testLayer";
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE
|
||||
&& lp.type == "AbsVal"
|
||||
)
|
||||
throw SkipTestException("Test is disabled");
|
||||
#endif
|
||||
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, NoParamActivation, Combine(
|
||||
|
||||
@@ -217,6 +217,7 @@ INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_ONNX_layers, dnnBackendsAndTargets());
|
||||
class Test_ONNX_nets : public Test_ONNX_layers {};
|
||||
TEST_P(Test_ONNX_nets, Alexnet)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
const String model = _tf("models/alexnet.onnx");
|
||||
|
||||
Net net = readNetFromONNX(model);
|
||||
@@ -270,31 +271,30 @@ TEST_P(Test_ONNX_nets, Googlenet)
|
||||
|
||||
TEST_P(Test_ONNX_nets, CaffeNet)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
testONNXModels("caffenet", pb);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, RCNN_ILSVRC13)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
|
||||
// Reference output values are in range [-4.992, -1.161]
|
||||
testONNXModels("rcnn_ilsvrc13", pb, 0.0045);
|
||||
}
|
||||
|
||||
#ifdef OPENCV_32BIT_CONFIGURATION
|
||||
TEST_P(Test_ONNX_nets, DISABLED_VGG16) // memory usage >2Gb
|
||||
#else
|
||||
TEST_P(Test_ONNX_nets, VGG16)
|
||||
#endif
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_6GB); // > 2.3Gb
|
||||
|
||||
// output range: [-69; 72], after Softmax [0; 0.96]
|
||||
testONNXModels("vgg16", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
#ifdef OPENCV_32BIT_CONFIGURATION
|
||||
TEST_P(Test_ONNX_nets, DISABLED_VGG16_bn) // memory usage >2Gb
|
||||
#else
|
||||
TEST_P(Test_ONNX_nets, VGG16_bn)
|
||||
#endif
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_6GB); // > 2.3Gb
|
||||
|
||||
// output range: [-16; 27], after Softmax [0; 0.67]
|
||||
const double lInf = (target == DNN_TARGET_MYRIAD) ? 0.038 : default_lInf;
|
||||
testONNXModels("vgg16-bn", pb, default_l1, lInf, true);
|
||||
@@ -302,23 +302,30 @@ TEST_P(Test_ONNX_nets, VGG16_bn)
|
||||
|
||||
TEST_P(Test_ONNX_nets, ZFNet)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
testONNXModels("zfnet512", pb);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, ResNet18v1)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
// output range: [-16; 22], after Softmax [0, 0.51]
|
||||
testONNXModels("resnet18v1", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, ResNet50v1)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
// output range: [-67; 75], after Softmax [0, 0.98]
|
||||
testONNXModels("resnet50v1", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, ResNet101_DUC_HDC)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_VERYLONG);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE targets");
|
||||
@@ -334,6 +341,8 @@ TEST_P(Test_ONNX_nets, ResNet101_DUC_HDC)
|
||||
|
||||
TEST_P(Test_ONNX_nets, TinyYolov2)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
if (cvtest::skipUnstableTests)
|
||||
throw SkipTestException("Skip unstable test");
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
@@ -347,6 +356,7 @@ TEST_P(Test_ONNX_nets, TinyYolov2)
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
|
||||
// output range: [-11; 8]
|
||||
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.017 : default_l1;
|
||||
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.14 : default_lInf;
|
||||
@@ -367,6 +377,7 @@ TEST_P(Test_ONNX_nets, MobileNet_v2)
|
||||
|
||||
TEST_P(Test_ONNX_nets, LResNet100E_IR)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
|
||||
(target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_OPENCL || target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
@@ -379,7 +390,7 @@ TEST_P(Test_ONNX_nets, LResNet100E_IR)
|
||||
lInf = 0.035;
|
||||
}
|
||||
else if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_CPU) {
|
||||
l1 = 4.5e-5;
|
||||
l1 = 4.6e-5;
|
||||
lInf = 1.9e-4;
|
||||
}
|
||||
testONNXModels("LResNet100E_IR", pb, l1, lInf);
|
||||
@@ -419,6 +430,8 @@ TEST_P(Test_ONNX_nets, Inception_v2)
|
||||
|
||||
TEST_P(Test_ONNX_nets, DenseNet121)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
// output range: [-87; 138], after Softmax [0; 1]
|
||||
testONNXModels("densenet121", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
@@ -140,10 +140,6 @@ TEST_P(Test_TensorFlow_layers, padding)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, padding_same)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
@@ -251,10 +247,6 @@ TEST_P(Test_TensorFlow_layers, reshape)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, flatten)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
|
||||
@@ -267,11 +259,6 @@ TEST_P(Test_TensorFlow_layers, flatten)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, unfused_flatten)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
|
||||
runTensorFlowNet("unfused_flatten");
|
||||
runTensorFlowNet("unfused_flatten_unknown_batch");
|
||||
}
|
||||
@@ -320,11 +307,14 @@ class Test_TensorFlow_nets : public DNNTestLayer {};
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
|
||||
{
|
||||
checkBackend();
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
|
||||
checkBackend();
|
||||
std::string netPath = findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false);
|
||||
std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt", false);
|
||||
std::string imgPath = findDataFile("dnn/street.png", false);
|
||||
@@ -333,34 +323,24 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
|
||||
resize(imread(imgPath), inp, Size(300, 300));
|
||||
inp = blobFromImage(inp, 1.0f / 127.5, Size(), Scalar(127.5, 127.5, 127.5), true);
|
||||
|
||||
std::vector<String> outNames(3);
|
||||
outNames[0] = "concat";
|
||||
outNames[1] = "concat_1";
|
||||
outNames[2] = "detection_out";
|
||||
|
||||
std::vector<Mat> refs(outNames.size());
|
||||
for (int i = 0; i < outNames.size(); ++i)
|
||||
{
|
||||
std::string path = findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco." + outNames[i] + ".npy", false);
|
||||
refs[i] = blobFromNPY(path);
|
||||
}
|
||||
Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco.detection_out.npy", false));
|
||||
|
||||
Net net = readNetFromTensorflow(netPath, netConfig);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
net.setInput(inp);
|
||||
Mat out = net.forward();
|
||||
|
||||
std::vector<Mat> output;
|
||||
net.forward(output, outNames);
|
||||
|
||||
normAssert(refs[0].reshape(1, 1), output[0].reshape(1, 1), "", 1e-5, 1.5e-4);
|
||||
normAssert(refs[1].reshape(1, 1), output[1].reshape(1, 1), "", 1e-5, 3e-4);
|
||||
normAssertDetections(refs[2], output[2], "", 0.2);
|
||||
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0043 : default_l1;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.037 : default_lInf;
|
||||
normAssertDetections(ref, out, "", 0.2, scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
@@ -426,6 +406,7 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD)
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, Faster_RCNN)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB)); // FIXIT split test
|
||||
static std::string names[] = {"faster_rcnn_inception_v2_coco_2018_01_28",
|
||||
"faster_rcnn_resnet50_coco_2018_01_28"};
|
||||
|
||||
@@ -521,6 +502,8 @@ TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
|
||||
// np.save('east_text_detection.geometry.npy', geometry)
|
||||
TEST_P(Test_TensorFlow_nets, EAST_text_detection)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
@@ -597,10 +580,6 @@ TEST_P(Test_TensorFlow_layers, fp16_weights)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, fp16_padding_same)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
@@ -695,6 +674,7 @@ TEST(Test_TensorFlow, two_inputs)
|
||||
|
||||
TEST(Test_TensorFlow, Mask_RCNN)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_1GB);
|
||||
std::string proto = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt", false);
|
||||
std::string model = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pb", false);
|
||||
|
||||
|
||||
@@ -345,6 +345,7 @@ static void normAssertSegmentation(const Mat& ref, const Mat& test)
|
||||
|
||||
TEST_P(Test_Torch_nets, ENet_accuracy)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
checkBackend();
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
|
||||
Reference in New Issue
Block a user