onnx 1.16 doc学习笔记一:ONNX概念

onnx作为一个通用格式,很少有中文教程,因此开一篇文章对onnx 1.16文档进行翻译与进一步解释,
onnx 1.16官方文档:https://onnx.ai/onnx/intro/index.html](https://onnx.ai/onnx/intro/index.html),
如果觉得有收获,麻烦点赞收藏关注,目前仅在CSDN发布,本博客会分为多个章节,目前尚在连载中,详见专栏链接:
https://blog.csdn.net/qq_33345365/category_12581965.html
开始编辑时间:2024/2/20;最后编辑时间:2024/2/21


ONNX 概念

ONNX 可以类比为一种专门用于数学函数的编程语言。它定义了机器学习模型执行推理功能所需的所有必要操作。线性回归可以用以下方式表示:

def onnx_linear_regressor(X):  # 线性回归的表达式:y = ax + b
    "ONNX code for a linear regression"
    return onnx.Add(onnx.MatMul(X, coefficients), bias)

这个例子非常类似于一个开发人员可以用 Python 写的表达式。它也可以用一个图表来表示,该图表一步一步地展示了如何转换特征以获得预测。这就是为什么使用 ONNX 实现的机器学习模型经常被称为:ONNX图(ONNX Graph)

在这里插入图片描述

ONNX 的目标是提供一种通用语言,任何机器学习框架都可以用来描述其模型。第一个场景是简化机器学习模型在生产环境中的部署。可以在部署环境中专门实现和优化 ONNX 解释器(或运行时)来完成这项任务。通过 ONNX,可以构建一个独特的流程,将模型部署到生产环境中,并且独立于构建模型所使用的学习框架。ONNX 实现了一个 Python 运行时,可以用来评估 ONNX 模型和评估 ONNX 操作。这旨在阐明 ONNX 的语义,并帮助理解和调试 ONNX 工具和转换器。此 Python 运行时并非用于生产环境,其性能也并非设计目标(请参见 onnx.reference)。


Input, Output, Node, Initializer, Attributes

本小节介绍五个概念的定义:

构建一个 ONNX 图意味着使用 ONNX 语言,或者更确切地说是使用ONNX Operators来实现一个函数。 线性回归可以用这种方式来编写。 下面的代码行不遵循 Python 语法,它们只是用于说明模型的一种伪代码。

Input: float[M,K] x, float[K,N] a, float[N] c
Output: float[M, N] y

r = onnx.MatMul(x, a)
y = onnx.Add(r, c)

这段代码实现了一个函数 f(x, a, c) -> y = x @ a + c,其中 x, a, c 是inputs,y 是outputs。r 是一个中间结果。MatMul 和 Add 是nodes,它们也有输入和输出。节点还具有类型,它是 ONNX Operators 中的一个算子(Operator)。

该图也可能有一个initializer。当输入永远不会改变时,例如线性回归的系数,将其转换为图中存储的常量是最有效的。如下所示:

Input: float[M,K] x
Initializer: float[K,N] a, float[N] c
Output: float[M, N] xac

xa = onnx.MatMul(x, a)
xac = onnx.Add(xa, c)

该图将类似于以下图像。右侧描述了操作符 Add,其中第二个输入被定义为initializer。

在这里插入图片描述

属性(attribute)是算子的固定参数。算子 Gemm 有四个属性:alpha、beta、transA 和 transB。除非运行时通过其 API 允许,否则在加载 ONNX 图后,这些值将无法更改,并且在所有预测中保持不变。


使用protobuf进行序列化(Serialization)

机器学习模型部署到生产环境通常需要复制整个用于训练模型的生态系统,大多数情况下会使用 Docker 进行容器化部署。然而,一旦模型被转换为 ONNX 格式,生产环境只需一个运行时(runtime)就能执行使用 ONNX算子定义的计算图。这个运行时可以用任何适合生产应用的语言开发,例如 C、Java、Python、JavaScript、C#、WebAssembly、ARM 等。

但是,为了实现上述目的,需要保存 ONNX 计算图。ONNX 使用 protobuf 将计算图序列化成一个单独的块(block)。其目标是尽可能优化模型的尺寸。


Metadata

机器学习模型会不断更新。因此,跟踪模型版本、模型作者以及训练方式非常重要。ONNX 允许将额外数据存储在模型本身中。

