当前位置:   article > 正文

PaddlePaddle飞桨(学习笔记六——模型训练、评估与推理)_飞浆模型评估怎么写

飞浆模型评估怎么写

目录

1、训练前准备

1.1 指定训练的硬件

1.2 准备训练用的数据集和模型

2、使用 paddle.Model 高层 API 训练、评估与推理

paddle.Model 封装模型

Model.prepare 配置训练准备参数

Model.fit 训练模型

Model.evaluate 评估模型

Model.predict 执行推理

2.1 使用 paddle.Model 封装模型

2.2 使用 Model.prepare 配置训练准备参数

2.3 使用 Model.fit 训练模型

2.4 使用 Model.evaluate 评估模型

2.5 使用 Model.predict 执行推理

2.6 总结

3、使用基础 API 训练、评估与推理

3.1 模型训练(拆解 Model.prepare、Model.fit)

3.2 模型评估(拆解 Model.evaluate)

3.3 模型推理(拆解 Model.predict)

3.4 总结

4、高层 API 和基础 API 组合使用


1、训练前准备

1.1 指定训练的硬件

模型训练时,需要用到 CPU、 GPU 等计算处理器资源,由于飞桨框架的安装包是区分处理器类型的,默认情况下飞桨框架会根据所安装的版本自动选择对应硬件,比如安装的 GPU 版本的飞桨,则自动使用 GPU 训练模型,无需手动指定。因此一般情况下,无需执行此步骤。

但是如果安装的 GPU 版本的飞桨框架,想切换到 CPU 上训练,则可通过 paddle.device.set_device 修改。如果本机有多个 GPU 卡,也可以通过该 API 选择指定的卡进行训练,不指定的情况下则默认使用 'gpu:0'。

  1. import paddle
  2. # 指定在 CPU 上训练
  3. paddle.device.set_device('cpu')
  4. # 指定在 GPU 第 0 号卡上训练
  5. paddle.device.set_device('gpu:0')

1.2 准备训练用的数据集和模型

模型训练前,需要先完成数据集的加载和模型组网,以 MNIST 手写数字识别任务为例,代码示例如下:

  1. from paddle.vision.transforms import Normalize
  2. transform = Normalize(mean=[127.5], std=[127.5], data_format='CHW')
  3. # 加载 MNIST 训练集和测试集
  4. train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
  5. test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
  6. # 模型组网,构建并初始化一个模型 mnist
  7. mnist = paddle.nn.Sequential(
  8. paddle.nn.Flatten(1, -1),
  9. paddle.nn.Linear(784, 512),
  10. paddle.nn.ReLU(),
  11. paddle.nn.Dropout(0.2),
  12. paddle.nn.Linear(512, 10)
  13. )

2、使用 paddle.Model 高层 API 训练、评估与推理

paddle.Model 封装模型

Model.prepare 配置训练准备参数

Model.fit 训练模型

Model.evaluate 评估模型

Model.predict 执行推理

2.1 使用 paddle.Model 封装模型

  1. # 封装模型为一个 model 实例,便于进行后续的训练、评估和推理
  2. model = paddle.Model(mnist)

2.2 使用 Model.prepare 配置训练准备参数

用 paddle.Model 完成模型的封装后,需通过 Model.prepare 进行训练前的配置准备工作,包括设置优化算法、Loss 计算方法、评价指标计算方法:

  • 优化器(optimizer):即寻找最优解的方法,可计算和更新梯度,并根据梯度更新模型参数。飞桨框架在 paddle.optimizer 下提供了优化器相关 API。并且需要为优化器设置合适的学习率,或者指定合适的学习率策略,飞桨框架在 paddle.optimizer.lr 下提供了学习率策略相关的 API。

  • 损失函数(loss):用于评估模型的预测值和真实值的差距,模型训练过程即取得尽可能小的 loss 的过程。飞桨框架在 paddle.nn Loss层 提供了适用不同深度学习任务的损失函数相关 API。

  • 评价指标(metrics):用于评估模型的好坏,不同的任务通常有不同的评价指标。飞桨框架在 paddle.metric 下提供了评价指标相关 API。

  1. # 为模型训练做准备,设置优化器及其学习率,并将网络的参数传入优化器,设置损失函数和精度计算方式
  2. model.prepare(optimizer=paddle.optimizer.Adam(learning_rate=0.001,parameters=model.parameters()),
  3. loss=paddle.nn.CrossEntropyLoss(),
  4. metrics=paddle.metric.Accuracy())

