PyTorch导出EfficientNetV2为ONNX后精度下降约10%问题求助
PyTorch 导出 EfficientNetV2 为 ONNX 后精度下降10%排查指南
按问题出现概率从高到低排查:
- 第一优先级:核对预处理逻辑一致性(90%的大幅掉点都是这个原因)
不要先怀疑模型转换本身,先逐行对齐PyTorch推理和ONNX推理的预处理代码:- 确认通道顺序:OpenCV默认读入是BGR格式,PyTorch训练时用的是RGB格式,通道顺序错了直接掉10%以上精度非常普遍。
- 确认归一化参数:timm库训练EfficientNetV2默认用的归一化参数是
mean=[0.485, 0.456, 0.406]、std=[0.229, 0.224, 0.225],要确认ONNX侧推理时用的参数完全一致,不要漏做归一化直接喂0-255范围的像素值,也不要错用其他模型的归一化参数。 - 确认resize、裁剪逻辑:训练和PyTorch推理时用的缩放插值方式、中心裁剪尺寸,要和ONNX侧完全对齐,插值算法选不对也会带来数个百分点的精度损失。
快速验证方法:把同一张图做完预处理后的张量存下来,分别喂给PyTorch模型和ONNX模型,对比输出结果,如果输出差值在1e-3量级,说明模型转换本身没问题,问题100%出在预处理环节。
- 第二优先级:核对模型导出配置
- 补全opset版本参数:当前导出代码没有指定
opset_version,PyTorch默认用的低版本opset对EfficientNetV2用到的SiLU激活、全局平均池化等算子支持有缺陷,建议指定opset_version=13及以上(推荐17,适配主流TensorRT版本)。 - 移除多余结构、对齐训练/推理结构:导出时在base_model外套了一层Softmax,先确认PyTorch侧测精度时是否也加了完全一致的Softmax层,建议先导出不带Softmax的纯logits输出模型,对齐精度后再按需添加Softmax,避免不同框架Softmax数值实现差异带来的偏差。另外如果用
exportable=True重训了模型,记得导出时调用create_model也要传入exportable=True参数,不是只在训练阶段加。 - 修正dummy_input配置:不要给dummy_input设置
requires_grad=True,推理模型不需要梯度计算,这个参数会导致导出的计算图冗余梯度相关算子,带来数值偏差。 - 补充导出必要参数:导出时加上
input_names=["input"]、output_names=["output"],如果需要动态batch就加上对应的dynamic_axes配置,避免静态shape适配带来的问题。
- 补全opset版本参数:当前导出代码没有指定
- 第三优先级:核对模型运行模式与算子兼容性
- 确认所有层都处于eval模式:代码里调用了
model.eval(),但要确认timm模型里自定义的DropPath等随机层真的被关闭,部分旧版本timm的DropPath在eval模式下不会自动失效,会随机丢弃路径导致输出波动。 - 导出后做模型简化:用onnxsim工具对导出的ONNX模型做常量折叠、冗余算子消除,再和PyTorch输出做余弦相似度对比,正常对齐的模型余弦相似度应该在0.9999以上。
- 核对推理精度配置:如果ONNX推理时开了FP16,先切回FP32测精度,如果FP32下精度对齐、FP16下掉点,说明是部分算子(比如首层卷积、Softmax)在FP16下数值溢出,后续转TensorRT时需要给这些算子单独保留FP32精度。
- 确认所有层都处于eval模式:代码里调用了
快速定位技巧:抽10张测试集图片,分别打印PyTorch和ONNX侧的预测类别、置信度,如果所有图片预测类别全错、置信度普遍偏低,直接回头查预处理;如果只有部分图片预测错误、置信度和PyTorch侧差距很小,再排查算子转换和精度配置问题。
内容的提问来源于stack exchange,提问作者LuisGF93
相关产品推荐
相关产品推荐

