【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 |
|---|---|
| paddlepaddle | 2.4.1 |
| paddle2onnx | 1.0.5 |
| onnx | 1.13.0 |
| onnxruntime | 1.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用户名)
相关文章:
【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 致谢原文来自于地平线开发者社区,未…...
虹科案例 | 如何可持续的对变压器进行温度监控?
为了延长变压器的使用寿命,需要一个测量系统来监测内部整个绕组区域的温度。它必须明确温度升高发生的位置及其强度。您可以在此处了解为什么会这样以及如何在实践中实施? PART 1 变压器多点测温问题 变压器的工作温度越高,使用寿命越短。这里主要存在…...
Go之入门(特性、变量、常量、数据类型)
一、Go语言特性 语法简单并发性。Go语言引入了协程goroutine,实现了并发编程内存分配。Go语言为了解决高并发下内存的分配和管理,选择了tcmalloc进行内存分配(为了并发设计的高性能内存分配组件,使用cache为当前线程提供无锁分配…...
第九届省赛——8等腰三角形(找规律)
题目:本题目要求你在控制台输出一个由数字组成的等腰三角形。具体的步骤是:1. 先用1,2,3,...的自然数拼一个足够长的串2. 用这个串填充三角形的三条边。从上方顶点开始,逆时针填充。比如,当三角形高度是8时:…...
【产品设计】ToB 增删改查显算传
入职培训时技术leader说:“我不需要你们太聪明,做好基础的增删改查就可以了。”看似很简单的活,要做好并不容易。基础的坑在哪里呢? 一、 增(新增、创建、导入) 1. 明确表字段类型 新增的业务是由不同类型…...
MySQL(二)视图、锁、存储过程、触发器、锁以及常用工具
MySQL进阶视图检查选项视图的更新存储过程存储过程基本语法变量系统变量用户自定义变量局部变量if判断参数casewhile循环repeat循环loop循环cursor游标handler条件处理程序存储函数触发器锁全局锁表级锁表锁元数据锁意向锁行级锁行锁间隙锁&临键锁InnoDB引擎逻辑存储结构事…...
CorelDRAW Graphics Suite2023更新内容介绍
懂设计的职场人都知道这款软件,CorelDRAW是一款非常高效的矢量图形设计软件。CorelDRAW操作界面简洁易懂,能够为用户提供精确地创建物体的尺寸和位置的功能,减少点击步骤,提高设计效率,节省设计时间。功能比普通的美图…...
2021牛客OI赛前集训营-提高组(第三场) T1变幻
2021牛客OI赛前集训营-提高组(第三场) 题目大意 对于一个大小为nnn的数组aaa的任意一点iii,若满足ai−1>aia_{i-1}>a_iai−1>ai且ai<ai1a_i<a_{i1}ai<ai1,则称iii为山谷点。111和nnn不可能为山谷点。…...
你还在使用if-else写代码吗,今天带你领略下策略模式的魅力!
1、什么是策略模式 策略模式其实也是在解耦,把策略的定义、创建、使用这三个部分解耦开来,因为本身策略模式也是基于接口编程,这样其实可以简单的理解客户端调用使用接口进行编程,可以通过工厂方法创建对应的策略模式,…...
Leetcode. 21 合并两个有序列表
尾插 核心思路:依次比较 ,取经过比较后较小值进行尾插 cur1 指向list1 ,cur 2指向list2 ,当cur1走完list1 或者cur2 走完list2 后停止 如果cur1走完list1 ,可以将cur2 整个拿下来尾插 如果cur2走完list2 ,可以将cur1 整个拿下来尾插 特殊情况 ࿱…...
使用 Wall 教你搭建 照片墙 和 视频墙
下载 Github:https://github.com/super-tongyao/wall 国内仓库(不推荐,只做加速访问,无编译包和发行版,以github仓库为准):https://gitee.com/Super_TongYao/wall 推荐github仓库,下载最新版…...
0103 MySQL06
1.事务 1.一个事务其实就是一个完整的业务逻辑 如:转账,从A账户向B账户转账10000,将A账户的钱减去10000(update),将B账户的钱加上10000(update),这就是一个完整的业务逻…...
【UE4 RTS游戏】04-摄像机运动_鼠标移动到视口边缘时移动Pawn
效果可以看到当鼠标移动到视口边缘时,Pawn就会向这个方向移动。步骤打开项目设置,添加两个操作映射打开“CameraPawnController”,在事件图表中添加两个浮点型变量,一个为公有一个为私有。分别命名为“ZoomSensitivity”、“MaxAr…...
147597-66-8,p-SCN-Bn-NOTA,NOTA-P-苯-NCS新型双功能螯合剂
p-SCN-Bn-NOTA | NOTA-P-苯-NCS | CAS:147597-66-8 | 纯度:95%1.p-SCN-Bn-NOTA试剂信息:CAS号:147597-66-8外观:白色固体分子量:C20H26N4O6S分子式:448.4928溶解性:溶于有机溶剂&…...
JDK解压安装及idea开发工具配置
1. 安装JDK 1.1 下载安装包 下载安装包,直接解压,注意,解压的路径不要有中文 1.2 配置环境变量 右键点击我的电脑,选择属性 选择高级系统设置 选择环境变量 选择新建 在变量名中输入JAVA_HOME,变量值就是1.1中压缩包…...
使用Ubuntu中的Docker部署Remix
一、简介1.博主这里使用的是腾讯云的服务,然后使用Docker进行部署Remix。2.踩了几个坑,没有花费过多时间,所以这篇文章会记录踩过的坑。然后避免你们掉进去,然后花费过多时间。3.这里就不写怎么安装Docker了,因为博主上…...
【MySQL】P9 多表查询(3) - 子查询
子查询子查询基本概念(公式)子查询分类按照结果分类标量 子查询列 子查询行 子查询表 子查询子查询 基本概念(公式) SQL查询语句中嵌套Select语句,称为嵌套查询,亦称为子查询; select * from…...
SpringMVC中的拦截器不生效的问题解决以及衍生出的WebMvcConfigurationSupport继承问题思考
文章目录SpringMVC中的拦截器不生效的问题解决WebMvcConfigurationSupport继承问题思考SpringMVC中的拦截器不生效的问题解决 过滤器代码(被Spring扫描并管理): Component public class StuInterceptor implements HandlerInterceptor {Overridepublic boolean pr…...
【量化交易笔记】3.实现数据库保存数据
上一节,我们通过下载相关的 pandas 数据保存为 本地csv文件,这一节将上节的数据以数据库方式保存。 数据库保存 采集数据部分前一节已做说明,这里就直接用采用前面的内容。这里着重说明的事数据库连接。对与 python 相连接的数据库有很多&a…...
[数据结构]:15-堆排序(顺序表指针实现形式)(C语言实现)
目录 前言 已完成内容 堆排序实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-PSeqListFunction.cpp 04-SortCommon.cpp 05-SortFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容,除其中使用到C引用外,全为C语言代码…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
