魔站建站系统哪家好,安徽省交通运输厅领导,国际数据公司idc,学校建设网站前的市场分析YOLO V5训练模型部署到瑞芯微的板子上面#xff0c;官方是有给出案例和转过详情的。并且也提供了Python版本的推理代码#xff0c;以及C语言的代码。
但是#xff0c;对于转换过程中的细节#xff0c;哪些需要改#xff1f;怎么改#xff1f;如何改#xff0c;和为什么…YOLO V5训练模型部署到瑞芯微的板子上面官方是有给出案例和转过详情的。并且也提供了Python版本的推理代码以及C语言的代码。
但是对于转换过程中的细节哪些需要改怎么改如何改和为什么这样改的问题并没有给出详细的介绍。于是本文就是对官方给出部分外的一个补充。这部分都是踩过坑的总结相信会对你的操作会有较大帮助的。
一、从pytorch的pt到rknn转换
第一步 使用yolov5提供的export.py函数导出yolov5.onnx模型
python3 export.py --weights yolov5s.pt --img-size 640 --include onnx第二步使用onnxsim简化导出的yolov5.onnx模型 onnxsim是一个基于ONNX规范的工具通过简化ONNX模型和优化ONNX模型帮助用户减小模型大小、提高模型的推理速度和减少推理过程中的内存开销。 onnxsim的工作原理是将一个ONNX模型简化成最少的节点并优化这些节点以最小化推理过程中的开销。 同时onnxsim还可以处理支持的神经网络层类型支持多个平台例如CPU,GPU, FPGA等。 onnxsim安装和使用onnx-simplifier
pip3 install onnxsimThen:onnxsim input_onnx_model output_onnx_model第三步要完全使用rknn提供的部署转换代码需要根据简化后的onnx模型选取合适层的输出以替代以下代码中的‘378’‘439’和‘500’如下图onnx例子中的onnx::Reshape_446‘onnx::Reshape_484’‘onnx::Reshape_522’。这三个name可能都是不一样的是什么就填什么即可
# Load ONNX model
print(-- Loading model)
ret rknn.load_onnx(modelONNX_MODEL, outputs[onnx::Reshape_446, onnx::Reshape_484, onnx::Reshape_522])
if ret ! 0:print(Load yolov5 failed!)exit(ret)
print(done)采用Netron打开的onnx文件如下
疑问为什么不用最后合并后的输出结果
因为最后的形状不固定导致的有可能5个框有可能10个框。输出模型到固定大小后续操作放到后处理目的是为了加快模型的npu上的推理速度(这里是我的理解不一定正确欢迎补充) 在PyTorch中神经网络的输出形状通常是根据输入形状来自动计算的而在 ONNX 中输出形状需要在转换时进行显式指定这是由于 ONNX 的静态图执行模型与 PyTorch 的动态图执行模型不同所致。 当你将PyTorch模型转换为 ONNX 模型时你需要为 ONNX 模型中的每个输出定义固定的形状以便在模型执行时为其分配正确的内存空间。如果输出形状不固定那么 ONNX 运行时就需要在运行时动态调整输出形状这将使得模型在部署时的性能受到影响。 因此在转换 PyTorch 模型为 ONNX 模型时你需要手动指定每个输出的固定形状以便在执行时能够顺利运行。 Yolo v5的输出格式一般为a × b × c × 85的形式其中:
a*b*c表示框的数目85则涵盖框的位置信息xcycwh、前景的置信度Pc和80个类别的预测条件概率c1...c80。4180无背景类
如果是你自己的模型可能是只有3个目标类别那么最后就是4138这个值记得在onnx模型中查看到。
二、需要注意事项
2.1、 设定anchor值
anchor的设定在训练yolo v5模型时候是可以设定自动适应采用聚类的方式通过标注的目标框的大小给出anchor的值。在train.py中noaotoanchor的默认为False如果设定为True则会使用默认的anchor设定。
所以如果经过autoanchor给出了新的anchor设定那么在推理和转完rknn后的设定都需要与之相匹配的anchor这个很重要。
为什么官方和很多博客都没有注意到这个问题呢因为大多数情况下aotoanchor并没有发挥作用。都是使用了默认的导致很多人即便没有注意到这个问题最后的结果也不差。
但是如果是不一样的结果就会比较差这个值就需要对应的做修改了。
2.1.1、训练阶段记录
如果在训练阶段你已经关注到autoAnchor的输出结果可以在这里直接进行记录在terminal打印的内容大致如下
AutoAnchor: 3.60 anchors/target, 0.974 Best Possible Recall (BPR). Anchors are a poor fit to dataset ⚠, attempting to improve...
AutoAnchor: WARNING ⚠ Extremely small objects found: 764 of 27545 labels are 3 pixels in size
AutoAnchor: Running kmeans for 9 anchors on 27522 points...
AutoAnchor: Evolving anchors with Genetic Algorithm: fitness 0.8052: 100%|██████████| 1000/1000 00:10
AutoAnchor: thr0.25: 0.9996 best possible recall, 5.11 anchors past thr
AutoAnchor: n9, img_size640, metric_all0.358/0.805-mean/best, past_thr0.532-mean: 5,5, 7,8, 11,11, 17,17, 28,28, 41,37, 56,56, 79,82, 143,1402.1.2、pt文件查询记录
查询autoAnchor记录到.pt文件内的anchor设定如下
import torch
import sys
sys.path.append(path/yolov5-master)
weights best.pt
model torch.load(str(weights[0] if isinstance(weights, list) else weights), map_locationcpu)
model1 model[ema if model.get(ema) else model]
model2 model1.float().fuse().model.state_dict()for k,v in model2.items():if anchor in k:# print(k)# print(v)print(v.numpy().flatten().tolist())打印结果
Fusing layers...
[0.54345703125, 0.58251953125, 0.8525390625, 0.88818359375, 1.353515625, 1.318359375, 1.0859375, 1.0380859375, 1.75390625, 1.705078125, 2.38671875, 2.462890625, 1.7421875, 1.6787109375, 2.578125, 2.458984375, 3.904296875, 3.75]
[4.34765625, 4.66015625, 6.8203125, 7.10546875, 10.828125, 10.546875, 17.375, 16.609375, 28.0625, 27.28125, 38.1875, 39.40625, 55.75, 53.71875, 82.5, 78.6875, 124.9375, 120.0]
YOLOv5m summary: 308 layers, 21037791 parameters, 0 gradients第二行是真的需要取整。第一行…
经过我的发现如果你打印的anchor就一行那么可能是默认的anchor默认使用COCO数据集的anchor就是good fit to dataset也就是默认的
[[10, 13], [16, 30], [33, 23],
[30, 61], [62, 45],[59, 119],
[116, 90], [156, 198], [373, 326]]2.2、rk3588推理性能
yolo v5m 量化前性能
推理性能Performance
Total Time(us): 194162
FPS: 5.15占用内存Memory Profile Info Dump NPU model memory detail(bytes):Total Weight Memory: 39.83 MiBTotal Internal Tensor Memory: 19.50 MiBTotal Memory: 59.33 MiB量化后性能
推理性能Performance
Total Time(us): 137508
FPS: 7.27占用内存Memory Profile Info Dump
NPU model memory detail(bytes):Total Weight Memory: 20.03 MiBTotal Internal Tensor Memory: 8.75 MiBTotal Memory: 28.78 MiB总的来说
模型时间效率上量化后能降低30%194ms到137ms占用内存上量化后减少50%59Mib到29Mib
三、C/C API部署 目标检测 YOLOv5 - 基于 瑞芯微 Rockchip RKNN C API 实现 ----------- github代码 yolov8 瑞芯微 RKNN 的 C部署------------- github代码
上述两个参考链接基本囊括了一下几个部分
rknn模型转换Python rknn推理c/c rknn推理 YOLO v5部分是瑞芯微官方开放的代码
如果你也是参考瑞芯微官方的C API代码那么替换上你的模型后有几个地方需要修改
输入图像大小要改anchor尺寸要改 const int anchor0[6] {4, 5, 7, 7, 11, 11}; const int anchor1[6] {17, 17, 28, 27, 38, 39}; const int anchor2[6] {56, 54, 83, 79, 125, 120};前景box阈值修改 const float box_conf_threswin 0.25;nms阈值修改 const float nms_threswin 0.1;类别置信度重新调整 objProbs.push_back(current_prob*box_confidence);针对各个类采用不同的阈值待补充这部分瑞芯微未采用这种二次过滤方式
尤其是anchor这里如果设定的不对那么输出的结果就会非常的奇怪。如果是对的那么差异性相对会小很多(和本地pt测试结果对比)。
四、总结
本文是对YOLO V5模型部署到瑞芯微板子上遇到的问题汇总。当然可能还会存在其他的更多问题但是暂时还没有遇到所以后面如果还会遇到什么问题还会补充到这里。
如果你也正在做这块并且遇到了问题可以评论交流。目前还发现就是转模型后的评估问题这个后面也会按照官方教程进行测试这是下一篇的预告期待。