0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于ONNX結(jié)構(gòu)分析

FPGA創(chuàng)新中心 ? 來(lái)源:FPGA創(chuàng)新中心 ? 作者:FPGA創(chuàng)新中心 ? 2022-10-13 11:29 ? 次閱讀

Q

什么是ONNX?

ONNX(Open Neural Network Exchange)- 開(kāi)放神經(jīng)網(wǎng)絡(luò)交換格式,作為框架共用的一種模型交換格式,使用protobuf 二進(jìn)制格式來(lái)序列化模型,可以提供更好的傳輸性能我們可能會(huì)在某一任務(wù)中Pytorch或者TensorFlow模型轉(zhuǎn)化為ONNX模型(ONNX模型一般用于中間部署階段),然后再拿轉(zhuǎn)化后的ONNX模型進(jìn)而轉(zhuǎn)化為我們使用不同框架部署需要的類型,ONNX相當(dāng)于一個(gè)翻譯的作用。

Q

為什么要用ONNX?

深度學(xué)習(xí)算法大多通過(guò)計(jì)算數(shù)據(jù)流圖來(lái)完成神經(jīng)網(wǎng)絡(luò)的深度學(xué)習(xí)過(guò)程。一些框架(例如CNTK,Caffe2,Theano和TensorFlow)使用靜態(tài)圖形,而其他框架(例如PyTorch和Chainer)使用動(dòng)態(tài)圖形。但是這些框架都提供了接口,使開(kāi)發(fā)人員可以輕松構(gòu)建計(jì)算圖和運(yùn)行時(shí),以優(yōu)化的方式處理圖。這些圖用作中間表示(IR),捕獲開(kāi)發(fā)人員源代碼的特定意圖,有助于優(yōu)化和轉(zhuǎn)換在特定設(shè)備(CPUGPU,FPGA等)上運(yùn)行。假設(shè)一個(gè)場(chǎng)景:現(xiàn)在某組織因?yàn)橹饕_(kāi)發(fā)用TensorFlow為基礎(chǔ)的框架,現(xiàn)在有一個(gè)深度算法,需要將其部署在移動(dòng)設(shè)備上,以觀測(cè)變現(xiàn)。傳統(tǒng)地我們需要用Caffe2重新將模型寫(xiě)好,然后再訓(xùn)練參數(shù);試想下這將是一個(gè)多么耗時(shí)耗力的過(guò)程。此時(shí),ONNX便應(yīng)運(yùn)而生,Caffe2,PyTorch,Microsoft Cognitive Toolkit,Apache MXNet等主流框架都對(duì)ONNX有著不同程度的支持。這就便于我們的算法及模型在不同框架之間的遷移。

ONNX結(jié)構(gòu)分析

ONNX將每一個(gè)網(wǎng)絡(luò)的每一層或者說(shuō)是每一個(gè)算子當(dāng)作節(jié)點(diǎn)Node,再由這些Node去構(gòu)建一個(gè)Graph,相當(dāng)于是一個(gè)網(wǎng)絡(luò)。最后將Graph和這個(gè)ONNX模型的其他信息結(jié)合在一起,生成一個(gè)Model,也就是最終的.onnx的模型。構(gòu)建一個(gè)簡(jiǎn)單的ONNX模型,實(shí)質(zhì)上,只要構(gòu)建好每一個(gè)node,然后將它們和輸入輸出超參數(shù)一起塞到Graph,最后轉(zhuǎn)成Model就可以了。

graph{
    node{
        input: "1"
        input: "2"
        output: "12"
        op_type: "Conv"
    }
    attribute{
        name: "strides"
        ints: 1
        ints: 1
    }
    attribute{
        name: "pads"
        ints: 2
        ints: 2
    }
    ...
}

