天天看點

Jetson nano上使用ncnn部署yolox

序言

之前一篇文章寫yolox的訓練,這篇文章寫一下關于部署,yolox之是以剛出來就這麼火爆,不僅是精度高、速度快,很大程度上還是因為直接把部署的代碼葉開源了,可謂是從訓練到部署一條龍服務,很良心,yolox裡面開源的部署代碼有四種:ncnn、openvino、onnx和tensorrt,剛好手上有一個nano的闆子,是以打算試試yolox使用ncnn在nano上的效果,寫一篇文章記錄一下過程。

yolox相關博文:

  • YOLOX自定義資料集訓練(搶先踩坑)
  • 使用libtorch部署yolox

一、模型轉換pytorch->onnx

使用ncnn部署,模型轉換的步驟還是:pytorch ->onnx -> ncnn,是以第一步需要将pytorch架構下訓練的模型先轉成onnx,然後在通過onnx轉成ncnn進行部署。部署的時候在兩台機器上操作,一是我的電腦主機,用于pytorch到onnx的模型轉換及onnx模型簡化,二是nano,用來編譯ncnn及一些cpp代碼修改和最後的編譯代碼工作。

轉onnx的步驟很簡單,因為代碼已經在倉庫中提供了,是以我們隻需要在終端運作指令即可:

python tools/export_onnx.py -n yolox-s -c weights/best_ckpt.pth.tar
           

這裡我加載了上次訓練好的權重,權重放在weights檔案夾下,運作後模型預設輸出的是yolox.onnx,在主目錄下可以找到。

特别要注意的是,因為這裡預設建構的模型是按照coco資料集來的,是以分類數是80,因為我訓練的網絡分類數隻有1類,是以在運作之前要修改exps/default/yolox_s.py檔案,将類别數改為1:

Jetson nano上使用ncnn部署yolox

然後再重新運作上面的指令,得到yolox.onnx檔案,得到onnx檔案後我們需要使用onnx-simplifier來簡化一下模型,可以一定程度上減少模型裡面出現的一些膠水OP,是以需要在終端中運作如下代碼:

pip install onnx-simplifier                  # pip安裝,如果已經安裝了可以不用執行這一步
python -m onnxsim yolox.onnx yolox_sim.onnx      # 直接運作
           
Jetson nano上使用ncnn部署yolox

這裡就已經成功了,得到一個新的yolox_sim.onnx簡化後的onnx模型。

二、nano上編譯ncnn環境

這一步也比較簡單,網上的教程也比較多,我這裡就直接貼出運作的指令即可,關于nano的刷機以及opencv的編譯可以參考我之前的文章:Jetson nano系統燒錄及pytorch環境配置,然後在這個基礎之上直接編譯ncnn:

https://github.com/Tencent/ncnn.git                  # git ncnn源碼
cd ncnn
git submodule update --depth=1 --init
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/jetson.toolchain.cmake -DNCNN_VULKAN=ON -DCMAKE_BUILD_TYPE=Release ..
make -j4
sudo make install
           

編譯完成後可以測試一下,把ncnn主目錄下子檔案夾中的param檔案全部複制到剛才的build/benchmark目錄中,然後進到ncnn/build/benchmark目錄中執行:

Jetson nano上使用ncnn部署yolox

看到如上輸出則為編譯成功。

三、模型轉換onnx->ncnn

編譯成功好需要将onnx模型轉換成ncnn模型,是以将剛才生成的yolox_sim.onnx模型拷貝到build/tools/onnx檔案夾中,然後執行如下語句:

Jetson nano上使用ncnn部署yolox

得到如上輸出,不過不要緊,這是focus子產品轉換的報錯,ncnn中已經實作了focus,隻需要按照如下修改,打開yolox.param檔案,修改這兩處:

Jetson nano上使用ncnn部署yolox

其中圈起來的Crop操作即為focus子產品,因為ncnn中已經實作了,是以我們需要将這十層删除,然後添加一層新的focus層,同樣的網絡層數也要随之改變,由235-10+1 = 226層,修改後的param檔案為:

Jetson nano上使用ncnn部署yolox

後面的503是Concat層的輸出,記得要對應。修改完後重新用用ncnnoptimize對模型進行優化,順便轉為 fp16 存儲減小模型體積,還是在onnx目錄下:

前面兩個參數是優化前的模型,後面兩個是優化後的模型,我這裡直接覆寫之前的模型儲存。

Jetson nano上使用ncnn部署yolox

運作後得到新的yolox.param和yolox.bin檔案,這時候模型轉換就完成了。

四、編譯yolox.cpp

模型轉換完成之後,可以直接把yolox.cpp檔案複制到ncnn工程的examples目錄下,然後在ncnn/examples/CMakeLists.txt中做如圖修改,添加yolox工程:

Jetson nano上使用ncnn部署yolox

然後需要修改一下yolox.cpp檔案,将這幾個地方做出對應的修改:

Jetson nano上使用ncnn部署yolox

沒編譯vulkan,是以選擇false,并且将ncnn模型和權重檔案位址改為自己的絕對路徑位址,因為我的模型是在640上效果更好一些,是以尺寸改成了640,儲存後接着可以直接重新編譯一遍ncnn源碼:

cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/jetson.toolchain.cmake -DNCNN_VULKAN=ON -DCMAKE_BUILD_TYPE=Release ..
make -j4
           
Jetson nano上使用ncnn部署yolox

可以看到已經編譯成功了,這時候打開examples目錄可以看到yolox的可執行檔案,我将一張1.jpg的圖檔拷貝到該目錄中測試一下,執行:

./yolox 1.jpg
           
Jetson nano上使用ncnn部署yolox

看下實際的效果圖,和之前訓練出來的基本上一緻,到這裡就搞完了:

Jetson nano上使用ncnn部署yolox

繼續閱讀