PyTorch最佳實踐,教你寫出一手風格優美的代碼

2021-01-10 騰訊網

選自github

本文轉自機器之心(nearhuman2014)

PyTorch是最優秀的深度學習框架之一,它簡單優雅,非常適合入門。本文將介紹PyTorch的最佳實踐和代碼風格都是怎樣的。雖然這是一個非官方的 PyTorch 指南,但本文總結了一年多使用 PyTorch 框架的經驗,尤其是用它開發深度學習相關工作的最優解決方案。請注意,我們分享的經驗大多是從研究和實踐角度出發的。

這是一個開發的項目,歡迎其它讀者改進該文檔:https://github.com/IgorSusmelj/pytorch-styleguide

本文檔主要由三個部分構成:首先,本文會簡要清點 Python 中的最好裝備。接著,本文會介紹一些使用 PyTorch 的技巧和建議。最後,我們分享了一些使用其它框架的見解和經驗,這些框架通常幫助我們改進工作流。

清點 Python 裝備

建議使用 Python 3.6 以上版本

根據我們的經驗,我們推薦使用 Python 3.6 以上的版本,因為它們具有以下特性,這些特性可以使我們很容易寫出簡潔的代碼:

自 Python 3.6 以後支持「typing」模塊

自 Python 3.6 以後支持格式化字符串(f string)

Python 風格指南

我們試圖遵循 Google 的 Python 編程風格。請參閱 Google 提供的優秀的 python 編碼風格指南:

地址:https://github.com/google/styleguide/blob/gh-pages/pyguide.md。

在這裡,我們會給出一個最常用命名規範小結:

集成開發環境

一般來說,我們建議使用 visual studio 或PyCharm這樣的集成開發環境。而 VS Code 在相對輕量級的編輯器中提供語法高亮和自動補全功能,PyCharm 則擁有許多用於處理遠程集群任務的高級特性。

Jupyter Notebooks VS Python 腳本

一般來說,我們建議使用 Jupyter Notebook 進行初步的探索,或嘗試新的模型和代碼。如果你想在更大的數據集上訓練該模型,就應該使用 Python 腳本,因為在更大的數據集上,復現性更加重要。

我們推薦你採取下面的工作流程:

在開始的階段,使用 Jupyter Notebook

對數據和模型進行探索

在 notebook 的單元中構建你的類/方法

將代碼移植到 Python 腳本中

在伺服器上訓練/部署

開發常備庫

常用的程序庫有:

文件組織

不要將所有的層和模型放在同一個文件中。最好的做法是將最終的網絡分離到獨立的文件(networks.py)中,並將層、損失函數以及各種操作保存在各自的文件中(layers.py,losses.py,ops.py)。最終得到的模型(由一個或多個網絡組成)應該用該模型的名稱命名(例如,yolov3.py,DCGAN.py),且引用各個模塊。

主程序、單獨的訓練和測試腳本應該只需要導入帶有模型名字的 Python 文件。

PyTorch 開發風格與技巧

我們建議將網絡分解為更小的可復用的片段。一個 nn.Module 網絡包含各種操作或其它構建模塊。損失函數也是包含在 nn.Module 內,因此它們可以被直接整合到網絡中。

繼承 nn.Module 的類必須擁有一個「forward」方法,它實現了各個層或操作的前向傳導。

一個 nn.module 可以通過「self.net(input)」處理輸入數據。在這裡直接使用了對象的「call()」方法將輸入數據傳遞給模塊。

PyTorch 環境下的一個簡單網絡

使用下面的模式可以實現具有單個輸入和輸出的簡單網絡:

請注意以下幾點:

我們復用了簡單的循環構建模塊(如卷積塊 ConvBlocks),它們由相同的循環模式(卷積、激活函數、歸一化)組成,並裝入獨立的 nn.Module 中。

我們構建了一個所需要層的列表,並最終使用「nn.Sequential()」將所有層級組合到了一個模型中。我們在 list 對象前使用「*」操作來展開它。

在前向傳導過程中,我們直接使用輸入數據運行模型。

PyTorch 環境下的簡單殘差網絡

在這裡,ResNet 模塊的跳躍連接直接在前向傳導過程中實現了,PyTorch 允許在前向傳導過程中進行動態操作。

PyTorch 環境下的帶多個輸出的網絡

對於有多個輸出的網絡(例如使用一個預訓練好的 VGG 網絡構建感知損失),我們使用以下模式:

請注意以下幾點:

