目的

本文档包含ONNX语义的规范性规范。

“onnx”文件夹下的.proto和.proto3文件构成了用协议缓冲区定义语言编写的语法规范。.proto和.proto3文件中的注释目的是提高这些文件的可读性,但如果它们与本文档冲突,则不具有规范性。此类冲突应报告为文档错误。

模型验证说明

有一个工具可以根据此规范执行模型的一般验证。它在C++中用Python命令行package实现。

本文件及所有相关文件中的语言说明:

在本文件中使用SHOULD、MUST、MAY等与RFC 2119一致。

“list”的使用应表示项目的有序集合,“set”应表示唯一元素的无序集合,“bag”表示可能非唯一元素的无序集合。

Components

ONNX is an open specification that consists of the following components:

  1. A definition of an extensible computation graph model.
  2. Definitions of standard data types.
  3. Definitions of built-in operators.

其中#1和#2包含在本文中;内置操作器在本文档末尾列出的文档中单独介绍。具体来说,内置算子operator被划分为一组原始算子operator和函数。函数是一种算子operator,其语义通过使用其他算子operator(和函数)扩展到子图(称为函数体)中来正式表示。就功能而言,与ONNX兼容的框架或运行时可以内联函数来执行它,如果它没有相应的函数实现。

有两个官方的ONNX变体;两者之间的主要区别在于支持的类型和默认的算子operator集。只有神经网络的ONNX变体只识别张量作为输入和输出类型,而经典的机器学习扩展ONNX-ML也识别序列和映射。ONNX-ML用非神经网络的ML算法扩展了ONNX算子集。

直到IR版本6,ONNX规范和模型格式只处理推理(也称为评分)。从IR版本7开始,ONNX规范和模型格式已扩展到支持训练。ONNX训练模型本身是推理模型的一个扩展,允许只进行推理的runtime忽略与训练相关的扩展并运行推理。然而,在典型的使用场景中,与训练模型相比,仅推理模型可以实现更优化的模型表示(用于推理目的)。

runtime不可知

ONNX并不预先假设或暗示任何特定的运行时实现方法。

例如,一个实现可以由一个解释模型的富运行时组成;

可以是一个代码生成器,它将整个模型转换为某些目标编程语言的可执行代码;

可以是硬件实现;

可以是其中两个或三个的组合。

本规范中的任何内容都不应被解释为主张一种实现方法胜过任何其他方法;

对具体实现的内部工作原理的任何评论都应解释为示例。

ONNX版本控制

ONNX中有几个地方有版本控制功能——IR(中间表示)规范本身、模型版本和算子operator集版本。此外,每一个单独的算子operator都指明它是在哪个版本的包含算子operator集中引入或稳定的。

版本号可以用作简单的数字,也可以用于对语义版本进行编码。如果使用semver,惯例是使用两个最高有效字节作为主要编号,下两个字节用于次要编号,最低有效的四个字节用于构建/错误修复build/bugfix编号。使用semver版本控制时,至少有一个主/辅编号必须为非零。

IR规范对其版本使用简单的单调递增数。有效的IR版本由枚举定义,该枚举当前具有以下值:

//  Version 1, published on Oct 10, 2017.

IR_VERSION_2017_10_10 = 0x0000000000000001;

// Version 2, published on Oct 30, 2017

IR_VERSION_2017_10_30 = 0x0000000000000002;

// Version 3 published on Nov 3, 2017

IR_VERSION = 0x0000000000000003;

算子operator集使用简单的版本号。每个算子operator集版本表示算子operator集及其在特定时间点的语义的快照。

本规范没有提供关于模型生产者应该使用什么版本控制方案的指导。

有关IR、算子operator集和模型版本控制的约定和最佳实践的更多详细信息,请参阅版本控制。

可扩展计算图模型

ONNX指定计算图的可移植、序列化格式。它不一定是框架选择的在内部使用和操作计算的形式。例如,如果在优化过程中操作更有效,则实现可能在内存中以不同的方式表示模型。

一个实现可以通过添加表示语义的算子operator来扩展ONNX,这些算子operator超出了所有实现必须支持的标准算子operator集。其机制是将算子operator集添加到依赖于扩展算子operator的模型中的opset_import属性。

模型Models

顶层ONNX构造是一个“Model”,在协议缓冲区中表示为类型onnx.ModelProto

模型结构的主要目的是将元数据与包含所有可执行元素的图形相关联。元数据是在第一次读取模型文件时使用的,它为实现提供了所需的信息,以确定它是否能够执行模型、生成日志消息、错误报告等。此外,元数据对工具(如IDE和模型库)很有用,它需要它来告诉人类一个给定模型的目的和特性。