2.3 使用 Model.fit 训练模型

需要指定至少三个关键参数:训练数据集,训练轮次和每批次大小:

  • 训练数据集:传入之前定义好的训练数据集。

  • 训练轮次(epoch):训练时遍历数据集的次数,即外循环轮次。

  • 批次大小(batch_size):内循环中每个批次的训练样本数。

  1. # 启动模型训练,指定训练数据集,设置训练轮次,设置每次数据集计算的批次大小,设置日志格式
  2. model.fit(train_dataset,
  3. epochs=5,
  4. batch_size=64,
  5. verbose=1)

2.4 使用 Model.evaluate 评估模型

使用 Model.evaluate 接口完成模型评估操作,结束后根据在 Model.prepare 中定义的 loss 和 metric 计算并返回相关评估结果。

返回格式是一个字典:

  • 只包含loss, {'loss': xxx}

  • 包含loss和一个评估指标, {'loss': xxx, 'metric name': xxx}

  • 包含loss和多个评估指标, {'loss': xxx, 'metric name1': xxx, 'metric name2': xxx}

  1. # 用 evaluate 在测试集上对模型进行验证
  2. eval_result = model.evaluate(test_dataset, verbose=1)
  3. print(eval_result)

2.5 使用 Model.predict 执行推理

只需传入待执行推理验证的样本数据,即可计算并返回推理结果。

返回格式是一个列表:

  • 模型是单一输出:[(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), …]

  1. # 用 predict 在测试集上对模型进行推理
  2. test_result = model.predict(test_dataset)
  3. print(test_result[0][0])
  4. # 打印推理结果,这里的argmax函数用于取出预测值中概率最高的一个的下标,作为预测标签
  5. pred_label = test_result[0][0].argmax()
  6. print('true label: {}, pred label: {}'.format(label[0], pred_label))
[[ -6.512169   -6.7076845   0.5048795   1.6733919  -9.670526   -1.6352568
  -15.833721   13.87411    -8.215239    1.5966017]]

true label: 7, pred label: 7

经过模型的计算得到一个数组 [[ -6.5593615 -6.4680595 -1.4708003 2.1043894 -11.743436 -4.4516582 -14.733968 12.036645 -6.582403 -1.8672216]],取其中最大的值(12.036645)的下标(对应 label 7),即得到该样本数据的预测结果(pred label: 7),可视化该样本图像(true label: 7),与预测结果一致,说明模型准确预测了样本图像上的数字。 

2.6 总结

完整代码

  1. from paddle.vision.transforms import Normalize
  2. ######################数据准备########################################
  3. #####################################################################
  4. transform = Normalize(mean=[127.5], std=[127.5], data_format='CHW')
  5. # 加载 MNIST 训练集和测试集
  6. train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
  7. test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
  8. ######################模型组网########################################
  9. #####################################################################
  10. # 模型组网,构建并初始化一个模型 mnist
  11. mnist = paddle.nn.Sequential(
  12. paddle.nn.Flatten(1, -1),
  13. paddle.nn.Linear(784, 512),
  14. paddle.nn.ReLU(),
  15. paddle.nn.Dropout(0.2),
  16. paddle.nn.Linear(512, 10)
  17. )
  18. ######################封装模型########################################
  19. ######################!paddle.Model!################################
  20. # 封装模型为一个 model 实例,便于进行后续的训练、评估和推理
  21. model = paddle.Model(mnist)
  22. ######################配置训练准备参数#################################
  23. ######################!Model.prepare!###############################
  24. # 为模型训练做准备,设置优化器及其学习率,并将网络的参数传入优化器,设置损失函数和精度计算方式
  25. model.prepare(optimizer=paddle.optimizer.Adam(learning_rate=0.001,parameters=model.parameters()),
  26. loss=paddle.nn.CrossEntropyLoss(),
  27. metrics=paddle.metric.Accuracy())
  28. ######################训练模型#######################################
  29. #####################!Model.fit!###################################
  30. # 启动模型训练,指定训练数据集,设置训练轮次,设置每次数据集计算的批次大小,设置日志格式
  31. model.fit(train_dataset,
  32. epochs=5, #循环次数
  33. batch_size=64,#每批次的数量
  34. verbose=1)#日志
  35. ######################评估模型#######################################
  36. #####################!Model.evaluate!##############################
  37. # 用 evaluate 在测试集上对模型进行验证
  38. eval_result = model.evaluate(test_dataset, verbose=1)
  39. print(eval_result)
  40. ######################执行推理#######################################
  41. #####################!Model.predict!##############################
  42. # 用 predict 在测试集上对模型进行推理
  43. ###############
  44. ###############
  45. test_result = model.predict(test_dataset)
  46. ###############
  47. ###############
  48. # 由于模型是单一输出,test_result的形状为[1, 10000],10000是测试数据集的数据量。这里打印第一个数据的结果,这个数组表示每个数字的预测概率
  49. print(len(test_result))
  50. print(test_result[0][0])
  51. # 从测试集中取出一张图片
  52. img, label = test_dataset[0]
  53. # 打印推理结果,这里的argmax函数用于取出预测值中概率最高的一个的下标,作为预测标签
  54. pred_label = test_result[0][0].argmax()
  55. print('true label: {}, pred label: {}'.format(label[0], pred_label))
  56. # 使用matplotlib库,可视化图片
  57. from matplotlib import pyplot as plt
  58. plt.imshow(img[0])

