神经网络的交换格式(1-2)

(本文翻译自NNEF,著作权归原作者所有)

1.引言

1.1什么是NNEF

1.1.1输出者对NNEF的看法
对于NNEF的输出者,比如深度学习框架,NNEF是一种可以转换内部网络表示的格式,之后所有能够使用NNEF的加速器库将能够执行训练好的网络(如果网络 匹配其功能)。 输出者的任务是将其操作和数据表示映射到NNEF的操作和数据表示,假定这种映射是可能的。

NNEF还旨在成为深度学习操作的精选集,这些操作在成功的神经架构中广为流传。 它是研究Caffe,Torch,Theano,TensorFlow,CNTK,Chainer等开源深度学习框架的结果,并且抽象出它们共同的计算和数据结构。 它主要集中在可能高效地在各种目标硬件上执行的操作,例如大规模并行操作,尤其是需要本地集中的输入数据子集来计算输出的“本地”操作。

1.1.2输入者对NNEF的看法
神经网络加速器库(及其底层硬件)等NNEF的导入程序能够导入一个NNEF文件,并将其编译为内部表示以准备执行。 此编译可能会在离线或在线进行。 在离线编译期间,可以将NNEF转换为优化的,特定于硬件的表示格式,可以保存并稍后快速加载执行。 在线编译期间,可能会发生转换和优化,而不会将其保存为硬件特定格式,而是立即执行转换后的网络。

NNEF将操作收集到组中以指示操作的相关性。这可以作为硬件实现的提示或指导,因为相关的操作可能需要类似的硬件能力。

1.1.3应用程序员对NNEF的看法
对于应用程序员来说,NNEF是存储和传输神经网络的标准方法。 给定NNEF格式的神经网络,以及能够导入它的驱动程序或库,应用程序员不需要担心网络来自何处,或者底层硬件会执行它,只要它能够 这样做。 应用程序员可以查询底层硬件的驱动程序是否能够执行给定的网络。

1.1.4 NNEF不是什么
NNEF不是一个API(应用程序编程接口)。 它没有定义神经网络的执行模型,因此它没有定义正确执行NNEF中描述的神经网络的意义。 虽然它确实定义了操作的语义,假设无限的算术,定义正确执行的实际实现将需要有限的算术和基本的表示,这是超出了NNEF的范围。

生产或消费NNEF的库可能有各种API。 然而,对于应用程序员来说,重要的是有意执行神经网络的NNEF消费者很可能具有导入和编译NNEF中描述的网络的功能,并且随后向该网络提供数据。 但是,这个API的确切性质超出了NNEF的范围。 OpenVX Khronos标准的神经网络扩展以及神经网络的执行模型描述了一个这样的API。

1.2规范术语