每个模型都有以下组件:

模型必须指定一个域,并根据负责组织的标识使用反向域名,这与传统上用于命名Java包的约定相同。

注意:检测ONNX文件

可以使用协议缓冲区分发中的Protocol工具检查ONNX文件的内容,方法如下:

$ protoc --decode=onnx.ModelProto onnx.proto < yourfile.onnx

Where onnx.proto is the file that is part of this repository.

Alternatively, you can use a tool like Netron to explore the ONNX file.

模型语义

推理模型的语义是一个无状态函数(除了用于随机数生成的状态)。因此,每当一个推理模型(没有随机的生成器操作)被用于对同一输入执行推理时,它都会产生相同的输出。

训练模型的语义是有状态对象的语义,状态由训练权重的当前值组成(以及学习算法所需的任何其他辅助状态,例如动量)。具体地说,它的语义是通过三种方法获取的:初始化方法(用于初始化或重置状态变量的值)、训练步骤方法(使用一批输入输出对进行训练)和一种推理方法,该方法利用学习到的权重的当前值进行推理。前两个方法更新对象的状态,而第三个方法没有副作用。

可选元数据

模型中的“metadata_props”字段可用于工具或模型开发人员选择放置在其中的任何类型的可选元数据。以下是定义的模型的“标准”可选元数据属性。

算子operator

每个模型都必须显式地命名其功能所依赖的算子operator。算子operator定义可用算子operator及其版本。每个模型按其域定义导入的算子operator。所有模型都隐式导入默认的ONNX算子operator。

每个算子operator应在单独的文档中定义,并使用protobuf作为序列化格式。如何在运行时找到算子operator文档取决于实现。

注:截至本文档的发布,还没有任何ONNX实现用于处理操作文档。

算子operator的属性包括:

算子operator版本是一个简单的整数值,随着新版本的算子operator的发布,该值单调增加。

默认算子operator以外的算子operator必须指定其域,并应根据负责组织的标识使用反向域名,这与用于命名Java包的约定相同。

算子operator

图中使用的每个算子operator必须由模型导入的算子operator之一显式声明。

算子operator定义的属性包括:

版本值必须与首次发布算子operator时的算子operator版本值相同。算子operator的后续版本一旦发布为稳定版本,则不得更改算子operator的签名或语义。

“status”属性指示算子operator的语法、语义或存在是否处于实验阶段或稳定阶段。一旦一个算子operator被发布为稳定的,它的语法和语义在算子operator集的后续版本中就不能改变。

有两种不同的方法将信息传递给算子operator–输入和属性。后者用于表示图中常量的值,而前者表示图形输入或在图中其他地方计算的值。这种区别可能与某些实现的良好性能密切相关,而与其他实现完全无关。              图

图用于描述无副作用的计算(函数)。序列化图由一组元数据字段、一组模型参数和一组计算节点组成。

每一个计算数据流图都被构造成一个拓扑排序的节点列表,这些节点必须没有循环。每个节点表示对算子operator的调用。每个节点有零个或多个输入和一个或多个输出。

图形具有以下属性:

ValueInfo has the following properties:

版本值必须与首次发布算子operator时的算子operator版本值相同。

算子operator的后续版本一旦发布为稳定版本,则不得更改算子operator的签名或语义。

“status”属性指示算子operator的语法、语义或存在是否处于实验阶段或稳定阶段。一旦一个算子operator被发布为稳定的,它的语法和语义在算子operator的后续版本中就不能改变。

有两种不同的方法将信息传递给算子operator–输入和属性。后者用于表示图中常量的值,而前者表示图形输入或在图中其他地方计算的值。这种区别可能与某些实现的良好性能密切相关,而与其他实现完全无关。

图用于描述无副作用的计算(函数)。序列化图由一组元数据字段、一组模型参数和一组计算节点组成。

每一个计算数据流图都被构造成一个拓扑排序的节点列表,这些节点必须没有循环。每个节点表示对算子operator的调用。每个节点有零个或多个输入和一个或多个输出。

图形具有以下属性:

