学更好的别人,
做更好的自己。
——《微卡智享》
本文长度为1974字,预计阅读5分钟
前言
很早就想学习深度学习了,因为平时都是自学,业余时间也有限,看过几个pyTorch的入门,都是一些碎片化的东西,始终串不起来。最近也是正好赶的疫情,出差少了,也是在B站看pyTorch视频时有评论说刘二大人的《pyTorch深度学习实践》讲的好,整个教程看下来后,确实是深入浅出,感觉就是宛然打通自己任督二脉,算是入门了。
pyTorch入门,最重要的还是需要真正用起来,OpenCV中DNN模块就是用来推理的,所以这篇就是专门做一个最简单的例子来验证效果,文章最后有源码的Github地址。
# | 实现方式 |
1 | pyTorch训练数据 |
2 | 将pyTorch训练好的数据模型转出为onnx的文件 |
3 | 使用C++ OpenCV DNN实现推理 |
配置环境
操作系统:Windows 11 Home
pyTorch相关:Miniconda + pyTorch1.12.1(cpu) + python3.9.12,IDE用的是Visual Studio Code
OpenCV相关:OpenCV 4.5.1 + C++,IDE用的是Visual Studio 2022
原来环境装的是Anaconda全家桶,需要的资源空间大,而Miniconda是最小的conda安装环境,所以这里推荐还是用Miniconda。具体的环境配置及安装方式,网上挺多的,包括视频也有,可以自行搜索一下。
平时办公外接大屏显示器,现在由于工作原因,现在出差较多,为了解决使用大屏的需求,同时出差携带方便,所以换了折叠屏的笔记本,由原来的ASUS灵耀X DUO换成了ASUS 灵耀X Fold,相应的原来还有独立显卡,现在也只能是集成显卡,pyTorch也装的是CPU版本。上几张两个笔记本对比图
代码实现
微卡智享
做一个最简单的训练及推理,那我们就不用图像,就是一个简单的运算,如下图:
上图中红框代表我要的训练集,我们一眼就可以看出,实现的效果就是输入值乘2得到输出结果,下面两条4.0和100.0用于推理出结果,得到的也应该是8.0和200.0
pyTorch训练
01
定义训练集
导入torch包后,我们直接定义输入的x_data为【1,2,3】,输出的结果y_data为【2,4,6】,输入结果打印如下:
02
定义训练的网络模型及损失函数和优化器
训练模型也非常简单,只有Linear全链接层一层,并且在前馈forward函数中没有用到激活函数,直接输出了。损失函数用的MSE,优化器SGD,其中学习率参数设置的0.02(lr=0.02)
03
训练模型
关于训练,主要就是四个步骤:
- forward(前馈)
- loss(计算损失函数)
- backward(反向传播)
- step(优化迭代)
上面我们设置了训练次数为1000次,每100次打印一下loss,最后输出权重值,训练的结果如下:
04
验证测试及输出onnx模型
训练完成后,我们来验证测试结果,分输入了4,8,10,15四个值,打印结果如下:
上图中可以看到,预测的结果完全准确,接下来我们就将训练的这个模型导出onnx文件用于OpenCV的推理。
- 将model模型改为eval(),是设置为推理模式。
- 定义一个输入的参数模型dummy_input
- 设置输出、输出的参数名称input和output,还有onnx的文件名称
- 用torch.onnx.export进行导出,其中verbose=True是将会输出被导出的轨迹的调试描述
成功后当前目录下会生成一个test.onnx的模型文件,这样pyTorch训练的模型这块就完成了,接下来就是看看如果用OpenCV的DNN进行推理。
C++ OpenCV推理
C++ OpenCV DNN推理这块代码也很简单,主要就是定义了dnn::Net,然后指定到onnx模型文件的目录,使用readNetfromOnnx加载模型文件。
输入的参数还是用OpenCV的Mat,因为只输入一个参数,所以这里定义的就是1X1,数据类型输入是float的类型,所以定义的也是CV_32F,将Mat传入到输入参数里,net.setInput(Mat值,输入参数名),第二个参数与我们导出的参数名相同,再通过net.forward(输出参数名)得到返回的结果。
代码中我们输入的为1024,所以预测的结果为2048,完全正确,这样一个最简单的pyTorch训练模型转出onnx,然后用C++ OpenCV推理的Demo就完成了。
完
微卡智享
源码地址
https://github.com/Vaccae/OpenCVDemoCpp.git