pytorch模型(pth,pkl)转ncnn(中介onnx)(附搭建ncnn教程)

pytorch模型(pth,pkl)转ncnn(中介onnx)(附搭建ncnn教程)

部署ncnn

pytorch转ncnn是要在电脑上部署好ncnn环境,下图为可部署ncnn的平台
请添加图片描述

在windows上部署ncnn(基于VS2019)

一.安装VS2019

下载地址:https://visualstudio.microsoft.com/zh-hans/vs/

请添加图片描述
请添加图片描述

二.安装cmake 3.16.5

1.下载后解压

2.添加环境变量(将解压后cmake-3.16.5-win64-x64文件夹点开进入bin将该路径添加至环境变量)

三.安装protobuf-3.4.0

​ 1.下载后解压

​ 2.使用VS2019中X64的命令行(下图红框)

请添加图片描述
​ 4.打开命令行后输入命令( 为你刚刚解压的protobuf-3.4.0文件夹的根目录)

> cd <protobuf-root-dir>
> mkdir build-vs2019
> cd build-vs2019
> cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ../cmake
> nmake
> nmake install

​ 5.成功后会产生build-vs2019文件夹以及该文件夹下的若干文件夹及文件

请添加图片描述

四.构建ncnn

1.ncnn下载地址:https://github.com/Tencent/ncnn (官网)

2.git clone该项目,或者直接下载压缩包

3.打开VS2019的X64命令行(进入到ncnn根目录下)执行以下语句

​ 注意:cmake -G…这条命令有三个需要换成之前安装protobuf-3.4.0的根目录

> cd <ncnn-root-dir>
> mkdir -p build-vs2019
> cd build-vs2019
> cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=<protobuf-root-dir>/build-vs2019/install/include -DProtobuf_LIBRARIES=<protobuf-root-dir>/build-vs2019/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=<protobuf-root-dir>/build-vs2019/install/bin/protoc.exe -DNCNN_VULKAN=OFF ..
> nmake
> nmake install

4.成功后会产生build-vs2019文件夹以及该文件夹下的若干文件夹及文件

五.安装opencv

​ 1.下载地址:https://github.com/opencv/opencv/releases/tag/3.4.2

​ 2.下载opencv-3.4.2-vc14_vc15.exe

​ 3.下载后解压

​ 4.配置环境变量(类比cmake)

在Ubuntu18.04上部署ncnn

一.将gcc、g++降级为4.8.5版本

sudo apt-get install gcc-4.8 g++4.8
cd /usr/bin
sudo rm g++ gcc
sudo ln -s gcc-4.8 gcc
sudo ln -s g++-4.8 g++

二.安装protobuf

​ 1.下载地址: https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz

​ 2.下载protobuf后解压

​ 3.执行以下命令

cd protobuf-2.6.1
./configure
make -j8
make check
sudo make install
sudo ldconfig

三.安装opencv

​ 1.1安装cmake

sudo apt-get install cmake

​ 1.2所需依赖

sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev
sudo apt-get install libgtk2.0-dev
sudo apt-get install pkg-config

​ 2.1下载opencv(建议3.版本的)

​ 下载地址:https://opencv.org/releases/

​ 2.2解压文件并进入文件夹

mkdir build
cd build
sudo cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
sudo make -j8
sudo make install

​ 2.3配置环境

​ 使用vim打开/etc/ld.so.conf,在文件中加一行/usr/local/lib(其中/user/loacal是opencv安装路径也就是makefile中指定的安装路径)

sudo gedit /etc/ld.so.conf
sudo ldconfig

​ 用vim在bash.bashrc文件末尾加入:

​ PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

​ export PKG_CONFIG_PATH

​ 然后使用命令

source /etc/bash.bashrc

四.安装ncnn

git clone https://github.com/Tencent/ncnn.git
cd ncnn
mkdir build && cd build
cmake ..
make
make install

pytorch模型转onnx(以TDnet为例)

pytorch转onnx主要是用pytorch里面自带的*torch.onnx.export()*这个函数(这个函数目前在pytorch1.4版本存在)。

先看来一下torch.onnx.export()的原型与部分参数

torch.onnx.export(model, args, f, export_params=True, verbose=False, training=False, input_names=None, output_names=None, aten=False, export_raw_ir=False, operator_export_type=None, opset_version=None, _retain_param_name=True, do_constant_folding=False, example_outputs=None, strip_doc_string=True, dynamic_axes=None, keep_initializers_as_inputs=None)

model:要转换的模型。

args:模型输入。

export_params : 如果指定为True或默认, 参数也会被导出. 如果你要导出一个没训练过的就设为 False.

verbose: 如果指定,我们将打印出一个导出轨迹的调试描述。

