当前位置: 首页 > news >正文

【PaddlePaddle onnx】PaddlePaddle导出ONNX及模型可视化教程

文章目录

  • 1 背景介绍
  • 2 实验环境
  • 3 paddle.onnx.export函数简介
  • 4 代码实操
    • 4.1 PaddlePaddle与ONNX模型导出
    • 4.2 ONNX正确性验证
    • 4.3 PaddlePaddle与ONNX的一致性检查
    • 4.4 多输入的情况
  • 5 ONNX模型可视化
  • 6 ir_version和opset_version修改
  • 7 致谢

原文来自于地平线开发者社区,未来会持续发布深度学习、板端部署的相关优质文章与视频,如果文章对您有帮助,麻烦给点个赞,如果您有兴趣一起学习,欢迎点个关注:寻找永不遗憾(CSDN用户名)

1 背景介绍

使用深度学习开源框架Pytorch训练完网络模型后,在部署之前通常需要进行格式转换,地平线工具链模型转换目前支持Caffe1.0和ONNX(opset_version=10/11 且 ir_version≤7)两种。ONNX(Open Neural Network Exchange)格式是一种常用的开源神经网络格式,被较多推理引擎支持,例如Pytorch、PaddlePaddle、TensorFlow等。本文将详细介绍如何将PaddlePaddle格式的模型导出到ONNX格式。

2 实验环境

本教程的实验环境如下:

Python库Version
paddlepaddle2.4.1
paddle2onnx1.0.5
onnx1.13.0
onnxruntime1.14.0

3 paddle.onnx.export函数简介

paddle.onnx.export函数可以将PaddlePaddle模型导出为ONNX模型,函数介绍如下,其中x_spec用于配置paddle.onnx.export的input_spec参数。

x_spec = paddle.static.InputSpec(shape=None, dtype='float32', name=None)
#shape:   声明维度信息,默认为 None
#dtype:   数据类型,默认为 float32
#name:    网络输入节点名称paddle.onnx.export(layer, path, input_spec=[x_spec], opset_version=11, **configs)
#layer:          导出的Layer对象,即需要转换的网络模型
#path:           存储模型的路径前缀,导出后会自动添加后缀“.onnx”
#input_spec:     用于配置模型输入属性
#opset_version:  默认为9,请手动配置10或11

关于paddle.onnx.export的更多详细介绍,可以查阅PaddlePaddle的API文档:
https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/onnx/export_cn.html

4 代码实操

4.1 PaddlePaddle与ONNX模型导出

以下代码展示了搭建一个简单分类模型并以PaddlePaddle和ONNX格式保存的过程。

import paddle
import paddle.nn as nnclass MyNet(nn.Layer):def __init__(self, num_classes=10):super(MyNet, self).__init__()self.num_classes = num_classesself.features = nn.Sequential(nn.Conv2D(in_channels=1, out_channels=2,kernel_size=3, stride=1, padding=1),nn.ReLU())self.linear = nn.Sequential(nn.Linear(98, num_classes))def forward(self, inputs):x = self.features(inputs)x = paddle.flatten(x, 1)x = self.linear(x)return xmodel = MyNet()#准备输入数据
x_spec = paddle.static.InputSpec([1, 1, 7, 7], 'float32', 'input1')
#将模型以PaddlePaddle的格式保存,以验证和ONNX模型推理的一致性
paddle.jit.save(layer=model, path='./pd_model/pdmodel',input_spec=[x_spec])
#将模型导出为ONNX格式保存
paddle.onnx.export(layer=model, path='./model',input_spec=[x_spec], opset_version=11)

4.2 ONNX正确性验证

可以用以下代码验证ONNX模型的正确性,会检查模型的版本,图的结构,节点及输入输出。若输出为 Check: None 则表示无报错信息,模型导出正确。

import onnxonnx_model = onnx.load("./model.onnx")
check = onnx.checker.check_model(onnx_model)
print('Check: ', check)

4.3 PaddlePaddle与ONNX的一致性检查

可以使用以下代码检查导出的ONNX模型和原始的PaddlePaddle模型是否有相同的计算结果。

import numpy as np
import onnxruntime
import paddleinput1 = np.random.random((1, 1, 7, 7)).astype('float32')ort_sess = onnxruntime.InferenceSession("./model.onnx")
ort_inputs = {ort_sess.get_inputs()[0].name: input1}
ort_outs = ort_sess.run(None, ort_inputs)model = paddle.jit.load("./pd_model/pdmodel")
model.eval()
paddle_input = paddle.to_tensor(input1)
paddle_outs = model(paddle_input)print(ort_outs[0])
print(paddle_outs.numpy())
np.testing.assert_allclose(tf_outs.numpy(), ort_outs[0], rtol=1e-03, atol=1e-05)
print("onnx model check finsh.")

4.4 多输入的情况

