主頁 >  其他 > 👇踩坑指南——onnx系列

👇踩坑指南——onnx系列

2023-05-18 09:44:27 其他

??踩坑指南——onnx系列

目錄
  • ??踩坑指南——onnx系列
    • ??1:轉onnx時protobuf庫報錯
    • ??2:訓練時protobuf庫相關錯
    • ??3:torch轉onnx:轉整個模型好?還是轉引數好?
    • ??4:如何使python呼叫torch和onnx模型的輸出一致?
    • ??5:如何使java、python加載onnx模型的輸出一致?
    • 注:

??1:轉onnx時protobuf庫報錯

  • 描述:當運行torch轉onnx的代碼時,出現ImportError: cannot import name 'builder' from 'google.protobuf.internal' ,如下圖:

    image

  • 原因:由于使用的google.protobuf版本太低而引起的,在較新的版本中,builder模塊已經移動到了google.protobuf包中,而不再在google.protobuf.internal中,

  • 解決辦法:升級protobuf庫

    pip install --upgrade protobuf
    

??2:訓練時protobuf庫相關錯

  • 描述:當運行訓練代碼出現如下錯誤:

    image

  • 原因:由于protobuf版本太高而引起的,在較新的protobuf版本中,為了改進性能,Descriptor物件的創建方式發生了變化,

  • 解決辦法:降級protobuf庫

    pip install protobuf==3.20.0
    
  • 注:坑1與坑2之間是相互影響的,暫未找到其他更好解決辦法,但目前辦法可以解決相關報錯,只是有些繁瑣,

??3:torch轉onnx:轉整個模型好?還是轉引數好?

  • 前提:模型訓練的時候保存的是torch.save(net, 'model.pth'),還是torch.save(net.state_dict(), 'weight.pth'),前者保存的是整個模型,后者保存的是引數,

  • 關于torch轉onnx模型,一開始認為轉整個模型比較好是因為考慮了預測時需要重新定義神經網路結構,并且java那邊定義神經網路可能比較復雜,然后就轉整個模型,之后發現不管是轉整個模型還是引數,在python這邊呼叫onnx并預測并不需要重新定義神經網路結構,所以建議訓練的時候只保存引數即可,torch轉onnx時也只轉引數,在轉onnx需加載網路結構,具體torch轉onnx的最小代碼如下:

    import torch
    import torchvision
    import onnx
    # 呼叫自定義網路結構
    from net import Net
    
    # 加載PyTorch模型
    model = Net()
    weight = torch.load('./weight/model.pth')
    model.load_state_dict(weight)
    
    # 設定模型輸入
    dummy_input = torch.randn(1, 3, 224, 224)
    
    # 匯出ONNX模型
    torch.onnx.export(model, dummy_input, 'weight/model.onnx', verbose=True)
    
  • 代碼決議:當前代碼轉的是模型引數;

    • 第一步:先重新加載定義好的神經網路結構,然后加載model.pth并加載引數;
    • 第二步:設定模型輸入,取決于定義的Ne的輸入;
    • 第三步:匯出onnx模型,正常情況傳三個引數即可(第一個:模型;第二個:模型輸入;第三個:匯出模型路徑),verbose默認為False,設定為True,會列印模型輸出至onnx的程序,便于確定模型轉成功了,
  • 總結:關于torch和onnx后續使用python呼叫并且預測時,轉整個模型還是轉引數是否會導致兩者輸出不一致的結果沒有進行對比驗證,但是基于目前本人踩坑到現在,最終torch和onnx的輸出一致了,使用的正是轉引數,關于torch和onnx的輸出不一致的問題見【??4:如何使python呼叫torch和onnx模型的輸出一致?】,所以總的來說,在torch轉onnx時,還是轉引數就行,畢竟在訓練的時候只保存引數會比保存整個模型更快,何為不好呢?

??4:如何使python呼叫torch和onnx模型的輸出一致?

  • 描述:在python開發這邊,訓練完模型后,并將torch模型轉onnx模型后,使用python加載torch模型和onnx模型進行預測同一張圖片,列印模型輸出及softmax后的輸出,出現嚴重不一致,按理來說同一個模型不同格式,最終輸出一個保持一致,

  • 原因:python預測的時候transforms.Resize()內的插值,與onnx中cv2.resize()內的插值不一致,

  • 解決辦法:

  • 辦法1:將onnx中resize操作使用transfroms.Resize(),確保torch和onnx模型進行預測中的resize確保一致(還得保證訓練時預處理的resize,三者保持一致),且resize內的interpolation插值型別一致,

    • 如圖:onnx中使用transfroms.Resize(),輸出如下:

      image

    • 如圖:torch不變,使用transforms.Resize(),輸出如下:

      image

  • 辦法2:將torch中的resize操作使用cv2.resize(),將torch的transforms.Resize()重寫,把里面的resize改成cv2的resize;(詳見 ??5:如何使java、python加載onnx模型的輸出一致?)

  • 總結:確保python中【訓練時預處理的resize】、【torch模型預測時的resize】、【onnx模型預測時的resize】中的插值方法保持一致,