我們查看ONNX網(wǎng)絡(luò)結(jié)構(gòu)和參數(shù)(查看網(wǎng)址:https://netron.app/)

fe08343a-4a1a-11ed-a3b6-dac502259ad0.png

ONNX安裝、使用

安裝ONNX環(huán)境,在終端中執(zhí)行以下命令,環(huán)境中需要提前準(zhǔn)本 python3.6. 以下流程以u(píng)bunt 20.04 為例。

模型轉(zhuǎn)換流程

超分辨率是一種提高圖像、視頻分辨率的算法,廣泛用于圖像處理或視頻編輯。首先,讓我們?cè)赑yTorch中創(chuàng)建一個(gè)SuperResolution 模型。該模型使用描述的高效子像素卷積層將圖像的分辨率提高了一個(gè)放大因子。該模型將圖像的YCbCr的Y分量作為輸入,并以超分辨率輸出放大的Y分量。

# Some standard imports
import io
import numpy as np


from torch import nn
import torch.utils.model_zoo as model_zoo
import torch.onnx
# 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 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


    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)


# Create the super-resolution model by using the above model definition.
torch_model = SuperResolutionNet(upscale_factor=3)

1

模型下載

由于本教程以演示為目的,因此采用下載預(yù)先訓(xùn)練好的權(quán)重。在導(dǎo)出模型之前調(diào)用torch_model.eval()或torch_model.train(False)將模型轉(zhuǎn)換為推理模式很重要。因?yàn)閐ropout或batchnorm等運(yùn)算符在推理和訓(xùn)練模式下的行為不同。

# Load pretrained model weights
model_url = 'https://s3.amazonaws.com/pytorch/test_data/export/superres_epoch100-44c6958e.pth'
batch_size = 1    # just a random number


# Initialize model with the pretrained weights
map_location = lambda storage, loc: storage
if torch.cuda.is_available():
    map_location = None
torch_model.load_state_dict(model_zoo.load_url(model_url, map_location=map_location))


# set the model to inference mode
torch_model.eval()

2

模型導(dǎo)出

要導(dǎo)出模型,我們調(diào)用該torch.onnx.export()函數(shù)。這將執(zhí)行模型,記錄用于計(jì)算輸出的運(yùn)算符。因?yàn)閑xport運(yùn)行模型,我們需要提供一個(gè)輸入張量x。只要它是正確的類型和大小,其中的值可以是隨機(jī)的。請(qǐng)注意,除非指定為動(dòng)態(tài)軸,否則所有輸入維度的導(dǎo)出ONNX圖中的輸入大小將是固定的。在此示例中,我們使用batch_size 1的輸入導(dǎo)出模型,但隨后在dynamic_axes參數(shù)中將第一個(gè)維度指定為動(dòng)態(tài) torch.onnx.export() . 因此,導(dǎo)出的模型將接受大小為[batch_size, 1, 224, 224]的輸入,其中batch_size可以是可變的。

# Input to the model
x = torch.randn(batch_size, 1, 224, 224, requires_grad=True)
torch_out = torch_model(x)


# Export the model
torch.onnx.export(torch_model,               # model being run
                  x,                         # model input (or a tuple for multiple inputs)
                  "super_resolution.onnx",   # where to save the model (can be a file or file-like object)
                  export_params=True,        # store the trained parameter weights inside the model file
                  opset_version=10,          # the ONNX version to export the model to
                  do_constant_folding=True,  # whether to execute constant folding for optimization
                  input_names = ['input'],   # the model's input names
                  output_names = ['output'], # the model's output names
                  dynamic_axes={'input' : {0 : 'batch_size'},    # variable length axes
                                'output' : {0 : 'batch_size'}})

3

導(dǎo)出模型測(cè)試