我們使用由「torchvision」包提供的預訓練模型

我們將一個網絡切分成三個模塊,每個模塊由預訓練模型中的層組成

我們通過設置「requires_grad = False」來固定網絡權重

我們返回一個帶有三個模塊輸出的 list

自定義損失函數

即使 PyTorch 已經具有了大量標準損失函數,你有時也可能需要創建自己的損失函數。為了做到這一點,你需要創建一個獨立的「losses.py」文件,並且通過擴展「nn.Module」創建你的自定義損失函數:

訓練模型的最佳代碼結構

對於訓練的最佳代碼結構,我們需要使用以下兩種模式:

使用 prefetch_generator 中的 BackgroundGenerator 來加載下一個批量數據

使用 tqdm 監控訓練過程,並展示計算效率,這能幫助我們找到數據加載流程中的瓶頸

PyTorch 的多 GPU 訓練

PyTorch 中有兩種使用多 GPU 進行訓練的模式。

根據我們的經驗,這兩種模式都是有效的。然而,第一種方法得到的結果更好、需要的代碼更少。由於第二種方法中的 GPU 間的通信更少,似乎具有輕微的性能優勢。

對每個網絡輸入的 batch 進行切分

最常見的一種做法是直接將所有網絡的輸入切分為不同的批量數據,並分配給各個 GPU。

這樣一來,在 1 個 GPU 上運行批量大小為 64 的模型,在 2 個 GPU 上運行時,每個 batch 的大小就變成了 32。這個過程可以使用「nn.DataParallel(model)」包裝器自動完成。

將所有網絡打包到一個超級網絡中,並對輸入 batch 進行切分

這種模式不太常用。下面的代碼倉庫向大家展示了 Nvidia 實現的 pix2pixHD,它有這種方法的實現。

地址:https://github.com/NVIDIA/pix2pixHD

PyTorch 中該做和不該做的

在「nn.Module」的「forward」方法中避免使用 Numpy 代碼

Numpy 是在 CPU 上運行的,它比 torch 的代碼運行得要慢一些。由於 torch 的開發思路與 numpy 相似,所以大多數Numpy中的函數已經在 PyTorch 中得到了支持。

將「DataLoader」從主程序的代碼中分離

載入數據的工作流程應該獨立於你的主訓練程序代碼。PyTorch 使用「background」進程更加高效地載入數據,而不會干擾到主訓練進程。

不要在每一步中都記錄結果

通常而言,我們要訓練我們的模型好幾千步。因此,為了減小計算開銷,每隔 n 步對損失和其它的計算結果進行記錄就足夠了。尤其是,在訓練過程中將中間結果保存成圖像,這種開銷是非常大的。

使用命令行參數

使用命令行參數設置代碼執行時使用的參數(batch 的大小、學習率等)非常方便。一個簡單的實驗參數跟蹤方法,即直接把從「parse_args」接收到的字典(dict 數據)列印出來:

如果可能的話,請使用「Use .detach()」從計算圖中釋放張量

為了實現自動微分,PyTorch 會跟蹤所有涉及張量的操作。請使用「.detach()」來防止記錄不必要的操作。

使用「.item()」列印出標量張量

