上一节《LeNet网络PaddlePaddle实现1》
本节介绍如何训练LeNet网络,具体步骤如下:
- 数据读取:读取每批数据,通过 to_variable 接口将 numpy.ndarray 对象转换为 Variable 类型的对象。
- 网络正向执行forward():在正向执行时,构造出images和labels之后,可利用类似函数调用的方式传递参数执行对应网络的 forward 函数。
- 计算损失值:根据网络返回的计算结果,调用相应的损失函数,计算损失值
- 执行反向计算:调用损失值的 backward() 方法来执行反向计算。
- 参数更新:调用优化器的 minimize() 方法对参数进行更新。
- 梯度重置:调用模型的clear_gradients()方法将本次计算的梯度值清零,以便进行下一次迭代和梯度更新。
- 保存训练好的模型:通过 模型对象 的 state_dict() 方法获取模型的参数;通过 save_dygraph() 方法对模型参数进行保存
模型训练代码具体实现如下所示:
# 训练模型
print("start training...")
with fluid.dygraph.guard():
model = LeNet(10)
model.train() #切换到训练模式
optimizer = fluid.optimizer.AdamOptimizer(0.001,parameter_list=model.parameters())
EPOCH_NUM = 5
BATCH_SIZE = 100
# 定义外层循环
for epoch_id in range(EPOCH_NUM):
# 在每轮迭代开始前,将训练数据随机打乱
seed_id = np.random.randint(1,100)
np.random.seed(seed_id)
np.random.shuffle(train_images)
np.random.seed(seed_id)
np.random.shuffle(train_labels)
# 将训练数据进行拆分,每个batch包含BATCH_SIZE条数据
mini_batches = [i for i in range(0, train_labels.shape[0], BATCH_SIZE)]
for iter_id, mini_batch in enumerate(mini_batches):
x = train_images[mini_batch:mini_batch+BATCH_SIZE,:,:].astype('float32').reshape(-1,1,28,28)
y = train_labels[mini_batch:mini_batch+BATCH_SIZE].astype('int64').reshape(-1,1)
# print(x.shape, y.shape)
# 将数据转为飞浆动态图格式
images = fluid.dygraph.to_variable(x)
labels = fluid.dygraph.to_variable(y)
# 前向计算
logits = model(images)
# 计算损失
loss = fluid.layers.softmax_with_cross_entropy(logits, labels)
avg_loss = fluid.layers.mean(loss)
# 每训练N批次数据,输出当前loss值
N = 100
if iter_id !=0 and iter_id%N == 0:
print("Epoch:{}, batch: {}, loss is {}".format(epoch_id, iter_id, avg_loss.numpy()))
# 后向传播,更新参数
avg_loss.backward()
optimizer.minimize(avg_loss)
model.clear_gradients()
#保存模型
fluid.save_dygraph(model.state_dict(),'LeNet')
网友评论