若您的模型存在多输入,则可参考下方代码保存成PaddlePaddle和ONNX格式。ONNX的正确性验证和PaddlePaddle与ONNX的一致性检查不再赘述,仿照上述代码编写即可。

import paddle
import paddle.nn as nnclass MyNet(nn.Layer):def __init__(self, num_classes=10):super(MyNet, self).__init__()self.num_classes = num_classesself.features_1 = nn.Sequential(nn.Conv2D(in_channels=1, out_channels=2,kernel_size=3, stride=1, padding=1),nn.ReLU())self.features_2 = nn.Sequential(nn.Conv2D(in_channels=1, out_channels=2,kernel_size=3, stride=1, padding=1),nn.ReLU())self.linear = nn.Sequential(nn.Linear(98, num_classes))def forward(self, inputs1, inputs2):x = self.features_1(inputs1)y = self.features_2(inputs2)z = paddle.concat((x, y), 1)z = paddle.flatten(z, 1)z = self.linear(z)return zmodel = MyNet()x_spec = paddle.static.InputSpec([1, 1, 7, 7], 'float32', 'input1')
y_spec = paddle.static.InputSpec([1, 1, 7, 7], 'float32', 'input2')
paddle.jit.save(layer=model, path='./pd_model/pdmodel',input_spec=[x_spec, y_spec])
paddle.onnx.export(layer=model, path='./model',input_spec=[x_spec, y_spec], opset_version=11)

5 ONNX模型可视化

导出成ONNX模型后,可以使用开源可视化工具Netron来查看网络结构及相关配置信息。Netron的使用方式主要分为两种,一种是使用在线网页版 https://netron.app/ ,另一种是下载安装程序 https://github.com/lutzroeder/netron 。此教程中模型的可视化效果为:

6 ir_version和opset_version修改

地平线工具链支持的ONNX模型需要满足 opset_version=10/11 且 ir_version≤7,当拿到的ONNX模型不满足这两个要求时,可以修改代码重新导出,或者尝试编写脚本直接修改ONNX模型的对应属性,第二种方式的示例代码如下:

import onnxmodel = onnx.load("./model.onnx")
model.ir_version = 6
model.opset_import[0].version = 10
onnx.save_model(model, "./model_version.onnx")

**注意:**高版本向低版本切换时可能会出现问题,这里只是一种可尝试的解决方案。
调整结束后,使用Netron可视化model_version.onnx,如下图所示:
在这里插入图片描述

此时,ONNX模型的ir_version=6,opset_version=10,满足地平线工具链的转换条件。

7 致谢

原文来自于地平线开发者社区,未来会持续发布深度学习、板端部署的相关优质文章与视频,如果文章对您有帮助,麻烦给点个赞,如果您有兴趣一起学习,欢迎点个关注:寻找永不遗憾(CSDN用户名)

http://www.lryc.cn/news/34602.html

相关文章:

  • 虹科案例 | 如何可持续的对变压器进行温度监控?
  • Go之入门(特性、变量、常量、数据类型)
  • 第九届省赛——8等腰三角形(找规律)
  • 【产品设计】ToB 增删改查显算传
  • MySQL(二)视图、锁、存储过程、触发器、锁以及常用工具
  • CorelDRAW Graphics Suite2023更新内容介绍
  • 2021牛客OI赛前集训营-提高组(第三场) T1变幻
  • 你还在使用if-else写代码吗,今天带你领略下策略模式的魅力!
  • Leetcode. 21 合并两个有序列表
  • 使用 Wall 教你搭建 照片墙 和 视频墙
  • 0103 MySQL06
  • 【UE4 RTS游戏】04-摄像机运动_鼠标移动到视口边缘时移动Pawn
  • 147597-66-8,p-SCN-Bn-NOTA,NOTA-P-苯-NCS新型双功能螯合剂
  • JDK解压安装及idea开发工具配置
  • 使用Ubuntu中的Docker部署Remix
  • 【MySQL】P9 多表查询(3) - 子查询
  • SpringMVC中的拦截器不生效的问题解决以及衍生出的WebMvcConfigurationSupport继承问题思考
  • 【量化交易笔记】3.实现数据库保存数据
  • [数据结构]:15-堆排序(顺序表指针实现形式)(C语言实现)
  • 蓝桥 卷“兔”来袭编程竞赛专场-02破解曾公亮密码 题解
  • CSS定位
  • python sympy库
  • 达梦数据库统计信息的导出导入
  • 信息系统基本知识(六)
  • <C++>智能指针
  • 1.分析vmlinux可执行文件是如何生成的? 2.整理内核编译流程:uImage/zImage/Image/vmlinx之间关系
  • 数据结构4——线性表3:线性表的链式结构
  • weblogic 忘记密码重置密码
  • 安卓开发之动态设置网络访问地址
  • 深度学习模型训练工作汇报(3.8)