Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
Paddle
提交
fd479631
P
Paddle
项目概览
BaiXuePrincess
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
fd479631
编写于
9月 28, 2017
作者:
Y
Yu Yang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Stablize elementwise_mul by using double precision
上级
5934aae4
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
78 addition
and
45 deletion
+78
-45
paddle/pybind/pybind.cc
paddle/pybind/pybind.cc
+7
-9
paddle/pybind/tensor_py.h
paddle/pybind/tensor_py.h
+14
-1
python/paddle/v2/framework/tests/op_test.py
python/paddle/v2/framework/tests/op_test.py
+42
-18
python/paddle/v2/framework/tests/test_elementwise_mul_op.py
python/paddle/v2/framework/tests/test_elementwise_mul_op.py
+15
-17
未找到文件。
paddle/pybind/pybind.cc
浏览文件 @
fd479631
...
...
@@ -77,20 +77,18 @@ PYBIND11_PLUGIN(core) {
})
.
def
(
"set"
,
PyCPUTensorSetFromArray
<
float
>
)
.
def
(
"set"
,
PyCPUTensorSetFromArray
<
int
>
)
.
def
(
"set"
,
PyCPUTensorSetFromArray
<
double
>
)
#ifndef PADDLE_ONLY_CPU
.
def
(
"set"
,
PyCUDATensorSetFromArray
<
float
>
)
.
def
(
"set"
,
PyCUDATensorSetFromArray
<
int
>
)
.
def
(
"set"
,
PyCUDATensorSetFromArray
<
double
>
)
#endif
.
def
(
"shape"
,
[](
Tensor
&
self
)
{
return
vectorize
(
self
.
dims
());
})
.
def
(
"set_float_element"
,
[](
Tensor
&
self
,
size_t
offset
,
float
f
)
{
// TODO(yuyang18): Only support GPU now.
self
.
data
<
float
>
()[
offset
]
=
f
;
})
.
def
(
"get_float_element"
,
[](
Tensor
&
self
,
size_t
offset
)
->
float
{
// TODO(yuyang18): Only support GPU now.
return
self
.
data
<
float
>
()[
offset
];
});
.
def
(
"set_float_element"
,
TensorSetElement
<
float
>
)
.
def
(
"get_float_element"
,
TensorGetElement
<
float
>
)
.
def
(
"set_double_element"
,
TensorSetElement
<
double
>
)
.
def
(
"get_double_element"
,
TensorGetElement
<
double
>
)
.
def
(
"dtype"
,
[](
Tensor
&
self
)
{
return
ToDataType
(
self
.
type
());
});
py
::
class_
<
LoDTensor
,
Tensor
>
(
m
,
"LoDTensor"
)
.
def_buffer
(
...
...
paddle/pybind/tensor_py.h
浏览文件 @
fd479631
...
...
@@ -73,10 +73,23 @@ struct CastToPyBufferImpl<true, I, ARGS...> {
};
}
// namespace details
inline
py
::
buffer_info
CastToPyBuffer
(
framework
::
Tensor
&
tensor
)
{
auto
buffer_info
=
details
::
CastToPyBufferImpl
<
true
,
0
,
float
,
int
>
()(
tensor
);
auto
buffer_info
=
details
::
CastToPyBufferImpl
<
true
,
0
,
float
,
int
,
double
>
()(
tensor
);
return
buffer_info
;
}
template
<
typename
T
>
T
TensorGetElement
(
framework
::
Tensor
&
self
,
size_t
offset
)
{
PADDLE_ENFORCE
(
platform
::
is_cpu_place
(
self
.
place
()));
return
self
.
data
<
T
>
()[
offset
];
}
template
<
typename
T
>
void
TensorSetElement
(
framework
::
Tensor
&
self
,
size_t
offset
,
T
elem
)
{
PADDLE_ENFORCE
(
platform
::
is_cpu_place
(
self
.
place
()));
self
.
data
<
T
>
()[
offset
]
=
elem
;
}
template
<
typename
T
>
void
PyCPUTensorSetFromArray
(
framework
::
Tensor
&
self
,
...
...
python/paddle/v2/framework/tests/op_test.py
浏览文件 @
fd479631
...
...
@@ -69,24 +69,27 @@ def set_input(scope, op, inputs, place):
def
set_output_grad
(
scope
,
op
,
outputs
,
place
):
def
__set_tensor__
(
name
):
out_tensor
=
scope
.
find_var
(
name
).
get_tensor
()
grad_tensor
=
scope
.
new_var
(
grad_var_name
(
name
)).
get_tensor
()
out_dtype
=
out_tensor
.
dtype
()
if
out_dtype
==
core
.
DataType
.
FP64
:
data
=
np
.
ones
(
out_tensor
.
shape
(),
dtype
=
np
.
float64
)
elif
out_dtype
==
core
.
DataType
.
FP32
:
data
=
np
.
ones
(
out_tensor
.
shape
(),
dtype
=
np
.
float32
)
else
:
raise
ValueError
(
"Not supported data type "
+
str
(
out_dtype
))
grad_tensor
.
set
(
data
,
place
)
for
out_name
,
out_dup
in
Operator
.
get_op_outputs
(
op
.
type
()):
if
out_name
in
outputs
:
if
out_dup
:
sub_out
=
outputs
[
out_name
]
for
sub_out_name
,
_
in
sub_out
:
out_tensor
=
scope
.
find_var
(
sub_out_name
).
get_tensor
()
grad_tensor
=
scope
.
new_var
(
grad_var_name
(
sub_out_name
)).
get_tensor
()
grad_tensor
.
set_dims
(
out_tensor
.
shape
())
data
=
np
.
ones
(
out_tensor
.
shape
(),
dtype
=
np
.
float32
)
grad_tensor
.
set
(
data
,
place
)
__set_tensor__
(
sub_out_name
)
else
:
out_tensor
=
scope
.
find_var
(
out_name
).
get_tensor
()
grad_tensor
=
scope
.
new_var
(
grad_var_name
(
out_name
)).
get_tensor
(
)
grad_tensor
.
set_dims
(
out_tensor
.
shape
())
data
=
np
.
ones
(
out_tensor
.
shape
(),
dtype
=
np
.
float32
)
grad_tensor
.
set
(
data
,
place
)
__set_tensor__
(
out_name
)
def
get_numeric_gradient
(
scope
,
...
...
@@ -96,7 +99,6 @@ def get_numeric_gradient(scope,
output_names
,
delta
=
0.005
,
in_place
=
False
):
set_input
(
scope
,
op
,
inputs
,
core
.
CPUPlace
())
tensor_to_check
=
scope
.
find_var
(
input_to_check
).
get_tensor
()
...
...
@@ -115,7 +117,29 @@ def get_numeric_gradient(scope,
tensor_to_check
=
scope
.
find_var
(
input_to_check
).
get_tensor
()
tensor_size
=
product
(
tensor_to_check
.
get_dims
())
gradient_flat
=
np
.
zeros
(
shape
=
(
tensor_size
,
),
dtype
=
'float32'
)
tensor_to_check_dtype
=
tensor_to_check
.
dtype
()
if
tensor_to_check_dtype
==
core
.
DataType
.
FP32
:
tensor_to_check_dtype
=
np
.
float32
elif
tensor_to_check_dtype
==
core
.
DataType
.
FP64
:
tensor_to_check_dtype
=
np
.
float64
else
:
raise
ValueError
(
"Not supported data type "
+
str
(
tensor_to_check_dtype
))
gradient_flat
=
np
.
zeros
(
shape
=
(
tensor_size
,
),
dtype
=
tensor_to_check_dtype
)
def
__get_elem__
(
tensor
,
i
):
if
tensor_to_check_dtype
==
np
.
float32
:
return
tensor
.
get_float_element
(
i
)
else
:
return
tensor
.
get_double_element
(
i
)
def
__set_elem__
(
tensor
,
i
,
e
):
if
tensor_to_check_dtype
==
np
.
float32
:
tensor
.
set_float_element
(
i
,
e
)
else
:
tensor
.
set_double_element
(
i
,
e
)
# we only compute gradient of one element each time.
# we use a for loop to compute the gradient of every element.
for
i
in
xrange
(
tensor_size
):
...
...
@@ -123,20 +147,20 @@ def get_numeric_gradient(scope,
set_input
(
scope
,
op
,
inputs
,
core
.
CPUPlace
())
# get one input element throw it's index i.
origin
=
tensor_to_check
.
get_float_element
(
i
)
origin
=
__get_elem__
(
tensor_to_check
,
i
)
# add delta to it, run op and then get the sum of the result tensor.
x_pos
=
origin
+
delta
tensor_to_check
.
set_float_element
(
i
,
x_pos
)
__set_elem__
(
tensor_to_check
,
i
,
x_pos
)
y_pos
=
get_output
()
if
in_place
:
set_input
(
scope
,
op
,
inputs
,
core
.
CPUPlace
())
x_neg
=
origin
-
delta
tensor_to_check
.
set_float_element
(
i
,
x_neg
)
__set_elem__
(
tensor_to_check
,
i
,
x_neg
)
y_neg
=
get_output
()
tensor_to_check
.
set_float_element
(
i
,
origin
)
__set_elem__
(
tensor_to_check
,
i
,
origin
)
gradient_flat
[
i
]
=
(
y_pos
-
y_neg
)
/
delta
/
2
return
gradient_flat
.
reshape
(
tensor_to_check
.
get_dims
())
...
...
python/paddle/v2/framework/tests/test_elementwise_mul_op.py
浏览文件 @
fd479631
...
...
@@ -7,8 +7,8 @@ class ElementwiseMulOp(OpTest):
def
setUp
(
self
):
self
.
op_type
=
"elementwise_mul"
self
.
inputs
=
{
'X'
:
np
.
random
.
uniform
(
0.1
,
1
,
[
13
,
17
]).
astype
(
"float
32
"
),
'Y'
:
np
.
random
.
uniform
(
0.1
,
1
,
[
13
,
17
]).
astype
(
"float
32
"
)
'X'
:
np
.
random
.
uniform
(
0.1
,
1
,
[
13
,
17
]).
astype
(
"float
64
"
),
'Y'
:
np
.
random
.
uniform
(
0.1
,
1
,
[
13
,
17
]).
astype
(
"float
64
"
)
}
self
.
outputs
=
{
'Out'
:
np
.
multiply
(
self
.
inputs
[
'X'
],
self
.
inputs
[
'Y'
])}
...
...
@@ -16,23 +16,21 @@ class ElementwiseMulOp(OpTest):
self
.
check_output
()
def
test_check_grad_normal
(
self
):
self
.
check_grad
([
'X'
,
'Y'
],
'Out'
,
max_relative_error
=
0.1
)
self
.
check_grad
([
'X'
,
'Y'
],
'Out'
)
def
test_check_grad_ingore_x
(
self
):
self
.
check_grad
(
[
'Y'
],
'Out'
,
max_relative_error
=
0.1
,
no_grad_set
=
set
(
"X"
))
self
.
check_grad
([
'Y'
],
'Out'
,
no_grad_set
=
set
(
"X"
))
def
test_check_grad_ingore_y
(
self
):
self
.
check_grad
(
[
'X'
],
'Out'
,
max_relative_error
=
0.1
,
no_grad_set
=
set
(
'Y'
))
self
.
check_grad
([
'X'
],
'Out'
,
no_grad_set
=
set
(
'Y'
))
class
TestElementwiseMulOp_Vector
(
ElementwiseMulOp
):
def
setUp
(
self
):
self
.
op_type
=
"elementwise_mul"
self
.
inputs
=
{
'X'
:
np
.
random
.
random
((
32
,
)).
astype
(
"float
32
"
),
'Y'
:
np
.
random
.
random
((
32
,
)).
astype
(
"float
32
"
)
'X'
:
np
.
random
.
random
((
32
,
)).
astype
(
"float
64
"
),
'Y'
:
np
.
random
.
random
((
32
,
)).
astype
(
"float
64
"
)
}
self
.
outputs
=
{
'Out'
:
np
.
multiply
(
self
.
inputs
[
'X'
],
self
.
inputs
[
'Y'
])}
...
...
@@ -41,8 +39,8 @@ class TestElementwiseMulOp_broadcast_0(ElementwiseMulOp):
def
setUp
(
self
):
self
.
op_type
=
"elementwise_mul"
self
.
inputs
=
{
'X'
:
np
.
random
.
rand
(
2
,
3
,
4
).
astype
(
np
.
float
32
),
'Y'
:
np
.
random
.
rand
(
2
).
astype
(
np
.
float
32
)
'X'
:
np
.
random
.
rand
(
2
,
3
,
4
).
astype
(
np
.
float
64
),
'Y'
:
np
.
random
.
rand
(
2
).
astype
(
np
.
float
64
)
}
self
.
attrs
=
{
'axis'
:
0
}
...
...
@@ -55,8 +53,8 @@ class TestElementwiseMulOp_broadcast_1(ElementwiseMulOp):
def
setUp
(
self
):
self
.
op_type
=
"elementwise_mul"
self
.
inputs
=
{
'X'
:
np
.
random
.
rand
(
2
,
3
,
4
).
astype
(
np
.
float
32
),
'Y'
:
np
.
random
.
rand
(
3
).
astype
(
np
.
float
32
)
'X'
:
np
.
random
.
rand
(
2
,
3
,
4
).
astype
(
np
.
float
64
),
'Y'
:
np
.
random
.
rand
(
3
).
astype
(
np
.
float
64
)
}
self
.
attrs
=
{
'axis'
:
1
}
...
...
@@ -69,8 +67,8 @@ class TestElementwiseMulOp_broadcast_2(ElementwiseMulOp):
def
setUp
(
self
):
self
.
op_type
=
"elementwise_mul"
self
.
inputs
=
{
'X'
:
np
.
random
.
rand
(
2
,
3
,
4
).
astype
(
np
.
float
32
),
'Y'
:
np
.
random
.
rand
(
4
).
astype
(
np
.
float
32
)
'X'
:
np
.
random
.
rand
(
2
,
3
,
4
).
astype
(
np
.
float
64
),
'Y'
:
np
.
random
.
rand
(
4
).
astype
(
np
.
float
64
)
}
self
.
outputs
=
{
...
...
@@ -82,8 +80,8 @@ class TestElementwiseMulOp_broadcast_3(ElementwiseMulOp):
def
setUp
(
self
):
self
.
op_type
=
"elementwise_mul"
self
.
inputs
=
{
'X'
:
np
.
random
.
rand
(
2
,
3
,
4
,
5
).
astype
(
np
.
float
32
),
'Y'
:
np
.
random
.
rand
(
3
,
4
).
astype
(
np
.
float
32
)
'X'
:
np
.
random
.
rand
(
2
,
3
,
4
,
5
).
astype
(
np
.
float
64
),
'Y'
:
np
.
random
.
rand
(
3
,
4
).
astype
(
np
.
float
64
)
}
self
.
attrs
=
{
'axis'
:
1
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录