因工作需要,需要將目標(biāo)檢測(cè)模型 部署在開發(fā)板上。在走了很多彎路后 找到一個(gè)成功的案例并記載下來
這里說一下我現(xiàn)有的硬件設(shè)備 。
我是購買的RADXA的rock3a開發(fā)板 搭載的soc是rk3568
這是開發(fā)板的正面圖,因?yàn)槿鹦疚⑨槍?duì)計(jì)算機(jī)視覺中的目標(biāo)檢測(cè)模型有一套自己的前向推理框架,所以我就著眼于搭載rockchip的開發(fā)板rock3a
目標(biāo)檢測(cè)模型 這里采用的是yolo模型? 由于原生yolov5模型里面有一些?算子 可能在模型轉(zhuǎn)換時(shí)不支持,這里采用瑞芯微官方推薦的yolov5,鏈接在下面:
GitHub - airockchip/yolov5: YOLOv5 in PyTorch > ONNX > CoreML > TFLite
下載好源代碼后,需要修改一個(gè)地方:
修改的代碼我這里貼出來
def forward(self, x):
z = [] # inference output
for i in range(self.nl):
if os.getenv('RKNN_model_hack', '0') != '0':
z.append(torch.sigmoid(self.m[i](x[i])))
continue
x[i] = self.m[i](x[i]) # conv
'''
bs, _, ny, nx = x[i].shape # x(bs,255,20,20) to x(bs,3,20,20,85)
x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
if not self.training: # inference
if self.onnx_dynamic or self.grid[i].shape[2:4] != x[i].shape[2:4]:
self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i)
y = x[i].sigmoid()
if self.inplace:
y[..., 0:2] = (y[..., 0:2] * 2 + self.grid[i]) * self.stride[i] # xy
y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh
else: # for YOLOv5 on AWS Inferentia https://github.com/ultralytics/yolov5/pull/2953
xy, wh, conf = y.split((2, 2, self.nc + 1), 4) # y.tensor_split((2, 4, 5), 4) # torch 1.8.0
xy = (xy * 2 + self.grid[i]) * self.stride[i] # xy
wh = (wh * 2) ** 2 * self.anchor_grid[i] # wh
y = torch.cat((xy, wh, conf), 4)
z.append(y.view(bs, -1, self.no))
if os.getenv('RKNN_model_hack', '0') != '0':
return z
return x if self.training else (torch.cat(z, 1),) if self.export else (torch.cat(z, 1), x)
'''
return x[0],x[1],x[2]
?然后 根據(jù)自己的數(shù)據(jù)集 訓(xùn)練一版模型 ,訓(xùn)練過程這里不贅述。
這里將訓(xùn)練好的模型yolov5s.pt 轉(zhuǎn)化為onnx模型
轉(zhuǎn)化命令為 :
python3 ? export.py --weights yolov5s.pt --img 640 --batch 1 --opset 12 --include onnx
轉(zhuǎn)化完后 需要用Netron軟件打開模型的可視化界面
記下 圖中 的三個(gè)框里面的節(jié)點(diǎn)名稱,這三個(gè)節(jié)點(diǎn)是網(wǎng)絡(luò)的輸出節(jié)點(diǎn)
?新建一個(gè) python文件?onnx2rknn.py? 該文件是仿制test.py文件編寫的
文件內(nèi)容為
from rknn.api import RKNN
ONNX_MODEL = 'yolov5s.onnx'
platform = "rk3568"
RKNN_MODEL = 'yolov5s_{}_out_opt.rknn'.format(platform)
if __name__ == '__main__':
add_perm = False # 如果設(shè)置成True,則將模型輸入layout修改成NHWC
# Create RKNN object
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform=platform,
)
print('done')
# Load tensorflow model
print('--> Loading model')
ret = rknn.load_onnx(model=ONNX_MODEL,outputs=['output', '327', '328'])# 這里一定要根據(jù)onnx模型修改
if ret != 0:
print('Load onnx model failed!')
exit(ret)
print('done')
# Build model
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build rkmodel failed!')
exit(ret)
print('done')
# rknn.export_rknn_precompile_model(RKNN_MODEL)
rknn.export_rknn(RKNN_MODEL)
rknn.release()
并將該文件放置于rknn-toolkit工作目錄下
我的目錄是/home/rock/workspace/rknn-toolkit2-1.4.0/examples/onnx/yolov5
也就是example目錄下的onnx專欄的yolov5子目錄?
?注意 需要在onnx2rknn.py文件中 注明 模型運(yùn)行的目標(biāo)平臺(tái) 我的目標(biāo)平臺(tái)是rk3568?
另外需要將上一步 netron 查看的輸出部分的三個(gè)節(jié)點(diǎn) 在onnx2rknn.py文件中注明
也就是如下截圖所示
?python3 onnx2rknn.py 運(yùn)行該文件后 生成的rknn模型?
將該模型 傳輸?shù)介_發(fā)板上
注意,這里有一個(gè)容易忽略的地方 我的rknn-toolkit的版本是1.4.0
如果我的開發(fā)板librknnrt.so 動(dòng)態(tài)庫的版本是1.3.0 就會(huì)報(bào)錯(cuò) 這里版本一定要對(duì)應(yīng)上
在開發(fā)板上運(yùn)行模型 進(jìn)行單張圖片的目標(biāo)檢測(cè) ,運(yùn)行結(jié)果如下圖所示
文章來源:http://www.zghlxwxcb.cn/news/detail-510624.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-510624.html
到了這里,關(guān)于采用rknn-toolkit導(dǎo)出rknn模型并部署在rock3a-rk3568芯片 上全流程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!