3、使用基础 API 训练、评估与推理

3.1 模型训练(拆解 Model.prepare、Model.fit)

飞桨框架通过基础 API 对模型进行训练,对应高层 API 的 Model.prepare 与 Model.fit ,一般包括如下几个步骤:

  1. 加载训练数据集、声明模型、设置模型实例为 train 模式

  2. 设置优化器、损失函数与各个超参数

  3. 设置模型训练的二层循环嵌套,并在内层循环嵌套中设置如下内容

        3.1 从数据读取器 DataLoader 获取一批次训练数据

        3.2 执行一次预测,即经过模型计算获得输入数据的预测值

        3.3 计算预测值与数据集标签的损失

        3.4 计算预测值与数据集标签的准确率

        3.5 将损失进行反向传播

        3.6 打印模型的轮数、批次、损失值、准确率等信息

        3.7 执行一次优化器步骤,即按照选择的优化算法,根据当前批次数据的梯度更新传入优化器的参数

        3.8 将优化器的梯度进行清零

  1. from paddle.vision.transforms import Normalize
  2. transform = Normalize(mean=[127.5], std=[127.5], data_format='CHW')
  3. # 加载 MNIST 训练集和测试集
  4. train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
  5. test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
  6. # 模型组网,构建并初始化一个模型 mnist
  7. mnist = paddle.nn.Sequential(
  8. paddle.nn.Flatten(1, -1),
  9. paddle.nn.Linear(784, 512),
  10. paddle.nn.ReLU(),
  11. paddle.nn.Dropout(0.2),
  12. paddle.nn.Linear(512, 10)
  13. )
  14. #########################################
  15. #########################################
  16. # dataset与mnist的定义与使用高层API的内容一致
  17. # 用 DataLoader 实现数据加载
  18. train_loader = paddle.io.DataLoader(train_dataset,batch_size=64,shuffle=True)
  19. # 将mnist模型及其所有子层设置为训练模式。这只会影响某些模块,如Dropout和BatchNorm。
  20. mnist.train()
  21. # 设置迭代次数
  22. epochs = 5
  23. # 设置优化器
  24. optim = paddle.optimizer.Adam(parameters=mnist.parameters())
  25. # 设置损失函数
  26. loss_fn = paddle.nn.CrossEntropyLoss()
  27. for epoch in range(epochs):
  28. for batch_id, data in enumerate(train_loader()):
  29. x_data = data[0] # 训练数据
  30. y_data = data[1] # 训练数据标签
  31. predicts = mnist(x_data) # 预测结果
  32. # 计算损失 等价于 prepare 中loss的设置
  33. loss = loss_fn(predicts, y_data)
  34. # 计算准确率 等价于 prepare 中metrics的设置
  35. acc = paddle.metric.accuracy(predicts, y_data)
  36. # 下面的反向传播、打印训练信息、更新参数、梯度清零都被封装到 Model.fit() 中
  37. # 反向传播
  38. loss.backward()
  39. if (batch_id+1) % 900 == 0:
  40. print("epoch: {}, batch_id: {}, loss is: {}, acc is: {}".format(epoch, batch_id+1, loss.numpy(), acc.numpy()))
  41. # 更新参数
  42. optim.step()
  43. # 梯度清零
  44. optim.clear_grad()

