pytorch模型(pth,pkl)轉ncnn(中介onnx)(附搭建ncnn教程)
文章目錄
- pytorch模型(pth,pkl)轉ncnn(中介onnx)(附搭建ncnn教程)
- 部署ncnn
- 在windows上部署ncnn(基于VS2019)
- 在Ubuntu18.04上部署ncnn
- pytorch模型轉onnx(以TDnet為例)
- 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295071.html
標籤:AI
上一篇:PyTorch學習筆記(13)--現有網路模型的使用及修改
下一篇:OPENCV圖片批量更換文字