training : 训练模式导出模型。 目前,ONNX 仅面向导出模型以进行推理,因此通常不需要将其设置为 True。

input_names : 按顺序分配名称到图中的输入节点。

output_names :按顺序分配名称到图中的输出节点。

opset_version :默认情况下,将模型导出到 onnx 子模块的 opset 版本。

样例:

import torch
from model import td4_psp18  ##引入自己的网络


##加载模型
model = td4_psp18.td4_psp18(nclass=19,path_num=4,model_path=".\\pretrained\\cityscapes\\td4-psp18.pkl")

model.eval()

input=torch.randn(1,3,769,1537)  ##网络输入
input_names=["input"]
output_names=["output"]
out_onnx='C:\\Users\\30229\\Desktop\\TDNet-master\\test.onnx'
torch.onnx.export(model,input,out_onnx,input_names=input_names,output_names=output_names,opset_version=11)

我这里设置opset_version=11是因为在转换模型的时候报错说opset_version=9不支持,需要换成opset_version=11。

TDnet除了这个参数会报错之外还不支持AdaptiveAvgPool2d,可以将AdaptiveAvgPool2d转为AvgPool2d

原代码
# self.pool1 = nn.AdaptiveAvgPool2d(1)
# self.pool2 = nn.AdaptiveAvgPool2d(2)
# self.pool3 = nn.AdaptiveAvgPool2d(3)
# self.pool4 = nn.AdaptiveAvgPool2d(6)

修改后
self.pool1=nn.AvgPool2d(kernel_size = (97,193),stride=(97,193),ceil_mode=False)
self.pool2=nn.AvgPool2d(kernel_size = (49,97),stride=(48,96),ceil_mode=False)
self.pool3=nn.AvgPool2d(kernel_size = (33,65),stride=(32,64),ceil_mode=False)
self.pool4=nn.AvgPool2d(kernel_size = (17,33),stride=(16,32),ceil_mode=False)

修改之后就可以使用torch.onnx.export()将pth/pkl文件转onnx了,虽然可以转到ncnn但是在使用ncnn时会发现LayerNorm层报错,可能是不兼容的问题,之后我把LayerNorm层删掉重新转出来的ncnn文件就可以正常使用了。可能是不兼容的问题,等后面改好了再添加修改方案。

转成的onnx文件还要测试一下,看看模型是否正常。测试代码如下

import os.path as osp
import numpy as np
import onnx
import onnxruntime as ort
import torch
import torchvision

##加载模型所在模块
from model import td4_psp18, td2_psp50, pspnet 

# 模型输入
test_arr = np.random.randn(1, 3, 769, 1537).astype(np.float32)
 
dummy_input = torch.randn(1, 3, 769, 1537, device='cuda')

#载入pytorch模型
model = td4_psp18.td4_psp18(nclass=19,path_num=4,model_path="C:\\Users\\30229\\Desktop\\TDNet-master\\pretrained\\cityscapes\\td4-psp18.pkl").cuda().eval()
print('pytorch result:', model(torch.from_numpy(test_arr).cuda()))
 
input_names = ["input"]
output_names = ["output"]
 
# if not osp.exists('TDnet.onnx'):
#     # translate your pytorch model to onnx
#     torch.onnx.export(model, dummy_input, "TDnet.onnx", verbose=True, input_names=input_names, output_names=output_names)
 
 #载入onnx模型
model = onnx.load("转ncnn\\test.onnx")
ort_session = ort.InferenceSession('转ncnn\\test.onnx')
outputs = ort_session.run(None, {'input': test_arr})
 
print('test result:', outputs[0])

然后可以对比一下原输出和转onnx模型的输出。两个输出有部分误差的话是正常现象,一般转模型都可能出现精度损失。下图为我输出的对比图请添加图片描述

onnx转ncnn

用torch导出的模型有时候参数过多,直接转ncnn会报错。查阅资料后发现可以使用onnxsim进行简化

pip install onnx-simplifier
python -m onnxsim model_name.onnx model_name-sim.onnx

出现下面这样就说明简化成功了
请添加图片描述

之后到之前部署好的ncnn目录里面打开build-vs2019(Windows)或者build(Ubuntu)依次进入tool和onnx,里面有个onnx2ncnn.exe 。把转换好的onnx文件和这个exe文件放在一起后运行

./onnx2ncnn.exe model_name.onnx model_name.bin model_name.param

在文件中出现bin和param文件,就说明转化成功

参考文章
在windows上部署ncnn:https://blog.csdn.net/qq_36890370/article/details/104966786
在ubuntu上安装opencv:https://blog.csdn.net/public669/article/details/99044895

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值