首頁 > 軟體

Pytorch中使用TensorBoard詳情

2022-06-30 22:01:10

本文記錄瞭如何在Pytorch中使用Tensorboard(主要是為了備忘)

前言

雖然我本身就會用TensorBoard,但是因為TensorBoard只有在寫訓練程式碼的框架的時候才會寫,因此實際上寫的頻率的還是很低的,所以我每次要寫訓練程式碼、使用TensorBoard的時候都需要看自己之前寫的程式碼,或者查一下別人寫的部落格。而且不少部落格寫的都是一鱗半爪的,不少用法都要查很多部落格,久而久之就會覺得很煩。而且很多技巧隨著時間的流逝也逐漸的忘記。

因此為了方便以後自己的查詢(備忘),同時也是能夠留下一個不錯的教學,因此決定自己寫一個比較全面的TensorBoard的教學。

一、 Introduction to TensorBoard

在煉丹的時候,經常需要追蹤模型在訓練過程中效能的變化,例如:Regression任務中的MSE、分類任務中的準確率、生成(圖片)任務中圖片的生成質量、此外還有合成語音的質量……

大體上來說,所有需要追蹤的資料包括:標量(scalar)、影象(image)、統計圖(diagram)、視訊(video)、音訊(audio)、文字(text)、Embedding等等

除了有大量的資料需要追蹤外,我們還需要很好的把這些資料顯示出來,即資料的寫入和顯示(讀取)要有非同步IO,有的時候伺服器在學校的機房託管,因此還需要能夠通過內網提供視覺化……

因此,在種種需求之下,使用一個網頁程式來幫助我們進行資料的追蹤就成了一個很好的解決方案。具體來說,網頁程式實現了前後端的分離,後端只需要專注於資料的記錄,而前端專注於資料的顯示。此外,網頁程式可以進一步擴充套件,提供網路服務。

因此,就有了TensorBoard這個網頁程式實現了我們上面的需求。TensorBoard最早是TensorFlow中的模組,不過現在經過Pytorch團隊的努力,TensorBoard已經整合到了Pytorch中。

TensorBoard的教學主要分為兩部分,一部分是如何使用TensorBoard(即在訓練過程中新增資料,然後在瀏覽器中監視訓練的這整個pipeline)的教學,另外一部分是TensorBoard如何新增不同種類資料(即TensorBoard的API)的教學

二、TensoBoard Pipeline

上面說道,TensorBoard是分為前段顯示和後端資料記錄的,因此其Pipeline也分為兩步:

第一步:後端資料記錄第二步:前段檢視資料

三、後端資料記錄

類似於FlaskDjango中把後端程式(伺服器)被抽象為了一個類,然而這個類中提供了方法來開啟和關閉服務,TensorBoard中也是把後端伺服器抽象成了一個類:SummaryWriter,不過不同的是,TensorBoard中的SummaryWriter類在被宣告後就開啟了對應的服務,直到我們使用了SummaryWriter關閉服務的API。

此外,還有一個不同的之處在於,TensorBoard的前段資料顯示和後端資料記錄是非同步I/O的,即後端程式(SummaryWriter類的範例)將資料寫入到一個檔案中,而前端程式讀取檔案中的資料來進行顯示。因此後端所謂的服務指的就是資料的記錄,而非提供前端的顯示。資料記錄的實現方式即通過SummaryWriter類中的方法

然後在開啟了後端程式的伺服器之後,我們就可以通過各種API來新增資料了

匯入包:

我們首先匯入包

import torch
from torch.utils.tensorboard import SummaryWriter

1. SummaryWriter類

SummaryWriter宣告之後就會開啟後端資料記錄的服務,因此在範例化該類的時候我們就需要儲存資料的位置。宣告儲存資料的位置有好幾種方式

SummaryWriter的簽名如下:

class torch.utils.tensorboard.writer.SummaryWriter(log_dir=None, comment='', purge_step=None, max_queue=10, flush_secs=120, filename_suffix='')

