原文链接:体验paddle2.0rc版本API-Model–实现Mnist数据集模型训练:https://blog.csdn.net/weixin_44604887/article/details/109566281
尝试Mnist训练
- 导入需要的包
- 导入Mnist数据集
- 组网
- 搭建网络
- 查看模型参数
- 查看模型网络(自动命名)
- 利用Model-API进行训练
- 模型传入
- Model-API参数配置
- fit--训练
- 模型评估
- 加载保存的模型
- 创建相同的网络模型--用于加载保存的模型参数
- 查看当前运算所在环境是否在GPU
- 加载模型参数
- 方法一
- 方法二
- Model-API参数配置
- 保存模型的评估
- 总结
QQ:3020889729 小蔡
主要内容:
- 利用paddle.vision.datasets加载paddle自带的图像数据集
- 利用paddle.nn.Sequntial进行顺序层网络组网–快捷组网
- 利用paddle.Model进行paddle自带的模型高级API进行一系列简便的训练,模型保存以及评估等
- 利用paddle.Model的load方法,对使用Model下saveAPI保存的模型进行加载
(主体代码源于官方文档,仅对部分知识点进行扩展和说明)
导入需要的包
import paddle
import paddle.nn as nn # 导入网络模块:包含所需要的模块
from paddle import optimizer # 导入优化器模块
from paddle import Model # 导入模型高级API,可传入设计好的网络模型,进行一系列的fit训练等操作
from paddle import metric # 导入度量模块:模型准确率计算等
from paddle.vision import datasets # 导入数据集接口
print(paddle.version) # 打印paddle版本号
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
导入Mnist数据集
datasets.MNIST的参数为mode
- mode=‘train’ 为默认值,返回训练集
- mode=‘test’ 返回验证集
train_datasets = datasets.MNIST(mode='train') # 加载训练数据
test_datasets = datasets.MNIST(mode='test')
- 1
- 2
组网
搭建网络
利用线性层进行组网
mnist = nn.Sequential(nn.Flatten(), # 平铺层,将多维数据展开为一维数据--将[N, ...] 转化为 [N, x]nn.Linear(784, 512), # 线性层(全连接层), 将input_size=N*784 -> N*512nn.ReLU(), # 激活曾(配置激活函数,添加非线性因子), 将上一层Linear的输出通过Relu激活层nn.Dropout(0.2), # 丢弃层(dropout防过拟合), 使用Dropout层进行随机drop(计算输出时,随机将某些值替换为0)nn.Linear(512, 10) # 将经过dropout层的输出size=512 -> 10 -> 得到输出类别
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
查看模型参数
# 查看模型参数--以及命名(字典形式)
for name, value in mnist.named_parameters(): print(name, '->', value)
- 1
- 2
- 3
- 4
查看模型网络(自动命名)
# 查看模型中的子层--即顺序层中的子层 --包括命名(字典形式)
for name, value in mnist.named_children(): print(name, '->', value.full_name())
# 一定程度上等价于以下代码
#for name, value in mnist.named_sublayers():
# print(name, ‘->’, value.full_name())
- 1
- 2
- 3
- 4
- 5
- 6
- 7
顺序层下的网络展示
利用Model-API进行训练
模型传入
# 利用paddle训练API进行快捷训练
model = paddle.Model(mnist) # 将创建的网络送入模型API
- 1
- 2
- 3
Model-API参数配置
# 模型API使用前所需传入参数--在训练前需要使用prepare进行训练配置
# 1-> optim(优化方法)
# 2-> loss(损失/目标函数)
# 3-> metric(评价/度量指标)
model.prepare(optimizer.Adam(parameters=mnist.parameters()), # Adam优化方法nn.CrossEntropyLoss(), # CE损失metric.Accuracy() # 准确率
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
fit–训练
fit参数:
- 明确常用fit参数 – 前四个
- train_data:训练数据–必须要有的
- eval_data: 验证数据–如果没有就不验证
- batch_size: 批大小–尽量设,默认为1
- verbose: 训练进度展示模式–0:无;1,每一个轮次展示进度条模式;2:将轮次作为迭代展示对象;
- eval_freq:评估频率–指间隔多少个eval进行一次评估–默认为1
- log_freq:同样的,日志输出频率–默认为10
- save_dir:模型保存路径–默认为None,不保存
- save_freq: 保存频率–同其他频率
- drop_last:最后一批数据如果不足batch_size,那么就舍去,不使用为训练数据
- shuffle: 是否打乱数据
- num_workers:工作线程–多线程加载数据
- save内容简单说明: pdparams–模型的参数–weight等 pdopt–优化器的参数–学习率大小等
model.fit(train_datasets, # 训练数据集epochs=10, # 轮次batch_size=24, # 批大小: 一次训练用多少个数据verbose=1, # 进度展示--0为不展示save_dir='./work/mnist' # 模型保存路径:包含pdparams与pdopt文件
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
模型评估
# 模型评估
# 参数:
# eval_data:验证集
# batch_size:批大小--默认为1
# log_freq:日志频率
# verbose:进度条模型--0为不展示
# num_workers:多线程
model.evaluate(test_datasets, verbose=1)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
加载保存的模型
创建相同的网络模型–用于加载保存的模型参数
# 创建一摸一样的模型
new_model = nn.Sequential(nn.Flatten(), # 将[N, ...] 转化为 [N, x]nn.Linear(784, 512), # 将input_size=N*784 -> N*512nn.ReLU(), # 将上一层Linear的输出通过Relu激活层nn.Dropout(0.2), # 使用Dropout层进行随机drop(计算输出时,随机将某些值替换为0)nn.Linear(512, 10) # 将经过dropout层的输出size=512 -> 10
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
查看当前运算所在环境是否在GPU
paddle.is_compiled_with_cuda() # 判断当前允许环境--在gpu上返回True
- 1
加载模型参数
方法一
# 按照paddle.Model.load-API 来加载参数
new_Model = Model(new_model)
new_Model.load('./work/mnist/final') # 将保存的参数加载到当前的模型中
for value in new_Model.parameters(): # 在ModelAPI下查看模型参数
print(value)
- 1
- 2
- 3
- 4
- 5
- 6
方法二
new_model.load_dict(paddle.load('./work/mnist/final.pdparams')) # 利用原始paddle通用模型加载API加载模型参数后,再传入ModelAPI
new_Model = Model(new_model)
- 1
- 2
Model-API参数配置
new_Model.prepare(
# 利用set_state_dict加载优化器对应的参数--比如学习率等 optimizer.Adam(parameters=new_model.parameters()).set_state_dict(paddle.load('./work/mnist/final.pdopt')), nn.CrossEntropyLoss(),metric.Accuracy()
)
- 1
- 2
- 3
- 4
- 5
- 6
保存模型的评估
new_Model.evaluate(test_datasets, verbose=1)
- 1
总结
- paddle2.0rc在整体上变化很大,首先是全面支持动态图,方便某火炬的小伙伴转到paddle进行学习
- 组网API更加亲近,将相关组网操作都放到了一起–比如Flatten平铺操作与激活函数作为网络层,方便组网时方法的查讯
- 高级API–Model的使用,方便了一般的训练过程,简化初始模型训练选型的成本(为后期模型选择后优化精度等节约了时间)
- 这次升级,最最最主要的还是API分类更明显,可用性和可读性有了更好的提升,这次简直杠杠的!!!
以下是API分类图(源于官方文档)