国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

pytorch模型(.pt)轉(zhuǎn)onnx模型(.onnx)的方法詳解(1)

這篇具有很好參考價(jià)值的文章主要介紹了pytorch模型(.pt)轉(zhuǎn)onnx模型(.onnx)的方法詳解(1)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1.?pytorch模型轉(zhuǎn)換到onnx模型

2.運(yùn)行onnx模型

3.比對(duì)onnx模型和pytorch模型的輸出結(jié)果

?我這里重點(diǎn)是第一點(diǎn)和第二點(diǎn),第三部分? 比較容易

首先你要安裝 依賴庫:onnx 和 onnxruntime,

pip install onnx
pip install onnxruntime 進(jìn)行安裝

也可以使用清華源鏡像文件安裝? 速度會(huì)快些。

開始:

1.?pytorch模型轉(zhuǎn)換到onnx模型

pytorch 轉(zhuǎn) onnx 僅僅需要一個(gè)函數(shù) torch.onnx.export?

torch.onnx.export(model, args, path, export_params, verbose, input_names, output_names, do_constant_folding, dynamic_axes, opset_version)

參數(shù)說明:

  • model——需要導(dǎo)出的pytorch模型
  • args——模型的輸入?yún)?shù),滿足輸入層的shape正確即可。
  • path——輸出的onnx模型的位置。例如‘yolov5.onnx’。
  • export_params——輸出模型是否可訓(xùn)練。default=True,表示導(dǎo)出trained model,否則untrained。
  • verbose——是否打印模型轉(zhuǎn)換信息。default=False。
  • input_names——輸入節(jié)點(diǎn)名稱。default=None。
  • output_names——輸出節(jié)點(diǎn)名稱。default=None。
  • do_constant_folding——是否使用常量折疊,默認(rèn)即可。default=True。
  • dynamic_axes——模型的輸入輸出有時(shí)是可變的,如Rnn,或者輸出圖像的batch可變,可通過該參數(shù)設(shè)置。如輸入層的shape為(b,3,h,w),batch,height,width是可變的,但是chancel是固定三通道。
    格式如下 :
    1)僅list(int) dynamic_axes={‘input’:[0,2,3],‘output’:[0,1]}
    2)僅dict<int, string> dynamic_axes={‘input’:{0:‘batch’,2:‘height’,3:‘width’},‘output’:{0:‘batch’,1:‘c’}}
    3)mixed dynamic_axes={‘input’:{0:‘batch’,2:‘height’,3:‘width’},‘output’:[0,1]}
  • opset_version——opset的版本,低版本不支持upsample等操作。

轉(zhuǎn)化代碼:參考1:

import torch
import torch.nn
import onnx
 
model = torch.load('best.pt')
model.eval()
 
input_names = ['input']
output_names = ['output']
 
x = torch.randn(1,3,32,32,requires_grad=True)
 
torch.onnx.export(model, x, 'best.onnx', input_names=input_names, output_names=output_names, verbose='True')

?參考2:PlainC3AENetCBAM 是網(wǎng)絡(luò)模型,如果你沒有自己的網(wǎng)絡(luò)模型,可能成功不了

import io
import torch
import torch.onnx
from models.C3AEModel import PlainC3AENetCBAM
 
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
 
def test():
  model = PlainC3AENetCBAM()
  
  pthfile = r'/home/joy/Projects/models/emotion/PlainC3AENet.pth'
  loaded_model = torch.load(pthfile, map_location='cpu')
  # try:
  #   loaded_model.eval()
  # except AttributeError as error:
  #   print(error)
 
  model.load_state_dict(loaded_model['state_dict'])
  # model = model.to(device)
 
  #data type nchw
  dummy_input1 = torch.randn(1, 3, 64, 64)
  # dummy_input2 = torch.randn(1, 3, 64, 64)
  # dummy_input3 = torch.randn(1, 3, 64, 64)
  input_names = [ "actual_input_1"]
  output_names = [ "output1" ]
  # torch.onnx.export(model, (dummy_input1, dummy_input2, dummy_input3), "C3AE.onnx", verbose=True, input_names=input_names, output_names=output_names)
  torch.onnx.export(model, dummy_input1, "C3AE_emotion.onnx", verbose=True, input_names=input_names, output_names=output_names)
 
if __name__ == "__main__":
 test()