doc_string: 对该模型的人类可读文档。 支持 Markdown 格式。

domain: 指示模型命名空间或领域的反向 DNS 名称,例如,“org.onnx”。

metadata_props: 命名元数据,以字典形式表示 map<string,string>,值和键应该不重复。

model_author: 以逗号分隔的姓名列表,模型作者和/或其组织的个人姓名。

model_license: 模型可用的许可证的知名名称或 URL。

model_version: 模型本身的版本,以整数编码。

producer_name: 生成模型的工具名称。

producer_version: 生成工具的版本。

training_info: 可选扩展,包含训练信息


可用算子和域(domains)的列表

这是现有列表:ONNX Operators。ONNX 算子列表涵盖了标准矩阵算子、归约、图像变换、深度神经网络层、激活函数。它涵盖了实现标准和深度机器学习推理函数所需的大部分操作。ONNX 并不会实现所有现有的机器学习算子,因为这样的列表会无限长。

主要算子列表使用域 ai.onnx 标识。域可以定义为一组算子。该列表中少数几个算子专用于文本处理,但几乎无法满足所有需求。该列表还缺少标准机器学习中非常流行的基于树的模型。这些模型是另一个域 ai.onnx.ml 的一部分,其中包括基于树的模型(TreeEnsemble Regressor 等)、预处理(OneHotEncoder、LabelEncoder 等)、SVM 模型(SVMRegressor 等)、插值器(Imputer)。

ONNX 只定义了这两个域。但是 ONNX 库支持任何自定义域和算子。


支持类型

ONNX 规范针对使用张量进行数值计算进行了优化。张量是一个多维数组,由以下几点定义:

  • a type: 张量中所有元素的元素类型,它是统一的。
  • a shape: 一个包含所有维度的数组,这个数组可以是空数组,维度也可以为空。
  • a contiguous array: 它表示所有值。

此定义不包括步长(strides)或基于现有张量定义张量视图的可能性。ONNX 张量是一个密集的完整数组,没有步长。


支持类型

ONNX 规范针对使用张量进行数值计算进行了优化。张量是一个多维数组,由以下几点定义:

  • a type: 张量中所有元素的元素类型,它是统一的。
  • a shape: 一个包含所有维度的数组,这个数组可以是空数组,维度也可以为空。
  • a contiguous array: 它表示所有值。

此定义不包括步长(strides)或基于现有张量定义张量视图的可能性。ONNX 张量是一个密集的完整数组,没有步长。

ONNX支持的类型包括元素类型,稀疏张量和一些其他的类型。


元素类型Element Type

ONNX最初是为了帮助部署深度学习模型而开发的。这就是为什么规范最初是为浮点数(32位)设计的。当前版本支持所有常用类型。字典TENSOR_TYPE_MAP给出了ONNX和numpy之间的对应关系。

import re
from onnx import TensorProto

reg = re.compile('^[0-9A-Z_]+$')

values = {}
for att in sorted(dir(TensorProto)):
    if att in {'DESCRIPTOR'}:
        continue
    if reg.match(att):
        values[getattr(TensorProto, att)] = att
for i, att in sorted(values.items()):
    si = str(i)
    if len(si) == 1:
        si = " " + si
    print("%s: onnx.TensorProto.%s" % (si, att))

运行上述代码,得到下述输出:

 0: onnx.TensorProto.UNDEFINED
 1: onnx.TensorProto.FLOAT
 2: onnx.TensorProto.UINT8
 3: onnx.TensorProto.INT8
 4: onnx.TensorProto.UINT16
 5: onnx.TensorProto.INT16
 6: onnx.TensorProto.INT32
 7: onnx.TensorProto.INT64
 8: onnx.TensorProto.STRING
 9: onnx.TensorProto.BOOL
10: onnx.TensorProto.FLOAT16
11: onnx.TensorProto.DOUBLE
12: onnx.TensorProto.UINT32
13: onnx.TensorProto.UINT64
14: onnx.TensorProto.COMPLEX64
15: onnx.TensorProto.COMPLEX128
16: onnx.TensorProto.BFLOAT16
17: onnx.TensorProto.FLOAT8E4M3FN
18: onnx.TensorProto.FLOAT8E4M3FNUZ
19: onnx.TensorProto.FLOAT8E5M2
20: onnx.TensorProto.FLOAT8E5M2FNUZ
21: onnx.TensorProto.UINT4
22: onnx.TensorProto.INT4