3.2 模型评估(拆解 Model.evaluate)

飞桨框架通过基础 API 对训练好的模型进行评估,对应高层 API 的 Model.evaluate 。与模型训练相比,模型评估的流程有如下几点不同之处:

  1. 加载的数据从训练数据集改为测试数据集

  2. 模型实例从 train 模式改为 eval 模式

  3. 不需要反向传播、优化器参数更新和优化器梯度清零

  1. # 加载测试数据集
  2. test_loader = paddle.io.DataLoader(test_dataset, batch_size=64, drop_last=True)
  3. # 设置损失函数
  4. loss_fn = paddle.nn.CrossEntropyLoss()
  5. # 将该模型及其所有子层设置为预测模式。这只会影响某些模块,如Dropout和BatchNorm
  6. mnist.eval()
  7. # 禁用动态图梯度计算
  8. for batch_id, data in enumerate(test_loader()):
  9. x_data = data[0] # 测试数据
  10. y_data = data[1] # 测试数据标签
  11. predicts = mnist(x_data) # 预测结果
  12. # 计算损失与精度
  13. loss = loss_fn(predicts, y_data)
  14. acc = paddle.metric.accuracy(predicts, y_data)
  15. # 打印信息
  16. if (batch_id+1) % 30 == 0:
  17. print("batch_id: {}, loss is: {}, acc is: {}".format(batch_id+1, loss.numpy(), acc.numpy()))

3.3 模型推理(拆解 Model.predict)

飞桨框架通过基础 API 对训练好的模型执行推理,对应高层 API 的 Model.predict 。模型的推理过程相对独立,是在模型训练与评估之后单独进行的步骤。只需要执行如下步骤:

  1. 加载待执行推理的测试数据,并将模型设置为 eval 模式

  2. 读取测试数据并获得预测结果

  3. 对预测结果进行后处理

  1. # 加载测试数据集
  2. test_loader = paddle.io.DataLoader(test_dataset, batch_size=64, drop_last=True)
  3. # 将该模型及其所有子层设置为预测模式
  4. mnist.eval()
  5. for batch_id, data in enumerate(test_loader()):
  6. # 取出测试数据
  7. x_data = data[0]
  8. # 获取预测结果
  9. predicts = mnist(x_data)
  10. print("predict finished")
  11. # 从测试集中取出一组数据
  12. img, label = test_loader().next()
  13. # 执行推理并打印结果
  14. pred_label = mnist(img)[0].argmax()
  15. print('true label: {}, pred label: {}'.format(label[0].item(), pred_label[0].item()))
  16. # 可视化图片
  17. from matplotlib import pyplot as plt
  18. plt.imshow(img[0][0])

3.4 总结

