Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
f9bb4f47
"vscode:/vscode.git/clone" did not exist on "d353b5aff6eaed6bb1bea45437e244d6c3068da3"
Commit
f9bb4f47
authored
Jun 26, 2017
by
Davis King
Browse files
Merge branch 'master' of
git://github.com/OranjeeGeneral/dlib
into OranjeeGeneral-master
parents
cbd187fb
ecb7095e
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
577 additions
and
52 deletions
+577
-52
dlib/dnn/cpu_dlib.cpp
dlib/dnn/cpu_dlib.cpp
+8
-19
dlib/dnn/cpu_dlib.h
dlib/dnn/cpu_dlib.h
+19
-4
dlib/dnn/cudnn_dlibapi.cpp
dlib/dnn/cudnn_dlibapi.cpp
+1
-7
dlib/dnn/cudnn_dlibapi.h
dlib/dnn/cudnn_dlibapi.h
+5
-8
dlib/dnn/layers.h
dlib/dnn/layers.h
+299
-6
dlib/dnn/layers_abstract.h
dlib/dnn/layers_abstract.h
+211
-0
dlib/dnn/tensor_tools.h
dlib/dnn/tensor_tools.h
+12
-6
dlib/test/dnn.cpp
dlib/test/dnn.cpp
+22
-2
No files found.
dlib/dnn/cpu_dlib.cpp
View file @
f9bb4f47
...
@@ -1739,43 +1739,32 @@ namespace dlib
...
@@ -1739,43 +1739,32 @@ namespace dlib
}
}
}
}
void
tensor_conv
::
operator
()
(
void
tensor_conv
::
operator
()
(
resizable_tensor
&
output
,
resizable_tensor
&
output
,
const
tensor
&
data
,
const
tensor
&
data
,
const
tensor
&
filters
,
const
tensor
&
filters
int
stride_y
,
int
stride_x
,
int
padding_y
,
int
padding_x
)
)
{
{
DLIB_CASSERT
(
is_same_object
(
output
,
data
)
==
false
);
DLIB_CASSERT
(
is_same_object
(
output
,
data
)
==
false
);
DLIB_CASSERT
(
is_same_object
(
output
,
filters
)
==
false
);
DLIB_CASSERT
(
is_same_object
(
output
,
filters
)
==
false
);
DLIB_CASSERT
(
filters
.
k
()
==
data
.
k
());
DLIB_CASSERT
(
filters
.
k
()
==
data
.
k
());
DLIB_CASSERT
(
stride_y
>
0
&&
stride_x
>
0
);
DLIB_CASSERT
(
filters
.
nr
()
<=
data
.
nr
()
+
2
*
last_padding_y
,
DLIB_CASSERT
(
0
<=
padding_y
&&
padding_y
<
filters
.
nr
());
DLIB_CASSERT
(
0
<=
padding_x
&&
padding_x
<
filters
.
nc
());
DLIB_CASSERT
(
filters
.
nr
()
<=
data
.
nr
()
+
2
*
padding_y
,
"Filter windows must be small enough to fit into the padded image."
);
"Filter windows must be small enough to fit into the padded image."
);
DLIB_CASSERT
(
filters
.
nc
()
<=
data
.
nc
()
+
2
*
padding_x
,
DLIB_CASSERT
(
filters
.
nc
()
<=
data
.
nc
()
+
2
*
last_
padding_x
,
"Filter windows must be small enough to fit into the padded image."
);
"Filter windows must be small enough to fit into the padded image."
);
output
.
set_size
(
data
.
num_samples
(),
output
.
set_size
(
data
.
num_samples
(),
filters
.
num_samples
(),
filters
.
num_samples
(),
1
+
(
data
.
nr
()
+
2
*
padding_y
-
filters
.
nr
())
/
stride_y
,
1
+
(
data
.
nr
()
+
2
*
last_
padding_y
-
filters
.
nr
())
/
last_
stride_y
,
1
+
(
data
.
nc
()
+
2
*
padding_x
-
filters
.
nc
())
/
stride_x
);
1
+
(
data
.
nc
()
+
2
*
last_
padding_x
-
filters
.
nc
())
/
last_
stride_x
);
matrix
<
float
>
temp
;
matrix
<
float
>
temp
;
for
(
long
n
=
0
;
n
<
data
.
num_samples
();
++
n
)
for
(
long
n
=
0
;
n
<
data
.
num_samples
();
++
n
)
{
{
img2col
(
temp
,
data
,
n
,
filters
.
nr
(),
filters
.
nc
(),
stride_y
,
stride_x
,
padding_y
,
padding_x
);
img2col
(
temp
,
data
,
n
,
filters
.
nr
(),
filters
.
nc
(),
last_
stride_y
,
last_
stride_x
,
last_
padding_y
,
last_
padding_x
);
output
.
set_sample
(
n
,
mat
(
filters
)
*
trans
(
temp
));
output
.
set_sample
(
n
,
mat
(
filters
)
*
trans
(
temp
));
}
}
last_stride_y
=
stride_y
;
last_stride_x
=
stride_x
;
last_padding_y
=
padding_y
;
last_padding_x
=
padding_x
;
}
}
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
...
...
dlib/dnn/cpu_dlib.h
View file @
f9bb4f47
...
@@ -368,14 +368,29 @@ namespace dlib
...
@@ -368,14 +368,29 @@ namespace dlib
void
clear
(
void
clear
(
)
{}
)
{}
void
operator
()
(
void
setup
(
resizable_tensor
&
output
,
const
tensor
&
data
,
/* not used but required for interface */
const
tensor
&
data
,
const
tensor
&
filters
,
/* not used but required for interface */
const
tensor
&
filters
,
int
stride_y
,
int
stride_y
,
int
stride_x
,
int
stride_x
,
int
padding_y
,
int
padding_y
,
int
padding_x
int
padding_x
)
{
(
void
)
data
;
/* silence compiler */
DLIB_CASSERT
(
stride_y
>
0
&&
stride_x
>
0
);
DLIB_CASSERT
(
0
<=
padding_y
&&
padding_y
<
filters
.
nr
());
DLIB_CASSERT
(
0
<=
padding_x
&&
padding_x
<
filters
.
nc
());
last_stride_y
=
stride_y
;
last_stride_x
=
stride_x
;
last_padding_y
=
padding_y
;
last_padding_x
=
padding_x
;
}
void
operator
()
(
resizable_tensor
&
output
,
const
tensor
&
data
,
const
tensor
&
filters
);
);
void
get_gradient_for_data
(
void
get_gradient_for_data
(
...
...
dlib/dnn/cudnn_dlibapi.cpp
View file @
f9bb4f47
...
@@ -953,11 +953,7 @@ namespace dlib
...
@@ -953,11 +953,7 @@ namespace dlib
void
tensor_conv
::
operator
()
(
void
tensor_conv
::
operator
()
(
resizable_tensor
&
output
,
resizable_tensor
&
output
,
const
tensor
&
data
,
const
tensor
&
data
,
const
tensor
&
filters
,
const
tensor
&
filters
int
stride_y
,
int
stride_x
,
int
padding_y
,
int
padding_x
)
)
{
{
DLIB_CASSERT
(
is_same_object
(
output
,
data
)
==
false
);
DLIB_CASSERT
(
is_same_object
(
output
,
data
)
==
false
);
...
@@ -978,8 +974,6 @@ namespace dlib
...
@@ -978,8 +974,6 @@ namespace dlib
);
);
setup
(
data
,
filters
,
stride_y
,
stride_x
,
padding_y
,
padding_x
);
output
.
set_size
(
out_num_samples
,
out_k
,
out_nr
,
out_nc
);
output
.
set_size
(
out_num_samples
,
out_k
,
out_nr
,
out_nc
);
DLIB_ASSERT
(
output
.
num_samples
()
==
data
.
num_samples
(),
out_num_samples
<<
" "
<<
data
.
num_samples
());
DLIB_ASSERT
(
output
.
num_samples
()
==
data
.
num_samples
(),
out_num_samples
<<
" "
<<
data
.
num_samples
());
...
...
dlib/dnn/cudnn_dlibapi.h
View file @
f9bb4f47
...
@@ -205,11 +205,7 @@ namespace dlib
...
@@ -205,11 +205,7 @@ namespace dlib
void
operator
()
(
void
operator
()
(
resizable_tensor
&
output
,
resizable_tensor
&
output
,
const
tensor
&
data
,
const
tensor
&
data
,
const
tensor
&
filters
,
const
tensor
&
filters
int
stride_y
,
int
stride_x
,
int
padding_y
,
int
padding_x
);
);
/*!
/*!
requires
requires
...
@@ -270,8 +266,6 @@ namespace dlib
...
@@ -270,8 +266,6 @@ namespace dlib
and assigns this gradient to filters_gradient.
and assigns this gradient to filters_gradient.
!*/
!*/
private:
void
setup
(
void
setup
(
const
tensor
&
data
,
const
tensor
&
data
,
const
tensor
&
filters
,
const
tensor
&
filters
,
...
@@ -280,6 +274,9 @@ namespace dlib
...
@@ -280,6 +274,9 @@ namespace dlib
int
padding_y
,
int
padding_y
,
int
padding_x
int
padding_x
);
);
private:
/*!
/*!
requires
requires
- filters.k() == data.k()
- filters.k() == data.k()
...
...
dlib/dnn/layers.h
View file @
f9bb4f47
...
@@ -147,14 +147,16 @@ namespace dlib
...
@@ -147,14 +147,16 @@ namespace dlib
template
<
typename
SUBNET
>
template
<
typename
SUBNET
>
void
forward
(
const
SUBNET
&
sub
,
resizable_tensor
&
output
)
void
forward
(
const
SUBNET
&
sub
,
resizable_tensor
&
output
)
{
{
conv
(
output
,
conv
.
setup
(
sub
.
get_output
(),
sub
.
get_output
(),
filters
(
params
,
0
),
filters
(
params
,
0
),
_stride_y
,
_stride_y
,
_stride_x
,
_stride_x
,
padding_y_
,
padding_y_
,
padding_x_
padding_x_
);
);
conv
(
output
,
sub
.
get_output
(),
filters
(
params
,
0
));
tt
::
add
(
1
,
output
,
1
,
biases
(
params
,
filters
.
size
()));
tt
::
add
(
1
,
output
,
1
,
biases
(
params
,
filters
.
size
()));
}
}
...
@@ -306,6 +308,297 @@ namespace dlib
...
@@ -306,6 +308,297 @@ namespace dlib
>
>
using
con
=
add_layer
<
con_
<
num_filters
,
nr
,
nc
,
stride_y
,
stride_x
>
,
SUBNET
>
;
using
con
=
add_layer
<
con_
<
num_filters
,
nr
,
nc
,
stride_y
,
stride_x
>
,
SUBNET
>
;
// ----------------------------------------------------------------------------------------
template
<
long
_num_filters
,
long
_nr
,
long
_nc
,
int
_stride_y
,
int
_stride_x
,
int
_padding_y
=
_stride_y
!=
1
?
0
:
_nr
/
2
,
int
_padding_x
=
_stride_x
!=
1
?
0
:
_nc
/
2
>
class
cont_
{
public:
static_assert
(
_num_filters
>
0
,
"The number of filters must be > 0"
);
static_assert
(
_nr
>
0
,
"The number of rows in a filter must be > 0"
);
static_assert
(
_nc
>
0
,
"The number of columns in a filter must be > 0"
);
static_assert
(
_stride_y
>
0
,
"The filter stride must be > 0"
);
static_assert
(
_stride_x
>
0
,
"The filter stride must be > 0"
);
static_assert
(
0
<=
_padding_y
&&
_padding_y
<
_nr
,
"The padding must be smaller than the filter size."
);
static_assert
(
0
<=
_padding_x
&&
_padding_x
<
_nc
,
"The padding must be smaller than the filter size."
);
cont_
(
)
:
learning_rate_multiplier
(
1
),
weight_decay_multiplier
(
1
),
bias_learning_rate_multiplier
(
1
),
bias_weight_decay_multiplier
(
0
),
padding_y_
(
_padding_y
),
padding_x_
(
_padding_x
)
{
}
long
num_filters
()
const
{
return
_num_filters
;
}
long
nr
()
const
{
return
_nr
;
}
long
nc
()
const
{
return
_nc
;
}
long
stride_y
()
const
{
return
_stride_y
;
}
long
stride_x
()
const
{
return
_stride_x
;
}
long
padding_y
()
const
{
return
padding_y_
;
}
long
padding_x
()
const
{
return
padding_x_
;
}
double
get_learning_rate_multiplier
()
const
{
return
learning_rate_multiplier
;
}
double
get_weight_decay_multiplier
()
const
{
return
weight_decay_multiplier
;
}
void
set_learning_rate_multiplier
(
double
val
)
{
learning_rate_multiplier
=
val
;
}
void
set_weight_decay_multiplier
(
double
val
)
{
weight_decay_multiplier
=
val
;
}
double
get_bias_learning_rate_multiplier
()
const
{
return
bias_learning_rate_multiplier
;
}
double
get_bias_weight_decay_multiplier
()
const
{
return
bias_weight_decay_multiplier
;
}
void
set_bias_learning_rate_multiplier
(
double
val
)
{
bias_learning_rate_multiplier
=
val
;
}
void
set_bias_weight_decay_multiplier
(
double
val
)
{
bias_weight_decay_multiplier
=
val
;
}
inline
point
map_output_to_input
(
point
p
)
const
{
p
.
x
()
=
(
p
.
x
()
+
padding_x
()
-
nc
()
/
2
)
/
stride_x
();
p
.
y
()
=
(
p
.
y
()
+
padding_y
()
-
nr
()
/
2
)
/
stride_y
();
return
p
;
}
inline
point
map_input_to_output
(
point
p
)
const
{
p
.
x
()
=
p
.
x
()
*
stride_x
()
-
padding_x
()
+
nc
()
/
2
;
p
.
y
()
=
p
.
y
()
*
stride_y
()
-
padding_y
()
+
nr
()
/
2
;
return
p
;
}
cont_
(
const
cont_
&
item
)
:
params
(
item
.
params
),
filters
(
item
.
filters
),
biases
(
item
.
biases
),
learning_rate_multiplier
(
item
.
learning_rate_multiplier
),
weight_decay_multiplier
(
item
.
weight_decay_multiplier
),
bias_learning_rate_multiplier
(
item
.
bias_learning_rate_multiplier
),
bias_weight_decay_multiplier
(
item
.
bias_weight_decay_multiplier
),
padding_y_
(
item
.
padding_y_
),
padding_x_
(
item
.
padding_x_
)
{
// this->conv is non-copyable and basically stateless, so we have to write our
// own copy to avoid trying to copy it and getting an error.
}
cont_
&
operator
=
(
const
cont_
&
item
)
{
if
(
this
==
&
item
)
return
*
this
;
// this->conv is non-copyable and basically stateless, so we have to write our
// own copy to avoid trying to copy it and getting an error.
params
=
item
.
params
;
filters
=
item
.
filters
;
biases
=
item
.
biases
;
padding_y_
=
item
.
padding_y_
;
padding_x_
=
item
.
padding_x_
;
learning_rate_multiplier
=
item
.
learning_rate_multiplier
;
weight_decay_multiplier
=
item
.
weight_decay_multiplier
;
bias_learning_rate_multiplier
=
item
.
bias_learning_rate_multiplier
;
bias_weight_decay_multiplier
=
item
.
bias_weight_decay_multiplier
;
return
*
this
;
}
template
<
typename
SUBNET
>
void
setup
(
const
SUBNET
&
sub
)
{
long
num_inputs
=
_nr
*
_nc
*
sub
.
get_output
().
k
();
long
num_outputs
=
_num_filters
;
// allocate params for the filters and also for the filter bias values.
params
.
set_size
(
num_inputs
*
_num_filters
+
_num_filters
);
dlib
::
rand
rnd
(
std
::
rand
());
randomize_parameters
(
params
,
num_inputs
+
num_outputs
,
rnd
);
filters
=
alias_tensor
(
sub
.
get_output
().
k
(),
_num_filters
,
_nr
,
_nc
);
biases
=
alias_tensor
(
1
,
_num_filters
);
// set the initial bias values to zero
biases
(
params
,
_num_filters
)
=
0
;
}
template
<
typename
SUBNET
>
void
forward
(
const
SUBNET
&
sub
,
resizable_tensor
&
output
)
{
auto
filt
=
filters
(
params
,
0
);
unsigned
int
gnr
=
_stride_y
*
(
sub
.
get_output
().
nr
()
-
1
)
+
filt
.
nr
()
-
2
*
padding_y_
;
unsigned
int
gnc
=
_stride_x
*
(
sub
.
get_output
().
nc
()
-
1
)
+
filt
.
nc
()
-
2
*
padding_x_
;
unsigned
int
gnsamps
=
sub
.
get_output
().
num_samples
();
unsigned
int
gk
=
filt
.
k
();
output
.
set_size
(
gnsamps
,
gk
,
gnr
,
gnc
);
output
=
0
;
conv
.
setup
(
output
,
filt
,
_stride_y
,
_stride_x
,
padding_y_
,
padding_x_
);
conv
.
get_gradient_for_data
(
sub
.
get_output
(),
filt
,
output
);
tt
::
add
(
1
,
output
,
1
,
biases
(
params
,
filters
.
size
()));
}
template
<
typename
SUBNET
>
void
backward
(
const
tensor
&
gradient_input
,
SUBNET
&
sub
,
tensor
&
params_grad
)
{
resizable_tensor
temp
;
temp
.
copy_size
(
sub
.
get_gradient_input
());
auto
filt
=
filters
(
params
,
0
);
conv
(
temp
,
gradient_input
,
filt
);
// need to add the new gradients on top of the previous ones
tt
::
add
(
1
,
sub
.
get_gradient_input
(),
1
,
temp
);
// no point computing the parameter gradients if they won't be used.
if
(
learning_rate_multiplier
!=
0
)
{
auto
filt
=
filters
(
params_grad
,
0
);
conv
.
get_gradient_for_filters
(
sub
.
get_output
(),
gradient_input
,
filt
);
auto
b
=
biases
(
params_grad
,
filters
.
size
());
tt
::
assign_conv_bias_gradient
(
b
,
gradient_input
);
}
}
const
tensor
&
get_layer_params
()
const
{
return
params
;
}
tensor
&
get_layer_params
()
{
return
params
;
}
friend
void
serialize
(
const
cont_
&
item
,
std
::
ostream
&
out
)
{
serialize
(
"cont_1"
,
out
);
serialize
(
item
.
params
,
out
);
serialize
(
_num_filters
,
out
);
serialize
(
_nr
,
out
);
serialize
(
_nc
,
out
);
serialize
(
_stride_y
,
out
);
serialize
(
_stride_x
,
out
);
serialize
(
item
.
padding_y_
,
out
);
serialize
(
item
.
padding_x_
,
out
);
serialize
(
item
.
filters
,
out
);
serialize
(
item
.
biases
,
out
);
serialize
(
item
.
learning_rate_multiplier
,
out
);
serialize
(
item
.
weight_decay_multiplier
,
out
);
serialize
(
item
.
bias_learning_rate_multiplier
,
out
);
serialize
(
item
.
bias_weight_decay_multiplier
,
out
);
}
friend
void
deserialize
(
cont_
&
item
,
std
::
istream
&
in
)
{
std
::
string
version
;
deserialize
(
version
,
in
);
long
num_filters
;
long
nr
;
long
nc
;
int
stride_y
;
int
stride_x
;
if
(
version
==
"cont_1"
)
{
deserialize
(
item
.
params
,
in
);
deserialize
(
num_filters
,
in
);
deserialize
(
nr
,
in
);
deserialize
(
nc
,
in
);
deserialize
(
stride_y
,
in
);
deserialize
(
stride_x
,
in
);
deserialize
(
item
.
padding_y_
,
in
);
deserialize
(
item
.
padding_x_
,
in
);
deserialize
(
item
.
filters
,
in
);
deserialize
(
item
.
biases
,
in
);
deserialize
(
item
.
learning_rate_multiplier
,
in
);
deserialize
(
item
.
weight_decay_multiplier
,
in
);
deserialize
(
item
.
bias_learning_rate_multiplier
,
in
);
deserialize
(
item
.
bias_weight_decay_multiplier
,
in
);
if
(
item
.
padding_y_
!=
_padding_y
)
throw
serialization_error
(
"Wrong padding_y found while deserializing dlib::con_"
);
if
(
item
.
padding_x_
!=
_padding_x
)
throw
serialization_error
(
"Wrong padding_x found while deserializing dlib::con_"
);
if
(
num_filters
!=
_num_filters
)
{
std
::
ostringstream
sout
;
sout
<<
"Wrong num_filters found while deserializing dlib::con_"
<<
std
::
endl
;
sout
<<
"expected "
<<
_num_filters
<<
" but found "
<<
num_filters
<<
std
::
endl
;
throw
serialization_error
(
sout
.
str
());
}
if
(
nr
!=
_nr
)
throw
serialization_error
(
"Wrong nr found while deserializing dlib::con_"
);
if
(
nc
!=
_nc
)
throw
serialization_error
(
"Wrong nc found while deserializing dlib::con_"
);
if
(
stride_y
!=
_stride_y
)
throw
serialization_error
(
"Wrong stride_y found while deserializing dlib::con_"
);
if
(
stride_x
!=
_stride_x
)
throw
serialization_error
(
"Wrong stride_x found while deserializing dlib::con_"
);
}
else
{
throw
serialization_error
(
"Unexpected version '"
+
version
+
"' found while deserializing dlib::con_."
);
}
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
cont_
&
item
)
{
out
<<
"cont
\t
("
<<
"num_filters="
<<
_num_filters
<<
", nr="
<<
_nr
<<
", nc="
<<
_nc
<<
", stride_y="
<<
_stride_y
<<
", stride_x="
<<
_stride_x
<<
", padding_y="
<<
item
.
padding_y_
<<
", padding_x="
<<
item
.
padding_x_
<<
")"
;
out
<<
" learning_rate_mult="
<<
item
.
learning_rate_multiplier
;
out
<<
" weight_decay_mult="
<<
item
.
weight_decay_multiplier
;
out
<<
" bias_learning_rate_mult="
<<
item
.
bias_learning_rate_multiplier
;
out
<<
" bias_weight_decay_mult="
<<
item
.
bias_weight_decay_multiplier
;
return
out
;
}
friend
void
to_xml
(
const
cont_
&
item
,
std
::
ostream
&
out
)
{
out
<<
"<cont"
<<
" num_filters='"
<<
_num_filters
<<
"'"
<<
" nr='"
<<
_nr
<<
"'"
<<
" nc='"
<<
_nc
<<
"'"
<<
" stride_y='"
<<
_stride_y
<<
"'"
<<
" stride_x='"
<<
_stride_x
<<
"'"
<<
" padding_y='"
<<
item
.
padding_y_
<<
"'"
<<
" padding_x='"
<<
item
.
padding_x_
<<
"'"
<<
" learning_rate_mult='"
<<
item
.
learning_rate_multiplier
<<
"'"
<<
" weight_decay_46mult='"
<<
item
.
weight_decay_multiplier
<<
"'"
<<
" bias_learning_rate_mult='"
<<
item
.
bias_learning_rate_multiplier
<<
"'"
<<
" bias_weight_decay_mult='"
<<
item
.
bias_weight_decay_multiplier
<<
"'>
\n
"
;
out
<<
mat
(
item
.
params
);
out
<<
"</cont>"
;
}
private:
resizable_tensor
params
;
alias_tensor
filters
,
biases
;
tt
::
tensor_conv
conv
;
double
learning_rate_multiplier
;
double
weight_decay_multiplier
;
double
bias_learning_rate_multiplier
;
double
bias_weight_decay_multiplier
;
int
padding_y_
;
int
padding_x_
;
};
template
<
long
num_filters
,
long
nr
,
long
nc
,
int
stride_y
,
int
stride_x
,
typename
SUBNET
>
using
cont
=
add_layer
<
cont_
<
num_filters
,
nr
,
nc
,
stride_y
,
stride_x
>
,
SUBNET
>
;
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
...
dlib/dnn/layers_abstract.h
View file @
f9bb4f47
...
@@ -840,6 +840,217 @@ namespace dlib
...
@@ -840,6 +840,217 @@ namespace dlib
>
>
using
con
=
add_layer
<
con_
<
num_filters
,
nr
,
nc
,
stride_y
,
stride_x
>
,
SUBNET
>
;
using
con
=
add_layer
<
con_
<
num_filters
,
nr
,
nc
,
stride_y
,
stride_x
>
,
SUBNET
>
;
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
long
_num_filters
,
long
_nr
,
long
_nc
,
int
_stride_y
,
int
_stride_x
,
int
_padding_y
=
_stride_y
!=
1
?
0
:
_nr
/
2
,
int
_padding_x
=
_stride_x
!=
1
?
0
:
_nc
/
2
>
class
cont_
{
/*!
REQUIREMENTS ON TEMPLATE ARGUMENTS
All of them must be > 0.
Also, we require that:
- 0 <= _padding_y && _padding_y < _nr
- 0 <= _padding_x && _padding_x < _nc
WHAT THIS OBJECT REPRESENTS
This is an implementation of the EXAMPLE_COMPUTATIONAL_LAYER_ interface
defined above. In particular, it defines a transposed convolution layer
that takes an input tensor (nominally representing an image) and
transpose convolves (deconvolves) it with a set of filters and then outputs the results.
This is basically a convolutional layer with reversed forward/backward passes
The dimensions of the tensors output by this layer are as follows (letting
IN be the input tensor and OUT the output tensor):
- OUT.num_samples() == IN.num_samples()
- OUT.k() == num_filters()
- OUT.nr() == stride_y * (IN.nr() -1) + nr) - 2*padding_y
- OUT.nc() == stride_x * (IN.nc() -1) + nc) - 2*padding_x
!*/
public:
cont_
(
);
/*!
ensures
- #num_filters() == _num_filters
- #nr() == _nr
- #nc() == _nc
- #stride_y() == _stride_y
- #stride_x() == _stride_x
- #padding_y() == _padding_y
- #padding_x() == _padding_x
- #get_learning_rate_multiplier() == 1
- #get_weight_decay_multiplier() == 1
- #get_bias_learning_rate_multiplier() == 1
- #get_bias_weight_decay_multiplier() == 0
!*/
long
num_filters
(
)
const
;
/*!
ensures
- returns the number of filters contained in this layer. The k dimension
of the output tensors produced by this layer will be equal to the number
of filters.
!*/
long
nr
(
)
const
;
/*!
ensures
- returns the number of rows in the filters in this layer.
!*/
long
nc
(
)
const
;
/*!
ensures
- returns the number of columns in the filters in this layer.
!*/
long
stride_y
(
)
const
;
/*!
ensures
- returns the vertical stride used when convolving the filters over an
image. That is, each filter will be moved stride_y() pixels down at a
time when it moves over the image.
!*/
long
stride_x
(
)
const
;
/*!
ensures
- returns the horizontal stride used when convolving the filters over an
image. That is, each filter will be moved stride_x() pixels right at a
time when it moves over the image.
!*/
long
padding_y
(
)
const
;
/*!
ensures
- returns the number of pixels of zero padding added to the top and bottom
sides of the image.
!*/
long
padding_x
(
)
const
;
/*!
ensures
- returns the number of pixels of zero padding added to the left and right
sides of the image.
!*/
double
get_learning_rate_multiplier
(
)
const
;
/*!
ensures
- returns a multiplier number. The interpretation is that this object is
requesting that the learning rate used to optimize its parameters be
multiplied by get_learning_rate_multiplier().
!*/
double
get_weight_decay_multiplier
(
)
const
;
/*!
ensures
- returns a multiplier number. The interpretation is that this object is
requesting that the weight decay used to optimize its parameters be
multiplied by get_weight_decay_multiplier().
!*/
void
set_learning_rate_multiplier
(
double
val
);
/*!
requires
- val >= 0
ensures
- #get_learning_rate_multiplier() == val
!*/
void
set_weight_decay_multiplier
(
double
val
);
/*!
requires
- val >= 0
ensures
- #get_weight_decay_multiplier() == val
!*/
double
get_bias_learning_rate_multiplier
(
)
const
;
/*!
ensures
- returns a multiplier number. The interpretation is that this object is
requesting that the learning rate used to optimize its bias parameters be
multiplied by get_learning_rate_multiplier()*get_bias_learning_rate_multiplier().
!*/
double
get_bias_weight_decay_multiplier
(
)
const
;
/*!
ensures
- returns a multiplier number. The interpretation is that this object is
requesting that the weight decay used to optimize its bias parameters be
multiplied by get_weight_decay_multiplier()*get_bias_weight_decay_multiplier().
!*/
void
set_bias_learning_rate_multiplier
(
double
val
);
/*!
requires
- val >= 0
ensures
- #get_bias_learning_rate_multiplier() == val
!*/
void
set_bias_weight_decay_multiplier
(
double
val
);
/*!
requires
- val >= 0
ensures
- #get_bias_weight_decay_multiplier() == val
!*/
template
<
typename
SUBNET
>
void
setup
(
const
SUBNET
&
sub
);
template
<
typename
SUBNET
>
void
forward
(
const
SUBNET
&
sub
,
resizable_tensor
&
output
);
template
<
typename
SUBNET
>
void
backward
(
const
tensor
&
gradient_input
,
SUBNET
&
sub
,
tensor
&
params_grad
);
point
map_input_to_output
(
point
p
)
const
;
point
map_output_to_input
(
point
p
)
const
;
const
tensor
&
get_layer_params
()
const
;
tensor
&
get_layer_params
();
/*!
These functions are implemented as described in the EXAMPLE_COMPUTATIONAL_LAYER_ interface.
!*/
};
template
<
long
num_filters
,
long
nr
,
long
nc
,
int
stride_y
,
int
stride_x
,
typename
SUBNET
>
using
cont
=
add_layer
<
cont_
<
num_filters
,
nr
,
nc
,
stride_y
,
stride_x
>
,
SUBNET
>
;
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class
dropout_
class
dropout_
...
...
dlib/dnn/tensor_tools.h
View file @
f9bb4f47
...
@@ -879,12 +879,8 @@ namespace dlib { namespace tt
...
@@ -879,12 +879,8 @@ namespace dlib { namespace tt
void
operator
()
(
void
operator
()
(
resizable_tensor
&
output
,
resizable_tensor
&
output
,
const
tensor
&
data
,
const
tensor
&
data
,
const
tensor
&
filters
,
const
tensor
&
filters
int
stride_y
,
)
{
impl
(
output
,
data
,
filters
);
}
int
stride_x
,
int
padding_y
,
int
padding_x
)
{
impl
(
output
,
data
,
filters
,
stride_y
,
stride_x
,
padding_y
,
padding_x
);
}
/*!
/*!
requires
requires
- stride_y > 0
- stride_y > 0
...
@@ -947,6 +943,16 @@ namespace dlib { namespace tt
...
@@ -947,6 +943,16 @@ namespace dlib { namespace tt
this gradient to filters_gradient.
this gradient to filters_gradient.
!*/
!*/
void
setup
(
const
tensor
&
data
,
const
tensor
&
filters
,
int
stride_y
,
int
stride_x
,
int
padding_y
,
int
padding_x
)
{
impl
.
setup
(
data
,
filters
,
stride_y
,
stride_x
,
padding_y
,
padding_x
);
}
private:
private:
#ifdef DLIB_USE_CUDA
#ifdef DLIB_USE_CUDA
cuda
::
tensor_conv
impl
;
cuda
::
tensor_conv
impl
;
...
...
dlib/test/dnn.cpp
View file @
f9bb4f47
...
@@ -805,8 +805,10 @@ namespace
...
@@ -805,8 +805,10 @@ namespace
padding_y
=
(
filters
.
nr
()
-
data
.
nr
()
+
1
)
/
2
;
padding_y
=
(
filters
.
nr
()
-
data
.
nr
()
+
1
)
/
2
;
if
(
!
(
filters
.
nc
()
<=
data
.
nc
()
+
2
*
padding_x
))
if
(
!
(
filters
.
nc
()
<=
data
.
nc
()
+
2
*
padding_x
))
padding_x
=
(
filters
.
nc
()
-
data
.
nc
()
+
1
)
/
2
;
padding_x
=
(
filters
.
nc
()
-
data
.
nc
()
+
1
)
/
2
;
conv1
(
output1
,
data
,
filters
,
stride_y
,
stride_x
,
padding_y
,
padding_x
);
conv1
.
setup
(
data
,
filters
,
stride_y
,
stride_x
,
padding_y
,
padding_x
);
conv2
(
output2
,
data
,
filters
,
stride_y
,
stride_x
,
padding_y
,
padding_x
);
conv1
(
output1
,
data
,
filters
);
conv2
.
setup
(
data
,
filters
,
stride_y
,
stride_x
,
padding_y
,
padding_x
);
conv2
(
output2
,
data
,
filters
);
dlog
<<
LINFO
<<
"forward error: "
<<
max
(
abs
(
mat
(
output1
)
-
mat
(
output2
)));
dlog
<<
LINFO
<<
"forward error: "
<<
max
(
abs
(
mat
(
output1
)
-
mat
(
output2
)));
DLIB_TEST_MSG
(
max
(
abs
(
mat
(
output1
)
-
mat
(
output2
)))
<
1e-3
,
max
(
abs
(
mat
(
output1
)
-
mat
(
output2
)))
DLIB_TEST_MSG
(
max
(
abs
(
mat
(
output1
)
-
mat
(
output2
)))
<
1e-3
,
max
(
abs
(
mat
(
output1
)
-
mat
(
output2
)))
<<
"
\n\t
padding_y: "
<<
padding_y
<<
"
\n\t
padding_y: "
<<
padding_y
...
@@ -1473,6 +1475,24 @@ namespace
...
@@ -1473,6 +1475,24 @@ namespace
auto
res
=
test_layer
(
l
);
auto
res
=
test_layer
(
l
);
DLIB_TEST_MSG
(
res
,
res
);
DLIB_TEST_MSG
(
res
,
res
);
}
}
{
print_spinner
();
cont_
<
3
,
3
,
3
,
2
,
2
>
l
;
auto
res
=
test_layer
(
l
);
DLIB_TEST_MSG
(
res
,
res
);
}
{
print_spinner
();
cont_
<
3
,
3
,
3
,
1
,
1
>
l
;
auto
res
=
test_layer
(
l
);
DLIB_TEST_MSG
(
res
,
res
);
}
{
print_spinner
();
cont_
<
3
,
2
,
2
,
2
,
2
>
l
;
auto
res
=
test_layer
(
l
);
DLIB_TEST_MSG
(
res
,
res
);
}
{
{
print_spinner
();
print_spinner
();
con_
<
3
,
2
,
2
,
2
,
2
>
l
;
con_
<
3
,
2
,
2
,
2
,
2
>
l
;
...
...
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