Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wmsofts
Paddle
提交
01d9c465
P
Paddle
项目概览
wmsofts
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
0
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
01d9c465
编写于
9月 28, 2017
作者:
Y
Yu Yang
提交者:
GitHub
9月 28, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4478 from reyoung/stable_elemwise_mul
Stable elemwise mul
上级
184768e0
6efcbc4f
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
98 addition
and
71 deletion
+98
-71
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
+60
-42
python/paddle/v2/framework/tests/test_cross_entropy_op.py
python/paddle/v2/framework/tests/test_cross_entropy_op.py
+1
-1
python/paddle/v2/framework/tests/test_elementwise_mul_op.py
python/paddle/v2/framework/tests/test_elementwise_mul_op.py
+15
-17
python/paddle/v2/framework/tests/test_prelu_op.py
python/paddle/v2/framework/tests/test_prelu_op.py
+1
-1
未找到文件。
paddle/pybind/pybind.cc
浏览文件 @
01d9c465
...
...
@@ -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
浏览文件 @
01d9c465
...
...
@@ -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
浏览文件 @
01d9c465
...
...
@@ -12,17 +12,19 @@ def grad_var_name(var_name):
def
create_op
(
scope
,
op_type
,
inputs
,
outputs
,
attrs
):
kwargs
=
dict
()
def
__create_var__
(
name
,
var_name
):
scope
.
new_var
(
var_name
)
kwargs
[
name
].
append
(
var_name
)
for
in_name
,
in_dup
in
Operator
.
get_op_inputs
(
op_type
):
if
in_name
in
inputs
:
kwargs
[
in_name
]
=
[]
if
in_dup
:
sub_in
=
inputs
[
in_name
]
for
sub_in_name
,
_
in
sub_in
:
var
=
scope
.
new_var
(
sub_in_name
)
kwargs
[
in_name
].
append
(
sub_in_name
)
__create_var__
(
in_name
,
sub_in_name
)
else
:
var
=
scope
.
new_var
(
in_name
)
kwargs
[
in_name
].
append
(
in_name
)
__create_var__
(
in_name
,
in_name
)
for
out_name
,
out_dup
in
Operator
.
get_op_outputs
(
op_type
):
if
out_name
in
outputs
:
...
...
@@ -30,11 +32,9 @@ def create_op(scope, op_type, inputs, outputs, attrs):
if
out_dup
:
sub_out
=
outputs
[
out_name
]
for
sub_out_name
,
_
in
sub_out
:
var
=
scope
.
new_var
(
sub_out_name
)
kwargs
[
out_name
].
append
(
sub_out_name
)
__create_var__
(
out_name
,
sub_out_name
)
else
:
var
=
scope
.
new_var
(
out_name
)
kwargs
[
out_name
].
append
(
out_name
)
__create_var__
(
out_name
,
out_name
)
for
attr_name
in
Operator
.
get_op_attr_names
(
op_type
):
if
attr_name
in
attrs
:
...
...
@@ -44,49 +44,46 @@ def create_op(scope, op_type, inputs, outputs, attrs):
def
set_input
(
scope
,
op
,
inputs
,
place
):
def
__set_input__
(
var_name
,
var
):
tensor
=
scope
.
find_var
(
var_name
).
get_tensor
()
if
isinstance
(
var
,
tuple
):
tensor
.
set_lod
(
var
[
1
])
var
=
var
[
0
]
tensor
.
set_dims
(
var
.
shape
)
tensor
.
set
(
var
,
place
)
for
in_name
,
in_dup
in
Operator
.
get_op_inputs
(
op
.
type
()):
if
in_name
in
inputs
:
if
in_dup
:
sub_in
=
inputs
[
in_name
]
for
sub_in_name
,
sub_in_val
in
sub_in
:
var
=
scope
.
find_var
(
sub_in_name
)
tensor
=
var
.
get_tensor
()
sub_in_array
=
sub_in_val
[
0
]
\
if
isinstance
(
sub_in_val
,
tuple
)
else
sub_in_val
tensor
.
set_dims
(
sub_in_array
.
shape
)
tensor
.
set
(
sub_in_array
,
place
)
if
isinstance
(
sub_in_val
,
tuple
):
tensor
.
set_lod
(
sub_in_val
[
1
])
__set_input__
(
sub_in_name
,
sub_in_val
)
else
:
var
=
scope
.
find_var
(
in_name
)
tensor
=
var
.
get_tensor
()
in_val
=
inputs
[
in_name
]
in_array
=
in_val
[
0
]
if
isinstance
(
in_val
,
tuple
)
else
in_val
tensor
.
set_dims
(
in_array
.
shape
)
tensor
.
set
(
in_array
,
place
)
if
isinstance
(
in_val
,
tuple
):
tensor
.
set_lod
(
in_val
[
1
])
__set_input__
(
in_name
,
inputs
[
in_name
])
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 +93,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 +111,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 +141,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_cross_entropy_op.py
浏览文件 @
01d9c465
...
...
@@ -80,7 +80,7 @@ class TestCrossEntropyOp3(OpTest):
cross_entropy2
=
(
-
label
*
np
.
log
(
X
)).
sum
(
axis
=
1
,
keepdims
=
True
).
astype
(
"float32"
)
self
.
inputs
=
{
"X"
:
X
,
"Label"
:
label
}
self
.
inputs
=
{
"X"
:
X
,
"Label"
:
label
.
astype
(
np
.
float32
)
}
self
.
outputs
=
{
"Y"
:
cross_entropy
}
self
.
attrs
=
{
"softLabel"
:
True
}
...
...
python/paddle/v2/framework/tests/test_elementwise_mul_op.py
浏览文件 @
01d9c465
...
...
@@ -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
}
...
...
python/paddle/v2/framework/tests/test_prelu_op.py
浏览文件 @
01d9c465
...
...
@@ -17,7 +17,7 @@ class PReluTest(OpTest):
x_np_sign
=
np
.
sign
(
x_np
)
x_np
=
x_np_sign
*
np
.
maximum
(
x_np
,
.
005
)
alpha_np
=
np
.
array
([.
1
])
alpha_np
=
np
.
array
([.
1
]
,
dtype
=
"float32"
)
self
.
inputs
=
{
'X'
:
x_np
,
'Alpha'
:
alpha_np
}
out_np
=
np
.
maximum
(
self
.
inputs
[
'X'
],
0.
)
out_np
=
out_np
+
np
.
minimum
(
self
.
inputs
[
'X'
],
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录