Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pintrend导出onnx模型精度问题 #1428

Closed
aiwenzhu opened this issue Nov 12, 2024 · 6 comments
Closed

pintrend导出onnx模型精度问题 #1428

aiwenzhu opened this issue Nov 12, 2024 · 6 comments
Labels

Comments

@aiwenzhu
Copy link

训练好的pointrend模型使用官方的额export_onnx.py导出onnx发现在np.testing.assert_allclose(onnx_out, paddle_out, rtol=0, atol=1e-03)报错,代码如下,也使用了paddle2onnx来导出模型实测发现精度不一致

def export_onnx(args):
args.config = '/workspace/PaddleSeg/configs/pointrend/pointrend_resnet50_os8_voc12aug_512x512_40k.yml'
args.model_path = '/workspace/PaddleSeg/output/best_model118/model.pdparams'
args.width = 800
args.height = 640
assert args.config is not None,
'Please set --config path/to/yml'
cfg = Config(args.config)
builder = SegBuilder(cfg)
model = builder.model
if args.model_path is not None:
utils.load_entire_model(model, args.model_path)
logger.info('Loaded trained params of model successfully')

model.eval()
if args.print_model:
print(model)

input_shape = [1, 3, args.height, args.width]
print("input shape:", input_shape)
input_data = np.random.random(input_shape).astype('float32')
model_name = os.path.basename(args.config).split(".")[0]

paddle_out = run_paddle(model, input_data)
print("out shape:", paddle_out.shape)
print("The paddle model has been predicted by PaddlePaddle.\n")

input_spec = paddle.static.InputSpec(input_shape, 'float32', 'x')
onnx_model_path = os.path.join(args.save_dir, model_name + "_model")
paddle.onnx.export(
model, onnx_model_path, input_spec=[input_spec], opset_version=11)
print("Completed export onnx model.\n")

onnx_model_path = onnx_model_path + ".onnx"
onnx_out = check_and_run_onnx(onnx_model_path, input_data)
assert onnx_out.shape == paddle_out.shape
np.testing.assert_allclose(onnx_out, paddle_out, rtol=0, atol=1e-03)
print("The paddle and onnx models have the same outputs.\n")

@Jiang-Jia-Jun
Copy link
Collaborator

对于分割类模型,一般来说分存在两种输出情况(不一定同时存在)

  1. 输出结果为各个像素点的置信度
  2. 输出结果为各个像素点的分类结果
    其中第2种结果一般是对第1种结果取argmax后得到的分类index

因此,如果我们对第1种结果做assert_allclose,这个应该是没有问题的。 但如果对第2点种结做assert_allclose,可能会出现的情况是,两者在置信度上差值很小,但在极端情况会导致最终的分类结果有差异,而分类结果都是整数的,会导致assert_allclose失败。

因此,从我的经验来看,对于第2种结果不应该取assert_allclose,而是看分类正确的像素点占比是多少。一种做法就是percent = np.sum(paddle_out == onnx_out)

@aiwenzhu
Copy link
Author

对于分割类模型,一般来说分存在两种输出情况(不一定同时存在)

  1. 输出结果为各个像素点的置信度
  2. 输出结果为各个像素点的分类结果
    其中第2种结果一般是对第1种结果取argmax后得到的分类index

因此,如果我们对第1种结果做assert_allclose,这个应该是没有问题的。 但如果对第2点种结做assert_allclose,可能会出现的情况是,两者在置信度上差值很小,但在极端情况会导致最终的分类结果有差异,而分类结果都是整数的,会导致assert_allclose失败。

因此,从我的经验来看,对于第2种结果不应该取assert_allclose,而是看分类正确的像素点占比是多少。一种做法就是percent = np.sum(paddle_out == onnx_out)

你好,我后来使用deeplabv3p也训练了模型去导出onnx测试,发现也是onnx版的结果不如pytorch结果,是否与我训练的图片尺寸不一致有关,我发现使用paddle2onnx导出的模型的输入是动态的,而pytorch模型的输入是固定的,因为我配置文件中的crop_size设置了固定值?但是我如果按照官方的代码把原图pading到固定大小输入到onnx发现结果完全不对,而使用上边的def export_onnx(args):代码导出的onnx有一一直跟pytorch的推理结果有差别

@Jiang-Jia-Jun
Copy link
Collaborator

在转模型过程,一般直接对比模型的输入输出diff,确保模型的正确性。 对于效果上的影响,固定shape和动态shape,对于效果肯定是有差异的。

@aiwenzhu
Copy link
Author

在转模型过程,一般直接对比模型的输入输出diff,确保模型的正确性。 对于效果上的影响,固定shape和动态shape,对于效果肯定是有差异的。

你好,那我现在是需要用paddle2onnx导出固定shape吗,我没看到paddle2onnx里有固定shape的参数

Copy link

This issue is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Dec 14, 2024
Copy link

This issue was closed because it has been inactive for 14 days since being marked as stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants