1. 程式人生 > 實用技巧 >【學習筆記】Pytorch深度學習——Tensorboard的使用(一)

【學習筆記】Pytorch深度學習——Tensorboard的使用(一)

本節筆記內容具體是學習tensorboard中的兩個方法分別是scalar和histogram,一共分為3個部分:(1)首先學習SummaryWriter類;(2)其次,學習兩個基本方法記錄標量add_scalar和直方圖視覺化add_histogram;(3)最後,使用scalar和histogram來監控模型指標(分別有Loss曲線、Acuracy曲線以及引數分佈、引數所對應的梯度分佈情況)

tensorboard執行機制
學習之前,回顧tensorboard執行機制:
首先在python腳本里①記錄要視覺化的資料,然後,這些②資料以event file形式儲存到硬碟中,最後在③終端讀取event file在tensorboard視覺化,展示在web端。


圖1 tensorboard執行機制

SummaryWriter

在python指令碼中怎樣記錄想要視覺化的資料?要在python指令碼中記錄資料並以event file儲存到硬碟中就需要SummaryWriter類。

SummaryWriter
功能:提供建立event file的高階介面
Class SummaryWriter(object)
 def_init_(self,log_dir=None,comment='',
 purge_step=None,max_queue=10,
 flush_secs=120,filename_suffix='')
主要屬性:
log_dir:event file 輸出資料夾
comment:不指定log_dir時,檔名字尾
filename_suffix:event file檔名字尾

解釋
3個屬性都與要建立的路徑有關。
(1)log_dir:event_file 輸出資料夾,通常採用預設引數即不設定;如果不設定log_dir,會在當前 .py檔案當前資料夾下建立1個runs資料夾(如:runs/Aug18_16-09-46_LAPTOP-73TM5PNOtest_tensorboard/event...)


(2)comment:不指定log_dir時,新增檔名字尾 (3)filename_suffix:新增 event file檔名字尾

實驗
(1)設定log_dir,創建出來的檔案有什麼特點?


(2)不設定log_dir,創建出來的檔案有什麼特點?


通常不會採用預設形式,而是要設定log_dir的具體路徑,保證程式碼和訓練資料隔離開來,便於管理。

add_scalar and add_histogram

學習了怎樣event file路徑,接下來學習具體方法。

1、add_scalar
功能:記錄標量
add_scalar(tag,scalar_value,global_step=None,
walltime=None)
tag:影象的標籤名,圖的唯一標識
scalar_value:要記錄的標量
global_step:x軸(通常以1個epoch或iteration為週期)

該方法使用受限,只能記錄一條曲線;但是在模型訓練時,想要監控訓練集和測試集曲線對比情況,add_scalar方法就不能使用了。因此,還提供add_scalars方法。

2、add_scalars()
功能:記錄標量,可以繪製多條曲線
add_scalar(main_tag,tag_scalar_dict,global_step=None,
walltime=None)
main_tag:該影象的標籤名
tag_scalar_dict:利用字典的形式記錄多條曲線,字典dict的key是變數的tag,value是變數的值

實驗
1、add_scalar

2、add_scalars

3、視覺化結果


3、add_histogram

觀察引數的分佈情況即統計、繪製直方圖。

功能:統計直方圖與多分位數折線圖
add_histogram(tag,values,global_step=None,
bins='tensorflow',walltime=None)
tag:影象的標籤名
values:要統計的引數(通常有權值、偏置及其對應的梯度)
global_step:y軸(是epoch數)
bins:取直方圖的bins(通常採用‘tensorflow’)

實驗
隨機建立1個標準正態分佈和均勻分佈,繪製其引數的統計圖。

< 程式碼 >


(1)histogram直方圖


(2)多分位數折線圖distributions


模型監控指標

下面利用上述方法監控模型的Loss、Accuracy曲線以及引數的分佈和引數的梯度分佈。

人名幣二分類模型中訓練部分程式碼--來自餘老師

# ============================ step 5/5 訓練 ============================
train_curve = list()
valid_curve = list()

iter_count = 0

# 構建 SummaryWriter
writer = SummaryWriter(comment='test_your_comment', filename_suffix="_test_your_filename_suffix")

for epoch in range(MAX_EPOCH):

    loss_mean = 0.
    correct = 0.
    total = 0.

    net.train()
    for i, data in enumerate(train_loader):

        iter_count += 1

        # forward
        inputs, labels = data
        outputs = net(inputs)

        # backward
        optimizer.zero_grad()
        loss = criterion(outputs, labels)
        loss.backward()

        # update weights
        optimizer.step()

        # 統計分類情況
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).squeeze().sum().numpy()

        # 列印訓練資訊
        loss_mean += loss.item()
        train_curve.append(loss.item())
        if (i+1) % log_interval == 0:
            loss_mean = loss_mean / log_interval
            print("Training:Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2%}".format(
                epoch, MAX_EPOCH, i+1, len(train_loader), loss_mean, correct / total))
            loss_mean = 0.

     # 訓練集:每個iteration記錄資料,保存於event file
        writer.add_scalars("Loss", {"Train": loss.item()}, iter_count)
        writer.add_scalars("Accuracy", {"Train": correct / total}, iter_count)

    # 訓練集——這就是監控過程!!!每個epoch,記錄梯度,權值(從named_parameters中獲取引數的   名字name,然後對每個引數的資料name+'data'、梯度name+'_grad'記錄。)
    for name, param in net.named_parameters():
        writer.add_histogram(name + '_grad', param.grad, epoch)
        writer.add_histogram(name + '_data', param, epoch)

    scheduler.step()  # 更新學習率

    # validate the model
    if (epoch+1) % val_interval == 0:

        correct_val = 0.
        total_val = 0.
        loss_val = 0.
        net.eval()
        with torch.no_grad():
            for j, data in enumerate(valid_loader):
                inputs, labels = data
                outputs = net(inputs)
                loss = criterion(outputs, labels)

                _, predicted = torch.max(outputs.data, 1)
                total_val += labels.size(0)
                correct_val += (predicted == labels).squeeze().sum().numpy()

                loss_val += loss.item()

            valid_curve.append(loss.item())
            print("Valid:\t Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2%}".format(
                epoch, MAX_EPOCH, j+1, len(valid_loader), loss_val, correct / total))

            # 驗證集:記錄資料,保存於event file
            writer.add_scalars("Loss", {"Valid": np.mean(valid_curve)}, iter_count)
            writer.add_scalars("Accuracy", {"Valid": correct / total}, iter_count)

(1)scalar



(2)histogram