同步数据读取

PaddlePaddle Fluid支持使用 fluid.data() 配置数据层; 再使用 Numpy Array 或者直接使用Python创建C++的 fluid.LoDTensor , 通过 Executor.run(feed=…) 传给 fluid.Executorfluid.ParallelExecutor

数据层配置

通过 fluid.data() 可以配置神经网络中需要的数据层。具体方法为:

  1. import paddle.fluid as fluid
  2.  
  3. image = fluid.data(name="image", shape=[None, 3, 224, 224])
  4. label = fluid.data(name="label", shape=[None, 1], dtype="int64")
  5.  
  6. # use image/label as layer input
  7. prediction = fluid.layers.fc(input=image, size=1000, act="softmax")
  8. loss = fluid.layers.cross_entropy(input=prediction, label=label)
  9. ...

上段代码中,imagelabel 是通过 fluid.data 创建的两个输入数据层。其中 image[None, 3, 224, 224] 维度的浮点数据; label[None, 1] 维度的整数数据。这里需要注意的是:

  • Executor在执行的时候,会检查定义的数据层数据和feed的数据的 shapedtype 是否一致,如果不一致,程序会报错退出。对于一些任务,在不同的轮数,数据的某些维度会变化,可以将维度的值设置为None,例如第0维会变化,可以将 shape 设置为 [None, 3, 224, 224]
  • Fluid中用来做类别标签的数据类型是 int64,并且标签从0开始。可用数据类型请参考 Fluid目前支持的数据类型

传递训练数据给执行器

Executor.runParallelExecutor.run 都接受一个 feed 参数。 这个参数是一个Python的字典。它的键是数据层的名字,例如上文代码中的 image。 它的值是对应的numpy array。

例如:

  1. exe = fluid.Executor(fluid.CPUPlace())
  2. # init Program
  3. exe.run(fluid.default_startup_program())
  4. exe.run(feed={
  5. "image": numpy.random.random(size=(32, 3, 224, 224)).astype('float32'),
  6. "label": numpy.random.random(size=(32, 1)).astype('int64')
  7. })

进阶使用

如何传入序列数据

序列数据是PaddlePaddle Fluid支持的特殊数据类型,可以使用 LoDTensor 作为 输入数据类型。它需要用户: 1. 传入一个mini-batch需要被训练的所有数据; 2.每个序列的长度信息。 用户可以使用 fluid.create_lod_tensor 来创建 LoDTensor

传入序列信息的时候,需要设置序列嵌套深度,lod_level 。 例如训练数据是词汇组成的句子,lod_level=1 ;训练数据是 词汇先组成了句子, 句子再组成了段落,那么 lod_level=2

例如:

  1. sentence = fluid.data(name="sentence", dtype="int64", shape=[None, 1], lod_level=1)
  2.  
  3. ...
  4.  
  5. exe.run(feed={
  6. "sentence": create_lod_tensor(
  7. data=numpy.array([1, 3, 4, 5, 3, 6, 8], dtype='int64').reshape(-1, 1),
  8. recursive_seq_lens=[[4, 1, 2]],
  9. place=fluid.CPUPlace()
  10. )
  11. })

训练数据 sentence 包含三个样本,他们的长度分别是 4, 1, 2 。 他们分别是 data[0:4]data[4:5]data[5:7]

如何分别设置ParallelExecutor中每个设备的训练数据

用户将数据传递给使用 ParallelExecutor.run(feed=…) 时, 可以显示指定每一个训练设备(例如GPU)上的数据。 用户需要将一个列表传递给 feed 参数,列表中的每一个元素都是一个字典。 这个字典的键是数据层的名字,值是数据层的值。

例如:

  1. parallel_executor = fluid.ParallelExecutor()
  2. parallel_executor.run(
  3. feed=[
  4. {
  5. "image": numpy.random.random(size=(32, 3, 224, 224)).astype('float32'),
  6. "label": numpy.random.random(size=(32, 1)).astype('int64')
  7. },
  8. {
  9. "image": numpy.random.random(size=(16, 3, 224, 224)).astype('float32'),
  10. "label": numpy.random.random(size=(16, 1)).astype('int64')
  11. },
  12. ]
  13. )

上述代码中,GPU0会训练 32 个样本,而 GPU1训练 16 个样本。

Fluid目前支持的数据类型

PaddlePaddle Fluid目前支持的数据类型包括:

  • float16: 部分操作支持
  • float32: 主要实数类型
  • float64: 次要实数类型,支持大部分操作
  • int32: 次要标签类型
  • int64: 主要标签类型
  • uint64: 次要标签类型
  • bool: 控制流数据类型
  • int16: 次要标签类型
  • uint8: 输入数据类型,可用于图像像素