QT 6.6.0 中腾讯优图NCNN环境配置以及基于ONNX转NCNN模型文件实现图像分类
yolov5目标检测和QT 6.6.0 基于OpenCV加载yolov5.onnx模型文件实现目标检测
ncnn operation param weight table
how to implement custom layer step by step
目录
问题1:PyTorch官方目标检测模型和分割模型ONNX转NCNN报错
问题2:NCNN执行yolov5s推理过程中卷积中途出现异常?
上一篇博文我们已经讲解了NCNN的相关应用介绍,NCNN的源码编译以及在QT 6.6.0中使用NCNN等相关问题和注意事项,最终通过加载自定义模型和PyTorch官方提供的的分类模型实现了简单的图像分类。本文主要是基于上一篇文章环境的配置实现NCNN在QT中的目标检测,目标检测相比于图像分类的实现过程相对复杂,尽管我们之前有很多文章都列举了目标检测的应用。除了图像分类和目标检测,像其他领域的如图像分割读者也可以进行尝试。
这里就不多说了,直接进入正题,以下最终实现界面的结果,和我们之前基于ONNX在QT中实现的效果界面是一样的,只不过是使用了不同的框架(yolov5s.pnnx -> (yolov5s.param,yolov5s.bin)):
问题1:PyTorch官方目标检测模型和分割模型ONNX转NCNN报错
首先将PyTorch官方提供的fcos_resnet50_fpn目标检测模型和deeplabv3_mobilenet_v3_large分割模型从.pth转换为.onnx中间格式之后,最后使用onnx2ncnn工具转换为NCNN格式,但是会报以下的错误:
注:针对这个问题,网上也有部分给出了解决方案,其中NCNN作者本人给出的解决方案:手工优化ncnn模型结构 ,但是我对NCNN框架目前只是了解一部分,所以并不会去尝试使用这种方式,使用这种方式去解决这个问题等后期再去解决。而且作者推荐目前开源的PNNX工具进行转换,不再需要ONNX中间商表示。下一篇博文会尝试这个PNNX转NCNN,不知道能不能弥补上面截图提到转换失败的问题。
当你为庆幸yolov5还没有进行尝试时,那就是崩溃的开始,从这个问题1到问题2就是崩溃的根源。当yolov5s.onnx转换为ncnn时,如下结果:
也许你可能回想是不是yolov5版本的原因,我这里从yolov5-6.0到yolov5-最新版本都试过了,问题依然存在(至于6.0以前的版本比较久了),到这里就已经是崩溃的开始了。没有办法只能硬着头皮按照NCNN作者提出的“手工优化NCNN模型结构”来尝试一下,对.param文件按照转换过程中存在的问题进行了修改,优化结果如下:
你以为到这里就结束了吗?远远没有,这里优化到没有任何出错之后,到QT中加载模型,幸运的是模型加载成功了,但是在检测图像的时候卷积异常了,问题2。
问题2:NCNN执行yolov5s推理过程中卷积中途出现异常?
首先这个图像的预处理没有问题,并且是指定模型输入图像大小。
手工对yolov5s.param进行优化之后,可以正常的加载模型.param和.bin,但是会报以下的错误,针对这个错误查看了文件许久,依然没有解决(崩溃)。
通过这个截图可以看到,在输入图像推理的时候出现卷积中途异常呢?,从而导致程序崩溃。对于这个问题,说实话我也不清楚是什么原因。
问题3:可视化.param和.bin模型结构
https://netron.app/ 使用网页版的打开.param文件,同时会自动找到对应的.bin文件从而实现可视化效果。如果是下载客户端到本地安装,我这里打不开(建议使用这个网页版的打开)。
onnx转ncnn总结一点
上面的问题1和问题2只是一个失败的案例,至于其他的目标检测算法能否转换ncnn成功,大家尽可去尝试,尝试了才知道会不会失败。对于这个失败案例,大家看一下即可,重点看下面PNNX的使用。按照作者所说的,建议使用pnnx转ncnn。
正式进入主题PNNX
https://github.com/Tencent/ncnn/tree/master/tools/pnnx |
PNNX转换工具(Windows,Linux,macOS) |
pnnx源码下载地址以及相关介绍 |
以下是官方推出PNNX的理由:
PNNX推出三种转换方式,我们这里就使用对源码进行编译,然后将编译得到的可执行文件(用于pnnx转换的工具)对其模型进行转换。
方式一:使用PNNX官方提供的转换工具
通过yolov5官方提供的7.0版本代码仓库将下载的yolov5s.pt通过代码export.py转换为yolov5s.torchscript.pt格式(官方在export.py中提供的转换为torchscript格式,我们这里在后面.pt,转换为pt格式)。
命令:pnnx yolov5s.torchscript.pt inputshape=[1,3,640,640]
实现单张图像和实时检测效果:
QT 6.6.0 中基于PNNX转NCNN模型实现目标检测
方式二:对PNNX源码进行编译
源码编译方式请看这里(建议初学者先尝试使用官方提供的预编译好的pnnx工具)
编译之前的准备
- torch的安装目录:D:\conda3\anaconda3\envs\Pytorch_lightning\Lib\site-packages\torch\share\cmake\Torch(其中Pytorch_lightning是创建的虚拟环境名称)
- torchvision的安装目录:同上。
如果读者不清楚安装目录,通过以下步骤来查看具体信息:
- 查看具体有哪些虚拟环境:conda env list
- 激活具体的环境:activate Pytorch_lightning
- 查看包的具体信息:pip show torchvision
注意:编译所使用的torchvision和torch是不需要GPU版本的(不支持)PNNX作者本人的描述
也可以下载libtorch和torchvision:https://download.pytorch.org/libtorch/cpu/ 和https://github.com/pytorch/vision/archive/refs/tags/v0.18.1.zip (注意libtorch和torchvision之间版本要对应)。
注意CMakeLists.txt中的torch和torchvision路径问题:
除了上面这种去修改CMakeLists.txt文件中的torch和torchvision的路径之外,我们还可以使用pnnx官方提供的命令行方式(推荐):
GitHub - pnnx/pnnx: PyTorch Neural Network eXchange(推荐这种方式编译)
https://zhuanlan.zhihu.com/p/431833958
git clone https://github.com/Tencent/ncnn.git
mkdir ncnn/tools/pnnx/build
cd ncnn/tools/pnnx/build
cmake -DCMAKE_INSTALL_PREFIX=install -DTorch_INSTALL_DIR=<your libtorch install dir> -DTorchVision_INSTALL_DIR=<your torchvision install dir> ..
cmake --build . --config Release -j 4
cmake --build . --config Release --target install
上面的命令根据下载的libtorch或者torch目录提供的路径,以及torchvision的路径,命令对应如下:
git clone https://github.com/Tencent/ncnn.git
mkdir ncnn/tools/pnnx/build
cd ncnn/tools/pnnx/build
cmake .. -DCMAKE_INSTALL_PREFIX=install -DTorch_INSTALL_DIR=D:\conda3\Transfer_Learning\NCNN\ncnn-master\tools\libtorch -DTorchvision_INSTALL_DIR=D:\conda3\Transfer_Learning\NCNN\vision-0.18.1
cmake --build . --config Release -j 4
cmake --build . --config Release --target install
第一步执行:cmake .. -DCMAKE_INSTALL_PREFIX=install -DTorch_INSTALL_DIR=D:\conda3\Transfer_Learning\NCNN\ncnn-master\tools\libtorch -DTorchvision_INSTALL_DIR=D:\conda3\Transfer_Learning\NCNN\vision-0.18.1
第二步执行:cmake --build . --config Release -j 4(执行之后会出现如下颜色的输出结果,不用管,一直让它编译,结束)
第三步:cmake --build . --config Release --target install