前言
PaddlePaddle使用Trainer训练模型虽然直接了当,方便快捷,但是对于一些需要逐步训练的模型则比较麻烦。类似Tensorflow采用session.run的形式逐步训练模型,使得训练过程更加显而易见。PaddlePaddle新版本Fluid中,采用Executor也可以完成类似的训练。本文针对简单的回归问题简述以下PaddlePaddle的Executor训练过程。
1. Reader的建立
本文尝试使用神经网络模型拟合二次函数,首先我们建立以下二次函数的训练数据,并加上噪声:
train_x = np.linspace(-1, 1, 128) # shape (100, 1) noise = np.random.normal(0, 0.1, size=train_x.shape) train_y = np.power(train_x, 2) + noise def reader(): def reader_creator(): for i in range(128): yield train_x[i],train_y[i] return reader_creator
train_reader = paddle.batch(reader(),batch_size=64)
2. 网络的构建以及损失函数
我们构建一层10个神经元的隐藏层,代码如下:
#构建网络模型 input_layer = fluid.layers.data(name='data',shape=[1],dtype='float32') hid = fluid.layers.fc(input=input_layer, size=10, act='relu') output = fluid.layers.fc(input=hid, size=1, act=None) label = fluid.layers.data(name='label',shape=[1],dtype='float32') #损失函数采用均方差 cost = fluid.layers.square_error_cost(input=output,label=label) avg_cost = fluid.layers.mean(cost) #优化器选择 optimizer = fluid.optimizer.AdamOptimizer(learning_rate=0.01) opts = optimizer.minimize(avg_cost)
3. 训练模型
训练同往常一样,但是需要新建一个Executor和DataFeeder,然后直接对每个batch进行训练,直接明了。
#选择CPU place = fluid.CPUPlace() feeder = fluid.DataFeeder(place=place, feed_list=['data', 'label']) #克隆program用于后面测试 test_program = fluid.default_main_program().clone(for_test=True) exe = fluid.Executor(place) #初始化参数 exe.run(fluid.default_startup_program()) for pass_id in range(1000): #遍历每个batch for batch_id,data in enumerate(train_reader()): loss = exe.run(fluid.default_main_program(), feed=feeder.feed(data), fetch_list=[avg_cost])
4. 测试
这里也是同样运用exe.run,与上面训练差不多一样。这里还是用回训练集测试,将每个batch的结果保存在数组中。
#用于保存每个batch的结果,便签等 x_ = [] y_ = [] l_= [] for batch_id,data in enumerate(train_reader()): x,y,l=exe.run(program=test_program, feed=feeder.feed(data), fetch_list=[input_layer,output,label]) x_ =np.hstack((x_,x.ravel())) y_ =np.hstack((y_,y.ravel())) l_ =np.hstack((l_,l.ravel()))
5.结果
红线逐步拟合到散点
参考:Tensorflow-Tutorial/tutorial-contents/301_simple_regression.py
代码:GitHub