直接將PlainC3AENetCBAM替換成需要轉(zhuǎn)換的模型,然后修改pthfile,輸入和onnx模型名字然后執(zhí)行即可。

注意:上面代碼中注釋的dummy_input2,dummy_input3,torch.onnx.export對(duì)應(yīng)的是多個(gè)輸入的例子。

在轉(zhuǎn)換過程中遇到的問題匯總

RuntimeError: Failed to export an ONNX attribute, since it's not constant, please try to make things (e.g., kernel size) static if possible

在轉(zhuǎn)換過程中遇到RuntimeError: Failed to export an ONNX attribute, since it's not constant, please try to make things (e.g., kernel size) static if possible的錯(cuò)誤。

我成功的案例,我直接把我訓(xùn)練的網(wǎng)絡(luò)貼上,成功轉(zhuǎn)換,沒有from **? ?import 模型名詞這么委婉,合法,我的比較粗暴

import torch
import torch.nn
import onnx
from torchvision import transforms
import torch.nn as nn
from torch.nn import Sequential

# 添加模型

# 設(shè)置數(shù)據(jù)轉(zhuǎn)換方式
preprocess_transform = transforms.Compose([
    transforms.ToTensor(),  # 把數(shù)據(jù)轉(zhuǎn)換為張量(Tensor)
    transforms.Normalize(  # 標(biāo)準(zhǔn)化,即使數(shù)據(jù)服從期望值為 0,標(biāo)準(zhǔn)差為 1 的正態(tài)分布
        mean=[0.5, ],  # 期望
        std=[0.5, ]  # 標(biāo)準(zhǔn)差
    )
])

class CNN(nn.Module):  # 從父類 nn.Module 繼承
    def __init__(self):  # 相當(dāng)于 C++ 的構(gòu)造函數(shù)
        # super() 函數(shù)是用于調(diào)用父類(超類)的一個(gè)方法,是用來解決多重繼承問題的
        super(CNN, self).__init__()

        # 第一層卷積層。Sequential(意為序列) 括號(hào)內(nèi)表示要進(jìn)行的操作
        self.conv1 = Sequential(
            nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )

        # 第二卷積層
        self.conv2 = Sequential(
            nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )

        # 全連接層(Dense,密集連接層)
        self.dense = Sequential(
            nn.Linear(7 * 7 * 128, 1024),
            nn.ReLU(),
            nn.Dropout(p=0.5),
            nn.Linear(1024, 10)
        )

    def forward(self, x):  # 正向傳播
        x1 = self.conv1(x)
        x2 = self.conv2(x1)
        x = x2.view(-1, 7 * 7 * 128)
        x = self.dense(x)
        return x

# 訓(xùn)練
# 訓(xùn)練和參數(shù)優(yōu)化

# 定義求導(dǎo)函數(shù)
def get_Variable(x):
    x = torch.autograd.Variable(x)  # Pytorch 的自動(dòng)求導(dǎo)
    # 判斷是否有可用的 GPU
    return x.cuda() if torch.cuda.is_available() else x


# 判斷是否GPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# device1 = torch.device('cpu')
# 定義網(wǎng)絡(luò)
model = CNN()




loaded_model = torch.load('save_model/model.pth', map_location='cuda:0')
model.load_state_dict(loaded_model)
model.eval()

input_names = ['input']
output_names = ['output']

# x = torch.randn(1,3,32,32,requires_grad=True)
x = torch.randn(1, 1, 28, 28, requires_grad=True)  # 這個(gè)要與你的訓(xùn)練模型網(wǎng)絡(luò)輸入一致。我的是黑白圖像

torch.onnx.export(model, x, 'save_model/model.onnx', input_names=input_names, output_names=output_names, verbose='True')

前提是你要準(zhǔn)備好*.pth模型保持文件

輸出結(jié)果:

