Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
FluidDoc
提交
770aa390
F
FluidDoc
项目概览
PaddlePaddle
/
FluidDoc
通知
4
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看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
770aa390
编写于
9月 27, 2019
作者:
L
liuwei1031
提交者:
GitHub
9月 27, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix data feeder related API (#1421)
上级
ae185c9a
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
205 addition
and
206 deletion
+205
-206
doc/fluid/api_cn/data_feeder_cn/DataFeeder_cn.rst
doc/fluid/api_cn/data_feeder_cn/DataFeeder_cn.rst
+205
-206
未找到文件。
doc/fluid/api_cn/data_feeder_cn/DataFeeder_cn.rst
浏览文件 @
770aa390
.. _cn_api_fluid_data_feeder_DataFeeder:
DataFeeder
-------------------------------
.. py:class:: paddle.fluid.data_feeder.DataFeeder(feed_list, place, program=None)
``DataFeeder`` 负责将reader(读取器)返回的数据转成一种特殊的数据结构,使它们可以输入到 ``Executor`` 和 ``ParallelExecutor`` 中。
reader通常返回一个minibatch条目列表。在列表中每一条目都是一个样本(sample),它是由具有一至多个特征的列表或元组组成的。
以下是简单用法:
.. code-block:: python
import paddle.fluid as fluid
place = fluid.CPUPlace()
img = fluid.layers.data(name='image', shape=[1, 28, 28])
label = fluid.layers.data(name='label', shape=[1], dtype='int64')
feeder = fluid.DataFeeder([img, label], fluid.CPUPlace())
result = feeder.feed([([0] * 784, [9]), ([1] * 784, [1])])
在多GPU模型训练时,如果需要提前分别向各GPU输入数据,可以使用 ``decorate_reader`` 函数。
.. code-block:: python
import paddle
import paddle.fluid as fluid
place=fluid.CUDAPlace(0)
data = fluid.layers.data(name='data', shape=[3, 224, 224], dtype='float32')
label = fluid.layers.data(name='label', shape=[1], dtype='int64')
feeder = fluid.DataFeeder(place=place, feed_list=[data, label])
reader = feeder.decorate_reader(
paddle.batch(paddle.dataset.flowers.train(), batch_size=16), multi_devices=False)
参数:
- **feed_list** (list) – 向模型输入的变量表或者变量表名
- **place** (Place) – place表明是向GPU还是CPU中输入数据。如果想向GPU中输入数据, 请使用 ``fluid.CUDAPlace(i)`` (i 代表 the GPU id);如果向CPU中输入数据, 请使用 ``fluid.CPUPlace()``
- **program** (Program) – 需要向其中输入数据的Program。如果为None, 会默认使用 ``default_main_program()``。 缺省值为None
弹出异常: ``ValueError`` – 如果一些变量不在此 Program 中
**代码示例**
.. code-block:: python
import numpy as np
import paddle
import paddle.fluid as fluid
place = fluid.CPUPlace()
def reader():
yield [np.random.random([4]).astype('float32'), np.random.random([3]).astype('float32')],
main_program = fluid.Program()
startup_program = fluid.Program()
with fluid.program_guard(main_program, startup_program):
data_1 = fluid.layers.data(name='data_1', shape=[1, 2, 2])
data_2 = fluid.layers.data(name='data_2', shape=[1, 1, 3])
out = fluid.layers.fc(input=[data_1, data_2], size=2)
# ...
feeder = fluid.DataFeeder([data_1, data_2], place)
exe = fluid.Executor(place)
exe.run(startup_program)
for data in reader():
outs = exe.run(program=main_program,
feed=feeder.feed(data),
fetch_list=[out])
.. py:method:: feed(iterable)
根据feed_list(数据输入表)和iterable(可遍历的数据)提供的信息,将输入数据转成一种特殊的数据结构,使它们可以输入到 ``Executor`` 和 ``ParallelExecutor`` 中。
参数:
- **iterable** (list|tuple) – 要输入的数据
返回: 转换结果
返回类型: dict
**代码示例**
.. code-block:: python
import numpy.random as random
import paddle.fluid as fluid
def reader(limit=5):
for i in range(limit):
yield random.random([784]).astype('float32'), random.random([1]).astype('int64'), random.random([256]).astype('float32')
data_1 = fluid.layers.data(name='data_1', shape=[1, 28, 28])
data_2 = fluid.layers.data(name='data_2', shape=[1], dtype='int64')
data_3 = fluid.layers.data(name='data_3', shape=[16, 16], dtype='float32')
feeder = fluid.DataFeeder(['data_1','data_2', 'data_3'], fluid.CPUPlace())
result = feeder.feed(reader())
.. py:method:: feed_parallel(iterable, num_places=None)
该方法获取的多个minibatch,并把每个minibatch提前输入进各个设备中。
参数:
- **iterable** (list|tuple) – 要输入的数据
- **num_places** (int) – 设备数目。默认为None。
返回: 转换结果
返回类型: dict
.. note::
设备(CPU或GPU)的数目必须等于minibatch的数目
**代码示例**
.. code-block:: python
import numpy.random as random
import paddle.fluid as fluid
def reader(limit=10):
for i in range(limit):
yield [random.random([784]).astype('float32'), random.random([1]).astype('float32')],
x = fluid.layers.data(name='x', shape=[1, 28, 28])
y = fluid.layers.data(name='y', shape=[1], dtype='float32')
fluid.layers.elementwise_add(x, y)
feeder = fluid.DataFeeder(['x','y'], fluid.CPUPlace())
place_num = 2
places = [fluid.CPUPlace() for x in range(place_num)]
data = []
exe = fluid.Executor(fluid.CPUPlace())
exe.run(fluid.default_startup_program())
program = fluid.CompiledProgram(fluid.default_main_program()).with_data_parallel(places=places)
for item in reader():
data.append(item)
if place_num == len(data):
exe.run(program=program, feed=list(feeder.feed_parallel(data, place_num)), fetch_list=[])
data = []
.. py:method:: decorate_reader(reader, multi_devices, num_places=None, drop_last=True)
将reader返回的输入数据batch转换为多个mini-batch,之后每个mini-batch都会被输入进各个设备(CPU或GPU)中。
参数:
- **reader** (fun) – 该参数是一个可以生成数据的函数
- **multi_devices** (bool) – bool型,指明是否使用多个设备
- **num_places** (int) – 如果 ``multi_devices`` 为 ``True`` , 可以使用此参数来设置GPU数目。如果 ``num_places`` 为 ``None`` ,该函数默认使用当前训练机所有GPU设备。默认为None。
- **drop_last** (bool) – 如果最后一个batch的大小比 ``batch_size`` 要小,则可使用该参数来指明是否选择丢弃最后一个batch数据。 默认为 ``True``
返回:转换结果
返回类型: dict
弹出异常: ValueError – 如果 ``drop_last`` 值为False并且reader返回的minibatch数目与设备数目不相等时,产生此异常
**代码示例**
.. code-block:: python
import numpy.random as random
import paddle
import paddle.fluid as fluid
def reader(limit=5):
for i in range(limit):
yield (random.random([784]).astype('float32'), random.random([1]).astype('int64')),
place=fluid.CPUPlace()
data = fluid.layers.data(name='data', shape=[1, 28, 28], dtype='float32')
label = fluid.layers.data(name='label', shape=[1], dtype='int64')
feeder = fluid.DataFeeder(place=place, feed_list=[data, label])
reader = feeder.decorate_reader(reader, multi_devices=False)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
for data in reader():
exe.run(feed=data)
.. _cn_api_fluid_data_feeder_DataFeeder:
DataFeeder
-------------------------------
.. py:class:: paddle.fluid.data_feeder.DataFeeder(feed_list, place, program=None)
``DataFeeder`` 负责将reader(数据读取函数)返回的数据转换为可以被 ``Executor`` 和 ``ParallelExecutor`` 解析的数据结构 - 用作executor的feed参数
reader通常是一个用来从文件中读取/生成数据样本的自定义python生成器,该函数通常会返回一个包含样本实例数据的列表。
参数:
- **feed_list** (list) – 向模型输入的变量列表或者变量名列表
- **place** (:ref:`cn_api_fluid_CPUPlace` | :ref:`cn_api_fluid_CUDAPlace` ) – place表明是向GPU还是CPU中输入数据。如果想向GPU中输入数据, 请使用 ``fluid.CUDAPlace(i)`` (i 代表 the GPU id);如果向CPU中输入数据, 请使用 ``fluid.CPUPlace()``
- **program** (:ref:`cn_api_fluid_Program` ) – 需要向其中输入数据的Program。如果为None, 会默认使用 ``default_main_program()`` 。 缺省值为None
异常情况: ``ValueError`` – 如果一些变量不在此 Program 中
**代码示例**
.. code-block:: python
import numpy as np
import paddle
import paddle.fluid as fluid
place = fluid.CPUPlace()
def reader():
for _ in range(4):
yield np.random.random([4]).astype('float32'), np.random.random([3]).astype('float32'),
main_program = fluid.Program()
startup_program = fluid.Program()
with fluid.program_guard(main_program, startup_program):
data_1 = fluid.layers.data(name='data_1', shape=[-1, 2, 2])
data_2 = fluid.layers.data(name='data_2', shape=[-1, 1, 3])
out = fluid.layers.fc(input=[data_1, data_2], size=2)
# ...
feeder = fluid.DataFeeder([data_1, data_2], place)
exe = fluid.Executor(place)
exe.run(startup_program)
feed_data = feeder.feed(reader())
# print feed_data to view feed results
# print(feed_data['data_1'])
# print(feed_data['data_2'])
outs = exe.run(program=main_program,
feed=feed_data,
fetch_list=[out])
print(outs)
.. py:method:: feed(iterable)
根据创建DataFeeder时候传入的feed_list(变量列表) 和iterable (自定义python生成器) 将原始数据转换为tensor结构
参数:
- **iterable** (generator) – 自定义的python生成器,用来获取原始输入数据
返回:以变量名为key,tensor为value的dict
返回类型: dict
**代码示例**
.. code-block:: python
# 本示例中,reader函数会返回一个长度为3的数组,每个元素都是ndarray类型,
# 分别对应data_1, data_2, data_3的原始数据
# feed函数内部会将每个传入的ndarray转换为Paddle内部用于计算的tensor结构
# 返回的结果是一个size为3的dict,key分别为data_1, data_2, data_3
# result['data_1'] 为一个shape 为 [5, 2, 1, 3] 的LoD-tensor 其中5为batch size, [2, 1, 3]为data_1的shape
# result['data_2'], result['data_3']以此类推
import numpy as np
import paddle.fluid as fluid
def reader(limit=5):
for i in range(1, limit + 1):
yield np.ones([6]).astype('float32') * i , np.ones([1]).astype('int64') * i, np.random.random([9]).astype('float32')
data_1 = fluid.layers.data(name='data_1', shape=[2, 1, 3])
data_2 = fluid.layers.data(name='data_2', shape=[1], dtype='int64')
data_3 = fluid.layers.data(name='data_3', shape=[3, 3], dtype='float32')
feeder = fluid.DataFeeder(['data_1','data_2', 'data_3'], fluid.CPUPlace())
result = feeder.feed(reader())
print(result['data_1'])
print(result['data_2'])
print(result['data_3'])
.. py:method:: feed_parallel(iterable, num_places=None)
功能类似于 ``feed`` 函数,feed_parallel用于使用多个设备(CPU|GPU)的情况,iterable为自定义的生成器列表,
列表中的每个生成器返回的数据最后会feed到相对应的设备中
参数:
- **iterable** (list(generator)) – 自定义的python生成器列表,列表元素个数与num_places保持一致
- **num_places** (int) – 设备数目。默认为None。
返回: 返回值为dict的生成器,生成器返回一个键值对为 ``变量名-tensor`` 组成的dict
返回类型: generator
.. note::
设备(CPU或GPU)的数目 - ``num-places`` 必须等于 ``iterable`` 参数中的生成器数量
**代码示例**
.. code-block:: python
import numpy as np
import paddle.fluid as fluid
def generate_reader(batch_size, base=0, factor=1):
def _reader():
for i in range(batch_size):
yield np.ones([4]) * factor + base, np.ones([4]) * factor + base + 5
return _reader()
x = fluid.layers.data(name='x', shape=[-1, 2, 2])
y = fluid.layers.data(name='y', shape=[-1, 2, 2], dtype='float32')
z = fluid.layers.elementwise_add(x, y)
feeder = fluid.DataFeeder(['x','y'], fluid.CPUPlace())
place_num = 2
places = [fluid.CPUPlace() for x in range(place_num)]
data = []
exe = fluid.Executor(fluid.CPUPlace())
exe.run(fluid.default_startup_program())
program = fluid.CompiledProgram(fluid.default_main_program()).with_data_parallel(places=places)
# 打印feed_parallel结果示例
# for item in list(feeder.feed_parallel([generate_reader(5, 0, 1), generate_reader(3, 10, 2)], 2)):
# print(item['x'])
# print(item['y'])
reader_list = [generate_reader(5, 0, 1), generate_reader(3, 10, 2)]
res = exe.run(program=program, feed=list(feeder.feed_parallel(reader_list, 2)), fetch_list=[z])
print(res)
.. py:method:: decorate_reader(reader, multi_devices, num_places=None, drop_last=True)
将reader返回的输入数据batch转换为多个mini-batch,之后每个mini-batch都会被输入进各个设备(CPU或GPU)中。
参数:
- **reader** (generator) – 一个用来自定义返回mini-batch的生成器,一个返回实例数据的reader可视为一个mini-batch(如下面例子中的 ``_mini_batch`` )
- **multi_devices** (bool) – 指明是否使用多个设备
- **num_places** (int,可选) – 如果 ``multi_devices`` 为 ``True`` , 可以使用此参数来设置设备数目。如果 ``num_places`` 为 ``None`` ,该函数默认使用当前训练机所有设备。默认为None。
- **drop_last** (bool, 可选) – 如果最后一组数据的数量比设备数要小,则可使用该参数来指明是否选择丢弃最后一个组数据。 默认为 ``True``
返回:一个装饰之后的生成器,该生成器会返回匹配num_places数量的tensor数据列表
返回类型:generator
异常情况: ValueError – 如果 ``drop_last`` 值为False并且最后一组数据的minibatch数目与设备数目不相等时,产生此异常
**代码示例**
.. code-block:: python
import numpy as np
import paddle
import paddle.fluid as fluid
import paddle.fluid.compiler as compiler
def reader():
def _mini_batch(batch_size):
for i in range(batch_size):
yield np.random.random([16]).astype('float32'), np.random.randint(10, size=[1])
for _ in range(10):
yield _mini_batch(np.random.randint(1, 10))
place_num = 3
places = [fluid.CPUPlace() for _ in range(place_num)]
data = fluid.layers.data(name='data', shape=[-1, 4, 4], dtype='float32')
label = fluid.layers.data(name='label', shape=[-1, 1], dtype='int64')
hidden = fluid.layers.fc(input=data, size=10)
feeder = fluid.DataFeeder(place=places[0], feed_list=[data, label])
reader = feeder.decorate_reader(reader, multi_devices=True, num_places=3, drop_last=True)
exe = fluid.Executor(places[0])
exe.run(fluid.default_startup_program())
compiled_prog = compiler.CompiledProgram(
fluid.default_main_program()).with_data_parallel(places=places)
for i,data in enumerate(reader()):
ret = exe.run(compiled_prog, feed=data, fetch_list=[hidden])
print(ret)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录