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
68cc2e29
Commit
68cc2e29
authored
7 years ago
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9734 from dkurt:fix_deconv_layer_kernel_layout
parents
45365e4d
6e593cd1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
39 additions
and
48 deletions
+39
-48
all_layers.hpp
modules/dnn/include/opencv2/dnn/all_layers.hpp
+1
-0
convolution_layer.cpp
modules/dnn/src/layers/convolution_layer.cpp
+34
-39
tf_importer.cpp
modules/dnn/src/tensorflow/tf_importer.cpp
+1
-3
torch_importer.cpp
modules/dnn/src/torch/torch_importer.cpp
+1
-4
test_halide_layers.cpp
modules/dnn/test/test_halide_layers.cpp
+2
-2
No files found.
modules/dnn/include/opencv2/dnn/all_layers.hpp
View file @
68cc2e29
...
...
@@ -199,6 +199,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
public
:
Size
kernel
,
stride
,
pad
,
dilation
,
adjustPad
;
String
padMode
;
int
numOutput
;
};
class
CV_EXPORTS
ConvolutionLayer
:
public
BaseConvolutionLayer
...
...
This diff is collapsed.
Click to expand it.
modules/dnn/src/layers/convolution_layer.cpp
View file @
68cc2e29
...
...
@@ -252,24 +252,13 @@ public:
}
Halide
::
RDom
r
(
0
,
kernel
.
width
,
0
,
kernel
.
height
,
0
,
inpGroupCn
);
Halide
::
Expr
kx
=
x
*
stride
.
width
-
pad
.
width
+
r
.
x
*
dilation
.
width
;
Halide
::
Expr
ky
=
y
*
stride
.
height
-
pad
.
height
+
r
.
y
*
dilation
.
height
;
Halide
::
Expr
kc
=
r
.
z
;
if
(
group
>
1
)
for
(
int
i
=
1
;
i
<
group
;
++
i
)
{
int
outCnBound
=
outGroupCn
;
int
inpChBound
=
inpGroupCn
;
Halide
::
Expr
shift
=
select
(
c
<
outCnBound
,
0
,
inpChBound
);
for
(
int
i
=
2
;
i
<
group
;
++
i
)
{
outCnBound
+=
outGroupCn
;
inpChBound
+=
inpGroupCn
;
shift
=
select
(
c
<
outCnBound
,
shift
,
inpChBound
);
}
kc
+=
shift
;
kc
=
select
(
c
<
outGroupCn
*
i
,
kc
,
inpGroupCn
*
i
+
r
.
z
);
}
Halide
::
Expr
kx
=
x
*
stride
.
width
-
pad
.
width
+
r
.
x
*
dilation
.
width
;
Halide
::
Expr
ky
=
y
*
stride
.
height
-
pad
.
height
+
r
.
y
*
dilation
.
height
;
Halide
::
Expr
topExpr
=
sum
(
padded_input
(
kx
,
ky
,
kc
,
n
)
*
weights
(
r
.
x
,
r
.
y
,
r
.
z
,
c
));
if
(
hasBias
())
...
...
@@ -278,7 +267,6 @@ public:
topExpr
+=
bias
(
c
);
}
top
(
x
,
y
,
c
,
n
)
=
topExpr
;
Ptr
<
BackendNode
>
pp
(
new
HalideBackendNode
({
padded_input
,
top
}));
return
Ptr
<
BackendNode
>
(
new
HalideBackendNode
({
padded_input
,
top
}));
#endif // HAVE_HALIDE
return
Ptr
<
BackendNode
>
();
...
...
@@ -793,7 +781,7 @@ public:
int
inpH
=
inpShape
[
2
];
int
inpW
=
inpShape
[
3
];
int
outCn
=
outShape
[
1
];
int
ngroups
=
inpCn
/
blobs
[
0
].
size
[
1
];
int
ngroups
=
inpCn
/
blobs
[
0
].
size
[
0
];
int
outGroupCn
=
outCn
/
ngroups
;
int
ksize
=
outGroupCn
*
kernel
.
height
*
kernel
.
width
;
return
shape
(
ksize
,
inpH
*
inpW
);
...
...
@@ -804,7 +792,7 @@ public:
std
::
vector
<
MatShape
>
&
outputs
,
std
::
vector
<
MatShape
>
&
internals
)
const
{
CV_Assert
(
!
hasBias
()
||
blobs
[
1
].
total
()
==
(
size_t
)
blobs
[
0
].
size
[
0
]
);
CV_Assert
(
!
hasBias
()
||
blobs
[
1
].
total
()
==
(
size_t
)
numOutput
);
CV_Assert
(
inputs
.
size
()
!=
0
);
int
inpCn
=
inputs
[
0
][
1
];
...
...
@@ -813,12 +801,13 @@ public:
int
outH
=
stride
.
height
*
(
inpH
-
1
)
+
kernel
.
height
-
2
*
pad
.
height
+
adjustPad
.
height
;
int
outW
=
stride
.
width
*
(
inpW
-
1
)
+
kernel
.
width
-
2
*
pad
.
width
+
adjustPad
.
width
;
int
outCn
=
blobs
[
0
].
size
[
0
]
;
int
outCn
=
numOutput
;
int
ngroups
=
inpCn
/
blobs
[
0
].
size
[
1
];
CV_Assert
(
outCn
%
blobs
[
0
].
size
[
1
]
==
0
);
int
ngroups
=
outCn
/
blobs
[
0
].
size
[
1
];
CV_Assert
(
inpCn
%
ngroups
==
0
&&
outCn
%
ngroups
==
0
);
CV_Assert
(
blobs
[
0
].
size
[
0
]
==
outCn
&&
blobs
[
0
].
size
[
1
]
==
inpCn
/
ngroups
);
CV_Assert
(
blobs
[
0
].
size
[
0
]
==
inpCn
);
int
dims
[]
=
{
inputs
[
0
][
0
],
outCn
,
outH
,
outW
};
outputs
.
resize
(
inputs
.
size
(),
shape
(
dims
));
...
...
@@ -1073,7 +1062,7 @@ public:
CV_TRACE_FUNCTION
();
CV_TRACE_ARG_VALUE
(
name
,
"name"
,
name
.
c_str
());
int
outCn
=
blobs
[
0
].
size
[
0
]
;
int
outCn
=
numOutput
;
int
inpCn
=
inputs
[
0
]
->
size
[
1
];
bool
is1x1flag
=
is1x1
();
int
nstripes
=
getNumThreads
();
...
...
@@ -1086,9 +1075,9 @@ public:
for
(
size_t
ii
=
0
;
ii
<
outputs
.
size
();
ii
++
)
{
int
ngroups
=
inp
Cn
/
blobs
[
0
].
size
[
1
];
int
inpGroupCn
=
blobs
[
0
].
size
[
1
]
;
int
outGroupCn
=
outCn
/
ngroups
;
int
ngroups
=
out
Cn
/
blobs
[
0
].
size
[
1
];
int
inpGroupCn
=
inpCn
/
ngroups
;
int
outGroupCn
=
blobs
[
0
].
size
[
1
]
;
const
Mat
&
inp
=
*
inputs
[
ii
];
Mat
&
out
=
outputs
[
ii
];
int
numImg
=
inp
.
size
[
0
];
...
...
@@ -1126,18 +1115,16 @@ public:
#ifdef HAVE_HALIDE
Halide
::
Buffer
<
float
>
inputBuffer
=
halideBuffer
(
inputs
[
0
]);
int
inW
,
inH
,
inC
,
inN
,
outC
=
blobs
[
0
].
size
[
0
]
;
int
inW
,
inH
,
inC
,
inN
;
getCanonicalSize
(
inputBuffer
,
&
inW
,
&
inH
,
&
inC
,
&
inN
);
if
(
inC
/
blobs
[
0
].
size
[
1
]
!=
1
)
CV_Error
(
cv
::
Error
::
StsNotImplemented
,
"Halide backend for Deconvolution with group > 1 is not implemented"
);
const
int
outGroupCn
=
blobs
[
0
].
size
[
1
];
const
int
group
=
numOutput
/
outGroupCn
;
const
int
inpGroupCn
=
blobs
[
0
].
size
[
0
]
/
group
;
Halide
::
Var
x
(
"x"
),
y
(
"y"
),
c
(
"c"
),
n
(
"n"
);
Halide
::
Func
top
=
(
name
.
empty
()
?
Halide
::
Func
()
:
Halide
::
Func
(
name
));
Halide
::
Func
padded_input
(
name
+
"_constant_exterior"
);
auto
weights
=
wrapToHalideBuffer
(
blobs
[
0
],
{
kernel
.
width
,
kernel
.
height
,
outC
,
inC
});
auto
weights
=
wrapToHalideBuffer
(
blobs
[
0
]);
Halide
::
Func
dilated_input
(
"dilated_input"
);
dilated_input
(
x
,
y
,
c
,
n
)
=
0.0
f
;
...
...
@@ -1153,13 +1140,21 @@ public:
0
,
inC
,
0
,
inN
);
padded_input
(
x
,
y
,
c
,
n
)
=
bounded
(
x
,
y
,
c
,
n
);
Halide
::
RDom
r
(
0
,
kernel
.
width
,
0
,
kernel
.
height
,
0
,
inC
);
Halide
::
Expr
topExpr
=
sum
(
padded_input
(
x
+
pad
.
width
-
r
.
x
,
y
+
pad
.
height
-
r
.
y
,
r
.
z
,
n
)
*
weights
(
r
.
x
,
r
.
y
,
c
,
r
.
z
));
Halide
::
RDom
r
(
0
,
kernel
.
width
,
0
,
kernel
.
height
,
0
,
inpGroupCn
);
Halide
::
Expr
kx
=
x
+
pad
.
width
-
r
.
x
;
Halide
::
Expr
ky
=
y
+
pad
.
height
-
r
.
y
;
Halide
::
Expr
kInC
=
r
.
z
;
Halide
::
Expr
kOutC
=
c
;
for
(
int
i
=
1
;
i
<
group
;
++
i
)
{
kInC
=
select
(
c
<
outGroupCn
*
i
,
kInC
,
inpGroupCn
*
i
+
r
.
z
);
kOutC
=
select
(
c
<
outGroupCn
*
i
,
kOutC
,
c
-
outGroupCn
*
i
);
}
Halide
::
Expr
topExpr
=
sum
(
padded_input
(
kx
,
ky
,
kInC
,
n
)
*
weights
(
r
.
x
,
r
.
y
,
kOutC
,
kInC
));
if
(
hasBias
())
{
auto
bias
=
wrapToHalideBuffer
(
blobs
[
1
],
{
outC
});
auto
bias
=
wrapToHalideBuffer
(
blobs
[
1
],
{
numOutput
});
topExpr
+=
bias
(
c
);
}
top
(
x
,
y
,
c
,
n
)
=
topExpr
;
...
...
@@ -1194,13 +1189,13 @@ static void initConvDeconvLayerFromCaffe(Ptr<BaseConvolutionLayer> l, const Laye
l
->
dilation
.
width
,
l
->
padMode
);
bool
bias
=
params
.
get
<
bool
>
(
"bias_term"
,
true
);
int
numOutput
=
params
.
get
<
int
>
(
"num_output"
);
l
->
numOutput
=
params
.
get
<
int
>
(
"num_output"
);
int
ngroups
=
params
.
get
<
int
>
(
"group"
,
1
);
l
->
adjustPad
.
height
=
params
.
get
<
int
>
(
"adj_h"
,
0
);
l
->
adjustPad
.
width
=
params
.
get
<
int
>
(
"adj_w"
,
0
);
CV_Assert
(
numOutput
%
ngroups
==
0
);
CV_Assert
(
l
->
numOutput
%
ngroups
==
0
);
CV_Assert
((
bias
&&
l
->
blobs
.
size
()
==
2
)
||
(
!
bias
&&
l
->
blobs
.
size
()
==
1
));
CV_Assert
(
l
->
adjustPad
.
width
<
l
->
stride
.
width
&&
l
->
adjustPad
.
height
<
l
->
stride
.
height
);
...
...
This diff is collapsed.
Click to expand it.
modules/dnn/src/tensorflow/tf_importer.cpp
View file @
68cc2e29
...
...
@@ -1015,13 +1015,11 @@ void TFImporter::populateNet(Net dstNet)
}
kernelFromTensor
(
getConstBlob
(
layer
,
value_id
,
1
),
layerParams
.
blobs
[
0
]);
// Swap just numbers of input and output channels.
std
::
swap
(
layerParams
.
blobs
[
0
].
size
[
0
],
layerParams
.
blobs
[
0
].
size
[
1
]);
const
int
*
kshape
=
layerParams
.
blobs
[
0
].
size
.
p
;
layerParams
.
set
(
"kernel_h"
,
kshape
[
2
]);
layerParams
.
set
(
"kernel_w"
,
kshape
[
3
]);
layerParams
.
set
(
"num_output"
,
kshape
[
0
]);
layerParams
.
set
(
"num_output"
,
kshape
[
1
]);
setStrides
(
layerParams
,
layer
);
setPadding
(
layerParams
,
layer
);
...
...
This diff is collapsed.
Click to expand it.
modules/dnn/src/torch/torch_importer.cpp
View file @
68cc2e29
...
...
@@ -798,10 +798,7 @@ struct TorchImporter : public ::cv::dnn::Importer
layerParams
.
set
(
"adj_h"
,
static_cast
<
int
>
(
scalarParams
.
get
<
double
>
(
"adjH"
)));
layerParams
.
set
(
"num_output"
,
static_cast
<
int
>
(
scalarParams
.
get
<
double
>
(
"nOutputPlane"
)));
Mat
weights
=
tensorParams
[
"weight"
].
second
;
CV_Assert
(
weights
.
dims
==
4
);
int
reorderedShape
[]
=
{
weights
.
size
[
1
],
weights
.
size
[
0
],
weights
.
size
[
2
],
weights
.
size
[
3
]
};
layerParams
.
blobs
.
push_back
(
weights
.
reshape
(
1
,
4
,
reorderedShape
));
layerParams
.
blobs
.
push_back
(
tensorParams
[
"weight"
].
second
);
bool
bias
=
tensorParams
.
count
(
"bias"
);
layerParams
.
set
(
"bias_term"
,
bias
);
...
...
This diff is collapsed.
Click to expand it.
modules/dnn/test/test_halide_layers.cpp
View file @
68cc2e29
...
...
@@ -129,7 +129,7 @@ TEST_P(Deconvolution, Accuracy)
Size
adjPad
=
Size
(
get
<
5
>
(
GetParam
())[
2
],
get
<
5
>
(
GetParam
())[
3
]);
bool
hasBias
=
get
<
6
>
(
GetParam
());
Mat
weights
({
outChannels
,
in
Channels
/
group
,
kernel
.
height
,
kernel
.
width
},
CV_32F
);
Mat
weights
({
inChannels
,
out
Channels
/
group
,
kernel
.
height
,
kernel
.
width
},
CV_32F
);
randu
(
weights
,
-
1.0
f
,
1.0
f
);
LayerParams
lp
;
...
...
@@ -161,7 +161,7 @@ TEST_P(Deconvolution, Accuracy)
INSTANTIATE_TEST_CASE_P
(
Layer_Test_Halide
,
Deconvolution
,
Combine
(
/*in channels, out channels, group*/
Values
(
Vec3i
(
6
,
4
,
1
),
Vec3i
(
6
,
9
,
1
)),
Values
(
Vec3i
(
6
,
4
,
1
),
Vec3i
(
6
,
9
,
3
)),
/*in size*/
Values
(
Size
(
5
,
6
)),
/*kernel*/
Values
(
Size
(
3
,
1
),
Size
(
1
,
3
)),
/*pad*/
Values
(
Size
(
1
,
0
),
Size
(
0
,
1
)),
...
...
This diff is collapsed.
Click to expand it.
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