Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
afe7bf61
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看板
提交
afe7bf61
编写于
7月 25, 2017
作者:
Y
Yu Yang
提交者:
GitHub
7月 25, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3032 from reyoung/feature/middle_level_net_api
Feature/middle level net api
上级
8273dd79
754f0c68
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
205 addition
and
22 deletion
+205
-22
paddle/framework/scope.h
paddle/framework/scope.h
+16
-5
paddle/framework/scope_test.cc
paddle/framework/scope_test.cc
+5
-0
paddle/pybind/pybind.cc
paddle/pybind/pybind.cc
+20
-13
python/paddle/v2/framework/create_op_creation_methods.py
python/paddle/v2/framework/create_op_creation_methods.py
+3
-0
python/paddle/v2/framework/network.py
python/paddle/v2/framework/network.py
+124
-0
python/paddle/v2/framework/tests/CMakeLists.txt
python/paddle/v2/framework/tests/CMakeLists.txt
+3
-2
python/paddle/v2/framework/tests/test_net.py
python/paddle/v2/framework/tests/test_net.py
+2
-2
python/paddle/v2/framework/tests/test_network.py
python/paddle/v2/framework/tests/test_network.py
+32
-0
未找到文件。
paddle/framework/scope.h
浏览文件 @
afe7bf61
...
...
@@ -56,7 +56,9 @@ class Scope {
if
(
var
)
{
return
var
;
}
else
{
vars_
[
name
]
=
std
::
unique_ptr
<
Variable
>
(
new
Variable
());
auto
ptr
=
new
Variable
();
name_to_var_
[
name
]
=
std
::
unique_ptr
<
Variable
>
(
ptr
);
var_to_name_
[
ptr
]
=
name
;
return
GetVariable
(
name
);
}
}
...
...
@@ -68,8 +70,8 @@ class Scope {
* from it's parent scope. Return nullptr if not found.
*/
Variable
*
GetVariable
(
const
std
::
string
&
name
)
const
{
auto
it
=
vars
_
.
find
(
name
);
if
(
it
!=
vars
_
.
end
())
{
auto
it
=
name_to_var
_
.
find
(
name
);
if
(
it
!=
name_to_var
_
.
end
())
{
return
it
->
second
.
get
();
}
else
if
(
parent_
!=
nullptr
)
{
return
parent_
->
GetVariable
(
name
);
...
...
@@ -84,12 +86,21 @@ class Scope {
* Find if there is a Variable in this scope and it's parent scope
*/
bool
HasVariable
(
const
std
::
string
&
name
)
const
{
return
(
vars_
.
find
(
name
)
!=
vars
_
.
end
()
||
return
(
name_to_var_
.
find
(
name
)
!=
name_to_var
_
.
end
()
||
(
parent_
&&
parent_
->
HasVariable
(
name
)));
}
std
::
string
GetVariableName
(
Variable
*
const
var
)
const
{
try
{
return
var_to_name_
.
at
(
var
);
}
catch
(...)
{
return
""
;
}
}
private:
std
::
unordered_map
<
std
::
string
,
std
::
unique_ptr
<
Variable
>>
vars_
;
std
::
unordered_map
<
Variable
*
,
std
::
string
>
var_to_name_
;
std
::
unordered_map
<
std
::
string
,
std
::
unique_ptr
<
Variable
>>
name_to_var_
;
std
::
shared_ptr
<
Scope
>
parent_
{
nullptr
};
};
...
...
paddle/framework/scope_test.cc
浏览文件 @
afe7bf61
...
...
@@ -40,6 +40,11 @@ TEST(Scope, Create) {
/// already exist.
Variable
*
var4
=
scope
->
CreateVariable
(
"a"
);
EXPECT_EQ
(
var4
,
var2
);
EXPECT_EQ
(
"a"
,
scope
->
GetVariableName
(
var4
));
Scope
scope2
;
auto
var
=
scope2
.
CreateVariable
(
"tmp"
);
EXPECT_EQ
(
""
,
scope
->
GetVariableName
(
var
));
}
TEST
(
Scope
,
Parent
)
{
...
...
paddle/pybind/pybind.cc
浏览文件 @
afe7bf61
...
...
@@ -48,6 +48,11 @@ void ExposeOperator(ClassType& m) {
.
def
(
"__str__"
,
&
ClassType
::
type
::
DebugString
);
}
static
size_t
UniqueIntegerGenerator
()
{
static
std
::
atomic
<
size_t
>
generator
;
return
generator
.
fetch_add
(
1
);
}
PYBIND11_PLUGIN
(
core
)
{
py
::
module
m
(
"core"
,
"C++ core of PaddlePaddle"
);
...
...
@@ -98,7 +103,8 @@ All parameter, weight, gradient are variables in Paddle.
py
::
return_value_policy
::
reference
)
.
def
(
"create_var"
,
&
pd
::
Scope
::
CreateVariable
,
py
::
return_value_policy
::
reference
);
py
::
return_value_policy
::
reference
)
.
def
(
"get_var_name"
,
&
pd
::
Scope
::
GetVariableName
);
//! @note: Be careful! PyBind will return std::string as an unicode, not
//! Python str. If you want a str object, you should cast them in Python.
...
...
@@ -141,23 +147,24 @@ All parameter, weight, gradient are variables in Paddle.
ExposeOperator
(
operator_base
);
using
PlainNetPtr
=
std
::
shared_ptr
<
pd
::
PlainNet
>
;
py
::
class_
<
pd
::
PlainNet
,
PlainNetPtr
>
plain_net
(
m
,
"PlainNet"
);
plain_net
.
def_static
(
"create"
,
[]()
->
std
::
shared_ptr
<
pd
::
PlainNet
>
{
auto
retv
=
std
::
make_shared
<
pd
::
PlainNet
>
();
retv
->
type_
=
"plain_net"
;
return
retv
;
})
py
::
class_
<
pd
::
PlainNet
,
PlainNetPtr
>
net
(
m
,
"Net"
);
net
.
def_static
(
"create"
,
[]()
->
std
::
shared_ptr
<
pd
::
PlainNet
>
{
auto
retv
=
std
::
make_shared
<
pd
::
PlainNet
>
();
retv
->
type_
=
"plain_net"
;
return
retv
;
})
.
def
(
"add_op"
,
&
pd
::
PlainNet
::
AddOp
)
.
def
(
"add_op"
,
[](
PlainNetPtr
&
self
,
const
PlainNetPtr
&
plain_
net
)
->
void
{
self
->
AddOp
(
std
::
static_pointer_cast
<
pd
::
OperatorBase
>
(
plain_
net
));
[](
PlainNetPtr
&
self
,
const
PlainNetPtr
&
net
)
->
void
{
self
->
AddOp
(
std
::
static_pointer_cast
<
pd
::
OperatorBase
>
(
net
));
})
.
def
(
"complete_add_op"
,
&
pd
::
PlainNet
::
CompleteAddOp
)
.
def
(
"complete_add_op"
,
[](
PlainNetPtr
&
self
)
{
self
->
CompleteAddOp
();
});
ExposeOperator
(
plain_net
);
ExposeOperator
(
net
);
m
.
def
(
"unique_integer"
,
UniqueIntegerGenerator
);
return
m
.
ptr
();
}
python/paddle/v2/framework/create_op_creation_methods.py
浏览文件 @
afe7bf61
...
...
@@ -220,6 +220,9 @@ def create_op_creation_method(op_proto):
__impl__
.
all_input_args
=
[
var
.
name
for
var
in
op_proto
.
inputs
]
__impl__
.
all_output_args
=
[
var
.
name
for
var
in
op_proto
.
outputs
]
__impl__
.
all_attr_args
=
[
attr
.
name
for
attr
in
op_proto
.
attrs
]
__impl__
.
all_not_temp_output_args
=
[
var
.
name
for
var
in
op_proto
.
outputs
if
not
var
.
temporary
]
return
__impl__
...
...
python/paddle/v2/framework/network.py
0 → 100644
浏览文件 @
afe7bf61
import
paddle.v2.framework.core
as
core
from
paddle.v2.framework.create_op_creation_methods
import
op_creations
from
default_scope_funcs
import
create_var
,
get_var
,
get_cur_scope
__all__
=
[
'Network'
]
# Only expose Network
class
NetworkFunctor
(
object
):
"""
Network Op Creation Function. Used internally in this module.
It convert string input to Variable. If it is not created before, just
create in scope.
It is a functor object. means the instances are callable.
:param func: The op creation function which generated in Python.
:param net: The Network instance.
"""
def
__init__
(
self
,
func
,
net
):
self
.
func
=
func
self
.
net
=
net
def
__call__
(
self
,
*
args
,
**
kwargs
):
if
len
(
args
)
!=
0
:
raise
ValueError
(
"Paddle must use keyword argument"
)
inputs
=
self
.
func
.
all_input_args
for
ipt
in
inputs
:
if
ipt
in
kwargs
:
var
=
kwargs
[
ipt
]
if
isinstance
(
var
,
basestring
):
var
=
create_var
(
var
)
if
not
isinstance
(
var
,
core
.
Variable
):
raise
TypeError
(
"Input of op creation must be string or variable"
)
kwargs
[
ipt
]
=
get_cur_scope
().
get_var_name
(
var
)
notemp_outputs
=
self
.
func
.
all_not_temp_output_args
for
name
in
notemp_outputs
:
if
name
not
in
kwargs
:
kwargs
[
name
]
=
self
.
func
.
__name__
+
"@OUT@%d"
%
core
.
unique_integer
(
)
outputs
=
self
.
func
.
all_output_args
for
opt
in
outputs
:
if
opt
in
kwargs
:
var
=
kwargs
[
opt
]
if
isinstance
(
var
,
basestring
):
var
=
create_var
(
var
)
if
not
isinstance
(
var
,
core
.
Variable
):
raise
TypeError
(
"Output of op creation must be string or variable"
)
kwargs
[
opt
]
=
get_cur_scope
().
get_var_name
(
var
)
op
=
self
.
func
(
**
kwargs
)
self
.
net
.
net
.
add_op
(
op
)
lst
=
[
get_var
(
kwargs
[
opt
])
for
opt
in
notemp_outputs
]
if
len
(
lst
)
==
1
:
return
lst
[
0
]
elif
len
(
lst
)
==
0
:
return
None
else
:
return
lst
class
Network
(
object
):
"""
The network concept. It avoid user to manually create operator, create
variable, and combine them into a Net. Just use Network.xxx can create the
operator, create variables in default scope, and add them into `self.net`.
For example:
.. code-block: python
net = Network()
out = net.add_two(X="a", Y="b")
fc_out = net.fc(X="out", W="fc.w")
net.run(...)
"""
def
__init__
(
self
):
self
.
net
=
core
.
Net
.
create
()
funcs
=
(
func_name
for
func_name
in
dir
(
op_creations
)
if
not
func_name
.
startswith
(
"__"
))
# TODO(yuyang18): This code can work, but do not generate a good
# docstring, try to give a better way generate function in runtime
# later.
for
func_name
in
funcs
:
func
=
getattr
(
op_creations
,
func_name
)
impl
=
NetworkFunctor
(
func
,
self
)
setattr
(
self
,
func_name
,
impl
.
__call__
)
self
.
__complete_add_op__
=
False
def
infer_shape
(
self
):
self
.
complete_add_op
()
self
.
net
.
infer_shape
(
get_cur_scope
())
def
run
(
self
,
device_context
):
self
.
complete_add_op
()
self
.
net
.
run
(
get_cur_scope
(),
device_context
)
def
__str__
(
self
):
return
str
(
self
.
net
)
def
complete_add_op
(
self
):
if
not
self
.
__complete_add_op__
:
self
.
net
.
complete_add_op
()
self
.
__complete_add_op__
=
True
if
__name__
==
'__main__'
:
net
=
Network
()
out
=
net
.
add_two
(
X
=
"a"
,
Y
=
"b"
)
fc_out
=
net
.
fc
(
X
=
out
,
W
=
"fc.w"
,
b
=
"fc.b"
,
activation
=
"softmax"
)
net
.
complete_add_op
()
print
net
python/paddle/v2/framework/tests/CMakeLists.txt
浏览文件 @
afe7bf61
...
...
@@ -3,7 +3,7 @@ add_python_test(test_framework
test_scope.py
test_default_scope_funcs.py
test_op_creation_methods.py
test_
plain_
net.py
test_net.py
test_tensor.py
test_fc_op.py
test_add_two_op.py
...
...
@@ -12,4 +12,5 @@ add_python_test(test_framework
test_mul_op.py
test_sigmoid_op.py
test_softmax_op.py
test_rowwise_add_op.py
)
test_rowwise_add_op.py
test_network.py
)
python/paddle/v2/framework/tests/test_
plain_
net.py
→
python/paddle/v2/framework/tests/test_net.py
浏览文件 @
afe7bf61
...
...
@@ -5,11 +5,11 @@ import unittest
class
TestNet
(
unittest
.
TestCase
):
def
test_net_all
(
self
):
net
=
core
.
Plain
Net
.
create
()
net
=
core
.
Net
.
create
()
op1
=
op_creations
.
add_two
(
X
=
"X"
,
Y
=
"Y"
,
Out
=
"Out"
)
net
.
add_op
(
op1
)
net2
=
core
.
Plain
Net
.
create
()
net2
=
core
.
Net
.
create
()
net2
.
add_op
(
op_creations
.
fc
(
X
=
"X"
,
W
=
"w"
,
Y
=
"fc.out"
))
net2
.
complete_add_op
(
True
)
net
.
add_op
(
net2
)
...
...
python/paddle/v2/framework/tests/test_network.py
0 → 100644
浏览文件 @
afe7bf61
from
paddle.v2.framework.network
import
Network
import
paddle.v2.framework.core
as
core
import
unittest
class
TestNet
(
unittest
.
TestCase
):
def
test_net_all
(
self
):
net
=
Network
()
out
=
net
.
add_two
(
X
=
"X"
,
Y
=
"Y"
)
fc_out
=
net
.
fc
(
X
=
out
,
W
=
"w"
)
net
.
complete_add_op
()
self
.
assertTrue
(
isinstance
(
fc_out
,
core
.
Variable
))
self
.
assertEqual
(
'''Op(plain_net), inputs:(@EMPTY@, X, Y, w), outputs:(@TEMP@fc@0, add_two@OUT@0, fc@OUT@1).
Op(add_two), inputs:(X, Y), outputs:(add_two@OUT@0).
Op(fc), inputs:(add_two@OUT@0, w, @EMPTY@), outputs:(fc@OUT@1, @TEMP@fc@0).
Op(mul), inputs:(add_two@OUT@0, w), outputs:(@TEMP@fc@0).
Op(sigmoid), inputs:(@TEMP@fc@0), outputs:(fc@OUT@1).
'''
,
str
(
net
))
net2
=
Network
()
tmp
=
net2
.
add_two
(
X
=
"X"
,
Y
=
"Y"
)
self
.
assertTrue
(
isinstance
(
tmp
,
core
.
Variable
))
net2
.
complete_add_op
()
self
.
assertEqual
(
'''Op(plain_net), inputs:(X, Y), outputs:(add_two@OUT@2).
Op(add_two), inputs:(X, Y), outputs:(add_two@OUT@2).
'''
,
str
(
net2
))
if
__name__
==
'__main__'
:
unittest
.
main
()
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录