开放式神经网络交换-ONNX(上)
開放式神經(jīng)網(wǎng)絡(luò)交換-ONNX(上)
目的
本文檔包含ONNX語義的規(guī)范性規(guī)范。
“onnx”文件夾下的.proto和.proto3文件構(gòu)成了用協(xié)議緩沖區(qū)定義語言編寫的語法規(guī)范。.proto和.proto3文件中的注釋目的是提高這些文件的可讀性,但如果它們與本文檔沖突,則不具有規(guī)范性。此類沖突應(yīng)報告為文檔錯誤。
模型驗證說明
有一個工具可以根據(jù)此規(guī)范執(zhí)行模型的一般驗證。它在C++中用Python命令行package實(shí)現(xiàn)。
本文件及所有相關(guān)文件中的語言說明:
在本文件中使用SHOULD、MUST、MAY等與RFC 2119一致。
“l(fā)ist”的使用應(yīng)表示項目的有序集合,“set”應(yīng)表示唯一元素的無序集合,“bag”表示可能非唯一元素的無序集合。
Components
ONNX is an open specification that consists of the
following components:
A definition of an extensible computation graph model. Definitions of standard data types.
Definitions of built-in operators.
其中#1和#2包含在本文中;內(nèi)置操作器在本文檔末尾列出的文檔中單獨(dú)介紹。具體來說,內(nèi)置算子operator被劃分為一組原始算子operator和函數(shù)。函數(shù)是一種算子operator,其語義通過使用其他算子operator(和函數(shù))擴(kuò)展到子圖(稱為函數(shù)體)中來正式表示。就功能而言,與ONNX兼容的框架或運(yùn)行時可以內(nèi)聯(lián)函數(shù)來執(zhí)行它,如果它沒有相應(yīng)的函數(shù)實(shí)現(xiàn)。
有兩個官方的ONNX變體;兩者之間的主要區(qū)別在于支持的類型和默認(rèn)的算子operator集。只有神經(jīng)網(wǎng)絡(luò)的ONNX變體只識別張量作為輸入和輸出類型,而經(jīng)典的機(jī)器學(xué)習(xí)擴(kuò)展ONNX-ML也識別序列和映射。ONNX-ML用非神經(jīng)網(wǎng)絡(luò)的ML算法擴(kuò)展了ONNX算子集。
直到IR版本6,ONNX規(guī)范和模型格式只處理推理(也稱為評分)。從IR版本7開始,ONNX規(guī)范和模型格式已擴(kuò)展到支持訓(xùn)練。ONNX訓(xùn)練模型本身是推理模型的一個擴(kuò)展,允許只進(jìn)行推理的runtime忽略與訓(xùn)練相關(guān)的擴(kuò)展并運(yùn)行推理。然而,在典型的使用場景中,與訓(xùn)練模型相比,僅推理模型可以實(shí)現(xiàn)更優(yōu)化的模型表示(用于推理目的)。
runtime不可知
ONNX并不預(yù)先假設(shè)或暗示任何特定的運(yùn)行時實(shí)現(xiàn)方法。
例如,一個實(shí)現(xiàn)可以由一個解釋模型的富運(yùn)行時組成;
可以是一個代碼生成器,它將整個模型轉(zhuǎn)換為某些目標(biāo)編程語言的可執(zhí)行代碼;
可以是硬件實(shí)現(xiàn);
可以是其中兩個或三個的組合。
本規(guī)范中的任何內(nèi)容都不應(yīng)被解釋為主張一種實(shí)現(xiàn)方法勝過任何其他方法;
對具體實(shí)現(xiàn)的內(nèi)部工作原理的任何評論都應(yīng)解釋為示例。
ONNX版本控制
ONNX中有幾個地方有版本控制功能——IR(中間表示)規(guī)范本身、模型版本和算子operator集版本。此外,每一個單獨(dú)的算子operator都指明它是在哪個版本的包含算子operator集中引入或穩(wěn)定的。
版本號可以用作簡單的數(shù)字,也可以用于對語義版本進(jìn)行編碼。如果使用semver,慣例是使用兩個最高有效字節(jié)作為主要編號,下兩個字節(jié)用于次要編號,最低有效的四個字節(jié)用于構(gòu)建/錯誤修復(fù)build/bugfix編號。使用semver版本控制時,至少有一個主/輔編號必須為非零。
IR規(guī)范對其版本使用簡單的單調(diào)遞增數(shù)。有效的IR版本由枚舉定義,該枚舉當(dāng)前具有以下值:
// 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集及其在特定時間點(diǎn)的語義的快照。
本規(guī)范沒有提供關(guān)于模型生產(chǎn)者應(yīng)該使用什么版本控制方案的指導(dǎo)。
有關(guān)IR、算子operator集和模型版本控制的約定和最佳實(shí)踐的更多詳細(xì)信息,請參閱版本控制。
可擴(kuò)展計算圖模型
ONNX指定計算圖的可移植、序列化格式。它不一定是框架選擇的在內(nèi)部使用和操作計算的形式。例如,如果在優(yōu)化過程中操作更有效,則實(shí)現(xiàn)可能在內(nèi)存中以不同的方式表示模型。
一個實(shí)現(xiàn)可以通過添加表示語義的算子operator來擴(kuò)展ONNX,這些算子operator超出了所有實(shí)現(xiàn)必須支持的標(biāo)準(zhǔn)算子operator集。其機(jī)制是將算子operator集添加到依賴于擴(kuò)展算子operator的模型中的opset_import屬性。
模型Models
頂層ONNX構(gòu)造是一個“Model”,在協(xié)議緩沖區(qū)中表示為類型onnx.ModelProto
模型結(jié)構(gòu)的主要目的是將元數(shù)據(jù)與包含所有可執(zhí)行元素的圖形相關(guān)聯(lián)。元數(shù)據(jù)是在第一次讀取模型文件時使用的,它為實(shí)現(xiàn)提供了所需的信息,以確定它是否能夠執(zhí)行模型、生成日志消息、錯誤報告等。此外,元數(shù)據(jù)對工具(如IDE和模型庫)很有用,它需要它來告訴人類一個給定模型的目的和特性。
每個模型都有以下組件:
模型必須指定一個域,并根據(jù)負(fù)責(zé)組織的標(biāo)識使用反向域名,這與傳統(tǒng)上用于命名Java包的約定相同。
注意:檢測ONNX文件
可以使用協(xié)議緩沖區(qū)分發(fā)中的Protocol工具檢查ONNX文件的內(nèi)容,方法如下:
$ 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.
模型語義
推理模型的語義是一個無狀態(tài)函數(shù)(除了用于隨機(jī)數(shù)生成的狀態(tài))。因此,每當(dāng)一個推理模型(沒有隨機(jī)的生成器操作)被用于對同一輸入執(zhí)行推理時,它都會產(chǎn)生相同的輸出。
訓(xùn)練模型的語義是有狀態(tài)對象的語義,狀態(tài)由訓(xùn)練權(quán)重的當(dāng)前值組成(以及學(xué)習(xí)算法所需的任何其他輔助狀態(tài),例如動量)。具體地說,它的語義是通過三種方法獲取的:初始化方法(用于初始化或重置狀態(tài)變量的值)、訓(xùn)練步驟方法(使用一批輸入輸出對進(jìn)行訓(xùn)練)和一種推理方法,該方法利用學(xué)習(xí)到的權(quán)重的當(dāng)前值進(jìn)行推理。前兩個方法更新對象的狀態(tài),而第三個方法沒有副作用。
可選元數(shù)據(jù)
模型中的“metadata_props”字段可用于工具或模型開發(fā)人員選擇放置在其中的任何類型的可選元數(shù)據(jù)。以下是定義的模型的“標(biāo)準(zhǔn)”可選元數(shù)據(jù)屬性。
算子operator
每個模型都必須顯式地命名其功能所依賴的算子operator。算子operator定義可用算子operator及其版本。每個模型按其域定義導(dǎo)入的算子operator。所有模型都隱式導(dǎo)入默認(rèn)的ONNX算子operator。
每個算子operator應(yīng)在單獨(dú)的文檔中定義,并使用protobuf作為序列化格式。如何在運(yùn)行時找到算子operator文檔取決于實(shí)現(xiàn)。
注:截至本文檔的發(fā)布,還沒有任何ONNX實(shí)現(xiàn)用于處理操作文檔。
算子operator的屬性包括:
算子operator版本是一個簡單的整數(shù)值,隨著新版本的算子operator的發(fā)布,該值單調(diào)增加。
默認(rèn)算子operator以外的算子operator必須指定其域,并應(yīng)根據(jù)負(fù)責(zé)組織的標(biāo)識使用反向域名,這與用于命名Java包的約定相同。
算子operator
圖中使用的每個算子operator必須由模型導(dǎo)入的算子operator之一顯式聲明。
算子operator定義的屬性包括:
版本值必須與首次發(fā)布算子operator時的算子operator版本值相同。算子operator的后續(xù)版本一旦發(fā)布為穩(wěn)定版本,則不得更改算子operator的簽名或語義。
“status”屬性指示算子operator的語法、語義或存在是否處于實(shí)驗階段或穩(wěn)定階段。一旦一個算子operator被發(fā)布為穩(wěn)定的,它的語法和語義在算子operator集的后續(xù)版本中就不能改變。
有兩種不同的方法將信息傳遞給算子operator–輸入和屬性。后者用于表示圖中常量的值,而前者表示圖形輸入或在圖中其他地方計算的值。這種區(qū)別可能與某些實(shí)現(xiàn)的良好性能密切相關(guān),而與其他實(shí)現(xiàn)完全無關(guān)。 圖
圖用于描述無副作用的計算(函數(shù))。序列化圖由一組元數(shù)據(jù)字段、一組模型參數(shù)和一組計算節(jié)點(diǎn)組成。
每一個計算數(shù)據(jù)流圖都被構(gòu)造成一個拓?fù)渑判虻墓?jié)點(diǎn)列表,這些節(jié)點(diǎn)必須沒有循環(huán)。每個節(jié)點(diǎn)表示對算子operator的調(diào)用。每個節(jié)點(diǎn)有零個或多個輸入和一個或多個輸出。
圖形具有以下屬性:
ValueInfo has the following properties:
版本值必須與首次發(fā)布算子operator時的算子operator版本值相同。
算子operator的后續(xù)版本一旦發(fā)布為穩(wěn)定版本,則不得更改算子operator的簽名或語義。
“status”屬性指示算子operator的語法、語義或存在是否處于實(shí)驗階段或穩(wěn)定階段。一旦一個算子operator被發(fā)布為穩(wěn)定的,它的語法和語義在算子operator的后續(xù)版本中就不能改變。
有兩種不同的方法將信息傳遞給算子operator–輸入和屬性。后者用于表示圖中常量的值,而前者表示圖形輸入或在圖中其他地方計算的值。這種區(qū)別可能與某些實(shí)現(xiàn)的良好性能密切相關(guān),而與其他實(shí)現(xiàn)完全無關(guān)。
圖
圖用于描述無副作用的計算(函數(shù))。序列化圖由一組元數(shù)據(jù)字段、一組模型參數(shù)和一組計算節(jié)點(diǎn)組成。
每一個計算數(shù)據(jù)流圖都被構(gòu)造成一個拓?fù)渑判虻墓?jié)點(diǎn)列表,這些節(jié)點(diǎn)必須沒有循環(huán)。每個節(jié)點(diǎn)表示對算子operator的調(diào)用。每個節(jié)點(diǎn)有零個或多個輸入和一個或多個輸出。
圖形具有以下屬性:
總結(jié)
以上是生活随笔為你收集整理的开放式神经网络交换-ONNX(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开放神经网络交换(ONNX)工具
- 下一篇: 开放式神经网络交换-ONNX(下)