【學習筆記】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...)
實驗
(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