Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
094d29aa
P
Paddle
项目概览
PaddlePaddle
/
Paddle
大约 1 年 前同步成功
通知
2298
Star
20931
Fork
5422
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
094d29aa
编写于
2月 15, 2017
作者:
Y
Yu Yang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Draft for parameters
上级
844d0620
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
148 addition
and
197 deletion
+148
-197
demo/mnist/api_train_v2.py
demo/mnist/api_train_v2.py
+16
-13
python/paddle/v2/parameters.py
python/paddle/v2/parameters.py
+123
-89
python/paddle/v2/trainer.py
python/paddle/v2/trainer.py
+9
-95
未找到文件。
demo/mnist/api_train_v2.py
浏览文件 @
094d29aa
...
...
@@ -23,29 +23,32 @@ def network_config():
outputs
(
cost
)
def
event_handler
(
event
):
if
isinstance
(
event
,
paddle
.
trainer
.
CompleteTrainOneBatch
):
print
"Pass %d, Batch %d, Cost %f"
%
(
event
.
pass_id
,
event
.
batch_id
,
event
.
cost
)
else
:
pass
def
main
():
paddle
.
init
(
use_gpu
=
False
,
trainer_count
=
1
)
model_config
=
parse_network_config
(
network_config
)
p
ool
=
paddle
.
parameters
.
create
(
model_config
)
for
param_name
in
p
ool
.
get_name
s
():
array
=
p
ool
.
get_parameter
(
param_name
)
p
arameters
=
paddle
.
parameters
.
create
(
model_config
)
for
param_name
in
p
arameters
.
key
s
():
array
=
p
arameters
[
param_name
]
array
[:]
=
numpy
.
random
.
uniform
(
low
=-
1.0
,
high
=
1.0
,
size
=
array
.
shape
)
parameters
[
param_name
]
=
array
adam_optimizer
=
paddle
.
optimizer
.
Optimizer
(
learning_rate
=
0.01
,
learning_method
=
AdamOptimizer
())
def
event_handler
(
event
):
if
isinstance
(
event
,
paddle
.
trainer
.
CompleteTrainOneBatch
):
para
=
parameters
[
'___fc_layer_2__.w0'
]
print
"Pass %d, Batch %d, Cost %f, Weight Mean Of Fc 2 is %f"
%
(
event
.
pass_id
,
event
.
batch_id
,
event
.
cost
,
para
.
mean
())
adam_optimizer
=
paddle
.
optimizer
.
Adam
(
learning_rate
=
1e-3
)
else
:
pass
trainer
=
paddle
.
trainer
.
SGDTrainer
(
update_equation
=
adam_optimizer
)
trainer
.
train
(
train_data_reader
=
train_reader
,
topology
=
model_config
,
parameters
=
p
ool
,
parameters
=
p
arameters
,
event_handler
=
event_handler
,
batch_size
=
32
,
# batch size should be refactor in Data reader
data_types
=
{
# data_types will be removed, It should be in
...
...
python/paddle/v2/parameters.py
浏览文件 @
094d29aa
...
...
@@ -2,110 +2,144 @@ import numpy as np
from
paddle.proto.ModelConfig_pb2
import
ModelConfig
from
paddle.proto.ParameterConfig_pb2
import
ParameterConfig
import
py_paddle.swig_paddle
as
api
__all__
=
[
'
IParameterPool'
,
'create'
,
'ParameterFlag
'
]
__all__
=
[
'
Parameters'
,
'create
'
]
class
ParameterFlag
(
object
):
"""
The flag for IParameterPool.get_parameter. If writeable, operation on return
numpy array will also apply to Paddle parameter. But it will be slower in
GPU mode.
def
create
(
*
topologies
):
"""
READ_ONLY
=
0x01
WRITE_ONLY
=
0x02
READ_WRITE
=
READ_ONLY
|
WRITE_ONLY
Create parameter pool by topologies.
class
IParameterPool
(
object
):
:param topologies:
:return:
"""
Interface of Parameter Pool. The parameter pool is a dictionary of
parameters. User can modify parameter or customize parameter value
by `get_parameter`.
.. code-block:: python
pool
=
Parameters
()
for
topo
in
topologies
:
if
not
isinstance
(
topo
,
ModelConfig
):
raise
ValueError
(
'create must pass a topologies which type is ModelConfig'
)
pool = paddle.parameters.create(topo1, topo2)
for
param
in
topo
.
parameters
:
pool
.
append_config
(
param
)
return
pool
embedding = pool.get_parameter("embedding")
assert isinstance(embedding, numpy.ndarray)
print embedding[1:]
"""
def
get_parameter
(
self
,
name
,
flag
=
ParameterFlag
.
READ_WRITE
):
"""
Get a parameter by name.
:param name: parameter name.
:type name: basestring
:param flag: the flag for return value. readable or writable.
:type flag: int
:return: The parameter value
:rtype: np.ndarray
"""
raise
NotImplementedError
()
def
get_names
(
self
):
"""
Get all parameter names
:return: all parameter names
:rtype: list
"""
raise
NotImplementedError
()
class
NumpyParameterPool
(
IParameterPool
):
class
Parameters
(
object
):
def
__init__
(
self
):
self
.
__param_configs__
=
dict
()
self
.
__params__
=
dict
()
def
append
(
self
,
conf
):
if
not
isinstance
(
conf
,
ParameterConfig
):
raise
ValueError
(
"conf must be ParameterConfig"
)
if
not
conf
.
IsInitialized
():
raise
ValueError
(
"conf is not initialized"
)
self
.
__param_configs__
[
conf
.
name
]
=
conf
self
.
__params__
[
conf
.
name
]
=
None
def
get_config
(
self
,
name
):
if
name
not
in
self
.
__param_configs__
:
raise
ValueError
(
"parameter %s is not appended"
%
name
)
return
self
.
__param_configs__
[
name
]
def
get_parameter
(
self
,
name
,
*
args
,
**
kwargs
):
if
name
not
in
self
.
__params__
:
raise
ValueError
(
"parameter %s is not appended"
%
name
)
self
.
__param_conf__
=
dict
()
self
.
__gradient_machines__
=
[]
self
.
__tmp_params__
=
[]
def
append_config
(
self
,
param_conf
):
if
not
isinstance
(
param_conf
,
ParameterConfig
):
raise
ValueError
(
"param_conf must be paddle.proto.ParameterConfig"
)
if
param_conf
.
name
in
self
.
__param_conf__
:
raise
ValueError
(
"duplicated parameter %s"
%
param_conf
.
name
)
self
.
__param_conf__
[
param_conf
.
name
]
=
param_conf
def
keys
(
self
):
return
self
.
__param_conf__
.
keys
()
def
names
(
self
):
return
self
.
keys
()
def
has_key
(
self
,
key
):
return
key
in
self
.
__param_conf__
.
keys
()
def
__getitem__
(
self
,
key
):
shape
=
self
.
get_shape
(
key
)
if
len
(
self
.
__gradient_machines__
)
==
0
:
# create new parameter in python numpy.
return
np
.
ndarray
(
shape
=
shape
,
dtype
=
np
.
float32
)
else
:
for
each_gradient_machine
in
self
.
__gradient_machines__
:
param
=
__get_parameter_in_gradient_machine__
(
each_gradient_machine
,
key
)
# for simplify implementation now, we always copy from C++
assert
isinstance
(
param
,
api
.
Parameter
)
val
=
param
.
getBuf
(
api
.
PARAMETER_VALUE
)
assert
isinstance
(
val
,
api
.
Vector
)
return
val
.
copyToNumpyArray
().
reshape
(
shape
=
shape
)
# else continue
raise
RuntimeError
(
"Unexpected branch"
)
def
get_shape
(
self
,
key
):
if
not
isinstance
(
key
,
basestring
):
raise
ValueError
(
"parameter name should be string"
)
if
not
self
.
has_key
(
key
):
raise
ValueError
(
"No such parameter %s"
%
key
)
conf
=
self
.
__param_conf__
[
key
]
return
map
(
int
,
conf
.
dims
)
def
__setitem__
(
self
,
key
,
value
):
if
not
isinstance
(
value
,
np
.
ndarray
):
raise
ValueError
(
"Must return ndarray"
)
value
=
value
.
astype
(
dtype
=
np
.
float32
)
shape
=
self
.
get_shape
(
key
)
if
not
reduce
(
lambda
a
,
b
:
a
and
b
,
map
(
lambda
x
:
x
[
0
]
==
x
[
1
],
zip
(
value
.
shape
,
shape
))):
raise
ValueError
(
"Value shape mismatch, expect %s, should %s"
%
(
shape
,
value
.
shape
))
if
len
(
self
.
__gradient_machines__
)
==
0
:
self
.
__tmp_params__
.
append
((
key
,
value
))
else
:
for
each_gradient_machine
in
self
.
__gradient_machines__
:
__copy_parameter_to_gradient_machine__
(
each_gradient_machine
,
key
,
value
)
def
append_gradient_machine
(
self
,
gradient_machine
):
if
not
isinstance
(
gradient_machine
,
api
.
GradientMachine
):
raise
ValueError
(
"gradient_machine should be api.GradientMachine"
)
if
len
(
self
.
__tmp_params__
)
!=
0
:
for
name
,
val
in
self
.
__tmp_params__
:
try
:
__copy_parameter_to_gradient_machine__
(
gradient_machine
,
name
,
val
)
except
ValueError
:
# If no such parameter in gradient machine, then don't copy
pass
def
__get_parameter_in_gradient_machine__
(
gradient_machine
,
name
):
"""
param
=
self
.
__params__
[
name
]
if
param
is
None
:
shape
=
self
.
__param_configs__
[
name
].
dims
if
len
(
shape
)
==
0
:
raise
ValueError
(
"parameter %s is no shape"
%
name
)
param
=
np
.
ndarray
(
shape
=
[
int
(
item
)
for
item
in
shape
],
dtype
=
'float32'
)
self
.
__params__
[
name
]
=
param
return
param
:param gradient_machine:
:type gradient_machine: api.GradientMachine
:param name:
:return:
:rtype: api.Parameter
"""
params
=
filter
(
lambda
p
:
p
.
getName
()
==
name
,
gradient_machine
.
getParameters
())
def
get_names
(
self
):
return
self
.
__param_configs__
.
keys
()
if
len
(
params
)
==
0
:
raise
ValueError
(
"No such parameter"
)
elif
len
(
params
)
>
1
:
raise
ValueError
(
"Unexpected branch"
)
else
:
return
params
[
0
]
def
create
(
*
topologies
):
def
__copy_parameter_to_gradient_machine__
(
gradient_machine
,
name
,
arr
):
"""
C
reate parameter pool by topologies
.
C
opy a python ndarray into the gradient machine
.
:param topologies:
:param gradient_machine:
:type gradient_machine: api.GradientMachine
:param name:
:param arr:
:type arr: np.ndarray
:return:
:rtype: api.Parameter
"""
pool
=
NumpyParameterPool
()
for
topo
in
topologies
:
if
not
isinstance
(
topo
,
ModelConfig
):
raise
ValueError
(
'create must pass a topologies which type is ModelConfig'
)
for
param
in
topo
.
parameters
:
pool
.
append
(
param
)
return
pool
param
=
__get_parameter_in_gradient_machine__
(
gradient_machine
,
name
)
vec
=
param
.
getBuf
(
api
.
PARAMETER_VALUE
)
assert
isinstance
(
vec
,
api
.
Vector
)
vec
.
copyFromNumpyArray
(
arr
.
flatten
())
python/paddle/v2/trainer.py
浏览文件 @
094d29aa
import
collections
from
paddle.proto.ModelConfig_pb2
import
ModelConfig
from
paddle.proto.ParameterConfig_pb2
import
ParameterConfig
from
.
import
parameters
as
v2_parameters
from
.
import
optimizer
as
v2_optimizer
import
py_paddle.swig_paddle
as
api
from
py_paddle
import
DataProviderConverter
from
paddle.proto.ModelConfig_pb2
import
ModelConfig
from
.
import
optimizer
as
v2_optimizer
from
.
import
parameters
as
v2_parameters
__all__
=
[
'ITrainer'
,
'SGDTrainer'
,
'CompleteTrainOneBatch'
,
'BaseEvent'
]
...
...
@@ -21,11 +22,10 @@ class CompleteTrainOneBatch(BaseEvent):
Event On One Batch Training Complete.
"""
def
__init__
(
self
,
pass_id
,
batch_id
,
cost
,
parameters
):
def
__init__
(
self
,
pass_id
,
batch_id
,
cost
):
self
.
pass_id
=
pass_id
self
.
batch_id
=
batch_id
self
.
cost
=
cost
self
.
parameters
=
parameters
def
default_event_handler
(
event
):
...
...
@@ -42,57 +42,6 @@ class ITrainer(object):
raise
NotImplementedError
()
class
LazyParameterPool
(
v2_parameters
.
IParameterPool
):
"""
Lazy Parameter Pool stores a reference to GradientMachine. User could invoke
`get_parameter` if needed, but the operation is lazy. It means the parameter
will only fetched from GPU or Parameter Server if `get_parameter` is
invoked. Also, set flag = writable will make a extra host2device copy after
reading/modifying parameter.
This class is not exposed to User. User should treat this class as a normal
IParameterPool.
See IParameterPool for usage documentation.
:type __gradient_machine__: api.GradientMachine
"""
def
get_parameter
(
self
,
name
,
flag
=
v2_parameters
.
ParameterFlag
.
READ_WRITE
):
param
=
filter
(
lambda
x
:
x
.
getName
()
==
name
,
self
.
__gradient_machine__
.
getParameters
())
if
len
(
param
)
==
0
:
raise
ValueError
(
"Cannot found parameter with name %s"
%
name
)
elif
len
(
param
)
>
1
:
raise
RuntimeError
(
"Unexpected branch"
)
else
:
conf
=
param
[
0
].
getConfig
().
toProto
()
param
=
param
[
0
].
getBuf
(
api
.
PARAMETER_VALUE
)
assert
isinstance
(
param
,
api
.
Vector
)
assert
isinstance
(
conf
,
ParameterConfig
)
shape
=
map
(
int
,
conf
.
dims
)
if
api
.
isUsingGpu
():
arr
=
param
.
copyToNumpyArray
().
reshape
(
shape
)
if
flag
&
v2_parameters
.
ParameterFlag
.
WRITE_ONLY
:
self
.
need_copy
=
True
self
.
arrays
[
name
]
=
arr
else
:
arr
=
param
.
toNumpyArrayInplace
().
reshape
(
shape
)
return
arr
def
get_names
(
self
):
return
[
param
.
getName
()
for
param
in
self
.
__gradient_machine__
.
getParameters
()
]
def
__init__
(
self
,
gradient_machine
):
self
.
__gradient_machine__
=
gradient_machine
self
.
need_copy
=
False
self
.
arrays
=
dict
()
class
SGDTrainer
(
ITrainer
):
def
__init__
(
self
,
update_equation
):
"""
...
...
@@ -137,7 +86,7 @@ class SGDTrainer(ITrainer):
gm
=
api
.
GradientMachine
.
createFromConfigProto
(
topology
,
api
.
CREATE_MODE_NORMAL
,
self
.
__optimizer__
.
enable_types
())
assert
isinstance
(
gm
,
api
.
GradientMachine
)
__copy_parameter_from_pool__
(
gm
,
parameters
)
parameters
.
append_gradient_machine
(
gm
)
updater
=
self
.
__optimizer__
.
create_local_updater
()
updater
.
init
(
gm
)
...
...
@@ -167,16 +116,9 @@ class SGDTrainer(ITrainer):
cost_vec
=
cost_vec
.
copyToNumpyMat
()
cost
=
cost_vec
.
sum
()
/
len
(
data_batch
)
updater
.
finishBatch
(
cost
)
pool
=
LazyParameterPool
(
gradient_machine
=
gm
)
event_handler
(
CompleteTrainOneBatch
(
pass_id
=
pass_id
,
batch_id
=
batch_id
,
cost
=
cost
,
parameters
=
pool
))
if
pool
.
need_copy
:
__copy_parameter_from_lazy_pool__
(
gm
,
pool
)
pass_id
=
pass_id
,
batch_id
=
batch_id
,
cost
=
cost
))
updater
.
finishPass
()
gm
.
finish
()
...
...
@@ -211,34 +153,6 @@ def __generator_to_batch__(generator, batch_size):
yield
ret_val
def
__copy_parameter_from_lazy_pool__
(
gm
,
pool
):
assert
isinstance
(
pool
,
LazyParameterPool
)
for
each_param_name
in
pool
.
arrays
.
keys
():
param
=
filter
(
lambda
x
:
x
.
getName
()
==
each_param_name
,
gm
.
getParameters
())
assert
len
(
param
)
==
1
param
=
param
[
0
]
param
.
getBuf
(
api
.
PARAMETER_VALUE
).
copyFromNumpyArray
(
pool
.
arrays
[
each_param_name
].
flatten
().
astype
(
'float32'
))
def
__copy_parameter_from_pool__
(
gm
,
pool
):
"""
:param gm:
:type gm: api.GradientMachine
:param pool:
:type pool: v2_parameters.IParameterPool
:return:
"""
assert
isinstance
(
pool
,
v2_parameters
.
IParameterPool
)
for
each_param
in
gm
.
getParameters
():
name
=
each_param
.
getName
()
param
=
pool
.
get_parameter
(
name
,
v2_parameters
.
ParameterFlag
.
READ_ONLY
)
each_param
.
getBuf
(
api
.
PARAMETER_VALUE
).
copyFromNumpyArray
(
param
.
flatten
(
).
astype
(
'float32'
))
def
__check_train_args__
(
train_data_reader
,
topology
,
parameters
,
test_data_reader
,
event_handler
,
**
kwargs
):
"""
...
...
@@ -258,7 +172,7 @@ def __check_train_args__(train_data_reader, topology, parameters,
if
not
isinstance
(
topology
,
ModelConfig
):
raise
ValueError
(
'topology should be a model config'
)
if
not
isinstance
(
parameters
,
v2_parameters
.
IParameterPool
):
if
not
isinstance
(
parameters
,
v2_parameters
.
Parameters
):
raise
ValueError
(
'parameters should be a parameter pool'
)
if
not
callable
(
event_handler
):
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录