??特別說明:參考官方開源的yolov9代碼、瑞芯微官方文檔、地平線的官方文檔,如有侵權告知刪,謝謝。
??模型和完整仿真測試代碼,放在github上參考鏈接 模型和代碼。
??之前寫過yolov8檢測、分割、關鍵點模型的部署的多篇博文,yolov8還沒玩溜,這不yolov9又來了。yolov9剛出來兩三天,有朋友就問:yolov9都出來好幾天了,怎么沒有見到你寫一篇部署博客呢。其實yolov9出來兩三天,說實話還是通過朋友告知才知道的。一直想抽時間把yolov9部署給盤一下,奈何一拖就又是好幾天,這兩天抽時間終于把這個yolov9給盤完了。
1 模型和訓練
??訓練代碼參考官方開源的yolov9訓練代碼,考慮到有些板端對SiLU的支持有限,本示例訓練前把激活函數SiLU替換成了ReLU,訓練使用的模型配置文件是yolov9.yaml,輸入分辨率640x640。用 from thop import profile 統計的模型計算量和參數 Flops: 120081612800.0(120G),Params: 55388336.0(55M)
2 導出 yolov9 onnx
??導出onnx時需要修改兩個地方。
??特別說明:只在導出onnx時修改,訓練時無需修改,修改以下代碼后運行會報錯,但是可以生成onnx文件,無需關注報錯。
?? 第一個處:增加以下代碼(紅色框內新增):
reslut = []for i in range(self.nl):reslut.append(self.cv2[i](x[i]))reslut.append(self.cv3[i](x[i]))return reslut
第二處修改:增加以下代碼(紅色框內新增)
class CBFuse(nn.Module):def __init__(self, idx):super(CBFuse, self).__init__()self.idx = idxdef forward(self, xs):target_size = xs[-1].shape[2:]if target_size[0] < 10:res = [F.interpolate(x[self.idx[i]], size=target_size, mode='nearest') for i, x in enumerate(xs[:-1])]out = torch.sum(torch.stack(res + xs[-1:]), dim=0)return outj = 0for i, x in enumerate(xs[:-1]):j = iif target_size[0] < 10:continueif i == 0:x0 = F.interpolate(x[self.idx[i]], size=target_size, mode='nearest')if i == 1:x1 = F.interpolate(x[self.idx[i]], size=target_size, mode='nearest')if i == 2:x2 = F.interpolate(x[self.idx[i]], size=target_size, mode='nearest')if j == 2 and target_size[0] > 10:out = x0 + x1 + x2 + xs[-1:][0]return outif j == 1 and target_size[0] > 10:out = x0 + x1 + xs[-1:][0]return outif j == 0 and target_size[0] > 10:out = x0 + xs[-1:][0]return outres = [F.interpolate(x[self.idx[i]], size=target_size, mode='nearest') for i, x in enumerate(xs[:-1])]out = torch.sum(torch.stack(res + xs[-1:]), dim=0)return out
最后:增加保存onnx文件代碼
print(torch.onnx.ir_version)print("=========== onnx =========== ")dummy_input0 = torch.randn(1, 3, 640, 640)input_names = ["data"]output_names = ["output1", "output2", "output3", "output4", "output5", "output6"]torch.onnx.export(model, (dummy_input0), "./test_onnx/yolov9_relu_80class.onnx", verbose=True, input_names=input_names, output_names=output_names, opset_version=12)print("======================== convert onnx Finished! .... ")
3 yolov9 測試效果
pytorhc測試效果
onnx測試效果(確保修改CBFuse后導出的onnx測試結果和pytorch是一致的)
4 tensorRT 時耗
??模型訓練使用的配置文件是yolov9.yaml,輸入分辨率是640x640,轉trt使用的fp16_mode,顯卡Tesla V100,cuda_11.0。
5 rknn 板端C++部署
??模型訓練使用的配置文件是yolov9.yaml,輸入分辨率是640x640,芯片rk3588.
??把在rk3588板子上測試的模特推理時耗,和用C++代碼寫的后處理時耗,都給貼出來供大家參考。【rk3588的C++代碼參考鏈接】。