graph(%input : Float(1, 1, 28, 28, strides=[784, 784, 28, 1], requires_grad=1, device=cpu),
      %dense.0.weight : Float(1024, 6272, strides=[6272, 1], requires_grad=1, device=cpu),
      %dense.0.bias : Float(1024, strides=[1], requires_grad=1, device=cpu),
      %dense.3.weight : Float(10, 1024, strides=[1024, 1], requires_grad=1, device=cpu),
      %dense.3.bias : Float(10, strides=[1], requires_grad=1, device=cpu),
      %33 : Float(64, 1, 3, 3, strides=[9, 9, 3, 1], requires_grad=0, device=cpu),
      %34 : Float(64, strides=[1], requires_grad=0, device=cpu),
      %36 : Float(128, 64, 3, 3, strides=[576, 9, 3, 1], requires_grad=0, device=cpu),
      %37 : Float(128, strides=[1], requires_grad=0, device=cpu)):
  %input.4 : Float(1, 64, 28, 28, strides=[50176, 784, 28, 1], requires_grad=1, device=cpu) = onnx::Conv[dilations=[1, 1], group=1, kernel_shape=[3, 3], pads=[1, 1, 1, 1], strides=[1, 1]](%input, %33, %34) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\modules\conv.py:443:0
  %21 : Float(1, 64, 28, 28, strides=[50176, 784, 28, 1], requires_grad=1, device=cpu) = onnx::Relu(%input.4) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\functional.py:1442:0
  %input.8 : Float(1, 64, 14, 14, strides=[12544, 196, 14, 1], requires_grad=1, device=cpu) = onnx::MaxPool[kernel_shape=[2, 2], pads=[0, 0, 0, 0], strides=[2, 2]](%21) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\functional.py:797:0
  %input.16 : Float(1, 128, 14, 14, strides=[25088, 196, 14, 1], requires_grad=1, device=cpu) = onnx::Conv[dilations=[1, 1], group=1, kernel_shape=[3, 3], pads=[1, 1, 1, 1], strides=[1, 1]](%input.8, %36, %37) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\modules\conv.py:443:0
  %25 : Float(1, 128, 14, 14, strides=[25088, 196, 14, 1], requires_grad=1, device=cpu) = onnx::Relu(%input.16) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\functional.py:1442:0
  %26 : Float(1, 128, 7, 7, strides=[6272, 49, 7, 1], requires_grad=1, device=cpu) = onnx::MaxPool[kernel_shape=[2, 2], pads=[0, 0, 0, 0], strides=[2, 2]](%25) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\functional.py:797:0
  %27 : Long(2, strides=[1], device=cpu) = onnx::Constant[value=   -1  6272 [ CPULongType{2} ]]() # E:/paddle_project/Pytorch_Imag_Classify/zifu_fenlei/CNN/pt模型轉(zhuǎn)onnx模型.py:51:0
  %28 : Float(1, 6272, strides=[6272, 1], requires_grad=1, device=cpu) = onnx::Reshape(%26, %27) # E:/paddle_project/Pytorch_Imag_Classify/zifu_fenlei/CNN/pt模型轉(zhuǎn)onnx模型.py:51:0
  %input.20 : Float(1, 1024, strides=[1024, 1], requires_grad=1, device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1](%28, %dense.0.weight, %dense.0.bias) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\modules\linear.py:103:0
  %input.24 : Float(1, 1024, strides=[1024, 1], requires_grad=1, device=cpu) = onnx::Relu(%input.20) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\functional.py:1442:0
  %output : Float(1, 10, strides=[10, 1], requires_grad=1, device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1](%input.24, %dense.3.weight, %dense.3.bias) # D:\ProgramData\Anaconda3\envs\openmmlab\lib\site-packages\torch\nn\modules\linear.py:103:0
  return (%output)

輸出結(jié)果的device? 是CPU,模型加載的時(shí)候是GPU。這就是轉(zhuǎn)換的意義吧

2.運(yùn)行onnx模型

import onnx
import onnxruntime as ort
 
model = onnx.load('best.onnx')
onnx.checker.check_model(model)
 
session = ort.InferenceSession('best.onnx')
x=np.random.randn(1,3,32,32).astype(np.float32)  # 注意輸入type一定要np.float32!!!!!
# x= torch.randn(batch_size,chancel,h,w)
 
 
outputs = session.run(None,input = { 'input' : x })

參考:

Pytorch模型轉(zhuǎn)onnx模型實(shí)例_python_腳本之家 (jb51.net)

pytorch模型轉(zhuǎn)onnx模型的方法詳解_python_腳本之家 (jb51.net)文章來源地址http://www.zghlxwxcb.cn/news/detail-407570.html

到了這里,關(guān)于pytorch模型(.pt)轉(zhuǎn)onnx模型(.onnx)的方法詳解(1)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包