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
06b82654
"src/graph/vscode:/vscode.git/clone" did not exist on "33abd2757b29c3c98cbecdb8113d338a277d8125"
Unverified
Commit
06b82654
authored
May 08, 2022
by
Adrià Arrufat
Committed by
GitHub
May 08, 2022
Browse files
Add SiLU activation layer (#2584)
parent
8af42260
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
333 additions
and
1 deletion
+333
-1
dlib/cuda/cpu_dlib.cpp
dlib/cuda/cpu_dlib.cpp
+42
-0
dlib/cuda/cpu_dlib.h
dlib/cuda/cpu_dlib.h
+13
-0
dlib/cuda/cuda_dlib.cu
dlib/cuda/cuda_dlib.cu
+52
-0
dlib/cuda/cuda_dlib.h
dlib/cuda/cuda_dlib.h
+13
-0
dlib/cuda/tensor_tools.cpp
dlib/cuda/tensor_tools.cpp
+28
-0
dlib/cuda/tensor_tools.h
dlib/cuda/tensor_tools.h
+35
-0
dlib/dnn/layers.h
dlib/dnn/layers.h
+72
-1
dlib/dnn/layers_abstract.h
dlib/dnn/layers_abstract.h
+38
-0
dlib/dnn/visitors.h
dlib/dnn/visitors.h
+8
-0
dlib/test/dnn.cpp
dlib/test/dnn.cpp
+32
-0
No files found.
dlib/cuda/cpu_dlib.cpp
View file @
06b82654
...
...
@@ -1998,6 +1998,8 @@ namespace dlib
}
}
// ----------------------------------------------------------------------------------------
void
smelu
(
tensor
&
dest
,
const
tensor
&
src
,
...
...
@@ -2053,6 +2055,46 @@ namespace dlib
}
}
// ----------------------------------------------------------------------------------------
void
silu
(
tensor
&
dest
,
const
tensor
&
src
)
{
const
auto
d
=
dest
.
host
();
const
auto
s
=
src
.
host
();
for
(
size_t
i
=
0
;
i
<
src
.
size
();
++
i
)
d
[
i
]
=
s
[
i
]
*
impl
::
sigmoid
(
s
[
i
]);
}
void
silu_gradient
(
tensor
&
grad
,
const
tensor
&
src
,
const
tensor
&
gradient_input
)
{
const
auto
g
=
grad
.
host
();
const
auto
s
=
src
.
host
();
const
auto
in
=
gradient_input
.
host
();
if
(
is_same_object
(
grad
,
gradient_input
))
{
for
(
size_t
i
=
0
;
i
<
src
.
size
();
++
i
)
{
const
auto
sig_s
=
impl
::
sigmoid
(
s
[
i
]);
g
[
i
]
=
in
[
i
]
*
(
sig_s
*
(
1.0
f
+
s
[
i
]
*
(
1.0
f
-
sig_s
)));
}
}
else
{
for
(
size_t
i
=
0
;
i
<
src
.
size
();
++
i
)
{
const
auto
sig_s
=
impl
::
sigmoid
(
s
[
i
]);
g
[
i
]
+=
in
[
i
]
*
(
sig_s
*
(
1.0
f
+
s
[
i
]
*
(
1.0
f
-
sig_s
)));
}
}
}
// ----------------------------------------------------------------------------------------
void
resize_bilinear
(
...
...
dlib/cuda/cpu_dlib.h
View file @
06b82654
...
...
@@ -434,6 +434,19 @@ namespace dlib
const
float
beta
);
// ----------------------------------------------------------------------------------------
void
silu
(
tensor
&
dest
,
const
tensor
&
src
);
void
silu_gradient
(
tensor
&
grad
,
const
tensor
&
dest
,
const
tensor
&
gradient_input
);
// ------------------------------------------------------------------------------------
void
resize_bilinear
(
...
...
dlib/cuda/cuda_dlib.cu
View file @
06b82654
...
...
@@ -1729,6 +1729,58 @@ namespace dlib
out
,
src
.
device
(),
gi
,
grad
.
size
(),
beta
);
}
}
// ----------------------------------------------------------------------------------------
__global__
void
_cuda_silu
(
const
float
*
s
,
float
*
d
,
size_t
n
)
{
for
(
auto
i
:
grid_stride_range
(
0
,
n
))
{
d
[
i
]
=
s
[
i
]
/
(
1.0
f
+
std
::
exp
(
-
s
[
i
]));
}
}
void
silu
(
tensor
&
dest
,
const
tensor
&
src
)
{
launch_kernel
(
_cuda_silu
,
max_jobs
(
dest
.
size
()),
src
.
device
(),
dest
.
device
(),
src
.
size
());
}
// ----------------------------------------------------------------------------------------
__global__
void
_cuda_silu_gradient_inplace
(
float
*
out
,
const
float
*
s
,
const
float
*
gi
,
size_t
n
)
{
for
(
auto
i
:
grid_stride_range
(
0
,
n
))
{
const
auto
sig_s
=
1.0
f
/
(
1.0
f
+
std
::
exp
(
-
s
[
i
]));
out
[
i
]
=
gi
[
i
]
*
(
sig_s
*
(
1.0
f
+
s
[
i
]
*
(
1.0
f
-
sig_s
)));
}
}
__global__
void
_cuda_silu_gradient
(
float
*
out
,
const
float
*
s
,
const
float
*
gi
,
size_t
n
)
{
for
(
auto
i
:
grid_stride_range
(
0
,
n
))
{
const
auto
sig_s
=
1.0
f
/
(
1.0
f
+
std
::
exp
(
-
s
[
i
]));
out
[
i
]
+=
gi
[
i
]
*
(
sig_s
*
(
1.0
f
+
s
[
i
]
*
(
1.0
f
-
sig_s
)));
}
}
void
silu_gradient
(
tensor
&
grad
,
const
tensor
&
src
,
const
tensor
&
gradient_input
)
{
float
*
out
=
grad
.
device
();
const
float
*
gi
=
gradient_input
.
device
();
if
(
out
==
gi
)
launch_kernel
(
_cuda_silu_gradient_inplace
,
max_jobs
(
grad
.
size
()),
out
,
src
.
device
(),
gi
,
grad
.
size
());
else
launch_kernel
(
_cuda_silu_gradient
,
max_jobs
(
grad
.
size
()),
out
,
src
.
device
(),
gi
,
grad
.
size
());
}
// ----------------------------------------------------------------------------------------
...
...
dlib/cuda/cuda_dlib.h
View file @
06b82654
...
...
@@ -478,6 +478,19 @@ namespace dlib
const
float
beta
);
// ----------------------------------------------------------------------------------------
void
silu
(
tensor
&
dest
,
const
tensor
&
src
);
void
silu_gradient
(
tensor
&
grad
,
const
tensor
&
src
,
const
tensor
&
gradient_input
);
// ------------------------------------------------------------------------------------
void
resize_bilinear
(
...
...
dlib/cuda/tensor_tools.cpp
View file @
06b82654
...
...
@@ -1118,6 +1118,34 @@ namespace dlib { namespace tt
cpu
::
smelu_gradient
(
grad
,
dest
,
gradient_input
,
beta
);
#endif
}
// ----------------------------------------------------------------------------------------
void
silu
(
tensor
&
dest
,
const
tensor
&
src
)
{
#ifdef DLIB_USE_CUDA
cuda
::
silu
(
dest
,
src
);
#else
cpu
::
silu
(
dest
,
src
);
#endif
}
void
silu_gradient
(
tensor
&
grad
,
const
tensor
&
src
,
const
tensor
&
gradient_input
)
{
#ifdef DLIB_USE_CUDA
cuda
::
silu_gradient
(
grad
,
src
,
gradient_input
);
#else
cpu
::
silu_gradient
(
grad
,
src
,
gradient_input
);
#endif
}
// ----------------------------------------------------------------------------------------
void
resize_bilinear
(
...
...
dlib/cuda/tensor_tools.h
View file @
06b82654
...
...
@@ -1790,6 +1790,41 @@ namespace dlib { namespace tt
is_same_object(grad, gradient_input)==true
!*/
// ----------------------------------------------------------------------------------------
void
silu
(
tensor
&
dest
,
const
tensor
&
src
);
/*!
requires
- have_same_dimensions(dest, src) == true
ensures
- for all valid i:
- #dest.host()[i] == src.host()[i] * sigmoid(src.host()[i])
- This function supports in-place operation, i.e. having
is_same_object(dest, src)==true
!*/
void
silu_gradient
(
tensor
&
grad
,
const
tensor
&
src
,
const
tensor
&
gradient_input
);
/*!
requires
- have_same_dimensions(src,gradient_input) == true
- have_same_dimensions(src,grad) == true
ensures
- Recalling that dest is the output of silu(dest,src), let f(src) ==
dot(gradient_input,dest). Then this function computes the gradient of f() with respect
to src and stores it to grad. Moreover, if is_same_object(grad,gradient_input)==true
then the output is assigned to grad, replacing its previous contents. Otherwise the
output is added to grad.
- This function supports in-place operation, i.e. having
is_same_object(grad, gradient_input)==true
!*/
// ----------------------------------------------------------------------------------------
void
resize_bilinear
(
...
...
dlib/dnn/layers.h
View file @
06b82654
...
...
@@ -3689,7 +3689,7 @@ namespace dlib
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
smelu_
&
item
)
{
out
<<
"smelu
\t
("
out
<<
"smelu
\t
("
<<
"beta="
<<
item
.
beta
<<
")"
;
return
out
;
...
...
@@ -3709,6 +3709,77 @@ namespace dlib
template
<
typename
SUBNET
>
using
smelu
=
add_layer
<
smelu_
,
SUBNET
>
;
// ----------------------------------------------------------------------------------------
class
silu_
{
public:
silu_
(
)
{
}
template
<
typename
SUBNET
>
void
setup
(
const
SUBNET
&
/*sub*/
)
{
}
template
<
typename
SUBNET
>
void
forward
(
const
SUBNET
&
sub
,
resizable_tensor
&
data_ouput
)
{
data_ouput
.
copy_size
(
sub
.
get_output
());
tt
::
silu
(
data_ouput
,
sub
.
get_output
());
}
template
<
typename
SUBNET
>
void
backward
(
const
tensor
&
gradient_input
,
SUBNET
&
sub
,
tensor
&
)
{
tt
::
silu_gradient
(
sub
.
get_gradient_input
(),
sub
.
get_output
(),
gradient_input
);
}
inline
dpoint
map_input_to_output
(
const
dpoint
&
p
)
const
{
return
p
;
}
inline
dpoint
map_output_to_input
(
const
dpoint
&
p
)
const
{
return
p
;
}
const
tensor
&
get_layer_params
()
const
{
return
params
;
}
tensor
&
get_layer_params
()
{
return
params
;
}
friend
void
serialize
(
const
silu_
&
/*item*/
,
std
::
ostream
&
out
)
{
serialize
(
"silu_"
,
out
);
}
friend
void
deserialize
(
silu_
&
/*item*/
,
std
::
istream
&
in
)
{
std
::
string
version
;
deserialize
(
version
,
in
);
if
(
version
!=
"silu_"
)
throw
serialization_error
(
"Unexpected version '"
+
version
+
"' found while deserializing dlib::silu_."
);
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
silu_
&
/*item*/
)
{
out
<<
"silu"
;
return
out
;
}
friend
void
to_xml
(
const
silu_
&
/*item*/
,
std
::
ostream
&
out
)
{
out
<<
"<silu/>
\n
"
;
}
private:
resizable_tensor
params
;
};
template
<
typename
SUBNET
>
using
silu
=
add_layer
<
silu_
,
SUBNET
>
;
// ----------------------------------------------------------------------------------------
class
softmax_
...
...
dlib/dnn/layers_abstract.h
View file @
06b82654
...
...
@@ -2691,6 +2691,44 @@ namespace dlib
template
<
typename
SUBNET
>
using
smelu
=
add_layer
<
prelu_
,
SUBNET
>
;
// ----------------------------------------------------------------------------------------
class
silu_
{
/*!
WHAT THIS OBJECT REPRESENTS
This is an implementation of the EXAMPLE_COMPUTATIONAL_LAYER_ interface
defined above. In particular, it defines a silu layer. Therefore, it
passes its inputs through the function
f(x)= x * sigmoid(x) = x / (1 + exp(-x))
where f() is applied pointwise across the input tensor.
This is the layer type introduced in the paper:
Dan Hendrycks, Kevin Gimpel. "Gaussian Error Linear Units (GELUs)".
!*/
public:
silu_
(
);
template
<
typename
SUBNET
>
void
setup
(
const
SUBNET
&
sub
);
template
<
typename
SUBNET
>
void
forward
(
const
SUBNET
&
sub
,
resizable_tensor
&
data_output
);
template
<
typename
SUBNET
>
void
backward
(
const
tensor
&
gradient_input
,
SUBNET
&
sub
,
tensor
&
);
dpoint
map_input_to_output
(
dpoint
p
)
const
;
dpoint
map_output_to_input
(
dpoint
p
)
const
;
const
tensor
&
get_layer_params
()
const
;
tensor
&
get_layer_params
();
/*!
These functions are implemented as described in the EXAMPLE_COMPUTATIONAL_LAYER_
interface. Note that this layer doesn't have any parameters, so the tensor
returned by get_layer_params() is always empty.
!*/
};
template
<
typename
SUBNET
>
using
silu
=
add_layer
<
silu_
,
SUBNET
>
;
// ----------------------------------------------------------------------------------------
class
softmax_
...
...
dlib/dnn/visitors.h
View file @
06b82654
...
...
@@ -870,6 +870,14 @@ namespace dlib
update
(
i
);
}
template
<
typename
U
,
typename
E
>
void
operator
()(
size_t
i
,
const
add_layer
<
silu_
,
U
,
E
>&
)
{
start_node
(
i
,
"silu"
);
end_node
();
update
(
i
);
}
template
<
typename
U
,
typename
E
>
void
operator
()(
size_t
i
,
const
add_layer
<
softmax_
,
U
,
E
>&
)
{
...
...
dlib/test/dnn.cpp
View file @
06b82654
...
...
@@ -398,6 +398,31 @@ namespace
#endif // DLIB_USE_CUDA
}
void
test_silu
()
{
#ifdef DLIB_USE_CUDA
using
namespace
dlib
::
tt
;
print_spinner
();
const
long
n
=
4
;
const
long
k
=
5
;
const
long
nr
=
3
;
const
long
nc
=
3
;
resizable_tensor
src
(
n
,
k
,
nr
,
nc
);
tt
::
tensor_rand
rnd
;
rnd
.
fill_gaussian
(
src
);
resizable_tensor
dest_cuda
,
dest_cpu
;
dest_cuda
.
copy_size
(
src
);
dest_cpu
.
copy_size
(
src
);
// initialize to different values in order to make sure the output is actually changed
dest_cuda
=
1
;
dest_cpu
=
2
;
cuda
::
silu
(
dest_cuda
,
src
);
cpu
::
silu
(
dest_cpu
,
src
);
DLIB_TEST_MSG
(
max
(
abs
(
mat
(
dest_cuda
)
-
mat
(
dest_cpu
)))
<
1e-6
,
max
(
abs
(
mat
(
dest_cuda
)
-
mat
(
dest_cpu
))));
#endif // DLIB_USE_CUDA
}
void
test_batch_normalize
()
{
using
namespace
dlib
::
tt
;
...
...
@@ -2135,6 +2160,12 @@ namespace
auto
res
=
test_layer
(
l
);
DLIB_TEST_MSG
(
res
,
res
);
}
{
print_spinner
();
silu_
l
;
auto
res
=
test_layer
(
l
);
DLIB_TEST_MSG
(
res
,
res
);
}
{
print_spinner
();
softmax_
l
;
...
...
@@ -4319,6 +4350,7 @@ namespace
test_elu
();
test_gelu
();
test_smelu
();
test_silu
();
test_batch_normalize
();
test_batch_normalize_conv
();
test_layer_normalize
();
...
...
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