开放式神经网络交换-ONNX(下)
開放式神經網絡交換-ONNX(下)
計算節點由名稱、它調用的算子operator的名稱、命名輸入的列表、命名輸出的列表和屬性列表組成。
輸入和輸出在位置上與算子operator輸入和輸出相關聯。屬性通過名稱與算子operator屬性相關聯。
它們具有以下屬性:
屬于值命名空間的名稱可以出現在多個位置,即作為圖形輸入、圖形初始值設定項、圖形輸出、節點輸入或節點輸出。名稱作為圖形輸入、圖形初始值設定項或節點輸出的出現稱為定義(站點),名稱作為節點輸入或圖形輸出的出現稱為使用(站點)。
圖形中使用的值名稱必須具有唯一的定義站點,但圖形輸入列表和圖形初始值設定項列表中可能出現相同的名稱。(如后文所述,在存在嵌套子圖的情況下適用其他例外情況。) 當名稱同時出現在初始值設定項列表和圖形輸入列表中時,runtime可能允許調用者為此(輸入)名稱指定一個值,覆蓋在初始值設定項中指定的值,而runtime可能允許用戶忽略為此(輸入)名稱指定的值,選擇在初始值設定項中指定的值。不打算被調用方重寫的常量的名稱應只出現在初始值設定項列表中,而不應出現在圖形輸入列表中。在用作屬性值的嵌套子圖中,用戶不能同時使用與子圖初始值設定項和子圖輸入相同的名稱(除非相應的操作規范明確允許)。
計算圖中的邊是由一個節點的輸出建立的,該節點在隨后一個節點的輸入中被名稱引用。
給定節點的輸出將新名稱引入圖中。節點輸出值由節點的算子operator計算。節點輸入可以引用節點輸出、圖形輸入和圖形初始化器。當節點輸出的名稱與圖形輸出的名稱一致時,圖形輸出的值是該節點計算的相應輸出值。嵌套子圖中的節點輸入可以引用外部圖中引入的名稱(作為節點輸出、圖形輸入或圖形初始值設定項)。
圖形必須對所有節點輸出使用單個靜態賦值,這意味著在一個圖中所有節點輸出名稱都必須是唯一的。對于嵌套子圖,節點輸出名稱必須與嵌套子圖中可見的外部作用域的名稱不同。
節點依賴項不能在計算圖中創建循環。
節點中輸入和輸出的數量、類型、節點中指定的屬性集及其類型必須滿足節點算子operator簽名所施加的約束。
定義頂層計算圖的節點列表必須按拓撲排序;也就是說,如果圖中節點K跟在節點N之后,N的任何數據輸入都不能引用K的輸出。
節點屬性用于將文本(靜態)值傳遞給算子operator。
輸入和輸出值
這種表示法區分了兩種類型的值:靜態已知的屬性值和輸入/輸出值。兩種情況下允許的值類型不同。
輸入和輸出值作為圖形輸入、輸出和初始化器,以及節點輸入和輸出。它們的值由啟動模型執行的代碼或計算輸出值的運算符在運行時確定。
屬性
屬性值只在節點中找到,通過名稱關聯傳遞給運算符。屬性值是運行時常量,因為它們的值是在構建模型圖時確定的,因此不會在運行時計算。屬性的一個常見用法是表示在模型訓練期間建立的系數。
屬性具有以下屬性:
屬性“name”和“type”對于所有屬性都是必需的,并且“doc_string”應該用于所有屬性。屬性必須只有一個承載值的屬性。
可變輸入和輸出
運算符的最后一個輸入或輸出可以標記為可變的。例如,運算符“Max()”可用于計算不同數量輸入值的最大值。變量運算符有一個關聯的最小arity,它指定必須指定的操作數的最小數目。
對于每個變量運算符輸入,必須指定N個或多個節點輸入,其中N是運算符的最小arity。對于每個變量運算符輸出,必須指定N個或多個節點輸出,其中N是運算符的最小arity。
可選輸入和輸出
一些運算符具有標記為可選的輸入,這意味著引用節點可以放棄為此類輸入提供值。
有些運算符的輸出是可選的。當未指定運算符的實際輸出參數時,運算符實現可以放棄此類輸出的計算值。
有兩種方法可以不指定可選的輸入或輸出:第一種方法僅適用于尾隨的輸入和輸出,即不提供該輸入;第二種方法是使用空字符串代替輸入或輸出名稱。
引用具有可選輸出的運算符的每個節點必須為計算的每個輸出提供名稱,并且不能為未計算的輸出提供名稱。
外部張量數據
大型常量張量的原始數據,如初始值設定項,可以在單獨的文件中序列化。在這種情況下,張量必須提供相對于模型文件的文件名,并且不能使用值字段。它可以提供該文件中的字節偏移量和長度。它還可以指定文件的SHA1摘要。一個文件可能包含多個張量的數據。
更多詳細信息請參見ExternalData.md。
標準數據類型
有兩個官方的ONNX類型;兩者之間的主要區別在于支持的類型和支持的運算符。
對于支持的類型,ONNX定義只識別張量作為輸入和輸出類型,而經典的機器學習擴展。ONNX-ML還可以識別序列和地圖。
ONNX支持以下數據類型,用于圖形和節點的輸入和輸出,以及圖形的初始值設定項。
基本數值、字符串和布爾類型必須用作張量的元素。
張量元素類型
Input / Output Data Types
The following types are used to define the types of graph and node inputs and outputs.
ONNX當前沒有定義稀疏張量類型。
靜態張量shape
除了元素類型,張量類型還有一個靜態shape。張量變量的靜態shape與張量值的運行時(動態)shape相關,但不同。靜態張量shape是表示張量是向量、矩陣還是更高維值的記錄列表。例如,100x100矩陣的shape為[100100]。
靜態shape由“TensorShapeProto”定義:
message
TensorShapeProto {
message Dimension {
oneof value {int64 dim_value = 1;string dim_param = 2;};
};
repeated Dimension dim = 1;
}
Which is referenced by the Tensor type message:
message Tensor {
optional TensorProto.DataType elem_type =
1;
optional TensorShapeProto shape = 2;
維數大小的空列表[]是有效的張量shape,表示零維(標量)值。零維張量不同于未知維數的張量,它由張量記錄中缺少的“shape”屬性來表示。當值類型(包括節點輸入)中缺少shape屬性時,它指示相應的運行時值可以具有任何shape。本小節描述了如何解釋缺少的shape或缺少尺寸的shape等。但是,特定的使用上下文可能會對類型和shape施加進一步的約束。例如,模型(頂層圖)的輸入和輸出必須具有一個shape,指示輸入和輸出的等級,即使不需要指定確切的尺寸。
列表中的每個大小可以表示為整數值,也可以表示為“維數變量”(dimension variable),這是一個字符串,表示維數的實際大小沒有靜態約束到某個特定的數字。這對于聲明關心維數數量而不是每個維數的確切大小的接口非常有用。維數既不能設置維數值,也不能設置維數參數。這樣的維數表示與其他未知維數無關的未知維數。
例如,NxM矩陣將具有shape列表[N,M]。
每個維數變量的名稱必須符合C標識符語法。
當前,維數變量沒有范圍。維數變量“N”表示模型中整個圖形的相同值。例如,如果圖有兩個輸入X和Y,每個輸入都有shape[“N”],那么在運行時,為X和Y傳入的值必須是具有相同維數的秩1的張量。嵌套子圖當前與主圖共享相同的維數變量范圍。這使得模型能夠將子圖內部張量的維數與外部圖中張量的維數相關聯。
ONNXML支持更豐富的類型,比如張量序列。維數變量的全局作用域意味著類型為“Sequence<Tensor<float[M,N]>”的變量表示一系列具有相同shape的張量。如果維數在序列中的所有張量上沒有固定的大小,則必須從上述類型中省略維數變量M或N。如果序列中不同的張量可能具有不同的秩,則必須從類型中省略整個shape。
例如,執行矩陣叉積cross-product的圖可以定義為獲取形狀[K,M]和[M,N]的兩個輸入,并產生形狀[K,N]的輸出。
形狀可以使用整數和變量的組合來定義。
歷史記錄:早期考慮過以下擴展,但從未實現或支持。
使用空字符串(作為維度變量)來表示與任何其他維度無關的未知維度。為了使用既沒有dim_value也沒有dim_param集的維度,這一點被丟棄了。
使用字符串“*”(作為維度變量)來表示零個或多個未知基數維的序列。不支持此操作。在當前的實現中,形狀中的維數必須表示張量的秩。一個未知等級的張量用一個沒有形狀的TypeProto::tensor對象來表示,這是合法的。
允許子圖(如循環體)局部的維度變量的作用域機制可能有用,但目前不支持。
ONNXML支持更豐富的類型,比如張量序列。一個類型的局部維度變量的作用域機制可能有助于區分以下兩種類型:一個平方矩陣序列(大小不同)和一個方陣序列(大小相同)。目前不支持。
The use of an empty string (as a dimension variable) to denote an
unknown dimension not related to any other dimension. This was discarded
in favor of using a Dimension with neither dim_value nor dim_param set.
The use of the string “*” (as a dimension variable) to
denote a sequence of zero or more dimensions of unknown cardinality. This
is not supported. In the current implementation, the number of dimensions
in a shape MUST represent the rank of the tensor. A tensor of unknown rank
is represented using a TypeProto::Tensor object with no shape, which is
legal.
A scoping mechanism to allow dimension variables that are local to a
sub-graph (such as the body of a loop) may be useful, but is not currently
supported.
ONNXML supports richer types such as Sequences of Tensors. A scoping
mechanism for the dimension variables local to a type may be useful to
distinguish between the following two types: a sequence of square matrices
(of differing sizes) vs a sequence of square matrices (all of same size).
This is not currently supported.
屬性類型
用于屬性的類型系統與用于輸入和輸出的類型系統相關,但略有不同。屬性值可以是稠密張量、稀疏張量、標量數值、字符串、圖形或上述類型之一的重復值。
訓練相關信息
與訓練相關的信息由模型中包含的一個或多個TrainingInfoProto實例來描述。每個TrainingInfoProto都包含描述初始化步驟和訓練步驟的信息。
初始化步驟用圖形描述(訓練InfoProto.initialization)以及初始化綁定映射(TrainingInfoProto.initialization_綁定). 初始化步驟是通過計算圖來執行的,并將圖產生的輸出分配給初始化綁定中指定的訓練模型的狀態變量。初始化綁定在概念上是一個映射,指定為鍵-值對的列表,其中每個鍵是狀態變量的名稱,值是(初始化)圖的輸出的名稱。在綁定中指定為鍵的每個名稱必須是出現在主推理圖(即ModelProto.graph.initializer)或出現在中的初始值設定項的名稱TrainingInfoProto.algorithm.initializer.
在綁定中指定為值的每個名稱都必須是訓練InfoProto.initialization圖表。在重復初始化綁定字段中指定的鍵值必須是唯一的。
訓練步驟也類似地用圖表描述(模擬算法訓練)和更新綁定映射(TrainingInfoProto.update_綁定). 訓練步驟是通過計算圖并將圖產生的輸出分配給更新綁定中指定的狀態變量來執行的。上述初始化的約束和描述也適用于訓練步驟。
因此,訓練模型的狀態變量由主推理圖(i.e.,
ModelProto.graph.initializer)以及訓練算法圖(TrainingInfoProto.algorithm.initializer)由綁定的鍵標識(in
TrainingInfoProto.initialization_binding
and TrainingInfoProto.update_binding)。
請注意,在訓練環境中,狀態變量不是常數值。它們表示由多個圖共享的可變變量(在頂級訓練模型范圍內隱式聲明)。為了與推理圖表示法向后兼容,使用了共享可變變量的隱式聲明,而不是顯式聲明。
所有狀態變量都預先初始化為相應的初始值設定項中指定的值。執行初始化步驟的后續調用(使用運行時公開的適當API)將更新上述狀態變量的值。如果訓練模型不止一個TrainingInfoProto實例,則依次執行每個實例對應的初始化步驟。一個訓練TrainingInfoProto.initialization可以省略(僅當沒有初始化\u綁定時)。對于訓練步驟,運行時可能允許用戶調用模擬算法訓練,允許訓練過程根據需要交織不同的算法。不同的訓練原型算法被調用會影響訓練結果,調用者有責任按正確的順序調用它們。
其它規范文件
ONNX規范由定義IR語義和標準數據類型的文檔和定義標準運算符語義和IR語法的以下文檔組成。后者被指定為protobuf_v2和v3模式文件。
有關詳細信息,請參閱元數據類別文檔。
總結
以上是生活随笔為你收集整理的开放式神经网络交换-ONNX(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开放式神经网络交换-ONNX(上)
- 下一篇: CUDA 7 Stream流简化并发性