ONNX是强类型的,它的定义不支持隐式强制转换。即使其他语言可以添加两个不同类型的张量或矩阵,也不可能。这就是为什么必须在图中插入显式强制转换的原因。

稀疏张量Sparse Tensor

稀疏张量常用于表示许多元素为空的数组。ONNX 支持二维稀疏张量。SparseTensorProto 类定义了维度 (dims)、索引 (indices,使用 int64) 和值 (values) 等属性。

其他类型

除了张量和稀疏张量,ONNX 还支持通过 SequenceProto 和 MapProto 类型来表示序列张量、张量映射以及序列张量映射。不过,这些类型的使用比较少见。


什么是opset version

ONNX 算子集 (opset) 与 ONNX 软件包的版本映射。每次 ONNX 的次版本号增加时,opset 版本也会增加。新的 opset 版本会包含更新或新增的算子。

import onnx

print(onnx.__version__, " opset=", onnx.defs.onnx_opset_version())

使用上述代码,输出是:

1.16.0  opset= 21

每个 ONNX 图都会附加一个 opset,它是一个全局信息,定义了图中所有算子的版本。Add算子在版本 6、7、13 和 14 中进行了更新。如果图的 opset 是 15,则意味着 Add算子遵循 14 版本的规范。如果图的 opset 是 12,则 Add算子遵循 7 版本的规范。图中的一个算子遵循其在全局图 opset 以下(或等于)的最新定义。

一个图可能包含来自多个域的算子,例如 ai.onnx 和 ai.onnx.ml。在这种情况下,图必须为每个域定义一个全局 opset。该规则适用于同一域内的所有算子。


子图,测试与循环 subgroups, tests and loops

ONNX 支持测试和循环,但这些结构通常又慢又复杂,因为它们都需要包含另一个 ONNX 图作为属性。如果可以,最好避免使用它们。

If

算子If根据条件(condition)评估执行两个图中的一个。

If(condition) then
    execute this ONNX graph (`then_branch`)
else
    execute this ONNX graph (`else_branch`)

这两个图可以利用图中已经计算的结果,并且必须产生完全相同的数量的输出。这些输出将是If算子的输出。

在这里插入图片描述

Scan

算子Scan 用于实现一个具有固定迭代次数的循环。它遍历输入的每一行(或任何其他维度),并将输出沿着相同轴进行连接。看一个成对距离pairwise distances的例子: M ( i , j ) = ∣ ∣ X i − X j ∣ ∣ 2 M(i,j)=||X_i-X_j||^2 M(i,j)=∣∣XiXj2
在这里插入图片描述

该循环即使比自定义实现成对距离慢,但效率仍然很高。它假设输入和输出都是张量,并自动将每次迭代的输出连接成单个张量。之前的例子只有一个,但它可能有多个。

Loop

算子Loop是一个能够实现 for循环while循环 的组件。它既可以让循环执行固定次数,也可以在某个条件不满足时自动结束。

循环的输出以两种方式处理:

  • 第一种方式类似于 Loop Scan: 输出结果以张量形式沿第一个维度进行拼接。这意味着所有输出张量必须具有兼容的形状。
  • 第二种方式将张量拼接成一个序列: 每个张量作为一个单独的元素存储在序列中。

扩展性Extensibility

ONNX 定义了标准算子列表,称为:ONNX Operators。但是,您完全可以在此域或新域下定义自己的算子。onnxruntime 定义了自定义算子以提高推理性能。每个节点都有一个类型、一个名称、命名输入和输出以及属性。只要节点符合这些约束描述,就可以将其添加到任何 ONNX 图形中。

可以使用 Scan算子实现成对距离计算。但是,一个名为 CDist 的专用算子被证明速度明显更快,快到足以让人愿意为此实现一个专门的运行时。


函数

函数是扩展 ONNX 规范的一种方式。某些模型需要使用相同组合的算子。通过创建由现有 ONNX Operators定义的函数本身,可以避免这种情况。一旦定义,函数就像任何其他运算符一样工作,它具有输入、输出和属性。

