Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
FluidDoc
提交
d9472b1a
F
FluidDoc
项目概览
PaddlePaddle
/
FluidDoc
通知
10
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
23
列表
看板
标记
里程碑
合并请求
111
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
FluidDoc
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
23
Issue
23
列表
看板
标记
里程碑
合并请求
111
合并请求
111
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
d9472b1a
编写于
10月 09, 2019
作者:
Z
Zeng Jinle
提交者:
GitHub
10月 09, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refine py_reader doc, test=develop (#1471)
上级
7c2642e2
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
58 addition
and
57 deletion
+58
-57
doc/fluid/user_guides/howto/prepare_data/use_py_reader.rst
doc/fluid/user_guides/howto/prepare_data/use_py_reader.rst
+58
-57
未找到文件。
doc/fluid/user_guides/howto/prepare_data/use_py_reader.rst
浏览文件 @
d9472b1a
...
@@ -4,12 +4,12 @@
...
@@ -4,12 +4,12 @@
异步数据读取
异步数据读取
#############
#############
除同步Feed方式外,我们提供了
PyReader。PyReader的性能比 :ref:`user_guide_use_numpy_array_as_train_data` 更好,因为PyRe
ader的数据读取和模型训练过程是异步进行的,且能与 :code:`double_buffer_reader` 配合以进一步提高数据读取性能。此外, :code:`double_buffer_reader` 负责异步完成CPU Tensor到GPU Tensor的转换,一定程度上提升了数据读取效率。
除同步Feed方式外,我们提供了
DataLoader。DataLoader的性能比 :ref:`user_guide_use_numpy_array_as_train_data` 更好,因为DataLo
ader的数据读取和模型训练过程是异步进行的,且能与 :code:`double_buffer_reader` 配合以进一步提高数据读取性能。此外, :code:`double_buffer_reader` 负责异步完成CPU Tensor到GPU Tensor的转换,一定程度上提升了数据读取效率。
创建
PyRe
ader对象
创建
DataLo
ader对象
################################
################################
创建
PyRe
ader对象的方式为:
创建
DataLo
ader对象的方式为:
.. code-block:: python
.. code-block:: python
...
@@ -20,20 +20,21 @@
...
@@ -20,20 +20,21 @@
ITERABLE = True
ITERABLE = True
py_reader = fluid.io.PyReader(feed_list=[image, label], capacity=64, use_double_buffer=True, iterable=ITERABLE)
data_loader = fluid.io.DataLoader.from_generator(
feed_list=[image, label], capacity=64, use_double_buffer=True, iterable=ITERABLE)
其中,
其中,
- feed_list为需要输入的数据层变量列表;
- feed_list为需要输入的数据层变量列表;
- capacity为
PyRe
ader对象的缓存区大小,单位为batch数量;
- capacity为
DataLo
ader对象的缓存区大小,单位为batch数量;
- use_double_buffer默认为True,表示使用 :code:`double_buffer_reader` 。建议开启,可提升数据读取速度;
- use_double_buffer默认为True,表示使用 :code:`double_buffer_reader` 。建议开启,可提升数据读取速度;
- iterable默认为True,表示该
PyReader对象是可For-Range迭代的。推荐设置iterable=True。当iterable=True时,PyReader与Program解耦,定义PyReader对象不会改变Program;当iterable=False时,PyRe
ader会在Program中插入数据读取相关的op。
- iterable默认为True,表示该
DataLoader对象是可For-Range迭代的。推荐设置iterable=True。当iterable=True时,DataLoader与Program解耦,定义DataLoader对象不会改变Program;当iterable=False时,DataLo
ader会在Program中插入数据读取相关的op。
需要注意的是:`Program.clone()` (参见 :ref:`cn_api_fluid_Program` )不能实现
PyReader对象的复制。如果您要创建多个不同PyReader对象(例如训练和预测阶段需创建两个不同的PyReader),则需重定义两个PyRe
ader对象。
需要注意的是:`Program.clone()` (参见 :ref:`cn_api_fluid_Program` )不能实现
DataLoader对象的复制。如果您要创建多个不同DataLoader对象(例如训练和预测阶段需创建两个不同的DataLoader),则需重定义两个DataLo
ader对象。
若需要共享训练阶段和测试阶段的模型参数,您可以通过 :code:`fluid.unique_name.guard()` 的方式来实现。
若需要共享训练阶段和测试阶段的模型参数,您可以通过 :code:`fluid.unique_name.guard()` 的方式来实现。
注:Paddle采用变量名区分不同变量,且变量名是根据 :code:`unique_name` 模块中的计数器自动生成的,每生成一个变量名计数值加1。 :code:`fluid.unique_name.guard()` 的作用是重置 :code:`unique_name` 模块中的计数器,保证多次调用 :code:`fluid.unique_name.guard()` 配置网络时对应变量的变量名相同,从而实现参数共享。
注:Paddle采用变量名区分不同变量,且变量名是根据 :code:`unique_name` 模块中的计数器自动生成的,每生成一个变量名计数值加1。 :code:`fluid.unique_name.guard()` 的作用是重置 :code:`unique_name` 模块中的计数器,保证多次调用 :code:`fluid.unique_name.guard()` 配置网络时对应变量的变量名相同,从而实现参数共享。
下面是一个使用
PyRe
ader配置训练阶段和测试阶段网络的例子:
下面是一个使用
DataLo
ader配置训练阶段和测试阶段网络的例子:
.. code-block:: python
.. code-block:: python
...
@@ -44,13 +45,13 @@
...
@@ -44,13 +45,13 @@
def network():
def network():
image = fluid.layers.data(name='image', dtype='float32', shape=[784])
image = fluid.layers.data(name='image', dtype='float32', shape=[784])
label = fluid.layers.data(name='label', dtype='int64', shape=[1])
label = fluid.layers.data(name='label', dtype='int64', shape=[1])
reader = fluid.io.PyReade
r(feed_list=[image, label], capacity=64)
loader = fluid.io.DataLoader.from_generato
r(feed_list=[image, label], capacity=64)
# Definition of models
# Definition of models
fc = fluid.layers.fc(image, size=10)
fc = fluid.layers.fc(image, size=10)
xe = fluid.layers.softmax_with_cross_entropy(fc, label)
xe = fluid.layers.softmax_with_cross_entropy(fc, label)
loss = fluid.layers.reduce_mean(xe)
loss = fluid.layers.reduce_mean(xe)
return loss ,
re
ader
return loss ,
lo
ader
# Create main program and startup program for training
# Create main program and startup program for training
train_prog = fluid.Program()
train_prog = fluid.Program()
...
@@ -59,7 +60,7 @@
...
@@ -59,7 +60,7 @@
with fluid.program_guard(train_prog, train_startup):
with fluid.program_guard(train_prog, train_startup):
# Use fluid.unique_name.guard() to share parameters with test network
# Use fluid.unique_name.guard() to share parameters with test network
with fluid.unique_name.guard():
with fluid.unique_name.guard():
train_loss, train_
re
ader = network()
train_loss, train_
lo
ader = network()
adam = fluid.optimizer.Adam(learning_rate=0.01)
adam = fluid.optimizer.Adam(learning_rate=0.01)
adam.minimize(train_loss)
adam.minimize(train_loss)
...
@@ -69,24 +70,24 @@
...
@@ -69,24 +70,24 @@
with fluid.program_guard(test_prog, test_startup):
with fluid.program_guard(test_prog, test_startup):
# Use fluid.unique_name.guard() to share parameters with train network
# Use fluid.unique_name.guard() to share parameters with train network
with fluid.unique_name.guard():
with fluid.unique_name.guard():
test_loss, test_
re
ader = network()
test_loss, test_
lo
ader = network()
设置
PyRe
ader对象的数据源
设置
DataLo
ader对象的数据源
################################
################################
PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sample_list_generator` 和 :code:`decorate
_batch_generator()` 方法设置其数据源。
DataLoader对象通过 :code:`set_sample_generator()` , :code:`set_sample_list_generator` 和 :code:`set
_batch_generator()` 方法设置其数据源。
这三个方法均接收Python生成器 :code:`generator` 作为参数,其区别在于:
这三个方法均接收Python生成器 :code:`generator` 作为参数,其区别在于:
- :code:`
decorate
_sample_generator()` 要求 :code:`generator` 返回的数据格式为[img_1, label_1],其中img_1和label_1为单个样本的Numpy Array类型数据。
- :code:`
set
_sample_generator()` 要求 :code:`generator` 返回的数据格式为[img_1, label_1],其中img_1和label_1为单个样本的Numpy Array类型数据。
- :code:`
decorate
_sample_list_generator()` 要求 :code:`generator` 返回的数据格式为[(img_1, label_1), (img_2, label_2), ..., (img_n, label_n)],其中img_i和label_i均为每个样本的Numpy Array类型数据,n为batch size。
- :code:`
set
_sample_list_generator()` 要求 :code:`generator` 返回的数据格式为[(img_1, label_1), (img_2, label_2), ..., (img_n, label_n)],其中img_i和label_i均为每个样本的Numpy Array类型数据,n为batch size。
- :code:`
decorate
_batch_generator()` 要求 :code:`generator` 返回的数据的数据格式为[batched_imgs, batched_labels],其中batched_imgs和batched_labels为batch级的Numpy Array或LoDTensor类型数据。
- :code:`
set
_batch_generator()` 要求 :code:`generator` 返回的数据的数据格式为[batched_imgs, batched_labels],其中batched_imgs和batched_labels为batch级的Numpy Array或LoDTensor类型数据。
值得注意的是,使用
PyRe
ader做多GPU卡(或多CPU核)训练时,实际的总batch size为用户传入的 :code:`generator` 的batch size乘以设备数量。
值得注意的是,使用
DataLo
ader做多GPU卡(或多CPU核)训练时,实际的总batch size为用户传入的 :code:`generator` 的batch size乘以设备数量。
当
PyRe
ader的iterable=True(默认)时,必须给这三个方法传 :code:`places` 参数,
当
DataLo
ader的iterable=True(默认)时,必须给这三个方法传 :code:`places` 参数,
指定将读取的数据转换为CPU Tensor还是GPU Tensor。当
PyRe
ader的iterable=False时,不需传places参数。
指定将读取的数据转换为CPU Tensor还是GPU Tensor。当
DataLo
ader的iterable=False时,不需传places参数。
例如,假设我们有两个reader,其中fake_sample_reader每次返回一个sample的数据,fake_batch_reader每次返回一个batch的数据。
例如,假设我们有两个reader,其中fake_sample_reader每次返回一个sample的数据,fake_batch_reader每次返回一个batch的数据。
...
@@ -120,7 +121,7 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
...
@@ -120,7 +121,7 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
image3 = fluid.layers.data(name='image3', dtype='float32', shape=[784])
image3 = fluid.layers.data(name='image3', dtype='float32', shape=[784])
label3 = fluid.layers.data(name='label3', dtype='int64', shape=[1])
label3 = fluid.layers.data(name='label3', dtype='int64', shape=[1])
对应的
PyRe
ader设置如下:
对应的
DataLo
ader设置如下:
.. code-block:: python
.. code-block:: python
...
@@ -132,7 +133,7 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
...
@@ -132,7 +133,7 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
USE_DATA_PARALLEL = True
USE_DATA_PARALLEL = True
if ITERABLE:
if ITERABLE:
# 若
PyRe
ader可迭代,则必须设置places参数
# 若
DataLo
ader可迭代,则必须设置places参数
if USE_DATA_PARALLEL:
if USE_DATA_PARALLEL:
# 若进行多GPU卡训练,则取所有的CUDAPlace
# 若进行多GPU卡训练,则取所有的CUDAPlace
# 若进行多CPU核训练,则取多个CPUPlace,本例中取了8个CPUPlace
# 若进行多CPU核训练,则取多个CPUPlace,本例中取了8个CPUPlace
...
@@ -142,29 +143,29 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
...
@@ -142,29 +143,29 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
# 若进行单CPU核训练,则取单个CPUPlace,本例中1代表1个CPUPlace
# 若进行单CPU核训练,则取单个CPUPlace,本例中1代表1个CPUPlace
places = fluid.cuda_places(0) if USE_CUDA else fluid.cpu_places(1)
places = fluid.cuda_places(0) if USE_CUDA else fluid.cpu_places(1)
else:
else:
# 若
PyRe
ader不可迭代,则不需要设置places参数
# 若
DataLo
ader不可迭代,则不需要设置places参数
places = None
places = None
# 使用sample级的reader作为
PyRe
ader的数据源
# 使用sample级的reader作为
DataLo
ader的数据源
py_reader1 = fluid.io.PyReade
r(feed_list=[image1, label1], capacity=10, iterable=ITERABLE)
data_loader1 = fluid.io.DataLoader.from_generato
r(feed_list=[image1, label1], capacity=10, iterable=ITERABLE)
py_reader1.decorate
_sample_generator(fake_sample_reader, batch_size=32, places=places)
data_loader1.set
_sample_generator(fake_sample_reader, batch_size=32, places=places)
# 使用sample级的reader +
paddle.batch设置PyRe
ader的数据源
# 使用sample级的reader +
fluid.io.batch设置DataLo
ader的数据源
py_reader2 = fluid.io.PyReade
r(feed_list=[image2, label2], capacity=10, iterable=ITERABLE)
data_loader2 = fluid.io.DataLoader.from_generato
r(feed_list=[image2, label2], capacity=10, iterable=ITERABLE)
sample_list_reader =
paddle
.batch(fake_sample_reader, batch_size=32)
sample_list_reader =
fluid.io
.batch(fake_sample_reader, batch_size=32)
sample_list_reader =
paddle.reader
.shuffle(sample_list_reader, buf_size=64) # 还可以进行适当的shuffle
sample_list_reader =
fluid.io
.shuffle(sample_list_reader, buf_size=64) # 还可以进行适当的shuffle
py_reader2.decorate
_sample_list_generator(sample_list_reader, places=places)
data_loader2.set
_sample_list_generator(sample_list_reader, places=places)
# 使用batch级的reader作为
PyRe
ader的数据源
# 使用batch级的reader作为
DataLo
ader的数据源
py_reader3 = fluid.io.PyReade
r(feed_list=[image3, label3], capacity=10, iterable=ITERABLE)
data_loader3 = fluid.io.DataLoader.from_generato
r(feed_list=[image3, label3], capacity=10, iterable=ITERABLE)
py_reader3.decorate
_batch_generator(fake_batch_reader, places=places)
data_loader3.set
_batch_generator(fake_batch_reader, places=places)
使用
PyRe
ader进行模型训练和测试
使用
DataLo
ader进行模型训练和测试
################################
################################
使用
PyRe
ader进行模型训练和测试的例程如下。
使用
DataLo
ader进行模型训练和测试的例程如下。
- 第一步,我们需组建训练网络和预测网络,并定义相应的
PyReader对象,设置好PyRe
ader对象的数据源。
- 第一步,我们需组建训练网络和预测网络,并定义相应的
DataLoader对象,设置好DataLo
ader对象的数据源。
.. code-block:: python
.. code-block:: python
...
@@ -180,8 +181,8 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
...
@@ -180,8 +181,8 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
image = fluid.layers.data(name='image', dtype='float32', shape=[784])
image = fluid.layers.data(name='image', dtype='float32', shape=[784])
label = fluid.layers.data(name='label', dtype='int64', shape=[1])
label = fluid.layers.data(name='label', dtype='int64', shape=[1])
# 创建
PyRe
ader对象
# 创建
DataLo
ader对象
reader = fluid.io.
PyReade
r(feed_list=[image, label], capacity=64, iterable=ITERABLE)
reader = fluid.io.
DataLoader.from_generato
r(feed_list=[image, label], capacity=64, iterable=ITERABLE)
# Definition of models
# Definition of models
fc = fluid.layers.fc(image, size=10)
fc = fluid.layers.fc(image, size=10)
...
@@ -197,7 +198,7 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
...
@@ -197,7 +198,7 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
with fluid.program_guard(train_prog, train_startup):
with fluid.program_guard(train_prog, train_startup):
# fluid.unique_name.guard() to share parameters with test network
# fluid.unique_name.guard() to share parameters with test network
with fluid.unique_name.guard():
with fluid.unique_name.guard():
train_loss, train_
re
ader = network()
train_loss, train_
lo
ader = network()
adam = fluid.optimizer.Adam(learning_rate=0.01)
adam = fluid.optimizer.Adam(learning_rate=0.01)
adam.minimize(train_loss)
adam.minimize(train_loss)
...
@@ -209,7 +210,7 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
...
@@ -209,7 +210,7 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
with fluid.program_guard(test_prog, test_startup):
with fluid.program_guard(test_prog, test_startup):
# Use fluid.unique_name.guard() to share parameters with train network
# Use fluid.unique_name.guard() to share parameters with train network
with fluid.unique_name.guard():
with fluid.unique_name.guard():
test_loss, test_
re
ader = network()
test_loss, test_
lo
ader = network()
place = fluid.CUDAPlace(0)
place = fluid.CUDAPlace(0)
exe = fluid.Executor(place)
exe = fluid.Executor(place)
...
@@ -222,45 +223,45 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
...
@@ -222,45 +223,45 @@ PyReader对象通过 :code:`decorate_sample_generator()` , :code:`decorate_sam
train_prog = fluid.CompiledProgram(train_prog).with_data_parallel(loss_name=train_loss.name)
train_prog = fluid.CompiledProgram(train_prog).with_data_parallel(loss_name=train_loss.name)
test_prog = fluid.CompiledProgram(test_prog).with_data_parallel(share_vars_from=train_prog)
test_prog = fluid.CompiledProgram(test_prog).with_data_parallel(share_vars_from=train_prog)
# 设置
PyRe
ader的数据源
# 设置
DataLo
ader的数据源
places = fluid.cuda_places() if ITERABLE else None
places = fluid.cuda_places() if ITERABLE else None
train_
reader.decorate
_sample_list_generator(
train_
loader.set
_sample_list_generator(
paddle.reader.shuffle(paddle
.batch(mnist.train(), 512), buf_size=1024), places=places)
fluid.io.shuffle(fluid.io
.batch(mnist.train(), 512), buf_size=1024), places=places)
test_
reader.decorate_sample_list_generator(paddle
.batch(mnist.test(), 512), places=places)
test_
loader.set_sample_list_generator(fluid.io
.batch(mnist.test(), 512), places=places)
- 第二步:根据
PyRe
ader对象是否iterable,选用不同的方式运行网络。
- 第二步:根据
DataLo
ader对象是否iterable,选用不同的方式运行网络。
若iterable=True,则
PyRe
ader对象是一个Python的生成器,可直接for-range迭代。for-range返回的结果通过exe.run的feed参数传入执行器。
若iterable=True,则
DataLo
ader对象是一个Python的生成器,可直接for-range迭代。for-range返回的结果通过exe.run的feed参数传入执行器。
.. code-block:: python
.. code-block:: python
def run_iterable(program, exe, loss,
py_re
ader):
def run_iterable(program, exe, loss,
data_lo
ader):
for data in
py_re
ader():
for data in
data_lo
ader():
loss_value = exe.run(program=program, feed=data, fetch_list=[loss])
loss_value = exe.run(program=program, feed=data, fetch_list=[loss])
print('loss is {}'.format(loss_value))
print('loss is {}'.format(loss_value))
for epoch_id in six.moves.range(10):
for epoch_id in six.moves.range(10):
run_iterable(train_prog, exe, train_loss, train_
re
ader)
run_iterable(train_prog, exe, train_loss, train_
lo
ader)
run_iterable(test_prog, exe, test_loss, test_
re
ader)
run_iterable(test_prog, exe, test_loss, test_
lo
ader)
若iterable=False,则需在每个epoch开始前,调用 :code:`start()` 方法启动
PyReader对象;并在每个epoch结束时,exe.run会抛出 :code:`fluid.core.EOFException` 异常,在捕获异常后调用 :code:`reset()` 方法重置PyRe
ader对象的状态,
若iterable=False,则需在每个epoch开始前,调用 :code:`start()` 方法启动
DataLoader对象;并在每个epoch结束时,exe.run会抛出 :code:`fluid.core.EOFException` 异常,在捕获异常后调用 :code:`reset()` 方法重置DataLo
ader对象的状态,
以便启动下一轮的epoch。iterable=False时无需给exe.run传入feed参数。具体方式为:
以便启动下一轮的epoch。iterable=False时无需给exe.run传入feed参数。具体方式为:
.. code-block:: python
.. code-block:: python
def run_non_iterable(program, exe, loss,
py_re
ader):
def run_non_iterable(program, exe, loss,
data_lo
ader):
py_re
ader.start()
data_lo
ader.start()
try:
try:
while True:
while True:
loss_value = exe.run(program=program, fetch_list=[loss])
loss_value = exe.run(program=program, fetch_list=[loss])
print('loss is {}'.format(loss_value))
print('loss is {}'.format(loss_value))
except fluid.core.EOFException:
except fluid.core.EOFException:
print('End of epoch')
print('End of epoch')
py_re
ader.reset()
data_lo
ader.reset()
for epoch_id in six.moves.range(10):
for epoch_id in six.moves.range(10):
run_non_iterable(train_prog, exe, train_loss, train_
re
ader)
run_non_iterable(train_prog, exe, train_loss, train_
lo
ader)
run_non_iterable(test_prog, exe, test_loss, test_
re
ader)
run_non_iterable(test_prog, exe, test_loss, test_
lo
ader)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录