本文最后更新于 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
transform = Normalize(mean=[127.5], std=[127.5], data_format='CHW')
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())
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]
img_batch = np.expand_dims(img.astype('float32'), axis=0)
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
|