你可以直接列印變量。然而,我們建議你使用「variable.detach()」或「variable.item()」。在早期版本的 PyTorch(

使用「call」方法代替「nn.Module」中的「forward」方法

這兩種方式並不完全相同,正如下面的 GitHub 問題單所指出的:https://github.com/IgorSusmelj/pytorch-styleguide/issues/3

本文由機器之心編譯,轉載請聯繫本公眾號獲得授權。

Python學習交流群

相關焦點

  • 華為雲應用編排,手把手教您完成pytorch代碼部署
    其歷史可以追溯至 2002 年使用Lua語言的Torch框架,並由其幕後團隊一手打造。PyTorch作為Torch框架的繼任者,並不僅僅只是移植代碼並提供接口,而是深入支持了Python,對大量模塊進行了重構,並新增了最先進的變量自動求導系統,成為時下最流行的動態圖框架。在入門時,PyTorch提供了完整的文檔,並有著活躍的社區論壇,對於新手而言上手遇到的難關容易解決。
  • 幾行代碼教你在Pytorch和Python中實現神經風格遷移
    從左到右為:內容圖像、風格圖像、生成的圖像這個方法相當直觀,本文是在pytorch和python中實現神經風格遷移的簡單指南,並預先解釋了這個方法。Github完整代碼:https://github.com/ksivaman/Transfer-image-styling理解風格和內容神經風格遷移涉及到將一個圖像的風格遷移到另一個圖像的內容上。它們分別是什麼?內容就是圖像的組成部分。可能是風景、海灘環境、花園裡的貓、動物園裡的長頸鹿等等……在典型的圖像分類網絡中,基本上是圖像的標籤。
  • 一行代碼安裝,TPU也能運行PyTorch,修改少量代碼即可快速移植
    現在福利來了,一個叫做Pytorch Lightning的項目,可以讓你幾乎修改代碼的情況下用上TPU。Pytorch Lightning已經上傳到PyPI,因此只需一行代碼就能安裝這個軟體。pip install pytorch-lightning該項目的開發者William Falcon說,PyTorch Lightning是他在紐約大學和FAIR做博士生時研發,專門為從事AI研究的專業研究人員和博士生創建的。
  • 教你用PyTorch實現「看圖說話」(附代碼、學習資源)
    注意: 本文假定你了解深度學習的基礎知識,以前曾使用CNN處理過圖像問題。你首先想到的是什麼?例子的代碼可以在GitHub上找到。代碼的原始作者是YunjeyChoi 向他傑出的pytorch例子致敬。在本例中,一個預先訓練好的ResNet-152被用作編碼器,而解碼器是一個LSTM網絡。
  • 程式設計師如何寫出高質量的代碼程序
    編碼是程式設計師最重要的工作,每個程式設計師都希望自己可以寫出優雅,高性能,高質量的代碼,對於大師級別的程式設計師,他們的寫的代碼就和藝術品一樣,你會忍不住發出驚嘆,他們怎麼可以創造出如此驚豔的作品出來。下面筆者就以自己的淺薄學識和一些經驗來總結下優秀的程序應該具有的特點。
  • 掌握這些小技巧,教你寫出一手好的鋼筆字
    所以,今天夢筆生輝與大家一起來分享硬筆書法的這些小技巧,教你如何寫好一手鋼筆字。第一、找準主筆,把主筆寫好,就成功了一半那麼,主筆是指什麼?主筆就是指單個字體裡面,最為突出的筆畫,起到主心骨和扛鼎作用。其它筆畫,都是為主筆而銜生出來的附筆。所以,在寫附筆的時候,不能喧賓奪主。
  • 華為雲pytorch代碼怎麼部署?
    其歷史可以追溯至2002年使用Lua語言的Torch框架,並由其幕後團隊一手打造。PyTorch作為Torch框架的繼任者,並不僅僅只是移植代碼並提供接口,而是深入支持了Python,對大量模塊進行了重構,並新增了最先進的變量自動求導系統,成為時下最流行的動態圖框架。 在入門時,PyTorch提供了完整的文檔,並有著活躍的社區論壇,對於新手而言上手遇到的難關容易解決。
  • 手把手教你用PyTorch實現圖像分類器(第一部分)
    本文的目標不是提供手把手的指導,而是幫助理解整個過程。如果你正在考慮學習機器學習或人工智慧,你將不得不做類似的項目,並理解本系列文章中介紹的概念。文章主要進行概念上的解釋,不需要知道如何編寫代碼。此外,下面所包含的PyTorch細節是次要的,主要以PyTorch作為示例。
  • PyTorch上也有Keras了,訓練模型告別Debug,只需專注數據和邏輯
    有了這樣一個快速研究框架,使用者只需關注核心訓練和驗證邏輯,繁瑣的工程細節通通自動化一鍵完成,既能保證核心訓練邏輯的正確性,又能保證最佳的實踐體驗。像閃電一樣迅疾所以,Lightning到底有多好用?原來,你需要這樣:在Lightning裡,這一整段代碼不需要你自己敲了,只需輸入以下兩行代碼:不僅如此,在Lightning裡,想用上單個GPU,直接調用即可:使用能將內存佔用減少一半的黑科技
  • PyTorch 0.4:完全改變API,官方支持Windows
    device無關的代碼PyTorch團隊編寫了一個遷移指南,幫助用戶將代碼轉換為新的API和style。如果您想要遷移以前版本的PyTorch中的代碼。遷移指南:http://pytorch.org/2018/04/22/0_4_0-migration-guide.html本部分的內容(主要核心變更)包含在遷移指南中。
  • PyTorch終於能用上谷歌雲TPU,推理性能提升4倍,該如何薅羊毛?
    之前機器學習開發者雖然也能在Colab中使用PyTorch,但是支持雲TPU還是第一次,這也意味著你不需要購買昂貴的GPU,可以在雲端訓練自己的模型。而且如果你是谷歌雲平臺(Google Cloud Platform)的新註冊用戶,還能獲得300美元的免費額度。
  • 「EMNLP2018乾貨」為NLP研究寫出好代碼(254頁教程)
    》,分享了編寫NLP研究代碼的良好實踐經驗。通過本教程,你將學習如何編寫NLP研究實驗代碼,如何設計和簡單化實驗代碼,從而推進研究,產出好的研究成果。現代的NLP研究工作都需要編寫代碼。良好的代碼可以實現快速的原型設計,簡單的代碼調試,實驗的可控性和可視化,幫助研究人員快速準確地了解實驗和模型的具體情況。
  • PyTorch官方教程書限時免費!500頁內容帶你上手最流行框架
    該書一改往日教程或教科書刻板的風格,書中隨處可見的插圖令人印象深刻,還包括大量手繪插圖。此外,該書具備配套代碼,且書中案例和代碼塊隨處可見。配套代碼地址:https://www.manning.com/books/deep-learning-with-pytorchhttps://github.com/deep-learning-with-pytorch/dlwpt-code書中的大量代碼塊可以幫助讀者邊看書邊寫代碼
  • 給訓練踩踩油門:編寫高效的PyTorch代碼技巧
    作者:vahidk前言這是一份 PyTorch 教程和最佳實踐筆記,目錄如下所示:首先 PyTorch 的安裝可以根據官方文檔進行操作:>https://pytorch.org/pip install torch torchvision1.
  • 重磅| Torch7團隊開源PyTorch:Python優先的深度學習框架
    官網:http://pytorch.orgGitHub:https://github.com/pytorch/pytorchPyTorch 是一個 Python 軟體包,其提供了兩種高層面的功能:使用強大的 GPU 加速的 Tensor 計算(類似 numpy)構建於基於 tape 的 autograd 系統的深度神經網絡如有需要,你也可以復用你最喜歡的
  • 一行代碼即可調用18款主流模型!PyTorch Hub輕鬆解決論文可復現性
    圖靈獎得主Yann LeCun發推表示,只需要一行代碼就可以調用所有倉庫裡的模型,通過一個pull請求來發布你自己的模型。同時,PyTorch Hub整合了Google Colab,併集成了論文代碼結合網站Papers With Code,可以直接找到論文的代碼。PyTorch Hub怎麼用?
  • 獨家 | 教你使用torchlayers 來構建PyTorch 模型(附連結)
    我在下面附上了代碼,這例子展示了:torch.nn 和 torchlayers 層的混合使用形狀和維度推斷(卷積、線性輸入和BatchNorm)默認的卷積核v大小卷積的填充默認為 「same」torchlayers池化層的使用(和Keras 相似,全局最大池化)https://github.com/szymonmaszke/torchlayers
  • 分離硬體和代碼、穩定 API,PyTorch Lightning 1.0.0 版本正式發布
    William Falcon 表示自己非常期待有一天,當用戶查看 GitHub 上的複雜項目時,深度學習代碼不再那麼令人望而生畏。特斯拉 AI 負責人 Andrej Karpathy 也評論稱:「這看起來很棒,也很有前途。PyTorch Lightning 倡導對深度學習代碼進行重構,將『工程(硬體)』與『科學(代碼)』分割開,然後將前者委託給框架。」
  • PyTorch實現,GitHub4000星:微軟開源的CV庫
    機器之心報導編輯:魔王、陳萍本文介紹了微軟開源的計算機視覺庫,它囊括了計算機視覺領域的最佳實踐、代碼示例和豐富文檔。近年來,計算機視覺領域突飛猛進,在人臉識別、圖像理解、搜索、無人機、地圖、半自動和自動駕駛方面得到廣泛應用。而這些應用的核心部分是視覺識別任務,如圖像分類、目標檢測和圖像相似度。
  • 兩行代碼統計模型參數量與FLOPs,這個PyTorch小工具值得一試
    機器之心報導參與:思源你的模型到底有多少參數,每秒的浮點運算到底有多少,這些你都知道嗎?近日,GitHub 開源了一個小工具,它可以統計 PyTorch 模型的參數量與每秒浮點運算數(FLOPs)。有了這兩種信息,模型大小控制也就更合理了。其實模型的參數量好算,但浮點運算數並不好確定,我們一般也就根據參數量直接估計計算量了。