Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
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_contrib
Commits
5127e7f2
Commit
5127e7f2
authored
Jan 10, 2017
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #916 from arrybn:torch_enet
parents
99294995
e784f137
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
815 additions
and
126 deletions
+815
-126
CMakeLists.txt
modules/dnn/CMakeLists.txt
+5
-1
all_layers.hpp
modules/dnn/include/opencv2/dnn/all_layers.hpp
+20
-2
dnn.hpp
modules/dnn/include/opencv2/dnn/dnn.hpp
+3
-0
torch_enet.cpp
modules/dnn/samples/torch_enet.cpp
+176
-0
layer_loaders.cpp
modules/dnn/src/caffe/layer_loaders.cpp
+44
-1
dnn.cpp
modules/dnn/src/dnn.cpp
+18
-0
init.cpp
modules/dnn/src/init.cpp
+5
-0
batch_norm_layer.cpp
modules/dnn/src/layers/batch_norm_layer.cpp
+69
-0
batch_norm_layer.hpp
modules/dnn/src/layers/batch_norm_layer.hpp
+37
-0
convolution_layer.cpp
modules/dnn/src/layers/convolution_layer.cpp
+88
-72
convolution_layer.hpp
modules/dnn/src/layers/convolution_layer.hpp
+17
-10
elementwise_layers.cpp
modules/dnn/src/layers/elementwise_layers.cpp
+42
-2
elementwise_layers.hpp
modules/dnn/src/layers/elementwise_layers.hpp
+10
-0
eltwise_layer.cpp
modules/dnn/src/layers/eltwise_layer.cpp
+2
-1
max_unpooling_layer.cpp
modules/dnn/src/layers/max_unpooling_layer.cpp
+69
-0
max_unpooling_layer.hpp
modules/dnn/src/layers/max_unpooling_layer.hpp
+37
-0
padding_layer.cpp
modules/dnn/src/layers/padding_layer.cpp
+86
-0
padding_layer.hpp
modules/dnn/src/layers/padding_layer.hpp
+37
-0
pooling_layer.cpp
modules/dnn/src/layers/pooling_layer.cpp
+28
-11
pooling_layer.hpp
modules/dnn/src/layers/pooling_layer.hpp
+3
-3
shift_layer.cpp
modules/dnn/src/layers/shift_layer.cpp
+9
-9
shift_layer.hpp
modules/dnn/src/layers/shift_layer.hpp
+4
-2
pooling.cl
modules/dnn/src/opencl/pooling.cl
+2
-8
torch_importer.cpp
modules/dnn/src/torch/torch_importer.cpp
+0
-0
test_layers.cpp
modules/dnn/test/test_layers.cpp
+1
-0
test_tf_importer.cpp
modules/dnn/test/test_tf_importer.cpp
+3
-4
No files found.
modules/dnn/CMakeLists.txt
View file @
5127e7f2
...
...
@@ -29,6 +29,10 @@ else()
)
endif
()
if
(
ANDROID
)
add_definitions
(
-DDISABLE_POSIX_MEMALIGN -DTH_DISABLE_HEAP_TRACKING
)
endif
()
# ----------------------------------------------------------------------------
# Resolve libprotobuf dependency
# ----------------------------------------------------------------------------
...
...
@@ -55,7 +59,7 @@ endif()
# ----------------------------------------------------------------------------
# Torch7 importer of blobs and models, produced by Torch.nn module
# ----------------------------------------------------------------------------
OCV_OPTION
(
${
the_module
}
_BUILD_TORCH_IMPORTER
"Build Torch model importer
(experimental functionality!)"
OFF
)
OCV_OPTION
(
${
the_module
}
_BUILD_TORCH_IMPORTER
"Build Torch model importer
"
ON
)
if
(
${
the_module
}
_BUILD_TORCH_IMPORTER
)
add_definitions
(
-DENABLE_TORCH_IMPORTER=1
)
ocv_warnings_disable
(
CMAKE_CXX_FLAGS /wd4702 /wd4127 /wd4267
)
#supress warnings in original torch files
...
...
modules/dnn/include/opencv2/dnn/all_layers.hpp
View file @
5127e7f2
...
...
@@ -209,7 +209,7 @@ namespace dnn
{
public
:
CV_PROP_RW
Size
kernel
,
stride
,
pad
,
dilation
;
CV_PROP_RW
Size
kernel
,
stride
,
pad
,
dilation
,
adjustPad
;
CV_PROP_RW
String
padMode
;
};
...
...
@@ -224,7 +224,7 @@ namespace dnn
{
public
:
static
CV_WRAP
Ptr
<
BaseConvolutionLayer
>
create
(
Size
kernel
=
Size
(
3
,
3
),
Size
stride
=
Size
(
1
,
1
),
Size
pad
=
Size
(
0
,
0
),
Size
dilation
=
Size
(
1
,
1
));
static
CV_WRAP
Ptr
<
BaseConvolutionLayer
>
create
(
Size
kernel
=
Size
(
3
,
3
),
Size
stride
=
Size
(
1
,
1
),
Size
pad
=
Size
(
0
,
0
),
Size
dilation
=
Size
(
1
,
1
)
,
Size
adjustPad
=
Size
()
);
};
class
CV_EXPORTS_W
LRNLayer
:
public
Layer
...
...
@@ -341,6 +341,12 @@ namespace dnn
static
CV_WRAP
Ptr
<
ReLULayer
>
create
(
double
negativeSlope
=
0
);
};
class
CV_EXPORTS_W
ChannelsPReLULayer
:
public
Layer
{
public
:
static
CV_WRAP
Ptr
<
ChannelsPReLULayer
>
create
();
};
class
CV_EXPORTS_W
TanHLayer
:
public
Layer
{
public
:
...
...
@@ -397,6 +403,18 @@ namespace dnn
static
Ptr
<
EltwiseLayer
>
create
(
EltwiseOp
op
,
const
std
::
vector
<
int
>
&
coeffs
);
};
class
CV_EXPORTS_W
BatchNormLayer
:
public
Layer
{
public
:
static
CV_WRAP
Ptr
<
BatchNormLayer
>
create
(
float
eps
,
bool
has_weights
,
bool
has_bias
);
};
class
CV_EXPORTS_W
MaxUnpoolLayer
:
public
Layer
{
public
:
static
CV_WRAP
Ptr
<
MaxUnpoolLayer
>
create
(
Size
unpoolSize
);
};
//! @}
//! @}
...
...
modules/dnn/include/opencv2/dnn/dnn.hpp
View file @
5127e7f2
...
...
@@ -270,6 +270,9 @@ namespace dnn //! This namespace is used for dnn module functionlaity.
*/
CV_WRAP
Blob
getParam
(
LayerId
layer
,
int
numParam
=
0
);
/** @brief Returns indexes of layers with unconnected outputs.
*/
CV_WRAP
std
::
vector
<
int
>
getUnconnectedOutLayers
()
const
;
private
:
struct
Impl
;
...
...
modules/dnn/samples/torch_enet.cpp
0 → 100644
View file @
5127e7f2
/*
Sample of using OpenCV dnn module with Torch ENet model.
*/
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using
namespace
cv
;
using
namespace
cv
::
dnn
;
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <sstream>
using
namespace
std
;
const
String
keys
=
"{help h || Sample app for loading ENet Torch model. "
"The model and class names list can be downloaded here: "
"https://www.dropbox.com/sh/dywzk3gyb12hpe5/AAD5YkUa8XgMpHs2gCRgmCVCa }"
"{model m || path to Torch .net model file (model_best.net) }"
"{image i || path to image file }"
"{i_blob | .0 | input blob name) }"
"{o_blob || output blob name) }"
"{c_names c || path to file with classnames for channels (categories.txt) }"
"{result r || path to save output blob (optional, binary format, NCHW order) }"
;
std
::
vector
<
String
>
readClassNames
(
const
char
*
filename
);
int
main
(
int
argc
,
char
**
argv
)
{
cv
::
CommandLineParser
parser
(
argc
,
argv
,
keys
);
if
(
parser
.
has
(
"help"
))
{
parser
.
printMessage
();
return
0
;
}
String
modelFile
=
parser
.
get
<
String
>
(
"model"
);
String
imageFile
=
parser
.
get
<
String
>
(
"image"
);
String
inBlobName
=
parser
.
get
<
String
>
(
"i_blob"
);
String
outBlobName
=
parser
.
get
<
String
>
(
"o_blob"
);
if
(
!
parser
.
check
())
{
parser
.
printErrors
();
return
0
;
}
String
classNamesFile
=
parser
.
get
<
String
>
(
"c_names"
);
String
resultFile
=
parser
.
get
<
String
>
(
"result"
);
//! [Create the importer of TensorFlow model]
Ptr
<
dnn
::
Importer
>
importer
;
try
//Try to import TensorFlow AlexNet model
{
importer
=
dnn
::
createTorchImporter
(
modelFile
);
}
catch
(
const
cv
::
Exception
&
err
)
//Importer can throw errors, we will catch them
{
std
::
cerr
<<
err
.
msg
<<
std
::
endl
;
}
//! [Create the importer of Caffe model]
if
(
!
importer
)
{
std
::
cerr
<<
"Can't load network by using the mode file: "
<<
std
::
endl
;
std
::
cerr
<<
modelFile
<<
std
::
endl
;
exit
(
-
1
);
}
//! [Initialize network]
dnn
::
Net
net
;
importer
->
populateNet
(
net
);
importer
.
release
();
//We don't need importer anymore
//! [Initialize network]
//! [Prepare blob]
Mat
img
=
imread
(
imageFile
);
if
(
img
.
empty
())
{
std
::
cerr
<<
"Can't read image from the file: "
<<
imageFile
<<
std
::
endl
;
exit
(
-
1
);
}
cv
::
Size
inputImgSize
=
cv
::
Size
(
512
,
512
);
if
(
inputImgSize
!=
img
.
size
())
resize
(
img
,
img
,
inputImgSize
);
//Resize image to input size
if
(
img
.
channels
()
==
3
)
cv
::
cvtColor
(
img
,
img
,
cv
::
COLOR_BGR2RGB
);
img
.
convertTo
(
img
,
CV_32F
,
1
/
255.0
);
dnn
::
Blob
inputBlob
=
dnn
::
Blob
::
fromImages
(
img
);
//Convert Mat to dnn::Blob image batch
//! [Prepare blob]
//! [Set input blob]
net
.
setBlob
(
inBlobName
,
inputBlob
);
//set the network input
//! [Set input blob]
cv
::
TickMeter
tm
;
tm
.
start
();
//! [Make forward pass]
net
.
forward
();
//compute output
//! [Make forward pass]
tm
.
stop
();
//! [Gather output]
dnn
::
Blob
prob
=
net
.
getBlob
(
outBlobName
);
//gather output of "prob" layer
Mat
&
result
=
prob
.
matRef
();
BlobShape
shape
=
prob
.
shape
();
if
(
!
resultFile
.
empty
())
{
CV_Assert
(
result
.
isContinuous
());
ofstream
fout
(
resultFile
.
c_str
(),
ios
::
out
|
ios
::
binary
);
fout
.
write
((
char
*
)
result
.
data
,
result
.
total
()
*
sizeof
(
float
));
fout
.
close
();
}
std
::
cout
<<
"Output blob shape "
<<
shape
<<
std
::
endl
;
std
::
cout
<<
"Inference time, ms: "
<<
tm
.
getTimeMilli
()
<<
std
::
endl
;
std
::
vector
<
String
>
classNames
;
if
(
!
classNamesFile
.
empty
())
{
classNames
=
readClassNames
(
classNamesFile
.
c_str
());
if
(
classNames
.
size
()
>
prob
.
channels
())
classNames
=
std
::
vector
<
String
>
(
classNames
.
begin
()
+
classNames
.
size
()
-
prob
.
channels
(),
classNames
.
end
());
}
for
(
int
i_c
=
0
;
i_c
<
prob
.
channels
();
i_c
++
)
{
ostringstream
convert
;
convert
<<
"Channel #"
<<
i_c
;
if
(
classNames
.
size
()
==
prob
.
channels
())
convert
<<
": "
<<
classNames
[
i_c
];
imshow
(
convert
.
str
().
c_str
(),
prob
.
getPlane
(
0
,
i_c
));
}
waitKey
();
return
0
;
}
//main
std
::
vector
<
String
>
readClassNames
(
const
char
*
filename
)
{
std
::
vector
<
String
>
classNames
;
std
::
ifstream
fp
(
filename
);
if
(
!
fp
.
is_open
())
{
std
::
cerr
<<
"File with classes labels not found: "
<<
filename
<<
std
::
endl
;
exit
(
-
1
);
}
std
::
string
name
;
while
(
!
fp
.
eof
())
{
std
::
getline
(
fp
,
name
);
if
(
name
.
length
())
classNames
.
push_back
(
name
);
}
fp
.
close
();
return
classNames
;
}
modules/dnn/src/caffe/layer_loaders.cpp
View file @
5127e7f2
...
...
@@ -23,6 +23,9 @@ static void initConvDeconvLayerFromCaffe(Ptr<BaseConvolutionLayer> l, LayerParam
int
numOutput
=
params
.
get
<
int
>
(
"num_output"
);
int
group
=
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
%
group
==
0
);
CV_Assert
((
bias
&&
l
->
blobs
.
size
()
==
2
)
||
(
!
bias
&&
l
->
blobs
.
size
()
==
1
));
}
...
...
@@ -40,6 +43,7 @@ Ptr<Layer> createLayerFromCaffe<DeconvolutionLayer>(LayerParams ¶ms)
{
Ptr
<
BaseConvolutionLayer
>
l
=
DeconvolutionLayer
::
create
();
initConvDeconvLayerFromCaffe
(
l
,
params
);
return
Ptr
<
Layer
>
(
l
);
}
...
...
@@ -248,7 +252,7 @@ Ptr<Layer> createLayerFromCaffe<CropLayer>(LayerParams& params)
return
Ptr
<
Layer
>
(
CropLayer
::
create
(
start_axis
,
offset
));
}
template
<>
//
Power
specialization
template
<>
//
Eltwise
specialization
Ptr
<
Layer
>
createLayerFromCaffe
<
EltwiseLayer
>
(
LayerParams
&
params
)
{
EltwiseLayer
::
EltwiseOp
op
=
EltwiseLayer
::
SUM
;
...
...
@@ -278,6 +282,42 @@ Ptr<Layer> createLayerFromCaffe<EltwiseLayer>(LayerParams& params)
return
Ptr
<
Layer
>
(
EltwiseLayer
::
create
(
op
,
coeffs
));
}
template
<>
//BatchNormLayer specialization
Ptr
<
Layer
>
createLayerFromCaffe
<
BatchNormLayer
>
(
LayerParams
&
params
)
{
const
std
::
vector
<
Blob
>
&
blobs
=
params
.
blobs
;
CV_Assert
(
blobs
.
size
()
==
4
);
float
eps
=
params
.
get
<
float
>
(
"eps"
);
bool
hasWeights
=
params
.
get
<
bool
>
(
"has_weight"
,
false
);
bool
hasBias
=
params
.
get
<
bool
>
(
"has_bias"
,
false
);
Ptr
<
BatchNormLayer
>
l
=
BatchNormLayer
::
create
(
eps
,
hasWeights
,
hasBias
);
l
->
setParamsFrom
(
params
);
return
Ptr
<
Layer
>
(
l
);
}
template
<>
//ChannelsPReLULayer specialization
Ptr
<
Layer
>
createLayerFromCaffe
<
ChannelsPReLULayer
>
(
LayerParams
&
params
)
{
CV_Assert
(
params
.
blobs
.
size
()
==
1
);
Ptr
<
ChannelsPReLULayer
>
l
=
ChannelsPReLULayer
::
create
();
l
->
setParamsFrom
(
params
);
return
Ptr
<
Layer
>
(
l
);
}
template
<>
//MaxUnpoolLayer specialization
Ptr
<
Layer
>
createLayerFromCaffe
<
MaxUnpoolLayer
>
(
LayerParams
&
params
)
{
Size
outSize
(
params
.
get
<
int
>
(
"out_w"
),
params
.
get
<
int
>
(
"out_h"
));
Ptr
<
MaxUnpoolLayer
>
l
=
MaxUnpoolLayer
::
create
(
outSize
);
return
Ptr
<
Layer
>
(
l
);
}
//Explicit instantiation
template
Ptr
<
Layer
>
createLayerFromCaffe
<
ConvolutionLayer
>
(
LayerParams
&
);
template
Ptr
<
Layer
>
createLayerFromCaffe
<
DeconvolutionLayer
>
(
LayerParams
&
);
...
...
@@ -299,6 +339,9 @@ template Ptr<Layer> createLayerFromCaffe<PowerLayer>(LayerParams&);
template
Ptr
<
Layer
>
createLayerFromCaffe
<
CropLayer
>
(
LayerParams
&
);
template
Ptr
<
Layer
>
createLayerFromCaffe
<
EltwiseLayer
>
(
LayerParams
&
);
template
Ptr
<
Layer
>
createLayerFromCaffe
<
BatchNormLayer
>
(
LayerParams
&
);
template
Ptr
<
Layer
>
createLayerFromCaffe
<
ChannelsPReLULayer
>
(
LayerParams
&
);
template
Ptr
<
Layer
>
createLayerFromCaffe
<
MaxUnpoolLayer
>
(
LayerParams
&
);
}
}
modules/dnn/src/dnn.cpp
View file @
5127e7f2
...
...
@@ -592,6 +592,24 @@ bool Net::empty() const
return
impl
->
layers
.
size
()
<=
1
;
//first layer is default Data layer
}
std
::
vector
<
int
>
Net
::
getUnconnectedOutLayers
()
const
{
std
::
vector
<
int
>
layersIds
;
Impl
::
MapIdToLayerData
::
iterator
it
;
for
(
it
=
impl
->
layers
.
begin
();
it
!=
impl
->
layers
.
end
();
it
++
)
{
int
lid
=
it
->
first
;
LayerData
&
ld
=
it
->
second
;
if
(
ld
.
requiredOutputs
.
size
()
==
0
)
layersIds
.
push_back
(
lid
);
}
return
layersIds
;
}
//////////////////////////////////////////////////////////////////////////
Importer
::~
Importer
()
{}
...
...
modules/dnn/src/init.cpp
View file @
5127e7f2
...
...
@@ -51,6 +51,7 @@
#include "layers/detection_output_layer.hpp"
#include "layers/normalize_bbox_layer.hpp"
#include "layers/shift_layer.hpp"
#include "layers/padding_layer.hpp"
namespace
cv
{
...
...
@@ -89,11 +90,14 @@ void initModule()
REG_RUNTIME_LAYER_FUNC
(
MVN
,
createLayerFromCaffe
<
MVNLayer
>
);
REG_RUNTIME_LAYER_FUNC
(
ReLU
,
createLayerFromCaffe
<
ReLULayer
>
);
REG_RUNTIME_LAYER_FUNC
(
ChannelsPReLU
,
createLayerFromCaffe
<
ChannelsPReLULayer
>
);
REG_RUNTIME_LAYER_FUNC
(
Sigmoid
,
createLayerFromCaffe
<
SigmoidLayer
>
);
REG_RUNTIME_LAYER_FUNC
(
TanH
,
createLayerFromCaffe
<
TanHLayer
>
);
REG_RUNTIME_LAYER_FUNC
(
BNLL
,
createLayerFromCaffe
<
BNLLLayer
>
);
REG_RUNTIME_LAYER_FUNC
(
AbsVal
,
createLayerFromCaffe
<
AbsLayer
>
);
REG_RUNTIME_LAYER_FUNC
(
Power
,
createLayerFromCaffe
<
PowerLayer
>
);
REG_RUNTIME_LAYER_FUNC
(
BatchNorm
,
createLayerFromCaffe
<
BatchNormLayer
>
);
REG_RUNTIME_LAYER_FUNC
(
MaxUnpool
,
createLayerFromCaffe
<
MaxUnpoolLayer
>
);
REG_RUNTIME_LAYER_CLASS
(
Dropout
,
BlankLayer
);
REG_RUNTIME_LAYER_CLASS
(
Identity
,
BlankLayer
);
...
...
@@ -104,6 +108,7 @@ void initModule()
REG_RUNTIME_LAYER_CLASS
(
DetectionOutput
,
DetectionOutputLayer
);
REG_RUNTIME_LAYER_CLASS
(
NormalizeBBox
,
NormalizeBBoxLayer
);
REG_RUNTIME_LAYER_CLASS
(
Shift
,
ShiftLayer
);
REG_RUNTIME_LAYER_CLASS
(
Padding
,
PaddingLayer
);
init
.
status
=
true
;
}
...
...
modules/dnn/src/layers/batch_norm_layer.cpp
0 → 100644
View file @
5127e7f2
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
Implementation of Batch Normalization layer.
*/
#include "batch_norm_layer.hpp"
namespace
cv
{
namespace
dnn
{
BatchNormLayerImpl
::
BatchNormLayerImpl
(
float
eps_
,
bool
hasWeights_
,
bool
hasBias_
)
:
eps
(
eps_
),
hasWeights
(
hasWeights_
),
hasBias
(
hasBias_
)
{}
void
BatchNormLayerImpl
::
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
blobs
.
size
()
==
4
);
outputs
.
resize
(
inputs
.
size
());
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
outputs
[
i
].
create
(
inputs
[
i
]
->
shape
());
}
}
void
BatchNormLayerImpl
::
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
inputs
.
size
()
==
1
);
Blob
&
inpBlob
=
*
inputs
[
0
];
for
(
size_t
ii
=
0
;
ii
<
outputs
.
size
();
ii
++
)
{
Blob
&
outBlob
=
outputs
[
ii
];
if
(
hasWeights
)
CV_Assert
(
inpBlob
.
channels
()
==
blobs
[
2
].
total
());
if
(
hasBias
)
CV_Assert
(
inpBlob
.
channels
()
==
blobs
[
3
].
total
());
for
(
int
n
=
0
;
n
<
inpBlob
.
channels
();
n
++
)
{
float
mean
=
blobs
[
0
].
matRefConst
().
at
<
float
>
(
n
);
float
invstd
=
1
/
sqrt
(
blobs
[
1
].
matRefConst
().
at
<
float
>
(
n
)
+
eps
);
float
w
=
hasWeights
?
blobs
[
2
].
matRefConst
().
at
<
float
>
(
n
)
:
1
;
float
b
=
hasBias
?
blobs
[
3
].
matRefConst
().
at
<
float
>
(
n
)
:
0
;
outBlob
.
getPlane
(
0
,
n
)
=
(
inpBlob
.
getPlane
(
0
,
n
)
-
mean
)
*
(
w
*
invstd
)
+
b
;
}
}
}
Ptr
<
BatchNormLayer
>
BatchNormLayer
::
create
(
float
eps
,
bool
has_weights
,
bool
has_bias
)
{
return
Ptr
<
BatchNormLayer
>
(
new
BatchNormLayerImpl
(
eps
,
has_weights
,
has_bias
));
}
}
// namespace dnn
}
// namespace cv
modules/dnn/src/layers/batch_norm_layer.hpp
0 → 100644
View file @
5127e7f2
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
Declaration of Batch Normalization layer.
*/
#ifndef __OPENCV_DNN_LAYERS_BATCH_NORM_LAYER_HPP__
#define __OPENCV_DNN_LAYERS_BATCH_NORM_LAYER_HPP__
#include <opencv2/dnn/all_layers.hpp>
namespace
cv
{
namespace
dnn
{
class
BatchNormLayerImpl
:
public
BatchNormLayer
{
public
:
BatchNormLayerImpl
(
float
eps_
,
bool
hasWeights_
,
bool
hasBias_
);
void
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
private
:
float
eps
;
bool
hasWeights
,
hasBias
;
};
}
}
#endif // BATCH_NORM_LAYER_HPP
modules/dnn/src/layers/convolution_layer.cpp
View file @
5127e7f2
...
...
@@ -53,12 +53,14 @@ namespace cv
namespace
dnn
{
ConvolutionLayerImpl
::
ConvolutionLayerImpl
()
BaseConvolutionLayerImpl
::
BaseConvolutionLayerImpl
()
:
numOutput
(
-
1
),
group
(
-
1
),
inpH
(
0
),
inpW
(
0
),
inpCn
(
0
),
outH
(
0
),
outW
(
0
),
outCn
(
0
),
inpGroupCn
(
0
),
outGroupCn
(
0
),
ksize
(
0
),
colBlobCols
(
0
),
bias
(
false
),
tryUseOpenCL
(
false
)
{
tryUseOpenCL
=
false
;
//true;
numOutput
=
-
1
;
group
=
-
1
;
#if HAVE_CBLAS
if
(
getBlasThreads
()
!=
cv
::
getThreadNum
())
{
...
...
@@ -67,37 +69,23 @@ ConvolutionLayerImpl::ConvolutionLayerImpl()
#endif
}
void
ConvolutionLayerImpl
::
init
()
void
Base
ConvolutionLayerImpl
::
init
()
{
CV_Assert
(
1
<=
blobs
.
size
()
&&
blobs
.
size
()
<=
2
);
bias
=
(
blobs
.
size
()
>=
2
);
numOutput
=
blobs
[
0
].
num
();
CV_Assert
(
blobs
.
size
()
>=
1
&&
blobs
.
size
()
<=
2
);
CV_Assert
(
blobs
[
0
].
dims
()
==
4
&&
blobs
[
0
].
cols
()
==
kernel
.
width
&&
blobs
[
0
].
rows
()
==
kernel
.
height
);
CV_Assert
(
!
bias
||
blobs
[
1
].
total
()
==
(
size_t
)
blobs
[
0
].
num
());
//TODO: dilation in OCL mode
bias
=
(
blobs
.
size
()
>=
2
);
useOpenCL
=
ocl
::
useOpenCL
()
&&
tryUseOpenCL
&&
dilation
==
Size
(
1
,
1
);
}
void
ConvolutionLayerImpl
::
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
void
Base
ConvolutionLayerImpl
::
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
inputs
.
size
()
>
0
);
init
();
CV_Assert
(
inputs
.
size
()
>
0
);
const
Blob
&
input
=
*
inputs
[
0
];
CV_Assert
(
input
.
dims
()
==
4
&&
(
input
.
type
()
==
CV_32F
||
input
.
type
()
==
CV_64F
));
computeInpOutShape
(
input
);
group
=
inpCn
/
blobs
[
0
].
channels
();
CV_Assert
(
inpCn
%
group
==
0
&&
outCn
%
group
==
0
);
CV_Assert
(
blobs
[
0
].
num
()
==
outCn
&&
blobs
[
0
].
channels
()
==
inpCn
/
group
);
outGroupCn
=
outCn
/
group
;
inpGroupCn
=
inpCn
/
group
;
ksize
=
inpGroupCn
*
kernel
.
height
*
kernel
.
width
;
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
CV_Assert
(
inputs
[
i
]
->
type
()
==
input
.
type
());
...
...
@@ -105,36 +93,73 @@ void ConvolutionLayerImpl::allocate(const std::vector<Blob*> &inputs, std::vecto
CV_Assert
(
inputs
[
i
]
->
rows
()
==
input
.
rows
()
&&
inputs
[
i
]
->
cols
()
==
input
.
cols
());
}
int
allocFlags
=
useOpenCL
?
Blob
::
ALLOC_UMAT
:
Blob
::
ALLOC_MAT
;
computeInpOutShape
(
input
)
;
if
(
!
is1x1
())
{
colBlob
.
create
(
Shape
(
ksize
,
outH
*
outW
),
input
.
type
(),
allocFlags
);
}
int
allocFlags
=
useOpenCL
?
Blob
::
ALLOC_UMAT
:
Blob
::
ALLOC_MAT
;
if
(
bias
)
{
biasOnesBlob
.
create
(
Shape
(
1
,
topH
*
top
W
),
input
.
type
(),
allocFlags
);
biasOnesBlob
.
create
(
Shape
(
1
,
outH
*
out
W
),
input
.
type
(),
allocFlags
);
biasOnesBlob
.
setTo
(
1
);
}
outputs
.
resize
(
inputs
.
size
());
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
outputs
[
i
].
create
(
Shape
(
inputs
[
i
]
->
num
(),
topCn
,
topH
,
topW
),
input
.
type
(),
allocFlags
);
outputs
[
i
].
create
(
Shape
(
inputs
[
i
]
->
num
(),
outCn
,
outH
,
outW
),
input
.
type
(),
allocFlags
);
}
if
(
!
is1x1
())
{
colBlob
.
create
(
Shape
(
ksize
,
colBlobCols
),
input
.
type
(),
allocFlags
);
}
}
bool
ConvolutionLayerImpl
::
is1x1
()
const
bool
Base
ConvolutionLayerImpl
::
is1x1
()
const
{
return
(
kernel
.
height
==
1
&&
kernel
.
width
==
1
)
&&
(
stride
.
height
==
1
&&
stride
.
width
==
1
)
&&
(
dilation
.
height
==
1
&&
dilation
.
width
==
1
);
}
void
ConvolutionLayerImpl
::
computeInpOutShape
(
const
Blob
&
input
)
{
CV_Assert
(
!
bias
||
blobs
[
1
].
total
()
==
(
size_t
)
blobs
[
0
].
num
());
numOutput
=
blobs
[
0
].
num
();
inpH
=
input
.
rows
();
inpW
=
input
.
cols
();
inpCn
=
input
.
channels
();
outCn
=
numOutput
;
if
(
padMode
.
empty
())
{
outH
=
(
inpH
+
2
*
pad
.
height
-
(
dilation
.
height
*
(
kernel
.
height
-
1
)
+
1
))
/
stride
.
height
+
1
;
outW
=
(
inpW
+
2
*
pad
.
width
-
(
dilation
.
width
*
(
kernel
.
width
-
1
)
+
1
))
/
stride
.
width
+
1
;
}
else
{
getConvPoolOutParams
(
inpH
,
inpW
,
kernel
,
stride
,
pad
,
padMode
,
outH
,
outW
);
}
group
=
inpCn
/
blobs
[
0
].
channels
();
CV_Assert
(
inpCn
%
group
==
0
&&
outCn
%
group
==
0
);
CV_Assert
(
blobs
[
0
].
num
()
==
outCn
&&
blobs
[
0
].
channels
()
==
inpCn
/
group
);
outGroupCn
=
outCn
/
group
;
inpGroupCn
=
inpCn
/
group
;
ksize
=
inpGroupCn
*
kernel
.
height
*
kernel
.
width
;
colBlobCols
=
outH
*
outW
;
}
template
<
typename
XMat
>
void
ConvolutionLayerImpl
::
forward_
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
inputs
.
size
()
>
0
);
XMat
weightsMat
=
reshaped
(
blobs
[
0
].
getRefConst
<
XMat
>
(),
Shape
(
outCn
,
ksize
));
XMat
biasesMat
=
(
bias
)
?
reshaped
(
blobs
[
1
].
getRefConst
<
XMat
>
(),
Shape
(
outCn
,
1
))
:
XMat
();
...
...
@@ -213,44 +238,33 @@ void ConvolutionLayerImpl::im2col(const Mat &srcImg, Mat &dstCol)
dstCol
=
colMat
;
}
void
ConvolutionLayerImpl
::
computeInpOutShape
(
const
Blob
&
input
)
{
inpH
=
input
.
rows
();
inpW
=
input
.
cols
();
inpCn
=
input
.
channels
();
outCn
=
numOutput
;
if
(
padMode
.
empty
())
{
outH
=
(
inpH
+
2
*
pad
.
height
-
(
dilation
.
height
*
(
kernel
.
height
-
1
)
+
1
))
/
stride
.
height
+
1
;
outW
=
(
inpW
+
2
*
pad
.
width
-
(
dilation
.
width
*
(
kernel
.
width
-
1
)
+
1
))
/
stride
.
width
+
1
;
}
else
{
getConvPoolOutParams
(
inpH
,
inpW
,
kernel
,
stride
,
pad
,
padMode
,
outH
,
outW
);
}
topH
=
outH
;
topW
=
outW
;
topCn
=
outCn
;
}
//Deconvolution
DeConvolutionLayerImpl
::
DeConvolutionLayerImpl
(
)
void
DeConvolutionLayerImpl
::
computeInpOutShape
(
const
Blob
&
inpBlob
)
{
BlobShape
bs0
=
blobs
[
0
].
shape
();
BlobShape
bs1
=
blobs
[
1
].
shape
();
CV_Assert
(
!
bias
||
blobs
[
1
].
total
()
==
(
size_t
)
blobs
[
0
].
channels
());
}
numOutput
=
blobs
[
0
].
channels
();
void
DeConvolutionLayerImpl
::
computeInpOutShape
(
const
Blob
&
inpBlob
)
{
outH
=
inpBlob
.
rows
();
outW
=
inpBlob
.
cols
();
outCn
=
inpBlob
.
channels
();
inpH
=
inpBlob
.
rows
();
inpW
=
inpBlob
.
cols
();
inpCn
=
inpBlob
.
channels
();
inpH
=
stride
.
height
*
(
outH
-
1
)
+
kernel
.
height
-
2
*
p
ad
.
height
;
inpW
=
stride
.
width
*
(
outW
-
1
)
+
kernel
.
width
-
2
*
p
ad
.
width
;
inp
Cn
=
numOutput
;
outH
=
stride
.
height
*
(
inpH
-
1
)
+
kernel
.
height
-
2
*
pad
.
height
+
adjustP
ad
.
height
;
outW
=
stride
.
width
*
(
inpW
-
1
)
+
kernel
.
width
-
2
*
pad
.
width
+
adjustP
ad
.
width
;
out
Cn
=
numOutput
;
topH
=
inpH
;
topW
=
inpW
;
topCn
=
inpCn
;
group
=
inpCn
/
blobs
[
0
].
num
();
outGroupCn
=
outCn
/
group
;
inpGroupCn
=
inpCn
/
group
;
ksize
=
outGroupCn
*
kernel
.
height
*
kernel
.
width
;
CV_Assert
(
inpCn
%
group
==
0
&&
outCn
%
group
==
0
);
CV_Assert
(
blobs
[
0
].
channels
()
==
outCn
&&
blobs
[
0
].
num
()
==
inpCn
/
group
);
colBlobCols
=
inpH
*
inpW
;
}
void
DeConvolutionLayerImpl
::
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
...
...
@@ -264,24 +278,24 @@ void DeConvolutionLayerImpl::forward(std::vector<Blob*> &inputs, std::vector<Blo
template
<
typename
XMat
>
void
DeConvolutionLayerImpl
::
forward_
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
XMat
weightsMat
=
reshaped
(
blobs
[
0
].
getRefConst
<
XMat
>
(),
Shape
(
out
Cn
,
ksize
));
XMat
weightsMat
=
reshaped
(
blobs
[
0
].
getRefConst
<
XMat
>
(),
Shape
(
inp
Cn
,
ksize
));
XMat
biasesMat
=
(
bias
)
?
reshaped
(
blobs
[
1
].
getRefConst
<
XMat
>
(),
Shape
(
outCn
,
1
))
:
XMat
();
for
(
size_t
ii
=
0
;
ii
<
outputs
.
size
();
ii
++
)
{
int
numImg
=
inputs
[
ii
]
->
size
(
0
);
XMat
convBlob
=
reshaped
(
inputs
[
ii
]
->
getRefConst
<
XMat
>
(),
Shape
(
numImg
*
outCn
,
outH
*
out
W
));
XMat
decnBlob
=
reshaped
(
outputs
[
ii
].
getRef
<
XMat
>
(),
Shape
(
numImg
*
inpCn
,
inpH
*
inp
W
));
XMat
convBlob
=
reshaped
(
inputs
[
ii
]
->
getRefConst
<
XMat
>
(),
Shape
(
numImg
*
inpCn
,
inpH
*
inp
W
));
XMat
decnBlob
=
reshaped
(
outputs
[
ii
].
getRef
<
XMat
>
(),
Shape
(
numImg
*
outCn
,
outH
*
out
W
));
for
(
int
n
=
0
;
n
<
numImg
;
n
++
)
{
for
(
int
g
=
0
;
g
<
group
;
g
++
)
{
XMat
dstMat
=
decnBlob
.
rowRange
(
_Range
((
g
+
n
*
group
)
*
inpGroupCn
,
inp
GroupCn
));
XMat
dstMat
=
decnBlob
.
rowRange
(
_Range
((
g
+
n
*
group
)
*
outGroupCn
,
out
GroupCn
));
XMat
&
colMat
=
(
is1x1
())
?
dstMat
:
colBlob
.
getRef
<
XMat
>
();
XMat
convMat
=
convBlob
.
rowRange
(
_Range
((
g
+
n
*
group
)
*
outGroupCn
,
out
GroupCn
));
XMat
wghtMat
=
weightsMat
.
rowRange
(
_Range
(
g
*
outGroupCn
,
out
GroupCn
));
XMat
convMat
=
convBlob
.
rowRange
(
_Range
((
g
+
n
*
group
)
*
inpGroupCn
,
inp
GroupCn
));
XMat
wghtMat
=
weightsMat
.
rowRange
(
_Range
(
g
*
inpGroupCn
,
inp
GroupCn
));
dnn
::
gemm
(
wghtMat
,
convMat
,
1
,
colMat
,
0
,
GEMM_1_T
);
...
...
@@ -306,7 +320,7 @@ void DeConvolutionLayerImpl::col2im(const Mat &colMat, Mat &dstImg)
return
;
}
if
(
dstImg
.
type
()
==
CV_32F
)
col2im_CpuPBody
<
float
>::
run
(
colMat
.
ptr
<
float
>
(),
inpGroupCn
,
inpH
,
inp
W
,
kernel
.
height
,
kernel
.
width
,
pad
.
height
,
pad
.
width
,
stride
.
height
,
stride
.
width
,
dstImg
.
ptr
<
float
>
());
col2im_CpuPBody
<
float
>::
run
(
colMat
.
ptr
<
float
>
(),
outGroupCn
,
outH
,
out
W
,
kernel
.
height
,
kernel
.
width
,
pad
.
height
,
pad
.
width
,
stride
.
height
,
stride
.
width
,
dstImg
.
ptr
<
float
>
());
if
(
dstImg
.
type
()
==
CV_64F
)
col2im_CpuPBody
<
double
>::
run
(
colMat
.
ptr
<
double
>
(),
inpGroupCn
,
inpH
,
inpW
,
kernel
.
height
,
kernel
.
width
,
pad
.
height
,
pad
.
width
,
stride
.
height
,
stride
.
width
,
dstImg
.
ptr
<
double
>
());
}
...
...
@@ -338,13 +352,15 @@ Ptr<BaseConvolutionLayer> ConvolutionLayer::create(Size kernel, Size stride, Siz
return
Ptr
<
BaseConvolutionLayer
>
(
l
);
}
Ptr
<
BaseConvolutionLayer
>
DeconvolutionLayer
::
create
(
Size
kernel
,
Size
stride
,
Size
pad
,
Size
dilation
)
Ptr
<
BaseConvolutionLayer
>
DeconvolutionLayer
::
create
(
Size
kernel
,
Size
stride
,
Size
pad
,
Size
dilation
,
Size
adjustPad
)
{
DeConvolutionLayerImpl
*
l
=
new
DeConvolutionLayerImpl
();
l
->
kernel
=
kernel
;
l
->
pad
=
pad
;
l
->
stride
=
stride
;
l
->
dilation
=
dilation
;
l
->
adjustPad
=
adjustPad
;
return
Ptr
<
BaseConvolutionLayer
>
(
l
);
}
...
...
modules/dnn/src/layers/convolution_layer.hpp
View file @
5127e7f2
...
...
@@ -49,30 +49,38 @@ namespace cv
namespace
dnn
{
//TODO: simultaneously convolution and bias addition for cache optimization
class
ConvolutionLayerImpl
:
public
ConvolutionLayer
class
BaseConvolutionLayerImpl
:
public
ConvolutionLayer
{
public
:
ConvolutionLayerImpl
();
BaseConvolutionLayerImpl
();
virtual
void
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
virtual
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
virtual
void
init
();
protected
:
void
init
();
virtual
void
computeInpOutShape
(
const
Blob
&
inpBlob
)
=
0
;
bool
is1x1
()
const
;
int
numOutput
,
group
;
int
inpH
,
inpW
,
inpCn
;
int
outH
,
outW
,
outCn
;
int
topH
,
topW
,
topCn
;
//switched between inp/out on deconv/conv
int
inpGroupCn
,
outGroupCn
;
int
ksize
;
int
colBlobCols
;
bool
bias
;
bool
tryUseOpenCL
,
useOpenCL
;
Blob
colBlob
,
biasOnesBlob
;
bool
is1x1
()
const
;
};
//TODO: simultaneously convolution and bias addition for cache optimization
class
ConvolutionLayerImpl
:
public
BaseConvolutionLayerImpl
{
public
:
virtual
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
protected
:
virtual
void
computeInpOutShape
(
const
Blob
&
inpBlob
);
template
<
typename
XMat
>
...
...
@@ -81,10 +89,9 @@ protected:
void
im2col
(
const
UMat
&
srcImg
,
UMat
&
dstCol
);
};
class
DeConvolutionLayerImpl
:
public
ConvolutionLayerImpl
class
DeConvolutionLayerImpl
:
public
Base
ConvolutionLayerImpl
{
public
:
DeConvolutionLayerImpl
();
virtual
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
protected
:
...
...
modules/dnn/src/layers/elementwise_layers.cpp
View file @
5127e7f2
#include "../precomp.hpp"
#include "elementwise_layers.hpp"
#include "opencv2/imgproc.hpp"
namespace
cv
{
...
...
@@ -42,5 +43,45 @@ Ptr<PowerLayer> PowerLayer::create(double power /*= 1*/, double scale /*= 1*/, d
return
Ptr
<
PowerLayer
>
(
new
ElementWiseLayer
<
PowerFunctor
>
(
f
));
}
////////////////////////////////////////////////////////////////////////////
void
ChannelsPReLULayerImpl
::
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
blobs
.
size
()
==
1
);
outputs
.
resize
(
inputs
.
size
());
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
outputs
[
i
].
create
(
inputs
[
i
]
->
shape
());
}
}
void
ChannelsPReLULayerImpl
::
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
inputs
.
size
()
==
1
);
Blob
&
inpBlob
=
*
inputs
[
0
];
for
(
size_t
ii
=
0
;
ii
<
outputs
.
size
();
ii
++
)
{
Blob
&
outBlob
=
outputs
[
ii
];
CV_Assert
(
blobs
[
0
].
total
()
==
inpBlob
.
channels
());
for
(
int
n
=
0
;
n
<
inpBlob
.
channels
();
n
++
)
{
float
slopeWeight
=
blobs
[
0
].
matRefConst
().
at
<
float
>
(
n
);
cv
::
threshold
(
inpBlob
.
getPlane
(
0
,
n
),
outBlob
.
getPlane
(
0
,
n
),
0
,
0
,
cv
::
THRESH_TOZERO_INV
);
outBlob
.
getPlane
(
0
,
n
)
=
inpBlob
.
getPlane
(
0
,
n
)
+
(
slopeWeight
-
1
)
*
outBlob
.
getPlane
(
0
,
n
);
}
}
}
Ptr
<
ChannelsPReLULayer
>
ChannelsPReLULayer
::
create
()
{
return
Ptr
<
ChannelsPReLULayer
>
(
new
ChannelsPReLULayerImpl
());
}
}
}
}
\ No newline at end of file
modules/dnn/src/layers/elementwise_layers.hpp
View file @
5127e7f2
...
...
@@ -313,6 +313,16 @@ struct PowerFunctor
#endif
};
class
ChannelsPReLULayerImpl
:
public
ChannelsPReLULayer
{
public
:
ChannelsPReLULayerImpl
()
{}
void
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
};
}
}
#endif
modules/dnn/src/layers/eltwise_layer.cpp
View file @
5127e7f2
...
...
@@ -62,7 +62,8 @@ namespace dnn
const
BlobShape
&
shape0
=
inputs
[
0
]
->
shape
();
for
(
size_t
i
=
1
;
i
<
inputs
.
size
();
++
i
)
{
CV_Assert
(
shape0
==
inputs
[
i
]
->
shape
());
BlobShape
iShape
=
inputs
[
i
]
->
shape
();
CV_Assert
(
shape0
==
iShape
);
}
outputs
.
resize
(
1
);
outputs
[
0
].
create
(
shape0
);
...
...
modules/dnn/src/layers/max_unpooling_layer.cpp
0 → 100644
View file @
5127e7f2
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
Implementation of Batch Normalization layer.
*/
#include "max_unpooling_layer.hpp"
namespace
cv
{
namespace
dnn
{
MaxUnpoolLayerImpl
::
MaxUnpoolLayerImpl
(
Size
outSize_
)
:
outSize
(
outSize_
)
{}
void
MaxUnpoolLayerImpl
::
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
inputs
.
size
()
==
2
);
BlobShape
outShape
=
inputs
[
0
]
->
shape
();
outShape
[
2
]
=
outSize
.
height
;
outShape
[
3
]
=
outSize
.
width
;
outputs
.
resize
(
1
);
outputs
[
0
].
create
(
outShape
);
}
void
MaxUnpoolLayerImpl
::
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
inputs
.
size
()
==
2
);
Blob
&
input
=
*
inputs
[
0
];
Blob
&
indices
=
*
inputs
[
1
];
CV_Assert
(
input
.
total
()
==
indices
.
total
());
CV_Assert
(
input
.
num
()
==
1
);
for
(
int
i_n
=
0
;
i_n
<
outputs
.
size
();
i_n
++
)
{
Blob
&
outBlob
=
outputs
[
i_n
];
CV_Assert
(
input
.
channels
()
==
outBlob
.
channels
());
for
(
int
i_c
=
0
;
i_c
<
input
.
channels
();
i_c
++
)
{
Mat
outPlane
=
outBlob
.
getPlane
(
0
,
i_c
);
for
(
int
i_wh
=
0
;
i_wh
<
input
.
size2
().
area
();
i_wh
++
)
{
int
index
=
indices
.
getPlane
(
0
,
i_c
).
at
<
float
>
(
i_wh
);
CV_Assert
(
index
<
outPlane
.
total
());
outPlane
.
at
<
float
>
(
index
)
=
input
.
getPlane
(
0
,
i_c
).
at
<
float
>
(
i_wh
);
}
}
}
}
Ptr
<
MaxUnpoolLayer
>
MaxUnpoolLayer
::
create
(
Size
unpoolSize
)
{
return
Ptr
<
MaxUnpoolLayer
>
(
new
MaxUnpoolLayerImpl
(
unpoolSize
));
}
}
}
modules/dnn/src/layers/max_unpooling_layer.hpp
0 → 100644
View file @
5127e7f2
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
Declaration of MaxUnpooling layer.
*/
#ifndef __OPENCV_DNN_LAYERS_MAX_UNPOOLING_LAYER_HPP__
#define __OPENCV_DNN_LAYERS_MAX_UNPOOLING_LAYER_HPP__
#include "../precomp.hpp"
#include <opencv2/dnn/all_layers.hpp>
namespace
cv
{
namespace
dnn
{
class
MaxUnpoolLayerImpl
:
public
MaxUnpoolLayer
{
public
:
MaxUnpoolLayerImpl
(
Size
outSize_
);
void
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
private
:
Size
outSize
;
};
}
}
#endif // __OPENCV_DNN_LAYERS_MAX_UNPOOLING_LAYER_HPP__
modules/dnn/src/layers/padding_layer.cpp
0 → 100644
View file @
5127e7f2
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
Implementation of padding layer, which adds paddings to input blob.
*/
#include "padding_layer.hpp"
#include <vector>
namespace
cv
{
namespace
dnn
{
PaddingLayer
::
PaddingLayer
(
LayerParams
&
params
)
{
paddingDim
=
params
.
get
<
int
>
(
"padding_dim"
);
padding
=
abs
(
params
.
get
<
int
>
(
"padding"
));
inputDims
=
params
.
get
<
int
>
(
"input_dims"
,
0
);
index
=
params
.
get
<
int
>
(
"index"
,
0
);
paddingValue
=
params
.
get
<
double
>
(
"value"
,
0
);
if
(
paddingDim
<
0
||
padding
<
0
)
CV_Error
(
cv
::
Error
::
StsNotImplemented
,
"Negative padding and dim aren't supported"
);
}
void
PaddingLayer
::
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
outputs
.
resize
(
inputs
.
size
());
for
(
int
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
BlobShape
shape
=
inputs
[
i
]
->
shape
();
int
dim
=
getPadDim
(
shape
);
CV_Assert
(
dim
<
shape
.
dims
());
shape
[
dim
]
+=
padding
;
outputs
[
i
].
create
(
shape
);
}
}
void
PaddingLayer
::
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
for
(
int
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
outputs
[
i
].
matRef
()
=
paddingValue
;
BlobShape
inShape
=
inputs
[
i
]
->
shape
();
BlobShape
outShape
=
outputs
[
i
].
shape
();
int
dim
=
getPadDim
(
inShape
);
int
actualIndex
=
index
;
if
(
index
==
0
)
actualIndex
=
inShape
[
dim
];
std
::
vector
<
std
::
pair
<
Range
,
Range
>
>
srcDstRanges
;
srcDstRanges
.
push_back
(
std
::
make_pair
(
Range
(
0
,
actualIndex
),
Range
(
0
,
actualIndex
)));
srcDstRanges
.
push_back
(
std
::
make_pair
(
Range
(
actualIndex
,
inShape
[
dim
]),
Range
(
actualIndex
+
padding
,
outShape
[
dim
])));
std
::
vector
<
Range
>
srcRanges
(
inShape
.
dims
(),
Range
::
all
()),
dstRanges
=
srcRanges
;
for
(
int
i
=
0
;
i
<
srcDstRanges
.
size
();
i
++
)
{
if
(
!
srcDstRanges
[
i
].
first
.
empty
())
{
srcRanges
[
dim
]
=
srcDstRanges
[
i
].
first
;
dstRanges
[
dim
]
=
srcDstRanges
[
i
].
second
;
Mat
dst
=
outputs
[
i
].
matRef
()(
&
dstRanges
[
0
]);
Mat
src
=
inputs
[
i
]
->
matRef
()(
&
srcRanges
[
0
]).
clone
();
src
.
copyTo
(
dst
);
}
}
}
}
int
PaddingLayer
::
getPadDim
(
const
BlobShape
&
shape
)
const
{
return
inputDims
>
0
&&
shape
.
dims
()
>
inputDims
?
paddingDim
+
1
:
paddingDim
;
}
}
}
modules/dnn/src/layers/padding_layer.hpp
0 → 100644
View file @
5127e7f2
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
Declaration of padding layer, which adds paddings to input blob.
*/
#ifndef __OPENCV_DNN_LAYERS_PADDING_LAYER_HPP__
#define __OPENCV_DNN_LAYERS_PADDING_LAYER_HPP__
#include "../precomp.hpp"
namespace
cv
{
namespace
dnn
{
class
PaddingLayer
:
public
Layer
{
public
:
PaddingLayer
()
{}
PaddingLayer
(
LayerParams
&
params
);
void
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
private
:
int
getPadDim
(
const
BlobShape
&
shape
)
const
;
int
paddingDim
,
padding
,
inputDims
,
index
;
float
paddingValue
;
};
}
}
#endif
modules/dnn/src/layers/pooling_layer.cpp
View file @
5127e7f2
...
...
@@ -72,7 +72,7 @@ PoolingLayerImpl::PoolingLayerImpl(int type_, Size kernel_, Size stride_, Size p
void
PoolingLayerImpl
::
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
)
{
CV_Assert
(
inputs
.
size
()
>
0
);
CV_Assert
(
inputs
.
size
()
==
1
);
inp
=
inputs
[
0
]
->
size2
();
...
...
@@ -85,11 +85,19 @@ void PoolingLayerImpl::allocate(const std::vector<Blob*> &inputs, std::vector<Bl
useOpenCL
=
ocl
::
useOpenCL
();
outputs
.
resize
(
inputs
.
size
());
outputs
.
resize
(
type
==
MAX
?
2
*
inputs
.
size
()
:
inputs
.
size
());
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
CV_Assert
(
inputs
[
i
]
->
rows
()
==
inp
.
height
&&
inputs
[
i
]
->
cols
()
==
inp
.
width
);
outputs
[
i
].
create
(
BlobShape
(
inputs
[
i
]
->
num
(),
inputs
[
i
]
->
channels
(),
out
.
height
,
out
.
width
));
if
(
type
==
MAX
)
{
outputs
[
2
*
i
].
create
(
BlobShape
(
inputs
[
i
]
->
num
(),
inputs
[
i
]
->
channels
(),
out
.
height
,
out
.
width
));
outputs
[
2
*
i
+
1
].
create
(
BlobShape
(
inputs
[
i
]
->
num
(),
inputs
[
i
]
->
channels
(),
out
.
height
,
out
.
width
));
}
else
{
outputs
[
i
].
create
(
BlobShape
(
inputs
[
i
]
->
num
(),
inputs
[
i
]
->
channels
(),
out
.
height
,
out
.
width
));
}
}
}
...
...
@@ -100,7 +108,7 @@ void PoolingLayerImpl::forward(std::vector<Blob*> &inputs, std::vector<Blob> &ou
switch
(
type
)
{
case
MAX
:
maxPooling
(
*
inputs
[
ii
],
outputs
[
ii
]);
maxPooling
(
*
inputs
[
ii
],
outputs
[
2
*
ii
],
outputs
[
2
*
ii
+
1
]);
break
;
case
AVE
:
avePooling
(
*
inputs
[
ii
],
outputs
[
ii
]);
...
...
@@ -112,17 +120,17 @@ void PoolingLayerImpl::forward(std::vector<Blob*> &inputs, std::vector<Blob> &ou
}
}
void
PoolingLayerImpl
::
maxPooling
(
Blob
&
src
,
Blob
&
dst
)
void
PoolingLayerImpl
::
maxPooling
(
Blob
&
src
,
Blob
&
dst
,
Blob
&
mask
)
{
if
(
!
useOpenCL
)
maxPooling_cpu
(
src
,
dst
);
maxPooling_cpu
(
src
,
dst
,
mask
);
else
{
CV_Assert
(
maxPooling_ocl
(
src
,
dst
));
CV_Assert
(
maxPooling_ocl
(
src
,
dst
,
mask
));
}
}
bool
PoolingLayerImpl
::
maxPooling_ocl
(
Blob
&
src
,
Blob
&
dst
)
bool
PoolingLayerImpl
::
maxPooling_ocl
(
Blob
&
src
,
Blob
&
dst
,
Blob
&
mask
)
{
return
pooling_ocl
(
"MaxPoolForward"
,
src
,
dst
);
}
...
...
@@ -142,7 +150,7 @@ bool PoolingLayerImpl::avePooling_ocl(Blob &src, Blob &dst)
return
pooling_ocl
(
"AvePoolForward"
,
src
,
dst
);
}
void
PoolingLayerImpl
::
maxPooling_cpu
(
Blob
&
src
,
Blob
&
dst
)
void
PoolingLayerImpl
::
maxPooling_cpu
(
Blob
&
src
,
Blob
&
dst
,
Blob
&
mask
)
{
CV_DbgAssert
(
dst
.
rows
()
==
out
.
height
&&
dst
.
cols
()
==
out
.
width
);
...
...
@@ -152,6 +160,7 @@ void PoolingLayerImpl::maxPooling_cpu(Blob &src, Blob &dst)
{
const
float
*
srcData
=
src
.
ptrf
(
n
,
c
);
float
*
dstData
=
dst
.
ptrf
(
n
,
c
);
float
*
dstMaskData
=
mask
.
ptrf
(
n
,
c
);
for
(
int
ph
=
0
;
ph
<
out
.
height
;
++
ph
)
{
...
...
@@ -165,16 +174,21 @@ void PoolingLayerImpl::maxPooling_cpu(Blob &src, Blob &dst)
wstart
=
max
(
wstart
,
0
);
const
int
poolIndex
=
ph
*
out
.
width
+
pw
;
float
max_val
=
-
FLT_MAX
;
int
max_index
=
-
1
;
for
(
int
h
=
hstart
;
h
<
hend
;
++
h
)
for
(
int
w
=
wstart
;
w
<
wend
;
++
w
)
{
const
int
index
=
h
*
inp
.
width
+
w
;
if
(
srcData
[
index
]
>
max_val
)
{
max_val
=
srcData
[
index
];
max_index
=
index
;
}
}
dstData
[
poolIndex
]
=
max_val
;
dstMaskData
[
poolIndex
]
=
max_index
;
}
}
}
...
...
@@ -187,7 +201,9 @@ bool PoolingLayerImpl::pooling_ocl(const char *kname, const Blob &src, Blob &dst
{
const
UMat
&
srcMat
=
src
.
umatRefConst
();
UMat
&
dstMat
=
dst
.
umatRef
();
CV_Assert
(
mask
==
NULL
&&
srcMat
.
offset
==
0
&&
dstMat
.
offset
==
0
);
UMat
*
indexesMat
=
mask
==
NULL
?
NULL
:
&
dst
.
umatRef
();
CV_Assert
(
srcMat
.
offset
==
0
&&
dstMat
.
offset
==
0
);
ocl
::
Kernel
ker
(
kname
,
ocl
::
dnn
::
pooling_oclsrc
,
String
(
"-DT="
)
+
ocl
::
typeToStr
(
src
.
type
()));
if
(
ker
.
empty
())
...
...
@@ -199,7 +215,8 @@ bool PoolingLayerImpl::pooling_ocl(const char *kname, const Blob &src, Blob &dst
ocl
::
KernelArg
::
PtrReadOnly
(
srcMat
),
s
[
0
],
s
[
1
],
s
[
2
],
s
[
3
],
out
.
height
,
out
.
width
,
kernel
.
height
,
kernel
.
width
,
stride
.
height
,
stride
.
width
,
pad
.
height
,
pad
.
width
,
ocl
::
KernelArg
::
PtrWriteOnly
(
dstMat
));
ocl
::
KernelArg
::
PtrWriteOnly
(
dstMat
),
ocl
::
KernelArg
(
ocl
::
KernelArg
::
PTR_ONLY
+
ocl
::
KernelArg
::
WRITE_ONLY
,
indexesMat
));
size_t
wgSize
=
ocl
::
Device
::
getDefault
().
maxWorkGroupSize
();
if
(
!
ker
.
run
(
1
,
&
nthreads
,
&
wgSize
,
true
))
...
...
modules/dnn/src/layers/pooling_layer.hpp
View file @
5127e7f2
...
...
@@ -58,9 +58,9 @@ class PoolingLayerImpl : public PoolingLayer
bool
pooling_ocl
(
const
char
*
kname
,
const
Blob
&
src
,
Blob
&
dst
,
Blob
*
mask
=
NULL
);
void
maxPooling
(
Blob
&
src
,
Blob
&
dst
);
void
maxPooling_cpu
(
Blob
&
src
,
Blob
&
dst
);
bool
maxPooling_ocl
(
Blob
&
src
,
Blob
&
dst
);
void
maxPooling
(
Blob
&
src
,
Blob
&
dst
,
Blob
&
mask
);
void
maxPooling_cpu
(
Blob
&
src
,
Blob
&
dst
,
Blob
&
mask
);
bool
maxPooling_ocl
(
Blob
&
src
,
Blob
&
dst
,
Blob
&
mask
);
void
avePooling
(
Blob
&
src
,
Blob
&
dst
);
void
avePooling_cpu
(
Blob
&
src
,
Blob
&
dst
);
...
...
modules/dnn/src/layers/shift_layer.cpp
View file @
5127e7f2
...
...
@@ -39,17 +39,17 @@ public:
virtual
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
,
const
std
::
vector
<
Blob
>&
blobs
)
{
for
(
size_t
ii
=
0
;
ii
<
outputs
.
size
();
ii
++
)
{
Blob
&
inpBlob
=
*
inputs
[
ii
];
Blob
&
outBlob
=
outputs
[
ii
];
Blob
&
inpBlob
=
*
inputs
[
ii
];
Blob
&
outBlob
=
outputs
[
ii
];
inpBlob
.
matRef
().
copyTo
(
outBlob
.
matRef
());
inpBlob
.
matRef
().
copyTo
(
outBlob
.
matRef
());
for
(
int
n
=
0
;
n
<
inpBlob
.
num
();
n
++
)
{
Mat
dstMat
(
inpBlob
.
channels
(),
inpBlob
.
rows
()
*
inpBlob
.
cols
(),
outBlob
.
type
(),
outBlob
.
ptr
(
n
));
dnn
::
gemm
(
blobs
[
0
].
matRefConst
(),
biasOnesMat
,
1
,
dstMat
,
1
);
//TODO: gemv
}
for
(
int
n
=
0
;
n
<
inpBlob
.
num
();
n
++
)
{
Mat
dstMat
(
inpBlob
.
channels
(),
inpBlob
.
rows
()
*
inpBlob
.
cols
(),
outBlob
.
type
(),
outBlob
.
ptr
(
n
));
dnn
::
gemm
(
blobs
[
0
].
matRefConst
(),
biasOnesMat
,
1
,
dstMat
,
1
);
//TODO: gemv
}
}
}
...
...
modules/dnn/src/layers/shift_layer.hpp
View file @
5127e7f2
...
...
@@ -22,13 +22,15 @@ class ShiftLayerImpl;
class
ShiftLayer
:
public
Layer
{
cv
::
Ptr
<
ShiftLayerImpl
>
impl
;
public
:
ShiftLayer
()
{}
ShiftLayer
(
LayerParams
&
params
);
void
allocate
(
const
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
void
forward
(
std
::
vector
<
Blob
*>
&
inputs
,
std
::
vector
<
Blob
>
&
outputs
);
private
:
cv
::
Ptr
<
ShiftLayerImpl
>
impl
;
};
}
...
...
modules/dnn/src/opencl/pooling.cl
View file @
5127e7f2
...
...
@@ -24,10 +24,7 @@
*
POSSIBILITY
OF
SUCH
DAMAGE.
**************************************************************************************
/
__kernel
void
MaxPoolForward
(
const
int
nthreads,
__global
T*
bottom_data,
const
int
num,
const
int
channels,
const
int
height,
const
int
width,
const
int
pooled_height,
const
int
pooled_width,
const
int
kernel_h,
const
int
kernel_w,
const
int
stride_h,
const
int
stride_w,
const
int
pad_h,
const
int
pad_w,
__global
T*
top_data
#
ifdef
MASK
,
__global
int*
mask,
__global
T*
top_mask
#
endif
__kernel
void
MaxPoolForward
(
const
int
nthreads,
__global
T*
bottom_data,
const
int
num,
const
int
channels,
const
int
height,
const
int
width,
const
int
pooled_height,
const
int
pooled_width,
const
int
kernel_h,
const
int
kernel_w,
const
int
stride_h,
const
int
stride_w,
const
int
pad_h,
const
int
pad_w,
__global
T*
top_data,
__global
int*
mask
)
{
int
index
=
get_global_id
(
0
)
;
int
tmp
=
get_global_size
(
0
)
;
...
...
@@ -55,13 +52,10 @@ __kernel void MaxPoolForward(const int nthreads, __global T* bottom_data, const
}
}
top_data[index]
=
maxval
;
#
ifdef
MASK
if
(
mask
)
{
mask[index]
=
maxidx
;
}
else
{
top_mask[index]
=
maxidx
;
}
#
endif
}
}
...
...
modules/dnn/src/torch/torch_importer.cpp
View file @
5127e7f2
This diff is collapsed.
Click to expand it.
modules/dnn/test/test_layers.cpp
View file @
5127e7f2
...
...
@@ -154,6 +154,7 @@ TEST(Layer_Test_DeConvolution, Accuracy)
{
OCL_OFF
(
testLayerUsingCaffeModels
(
"layer_deconvolution"
,
true
,
false
));
}
OCL_TEST
(
Layer_Test_DeConvolution
,
Accuracy
)
{
OCL_ON
(
testLayerUsingCaffeModels
(
"layer_deconvolution"
,
true
,
false
););
...
...
modules/dnn/test/test_tf_importer.cpp
View file @
5127e7f2
...
...
@@ -38,13 +38,12 @@ TEST(Test_TensorFlow, read_inception)
resize
(
sample
,
input
,
Size
(
224
,
224
));
input
-=
128
;
// mean sub
std
::
vector
<
Mat
>
inpMats
;
inpMats
.
push_back
(
input
);
dnn
::
Blob
inputBlob
=
dnn
::
Blob
::
fromImages
(
input
);
net
.
setBlob
(
"_input.input"
,
Blob
(
inpMats
)
);
net
.
setBlob
(
"_input.input"
,
inputBlob
);
net
.
forward
();
Blob
out
=
net
.
getBlob
(
"
output
"
);
Blob
out
=
net
.
getBlob
(
"
softmax2
"
);
std
::
cout
<<
out
.
dims
()
<<
std
::
endl
;
}
...
...
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