深度学习笔记(一) 飞桨框架下的模型训练demo

本文最后更新于 2022年10月19日 上午

最初的需求是做人脸识别,作为菜鸡第一步肯定是去github搜搜,然后在一个仓库简介中知道了飞桨。从零开始且不知道咋开始,英文阅读全靠翻译的我,能找到个全中文的学习地儿就很棒,于是有了本文。

前言

目前我的理解,深度学习就是导出一个能够解决特定任务的模型,例如传入一个人脸,通过模型处理后输出他是男人还是女人,是老人还是小孩。又或是传入一个人说的话,得到他是开心还是生气之类的。
在深度学习之前应该是用特征值来判断,是与否的界限全靠一个明确的特征,但是实际上这个特征是不那么好找的。而深度学习感觉实际上也是判断特征啦,但是它是自己来得出这个特征。
下面来简述下训练一个模型的流程:

  • 数据处理,数据首先需要统一格式,然后区分为训练用还是验证用
  • 模型设计,实际上就是一个猜测的特征,比如判断男女,设计一种判断
    方式,该方式不需要准确,但可以修改参数来调整。
  • 训练配置,就是战前准备了,需要制定一个损失函数用来衡量模型的优劣,一个优化器来指明修改方向。
  • 训练过程,传入数据得到结果,根据实际结果和理论结果计算损失,然后差值和输入计算梯度,用梯度来更新参数降低损失,就这样不断循环
  • 模型保存
    以上是我此时段的理解,可能存在问题,观者自行判断。

环境

我这里是windows11环境,GPU是NV的1050,使用conda来跑。
conda前面有文章就不谈了。
首先在飞桨安装页
查看支持那些CUDA,例如目前最高的是CUDA是11.6,最低的是10.1。然后去看看直接显卡版本支持那些,1050这个最新固件就无所谓了。10.1的最低固件版本是418.96
cuda官网下载,我这儿选择的是11.6.2
下载完成后运行选择解压位置,默认就行,之后会自动删除,安装完成后如果是默认地址则在C盘 program Files下多了个NVIDIA GPU Computing Toolkit文件夹,添加其中的bin/lib/libnvvp三个文件夹到环境变量的path中。
之后安装cuDNN,官网下载需要先注册,可以直接谷歌登录。虽说要对应版本,但是实际操作时我下载的cudnn8.4.1对应CUDA11.6,在训练时报错缺少infer64_8.dll,之后换成了cudnn8.2.4对应CUDA11.4版本就可以。。
在下载后时一个压缩包,将里面的三个文件夹扔进NVIDIA GPU Computing Toolkit中。
然后打开conda的控制台,执行以下

1
2
3
4
conda create -n tt python=3.10
activate tt
python -m pip install paddlepaddle-gpu==2.3.1.post116 -f https://www.paddlepaddle.org.cn/whl/windows/mkl/avx/stable.html

测试cuda是否配置成功

1
2
3
python
import paddle
paddle.utils.run_check()

训练

执行以下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import paddle
import numpy as np
from paddle.vision.transforms import Normalize

#用均值和标准差归一化输入数据
#mean (list|tuple) - 用于每个通道归一化的均值。
#std (list|tuple) - 用于每个通道归一化的标准差值。
#data_format (str, optional): 数据的格式,必须为 'HWC' 或 'CHW'。 默认值: 'CHW'。
transform = Normalize(mean=[127.5], std=[127.5], data_format='CHW')


# 下载数据集并初始化 DataSet
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)

# 模型组网并初始化网络
lenet = paddle.vision.models.LeNet(num_classes=10)
model = paddle.Model(lenet)

# 模型训练的配置准备,准备损失函数,优化器和评价指标
model.prepare(paddle.optimizer.Adam(parameters=model.parameters()),
paddle.nn.CrossEntropyLoss(),
paddle.metric.Accuracy())

# 模型训练
# 共遍历 5 轮(epochs=5),每轮迭代中分批次取数据训练,每批次 64 个样本(batch_size=64),并打印训练过程中的日志(verbose=1)
model.fit(train_dataset, epochs=5, batch_size=64, verbose=1)

# 模型评估
model.evaluate(test_dataset, batch_size=64, verbose=1)

# 保存模型
model.save('./output/mnist')

输出:

1
2
3
4
5
6
7
8
9
10
11
12
step 938/938 [==============================] - loss: 0.0448 - acc: 0.9419 - 17ms/step
Epoch 2/5
step 938/938 [==============================] - loss: 0.0744 - acc: 0.9779 - 13ms/step
Epoch 3/5
step 938/938 [==============================] - loss: 0.0303 - acc: 0.9812 - 13ms/step
Epoch 4/5
step 938/938 [==============================] - loss: 5.5136e-04 - acc: 0.9843 - 13ms/step
Epoch 5/5
step 938/938 [==============================] - loss: 0.1114 - acc: 0.9865 - 13ms/step
Eval begin...
step 157/157 [==============================] - loss: 5.2994e-04 - acc: 0.9833 - 9ms/step
Eval samples: 10000

在output文件中生成了mnist.pdopt和mnist.pdparams,前者时优化器的参数后者是模型参数。
使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import paddle
import numpy as np
from paddle.vision.transforms import Normalize

transform = Normalize(mean=[127.5], std=[127.5], data_format='CHW')
test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)

lenet = paddle.vision.models.LeNet(num_classes=10)
model = paddle.Model(lenet)
model.load('output/mnist')


# 从测试集中取出一张图片
img, label = test_dataset[0]
# 将图片shape从1*28*28变为1*1*28*28,增加一个batch维度,以匹配模型输入格式要求
img_batch = np.expand_dims(img.astype('float32'), axis=0)

# 执行推理并打印结果,此处predict_batch返回的是一个list,取出其中数据获得预测结果
out = model.predict_batch(img_batch)[0]
pred_label = out.argmax()
print('true label: {}, pred label: {}'.format(label[0], pred_label))
# 可视化图片
from matplotlib import pyplot as plt
plt.imshow(img[0])

返回结果

1
true label: 7, pred label: 7

深度学习笔记(一) 飞桨框架下的模型训练demo
https://blog.kala.love/posts/eec07d54/
作者
久远·卡拉
发布于
2022年8月10日
许可协议