超简单的pyTorch训练->onnx模型->C++ OpenCV DNN推理(附源码地址)

学更好的别人,

做更好的自己。

——《微卡智享》

02d27cd2fb04ea8125f457b29e61b7d8.jpeg

本文长度为1974,预计阅读5分钟

前言

很早就想学习深度学习了,因为平时都是自学,业余时间也有限,看过几个pyTorch的入门,都是一些碎片化的东西,始终串不起来。最近也是正好赶的疫情,出差少了,也是在B站看pyTorch视频时有评论说刘二大人的《pyTorch深度学习实践》讲的好,整个教程看下来后,确实是深入浅出,感觉就是宛然打通自己任督二脉,算是入门了。

pyTorch入门,最重要的还是需要真正用起来,OpenCV中DNN模块就是用来推理的,所以这篇就是专门做一个最简单的例子来验证效果,文章最后有源码的Github地址。

0ff0d9a3d24041e6d11fb0f0863aa52c.png

# 实现方式
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版本。上几张两个笔记本对比图

c21674c7d6519c005a44cbd52e05cacf.jpeg

7686eb22652659964762a8aad8b0b1a4.jpeg

38533352dd4224d6774e82b2dc1f3472.png

代码实现

774fd61e6cfedeb540a07cf0f9e78db2.png

微卡智享

做一个最简单的训练及推理,那我们就不用图像,就是一个简单的运算,如下图:

e97ef5e2f76030081cf4b39f4a35283d.png

上图中红框代表我要的训练集,我们一眼就可以看出,实现的效果就是输入值乘2得到输出结果,下面两条4.0和100.0用于推理出结果,得到的也应该是8.0和200.0

pyTorch训练

01

定义训练集

a484e8d1aeeec6bee68d4cb1e9966996.png

导入torch包后,我们直接定义输入的x_data为【1,2,3】,输出的结果y_data为【2,4,6】,输入结果打印如下:

f42941468963d713b5d6d1881937c9e7.png

02

定义训练的网络模型及损失函数和优化器

462979809864acc366b447c862a1c7b4.png

训练模型也非常简单,只有Linear全链接层一层,并且在前馈forward函数中没有用到激活函数,直接输出了。损失函数用的MSE,优化器SGD,其中学习率参数设置的0.02(lr=0.02)

03

训练模型

4025631be7ed43ab6760d1e30159afec.png

关于训练,主要就是四个步骤:

  1. forward(前馈)

  2. loss(计算损失函数)

  3. backward(反向传播)

  4. step(优化迭代)

上面我们设置了训练次数为1000次,每100次打印一下loss,最后输出权重值,训练的结果如下:

404d35da7262d8f35a8619fab84e955e.png

04

验证测试及输出onnx模型

d511fca12cae05f21e9ccf6d7704c0f6.png

训练完成后,我们来验证测试结果,分输入了4,8,10,15四个值,打印结果如下:

32f1c12d53cd8a02937e1e4786689940.png

上图中可以看到,预测的结果完全准确,接下来我们就将训练的这个模型导出onnx文件用于OpenCV的推理。

cde05f6aa87499bb8da6ef04acbc5b59.png

  1. 将model模型改为eval(),是设置为推理模式。

  2. 定义一个输入的参数模型dummy_input

  3. 设置输出、输出的参数名称input和output,还有onnx的文件名称

  4. 用torch.onnx.export进行导出,其中verbose=True是将会输出被导出的轨迹的调试描述

成功后当前目录下会生成一个test.onnx的模型文件,这样pyTorch训练的模型这块就完成了,接下来就是看看如果用OpenCV的DNN进行推理。

C++ OpenCV推理

9348ee26fe678bca00960f4116d5a3d6.png

C++ OpenCV DNN推理这块代码也很简单,主要就是定义了dnn::Net,然后指定到onnx模型文件的目录,使用readNetfromOnnx加载模型文件。

The input parameter still uses OpenCV's Mat, because only one parameter is input, so the definition here is 1X1, the data type input is the type of float, so the definition is also CV_32F, and Mat is passed into the input parameter, net.setInput(Mat Value, input parameter name), the second parameter is the same as the parameter name we exported, and then get the returned result through net.forward (output parameter name).
 

8b375a21a0f76c1fecfd8a0d9d6f7ef7.png

In the code, we input 1024, so the predicted result is 2048, which is completely correct. Such a simple pyTorch training model is transferred to onnx, and then the Demo of C++ OpenCV reasoning is completed.

over

c0b4e255eefd8743fe0fe71285b31e5d.png

Micro card Zhixiang

source address

https://github.com/Vaccae/OpenCVDemoCpp.git

Click to read the original text to see the code address of "Code Cloud"

6d0e571f5eec544d746ca8ff5a362c31.png

Wonderful review of the past

8fc8fd206a22120d4778889490d0a50f.jpeg

Kotlin uses Select expression in coroutine to select fastest result

 

14c33670fd4b6f1c84122cee9d19c45a.jpeg

C++ OpenCV manually intercepts images for perspective transformation

 

0a2a58bcdb71e468a78ee17a128c2370.jpeg

Use OpenCV to make a simple color extractor

Guess you like

Origin blog.csdn.net/Vaccae/article/details/128029908