其中:

  • log_dir (str):指定了資料儲存的資料夾的位置,如果該資料夾不存在則會建立一個出來。如果沒有指定的話,預設的儲存的資料夾是./runs/現在的時間_主機名,例如:Feb04_22-42-47_Alienware,因此每次執行之後都會建立一個新的資料夾。在寫論文的時候我們會涉及一系列實驗,從不同的角度來說明一些問題,例如我們的假設是否正確、模型效能是否更好……因此最好不要用預設的實現來直接作為存放資料的資料夾,而是使用具有含義的二級結構,例如:runs/exp1。這樣的話,所有的實驗1的資料都在這個資料夾下,這樣我們就可以方便的進行比較。
  • comment (string):給預設的log_dir新增的字尾,如果我們已經指定了log_dir具體的值,那麼這個引數就不會有任何的效果
  • purge_step (int):TensorBoard在記錄資料的時候有可能會崩潰,例如在某一個epoch中,進行到第 T + X T+X T+X個step的時候由於各種原因(記憶體溢位)導致崩潰,那麼當服務重啟之後,就會從 T T T個step重新開始將資料寫入檔案,而中間的 X X X,即purge_step指定的step內的資料都被被丟棄。
  • max_queue (int):在記錄資料的時候,在記憶體中開的佇列的長度,當佇列慢了之後就會把資料寫入磁碟(檔案)中。
  • flush_secs (int):以秒為單位的寫入磁碟的間隔,預設是120秒,即兩分鐘。
  • filename_suffix (string):新增到log_dir中每個檔案的字尾。更多檔名稱設定要參考tensorboard.summary.writer.event_file_writer.EventFileWriter類。

因此,一個成熟的資料記錄方式就是在runs資料夾下按照一定的意義來劃分二級資料夾,例如網路結構1網路結構2實驗1實驗2等等。

2. 新增資料

想後端服務程式新增資料使用的是SummaryWriter類中的一系列方法,這些方法都以add_開頭,例如:add_scalaradd_scalarsadd_image……具體來說,所有的方法有:

import pprint
pprint.pprint([i for i in SummaryWriter.__dict__.keys() if i.startwith("add_")])

add_hparams,add_scalar,add_scalars,add_histogram,add_histogram_raw,add_image,add_images,add_image_with_boxes,add_figure,add_video,add_audio,add_text,add_onnx_graph,add_graph,add_embedding,add_pr_curve,add_pr_curve_raw,add_custom_scalars_multilinechart,add_custom_scalars_marginchart,add_custom_scalars,add_mesh

後面在第二部分會詳細的講解每個方法,這裡先講共性。

每個方法根據需要新增的資料的不同,方法中具體的引數也不同,但是所有的方法終歸都是要新增資料的,因此會存在相同的引數。具體來說,相同的引數包括:

  • tag (str):用於給資料進行分類的標籤,標籤中可以包含父級和子級標籤。例如給訓練的loss以loss/train的tag,而給驗證以loss/val的tag,這樣的話,最終的效果就是訓練的loss和驗證的loss都被分到了loss這個父級標籤下。而trainval則是具體用於區分兩個引數的識別符號(identifier)。例如我們現在有兩個tag,cos/densecos/sparse,那麼最終展示下來的效果是這樣的。此外,只支援二級標籤

  • globa_step (int):首先,每個epoch中我們都會更新固定的step。因此,在一個資料被加入的時候,有兩種step,第一種step是資料被加入時當前epoch已經進行了多少個step,第二種step是資料被加入時候,累計(包括之前的epoch)已經進行了多少個step。而考慮到我們在繪圖的時候往往是需要觀察所有的step下的資料的變化,因此global_step指的就是當前資料被加入的時候已經計算了多少個step。計算global_step的步驟很簡單,就是 g l o b a l _ s t e p = e p o c h ∗ l e n ( d a t a l o a d e r ) + c u r r e n t _ s t e p global_step=epoch * len(dataloader) + current_step global_step=epoch∗len(dataloader)+current_step
  • wlltime (int):從SummaryWriter範例化開始到當前資料被加入時候所經歷時間(以秒計算),預設是使用time.time()來自動計算的,當然我們也可以指定這個引數來進行修改。這個引數一般不改

以新增標量(add_scalar)為例,演示一下新增資料的方法的用法。其他的方法第二部分會講