开放式神经网络交换-ONNX(上)的更多相关文章

  1. 开放式神经网络交换-ONNX(下)

    开放式神经网络交换-ONNX(下) 计算节点由名称.它调用的算子operator的名称.命名输入的列表.命名输出的列表和属性列表组成. 输入和输出在位置上与算子operator输入和输出相关联.属性通 ...

  2. 开放神经网络交换(ONNX)工具

    开放神经网络交换(ONNX)工具 开放神经网络交换(ONNX)是一个开放的生态系统,它使人工智能开发人员能够在项目发展过程中选择正确的工具.ONNX为人工智能模型提供了一种开源格式,包括深度学习和传统 ...

  3. 深度学习与CV教程(6) | 神经网络训练技巧 (上)

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...

  4. RabbitMQ-从基础到实战(3)— 消息的交换(上)

    转载请注明出处 0.目录 RabbitMQ-从基础到实战(1)— Hello RabbitMQ RabbitMQ-从基础到实战(2)— 防止消息丢失 RabbitMQ-从基础到实战(4)— 消息的交换 ...

  5. [Deep-Learning-with-Python]神经网络入手学习[上]

    神经网络入手[上] [x] 神经网络的核心部分 [x] Keras介绍 [ ] 使用Keras解决简单问题:分类和回归 神经网络剖析 神经网络的训练与下列对象相关: 网络层Layers,网络层结合形成 ...

  6. 如何使用numpy实现一个全连接神经网络?(上)

    全连接神经网络的概念我就不介绍了,对这个不是很了解的朋友,可以移步其他博主的关于神经网络的文章,这里只介绍我使用基本工具实现全连接神经网络的方法. 所用工具: numpy == 1.16.4 matp ...

  7. Stanford CS231n实践笔记(课时14卷积神经网络详解 上)

    本课我们主要来研究一个"浏览器中的卷积神经网络" 这只是一个展示项目,但是能够帮助直观地看到一些东西 地址:https://cs.stanford.edu/people/karpa ...

  8. 微软推出了Cloud Native Application Bundles和开源ONNX Runtime

    微软的Microsoft Connect(); 2018年的开发者大会 对Azure和IoT Edge服务进行了大量更新; Windows Presentation Foundation,Window ...

  9. ONNX MLIR方法

    ONNX MLIR方法 MLIR中的开放式神经网络交换实现. Prerequisites gcc >= 6.4 libprotoc >= 3.11.0 cmake >= 3.15.4 ...

随机推荐

  1. hdu2433 spfa+mark[x][u][v]优化

    题意:           删除每一条边求最短路的和,每删除一个就输出一个和.    思路:         直接暴力可定TLE了,自己SB的尝试过,就要剪纸,当每次输出一个答案的时候我们没有必要再从 ...

  2. hdu4971 流-最大权闭包

    题意:       给了一些任务,然后给了一些完成某些任务的限制,然后又给了限制之间的拓扑关系,最后问你最大收益. 思路:       很直白,就是流的一个应用,最大权闭包,没涉及到什么想法的地方,建 ...

  3. POJ1789简单小生成树

    题意:       给你一些车牌号,然后另一两个车牌号之间的权值就是这两个字符串之间相同位置不同字母的个数,然后求最小生成树. 思路:       裸题,不解释了. #include<stdio ...

  4. 混部之殇-论云原生资源隔离技术之CPU隔离(一)

    作者 蒋彪,腾讯云高级工程师,10+年专注于操作系统相关技术,Linux内核资深发烧友.目前负责腾讯云原生OS的研发,以及OS/虚拟化的性能优化工作. 导语 混部,通常指在离线混部(也有离在线混部之说 ...

  5. 线程本地存储(动态TLS和静态TLS)

    线程本地存储(TLS) 对于多线程应用程序,如果线程过于依赖全局变量和静态局部变量就会产生线程安全问题.也就是一个线程的使用全局变量可能会影响到其他也使用此全局变量的线程,有可能会造成一定的错误,这可 ...

  6. 自定义WPF分页控件

    一.分页控件功能说明 实现如上图所示的分页控件,需要实现一下几个功能: 可以设置每页能够展示的最大列数(例如每页8列.每页16列等等). 加载的数组总数量超过设置的每页列数后,需分页展示. 可以直接点 ...

  7. Windows下 MySQL慢查询配置修改

    在剖析服务器性能的过程中,慢查询是一个很好的工具. 我们可以通过设置slow_query_log来开启慢查询日志,long_query_time属性来设置慢查询定义阈值,设置slow_query_lo ...

  8. Python自动扫描出微信不是好友名单

    前言 最近找几个老友准备聊天发现几个已经被删除好友名单,做为潜水党多年的我已经不知道成为多少人的黑名单,但是好友列表却依然有不是好友的名单,面对庞大的好友数量想要清除谈何容易.虽然可以发消息给所有人, ...

  9. RTTI之dynamic_cast运算符

    #include <iostream> #include <cstdlib> #include <ctime> using std::cout; class Gra ...

  10. mysql注入getshell

    0x00 利用条件 root权限 secure_file_priv=为空或者在网站根目录下(网站根目录为d:\www,secure_file_priv=d:\也可以) 知道绝对路径 gpc关闭,这个应 ...