使用函数有两个优点。第一个是使代码更短,更容易阅读。第二个是任何 onnxruntime 都可以利用该信息来更快速地运行预测。对于不依赖现有运算符实现的函数,运行时可以有特定的实现。


形状和种类推理 Shape (and Type) Inference

了解结果的形状并不是执行 ONNX 图形所必需的,但是可以利用这些信息来提高其速度。例如,假设您有一个以下图形:

Add(x, y) -> z 
Abs(z) -> w

如果 x 和 y 具有相同的形状,那么 z 和 w 也具有相同的形状。知道这一点,就可以重用为 z 分配的缓冲区,从而原地计算绝对值 w。形状推理有助于运行时管理内存,从而提高效率。

在大多数情况下,ONNX 软件包可以根据每个标准算子的输入形状来计算输出形状。对于官方列表之外的任何自定义算子,则无法进行推理。


工具

在可视化 ONNX 图表方面,netron是一个非常实用的工具,而且不需要编程。第一个屏幕截图就是用这个工具制作的。

onnx2py.py 脚本可以将一个 ONNX 图转换为 Python 文件。生成的脚本能够创建与原图相同的计算图,并且用户可以进行修改。

zetane工具可以加载 ONNX 模型并在模型执行过程中显示中间结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/404712.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Redis服务搭建】

目录 Redis的修改配置启动以及参数调优Redis的常用基本操作Redis运维监控命令Redis的配置的动态更新和写入Redis的多用户管理Redis的慢日志Redis禁用危险命令和压测工具Redis持久化存储1.Redis的RDB持久化存储2.Redis的AOF持久化存储 Redis的主从复制redis的哨兵实现主从自动切…

信号信号槽

三、信号槽 概念 信号和槽是两种函数&#xff0c;这是Qt在C基础上新增的特性&#xff0c;类似于其他技术中的回调的概念。 信号槽通过程序员提前设定的“约定”&#xff0c;可以实现对象之间的通信&#xff0c;有两个先决条件。 通信的对象都是在QOBject类中派生出来的。 QOBje…

提升App推广效果,从优化落地页开始

在App推广过程中&#xff0c;落地页的转化率一直是推广运营者关注的重点。然而&#xff0c;很多运营者发现&#xff0c;即使使用了相同的工具和模板&#xff0c;别人的效果却远远超出自己。那么&#xff0c;问题到底出在哪里呢&#xff1f;今天&#xff0c;我们就来聊聊如何提升…

便携式气象站的安装注意事项

型号推荐&#xff1a;云境天合TH-BQX9】便携式气象站的安装注意事项包括以下几点&#xff1a; 安装前检查&#xff1a;在安装前&#xff0c;应对便携式气象站进行检查&#xff0c;确保设备的包装完好无损&#xff0c;配件齐全&#xff0c;如气象站传感器、支架、采集器和传输模…

链表和顺序表的优劣分析及其时间、空间复杂度分析

链表和顺序表的优劣分析及其时间、空间复杂度分析 一、链表和顺序表的优劣分析二、算法复杂度<font face "楷体" size 5 color blue>//上面算法的执行次数大致为&#xff1a;F&#xff08;N&#xff09; N^22*N10;   N 10,F(10) 1002010 130次   N 1…

提高学习效率和速度的方法

如下是一些策略和方法来帮助提高学习效率和速度&#xff1a; 1. **主动学习**&#xff1a;主动寻找信息并提出问题&#xff0c;而不是被动接受。这样可以提高您的学习动力和效率。 2. **分块学习**&#xff1a;将复杂的知识点分解成小块&#xff0c;逐一理解和掌握。这种方法可…

unity屏幕受伤特效

//使用用途&#xff1a;同于屏幕掉血的后处理特效 //请结合和脚本&#xff1a;BloodScreen 挂载至摄像机使用本特效 //本特效设计之初未考虑兼容移动设备&#xff0c;请注意//使用说明&#xff1a; //掉血获取此脚本&#xff0c;将showBlood设置为true&#xff0c;如果您需要更…

Js的 Promise的 then catch 笔记240222

