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
6e593cd1
Commit
6e593cd1
authored
Sep 27, 2017
by
Dmitry Kurtaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Swap dimensions of deconvolution kernel
parent
0f0f5652
Show 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 @
6e593cd1
...
@@ -199,6 +199,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
...
@@ -199,6 +199,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
public
:
public
:
Size
kernel
,
stride
,
pad
,
dilation
,
adjustPad
;
Size
kernel
,
stride
,
pad
,
dilation
,
adjustPad
;
String
padMode
;
String
padMode
;
int
numOutput
;
};
};
class
CV_EXPORTS
ConvolutionLayer
:
public
BaseConvolutionLayer
class
CV_EXPORTS
ConvolutionLayer
:
public
BaseConvolutionLayer
...
...
modules/dnn/src/layers/convolution_layer.cpp
View file @
6e593cd1
...
@@ -252,24 +252,13 @@ public:
...
@@ -252,24 +252,13 @@ public:
}
}
Halide
::
RDom
r
(
0
,
kernel
.
width
,
0
,
kernel
.
height
,
0
,
inpGroupCn
);
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
;
Halide
::
Expr
kc
=
r
.
z
;
if
(
group
>
1
)
for
(
int
i
=
1
;
i
<
group
;
++
i
)
{
{
int
outCnBound
=
outGroupCn
;
kc
=
select
(
c
<
outGroupCn
*
i
,
kc
,
inpGroupCn
*
i
+
r
.
z
);
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
;
}
}
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
)
*
Halide
::
Expr
topExpr
=
sum
(
padded_input
(
kx
,
ky
,
kc
,
n
)
*
weights
(
r
.
x
,
r
.
y
,
r
.
z
,
c
));
weights
(
r
.
x
,
r
.
y
,
r
.
z
,
c
));
if
(
hasBias
())
if
(
hasBias
())
...
@@ -278,7 +267,6 @@ public:
...
@@ -278,7 +267,6 @@ public:
topExpr
+=
bias
(
c
);
topExpr
+=
bias
(
c
);
}
}
top
(
x
,
y
,
c
,
n
)
=
topExpr
;
top
(
x
,
y
,
c
,
n
)
=
topExpr
;
Ptr
<
BackendNode
>
pp
(
new
HalideBackendNode
({
padded_input
,
top
}));
return
Ptr
<
BackendNode
>
(
new
HalideBackendNode
({
padded_input
,
top
}));
return
Ptr
<
BackendNode
>
(
new
HalideBackendNode
({
padded_input
,
top
}));
#endif // HAVE_HALIDE
#endif // HAVE_HALIDE
return
Ptr
<
BackendNode
>
();
return
Ptr
<
BackendNode
>
();
...
@@ -793,7 +781,7 @@ public:
...
@@ -793,7 +781,7 @@ public:
int
inpH
=
inpShape
[
2
];
int
inpH
=
inpShape
[
2
];
int
inpW
=
inpShape
[
3
];
int
inpW
=
inpShape
[
3
];
int
outCn
=
outShape
[
1
];
int
outCn
=
outShape
[
1
];
int
ngroups
=
inpCn
/
blobs
[
0
].
size
[
1
];
int
ngroups
=
inpCn
/
blobs
[
0
].
size
[
0
];
int
outGroupCn
=
outCn
/
ngroups
;
int
outGroupCn
=
outCn
/
ngroups
;
int
ksize
=
outGroupCn
*
kernel
.
height
*
kernel
.
width
;
int
ksize
=
outGroupCn
*
kernel
.
height
*
kernel
.
width
;
return
shape
(
ksize
,
inpH
*
inpW
);
return
shape
(
ksize
,
inpH
*
inpW
);
...
@@ -804,7 +792,7 @@ public:
...
@@ -804,7 +792,7 @@ public:
std
::
vector
<
MatShape
>
&
outputs
,
std
::
vector
<
MatShape
>
&
outputs
,
std
::
vector
<
MatShape
>
&
internals
)
const
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
);
CV_Assert
(
inputs
.
size
()
!=
0
);
int
inpCn
=
inputs
[
0
][
1
];
int
inpCn
=
inputs
[
0
][
1
];
...
@@ -813,12 +801,13 @@ public:
...
@@ -813,12 +801,13 @@ public:
int
outH
=
stride
.
height
*
(
inpH
-
1
)
+
kernel
.
height
-
2
*
pad
.
height
+
adjustPad
.
height
;
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
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
(
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
};
int
dims
[]
=
{
inputs
[
0
][
0
],
outCn
,
outH
,
outW
};
outputs
.
resize
(
inputs
.
size
(),
shape
(
dims
));
outputs
.
resize
(
inputs
.
size
(),
shape
(
dims
));
...
@@ -1073,7 +1062,7 @@ public:
...
@@ -1073,7 +1062,7 @@ public:
CV_TRACE_FUNCTION
();
CV_TRACE_FUNCTION
();
CV_TRACE_ARG_VALUE
(
name
,
"name"
,
name
.
c_str
());
CV_TRACE_ARG_VALUE
(
name
,
"name"
,
name
.
c_str
());
int
outCn
=
blobs
[
0
].
size
[
0
]
;
int
outCn
=
numOutput
;
int
inpCn
=
inputs
[
0
]
->
size
[
1
];
int
inpCn
=
inputs
[
0
]
->
size
[
1
];
bool
is1x1flag
=
is1x1
();
bool
is1x1flag
=
is1x1
();
int
nstripes
=
getNumThreads
();
int
nstripes
=
getNumThreads
();
...
@@ -1086,9 +1075,9 @@ public:
...
@@ -1086,9 +1075,9 @@ public:
for
(
size_t
ii
=
0
;
ii
<
outputs
.
size
();
ii
++
)
for
(
size_t
ii
=
0
;
ii
<
outputs
.
size
();
ii
++
)
{
{
int
ngroups
=
inp
Cn
/
blobs
[
0
].
size
[
1
];
int
ngroups
=
out
Cn
/
blobs
[
0
].
size
[
1
];
int
inpGroupCn
=
blobs
[
0
].
size
[
1
]
;
int
inpGroupCn
=
inpCn
/
ngroups
;
int
outGroupCn
=
outCn
/
ngroups
;
int
outGroupCn
=
blobs
[
0
].
size
[
1
]
;
const
Mat
&
inp
=
*
inputs
[
ii
];
const
Mat
&
inp
=
*
inputs
[
ii
];
Mat
&
out
=
outputs
[
ii
];
Mat
&
out
=
outputs
[
ii
];
int
numImg
=
inp
.
size
[
0
];
int
numImg
=
inp
.
size
[
0
];
...
@@ -1126,18 +1115,16 @@ public:
...
@@ -1126,18 +1115,16 @@ public:
#ifdef HAVE_HALIDE
#ifdef HAVE_HALIDE
Halide
::
Buffer
<
float
>
inputBuffer
=
halideBuffer
(
inputs
[
0
]);
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
);
getCanonicalSize
(
inputBuffer
,
&
inW
,
&
inH
,
&
inC
,
&
inN
);
const
int
outGroupCn
=
blobs
[
0
].
size
[
1
];
if
(
inC
/
blobs
[
0
].
size
[
1
]
!=
1
)
const
int
group
=
numOutput
/
outGroupCn
;
CV_Error
(
cv
::
Error
::
StsNotImplemented
,
const
int
inpGroupCn
=
blobs
[
0
].
size
[
0
]
/
group
;
"Halide backend for Deconvolution with group > 1 is not implemented"
);
Halide
::
Var
x
(
"x"
),
y
(
"y"
),
c
(
"c"
),
n
(
"n"
);
Halide
::
Var
x
(
"x"
),
y
(
"y"
),
c
(
"c"
),
n
(
"n"
);
Halide
::
Func
top
=
(
name
.
empty
()
?
Halide
::
Func
()
:
Halide
::
Func
(
name
));
Halide
::
Func
top
=
(
name
.
empty
()
?
Halide
::
Func
()
:
Halide
::
Func
(
name
));
Halide
::
Func
padded_input
(
name
+
"_constant_exterior"
);
Halide
::
Func
padded_input
(
name
+
"_constant_exterior"
);
auto
weights
=
wrapToHalideBuffer
(
blobs
[
0
],
{
kernel
.
width
,
auto
weights
=
wrapToHalideBuffer
(
blobs
[
0
]);
kernel
.
height
,
outC
,
inC
});
Halide
::
Func
dilated_input
(
"dilated_input"
);
Halide
::
Func
dilated_input
(
"dilated_input"
);
dilated_input
(
x
,
y
,
c
,
n
)
=
0.0
f
;
dilated_input
(
x
,
y
,
c
,
n
)
=
0.0
f
;
...
@@ -1153,13 +1140,21 @@ public:
...
@@ -1153,13 +1140,21 @@ public:
0
,
inC
,
0
,
inN
);
0
,
inC
,
0
,
inN
);
padded_input
(
x
,
y
,
c
,
n
)
=
bounded
(
x
,
y
,
c
,
n
);
padded_input
(
x
,
y
,
c
,
n
)
=
bounded
(
x
,
y
,
c
,
n
);
Halide
::
RDom
r
(
0
,
kernel
.
width
,
0
,
kernel
.
height
,
0
,
inC
);
Halide
::
RDom
r
(
0
,
kernel
.
width
,
0
,
kernel
.
height
,
0
,
inpGroupCn
);
Halide
::
Expr
topExpr
=
sum
(
Halide
::
Expr
kx
=
x
+
pad
.
width
-
r
.
x
;
padded_input
(
x
+
pad
.
width
-
r
.
x
,
y
+
pad
.
height
-
r
.
y
,
r
.
z
,
n
)
*
Halide
::
Expr
ky
=
y
+
pad
.
height
-
r
.
y
;
weights
(
r
.
x
,
r
.
y
,
c
,
r
.
z
));
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
())
if
(
hasBias
())
{
{
auto
bias
=
wrapToHalideBuffer
(
blobs
[
1
],
{
outC
});
auto
bias
=
wrapToHalideBuffer
(
blobs
[
1
],
{
numOutput
});
topExpr
+=
bias
(
c
);
topExpr
+=
bias
(
c
);
}
}
top
(
x
,
y
,
c
,
n
)
=
topExpr
;
top
(
x
,
y
,
c
,
n
)
=
topExpr
;
...
@@ -1194,13 +1189,13 @@ static void initConvDeconvLayerFromCaffe(Ptr<BaseConvolutionLayer> l, const Laye
...
@@ -1194,13 +1189,13 @@ static void initConvDeconvLayerFromCaffe(Ptr<BaseConvolutionLayer> l, const Laye
l
->
dilation
.
width
,
l
->
padMode
);
l
->
dilation
.
width
,
l
->
padMode
);
bool
bias
=
params
.
get
<
bool
>
(
"bias_term"
,
true
);
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
);
int
ngroups
=
params
.
get
<
int
>
(
"group"
,
1
);
l
->
adjustPad
.
height
=
params
.
get
<
int
>
(
"adj_h"
,
0
);
l
->
adjustPad
.
height
=
params
.
get
<
int
>
(
"adj_h"
,
0
);
l
->
adjustPad
.
width
=
params
.
get
<
int
>
(
"adj_w"
,
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
((
bias
&&
l
->
blobs
.
size
()
==
2
)
||
(
!
bias
&&
l
->
blobs
.
size
()
==
1
));
CV_Assert
(
l
->
adjustPad
.
width
<
l
->
stride
.
width
&&
CV_Assert
(
l
->
adjustPad
.
width
<
l
->
stride
.
width
&&
l
->
adjustPad
.
height
<
l
->
stride
.
height
);
l
->
adjustPad
.
height
<
l
->
stride
.
height
);
...
...
modules/dnn/src/tensorflow/tf_importer.cpp
View file @
6e593cd1
...
@@ -1038,13 +1038,11 @@ void TFImporter::populateNet(Net dstNet)
...
@@ -1038,13 +1038,11 @@ void TFImporter::populateNet(Net dstNet)
}
}
kernelFromTensor
(
getConstBlob
(
layer
,
value_id
,
1
),
layerParams
.
blobs
[
0
]);
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
;
const
int
*
kshape
=
layerParams
.
blobs
[
0
].
size
.
p
;
layerParams
.
set
(
"kernel_h"
,
kshape
[
2
]);
layerParams
.
set
(
"kernel_h"
,
kshape
[
2
]);
layerParams
.
set
(
"kernel_w"
,
kshape
[
3
]);
layerParams
.
set
(
"kernel_w"
,
kshape
[
3
]);
layerParams
.
set
(
"num_output"
,
kshape
[
0
]);
layerParams
.
set
(
"num_output"
,
kshape
[
1
]);
setStrides
(
layerParams
,
layer
);
setStrides
(
layerParams
,
layer
);
setPadding
(
layerParams
,
layer
);
setPadding
(
layerParams
,
layer
);
...
...
modules/dnn/src/torch/torch_importer.cpp
View file @
6e593cd1
...
@@ -796,10 +796,7 @@ struct TorchImporter : public ::cv::dnn::Importer
...
@@ -796,10 +796,7 @@ struct TorchImporter : public ::cv::dnn::Importer
layerParams
.
set
(
"adj_h"
,
static_cast
<
int
>
(
scalarParams
.
get
<
double
>
(
"adjH"
)));
layerParams
.
set
(
"adj_h"
,
static_cast
<
int
>
(
scalarParams
.
get
<
double
>
(
"adjH"
)));
layerParams
.
set
(
"num_output"
,
static_cast
<
int
>
(
scalarParams
.
get
<
double
>
(
"nOutputPlane"
)));
layerParams
.
set
(
"num_output"
,
static_cast
<
int
>
(
scalarParams
.
get
<
double
>
(
"nOutputPlane"
)));
Mat
weights
=
tensorParams
[
"weight"
].
second
;
layerParams
.
blobs
.
push_back
(
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
));
bool
bias
=
tensorParams
.
count
(
"bias"
);
bool
bias
=
tensorParams
.
count
(
"bias"
);
layerParams
.
set
(
"bias_term"
,
bias
);
layerParams
.
set
(
"bias_term"
,
bias
);
...
...
modules/dnn/test/test_halide_layers.cpp
View file @
6e593cd1
...
@@ -107,7 +107,7 @@ TEST_P(Deconvolution, Accuracy)
...
@@ -107,7 +107,7 @@ TEST_P(Deconvolution, Accuracy)
Size
adjPad
=
Size
(
get
<
5
>
(
GetParam
())[
2
],
get
<
5
>
(
GetParam
())[
3
]);
Size
adjPad
=
Size
(
get
<
5
>
(
GetParam
())[
2
],
get
<
5
>
(
GetParam
())[
3
]);
bool
hasBias
=
get
<
6
>
(
GetParam
());
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
);
randu
(
weights
,
-
1.0
f
,
1.0
f
);
LayerParams
lp
;
LayerParams
lp
;
...
@@ -139,7 +139,7 @@ TEST_P(Deconvolution, Accuracy)
...
@@ -139,7 +139,7 @@ TEST_P(Deconvolution, Accuracy)
INSTANTIATE_TEST_CASE_P
(
Layer_Test_Halide
,
Deconvolution
,
Combine
(
INSTANTIATE_TEST_CASE_P
(
Layer_Test_Halide
,
Deconvolution
,
Combine
(
/*in channels, out channels, group*/
/*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
)),
/*in size*/
Values
(
Size
(
5
,
6
)),
/*kernel*/
Values
(
Size
(
3
,
1
),
Size
(
1
,
3
)),
/*kernel*/
Values
(
Size
(
3
,
1
),
Size
(
1
,
3
)),
/*pad*/
Values
(
Size
(
1
,
0
),
Size
(
0
,
1
)),
/*pad*/
Values
(
Size
(
1
,
0
),
Size
(
0
,
1
)),
...
...
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