Task7:模型部署

ONNX-ONNX Runtime部署

1. 部署ImageNet預(yù)訓(xùn)練圖像分類模型

#安裝配置環(huán)境
pip3 install torch torchvision --extra-index-url https://download.pytorch.org/whl/cu113

pip install numpy pandas matplotlib tqdm opencv-python pillow onnx onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple

導(dǎo)出ONNX模型(把原生pytorch訓(xùn)練得到的圖像分類模型铛绰,導(dǎo)出為ONNX格式染坯,用于后續(xù)在ONNX Runtime推理引擎上部署)

#導(dǎo)入工具包
import torch
from torchvision import models

# 有 GPU 就用 GPU诀姚,沒有就用 CPU
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
print('device', device)

#載入ImageNet預(yù)訓(xùn)練圖像分類模型
model=models.resnet18(pretrained=True)
model=model.eval().to(device)
x = torch.randn(1, 3, 256, 256).to(device)
output=model(x)
output.shape
#pytorch模型轉(zhuǎn)為ONNX模型
x = torch.randn(1, 3, 256, 256).to(device)

with torch.no_grad():
    torch.onnx.export(
        model,                  # 要轉(zhuǎn)換的模型
        x,                      # 模型的任意一組輸入
        'resnet18.onnx',        # 導(dǎo)出的 ONNX 文件名
        opset_version=11,       # ONNX 算子集版本
        input_names=['input'],  # 輸入 Tensor 的名稱(自己起名字)
        output_names=['output'] # 輸出 Tensor 的名稱(自己起名字)
    ) 

#驗(yàn)證ONNX模型導(dǎo)出成功
import onnx

# 讀取 ONNX 模型
onnx_model = onnx.load('resnet18.onnx')

# 檢查模型格式是否正確
onnx.checker.check_model(onnx_model)
print('無報(bào)錯(cuò)橙数,onnx模型載入成功')

#以可讀的形式打印計(jì)算圖
print(onnx.helper.printable_graph(onnx_model.graph))

## 使用Netron對onnx模型可視化
https://netron.app
resnet18.onnx

使用ONNX尽楔,讀取onnx格式的模型文件,對單張圖像文件進(jìn)行預(yù)測

#導(dǎo)入工具包
import onnxruntime
import numpy as np
import torch

#載入onnx模型
ort_session = onnxruntime.InferenceSession('resnet18.onnx')

#構(gòu)造輸入拱她,獲取輸出結(jié)果
x = torch.randn(1, 3, 256, 256).numpy()
x.shape
# onnx runtime 輸入
ort_inputs = {'input': x}

# onnx runtime 輸出
ort_output = ort_session.run(['output'], ort_inputs)[0]
ort_output.shape

#預(yù)處理
from torchvision import transforms

# 測試集圖像預(yù)處理-RCTN:縮放裁剪、轉(zhuǎn) Tensor扔罪、歸一化
test_transform = transforms.Compose([transforms.Resize(256),
                                     transforms.CenterCrop(256),
                                     transforms.ToTensor(),
                                     transforms.Normalize(
                                         mean=[0.485, 0.456, 0.406], 
                                         std=[0.229, 0.224, 0.225])
                                    ])

#載入測試圖像
img_path = 'banana1.jpg'
# 用 pillow 載入
from PIL import Image
img_pil = Image.open(img_path)
img_pil
#運(yùn)行預(yù)處理
input_img = test_transform(img_pil)
input_img.shape
input_tensor = input_img.unsqueeze(0).numpy()
input_tensor.shape

#使用ONNX預(yù)測
# ONNX Runtime 輸入
ort_inputs = {'input': input_tensor}
# ONNX Runtime 輸出
pred_logits = ort_session.run(['output'], ort_inputs)[0]
pred_logits = torch.tensor(pred_logits)
pred_logits.shape
import torch.nn.functional as F
pred_softmax = F.softmax(pred_logits, dim=1) # 對 logit 分?jǐn)?shù)做 softmax 運(yùn)算
pred_softmax.shape

#柱狀圖可視化
import matplotlib.pyplot as plt
%matplotlib inline

plt.figure(figsize=(8,4))

x = range(1000)
y = pred_softmax.cpu().detach().numpy()[0]

ax = plt.bar(x, y, alpha=0.5, width=0.3, color='yellow', edgecolor='red', lw=3)
plt.ylim([0, 1.0]) # y軸取值范圍
# plt.bar_label(ax, fmt='%.2f', fontsize=15) # 置信度數(shù)值

plt.xlabel('Class', fontsize=20)
plt.ylabel('Confidence', fontsize=20)
plt.tick_params(labelsize=16) # 坐標(biāo)文字大小
plt.title(img_path, fontsize=25)

plt.show()

2. 部署自己訓(xùn)練的水果圖像分類模型

導(dǎo)出ONNX模型

#導(dǎo)入工具包
import torch
from torchvision import models

# 有 GPU 就用 GPU秉沼,沒有就用 CPU
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
print('device', device)

#導(dǎo)入訓(xùn)練好的模型
model = torch.load('checkpoints/fruit30_pytorch_20220814.pth')
model = model.eval().to(device)

x = torch.randn(1, 3, 256, 256).to(device)
output = model(x)
output.shape

#pytorch模型轉(zhuǎn)為ONNX模型
x = torch.randn(1, 3, 256, 256).to(device)