在使用ONNX Runtime驗(yàn)證模型的輸出之前,我們將使用ONNX的 API檢查ONNX 模型。首先,onnx.load("super_resolution.onnx")將加載保存的模型并輸出 onnx.ModelProto結(jié)構(gòu)(用于捆綁 ML 模型的頂級(jí)文件/容器格式)。然后,onnx.checker.check_model(onnx_model)將驗(yàn)證模型的結(jié)構(gòu)并確認(rèn)模型具有有效的架構(gòu)。ONNX 圖的有效性通過(guò)檢查模型的版本、圖的結(jié)構(gòu)以及節(jié)點(diǎn)及其輸入和輸出來(lái)驗(yàn)證。

import onnx


onnx_model = onnx.load("super_resolution.onnx")
onnx.checker.check_model(onnx_model)


import onnxruntime


ort_session = onnxruntime.InferenceSession("super_resolution.onnx")


def to_numpy(tensor):
    return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy()


# compute ONNX Runtime output prediction
ort_inputs = {ort_session.get_inputs()[0].name: to_numpy(x)}
ort_outs = ort_session.run(None, ort_inputs)


# compare ONNX Runtime and PyTorch results
np.testing.assert_allclose(to_numpy(torch_out), ort_outs[0], rtol=1e-03, atol=1e-05)


print("Exported model has been tested with ONNXRuntime, and the result looks good!")

1.加載處理前圖片,使用標(biāo)準(zhǔn)PIL python庫(kù)對(duì)其進(jìn)行預(yù)處理。 2.調(diào)整圖像大小以適應(yīng)模型輸入的大小 (224x224)。

審核編輯:彭靜
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 神經(jīng)網(wǎng)絡(luò)

    關(guān)注

    42

    文章

    4733

    瀏覽量

    100419
  • 模型
    +關(guān)注

    關(guān)注

    1

    文章

    3112

    瀏覽量

    48660
  • Graph
    +關(guān)注

    關(guān)注

    0

    文章

    36

    瀏覽量

    9047

原文標(biāo)題:【技術(shù)基礎(chǔ)】使用ONNX使模型通用化