writer = SummaryWriter()
for epoch in range(n_epoch := 10):
    for step in range(total_step := 100):
        # 訓練程式碼讀取資料來進行顯示。
        # ...
        # ...

        # 計算 loss
        loss = np.sin(step * 0.01)
        # 新增標量
        writer.add_scalar(tag="loss/train", scalar_value=loss,
                          global_step=epoch * total_step + step)

然後可以看到的效果如下:

3. 關閉SummaryWriter

我們剛才說過,SummaryWriter這樣的後端程式在被範例化出來就自動開啟了資料記錄的服務,而我們在完成了所有的資料記錄只有,需要關閉服務。

關閉服務很簡單,就是直接呼叫close方法即可

writer.close()

4. Summary

最終,總結一下整個後端資料記錄的流程,其實就三步:

範例化SummaryWriter類,同時指定資料儲存的資料夾利用SummaryWriter類提供的方法,新增不同型別的的資料關閉SummaryWriter類,中止服務

四、前端顯示資料

因為TensorBoard是非同步I/O的網頁服務程式,因此後端程式在把資料寫入到檔案的時候,前端程式可以讀取資料來進行顯示。

具體來說,後端資料記錄程式會把所有的資料記錄到同一個資料夾下的多個檔案內,以方便前端顯示程式多執行緒加速讀取。因此,前端顯示程式在啟動的時候需要指定讀取的資料夾

1. 預設使用

前端顯示程式提供了CLI(命令列)介面,因此我們直接在命令列啟動就行了

tensorboard --logdir=資料資料夾

其中資料資料夾就是在宣告SummaryWriter時候指定的資料夾。

例如:

tensorboard --logdir=./Feb05_01-00-48_Alienware/

而在我們啟動前端顯示程式之後,就會得到一個埠,存取這個埠就能看到顯示的效果

存取該埠就能看到程式:

2. 修改埠

有的時候,在伺服器上訓練模型的時候為了避免和別人的TensorBoard的埠撞了,我們需要指定新的埠。或者有的時候我們在docker容器裡跑TensorBoard,我們通過一個埠對映到主機上去,這個時候就需要指定TensorBoard使用特定的埠。

具體來說就是通過CLI的--port引數

tensorboard --logdir=資料資料夾 --port=埠

例如我們現在指定上面的例子埠為10000

tensorboard --logdir=./Feb05_01-00-48_Alienware/ --port=10000

五、Summary

最後,總結一下使用TensorFlow的Pipeline,首先在訓練的過程中使用SummaryWriter來記錄資料,記錄的過程中需要注意資料夾需要來合理的劃分。

然後我們在前端檢視的時候,執行tensorboard的CLI程式即可,一般用的最多的就是--log_dir--port兩個引數。

此外,如果是伺服器上的話,那麼tensorboard的CLI執行在伺服器上,然後在自己的電腦上,利用瀏覽器,通過內網來檢視訓練過程。

1. SummaryWriter APIs

上面講完了SummaryWriter的Workflow/Pipeline,剩下的就是SummaryWriter新增資料的API的講解了。關於這些API的話,正如上面介紹的,他們都以add_開頭,具體有:

標量類:add_scalaradd_scalarsadd_custom_scalarsadd_custom_scalars_marginchartadd_custom_scalars_multilinechart

資料顯示類:

  • 影象:add_imageadd_imagesadd_image_with_boxesadd_figure
  • 視訊:add_video
  • 音訊:add_audio
  • 文字:add_text
  • ​​​​​​​Embedding:add_embedding
  • ​​​​​​​點雲:add_mesh

統計圖:add_histogramadd_histogram_rawadd_pr_curve、add_pr_curve_raw

網路圖:add_onnx_graphadd_graph

​​​​​​​超引數圖:add_hparams

因為我目前主要在做CV、點雲和NLP,對於語音、視訊設計的比較少,因此關於這些API以後用到了我再慢慢補充。

其實主要就是對官網上的翻譯,可以直接看官網上的介紹:https://pytorch.org/docs/stable/tensorboard.html

到此這篇關於Pytorch中使用TensorBoard詳情的文章就介紹到這了,更多相關Pytorch TensorBoard內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com