• 同步数据读取
    • 数据层配置
    • 传递训练数据给执行器
    • 进阶使用
      • 如何传入序列数据
      • 如何分别设置ParallelExecutor中每个设备的训练数据
      • 自定义BatchSize维度
      • Fluid目前支持的数据类型

    同步数据读取

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

    数据层配置

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

    1. import paddle.fluid as fluid
    2.  
    3. image = fluid.layers.data(name="image", shape=[3, 224, 224])
    4. label = fluid.layers.data(name="label", shape=[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.layers.data创建的两个输入数据层。其中 image[3, 224, 224] 维度的浮点数据;label[1] 维度的整数数据。这里需要注意的是:

    • Fluid中默认使用 -1 表示 batch size 维度,默认情况下会在 shape的第一个维度添加 -1 。 所以 上段代码中, 我们可以接受将一个[32, 3, 224, 224] 的numpy array传给 image 。 如果想自定义batch size维度的位置的话,请设置 fluid.layers.data(append_batch_size=False) 。请参考进阶使用中的 自定义BatchSize维度 。
    • 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.layers.data(name="sentence", dtype="int64", shape=[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 个样本。

    自定义BatchSize维度

    PaddlePaddle Fluid默认batch size是数据的第一维度,以 -1 表示。但是在高级使用中,batch_size 可以固定,也可以是其他维度或者多个维度来表示。这都需要设置fluid.layers.data(append_batch_size=False) 来完成。

    • 固定batch size维度
    1. image = fluid.layers.data(name="image", shape=[32, 784], append_batch_size=False)

    这里,image 永远是一个 [32, 784] 大小的矩阵。

    • 使用其他维度表示batch size
    1. sentence = fluid.layers.data(name="sentence", shape=[80, -1, 1], append_batch_size=False, dtype="int64")

    这里 sentence 的中间维度是batch size。这种数据排布会用在定长的循环神经网络中。

    Fluid目前支持的数据类型

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

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