文章出處:【微信號(hào):FPGA創(chuàng)新中心,微信公眾號(hào):FPGA創(chuàng)新中心】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    將yolov5s的模型轉(zhuǎn)成.onnx模型,進(jìn)行cube-ai分析時(shí)報(bào)錯(cuò)的原因?

    報(bào)錯(cuò)顯示張量不能大于四維的,想請(qǐng)教解決一下,我再此之后通過(guò)onnx-simplifier對(duì).onnx進(jìn)行簡(jiǎn)化之后再通過(guò)cube-ai進(jìn)行分析還是出現(xiàn)上述報(bào)錯(cuò),懇求指導(dǎo),謝謝您!
    發(fā)表于 03-15 06:54

    STM CUBE AI錯(cuò)誤導(dǎo)入onnx模型報(bào)錯(cuò)的原因?

    使用cube-AI分析模型時(shí)報(bào)錯(cuò),該模型是pytorch的cnn轉(zhuǎn)化成onnx ``` Neural Network Tools for STM32AI v1.7.0 (STM.ai v8.0.0-19389) INTERNAL ERROR: list index
    發(fā)表于 05-27 07:15

    導(dǎo)入keras或者onnx模型到cubeai進(jìn)行分析,為什么會(huì)報(bào)錯(cuò)?

    請(qǐng)問(wèn)我導(dǎo)入keras或者onnx模型到cubeai進(jìn)行分析,為什么會(huì)報(bào)錯(cuò),而且沒(méi)有報(bào)錯(cuò)內(nèi)容,cubeai版本9.0.0。換成8.1.0版本后報(bào)錯(cuò)內(nèi)容是invalid network。該怎么入手解決。
    發(fā)表于 07-03 07:55

    深度探索ONNX模型部署 精選資料分享

    這篇文章從多個(gè)角度探索了ONNX,從ONNX的導(dǎo)出到ONNX和Caffe的對(duì)比,以及使用ONNX遭遇的困難以及一些解決辦法,另...
    發(fā)表于 07-20 07:41

    ONNX的相關(guān)資料分享

    ONNX簡(jiǎn)述ONNX是一種AI神經(jīng)網(wǎng)絡(luò)模型的通用中間文件保存方法(可以理解成AI世界的XML),各種AI框架,Inference引擎,甚至OpenCV里面的dnn onnx相關(guān)的模塊都可以解析
    發(fā)表于 11-05 06:45

    如何使用Paddle2ONNX模型轉(zhuǎn)換工具將飛槳模型轉(zhuǎn)換為ONNX模型?

    如何使用Paddle2ONNX模型轉(zhuǎn)換工具將飛槳模型轉(zhuǎn)換為ONNX模型?
    發(fā)表于 12-29 07:42

    怎么解決rknntoolkit1.7.1轉(zhuǎn)onnx報(bào)錯(cuò)的問(wèn)題呢?

    -> Config model --> Loading onnx model I Start importing onnx... W Detect Input node:1325
    發(fā)表于 03-13 11:46

    EIQ onnx模型轉(zhuǎn)換為tf-lite失敗怎么解決?

    我們正在嘗試將 tflite 框架與 npu 一起使用來(lái)進(jìn)行機(jī)器學(xué)習(xí)。這是我們的步驟:1)用pytorch訓(xùn)練一個(gè)模型2) 以onnx格式導(dǎo)出模型3) eiq工具的covnert模型 我們遇到了這個(gè)
    發(fā)表于 03-31 08:03

    yolov7 onnx模型在NPU上太慢了怎么解決?

    我將 yolov7tiny.pt(yolov7-tiny 模型)轉(zhuǎn)換為具有 uint8 權(quán)重的 yolov7tiny.onnx,然后在 i.MX 8M Plus NPU 上運(yùn)行
    發(fā)表于 04-04 06:13

    將TensorFlow Lite模型轉(zhuǎn)換為ONNX

    由 Facebook 和 Microsoft 創(chuàng)建的開(kāi)放格式神經(jīng)網(wǎng)絡(luò)交換格式 ONNX,是一種用于表示機(jī)器學(xué)習(xí)模型。
    的頭像 發(fā)表于 12-08 23:19 ?1333次閱讀

    手工優(yōu)化ncnn模型結(jié)構(gòu)

    本文模型結(jié)構(gòu)使用 netron visualizer 截圖展示,支持 onnx 和 ncnn 模型的可視化
    發(fā)表于 01-26 18:48 ?0次下載
    手工優(yōu)化ncnn模型<b class='flag-5'>結(jié)構(gòu)</b>

    YOLOX模型ONNX格式說(shuō)明

    我記得大概是在去年七月份的時(shí)候我寫(xiě)過(guò)一篇文章是介紹YOLOX+OpenVINO推理的,下載YOLOX的ONNX格式模型(github上可以下載)
    的頭像 發(fā)表于 04-13 08:35 ?5494次閱讀

    Pytorch轉(zhuǎn)化ONNX過(guò)程代碼實(shí)操

    一般來(lái)說(shuō)轉(zhuǎn)ONNX只是一個(gè)手段,在之后得到ONNX模型后還需要再將它做轉(zhuǎn)換,比如轉(zhuǎn)換到TensorRT上完成部署,或者有的人多加一步,從ONNX先轉(zhuǎn)換到caffe,再?gòu)腸affe到tensorRT。
    發(fā)表于 01-02 07:32 ?643次閱讀

    AI推理框架軟件ONNX Runtime正式支持龍架構(gòu)

    近日,知名AI推理框架開(kāi)源社區(qū)ONNX Runtime正式發(fā)布支持龍架構(gòu)的版本1.17.0。
    的頭像 發(fā)表于 03-12 12:23 ?527次閱讀
    AI推理框架軟件<b class='flag-5'>ONNX</b> Runtime正式支持龍架構(gòu)

    ONNX是什么?

    ONNX是什么?
    的頭像 發(fā)表于 05-15 09:49 ?1667次閱讀