??5:如何使java、python加載onnx模型的輸出一致?

  • 描述:在??五中已經解決了python中呼叫torch和onnx模型預測的輸出一致,但是為了和java對接上,需要保證【python呼叫onnx模型預測的輸出】和【Java呼叫onnx模型預測的輸出】保持一致,如何保持一致?一開始java那邊使用的opencv的resize,python這邊使用的是transforms.Resize(),但是運行結果仍不一致,盡管是transforms.Resize()中使用的是的插值法是Resize(shape,interpolation=InterpolationMode.BILINEAR),java那邊使用的是cv2.INTER_LINEAR,雖然兩者都線性,前者為雙線性,后者為線性,但是最終輸出結果會有出入;

  • 原因:java的cv2.resize和python的transforms.Resize中的插值方法不一樣;

  • 解決辦法:將torch中的resize操作使用cv2.resize(),

    • 1)重寫Resize:

      import torch
      import numpy as np
      from PIL import Image
      import cv2
      from collections.abc import Sequence
      
      class CV2_Resize(torch.nn.Module):
          def __init__(self, size, interpolation=cv2.INTER_LINEAR, max_size=None, antialias=None):
              super().__init__()
              if not isinstance(size, (int, Sequence)):
                  raise TypeError(f"Size should be int or sequence. Got {type(size)}")
              if isinstance(size, Sequence) and len(size) not in (1, 2):
                  raise ValueError("If size is a sequence, it should have 1 or 2 values")
              self.size = size
              self.max_size = max_size
              self.interpolation = interpolation
              self.antialias = antialias
      
          def forward(self, img):
              if isinstance(img, torch.Tensor):
                  img = img.permute(1, 2, 0).cpu().numpy()
                  img = cv2.resize(img, self.size[::-1], interpolation=self.interpolation)
                  img = torch.from_numpy(img).permute(2, 0, 1)
              else:
                  img = np.array(img)
                  img = cv2.resize(img, self.size[::-1], interpolation=self.interpolation)
                  img = Image.fromarray(img)
                  if self.max_size is not None:
                      w, h = img.size
                      if w > h:
                          new_w = self.max_size
                          new_h = int(h * (self.max_size / w))
                      else:
                          new_h = self.max_size
                          new_w = int(w * (self.max_size / h))
                      img = img.resize((new_w, new_h), resample=Image.BILINEAR)
              return img
      
          def __repr__(self) -> str:
              detail = f"(size={self.size}, interpolation={self.interpolation}, max_size={self.max_size}, antialias={self.antialias})"
              return f"{self.__class__.__name__}{detail}"
      
    • 2)然后在訓練時預處理使用重寫的Resize,重新訓模型:

      image

    • 3)訓好轉onnx后,使用python加載onnx模型并預測,輸出結果,但下面使用的是重寫的Resize:

      image

      image

    • 4)使用java加載onnx模型并預測,輸出結果:

      image

      image

    • 但為了我們使用python加載onnx時,resize應該直接使用cv2.resize()

      image

      image

    • 總結:通過如下對比,可以發現【使用python加載onnx,使用cv2.resize】和【java加載onnx,使用cv2的resize】(且插值方法保持一致的情況下),兩者輸出保持一致,但【py加載onnx,cv.resize】和【py加載torch,重寫的Resize】或【py加載onnx,重寫的resize】之間的輸出仍有出入,但范圍已經控制在最小范圍了,

      image

注:

主頁:https://www.cnblogs.com/xielaoban/
本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文連接,否則保留追究法律責任的權利,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/552776.html

標籤:其他

上一篇:👇踩坑指南——onnx系列

下一篇:返回列表

