深度學(xué)習(xí)模型在硬件加速器上的部署常常要用到ONNX(Open Neural Network Exchange,開放神經(jīng)網(wǎng)絡(luò)交換)格式,也可以通過ONNX實(shí)現(xiàn)不同AI框架(如Pytorch、TensorFlow、Caffe2、PaddlePaddle等)之間的模型轉(zhuǎn)換。
最近臨時(shí)使用PaddlePaddle開發(fā)模型,需要將準(zhǔn)備好的模型轉(zhuǎn)換成ONNX格式,在此記錄一下。
Paddle轉(zhuǎn)ONNX庫(kù)需要用到paddle2onnx工具。在完成PaddlePaddle環(huán)境安裝的基礎(chǔ)上,通過如下命令安裝paddle2onnx:
pip install paddle2onnx
安裝完成后,就可以通過該工具完成paddle模型向onnx的轉(zhuǎn)換了。下面就用一個(gè)簡(jiǎn)單的例子來說明用法。
首先,定義一個(gè)我們自己的模型。比如,我們定義一個(gè)輕量級(jí)OCR檢測(cè)模型,該模型由三部分組成,分別是:一個(gè)輕量級(jí)特征提取網(wǎng)絡(luò)MobileNetV3、一個(gè)金字塔結(jié)構(gòu)FPN和一個(gè)Head,這三個(gè)結(jié)構(gòu)已經(jīng)在PaddleOCR開源代碼中定義好了,我們只需要自己將這幾部分拼成一個(gè)模型即可:
import paddle
from ppocr.modeling.heads.det_db_head import DBHead
from ppocr.modeling.backbones.det_mobilenet_v3 import MobileNetV3
from ppocr.modeling.necks.db_fpn import DBFPN
class MyPaddleOCR(paddle.nn.Layer):
def __init__(self, out_channels):
super(MyPaddleOCR, self).__init__()
self.backbone = MobileNetV3()
self.in_channels = self.backbone.out_channels
self.fpn = DBFPN(in_channels=self.in_channels, out_channels=out_channels)
self.db_head = DBHead(in_channels=out_channels)
def forward(self, x):
backbone_outs = self.backbone(x)
fpn_outs = self.fpn(backbone_outs)
head_outs = self.db_head(fpn_outs)
return head_outs
網(wǎng)絡(luò)定義好之后,當(dāng)然要進(jìn)行模型訓(xùn)練,或者加載已知模型參數(shù),這部分略去,我們直接講如何將paddle模型轉(zhuǎn)換成onnx。
模型轉(zhuǎn)換需要用到paddle.onnx.export接口,像其他框架一樣,導(dǎo)出模型時(shí)也需要指定輸入數(shù)據(jù)的shape,在Paddle中,可以使用paddle.static.InputSpec來指定輸入數(shù)據(jù)的shape,調(diào)用流程如下:
paddle_ocr_model = MyPaddleOCR(out_channels=256)
# ......
# 省略模型訓(xùn)練或參數(shù)加載
# 定義輸出onnx文件路徑
onnx_path = 'paddle_ocr_det'
# 定義輸入數(shù)據(jù),包括shape、type、name
# 將某一維度設(shè)置為None,則該維度為動(dòng)態(tài)維度
#x_spec = paddle.static.InputSpec([None, 1, 640, 640], 'float32', 'x')
x_spec = paddle.static.InputSpec([1,3,640,640], 'float32', 'x')
# 調(diào)用paddle.onnx.export接口導(dǎo)出onnx模型
paddle.onnx.export(paddle_ocr_model, onnx_path, input_spec=[x_spec], opset_version=11)
好了,現(xiàn)在在當(dāng)前目錄下生成了paddle_ocr_det.onnx文件,讓我們用onnxruntime來運(yùn)行一下:
import onnxruntime
import numpy as np
onnx_path = 'paddle_ocr_det.onnx'
x = np.random.random((1, 3, 640, 640)).astype('float32')
ort_sess = onnxruntime.InferenceSession(onnx_path)
ort_inputs = {ort_sess.get_inputs()[0].name: x}
ort_outs = ort_sess.run(None, ort_inputs)
print(ort_outs[0].shape)
輸出結(jié)果的形狀為:?(1, 3, 640, 640),是OK的。
ps:如果環(huán)境中未安裝onnxruntime,需要先安裝一下,看自己的機(jī)器是否有GPU,選擇以下兩個(gè)命令安裝即可:
非GPU機(jī)器:文章來源:http://www.zghlxwxcb.cn/news/detail-785578.html
pip install onnxruntime
GPU機(jī)器:文章來源地址http://www.zghlxwxcb.cn/news/detail-785578.html
pip install onnxruntime-gpu
到了這里,關(guān)于Paddle模型轉(zhuǎn)ONNX的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!