1. Resnet50簡介
ResNet50網絡是2015年由微軟實驗室的何愷明提出,獲得ILSVRC2015圖像分類競賽第一名。在ResNet網絡提出之前,傳統的卷積神經網絡都是將一系列的卷積層和池化層堆疊得到的,但當網絡堆疊到一定深度時,就會出現退化問題。 殘差網絡的特點是容易優化,并且能夠通過增加相當的深度來提高準確率。其內部的殘差塊使用了跳躍連接,緩解了在深度神經網絡中增加深度帶來的梯度消失問題。
本教程基于圖像分類算法ResNet50的訓練和部署到EASY-EAI-Nano(RV1126)進行說明。

2. 準備數據集
2.1 數據集下載
本教程以車輛分類算法為例
解壓完成后得到以下兩個文件夾:

打開可以看到一共10類汽車:

類別名稱 | 類別索引號 |
SUV | 0 |
BUS | 1 |
family sedan | 2 |
fire engine | 3 |
heavy truck | 4 |
jeep | 5 |
mini bus | 6 |
racing car | 7 |
taxi | 8 |
truck | 9 |
3. ResNet50圖像分類訓練
3.1 訓練源碼下載
得到下圖所示目錄:

把數據集解壓到當前目錄:

3.2 訓練模型
進入anconda的pyTorch環境,切換到訓練源碼目錄執行以下指令開始訓練:
python train.py
執行結果如下圖所示:

訓練結束后test loss結果如下所示:

訓練結束后test accuracy結果如下所示:

生成的最優模型如下所示:

3.3 在PC端測試模型
在訓練源碼目錄執行以下指令,測試模型(生成模型名稱不一致則修改predict.py腳本):
python predict.py

結果類別索引號為1——BUS, 測試結果正確。
3.4 pth模型轉換為onnx模型
執行以下指令把pytorch的pth模型轉換onxx模型:
python pth_to_onnx.py

生成ONNX模型如下所示:

4. rknn-toolkit模型轉換
4.1 rknn-toolkit模型轉換環境搭建
onnx模型需要轉換為rknn模型才能在EASY-EAI-Nano運行,所以需要先搭建rknn-toolkit模型轉換工具的環境。當然tensorflow、tensroflow lite、caffe、darknet等也是通過類似的方法進行模型轉換,只是本教程onnx為例。
4.1.1 概述
模型轉換環境搭建流程如下所示:

4.1.2 下載模型轉換工具
為了保證模型轉換工具順利運行,請下載網盤里”AI算法開發/RKNN-Toolkit模型轉換工具/rknn-toolkit-v1.7.3/docker/rknn-toolkit-1.7.3-docker.tar.gz”。
4.1.3 把工具移到ubuntu18.04
把下載完成的docker鏡像移到我司的虛擬機ubuntu18.04的rknn-toolkit目錄,如下圖所示:

4.1.4 運行模型轉換工具環境
在該目錄打開終端:

執行以下指令加載模型轉換工具docker鏡像:
docker load --input /home/developer/rknn-toolkit/rknn-toolkit-1.7.3-docker.tar.gz
執行以下指令進入鏡像bash環境:
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb rknn-toolkit:1.7.3 /bin/bash
現象如下圖所示:

輸入“python”加載python相關庫,嘗試加載rknn庫,如下圖環境測試成功:

至此,模型轉換工具環境搭建完成。
4.2 模型轉換為RKNN
EASY EAI Nano支持.rknn后綴的模型的評估及運行,對于常見的tensorflow、tensroflow lite、caffe、darknet、onnx和Pytorch模型都可以通過我們提供的 toolkit 工具將其轉換至 rknn 模型,而對于其他框架訓練出來的模型,也可以先將其轉至 onnx 模型再轉換為 rknn 模型。 模型轉換操作流程入下圖所示:

4.2.1 模型轉換Demo下載
把resnet50_model_convert.tar.bz2和quant_dataset.zip解壓到虛擬機,如下圖所示:

4.2.2 進入模型轉換工具docker環境
執行以下指令把工作區域映射進docker鏡像,其中/home/developer/rknn-toolkit/model_convert_test為工作區域,/test為映射到docker鏡像,/dev/bus/usb:/dev/bus/usb為映射usb到docker鏡像:
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb -v /home/developer/rknn-toolkit/model_convert_test:/test rknn-toolkit:1.7.3 /bin/bash
執行成功如下圖所示:

4.2.3 模型轉換Demo目錄介紹
模型轉換測試Demo由resnet50_model_convert和quant_dataset組成。resnet50_model_convert存放軟件腳本,quant_dataset存放量化模型所需的數據。如下圖所示:

resnet50_model_convert文件夾存放以下內容,如下圖所示:

4.2.4 生成量化圖片列表
在docker環境切換到模型轉換工作目錄:
cd /test/resnet50_model_convert
如下圖所示:

執行gen_list.py生成量化圖片列表:
python gen_list.py
命令行現象如下圖所示:

生成“量化圖片列表”如下文件夾所示:

4.2.5 onnx模型轉換為rknn模型
rknn_convert.py腳本默認進行int8量化操作,腳本代碼清單如下所示:
import os import urllib import traceback import time import sys import numpy as np import cv2 from rknn.api import RKNN ONNX_MODEL = '10class_ResNet50.onnx' RKNN_MODEL = './10class_ResNet50.rknn' DATASET = './pic_path.txt' QUANTIZE_ON = True if __name__ == '__main__': # Create RKNN object rknn = RKNN(verbose=True) if not os.path.exists(ONNX_MODEL): print('model not exist') exit(-1) # pre-process config print('--> Config model') rknn.config(reorder_channel='0 1 2', mean_values=[[123.67, 116.28,103.53]], std_values=[[58.395, 57.12, 57.375]], optimization_level=3, target_platform = 'rv1126', output_optimize=1, quantize_input_node=QUANTIZE_ON) print('done') # Load ONNX model print('--> Loading model') ret = rknn.load_onnx(model=ONNX_MODEL) if ret != 0: print('Load failed!') exit(ret) print('done') # Build model print('--> Building model') ret = rknn.build(do_quantization=QUANTIZE_ON, dataset=DATASET) if ret != 0: print('Build resnet failed!') exit(ret) print('done') # Export RKNN model print('--> Export RKNN model') ret = rknn.export_rknn(RKNN_MODEL) if ret != 0: print('Export resnet failed!') exit(ret) print('done')
把onnx模型10class_ResNet50.onnx放到resnet50_model_convert目錄,并執行rknn_convert.py腳本進行模型轉換:
python rknn_convert.py
生成模型如下圖所示,此模型可以在rknn-toolkit環境和EASY EAI Nano環境運行:

4.2.6 運行rknn模型
用predict.py腳本在PC端的環境下可以運行rknn的模型,如下圖所示:

predict.py腳本程序清單如下所示:
import os import urllib import traceback import time import sys import numpy as np import cv2 import random from rknn.api import RKNN RKNN_MODEL = '10class_ResNet50.rknn' IMG_PATH = './test-1.jpg' BOX_THRESH = 0.25 NMS_THRESH = 0.6 CLASSES = ("SUV", "bus", "family sedan", "fire engine", "heavy truck", "jeep", "minibus", "racing car", "taxi", "truck") def show_outputs(output): print("softmax output:", output) max_confidence = np.max(output) index = np.where(output == max_confidence) print("max confidence:", max_confidence) print("max confidence index:", index[0][0]) print("CLASSES predict: ", CLASSES[index[0][0]]) def softmax(x): return np.exp(x)/sum(np.exp(x)) if __name__ == '__main__': # Create RKNN object rknn = RKNN(verbose=True) print('--> Loading model') ret = rknn.load_rknn(RKNN_MODEL) if ret != 0: print('load rknn model failed') exit(ret) print('done') # init runtime environment print('--> Init runtime environment') ret = rknn.init_runtime() # ret = rknn.init_runtime('rv1126', device_id='1126') if ret != 0: print('Init runtime environment failed') exit(ret) print('done') # Set inputs img = cv2.imread(IMG_PATH) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) resize_img = cv2.resize(img,(224,224)) # Inference print('--> Running model') outputs = rknn.inference(inputs=[resize_img]) print("outputs[0]:", outputs[0]) print("outputs[0].shape:", outputs[0].shape) show_outputs(softmax(np.array(outputs[0][0]))) print('done') rknn.release()
執行結果如下圖所示:

4.2.7 模型預編譯
由于rknn模型用NPU API在EASY EAI Nano加載的時候啟動速度會很慢,在評估完模型精度沒問題的情況下,建議進行模型預編譯。預編譯的時候需要通過EASY EAI Nano主板的環境,所以請務必接上adb口與ubuntu保證穩定連接。
板子端接線如下圖所示,撥碼開關需要是adb:

虛擬機要保證接上adb設備:

由于在虛擬機里ubuntu環境與docker環境對adb設備資源是競爭關系,所以需要關掉ubuntu環境下的adb服務,且在docker里面通過apt-get安裝adb軟件包。以下指令在ubuntu環境與docker環境里各自執行:

在docker環境里執行adb devices,現象如下圖所示則設備連接成功:

運行precompile_rknn.py腳本把模型執行預編譯:
python precompile_rknn.py
執行效果如下圖所示,生成預編譯模型10class_ResNet50_pre.rknn:

至此預編譯部署完成,模型轉換步驟已全部完成。生成如下預編譯后的int8量化模型:

至此RKNN模型生成完畢,注意預編譯模型只能在板卡端執行。
5. ResNet50圖像分類部署
5.1 模型部署示例介紹
本小節展示ResNet50模型的在EASY EAI Nano的部署過程,該模型僅經過簡單訓練供示例使用,不保證模型精度。
5.2 開發環境準備
如果您初次閱讀此文檔,請閱讀《入門指南/開發環境準備/Easy-Eai編譯環境準備與更新》,并按照其相關的操作,進行編譯環境的部署。
在PC端Ubuntu系統中執行run腳本,進入EASY-EAI編譯環境,具體如下所示。
cd ~/develop_environment ./run.sh

5.3 源碼下載以及例程編譯
下載ResNet50 C Demo示例文件。
下載程序包移至ubuntu環境后,執行以下指令解壓:
tar -xvf resnet50_classification_C_demo.tar.bz2
下載解壓后如下圖所示:

在EASY-EAI編譯環境下,切換到例程目錄執行編譯操作:
cd /opt/rknn-toolkit/resnet50_classification_C_demo/ ./build.sh
注:
* 由于依賴庫部署在板卡上,因此交叉編譯過程中必須保持adb連接。

5.4 在開發板執行ResNet50 圖像分類算法
在EASY-EAI編譯環境下,在例程目錄執行以下指令把可執行程序推送到開發板端:
cp resnet_classification_demo_release/ /mnt/userdata/ -rf
通過按鍵Ctrl+Shift+T創建一個新窗口,執行adb shell命令,進入板卡運行環境:
adb shell

進入板卡后,定位到例程上傳的位置,如下所示:
cd /userdata/resnet_classification_demo_release/
運行例程命令如下所示:
./resnet_classification_demo
執行結果如下圖所示,算法執行時間約為35ms:

至此,ResNet50圖像分類例程已成功在板卡運行。
-
開發板
+關注
關注
25文章
5513瀏覽量
102260 -
resnet
+關注
關注
0文章
13瀏覽量
3289 -
rv1126
+關注
關注
0文章
106瀏覽量
3348
發布評論請先 登錄
Qt程序部署到瑞星微RV1126開發板上,使用QCursor::pos()獲取鼠標為零是為什么?
【R329開發板評測】實機測試Resnet50

RV1126-AI開發手記(一)Resnet50性能評估

基于RV1126開發板網絡配置方法

基于RV1126開發板實現人臉檢測方案

基于RV1126開發板實現自學習圖像分類方案

基于RV1126開發板實現人臉檢測方案

基于RV1126開發板實現人臉檢測方案

評論