根据《90分钟PaddlePaddle快速上手》整理。
概念:
Batch:多个样本数据组成的一份训练(预测)数据称为batch。每个batch包含的样本数量称为batch_size
Epoch:每次便利全体数据集进行训练(预测)的过程称为一轮epoch
数据增强训练神经网络的有效手段,增强方式:Shuffle、随机裁剪、图像反转、光照色彩变换、随机加噪…
步骤
- 自定义数据读取reader
读取原始训练数据-数据增强-组成batch - 使用Paddle fluid API将数据送入网络:
- feed方式
- Py_reader接口
- 执行器训练
自定义数据读取reader
reader是一个python生成器(generator),每次通过yield返回一个样本数据,全体数据集便利完毕reader后退出。
示例:
import numpy as np
def mnist_reader(image_file, label_file):
def __reader__():
with open(image_file) as f:
f.seek(16)
images = np.reshape(np.fromfile(f, dtype='unit8'),[-1, 28, 28])
images = images / 255.0 * 2.0 - 1.0
with open(label_file) as f:
f.seek(8)
labels = np.fromfile(f, dtype='unit8')
with idx in range(len(labels)):
yield images[idx, :], labels[idx]
return __reader__
#训练调用reader
train_reader = mnist_reader('train-images.idx3-ubyte','train-labels.idx1-ubyte')
#官方api调用
import paddle
train_reader = paddle.dataset.mnist.train()
定义数据增强逻辑
import paddle
import paddle.fluid as fluid
Import numpy as np
#左右翻转
def random_flipped_reader(reader):
def __reader__():
for image, label in reader():
#生成闭区间[1,2]上离散均匀分布的整数值
if np.random.random_integers(2) == 1:
image = np.fliplr(image)#矩阵左右翻转
yield image, label
return __reader__
#随机加噪
def random_noised_reader(reader):
def __reader__():
for image, label in reader():
image += np.random.normal(0, 0.01, size=image.shape)
yield image
return __reader__
train_reader = paddle.dataset.mnist.train()
train_reader = random_noised_reader(random_flipped_reader(train_reader))
-
随机shuffle
shuffle_reader = paddle.reader.shuffle(train_reader, buf_size=64) -
调用paddle.batch组成一个batch的训练数据
batch_reader = paddle_batch(shuffle_reader, batch_size=32)
把数据送入网络训练
Feed方式
用户先将reader数据通过data feeder转换为Paddle可识别的Tensor格式数据,传入执行器进行训练。
- 步骤
- 准备
images = fluid.layers.data(name='image',shape=[28,28], dtype='float32')
labels = fluid.layers.data(name='labels', shape=[1],dtype='int64')
- 定义feeder对象
data_feeder = fluid.DataFeeder(feed_list= [images, labels], place=place)
- 训练网络
exe.run(fluid.default_startup_program())
for epoch_id in range(epoch_num):
for batch_id, batch_data in enumerate(batch_reader()):
exe.run(feed=data_feeder.feed(data),...)
#DataFeeder.feed()将用户定义的batch_reader数据转化为paddle可识别的Tensor格式数据
py_reader接口送入训练数据
Python端开启线程往Paddle backend持续送入训练数据,模型训练线程与Python数据送入线程并行执行。
- 与feed方法不同
使用py_reader接口数据读取和模型训练过程是异步进行的,效率更高,适合于高速工业训练场景,而feed方式API更简单,适于入门和调试使用。 - 步骤:
- 定义准备py_reader对象
py_reader = fluid.layers.py_reader(capacity=8, shapes=[28,28], [1]), dtypes=['float32' 'int64'])
#capacity为数据队列容量,shapes和dtypes对应feed方式下data layer shape和dtype设置
- 调用read_file读取数据
#调用read_file接口从py_reader中读取数据
#read_file返回值对应feed方式下的data_layer
images, labels = fluid.layers.read_file(py_reader)
-
将用户自定义的reader传入py_reader
py_reader.decorate_paddle_reader(batch_reader) -
训练网络
exe.run(fluid.default_startup_program())
for epoch_id in range(n_epochs):
py_reader.start()#线程启动
while True:
try:
exe.run(...)
except fluid.core.EOFException:
pt_reader.reset()
#每轮epoch结束后,C++Backend抛出EOF异常
#用户需捕获该异常并通过py_reader.reset()重置py_reader
#以启动下一轮训练
break