在本文档中必须,必须,应该推荐,可以和可选择的关键词按照RFC 2119中的描述进行解释:[http://www.ietf.org/rfc/rfc2119.txt]

must
当单独使用时,这个词或所需的术语意味着定义是规范的绝对要求。如果后面跟着not(“must not”),那么这个短语就意味着这个定义绝对禁止了这个规范。

should
当单独使用时,这个词意味着在特殊情况下可能存在一些无效的理由来忽略某个特定的项目,但是在选择不同的课程之前,必须理解并仔细权衡全部含义。 如果后面跟着not(“should not”),那么这个短语就意味着在某些特定的行为是可以接受的甚至是有用的情况下,可能存在一些合理的理由,但是在实现任何描述的行为之前,应该理解全部含义并仔细权衡 与这个标签。 在语法上合适的情况下,可以使用术语推荐或推荐来代替应用。

may
这个词,或可选的形容词,意味着一个东西是真正的可选项。 一个供应商可能会选择包含该项目,因为特定的市场需要它,或者因为供应商认为它增强了产品,而另一个供应商可能省略相同的项目。 不包含特定选项的实现必须准备好与另一个包含该选项的实现进行交互操作,但可能会降低功能。 同样,包含特定选项的实现必须准备好与另一个不包含选项的实现(当然,该选项提供的特性除外)进行交互操作。

此外can 和 cannot被解释如下:

can
这个词意味着所描述的特定行为是应用程序的有效选择,并且从未被用于指代实现行为。

cannot
这个词意味着某个特定的行为描述是无法通过一个应用来实现的。

本规范中使用的“cannot”与“must not”之间有一个重要的区别。 cannot意味着字面意义上无法表达的东西,而must not意味着字面意义能够表达的东西,但是这样做的后果是未定义的,并且可能造成不可预计的后果。

2.基础

本章介绍基本概念,包括计算图,运算和张量,NNEF语法和数据描述。 它提供了一个框架来解释本规范其余部分中有关操作和网络体系结构的更具体的描述。

2.1计算图

神经网络可以用计算图来描述。 计算图是有向图,有两类节点:数据节点和操作节点。 从数据节点到操作节点的有向边意味着操作将数据作为其输入,而从操作节点到数据节点的有向边意味着操作产生数据作为其输出。 不允许从数据节点到数据节点或从操作节点到操作节点的边缘。

作为一个例子,一个简单的多层前馈网络可以用一个线性图来描述,从一个输入数据节点开始,每个层对应一个操作节点,产生一个新的中间数据节点,同时把之前的(中间)数据作为 输入,最后产生一些输出数据。

数据节点代表称为张量的多维数组(例如向量,矩阵或高维数组)。 计算从不是任何操作结果的数据节点(如输入和张量常量)开始。 为了使描述一致,这些数据节点是特殊张量声明操作的结果。 因此,整个计算图由一组操作来描述,由数据节点互连。

图1.示例计算图:正方形表示张量数据(E:外部,C:常数,V:变量,T:常规张量),椭圆表示操作

计算图描述了神经网络计算的单个步骤,也就是说,对单个输入(或单批输入)执行的计算被馈送到该图。 这简单地描述了前馈网络,但并不是所有的网络都那么简单。 循环网络通过允许在一个步骤中计算的一些张量值在下一步中被使用来引入步骤之间的依赖关系,因此总体计算的结果依赖于一系列输入。 为了保持清晰和容易验证的描述,每个步骤的计算由非循环图来描述,循环网络所需的循环依赖的数量通过变量张量来实现,变量张量可以在每个步骤中被更新并保留 他们之间的值连续的步骤。 为了达到这个目的,引入了一个特殊的操作来更新变量张量(见变量更新)。

2.2数据描述

多维数组可以通过其维数及其在每个维度(其形状)的范围来描述。 从概念上讲,多维数组是无限维度的,不相关的(尾随)维度是范围1(以下称为单一维度)。 在这个描述中,我们没有限制维度的数量,并且将未明确描述的维度视为单例。 当然,实际上,一个实现限制了支持维度的数量。 支持的最小维数为2.维度从0开始索引。所有范围的乘积称为张量的体积(请注意,尾随单体维度不影响体积)。

在计算图中,每个张量必须有一个明确的形状。 外部操作,常量操作和变量操作明确地定义了结果的形状,从而为那些构成计算输入的张量提供了形状。 所有其他操作将其结果张量的形状定义为其输入张量形状的函数,这样通过计算图形来传播形状信息。

为了描述计算图的结构,不需要实际的数据。 但是,当要执行图形时,那些用作计算参数的张量需要实际数据,例如具有先前计算的值的变量。 因此,除了数据节点的结构方面,它们的实际数据也需要在某个地方定义。 规范引入了描述个体张量内容的二进制格式。

2.3操作描述

除了数据节点之外,计算节点可以具有详细描述所执行的精确计算的元参数。 计算节点具有定义明确的语义,它根据输入张量的输入张量指定输入到输出的映射,包括输出张量的形状和内容。

计算图可以以平面或组合的方式描述。 在构图描述中,操作可以用其他更简单的操作来表示。 因此,计算图的描述可以被组织成层次结构。 平面描述不会将操作分组为较大的单位。
NNEF图形描述语法可以分为两部分:平面描述所需的核心部分和描述复合操作的扩展部分。 在构成描述的情况下,操作分为两大类:
- 原语(primitive):无法用其他操作表达的操作
- 复合(compound):可以从其他操作构建的操作

复合操作仍然可以被认为是有效的平面描述,但是,它们也被视为原子基元。
下面是一个关于如何建立更大和更大的子图的图解说明,直到整个图被定义为止:

图2.复合片段和图形的分层构建

组合描述是有用的,因为它传达了图中的高阶结构,将频繁出现的子图分组。 这有利于简洁描述,传达比平面描述更多的信息,并且执行引擎可以利用这样的结构信息。 但是,构图描述更为复杂,难以编译。 因此,在平面描述足够的情况下,可以仅使用适当的NNEF语法子集。

在描述操作时,基元需要指定它们的输入 - 输出映射,包括它们执行的计算以及结果的形状和数据类型作为其输入的函数。 这些基本操作的语义由数学公式表示。 另一方面,复合操作是从原语构建的,它们的构建方式为它们提供了可以从原语派生的语义。 这样,整个计算图将具有明确定义的语义。

为了能够用其他操作(原语或复合词)来描述复合操作,使用程序符号。 流行的深度学习框架通常使用通用的脚本语言(如Python)。 图形结构的当前描述模仿这种脚本语言的简单子集,围绕图形片段构建建立,该图形片段构造允许根据其他较低级别的操作来指定参数化操作。 这种方法可以用来以紧凑的方式描述整个神经网络的图形。

2.4图描述和用法概述

这种格式的目的是描述一个可以最终执行的计算图,但是格式本身并没有定义执行模型,只是定义了图的结构和数据参数。 为了这样做,一个简单的文本格式描述了计算图的结构方面。 伴随该文本格式是描述计算图的外部张量参数的数据存储格式。

本文件结构如下。 Chapter Formal Description详细说明了文本格式的语法和语义。 章节操作描述了一系列可以构建计算图形的基元和复合操作,以及它们的参数化和语义。 存储网络数据的章节描述了存储网络权重的二进制格式。

为了更清楚地了解如何使用这种格式,我们描述了如何将这些部分组合在一起来编译和执行计算图。

2.4.1图编译和执行
- 一个字节流(文本)将计算图形描述为一系列操作。
计算图的编译从下面开始:
- 包含序列化外部张量参数数据的可选字节流(二进制)到图中。 在概念层面上,编译过程可能有以下几个步骤:
- 解析结构描述,按照形式描述中的规则检查其有效性。
- 如果描述是合成的,则通过评估元参数的编译时表达式来将操作的层次结构扩展为基元,从而产生扁平的结构。
- 传播张量形状和数据类型,按操作中所述执行操作参数检查。

一个实现并不局限于编译一个在操作中列出的原始操作图,而是可以实现像复合操作那样的操作作为原子操作来提高效率。 在构建可执行图之后,实现可以优化它,例如通过移除中间缓冲区和不必要的操作或合并操作序列。

编译过程之后,图形执行可能有以下步骤:
- 加载以前的序列化数据或将初始值传递给声明为变量的张量。
- 在每个循环中,张量的馈送值被声明为外部输入,执行所需的操作,读出输出。
- 如有必要保存更新的变量。

再次注意,交换格式没有定义正在描述的计算图的执行模型。以上只是如何使用它的一个例子。

2.5专业术语

以下术语在规范中经常使用,并在此处明确列出:

复合操作(compound operation)
根据其他操作定义的操作。它的语义是通过它定义的操作的组合来定义的。

计算图
节点是操作或张量的图形。操作节点仅连接到张量节点,反之亦然。

图分段(graph fragment)
整个图(网络)中的一个子图。一个片段可以用一系列由张量互连的操作来描述。

图编译时间(graph compilation-time)
在执行之前构建图形的时间。类似于编程语言的编译时间。

图执行时间(graph execution-time)
建立后图形运行的时间(可能多次)。类似于编程语言的运行时间。

元参数(meta-parameter)
定义操作的更多细节的操作的非张量参数。元编译时可以使用元参数,因此可以在图编译时评估元参数表达式。

操作()
输入张量到输出张量的映射。

原语操作(primitive operation)
其他操作没有定义的操作。它的语义是通过数学公式定义的。

(张量的)等级
之后只有尾随奇异维度的维数。请注意,领先或中间奇异维度也计入等级,所以形状(1,5)具有等级2,而形状(5,1)仅具有等级1。

行主序
将矩阵的行 - 主数据布局推广到多维数组。 数据的排列顺序是:多维索引沿着最后维度变化最快,沿维度0变化最慢。请注意,该定义对于概念无限维数据也是有效的,因为尾随单独维度只在 概念上是无限的多指标。

(张量)的形状
定义张量在相关(非单一)维度上的范围的一列整数.

张量
代表图中数据流的多维标量数组。 维度的数量在概念上是无限的; 无足轻重的拖尾维度是1(单一维度)。 一个实现实际支持的最小维数是2。

张量变量(variable tensor)
张量的值可以通过指定的操作来更新。所有其他的张量在概念上是不可改变的;每个操作产生一个新的张量。

(张量的)体积
一个整数值,它是形状的乘积。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值