训练与预测

    注解

    高层API实现的模型训练与预测如Model.fit()、Model.evaluate()、Model.predict()都可以通过基础API实现,本文先介绍高层API的训练方式,然后会将高层API拆解为基础API的方式,方便对比学习。

    在封装模型前,需要先完成数据的加载与模型的组建,由于这一部分高层API与基础API通用,所以都可用下面的代码实现:

    通过上述的代码,你就完成了训练集与测试集的构建,并创建了一个 mnist的网络模型。下面分别用两种方式完成模型的训练与预测。

    1. model = paddle.Model(mnist)

    paddle.Model完成模型的封装后,在训练前,需要对模型进行配置,通过Model.prepare接口来对训练进行提前的配置准备工作,包括设置模型优化器,Loss计算方法,精度计算方法等。

    1. # 为模型训练做准备,设置优化器,损失函数和精度计算方式
    2. model.prepare(optimizer=paddle.optimizer.Adam(parameters=model.parameters()),
    3. loss=paddle.nn.CrossEntropyLoss(),
    4. metrics=paddle.metric.Accuracy())

    2.2 用Model.fit()训练模型

    做好模型训练的前期准备工作后,调用fit()接口来启动训练过程,需要指定至少3个关键参数:训练数据集,训练轮次和单次训练数据批次大小。

    1. # 启动模型训练,指定训练数据集,设置训练轮次,设置每次数据集计算的批次大小,设置日志格式
    2. model.fit(train_dataset,
    3. epochs=5,
    4. batch_size=64,
    5. verbose=1)
    1. The loss value printed in the log is the current step, and the metric is the average value of previous step.
    2. Epoch 1/5
    3. step 938/938 [==============================] - loss: 0.1785 - acc: 0.9281 - 19ms/step
    4. Epoch 2/5
    5. step 938/938 [==============================] - loss: 0.0365 - acc: 0.9688 - 19ms/step
    6. Epoch 3/5
    7. step 938/938 [==============================] - loss: 0.0757 - acc: 0.9781 - 19ms/step
    8. Epoch 4/5
    9. step 938/938 [==============================] - loss: 0.0054 - acc: 0.9824 - 19ms/step
    10. Epoch 5/5
    11. step 938/938 [==============================] - loss: 0.0640 - acc: 0.9858 - 19ms/step

    对于训练好的模型进行评估可以使用evaluate接口,事先定义好用于评估使用的数据集后,直接调用evaluate接口即可完成模型评估操作,结束后根据在preparelossmetric的定义来进行相关评估结果计算返回。

    返回格式是一个字典: * 只包含loss,{'loss': xxx} * 包含loss和一个评估指标,{'loss': xxx, 'metric name': xxx} * 包含loss和多个评估指标,

    1. Eval begin...
    2. The loss value printed in the log is the current batch, and the metric is the average value of previous step.
    3. step 10000/10000 [==============================] - loss: 3.5763e-07 - acc: 0.9809 - 2ms/step
    4. Eval samples: 10000

    1.4 用Model.predict()预测模型

    返回格式是一个list,元素数目对应模型的输出数目: * 模型是单一输出:[(numpy_ndarray_1, numpy_ndarray_2, …, numpy_ndarray_n)] * 模型是多输出:[(numpy_ndarray_1, numpy_ndarray_2, …, numpy_ndarray_n), (numpy_ndarray_1, numpy_ndarray_2, …, numpy_ndarray_n), …]

    numpy_ndarray_n是对应原始数据经过模型计算后得到的预测数据,数目对应预测数据集的数目。

    1. # 用 predict 在测试集上对模型进行测试
    2. test_result = model.predict(test_dataset)
    1. step 10000/10000 [==============================] - 2ms/step
    2. Predict samples: 10000

    除了通过第一部分的高层API实现模型的训练与预测,飞桨框架也同样支持通过基础API对模型进行训练与预测。简单来说,Model.prepare()、Model.fit()、Model.evaluate()、Model.predict()都是由基础API封装而来。下面通过拆解高层API到基础API的方式,来了解如何用基础API完成模型的训练与预测。

    飞桨框架通过基础API对模型进行训练与预测,对应第一部分的Model.prepare()Model.fit()

    1. # dataset与mnist的定义与第一部分内容一致
    2. # 用 DataLoader 实现数据加载
    3. train_loader = paddle.io.DataLoader(train_dataset, batch_size=64, shuffle=True)
    4. mnist.train()
    5. # 设置迭代次数
    6. epochs = 5
    7. # 设置优化器
    8. optim = paddle.optimizer.Adam(parameters=mnist.parameters())
    9. # 设置损失函数
    10. loss_fn = paddle.nn.CrossEntropyLoss()
    11. for epoch in range(epochs):
    12. for batch_id, data in enumerate(train_loader()):
    13. x_data = data[0] # 训练数据
    14. y_data = data[1] # 训练数据标签
    15. predicts = mnist(x_data) # 预测结果
    16. # 计算损失 等价于 prepare 中loss的设置
    17. loss = loss_fn(predicts, y_data)
    18. # 计算准确率 等价于 prepare 中metrics的设置
    19. acc = paddle.metric.accuracy(predicts, y_data)
    20. # 下面的反向传播、打印训练信息、更新参数、梯度清零都被封装到 Model.fit() 中
    21. # 反向传播
    22. if (batch_id+1) % 900 == 0:
    23. print("epoch: {}, batch_id: {}, loss is: {}, acc is: {}".format(epoch, batch_id+1, loss.numpy(), acc.numpy()))
    24. # 更新参数
    25. optim.step()
    26. # 梯度清零
    27. optim.clear_grad()

    3.2 拆解Model.evaluate()-- 用基础API验证模型

    1. # 加载测试数据集
    2. test_loader = paddle.io.DataLoader(test_dataset, batch_size=64, drop_last=True)
    3. loss_fn = paddle.nn.CrossEntropyLoss()
    4. mnist.eval()
    5. for batch_id, data in enumerate(test_loader()):
    6. x_data = data[0] # 测试数据
    7. y_data = data[1] # 测试数据标签
    8. predicts = mnist(x_data) # 预测结果
    9. # 计算损失与精度
    10. loss = loss_fn(predicts, y_data)
    11. acc = paddle.metric.accuracy(predicts, y_data)
    12. # 打印信息
    13. if (batch_id+1) % 30 == 0:
    14. print("batch_id: {}, loss is: {}, acc is: {}".format(batch_id+1, loss.numpy(), acc.numpy()))
    1. batch_id: 30, loss is: [0.15860887], acc is: [0.953125]
    2. batch_id: 60, loss is: [0.21005578], acc is: [0.921875]
    3. batch_id: 90, loss is: [0.0889321], acc is: [0.953125]
    4. batch_id: 120, loss is: [0.00115552], acc is: [1.]
    5. batch_id: 150, loss is: [0.12016675], acc is: [0.984375]

    飞桨框架通过基础API对模型进行测试,对应第一部分的Model.predict():

    1. # 加载测试数据集
    2. test_loader = paddle.io.DataLoader(test_dataset, batch_size=64, drop_last=True)
    3. mnist.eval()
    4. for batch_id, data in enumerate(test_loader()):
    5. x_data = data[0]
    6. predicts = mnist(x_data)
    7. # 获取预测结果