Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
a07da949
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a07da949
编写于
11月 08, 2016
作者:
H
hedaoyuan
提交者:
Yu Yang
11月 08, 2016
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix floating-point overflow problem of tanh (#355)
上级
56b23d18
变更
10
显示空白变更内容
内联
并排
Showing
10 changed file
with
119 addition
and
14 deletion
+119
-14
paddle/cuda/include/hl_base.h
paddle/cuda/include/hl_base.h
+9
-0
paddle/cuda/src/hl_avx_functions.cc
paddle/cuda/src/hl_avx_functions.cc
+2
-0
paddle/cuda/src/hl_cpu_functions.cc
paddle/cuda/src/hl_cpu_functions.cc
+3
-1
paddle/gserver/tests/test_LayerGrad.cpp
paddle/gserver/tests/test_LayerGrad.cpp
+1
-1
paddle/gserver/tests/test_RecurrentLayer.cpp
paddle/gserver/tests/test_RecurrentLayer.cpp
+1
-1
paddle/math/BaseMatrix.cu
paddle/math/BaseMatrix.cu
+4
-1
paddle/math/MathFunctions.cpp
paddle/math/MathFunctions.cpp
+4
-1
paddle/math/Matrix.cpp
paddle/math/Matrix.cpp
+0
-9
paddle/math/tests/CMakeLists.txt
paddle/math/tests/CMakeLists.txt
+1
-0
paddle/math/tests/test_FPException.cpp
paddle/math/tests/test_FPException.cpp
+94
-0
未找到文件。
paddle/cuda/include/hl_base.h
浏览文件 @
a07da949
...
...
@@ -209,6 +209,15 @@ typedef struct {
#define HL_FLOAT_MIN 2.2250738585072014e-308
#endif
/**
* The maximum input value for exp, used to avoid overflow problem.
*
* Currently only used for tanh function.
*/
#define EXP_MAX_INPUT 40.0
/**
* @brief DIVUP(x, y) is similar to ceil(x / y).
* @note For CUDA, DIVUP will be used to specify
...
...
paddle/cuda/src/hl_avx_functions.cc
浏览文件 @
a07da949
...
...
@@ -38,7 +38,9 @@ namespace hppl {
}
__m256
tanh
(
const
__m256
a
)
{
__m256
max
=
_mm256_set1_ps
(
EXP_MAX_INPUT
);
__m256
tmp
=
_mm256_mul_ps
(
_mm256_set1_ps
(
-
2.0
f
),
a
);
tmp
=
_mm256_min_ps
(
tmp
,
max
);
tmp
=
exp
(
tmp
);
return
_mm256_sub_ps
(
_mm256_div_ps
(
_mm256_set1_ps
(
2.0
f
),
...
...
paddle/cuda/src/hl_cpu_functions.cc
浏览文件 @
a07da949
...
...
@@ -30,7 +30,9 @@ namespace hppl {
}
real
tanh
(
const
real
a
)
{
return
(
2.0
/
(
1.0
+
exp
(
-
2.0
*
a
)))
-
1.0
;
real
tmp
=
-
2.0
*
a
;
tmp
=
(
tmp
>
EXP_MAX_INPUT
)
?
EXP_MAX_INPUT
:
tmp
;
return
(
2.0
/
(
1.0
+
exp
(
tmp
)))
-
1.0
;
}
real
linear
(
const
real
a
)
{
...
...
paddle/gserver/tests/test_LayerGrad.cpp
浏览文件 @
a07da949
...
...
@@ -995,7 +995,7 @@ TEST(Layer, LstmLayer) {
TestConfig
config
;
config
.
layerConfig
.
set_type
(
"lstmemory"
);
config
.
layerConfig
.
set_size
(
4
);
config
.
layerConfig
.
set_active_type
(
"
sigmoid
"
);
config
.
layerConfig
.
set_active_type
(
"
tanh
"
);
config
.
layerConfig
.
set_active_state_type
(
"sigmoid"
);
config
.
layerConfig
.
set_active_gate_type
(
"sigmoid"
);
config
.
biasSize
=
28
;
...
...
paddle/gserver/tests/test_RecurrentLayer.cpp
浏览文件 @
a07da949
...
...
@@ -369,7 +369,7 @@ TEST(Layer, LstmLayer) {
LayerConfig
layerConfig
;
layerConfig
.
set_type
(
"lstmemory"
);
layerConfig
.
set_active_type
(
"relu"
);
layerConfig
.
set_active_state_type
(
"
sigmoid
"
);
layerConfig
.
set_active_state_type
(
"
tanh
"
);
layerConfig
.
set_active_gate_type
(
"sigmoid"
);
layerConfig
.
add_inputs
();
...
...
paddle/math/BaseMatrix.cu
浏览文件 @
a07da949
...
...
@@ -625,7 +625,10 @@ void BaseMatrixT<T>::squareDerivative(BaseMatrixT& b) {
applyBinary
(
binary
::
SquareDerivative
<
T
>
(),
b
);
}
DEFINE_MATRIX_BINARY_OP
(
Tanh
,
b
=
2.0
/
(
1.0
+
exp
(
-
2
*
a
))
-
1.0
);
DEFINE_MATRIX_BINARY_OP
(
Tanh
,
T
tmp
=
-
2.0
*
a
;
tmp
=
(
tmp
>
EXP_MAX_INPUT
)
?
EXP_MAX_INPUT
:
tmp
;
b
=
2.0
/
(
1.0
+
std
::
exp
(
tmp
))
-
1.0
);
template
<
>
void
BaseMatrixT
<
real
>::
tanh
(
BaseMatrixT
&
b
)
{
applyBinary
(
binary
::
Tanh
<
real
>
(),
b
);
...
...
paddle/math/MathFunctions.cpp
浏览文件 @
a07da949
...
...
@@ -200,7 +200,10 @@ void vLog1p(const int n, const T* a, T* r) {
binary
::
vLog1p
<
T
>
(),
const_cast
<
T
*>
(
a
),
r
,
1
,
n
,
n
,
n
);
}
DEFINE_MATRIX_BINARY_OP
(
vTanh
,
b
=
2.0
/
(
1.0
+
std
::
exp
(
-
2
*
a
))
-
1.0
);
DEFINE_MATRIX_BINARY_OP
(
vTanh
,
T
tmp
=
-
2.0
*
a
;
tmp
=
(
tmp
>
EXP_MAX_INPUT
)
?
EXP_MAX_INPUT
:
tmp
;
b
=
2.0
/
(
1.0
+
std
::
exp
(
tmp
))
-
1.0
);
template
<
class
T
>
void
vTanh
(
const
int
n
,
const
T
*
a
,
T
*
r
)
{
hl_cpu_apply_binary_op
<
T
,
binary
::
vTanh
<
T
>
,
0
,
0
>
(
...
...
paddle/math/Matrix.cpp
浏览文件 @
a07da949
...
...
@@ -3471,9 +3471,7 @@ void CpuMatrix::tanh(Matrix& output) {
size_t
dim
=
getWidth
();
CHECK_EQ
(
output
.
getHeight
(),
numSamples
);
CHECK_EQ
(
output
.
getWidth
(),
dim
);
errno
=
0
;
vTanh
(
numSamples
*
dim
,
getData
(),
output
.
getData
());
CHECK_EQ
(
errno
,
0
)
<<
"vTanh error"
;
}
void
CpuMatrix
::
tanhDerivative
(
Matrix
&
output
)
{
...
...
@@ -3495,10 +3493,8 @@ void CpuMatrix::softrelu(Matrix& output) {
out
[
j
]
=
x
;
}
}
errno
=
0
;
vExp
(
numSamples
*
dim
,
output
.
getData
(),
output
.
getData
());
vLog1p
(
numSamples
*
dim
,
output
.
getData
(),
output
.
getData
());
CHECK_EQ
(
errno
,
0
)
<<
"vExp+vLog1p error"
;
}
void
CpuMatrix
::
softreluDerivative
(
Matrix
&
output
)
{
...
...
@@ -3513,9 +3509,7 @@ void CpuMatrix::softreluDerivative(Matrix& output) {
MatrixPtr
tmpMat
=
Matrix
::
create
(
numSamples
,
dim
);
real
*
tmp
=
tmpMat
->
getData
();
errno
=
0
;
vExp
(
size
,
output
.
getData
(),
tmpMat
->
getData
());
CHECK_EQ
(
errno
,
0
)
<<
"vExp error"
;
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
grad
[
i
]
*=
(
1.0
-
1.0
/
tmp
[
i
]);
...
...
@@ -3538,10 +3532,7 @@ void CpuMatrix::scaledTanh(Matrix& output, real p1, real p2) {
out
[
i
]
=
p2
*
in
[
i
];
}
// out = tanh(out)
errno
=
0
;
vTanh
(
numSamples
*
dim
,
out
,
out
);
CHECK_EQ
(
errno
,
0
)
<<
"vTanh error"
;
// out = p1 * out
for
(
size_t
i
=
0
;
i
<
numSamples
*
dim
;
++
i
)
{
...
...
paddle/math/tests/CMakeLists.txt
浏览文件 @
a07da949
...
...
@@ -13,3 +13,4 @@ add_simple_unittest(test_sparseMatrixCompare)
add_simple_unittest
(
test_perturbation
)
add_simple_unittest
(
test_CpuGpuVector
)
add_simple_unittest
(
test_Allocator
)
add_simple_unittest
(
test_FPException
)
paddle/math/tests/test_FPException.cpp
0 → 100644
浏览文件 @
a07da949
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
/**
* This test is about floating point calculation exception.
* Paddle catches FE_INVALID, FE DIVBYZERO and FE_OVERFLOW exceptions.
*
* Some exceptions occur in the middle of a set of formulas,
* that can be circumvented by some tricks.
* For example,
* calculate tanh
* b = 2.0 / (1.0 + exp(-2 * a)) - 1.0
*
* If the result of (-2 * a) is too large,
* a FE_OVERFLOW exception occurs when calculating exp.
* But the result of tanh is no overflow problem,
* so we can add some tricks to prevent exp calculate an excessive value.
*
*/
#include <fenv.h>
#include <gtest/gtest.h>
#include "paddle/math/Matrix.h"
#include "paddle/utils/Excepts.h"
using
namespace
paddle
;
// NOLINT
void
SetTensorValue
(
Matrix
&
matrix
,
real
value
)
{
int
height
=
matrix
.
getHeight
();
int
width
=
matrix
.
getWidth
();
int
stride
=
matrix
.
getStride
();
real
*
data
=
matrix
.
getData
();
for
(
int
i
=
0
;
i
<
height
;
i
++
)
{
int
j
=
rand
()
%
width
;
// NOLINT
if
(
typeid
(
matrix
)
==
typeid
(
CpuMatrix
))
{
data
[
i
*
stride
+
j
]
=
value
;
}
else
if
(
typeid
(
matrix
)
==
typeid
(
GpuMatrix
))
{
hl_memcpy
(
&
data
[
i
*
stride
+
j
],
&
value
,
sizeof
(
real
));
}
else
{
LOG
(
FATAL
)
<<
"should not reach here"
;
}
}
}
template
<
typename
Matrix
>
void
testTanh
(
real
illegal
)
{
MatrixPtr
A
=
std
::
make_shared
<
Matrix
>
(
10
,
10
);
MatrixPtr
B
=
std
::
make_shared
<
Matrix
>
(
10
,
10
);
A
->
randomizeUniform
();
B
->
randomizeUniform
();
SetTensorValue
(
*
A
,
illegal
);
A
->
tanh
(
*
B
);
}
template
<
typename
Matrix
>
void
testSigmoid
(
real
illegal
)
{
MatrixPtr
A
=
std
::
make_shared
<
Matrix
>
(
10
,
10
);
MatrixPtr
B
=
std
::
make_shared
<
Matrix
>
(
10
,
10
);
A
->
randomizeUniform
();
B
->
randomizeUniform
();
SetTensorValue
(
*
A
,
illegal
);
A
->
sigmoid
(
*
B
);
}
TEST
(
fp
,
overflow
)
{
for
(
auto
illegal
:
{
-
90.0
,
90.0
})
{
LOG
(
INFO
)
<<
" illegal="
<<
illegal
;
testTanh
<
CpuMatrix
>
(
illegal
);
testSigmoid
<
CpuMatrix
>
(
illegal
);
}
}
int
main
(
int
argc
,
char
**
argv
)
{
testing
::
InitGoogleTest
(
&
argc
,
argv
);
initMain
(
argc
,
argv
);
feenableexcept
(
FE_INVALID
|
FE_DIVBYZERO
|
FE_OVERFLOW
);
return
RUN_ALL_TESTS
();
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录