使用官方Model Zoo包中的yolov5示例中的模型.bin文件推理后,和电脑端跑的结果差很多

我来帮你分析这个问题。先搜索一下社区是否有类似的精度差异讨论。

根据你提供的测试结果和代码,我来直接回答你的两个问题:

结论

1. Model Zoo 提供的.bin 文件不是精度最优版本?

  • 不是。Model Zoo 提供的模型是经过标准 PTQ 流程转换的通用版本,精度损失在可接受范围内。

2. 板卡精度下降是否正常?

  • 不正常。你的测试结果中:
    • 板卡端 mAP@0.5: 0.5430
    • 电脑端 mAP@0.5: 0.7079
    • 精度损失达 23%,远超正常的 1-3% 范围

问题排查

根据社区官方文档《模型精度验证及调优建议》,你需要按以下步骤排查:

第一步:验证 quantized.onnx 与.bin 的一致性

使用 hb_verifier 工具验证模型转换是否正确:

hb_verifier -m quantized.onnx,yolov5m_tag_v2.0_detect_640x640_bayese_nv12.bin -b <板卡 IP> -s True

预期结果:应显示 Quanti onnx and Arm result Strict check PASSED

如果一致性验证失败,说明模型转换或编译有问题,需要重新转换。

第二步:检查前后处理代码

你的代码中有几个关键问题

问题 1:Score 计算方式错误

你的代码中:

s_max_scores = 1 / ((1 + np.exp(-s_pred[:, 4]))*(1 + np.exp(-s_raw_max_scores)))

这个计算公式不正确。YOLOv5 的正确 score 计算应该是:

objectness = sigmoid(s_pred[:, 4])  # 目标置信度
class_scores = sigmoid(s_pred[:, 5:])  # 类别概率
s_max_scores = objectness * np.max(class_scores, axis=1)  # 最终得分

问题 2:Anchor 解码公式可能不匹配

你使用的解码公式:

s_dxyhw = 1 / (1 + np.exp(-s_pred[s_valid_indices, :4]))
s_xy = (s_dxyhw[:, 0:2] * 2.0 + self.s_grid[s_valid_indices,:] - 1.0) * self.strides[0]
s_wh = (s_dxyhw[:, 2:4] * 2.0) ** 2 * self.s_anchors[s_valid_indices, :]

这是 YOLOv5 v6.0+ 的解码方式,但 Model Zoo 的 yolov5s-v2.0 应该使用 v2.0 的解码方式:

# YOLOv5 v2.0 标准解码
s_xy = (sigmoid(s_pred[:, :2]) + self.s_grid) * self.strides[0]
s_wh = (np.exp(s_pred[:, 2:4]) * self.s_anchors) * self.strides[0]

问题 3:输入数据预处理

确认你的 NV12 转换是否正确。建议使用官方推荐的方式:

# 使用 hobot_dnn 的预处理
input_tensor = cv2.resize(orig_img, (self.input_w, self.input_h))
# 不需要手动转 NV12,hobot_dnn 会自动处理

建议的排查流程

1. 先用官方示例代码测试

下载官方 Model Zoo 示例代码,直接用提供的测试脚本跑一下:

cd ~/model_zoo/yolov5
python3 test.py --model bin/yolov5s-v2.0.bin --data dataset/coco128

如果官方代码结果正常,说明是你的后处理代码有问题。

2. 使用 hb_verifier 验证

# 验证一致性
hb_verifier -m quantized.onnx,yolov5s-v2.0.bin -b <板卡 IP> -s True

# 如果失败,查看详细信息
hb_verifier -m quantized.onnx,yolov5s-v2.0.bin -b <板卡 IP> -r True

3. 对比 quantized.onnx 和.bin 的输出

在电脑端用 HB_ONNXRuntime 跑 quantized.onnx:

from horizon_tc_ui import HB_ONNXRuntime

sess = HB_ONNXRuntime(model_file="quantized.onnx")
input_names = [input.name for input in sess.get_inputs()]
output_names = [output.name for output in sess.get_outputs()]

# 准备输入(注意 input_offset=128)
feed_dict = {input_names[0]: input_data}
outputs = sess.run(output_names, feed_dict, input_offset=128)

对比 quantized.onnx 和.bin 的原始输出(后处理之前),如果差异大,说明模型转换有问题。


快速修复建议

最可能的原因是后处理代码与模型版本不匹配。建议:

  1. 直接使用官方后处理代码:从 Model Zoo 示例中复制后处理部分
  2. 或者重新训练/转换模型:使用你自己的数据集和配置重新转换,确保前后处理一致

如果需要进一步帮助,请提供:

  • hb_verifier 的验证结果
  • 你使用的具体模型文件(yolov5s 还是 yolov5m?)
  • 转换时使用的 yaml 配置文件

相关社区资源