with torch.no_grad():
    torch.onnx.export(
        model,                   # 要轉(zhuǎn)換的模型
        x,                       # 模型的任意一組輸入
        'fruit30_resnet18.onnx', # 導(dǎo)出的 ONNX 文件名
        opset_version=11,        # ONNX 算子集版本
        input_names=['input'],   # 輸入 Tensor 的名稱(自己起名字)
        output_names=['output']  # 輸出 Tensor 的名稱(自己起名字)
    ) 

#驗(yàn)證ONNX模型導(dǎo)出成功import onnx

# 讀取 ONNX 模型
onnx_model = onnx.load('fruit30_resnet18.onnx')

# 檢查模型格式是否正確
onnx.checker.check_model(onnx_model)

print('無報(bào)錯(cuò),onnx模型載入成功')

#以可讀的形式打印計(jì)算圖
print(onnx.helper.printable_graph(onnx_model.graph))

### 使用Netron對onnx模型可視化  https://netron.app
fruit30_resnet18.onnx

使用ONNX矿酵,讀取onnx格式的模型文件唬复,預(yù)測單張圖像

#導(dǎo)入工具包
import onnxruntime
import numpy as np
import torch

#載入onnx模型
ort_session = onnxruntime.InferenceSession('fruit30_resnet18.onnx')

#構(gòu)造輸入,獲取輸出結(jié)果
x = torch.randn(1, 3, 256, 256).numpy()
x.shape
# onnx runtime 輸入
ort_inputs = {'input': x}

# onnx runtime 輸出
ort_output = ort_session.run(['output'], ort_inputs)[0]
ort_output.shape

#預(yù)處理
from torchvision import transforms

# 測試集圖像預(yù)處理-RCTN:縮放裁剪全肮、轉(zhuǎn) Tensor敞咧、歸一化
test_transform = transforms.Compose([transforms.Resize(256),
                                     transforms.CenterCrop(256),
                                     transforms.ToTensor(),
                                     transforms.Normalize(
                                         mean=[0.485, 0.456, 0.406], 
                                         std=[0.229, 0.224, 0.225])
                                    ])

#載入測試圖像
img_path = 'test_img/watermelon1.jpg'
# 用 pillow 載入
from PIL import Image
img_pil = Image.open(img_path)
img_pil
input_img = test_transform(img_pil)
input_img.shape
input_tensor = input_img.unsqueeze(0).numpy()
input_tensor.shape

#ONNX預(yù)測
# ONNX Runtime 輸入
ort_inputs = {'input': input_tensor}

# ONNX Runtime 輸出
pred_logits = ort_session.run(['output'], ort_inputs)[0]
pred_logits = torch.tensor(pred_logits)

pred_logits.shape
import torch.nn.functional as F
pred_softmax = F.softmax(pred_logits, dim=1) # 對 logit 分?jǐn)?shù)做 softmax 運(yùn)算
pred_softmax.shape

#解析預(yù)測結(jié)果
idx_to_labels = np.load('idx_to_labels.npy', allow_pickle=True).item()
idx_to_labels

import matplotlib.pyplot as plt
%matplotlib inline

plt.figure(figsize=(22, 10))

x = idx_to_labels.values()
y = pred_softmax.cpu().detach().numpy()[0] * 100
width = 0.45 # 柱狀圖寬度

ax = plt.bar(x, y, width)

plt.bar_label(ax, fmt='%.2f', fontsize=15) # 置信度數(shù)值
plt.tick_params(labelsize=20) # 設(shè)置坐標(biāo)文字大小

plt.title(img_path, fontsize=30)
plt.xticks(rotation=45) # 橫軸文字旋轉(zhuǎn)
plt.xlabel('類別', fontsize=20)
plt.ylabel('置信度', fontsize=20)
plt.show()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市倔矾,隨后出現(xiàn)的幾起案子妄均,更是在濱河造成了極大的恐慌,老刑警劉巖哪自,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丰包,死亡現(xiàn)場離奇詭異,居然都是意外死亡壤巷,警方通過查閱死者的電腦和手機(jī)邑彪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胧华,“玉大人寄症,你說我怎么就攤上這事【囟” “怎么了有巧?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長悲没。 經(jīng)常有香客問我篮迎,道長,這世上最難降的妖魔是什么示姿? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任甜橱,我火速辦了婚禮,結(jié)果婚禮上栈戳,老公的妹妹穿的比我還像新娘岂傲。我一直安慰自己,他們只是感情好子檀,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布镊掖。 她就那樣靜靜地躺著乃戈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪堰乔。 梳的紋絲不亂的頭發(fā)上偏化,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天脐恩,我揣著相機(jī)與錄音镐侯,去河邊找鬼。 笑死驶冒,一個(gè)胖子當(dāng)著我的面吹牛苟翻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骗污,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼崇猫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了需忿?” 一聲冷哼從身側(cè)響起诅炉,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屋厘,沒想到半個(gè)月后涕烧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汗洒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年议纯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溢谤。...
    茶點(diǎn)故事閱讀 40,926評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瞻凤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出世杀,到底是詐尸還是另有隱情阀参,我是刑警寧澤,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布瞻坝,位于F島的核電站蛛壳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏湿镀。R本人自食惡果不足惜炕吸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勉痴。 院中可真熱鬧赫模,春花似錦、人聲如沸蒸矛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至斩祭,卻和暖如春劣像,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摧玫。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工耳奕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诬像。 一個(gè)月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓屋群,卻偏偏與公主長得像,于是被迫代替她去往敵國和親坏挠。 傳聞我的和親對象是個(gè)殘疾皇子芍躏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容