Js的 Promise的 then catch 笔记240222 基本用法 new Promise(f>{setTimeout(ev>{f("一秒后输出控制台");},1000); }).then(f的参数>{console.log(f的参数); }); // 控制台输出: 一秒后输出控制台上面代码中, f 的标准名叫做 resolve , 所以应该写成 new …

函数栈帧的创建及销毁(超详解)

目录 1.预备知识 1.1内存区的划分 1.2认识相关寄存器和汇编指令 1.2.1寄存器 1.2.2相关汇编指令 2.测试前 2.1测试代码及环境 2.2 main函数也是被其他函数调用的 3.函数栈帧的创建 4.进入函数内部 5.形参与实参 6.call/jump add函数 7.函数栈帧的销毁 7.1保存…

使用python查看官网是否发布新的内容

目录 前言 第一章、python介绍和使用pip install下载包 1.python介绍 2.使用vscode编写python 3.pip install的使用 第二章、查看官网是否发布新的内容 第三章、代码实现 目录结构 代码实现 check_new_news.py files.py news.py main.py file.txt 运行演示 前言 也…

【已解决】@tableid can‘t more than one

实体里面不能有两个TableId&#xff0c;只留一个就好了

SpringBoot对于SpringMVC的支持

创建项目 版本说明这里使用的 SpringBoot 2.0.0.Release SpringBoot对于SpringMVC的支持 在之前的开发中很多场景下使用的是基于xml配置文件或者是Java配置类的方式来进行SpringMVC的配置。一般来讲&#xff0c;初始的步骤如下所示 1、初始化SpringMVC的DispatcherServlet2、…

[OpenAI]继ChatGPT后发布的Sora模型原理与体验通道

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言OpenAI体验通道Spacetime Latent Patches 潜变量时空碎片, 建构视觉语言系统…

kettle计算增长率

kettle计算增长率 问题描述处理方法 问题描述 读取一段时间内的数据记录&#xff0c;计算相邻记录的比率 iddatevalue12024-01-0110012024-01-0211012024-01-0312012024-01-0490 处理方法 1.使用统计中的分析查询节点能在每一行中添加前后行的数据 2.使用计算器节点计算比…

音视频基础概念笔记

RGB 色彩空间更适合图像采集和显示&#xff0c; YUV 空间用于编码和存储则比较好。 无论是 RGB 还是 YUV &#xff0c;他们都是 表达 色彩信息的一种方式。 &#xff08;Human Visual System&#xff09;人类视觉系统 色度感知 包含两个维度&#xff1a;色调&#xff08;Hue&…

ELK入门(四)-logstash

Logstash Logstash 是开源的服务器端数据处理管道&#xff0c;能够同时从多个来源采集数据&#xff0c;转换数据&#xff0c;然后将数据发送到您最喜欢的存储库中。 Logstash 能够动态地采集、转换和传输数据&#xff0c;不受格式或复杂度的影响。利用 Grok 从非结构化数据中…

WebService学习,wsdl文件详解

目录 第一章、起因1.1&#xff09;学习原因1.2&#xff09;提问的过程&#xff08;逐步提出问题&#xff09;1、&#xff1f;wsdl链接的含义&#xff0c;有什么作用&#xff1f;2、什么是wsdl文档&#xff1f;3、如何阅读wsdl文件&#xff1f;4、wsdl文件有什么作用&#xff1f…

Linux编译器---gcc/g++使用详解

目录 前言 gcc/g介绍 gcc/g的编译指令&#xff08;以gcc为例&#xff09; ​编辑 gcc选项 预处理(进行宏替换) 编译&#xff08;生成汇编&#xff09; 汇编&#xff08;生成机器可识别代码&#xff09; 链接&#xff08;生成可执行文件或库文件&#xff09; 函数库 概念 …

Vue单文件学习项目综合案例Demo,黑马vue教程

文章目录 前言一、小黑记事本二、购物车三、小黑记账清单 前言 bilibili视频地址 一、小黑记事本 效果图 主代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"/><meta http-equiv"X-UA-Compatible&…

C# CAD2016 cass10宗地Xdata数据写入

一、 查看cass10写入信息 C# Cad2016二次开发获取XData信息&#xff08;二&#xff09; 一共有81条数据 XData value: QHDM XData value: 121321 XData value: SOUTH XData value: 300000 XData value: 141121JC10720 XData value: 权利人 XData value: 0702 XData value: YB…