Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
34f6b054
Commit
34f6b054
authored
Jul 12, 2019
by
Lubov Batanina
Committed by
Alexander Alekhin
Jul 12, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge pull request #14996 from l-bat:ocv_deconv3d
* Support Deconvolution3D on IE backend * Add test tag * Fix tests
parent
8bcd7e12
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
84 additions
and
51 deletions
+84
-51
convolution_layer.cpp
modules/dnn/src/layers/convolution_layer.cpp
+44
-22
layers_common.cpp
modules/dnn/src/layers/layers_common.cpp
+3
-1
layers_common.hpp
modules/dnn/src/layers/layers_common.hpp
+2
-1
onnx_importer.cpp
modules/dnn/src/onnx/onnx_importer.cpp
+22
-27
test_onnx_importer.cpp
modules/dnn/test/test_onnx_importer.cpp
+13
-0
No files found.
modules/dnn/src/layers/convolution_layer.cpp
View file @
34f6b054
...
@@ -67,7 +67,7 @@ public:
...
@@ -67,7 +67,7 @@ public:
BaseConvolutionLayerImpl
(
const
LayerParams
&
params
)
BaseConvolutionLayerImpl
(
const
LayerParams
&
params
)
{
{
setParamsFrom
(
params
);
setParamsFrom
(
params
);
getConvolutionKernelParams
(
params
,
kernel_size
,
pads_begin
,
pads_end
,
strides
,
dilations
,
padMode
);
getConvolutionKernelParams
(
params
,
kernel_size
,
pads_begin
,
pads_end
,
strides
,
dilations
,
padMode
,
adjust_pads
);
numOutput
=
params
.
get
<
int
>
(
"num_output"
);
numOutput
=
params
.
get
<
int
>
(
"num_output"
);
int
ngroups
=
params
.
get
<
int
>
(
"group"
,
1
);
int
ngroups
=
params
.
get
<
int
>
(
"group"
,
1
);
...
@@ -83,14 +83,14 @@ public:
...
@@ -83,14 +83,14 @@ public:
pad
=
Size
(
pads_begin
[
1
],
pads_begin
[
0
]);
pad
=
Size
(
pads_begin
[
1
],
pads_begin
[
0
]);
dilation
=
Size
(
dilations
[
1
],
dilations
[
0
]);
dilation
=
Size
(
dilations
[
1
],
dilations
[
0
]);
adjust_pads
.
push_back
(
params
.
get
<
int
>
(
"adj_h"
,
0
));
adjust_pads
.
push_back
(
params
.
get
<
int
>
(
"adj_w"
,
0
));
adjustPad
.
height
=
adjust_pads
[
0
];
adjustPad
.
height
=
adjust_pads
[
0
];
adjustPad
.
width
=
adjust_pads
[
1
];
adjustPad
.
width
=
adjust_pads
[
1
];
CV_Assert
(
adjustPad
.
width
<
stride
.
width
&&
adjustPad
.
height
<
stride
.
height
);
}
}
for
(
int
i
=
0
;
i
<
adjust_pads
.
size
();
i
++
)
{
CV_Assert
(
adjust_pads
[
i
]
<
strides
[
i
]);
}
fusedWeights
=
false
;
fusedWeights
=
false
;
fusedBias
=
false
;
fusedBias
=
false
;
}
}
...
@@ -1241,29 +1241,39 @@ public:
...
@@ -1241,29 +1241,39 @@ public:
virtual
bool
supportBackend
(
int
backendId
)
CV_OVERRIDE
virtual
bool
supportBackend
(
int
backendId
)
CV_OVERRIDE
{
{
#ifdef HAVE_INF_ENGINE
#ifdef HAVE_INF_ENGINE
const
int
outGroupCn
=
blobs
[
0
].
size
[
1
];
// Weights are in IOHW layout
const
int
outGroupCn
=
blobs
[
0
].
size
[
1
];
// Weights are in IOHW
or IODHW
layout
const
int
group
=
numOutput
/
outGroupCn
;
const
int
group
=
numOutput
/
outGroupCn
;
if
(
backendId
==
DNN_BACKEND_INFERENCE_ENGINE
)
if
(
backendId
==
DNN_BACKEND_INFERENCE_ENGINE
)
{
{
if
(
kernel_size
.
size
()
==
3
)
if
(
kernel_size
.
size
()
==
3
&&
preferableTarget
!=
DNN_TARGET_CPU
)
{
CV_Error
(
Error
::
StsNotImplemented
,
"Unsupported deconvolution3D layer"
);
return
false
;
}
if
(
adjustPad
.
height
||
adjustPad
.
width
)
if
(
std
::
accumulate
(
adjust_pads
.
begin
(),
adjust_pads
.
end
(),
0
,
std
::
plus
<
size_t
>
())
>
0
)
{
{
if
(
padMode
.
empty
())
if
(
padMode
.
empty
())
{
{
if
(
preferableTarget
!=
DNN_TARGET_CPU
&&
group
!=
1
)
if
(
preferableTarget
!=
DNN_TARGET_CPU
&&
group
!=
1
)
{
{
if
((
adjustPad
.
height
&&
pad
.
height
)
||
(
adjustPad
.
width
&&
pad
.
width
))
for
(
int
i
=
0
;
i
<
adjust_pads
.
size
();
i
++
)
{
if
(
adjust_pads
[
i
]
&&
pads_begin
[
i
])
return
false
;
}
}
for
(
int
i
=
0
;
i
<
adjust_pads
.
size
();
i
++
)
{
if
(
pads_end
[
i
]
<
adjust_pads
[
i
])
return
false
;
return
false
;
}
}
return
pad
.
width
>=
adjustPad
.
width
&&
pad
.
height
>=
adjustPad
.
height
;
return
true
;
}
}
else
if
(
padMode
==
"SAME"
)
else
if
(
padMode
==
"SAME"
)
{
{
return
kernel
.
width
>=
pad
.
width
+
1
+
adjustPad
.
width
&&
for
(
int
i
=
0
;
i
<
adjust_pads
.
size
();
i
++
)
{
kernel
.
height
>=
pad
.
height
+
1
+
adjustPad
.
height
;
if
(
kernel_size
[
i
]
<
pads_begin
[
i
]
+
1
+
adjust_pads
[
i
])
return
false
;
}
return
true
;
}
}
else
if
(
padMode
==
"VALID"
)
else
if
(
padMode
==
"VALID"
)
return
false
;
return
false
;
...
@@ -1274,7 +1284,7 @@ public:
...
@@ -1274,7 +1284,7 @@ public:
return
preferableTarget
==
DNN_TARGET_CPU
;
return
preferableTarget
==
DNN_TARGET_CPU
;
}
}
if
(
preferableTarget
==
DNN_TARGET_OPENCL
||
preferableTarget
==
DNN_TARGET_OPENCL_FP16
)
if
(
preferableTarget
==
DNN_TARGET_OPENCL
||
preferableTarget
==
DNN_TARGET_OPENCL_FP16
)
return
dilation
.
width
==
1
&&
dilation
.
height
==
1
;
return
std
::
accumulate
(
dilations
.
begin
(),
dilations
.
end
(),
1
,
std
::
multiplies
<
size_t
>
())
==
1
;
return
true
;
return
true
;
}
}
else
else
...
@@ -1861,11 +1871,14 @@ public:
...
@@ -1861,11 +1871,14 @@ public:
#ifdef HAVE_INF_ENGINE
#ifdef HAVE_INF_ENGINE
virtual
Ptr
<
BackendNode
>
initInfEngine
(
const
std
::
vector
<
Ptr
<
BackendWrapper
>
>
&
)
CV_OVERRIDE
virtual
Ptr
<
BackendNode
>
initInfEngine
(
const
std
::
vector
<
Ptr
<
BackendWrapper
>
>
&
)
CV_OVERRIDE
{
{
auto
ieWeights
=
wrapToInfEngineBlob
(
blobs
[
0
],
InferenceEngine
::
Layout
::
OIHW
);
InferenceEngine
::
Layout
layout
=
blobs
[
0
].
dims
==
5
?
InferenceEngine
::
Layout
::
NCDHW
:
InferenceEngine
::
Layout
::
OIHW
;
auto
ieWeights
=
wrapToInfEngineBlob
(
blobs
[
0
],
layout
);
if
(
fusedWeights
)
if
(
fusedWeights
)
{
{
ieWeights
=
InferenceEngine
::
make_shared_blob
<
float
>
(
ieWeights
=
InferenceEngine
::
make_shared_blob
<
float
>
(
InferenceEngine
::
Precision
::
FP32
,
InferenceEngine
::
Layout
::
OIHW
,
InferenceEngine
::
Precision
::
FP32
,
layout
,
ieWeights
->
dims
());
ieWeights
->
dims
());
ieWeights
->
allocate
();
ieWeights
->
allocate
();
...
@@ -1874,7 +1887,7 @@ public:
...
@@ -1874,7 +1887,7 @@ public:
transpose
(
weightsMat
,
newWeights
);
transpose
(
weightsMat
,
newWeights
);
}
}
const
int
outGroupCn
=
blobs
[
0
].
size
[
1
];
// Weights are in IOHW layout
const
int
outGroupCn
=
blobs
[
0
].
size
[
1
];
// Weights are in IOHW
or OIDHW
layout
const
int
group
=
numOutput
/
outGroupCn
;
const
int
group
=
numOutput
/
outGroupCn
;
InferenceEngine
::
Builder
::
DeconvolutionLayer
ieLayer
(
name
);
InferenceEngine
::
Builder
::
DeconvolutionLayer
ieLayer
(
name
);
...
@@ -1886,12 +1899,19 @@ public:
...
@@ -1886,12 +1899,19 @@ public:
if
(
padMode
.
empty
())
if
(
padMode
.
empty
())
{
{
ieLayer
.
setPaddingsEnd
({
pads_end
[
0
]
-
adjust_pads
[
0
],
pads_end
[
1
]
-
adjust_pads
[
1
]});
std
::
vector
<
size_t
>
paddings_end
;
for
(
int
i
=
0
;
i
<
pads_end
.
size
();
i
++
)
{
paddings_end
.
push_back
(
pads_end
[
i
]
-
adjust_pads
[
i
]);
}
ieLayer
.
setPaddingsEnd
(
paddings_end
);
}
}
else
if
(
padMode
==
"SAME"
)
else
if
(
padMode
==
"SAME"
)
{
{
ieLayer
.
setPaddingsEnd
({
kernel_size
[
0
]
-
pads_begin
[
0
]
-
1
-
adjust_pads
[
0
],
std
::
vector
<
size_t
>
paddings_end
;
kernel_size
[
1
]
-
pads_begin
[
1
]
-
1
-
adjust_pads
[
1
]});
for
(
int
i
=
0
;
i
<
pads_begin
.
size
();
i
++
)
{
paddings_end
.
push_back
(
kernel_size
[
i
]
-
pads_begin
[
i
]
-
1
-
adjust_pads
[
i
]);
}
ieLayer
.
setPaddingsEnd
(
paddings_end
);
}
}
ieLayer
.
setGroup
((
size_t
)
group
);
ieLayer
.
setGroup
((
size_t
)
group
);
ieLayer
.
setOutDepth
((
size_t
)
numOutput
);
ieLayer
.
setOutDepth
((
size_t
)
numOutput
);
...
@@ -1911,10 +1931,12 @@ public:
...
@@ -1911,10 +1931,12 @@ public:
float
flops
=
0
;
float
flops
=
0
;
int
outChannels
=
blobs
[
0
].
size
[
0
];
int
outChannels
=
blobs
[
0
].
size
[
0
];
size_t
karea
=
std
::
accumulate
(
kernel_size
.
begin
(),
kernel_size
.
end
(),
1
,
std
::
multiplies
<
size_t
>
());
for
(
int
i
=
0
;
i
<
inputs
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
{
flops
+=
CV_BIG_INT
(
2
)
*
outChannels
*
k
ernel
.
area
()
*
total
(
inputs
[
i
]);
flops
+=
CV_BIG_INT
(
2
)
*
outChannels
*
k
area
*
total
(
inputs
[
i
]);
}
}
return
flops
;
return
flops
;
...
...
modules/dnn/src/layers/layers_common.cpp
View file @
34f6b054
...
@@ -175,11 +175,13 @@ void getPoolingKernelParams(const LayerParams ¶ms, std::vector<size_t>& kern
...
@@ -175,11 +175,13 @@ void getPoolingKernelParams(const LayerParams ¶ms, std::vector<size_t>& kern
}
}
void
getConvolutionKernelParams
(
const
LayerParams
&
params
,
std
::
vector
<
size_t
>&
kernel
,
std
::
vector
<
size_t
>&
pads_begin
,
void
getConvolutionKernelParams
(
const
LayerParams
&
params
,
std
::
vector
<
size_t
>&
kernel
,
std
::
vector
<
size_t
>&
pads_begin
,
std
::
vector
<
size_t
>&
pads_end
,
std
::
vector
<
size_t
>&
strides
,
std
::
vector
<
size_t
>&
dilations
,
cv
::
String
&
padMode
)
std
::
vector
<
size_t
>&
pads_end
,
std
::
vector
<
size_t
>&
strides
,
std
::
vector
<
size_t
>&
dilations
,
cv
::
String
&
padMode
,
std
::
vector
<
size_t
>&
adjust_pads
)
{
{
util
::
getKernelSize
(
params
,
kernel
);
util
::
getKernelSize
(
params
,
kernel
);
util
::
getStrideAndPadding
(
params
,
pads_begin
,
pads_end
,
strides
,
padMode
,
kernel
.
size
());
util
::
getStrideAndPadding
(
params
,
pads_begin
,
pads_end
,
strides
,
padMode
,
kernel
.
size
());
util
::
getParameter
(
params
,
"dilation"
,
"dilation"
,
dilations
,
true
,
std
::
vector
<
size_t
>
(
kernel
.
size
(),
1
));
util
::
getParameter
(
params
,
"dilation"
,
"dilation"
,
dilations
,
true
,
std
::
vector
<
size_t
>
(
kernel
.
size
(),
1
));
util
::
getParameter
(
params
,
"adj"
,
"adj"
,
adjust_pads
,
true
,
std
::
vector
<
size_t
>
(
kernel
.
size
(),
0
));
for
(
int
i
=
0
;
i
<
dilations
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
dilations
.
size
();
i
++
)
CV_Assert
(
dilations
[
i
]
>
0
);
CV_Assert
(
dilations
[
i
]
>
0
);
...
...
modules/dnn/src/layers/layers_common.hpp
View file @
34f6b054
...
@@ -60,7 +60,8 @@ namespace cv
...
@@ -60,7 +60,8 @@ namespace cv
namespace
dnn
namespace
dnn
{
{
void
getConvolutionKernelParams
(
const
LayerParams
&
params
,
std
::
vector
<
size_t
>&
kernel
,
std
::
vector
<
size_t
>&
pads_begin
,
void
getConvolutionKernelParams
(
const
LayerParams
&
params
,
std
::
vector
<
size_t
>&
kernel
,
std
::
vector
<
size_t
>&
pads_begin
,
std
::
vector
<
size_t
>&
pads_end
,
std
::
vector
<
size_t
>&
strides
,
std
::
vector
<
size_t
>&
dilations
,
cv
::
String
&
padMode
);
std
::
vector
<
size_t
>&
pads_end
,
std
::
vector
<
size_t
>&
strides
,
std
::
vector
<
size_t
>&
dilations
,
cv
::
String
&
padMode
,
std
::
vector
<
size_t
>&
adjust_pads
);
void
getPoolingKernelParams
(
const
LayerParams
&
params
,
std
::
vector
<
size_t
>&
kernel
,
bool
&
globalPooling
,
void
getPoolingKernelParams
(
const
LayerParams
&
params
,
std
::
vector
<
size_t
>&
kernel
,
bool
&
globalPooling
,
std
::
vector
<
size_t
>&
pads_begin
,
std
::
vector
<
size_t
>&
pads_end
,
std
::
vector
<
size_t
>&
strides
,
cv
::
String
&
padMode
);
std
::
vector
<
size_t
>&
pads_begin
,
std
::
vector
<
size_t
>&
pads_end
,
std
::
vector
<
size_t
>&
strides
,
cv
::
String
&
padMode
);
...
...
modules/dnn/src/onnx/onnx_importer.cpp
View file @
34f6b054
...
@@ -682,42 +682,37 @@ void ONNXImporter::populateNet(Net dstNet)
...
@@ -682,42 +682,37 @@ void ONNXImporter::populateNet(Net dstNet)
layerParams
.
set
(
"num_output"
,
layerParams
.
blobs
[
0
].
size
[
1
]
*
layerParams
.
get
<
int
>
(
"group"
,
1
));
layerParams
.
set
(
"num_output"
,
layerParams
.
blobs
[
0
].
size
[
1
]
*
layerParams
.
get
<
int
>
(
"group"
,
1
));
layerParams
.
set
(
"bias_term"
,
node_proto
.
input_size
()
==
3
);
layerParams
.
set
(
"bias_term"
,
node_proto
.
input_size
()
==
3
);
if
(
!
layerParams
.
has
(
"kernel_size"
))
CV_Error
(
Error
::
StsNotImplemented
,
"Required attribute 'kernel_size' is not present."
);
if
(
layerParams
.
has
(
"output_shape"
))
if
(
layerParams
.
has
(
"output_shape"
))
{
{
const
DictValue
&
outShape
=
layerParams
.
get
(
"output_shape"
);
const
DictValue
&
outShape
=
layerParams
.
get
(
"output_shape"
);
DictValue
strides
=
layerParams
.
get
(
"stride"
);
DictValue
kernel
=
layerParams
.
get
(
"kernel_size"
);
if
(
outShape
.
size
()
!=
4
)
String
padMode
;
CV_Error
(
Error
::
StsNotImplemented
,
"Output shape must have 4 elements."
);
std
::
vector
<
int
>
adjust_pads
;
if
(
layerParams
.
has
(
"pad_mode"
))
DictValue
stride
=
layerParams
.
get
(
"stride"
);
const
int
strideY
=
stride
.
getIntValue
(
0
);
const
int
strideX
=
stride
.
getIntValue
(
1
);
const
int
outH
=
outShape
.
getIntValue
(
2
);
const
int
outW
=
outShape
.
getIntValue
(
3
);
if
(
layerParams
.
get
<
String
>
(
"pad_mode"
)
==
"SAME"
)
{
{
layerParams
.
set
(
"adj_w"
,
(
outW
-
1
)
%
strideX
);
padMode
=
toUpperCase
(
layerParams
.
get
<
String
>
(
"pad_mode"
)
);
layerParams
.
set
(
"adj_h"
,
(
outH
-
1
)
%
strideY
);
if
(
padMode
!=
"SAME"
&&
padMode
!=
"VALID"
)
}
CV_Error
(
Error
::
StsError
,
"Unsupported padding mode "
+
padMode
);
else
if
(
layerParams
.
get
<
String
>
(
"pad_mode"
)
==
"VALID"
)
{
for
(
int
i
=
0
;
i
<
strides
.
size
();
i
++
)
if
(
!
layerParams
.
has
(
"kernel_size"
))
{
CV_Error
(
Error
::
StsNotImplemented
,
int
sz
=
outShape
.
get
<
int
>
(
2
+
i
);
"Required attribute 'kernel_size' is not present."
);
int
stride
=
strides
.
get
<
int
>
(
i
);
adjust_pads
.
push_back
(
padMode
==
"SAME"
?
(
sz
-
1
)
%
stride
:
DictValue
kernel
=
layerParams
.
get
(
"kernel_size"
);
(
sz
-
kernel
.
get
<
int
>
(
i
))
%
stride
);
layerParams
.
set
(
"adj_h"
,
(
outH
-
kernel
.
getIntValue
(
0
))
%
strideY
);
}
layerParams
.
set
(
"adj
_w"
,
(
outW
-
kernel
.
getIntValue
(
1
))
%
strideX
);
layerParams
.
set
(
"adj
"
,
DictValue
::
arrayInt
(
&
adjust_pads
[
0
],
adjust_pads
.
size
())
);
}
}
}
}
else
if
(
layerParams
.
has
(
"output_padding"
))
else
if
(
layerParams
.
has
(
"output_padding"
))
{
{
const
DictValue
&
adj_pad
=
layerParams
.
get
(
"output_padding"
);
replaceLayerParam
(
layerParams
,
"output_padding"
,
"adj"
);
if
(
adj_pad
.
size
()
!=
2
)
CV_Error
(
Error
::
StsNotImplemented
,
"Deconvolution3D layer is not supported"
);
layerParams
.
set
(
"adj_w"
,
adj_pad
.
get
<
int
>
(
1
));
layerParams
.
set
(
"adj_h"
,
adj_pad
.
get
<
int
>
(
0
));
}
}
}
}
else
if
(
layer_type
==
"Transpose"
)
else
if
(
layer_type
==
"Transpose"
)
...
...
modules/dnn/test/test_onnx_importer.cpp
View file @
34f6b054
...
@@ -127,6 +127,19 @@ TEST_P(Test_ONNX_layers, Deconvolution)
...
@@ -127,6 +127,19 @@ TEST_P(Test_ONNX_layers, Deconvolution)
testONNXModels
(
"deconv_adjpad_2d"
,
npy
,
0
,
0
,
false
,
false
);
testONNXModels
(
"deconv_adjpad_2d"
,
npy
,
0
,
0
,
false
,
false
);
}
}
TEST_P
(
Test_ONNX_layers
,
Deconvolution3D
)
{
#if defined(INF_ENGINE_RELEASE)
applyTestTag
(
CV_TEST_TAG_DNN_SKIP_IE_2018R5
);
#endif
if
(
backend
!=
DNN_BACKEND_INFERENCE_ENGINE
||
target
!=
DNN_TARGET_CPU
)
throw
SkipTestException
(
"Only DLIE backend on CPU is supported"
);
testONNXModels
(
"deconv3d"
);
testONNXModels
(
"deconv3d_bias"
);
testONNXModels
(
"deconv3d_pad"
);
testONNXModels
(
"deconv3d_adjpad"
);
}
TEST_P
(
Test_ONNX_layers
,
Dropout
)
TEST_P
(
Test_ONNX_layers
,
Dropout
)
{
{
testONNXModels
(
"dropout"
);
testONNXModels
(
"dropout"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment