PyTorch训练的ResNet18转ONNX后用OpenCV推理仅输出固定标签如何排查
问题排查与修复方案
1. 图像预处理顺序错误(核心问题)
你当前的albumentations变换顺序完全颠倒,ToFloat操作必须放在Normalize之前:
# 错误顺序 albumentations.Normalize(mean=(0.5), std=(0.2)), albumentations.ToFloat(max_value=255)
ToFloat的作用是将0255范围的uint8图像缩放为01范围的浮点数,而你的Normalize参数mean=0.5、std=0.2是针对01范围的数值设计的。如果先做Normalize,会直接对0255的原始值做归一化,得到完全错误的数值分布,最终导致模型推理结果异常。
修改后的变换顺序应为:
self.transform = albumentations.Compose([ albumentations.Resize(512, 384, cv2.INTER_LINEAR), albumentations.GaussianBlur(3, sigma_limit=(0.1, 2)), albumentations.ToFloat(max_value=255), albumentations.Normalize(mean=(0.5, 0.5, 0.5), std=(0.2, 0.2, 0.2)) ])
这里同时把单值的mean、std改为三通道格式,避免广播歧义。
2. blobFromImage参数缺失
调用cv2.dnn.blobFromImage时建议显式指定输入尺寸,避免因图像尺寸不匹配导致的推理错误,同时确认输入张量维度和导出ONNX时的输入维度一致:
blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size=(384, 512), swapRB=False, crop=False)
注意blobFromImage的size参数格式是(width, height),和你导出时的输入尺寸[1,3,512,384]对应,这里要传(384,512)。
3. ONNX导出配置优化
你当前使用的opset_version=10版本较低,旧版本算子可能存在OpenCV兼容问题,建议升级到opset16及以上:
torch.onnx.export(model, x, "model.onnx", export_params=True, opset_version=16, do_constant_folding=True, input_names = ['input'], output_names = ['output'])
导出后可以先通过onnxruntime验证ONNX模型的输出和PyTorch原生输出是否一致,排除导出环节的问题。
4. 依赖版本检查
如果以上修改后仍有问题,建议升级OpenCV到4.5.0以上版本,旧版本OpenCV的DNN模块对ONNX格式的支持存在较多已知bug。
内容的提问来源于stack exchange,提问作者이준혁
相关产品推荐
相关产品推荐

