在构建好CNN网络模型之后,接下来便是通过训练集来对模型进行训练:
下面是这次搭建“”美食分类”深度学习代码中,所用到的训练部分的代码:
# CNN网络组建完毕之后,开始进行模型训练
print(train_parameters['class_dim'])
print(train_parameters['label_dict'])
model = CNN()
optimizer = paddle.optimizer.Adam(learning_rate = train_parameters['learning_strategy']['lr'],
parameters = model.parameters())
for epoch_num in range (train_parameters['num_epochs']):
for batch_id, data in enumerate(train_reader()):
x_data = np.array([item[0] for item in data], dtype='float32').reshape(-1, 3, 64, 64)
x_data = paddle.to_tensor(x_data, dtype = 'float32', place=paddle.CUDAPinnedPlace()) # 将numpy.array数据转换成tensor张量
y_data = np.array([item[1] for item in data], dtype='int64').reshape(-1, 1) # 将元组转换成numpy.array
y_data = paddle.to_tensor(y_data, dtype = 'int64', place=paddle.CUDAPinnedPlace())
#print("y的数据类型: ", type(y_data))
#print("x_data的数据类型:", type(x_data))
predicts = model(x_data)
#print("预测值的数据类型: ", type(predicts), "\n", "predicts内容: ", predicts)
loss = fun.cross_entropy(predicts, y_data)
acc = paddle.metric.accuracy(predicts, y_data)
loss.backward()
if batch_id % 1 == 0:
print("epoch: {}, batch_id: {}, loss is: {}, acc is: {}".format(epoch_num, batch_id, loss.numpy(), acc.numpy()))
optimizer.step()
optimizer.clear_grad()
通过前面设计的数据读取器,train_reader来读取训练集中的数据,然后可知data[0]是数据,data[1]是训练图片所对应的标签,但是在读取出来的数据是元组类型,而对于paddle中对paddle.nn.Conv2D以及池化层的描述,输入的数据应该是tensor,张量,因此在后续将元组转换成numpy.array之后,采用paddle.to_tensor将numpy.array转换成张量,对于paddle.to_tensor内部的参量,place=paddle.CUDAPinnedPlace()代表将转换后的存放于GPU设备,我理解就是采用GPU环境进行训练。
这样网络输出的预测值presicts的类型也为tensor张量,阅读paddle关于计算准确率以及损失函数的API文档,是要求输入的参数数据类型一致:
loss = fun.cross_entropy(predicts, y_data)
acc = paddle.metric.accuracy(predicts, y_data)
也就是predicts 以及 y_data的数据类型一致,因此我们需要同样将训练集图片读取的标签转换为tensor类型。