weixin_39575775
2020-12-02 17:34 阅读 33

onnx转paddle,Upsample动态shape

模型转换Pytorch->onnx->paddle。 1. Pytorch代码中对应部分代码:


def forward(self, x):
    n,c,h,w = x.shape
    up = nn.functional.interpolate(rb2, size=((h+1)//2, (w+1)//2), mode='bilinear', align_corners=False) 
    return up
  1. 转onnx时候,Upsample对应层是: %827 : Float(1, 576, 4, 35) = onnx::Upsamplemode="linear",其中%826是计算动态shape

  2. 使用develop分支的X2Paddle转,在model = ONNXDecoder(model_path)这步里有一个model = onnx.shape_inference.infer_shapes(model),onnx貌似不支持动态的shape推断,打印出来Upsample的四个dim都是空

  3. 由于3中所述,在onnx转paddle的时,Upsample转成paddle的out_shape=[0,0],转出来的model.py对应层是_827 = fluid.layers.resize_bilinear(_808, scale=None, out_shape=[0, 0], name='_827'),这里手动把2中的mode=“linear”改成了paddle支持的“bilinear”。

我看到paddle的文档中写了“根据指定的out_shape执行双线性插值调整输入大小,输出形状按优先级由actual_shape、out_shape和scale指定。”其中acutal_shape是动态图时用到的。 我现在想法是在ONNXOpMapper这里改,Upsample层对应的是_interpolate函数,但不清楚用actual_shape参数要怎么改,或者有更方便的改法嘛~ 其中_interpolate函数里层的现在是提供scale和out_shape的参数,如下:


        attr = {
            'scale': scale,
            'out_shape': out_shape,
            'name': string(node.layer_name)
        }
        node.fluid_code.add_layer(fluid_op,
                                  inputs=val_x,
                                  output=node,
                                  param_attr=attr)

该提问来源于开源项目:PaddlePaddle/X2Paddle

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

15条回答 默认 最新

  • weixin_39772420 weixin_39772420 2020-12-02 17:34

    方便提供一下onnx的模型吗?

    点赞 评论 复制链接分享
  • weixin_39575775 weixin_39575775 2020-12-02 17:34

    抱歉,刚刚在修改问题描述~

    点赞 评论 复制链接分享
  • weixin_39772420 weixin_39772420 2020-12-02 17:34

    抱歉,刚刚在修改问题描述~

    方便提供一下onnx的模型,我们需要分析一下。

    点赞 评论 复制链接分享
  • weixin_39575775 weixin_39575775 2020-12-02 17:34

    好的,层可能和描述有点变化 链接:https://pan.baidu.com/s/1_l_MpZGoBXOzpNX5B7xoMw 提取码:dnxh

    点赞 评论 复制链接分享
  • weixin_39772420 weixin_39772420 2020-12-02 17:34

    我在本地做了测试,支持了动态的scale和out_shape后,但是无法支持线性插值,paddle现在只支持双线性插值

    点赞 评论 复制链接分享
  • weixin_39575775 weixin_39575775 2020-12-02 17:34

    pytorch也是bilinear,不过转成onnx显示是linear而已,这部分我已经手动改了。可以说一下怎么转动态的interpolate嘛

    点赞 评论 复制链接分享
  • weixin_39772420 weixin_39772420 2020-12-02 17:34

    新的代码已经上传,你可以试试

    点赞 评论 复制链接分享
  • weixin_39575775 weixin_39575775 2020-12-02 17:34

    非常感谢,我现在用昨天更新后的X2Paddle可以直接转成功。但是也inference的时候也遇到一个问题,我看到在Upsample前的MaxPool层转的时候会多一个reshape层,同时提供了一个固定参数的shape,由于我的是不定长输入,所以inference的时候会报错~这个在我上周clone的X2Paddle版本中没有出现

    点赞 评论 复制链接分享
  • weixin_39772420 weixin_39772420 2020-12-02 17:34

    你换了新的不定长输入的model吗?我这边测试之前你上传的model:https://pan.baidu.com/s/1_l_MpZGoBXOzpNX5B7xoMw, 是能够inference的。

    点赞 评论 复制链接分享
  • weixin_39575775 weixin_39575775 2020-12-02 17:34

    我原来的模型也是可以不定长的,只是onnx在trace的时候需要一个任意输入,所以会保留形状。如果是和trace时相同长度的输入应该是可以执行的~

    点赞 评论 复制链接分享
  • weixin_39772420 weixin_39772420 2020-12-02 17:34

    你能把报错信息贴出来,同时把新的model分享出来吗?另外,原来的model你转换过吗?

    点赞 评论 复制链接分享
  • weixin_39575775 weixin_39575775 2020-12-02 17:34

    所谓的新旧模型是一样的。但是新的X2Paddle在转MaxPool后多了一个reshape层,reshape层固定了shape的大小,所以不能接受不定长度的图片~

    点赞 评论 复制链接分享
  • weixin_39772420 weixin_39772420 2020-12-02 17:34

    不仅仅是reshape,由于paddle目前存在一些op不支持动态的shape输入,同时在转换某些op的过程中还要利用shape信息,所以大部分情况下,onnx2paddle转换后的model不支持不定长的输入。另外我尝试用onnxruntime推理你的onnx model的时候,也无法支持不定长的输入。

    点赞 评论 复制链接分享
  • weixin_39575775 weixin_39575775 2020-12-02 17:34

    好的非常感谢~应该把reshape去掉就可以使用不定长输入了。在使用你的版本前,我尝试手动设置scale=2做双线性插值,同时保证输入图片宽度能够被16整除(这样降采样再上采样后能相等,即width//16*16 = width),是可以在paddle下跑不定长输入的,且结果正常。

    点赞 评论 复制链接分享
  • weixin_39726697 weixin_39726697 2020-12-02 17:34

    你这个问题是怎么解决的呢? 我也遇到差不多的问题了, 请说下解决方案吧, 谢谢

    点赞 评论 复制链接分享

相关推荐