各主流深度学习框架转换onnx

Paddle2onnx

模型转换

动态图ONNX模型导出和静态图ONNX模型导出;

动态图

大致的原理就是动转静,然后再将静态图模型转换为ONNX模型,所以转换的代码上与动转静很相似;

import os
import time 
import paddle

# 从模型代码中导入模型
from u2net import U2NETP

# 实例化模型
model = U2NETP()

# 加载预训练模型参数
model.set_dict(paddle.load([path to the pretrained model]))

# 将模型设置为评估状态
model.eval()

# 定义输入数据
input_spec = paddle.static.InputSpec(shape=[None, 3, 320, 320], dtype='float32', name='image')

# ONNX模型导出 (paddle version > 2.0.0)
paddle.onnx.export(model, [path to the save onnx model], input_spec=[input_spec], opset_version=[opset version])

例如通过paddle提供的动态图转静态图的工具,具体如下

python PaddleSeg/export.py 
--config PaddleSeg/configs/bisenet/bisenet_cityscapes_1024x1024_160k.yml
--model_path model.pdparams 
--save_dir bisenet

save_dir即output输出文件
├── deploy.yaml # 部署相关的配置文件,主要说明数据预处理的方式
├── model.pdmodel # 预测模型的拓扑结构文件
├── model.pdiparams # 预测模型的权重文件
└── model.pdiparams.info # 参数额外信息,一般无需关注

静态图

  • 除了动态图模型可以导出为ONNX模型
  • 静态图的推理模型当然也可以转换为ONNX模型
  • 通过命令行调用如下命令即可完成转换
$ paddle2onnx \
    --model_dir [model dir] \
    --model_filename [model filename] \
    --params_filename [params filename] \
    --save_file [save file] \
    --opset_version [opset version]
Parameters Description
model_dir The directory path of the paddlepaddle model saved by paddle.fluid.io.save_inference_model
model_filename [Optional] The model file name under the directory designated by--model_dir
params_filename [Optonal] the parameter file name under the directory designated by--model_dir
opset_version [Optional] To configure the ONNX Opset version. Opset 9-11 are stably supported. Default value is 9.

模型可视化

通过netron导入可视化模型结构:
各主流深度学习框架转换onnx_第1张图片

Pytorch2onnx

torch.onnx.export(model, args, f, export_params=True, verbose=False, input_names=None, 
output_names=None,do_constant_folding=True,dynamic_axes=None,opset_version=9)

Function Parameters:
    1. model:torch.nn.model
        要导出的模型
    2. args:tuple or tensor
        模型的输入参数。注意tuple的最后参数为dict要小心,详见pytorch文档。
        输入参数只需满足shape正确,为什么要输入参数呢?因为后面torch.jit.trace要用到,先按下不表。
    3. f:file object or string
        转换输出的模型的位置,如'yolov4.onnx'
    4. export_params:bool,default=True
        true表示导出trained model,否则untrained model。默认即可
    5. verbose:bool,default=False
        true表示打印调试信息
    6. input_names:list of string,default=None
        指定输入节点名称
    7. output_names:list of string,default=None
        指定输出节点名称
    8. do_constant_folding:bool,default=True
        是否使用常量折叠,默认即可
    9. dynamic_axes:dict> or dict,default=None
        有时模型的输入输出是可变的,如RNN,或者输入输出图片的batch是可变的,
        这时我们通过dynamic_axes来指定输入tensor的哪些参数可变。
        如input的shape为(b,3,h,w)其中b、h、w可变
          output的shape为(b,c,5)其中b、c可变
        有几种方式实现:
        1) 仅list(int)
            dynamic_axes={'input':[0,2,3],'output':[0,1]}
        2) 仅dict
            dynamic_axes={'input':{0:'batch',2:'height',3:'width'},'output':{0:'batch',1:'c'}}
        3) mixed
            dynamic_axes={'input':{0:'batch',2:'height',3:'width'},'output':[0,1]}
     10. opset_version:int,default=9
        指定onnx的opset版本,版本过低的话,不支持upsample等操作。

多输入以及不定尺寸问题

  • input_names=[‘input1’, ‘input2’], # 定义输入结点的名字,有几个输入就定义几个
  • dynamic_axes指定可定的axes

不支持的操作

  • onnx只能输出静态图,因此不支持if-else分支。一次只能走一个分支
  • onnx不支持步长为2的切片。例如a[::2,::2]
  • onnx不支持对切片对象赋值。例如a[0,:,:,:]=b, 可以用torch.cat改写
  • onnx里面的resize要求output shape必须为常量
  • 不支持自定义的conv,支持conv1d,conv2d,conv3d
  • AdaptiveAvgPool2d : 使用AvgPool2d替换
  • Expand : torch.cat进行替换
  • ReLU6 : 通过relu改写;即 ReLU6 = 6.0 - nn.ReLU(inplace=True)(6.0-relu)
  • C++调用时数据类型要是32位浮点型

reference

  • 不支持的操作

Tensorflow2onnx

  • 后续更新

你可能感兴趣的:(pytorch,学习,深度学习,paddlepaddle,pytorch,tensorflow)