導(dǎo)讀
Facebook與微軟聯(lián)合推出了一種開放式的神經(jīng)網(wǎng)絡(luò)切換格式——ONNX,它是一種表征深度學(xué)習(xí)模型的標(biāo)準(zhǔn),可以實(shí)現(xiàn)模型在不同框架之間進(jìn)行遷移。
ONNX 的全稱為“Open Neural Network Exchange”,即“開放的神經(jīng)網(wǎng)絡(luò)切換”。顧名思義,該項(xiàng)目的目的是讓不同的神經(jīng)網(wǎng)絡(luò)開發(fā)框架做到互通互用。目前,ONNX 已經(jīng)得到 PyTorch、Caffe2、CNTK、MXNet 以及包括 Intel、ARM、Huawei、高通、AMD、IBM 等芯片商的支持。
按照該項(xiàng)目的設(shè)想,ONNX 的推出主要是為了解決當(dāng)下AI生態(tài)系統(tǒng)的關(guān)鍵問題之一:開發(fā)框架的碎片化?,F(xiàn)在有大量的不同框架用來構(gòu)建和執(zhí)行神經(jīng)網(wǎng)絡(luò),還有其他的機(jī)器學(xué)習(xí)系統(tǒng),但是它們之間不盡相同,而且無法協(xié)同運(yùn)行。
AI的開發(fā)技術(shù)主要是深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò),而神經(jīng)網(wǎng)絡(luò)訓(xùn)練和推理通常采用一種主流的深度學(xué)習(xí)框架。目前,主流的框架有如下這些:
- TensorFlow(Google)
- Caffe/Caffe2(Facebook)
- CNTK(Microsoft)
- MXNet(Amazon主導(dǎo))
- PyTorch(Facebook主導(dǎo))
不同的框架有不同的優(yōu)勢(shì),但是框架之間的互通性并不好,甚至沒有互通性。開發(fā)AI模型時(shí),工程師和研究人員有很多的AI框架可以選擇,但是并不能“一次開發(fā),多處直接使用”。面對(duì)不同的服務(wù)平臺(tái),往往需要耗費(fèi)大量的時(shí)間把模型從一個(gè)開發(fā)平臺(tái)移植到另一個(gè),讓開發(fā)者苦不堪言。因此增強(qiáng)框架之間的互通性變的非常重要,例如:
- 情況1:某個(gè)框架的某個(gè)模型不管是準(zhǔn)確度還是性能都非常好,但是和軟件整體的架構(gòu)不相符;
- 情況2:由于框架A表現(xiàn)很好,用它訓(xùn)練了一個(gè)神經(jīng)網(wǎng)絡(luò),結(jié)果生產(chǎn)環(huán)境中使用的是框架B,這就意味著你可能需要將框架A訓(xùn)練的神經(jīng)網(wǎng)絡(luò)移植到框架B支持的格式上。
但是如果使用ONNX,就可以消除這種尷尬,例如ONNX可以導(dǎo)出用PyTorch構(gòu)建的訓(xùn)練模型,并將它與Caffe2結(jié)合起來用于推理(詳細(xì)教程)。這對(duì)于研究階段使用PyTorch構(gòu)建模型,正式環(huán)境使用Caffe2的結(jié)構(gòu)非常合適,且省去了模型移植的時(shí)間成本和人力成本等。
目前支持ONNX的框架如下:
詳細(xì)支持情況,可查看Importing and Exporting from Frameworks中各項(xiàng)詳細(xì)說明。
ONNX 技術(shù)概括
根據(jù)官方介紹中的內(nèi)容,ONNX 為可擴(kuò)展的計(jì)算圖模型、內(nèi)部運(yùn)算器(Operator)以及標(biāo)準(zhǔn)數(shù)據(jù)類型提供了定義。每個(gè)計(jì)算圖以節(jié)點(diǎn)列表的形式組織起來,構(gòu)成一個(gè)非循環(huán)的圖。節(jié)點(diǎn)有一個(gè)或多個(gè)的輸入與輸出。每個(gè)節(jié)點(diǎn)都是對(duì)一個(gè)運(yùn)算器的調(diào)用。圖還會(huì)包含協(xié)助記錄其目的、作者等元數(shù)據(jù)信息。運(yùn)算器在圖的外部實(shí)現(xiàn),但那些內(nèi)置的運(yùn)算器可移植到不同的框架上。每個(gè)支持 ONNX 的框架將在匹配的數(shù)據(jù)類型上提供這些運(yùn)算器的實(shí)現(xiàn)。
概括的說就是,ONNX是在跟蹤分析AI框架所生成的神經(jīng)網(wǎng)絡(luò)在運(yùn)行時(shí)是如何執(zhí)行的,然后會(huì)利用分析的信息,創(chuàng)建一張可以傳輸?shù)耐ㄓ糜?jì)算圖,即符合ONNX標(biāo)準(zhǔn)的計(jì)算圖。雖然各個(gè)框架中的計(jì)算表示法不同,但是生成的結(jié)果非常相似,因此這樣的方式也是行得通的。
那么ONNX標(biāo)準(zhǔn)的推出,為研究者、給開發(fā)者帶來的意義是什么呢?
ONNX標(biāo)準(zhǔn)的意義
- 首當(dāng)其沖就是框架之間的互通性
開發(fā)者能夠方便的在不同框架之間切換,為不同的任務(wù)選擇最優(yōu)的工具。往往在研發(fā)階段需要的模型屬性和產(chǎn)品階段是不同的,而且不同的框架也會(huì)在特定的某個(gè)屬性上有所優(yōu)化,例如訓(xùn)練速度、對(duì)網(wǎng)絡(luò)架構(gòu)的支持、是否支持移動(dòng)設(shè)備等等。如果不在研發(fā)階段更換框架或者將研發(fā)階段的模型進(jìn)行移植,可能造成項(xiàng)目延遲等。ONNX解決了這個(gè)難題,使用ONNX支持的AI框架,則可以靈活選擇AI框架,方便的進(jìn)行模型切換。
- 共享優(yōu)化
芯片制造商不斷地推出針對(duì)神經(jīng)網(wǎng)絡(luò)性能有所優(yōu)化的硬件,如果這個(gè)優(yōu)化頻繁發(fā)生,那么把優(yōu)化整合到各個(gè)框架是非常耗時(shí)的事。但是使用ONNX標(biāo)準(zhǔn),開發(fā)者就可以直接使用優(yōu)化的框架了。
這次沒有Google
Google 是 TensorFlow 框架的核心主導(dǎo)者,而 TensorFlow 目前是業(yè)界的主流,是 GitHub 最受歡迎、生態(tài)體系健全度較高的框架。但是目前看來,TensorFlow 官方并沒有支持ONNX。但是社區(qū)已經(jīng)有了非官方的ONNX版TensorFlow,詳情可參考o(jì)nnx-tf。
如何使用
以下是根據(jù)ONNX官方教程,進(jìn)行的實(shí)踐和遇到的具體問題。Getting Started。
ONNX 的使用總體分為兩步:
模型的導(dǎo)出:將使用支持ONNX標(biāo)準(zhǔn)的AI框架訓(xùn)練的模型導(dǎo)出為ONNX格式;
模型的導(dǎo)入:將ONNX格式的模型導(dǎo)入到支持ONNX的另一個(gè)AI框架中。
這里我選擇模型導(dǎo)出的AI框架是:PyTorch,導(dǎo)出的模型是Apple Core ML所支持的mlmodel格式。
1. ONNX 安裝
本地環(huán)境:
- macOS High Sierra v10.13.1
- Python?2.7
- Xcode 9.1 command line tools
- conda 4.3.30
ONNX的安裝支持Binaries、Docker、Source三種方式,由于我本地常使用Anaconda,因此這里我使用Binaries方式 進(jìn)行安裝:
conda install -c conda-forge onnx
安裝完成后如下顯示:
2. coremltools 安裝
coremltools?的安裝較為簡(jiǎn)單,如果本地環(huán)境無誤,運(yùn)行如下指令:
pip install coremltools
即可完成安裝。
3. PyTorch 安裝
PyTorch?ONNX支持的版本目前僅支持從源碼Master分支安裝,因此如果你本機(jī)的環(huán)境中已經(jīng)安裝了PyTorch,可能需要重新安裝,安裝方法可見:From Source。
需要注意的是,在進(jìn)行安裝時(shí),需要將指令?MACOSX_DEPLOYMENT_TARGET=10.9 CC=clang CXX=clang++ python setup.py install?中的MACOSX_DEPLOYMENT_TARGET部分修改為當(dāng)前你設(shè)備安裝的macOS版本號(hào)。
PyTorch已經(jīng)更新了官網(wǎng)版本,已經(jīng)支持了ONNX,因此你可以直接使用官網(wǎng)的方式安裝了。【注意:如果本地已經(jīng)安裝過了,使用此方法安裝后,需要重新安裝TorchVision (conda install torchvision -c pytorch),否則部分功能可能不能使用。】
3. 模型算法選擇
這里選擇的是PyTorch中的一個(gè)示例模型算法Super-resolution?進(jìn)行實(shí)踐。
Super-resolution(超分辨率)技術(shù)是指由低分辨率(LR, low-resolution)的圖像或圖像序列恢復(fù)出高分辨率(HR, high-resolution)的技術(shù),其原理可參考圖像超分辨率技術(shù)(Image Super Resolution)中的介紹。?Super-resolution(超分辨率)核心思想是用時(shí)間分辨率(同一場(chǎng)景的多幀圖像序列)換成更高的空間分辨率,實(shí)現(xiàn)時(shí)間分辨率向空間分辨率的轉(zhuǎn)換,論文地址。
在本文中,將使用一個(gè)具有虛擬輸入的小型超分辨率模型。
本文主要是講解如何使用ONNX進(jìn)行模型轉(zhuǎn)換,對(duì)于具體的技術(shù)原理可參考文中鏈接。
4. 模型構(gòu)建
了解了相關(guān)的軟件安裝和模型之后,我們開始構(gòu)建Super-resolution模型網(wǎng)絡(luò),此部分內(nèi)容借鑒PyTorch examples中的實(shí)現(xiàn)。
# Super Resolution model definition in PyTorch
import torch.nn as nn
import torch.nn.init as init
class SuperResolutionNet(nn.Module):
????def __init__(self, upscale_factor, inplace=False):
????????super(SuperResolutionNet, self).__init__()
????????self.relu = nn.ReLU(inplace=inplace)
????????self.conv1 = nn.Conv2d(1, 64, (5, 5), (1, 1), (2, 2))
????????self.conv2 = nn.Conv2d(64, 64, (3, 3), (1, 1), (1, 1))
????????self.conv3 = nn.Conv2d(64, 32, (3, 3,), (1, 1), (1, 1))
????????self.conv4 = nn.Conv2d(32, upscale_factor ** 2, (3, 3), (1, 1), (1, 1))
????????self.pixel_shuffle = nn.PixelShuffle(upscale_factor)
????????self._initialize_weights()
????def _initialize_weights(self):
????????init.orthogonal(self.conv1.weight, init.calculate_gain('relu'))
????????init.orthogonal(self.conv2.weight, init.calculate_gain('relu'))
????????init.orthogonal(self.conv3.weight, init.calculate_gain('relu'))
????????init.orthogonal(self.conv4.weight)
????def forward(self, x):
????????x = self.relu(self.conv1(x))
????????x = self.relu(self.conv2(x))
????????x = self.relu(self.conv3(x))
????????x = self.pixel_shuffle(self.conv4(x))
????????return x
以上模型網(wǎng)絡(luò)構(gòu)件完成后,我們就可以創(chuàng)建一個(gè)模型了,例如:
torch_model = SuperResolutionNet(upscale_factor=3)
此模型的結(jié)構(gòu)如下:
SuperResolutionNet(
??(relu): ReLU()
??(conv1): Conv2d (1, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
??(conv2): Conv2d (64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
??(conv3): Conv2d (64, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
??(conv4): Conv2d (32, 9, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
??(pixel_shuffle): PixelShuffle(upscale_factor=3)
)
如果你不想自己再去訓(xùn)練模型,可以下載已經(jīng)構(gòu)建好的預(yù)訓(xùn)練模型權(quán)重文件pretrained model weights,進(jìn)行模型的構(gòu)建,例如:
import torch.utils.model_zoo as model_zoo
# 加載預(yù)訓(xùn)練模型權(quán)重文件
model_url = 'https://s3.amazonaws.com/pytorch/test_data/export/superres_epoch100-44c6958e.pth'
batch_size = 1 ???# 這里是一個(gè)隨機(jī)數(shù)(這了僅僅是為了演示使用,實(shí)際項(xiàng)目中需要調(diào)整)
# 使用權(quán)重文件初始化模型
torch_model.load_state_dict(model_zoo.load_url(model_url))
# 設(shè)置訓(xùn)練模式為False,因?yàn)槲覀儍H使用正向傳播的方式
torch_model.train(False)
訓(xùn)練后,得到的模型結(jié)構(gòu)同上。
5. 模型導(dǎo)出為ONNX格式
上面通過構(gòu)建模型的過程,我們已經(jīng)得到了模型,為了能夠?qū)⒋四P褪褂迷贑ore ML框架中,首先需要將此模型導(dǎo)出為ONNX標(biāo)準(zhǔn)格式的模型文件。關(guān)于PyTorch中如何導(dǎo)出ONNX格式的模型文件,可以參考torch.onnx中的說明和示例。
簡(jiǎn)單的說,在PyTorch中要導(dǎo)出模型是通過跟蹤其工作的方式進(jìn)行的。要導(dǎo)出模型需要調(diào)用 torch.onnx._export()?函數(shù),此函數(shù)將會(huì)記錄模型中的運(yùn)算符用于計(jì)算輸出的軌跡,另外此函數(shù)需要一個(gè)輸入張量 x,可以是一個(gè)圖像或一個(gè)隨機(jī)張量,只要它是正確的大小即可。
import torch.onnx
from torch.autograd import Variable
# 張量 `x` 大小確定
x = Variable(torch.randn(batch_size, 1, 224, 224), requires_grad=True)
# 導(dǎo)出模型
torch_out = torch.onnx._export(
????torch_model, ??# 模型對(duì)象
????x, ????# 模型輸入(或多元輸入的元組)
????"onnx-model/super_resolution.onnx", ?# 保存文件的路徑(或文件對(duì)象)
????export_params=True) ?# 是否存儲(chǔ)參數(shù)(True:將訓(xùn)練過的參數(shù)權(quán)重存儲(chǔ)在模型文件中;False:不存儲(chǔ))
torch_out?是執(zhí)行模型后的輸出。通常情況下可以忽略這個(gè)輸出,但是在這里我們將使用它來驗(yàn)證在Core ML中運(yùn)行導(dǎo)出的模型是否和此值具有計(jì)算相同的值。
6. 轉(zhuǎn)換ONNX格式到Core?ML支持的mlmodel格式
6.1 安裝轉(zhuǎn)換工具onnx-coreml
首先我們要安裝能夠?qū)NNX標(biāo)準(zhǔn)格式的模型轉(zhuǎn)換為Apple Core?ML格式的工具onnx-coreml。安裝指令如下:
pip install ?onnx-coreml
安裝完成后,就可以使用此工具將ONNX標(biāo)準(zhǔn)格式的模型轉(zhuǎn)換為Apple Core?ML格式了。
6.2 加載ONNX格式模型文件
在開始之前,需要先使用ONNX加載之前導(dǎo)出的ONNX格式模型文件到對(duì)象中:
import onnx
model = onnx.load('super_resolution.onnx')
6.3 轉(zhuǎn)換模型到CoreML
由于我們安裝了ONNX 到Core ML的轉(zhuǎn)換工具,因此我們可以直接使用其中的 convert()?函數(shù)轉(zhuǎn)換模型:
import onnx_coreml
cml = onnx_coreml.convert(model)
print type(cml)
cml.save('coreml-model/super_resolution.mlmodel')
這里的cml是格式轉(zhuǎn)換后的coreml model對(duì)象,調(diào)用其save()方法即可將轉(zhuǎn)換后的對(duì)象存儲(chǔ)文件,即得到Core ML支持的模型文件。
有了這個(gè)mlmodel格式的模型文件后,我們就可以將其應(yīng)用在 Core ML中進(jìn)行推理了,這里不再進(jìn)行此部分的描述,具體使用方法可參考Apple官方給出的mlmodel模型文件相關(guān)的使用示例,Integrating a Core ML Model into Your App。
總結(jié)
目前,ONNX所支持的AI框架和工具還較少,已經(jīng)能夠看出,ONNX的推出無疑是對(duì)整個(gè)AI研究和開發(fā)領(lǐng)域極大的福祉。不遠(yuǎn)的將來,當(dāng)大多數(shù)的AI框架和工具都支持ONNX標(biāo)準(zhǔn)的時(shí)候,就不會(huì)發(fā)生為了選擇生產(chǎn)環(huán)境的AI框架而重新學(xué)習(xí)、為了能夠生產(chǎn)環(huán)境應(yīng)用模型而耗時(shí)移植模型等等類似的事件了。減少了開發(fā)人員消耗在移植過程中的時(shí)間,增加了鉆研算法和開發(fā)更令人興奮的AI應(yīng)用的時(shí)間,相信每個(gè)開發(fā)者和研究者都盼望著這個(gè)時(shí)期的到來。文章來源:http://www.zghlxwxcb.cn/news/detail-788618.html
補(bǔ)充:如果文章中有些鏈接打不開需要梯子,日常工作,會(huì)經(jīng)常遇到一些技術(shù)問題或者查詢一些資料,某度的查詢結(jié)果沒有某歌的好,強(qiáng)烈推薦某歌,某歌目前需要梯子,推薦一個(gè)梯子,可以注冊(cè)試用:點(diǎn)擊文章來源地址http://www.zghlxwxcb.cn/news/detail-788618.html
參考資料
- Facebook and Microsoft introduce new open ecosystem for interchangeable AI frameworks
- Microsoft and Facebook create open ecosystem for AI model interoperability
- ONNX
- Core ML
- PyTorch
- Announcing ONNX Support for Apache MXNet
到了這里,關(guān)于AI模型互通的新開放生態(tài)系統(tǒng)ONNX介紹與實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!