完整代码

  1. from paddle.vision.transforms import Normalize
  2. ########################数据加载########################################
  3. #######################################################################
  4. transform = Normalize(mean=[127.5], std=[127.5], data_format='CHW')
  5. # 加载 MNIST 训练集和测试集
  6. train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
  7. test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
  8. #########################模型组网#######################################
  9. #######################################################################
  10. # 模型组网,构建并初始化一个模型 mnist
  11. mnist = paddle.nn.Sequential(
  12. paddle.nn.Flatten(1, -1),
  13. paddle.nn.Linear(784, 512),
  14. paddle.nn.ReLU(),
  15. paddle.nn.Dropout(0.2),
  16. paddle.nn.Linear(512, 10)
  17. )
  18. #########################模型训练#######################################
  19. #######################################################################
  20. # dataset与mnist的定义与使用高层API的内容一致
  21. # 用 DataLoader 实现数据加载
  22. train_loader = paddle.io.DataLoader(train_dataset, batch_size=64, shuffle=True)
  23. # 将mnist模型及其所有子层设置为训练模式。这只会影响某些模块,如Dropout和BatchNorm。
  24. #####################
  25. #####################
  26. mnist.train()
  27. #####################
  28. #####################
  29. # 设置迭代次数
  30. epochs = 5
  31. # 设置优化器
  32. optim = paddle.optimizer.Adam(parameters=mnist.parameters())
  33. # 设置损失函数
  34. loss_fn = paddle.nn.CrossEntropyLoss()
  35. #####################
  36. #####################
  37. for epoch in range(epochs):
  38. for batch_id, data in enumerate(train_loader()):
  39. x_data = data[0] # 训练数据
  40. y_data = data[1] # 训练数据标签
  41. predicts = mnist(x_data) # 预测结果
  42. # 计算损失 等价于 prepare 中loss的设置
  43. loss = loss_fn(predicts, y_data)
  44. # 计算准确率 等价于 prepare 中metrics的设置
  45. acc = paddle.metric.accuracy(predicts, y_data)
  46. # 下面的反向传播、打印训练信息、更新参数、梯度清零都被封装到 Model.fit() 中
  47. # 反向传播
  48. loss.backward()
  49. if (batch_id+1) % 900 == 0:
  50. print("epoch: {}, batch_id: {}, loss is: {}, acc is: {}".format(epoch, batch_id+1, loss.numpy(), acc.numpy()))
  51. # 更新参数
  52. optim.step()
  53. # 梯度清零
  54. optim.clear_grad()
  55. #########################模型评估#######################################
  56. #######################################################################
  57. # 加载测试数据集
  58. test_loader = paddle.io.DataLoader(test_dataset, batch_size=64, drop_last=True)
  59. # 设置损失函数
  60. loss_fn = paddle.nn.CrossEntropyLoss()
  61. # 将该模型及其所有子层设置为预测模式。这只会影响某些模块,如Dropout和BatchNorm
  62. #####################
  63. #####################
  64. mnist.eval()
  65. #####################
  66. #####################
  67. # 禁用动态图梯度计算
  68. for batch_id, data in enumerate(test_loader()):
  69. x_data = data[0] # 测试数据
  70. y_data = data[1] # 测试数据标签
  71. predicts = mnist(x_data) # 预测结果
  72. # 计算损失与精度
  73. loss = loss_fn(predicts, y_data)
  74. acc = paddle.metric.accuracy(predicts, y_data)
  75. # 打印信息
  76. if (batch_id+1) % 30 == 0:
  77. print("batch_id: {}, loss is: {}, acc is: {}".format(batch_id+1, loss.numpy(), acc.numpy()))
  78. #########################模型推理#######################################
  79. #######################################################################
  80. # 加载测试数据集
  81. # 将该模型及其所有子层设置为预测模式
  82. for batch_id, data in enumerate(test_loader()):
  83. # 取出测试数据
  84. x_data = data[0]
  85. # 获取预测结果
  86. predicts = mnist(x_data)
  87. print("predict finished")
  88. # 从测试集中取出一组数据
  89. img, label = test_loader().next()
  90. # 执行推理并打印结果
  91. pred_label = mnist(img)[0].argmax()
  92. print('true label: {}, pred label: {}'.format(label[0].item(), pred_label[0].item()))
  93. # 可视化图片
  94. from matplotlib import pyplot as plt
  95. plt.imshow(img[0][0])

4、高层 API 和基础 API 组合使用

同时,飞桨的高层 API 和基础 API 可以组合使用,并不是完全割裂开的,这样有助于开发者更便捷地完成算法迭代。示例代码如下:

  1. from paddle.vision.models import LeNet
  2. class FaceNet(paddle.nn.Layer):
  3. def __init__(self):
  4. super().__init__()
  5. # 使用高层API组网
  6. #######################
  7. self.backbone = LeNet()
  8. #######################
  9. # 使用基础API组网
  10. #######################
  11. self.outLayer1 = paddle.nn.Sequential(
  12. paddle.nn.Linear(10, 512),
  13. paddle.nn.ReLU(),
  14. paddle.nn.Dropout(0.2)
  15. )
  16. #######################
  17. self.outLayer2 = paddle.nn.Linear(512, 10)
  18. #######################
  19. #######################
  20. #######################
  21. def forward(self, inputs):
  22. out = self.backbone(inputs)
  23. out = self.outLayer1(out)
  24. out = self.outLayer2(out)
  25. #######################
  26. #######################
  27. return out
  28. # 使用高层API封装网络
  29. model = paddle.Model(FaceNet())
  30. # 使用基础API定义优化器
  31. optim = paddle.optimizer.Adam(learning_rate=1e-3, parameters=model.parameters())
  32. # 使用高层API封装优化器和损失函数
  33. model.prepare(optim, paddle.nn.CrossEntropyLoss(), metrics=paddle.metric.Accuracy())
  34. # 使用高层API训练网络
  35. model.fit(train_dataset, test_dataset, epochs=5, batch_size=64, verbose=1)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/813877
推荐阅读
相关标签
  

闽ICP备14008679号