標籤雲
其他(159258) Python(38148) JavaScript(25433) Java(18059) C(15228) 區塊鏈(8267) C#(7972) AI(7469) 爪哇(7425) MySQL(7197) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5871) 数组(5741) R(5409) Linux(5340) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4573) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2433) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1975) 功能(1967) Web開發(1951) HtmlCss(1938) python-3.x(1918) C++(1917) 弹簧靴(1913) xml(1889) PostgreSQL(1878) .NETCore(1861) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 👇踩坑指南——onnx系列

    👇踩坑指南——onnx系列 🕳1:轉onnx時protobuf庫報錯 描述:當運行torch轉onnx的代碼時,出現ImportError: cannot import name 'builder' from 'google.protobuf.internal' ,如下圖: 原因:由于使用的go ......

    uj5u.com 2023-05-18 09:44:27 more
  • 👇踩坑指南——onnx系列

    👇踩坑指南——onnx系列 🕳1:轉onnx時protobuf庫報錯 描述:當運行torch轉onnx的代碼時,出現ImportError: cannot import name 'builder' from 'google.protobuf.internal' ,如下圖: 原因:由于使用的go ......

    uj5u.com 2023-05-18 09:38:28 more
  • 聲音好聽,顏值能打,基于PaddleGAN給人工智能AI語音模型配上動態

    借助So-vits我們可以自己訓練五花八門的音色模型,然后復刻想要欣賞的任意歌曲,實作點歌自由,但有時候卻又總覺得少了點什么,沒錯,缺少了畫面,只聞其聲,卻不見其人,本次我們讓AI川普的歌聲和他偉岸的形象同時出現,基于PaddleGAN構建“靚聲靚影”的“懂王”。 PaddlePaddle是百度開源 ......

    uj5u.com 2023-05-18 08:29:38 more
  • AI 繪畫 - 如何 0 成本在線體驗 AI 繪畫的魅力

    要想體驗 AI 繪畫,比較流行的三種方式是 Midjourney、OpenAI 的 DALL·E 2 以及 Stable Diffusion。而 Midjourney 已經停止免費試用,且使用價格不太便宜,DALL·E 2 也是一樣價格不菲。只有 Stable Diffusion 作為一款開源模型可 ......

    uj5u.com 2023-05-18 08:28:48 more
  • windows環境下如何優雅搭建ftp服務?

    (windows環境下如何優雅搭建ftp服務) 0. 前言 由于學習或作業需要,我們經常需要和他人或其他電腦共享檔案,在這之前我們普遍的做法是用U盤來回拷貝檔案,但這樣就存在著一個風險,①U盤容易中毒;②容易把U盤上的病毒帶到別的電腦上。 不管哪個風險都是我們不愿看到的,為了盡可能規避以上風險,我們 ......

    uj5u.com 2023-05-18 08:28:29 more
  • [SWPUCTF 2021 新生賽]PseudoProtocols

    ##看到提示和地址欄 很明顯了吧 偽協議 base64解碼可得 <?php //go to /test2222222222222.php ?> <?php ini_set("max_execution_time", "180"); show_source(__FILE__); include('fl ......

    uj5u.com 2023-05-18 08:28:16 more
  • 自動化測驗基礎知識,你知道的不知道的都在這里

    借助測驗工具,依照測驗規范,區域或全部代替人工測驗,提高測驗有效性。
    備注:測驗不需要對軟體所有功能進行測驗,比如很多軟體的幫助。 ......

    uj5u.com 2023-05-18 08:28:07 more
  • ChatGPT初學者最佳實踐

    2022年11月底,ChatGPT引爆了新一輪AI的革命,也讓人們意識到AI真的能夠大幅度提高人們的作業效率,甚至有人擔心自己的作業會因為AI不保。這種居安思危的意識是正確的,但是正如錛鑿斧鋸的出現,并沒有讓木匠這個行業消失,而是讓這個行業以更高效的方式作業。所以作為一種工具,我們應當對ChatGP ......

    uj5u.com 2023-05-18 08:22:17 more
  • 最佳軟體測驗基礎入門教程3軟體開發生命周期的測驗

    軟體開發生命周期的測驗 本章簡要介紹了軟體開發專案中常用的生命周期模型,并解釋了測驗在每個模型中扮演的角色。它討論了各種測驗級別和測驗型別之間的區別,并解釋了這些在開發程序中的應用位置和方式。 大多數軟體開發專案是按照事先選擇的軟體開發生命周期模型來計劃和執行的。這種模型也被稱為軟體開發程序模型,或 ......

    uj5u.com 2023-05-18 08:11:41 more
  • 百度飛槳(PaddlePaddle) - PP-OCRv3 文字檢測識別系統 Paddle In

    Paddle Inference 模型推理流程 分別介紹文字檢測、方向分類器和文字識別3個模型,基于Paddle Inference的推理程序。 Paddle Inference 的 Python 離線推理 離線推理,即在特定機器上部署的代碼只能在這臺機器上使用,無法通過其他機器進行訪問 使用whl ......

    uj5u.com 2023-05-18 08:11:05 more