Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
Paddle
提交
d874fca4
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看板
提交
d874fca4
编写于
9月 11, 2017
作者:
L
Liu Yiqun
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support multiple inputs in FCOp.
上级
c05d319c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
67 addition
and
49 deletion
+67
-49
paddle/operators/fc_op.cc
paddle/operators/fc_op.cc
+37
-18
python/paddle/v2/framework/tests/test_fc_op.py
python/paddle/v2/framework/tests/test_fc_op.py
+30
-31
未找到文件。
paddle/operators/fc_op.cc
浏览文件 @
d874fca4
...
...
@@ -24,30 +24,49 @@ class FCOp : public NetOp {
const
framework
::
VariableNameMap
&
outputs
,
const
framework
::
AttributeMap
&
attrs
)
:
NetOp
(
type
,
inputs
,
outputs
,
attrs
)
{
// mul_out = X * W
AppendOp
(
framework
::
OpRegistry
::
CreateOp
(
"mul"
,
{{
"X"
,
{
Input
(
"X"
)}},
{
"Y"
,
{
Input
(
"W"
)}}},
{{
"Out"
,
{
Output
(
"mul_out"
)}}},
{}));
auto
x
=
Inputs
(
"X"
);
auto
w
=
Inputs
(
"W"
);
PADDLE_ENFORCE_EQ
(
x
.
size
(),
w
.
size
(),
"The size of inputs X(%d) should be the same as that of weights W(%d)."
,
x
.
size
(),
w
.
size
());
int
n
=
x
.
size
();
PADDLE_ENFORCE_GE
(
n
,
1
,
"The size of inputs X(%d) should be no less than 1."
,
n
);
// mul_out = X[0] * W[0] + ... + X[n-1] * W[n-1]
AppendOp
(
framework
::
OpRegistry
::
CreateOp
(
"mul"
,
{{
"X"
,
{
x
[
0
]}},
{
"W"
,
{
w
[
0
]}}},
{{
"Out"
,
{
Output
(
"mul_out"
)}}},
{}));
for
(
int
i
=
1
;
i
<
n
;
i
++
)
{
// mul_out = mul_out + X[i] * W[i]
AppendOp
(
framework
::
OpRegistry
::
CreateOp
(
"mul"
,
{{
"X"
,
{
x
[
i
]}},
{
"Y"
,
{
w
[
i
]}}},
{{
"Out"
,
{
Output
(
"add_out"
)}}},
{}));
AppendOp
(
framework
::
OpRegistry
::
CreateOp
(
"add"
,
{{
"X"
,
{
Output
(
"mul_out"
)}},
{
"Y"
,
{
Output
(
"add_out"
)}}},
{{
"Out"
,
{
Output
(
"mul_out"
)}}},
{}));
}
std
::
string
add_out_name
=
"mul_out"
;
auto
b
=
Input
(
"b"
);
std
::
string
add_out
=
"mul_out"
;
if
(
b
!=
framework
::
kEmptyVarName
)
{
// add_out = mul_out + b
AppendOp
(
framework
::
OpRegistry
::
CreateOp
(
"rowwise_add"
,
{{
"X"
,
{
Output
(
"mul_out"
)}},
{
"b"
,
{
Input
(
"b"
)}}},
{{
"Out"
,
{
Output
(
"add_out"
)}}},
{}));
add_out
_name
=
"add_out"
;
add_out
=
"add_out"
;
}
else
{
auto
add_out
=
Output
(
"add_out"
);
if
(
add_out
!=
framework
::
kEmptyVarName
)
{
this
->
Rename
(
add_out
,
framework
::
kEmptyVarName
);
if
(
Output
(
"add_out"
)
!=
framework
::
kEmptyVarName
)
{
this
->
Rename
(
Output
(
"add_out"
),
framework
::
kEmptyVarName
);
}
}
auto
activation
=
GetAttr
<
std
::
string
>
(
"activation"
);
AppendOp
(
framework
::
OpRegistry
::
CreateOp
(
activation
,
{{
"X"
,
{
Output
(
add_out_name
)}}},
{{
"Y"
,
{
Output
(
"Out"
)}}},
{}));
auto
activation
=
Attr
<
std
::
string
>
(
"activation"
);
AppendOp
(
framework
::
OpRegistry
::
CreateOp
(
activation
,
{{
"X"
,
{
Output
(
add_out
)}}},
{{
"Y"
,
{
Output
(
"Y"
)}}},
{}));
CompleteAddOp
(
false
);
}
};
...
...
@@ -56,11 +75,11 @@ class FCOpMaker : public framework::OpProtoAndCheckerMaker {
public:
FCOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"The 2
D input matrix of FC operator."
);
AddInput
(
"W"
,
"The 2
D weight matrix of FC operator."
);
AddInput
(
"b"
,
"The 1D bias vector of FC operator"
);
AddInput
(
"X"
,
"The 2
-D input matrix of FC operator."
).
AsDuplicable
(
);
AddInput
(
"W"
,
"The 2
-D weight matrix of FC operator."
).
AsDuplicable
(
);
AddInput
(
"b"
,
"The 1
-
D bias vector of FC operator"
);
AddOutput
(
"
Out
"
,
"The activated output matrix of FC operator"
);
AddOutput
(
"
Y
"
,
"The activated output matrix of FC operator"
);
AddOutput
(
"mul_out"
,
"The non-actived output of FC operator, X * W"
)
.
AsIntermediate
();
AddOutput
(
"add_out"
,
"The non-actived output of FC operator, X * W + b"
)
...
...
@@ -78,7 +97,7 @@ learned weights with a matrix multiplication followed by a bias offset
(optionally).
Equation:
Out
= Act(sum_n{X_i * W_i} + b)
Y
= Act(sum_n{X_i * W_i} + b)
where X_i is a 2D matrix of size (M x K), usually M is the minibatch size and
K is the number of features. W_i is also a 2D matrix of size (K x N),
...
...
python/paddle/v2/framework/tests/test_fc_op.py
浏览文件 @
d874fca4
import
unittest
import
numpy
as
np
from
gradient_checker
import
GradientChecker
,
create_op
from
op_test_util
import
OpTestMeta
from
op_test
import
OpTest
import
paddle.v2.framework.core
as
core
from
paddle.v2.framework.op
import
Operator
class
TestFCOp
(
unittest
.
TestCase
):
__metaclass__
=
OpTestMeta
class
TestFCOp
(
OpTest
):
def
setUp
(
self
):
self
.
type
=
"fc"
print
"Run"
self
.
op_type
=
"fc"
x0
=
np
.
random
.
random
((
32
,
256
)).
astype
(
"float32"
)
x1
=
np
.
random
.
random
((
32
,
256
)).
astype
(
"float32"
)
w0
=
np
.
random
.
random
((
256
,
100
)).
astype
(
"float32"
)
w1
=
np
.
random
.
random
((
256
,
100
)).
astype
(
"float32"
)
b
=
np
.
random
.
random
(
100
).
astype
(
"float32"
)
self
.
inputs
=
{
"X"
:
np
.
random
.
random
((
32
,
784
)).
astype
(
"float32"
),
"W"
:
np
.
random
.
random
((
784
,
1000
)).
astype
(
"float32"
),
"b"
:
np
.
random
.
random
(
1000
).
astype
(
"float32"
)
"X"
:
{
"X0"
:
x0
,
"X1"
:
x1
},
"W"
:
{
"W0"
:
w0
,
"W1"
:
w1
},
"b"
:
b
}
self
.
attrs
=
{
"activation"
:
"sigmoid"
}
mul_out
=
np
.
dot
(
self
.
inputs
[
"X"
],
self
.
inputs
[
"W"
])
add_out
=
np
.
add
(
mul_out
,
self
.
inputs
[
"b"
])
sigmoid_out
=
1
/
(
1
+
np
.
exp
(
-
add_out
))
#self.attrs = {"activation": "sigmoid"}
mul_out
=
np
.
dot
(
x0
,
w0
)
+
np
.
dot
(
x1
,
w1
)
add_out
=
np
.
add
(
mul_out
,
b
)
#sigmoid_out = 1 / (1 + np.exp(-add_out))
sigmoid_out
=
add_out
self
.
outputs
=
{
"mul_out"
:
mul_out
,
"add_out"
:
add_out
,
"
Out
"
:
sigmoid_out
"
Y
"
:
sigmoid_out
}
def
test_check_output
(
self
):
self
.
check_output
(
core
.
CPUPlace
())
self
.
check_output
(
core
.
GPUPlace
(
0
))
class
TestFCGradOp
(
GradientChecker
):
def
test_normal
(
self
):
self
.
inputs
=
{
"X"
:
np
.
random
.
random
((
32
,
256
)).
astype
(
"float32"
),
"W"
:
np
.
random
.
random
((
256
,
100
)).
astype
(
"float32"
),
"b"
:
np
.
random
.
random
(
100
).
astype
(
"float32"
)
}
op
=
Operator
(
"fc"
,
X
=
"X"
,
W
=
"W"
,
b
=
"b"
,
Out
=
"Out"
,
mul_out
=
"mul_out"
,
add_out
=
"add_out"
,
activation
=
"sigmoid"
)
self
.
check_grad
(
op
,
self
.
inputs
,
[
"X"
,
"W"
,
"b"
],
"Out"
)
#def test_check_grad(self):
# self.check_grad(["X0", "X1", "W0", "W1", "b"], "Y")
if
__name__
==
'__main__'
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录