PyTorch框架学习十五——可视化工具TensorBoard
PyTorch框架學(xué)習(xí)十五——可視化工具TensorBoard
- 一、TensorBoard簡(jiǎn)介
- 二、TensorBoard安裝及測(cè)試
- 三、TensorBoard的使用
- 1.add_scalar()
- 2.add_scalars()
- 3.add_histogram()
- 4.add_image()
- 5.add_graph()
之前的筆記介紹了模型訓(xùn)練中的數(shù)據(jù)、模型、損失函數(shù)和優(yōu)化器,下面將介紹迭代訓(xùn)練部分的知識(shí),而迭代訓(xùn)練過(guò)程中我們會(huì)想要監(jiān)測(cè)或查看一些中間變量,所以先介紹一下PyTorch的可視化,使用的是TensorBoard。TensorBoard可以幫助顯示很多重要的中間訓(xùn)練過(guò)程,如可視化損失值、準(zhǔn)確率的變化,特征圖的顯示,模型的計(jì)算圖(結(jié)構(gòu))以及網(wǎng)絡(luò)層的權(quán)重分布等等,非常有利于分析模型的正確性,方便理解和調(diào)整模型。
一、TensorBoard簡(jiǎn)介
TensorBoard是TensorFlow中強(qiáng)大的可視化工具,支持顯示標(biāo)量、圖像、文本、音頻、視頻和Embedding等多種數(shù)據(jù)可視化。其在PyTorch中也能使用。
它的運(yùn)行機(jī)制如下圖所示:
在程序中加入記錄可視化數(shù)據(jù)的代碼,程序運(yùn)行的時(shí)候會(huì)在硬盤(pán)生成event file,將需要記錄和顯示的數(shù)據(jù)存入event file,TensorBoard就可以讀取event file里的數(shù)據(jù)并在終端(默認(rèn)網(wǎng)頁(yè))進(jìn)行繪制。
二、TensorBoard安裝及測(cè)試
TensorBoard的安裝也是很簡(jiǎn)單的,打開(kāi)Anaconda的終端,進(jìn)入需要安裝TensorBoard的虛擬環(huán)境:
然后輸入pip install tensorboard,就會(huì)自動(dòng)安裝:
ps:可能還需要手動(dòng)再安裝一個(gè)future包,如果在安裝TensorBoard時(shí)沒(méi)有自動(dòng)安裝的話。
用一個(gè)例子來(lái)試驗(yàn)一下TensorBoard是否可以使用,先不用管代碼具體什么意思:
import numpy as np from torch.utils.tensorboard import SummaryWriterwriter = SummaryWriter(comment='test_tensorboard')for x in range(100):writer.add_scalars('data/scalar_group', {"xsinx": x * np.sin(x),"xcosx": x * np.cos(x),"arctanx": np.arctan(x)}, x) writer.close()運(yùn)行沒(méi)有報(bào)錯(cuò)之后,在終端進(jìn)入該虛擬環(huán)境該路徑下,輸入tensorboard --logdir=./,如下圖所示:
會(huì)給出一個(gè)網(wǎng)址,點(diǎn)進(jìn)去之后就是TensorBoard的終端網(wǎng)頁(yè),以及繪制好的圖像:
以上就是安裝以及測(cè)試的簡(jiǎn)介。
三、TensorBoard的使用
首先需要介紹SummaryWriter類:
class SummaryWriter(object):def __init__(self, log_dir=None, comment='', purge_step=None, max_queue=10,flush_secs=120, filename_suffix=''):功能:提供創(chuàng)建event file的高級(jí)接口。
主要屬性:(都與event file的創(chuàng)建路徑有關(guān))
舉幾個(gè)例子就明白了:
首先是指定log_dir的:
創(chuàng)建的event file的路徑如下圖所示:
都是按照l(shuí)og_dir指定的路徑創(chuàng)建,此時(shí)comment雖然指定但是不起作用,event file后面也帶上了filename_suffix的后綴12345678。
再來(lái)看一下不指定log_dir的例子:
writer = SummaryWriter(comment='_scalars', filename_suffix="12345678")for x in range(100):writer.add_scalar('y=pow_2_x', 2 ** x, x)writer.close()創(chuàng)建的event file的路徑如下圖所示:
這邊的runs/時(shí)間+設(shè)備型號(hào)/event file是默認(rèn)的創(chuàng)建路徑,comment指定的‘_scalars’是加在了時(shí)間+設(shè)備型號(hào)這個(gè)文件夾后面,即event file的上級(jí)目錄,filename_suffix指定的‘12345678’還是加在event file后面。
以上是SummaryWriter類的使用簡(jiǎn)介,下面將介紹SummaryWriter類下的具體方法,用以在TensorBoard中進(jìn)行繪制。
1.add_scalar()
功能:記錄標(biāo)量。
add_scalar(self, tag, scalar_value, global_step=None, walltime=None)主要參數(shù):
舉例如下:
max_epoch = 100writer = SummaryWriter(comment='test_comment', filename_suffix="test_suffix")for x in range(max_epoch):writer.add_scalar('y=2x', x * 2, x)writer.add_scalar('y=pow_2_x', 2 ** x, x)writer.close()分別可視化了y=2x和y=pow_2_x,如下圖所示:
2.add_scalars()
功能:在一張圖中記錄多個(gè)標(biāo)量。
add_scalars(self, main_tag, tag_scalar_dict, global_step=None, walltime=None)主要參數(shù):
例子的話,剛剛測(cè)試的時(shí)候的代碼就是用到了add_scalars(),具體見(jiàn)上面。
3.add_histogram()
功能:統(tǒng)計(jì)直方圖與多分位數(shù)折線圖。
add_histogram(self, tag, values, global_step=None, bins='tensorflow', walltime=None, max_bins=None)主要參數(shù):
舉例如下:
writer = SummaryWriter(comment='test_comment', filename_suffix="test_suffix")for x in range(2):np.random.seed(x)data_union = np.arange(100)data_normal = np.random.normal(size=1000)writer.add_histogram('distribution union', data_union, x)writer.add_histogram('distribution normal', data_normal, x)writer.close()可視化了一個(gè)正態(tài)分布和均勻分布:
4.add_image()
功能:記錄圖像,將CHW、HWC或HW格式的圖像可視化。
add_image(self, tag, img_tensor, global_step=None, walltime=None, dataformats='CHW')主要參數(shù):
需要注意的是img_tensor這個(gè)參數(shù),當(dāng)輸入圖像的像素全都小于等于1時(shí),會(huì)自動(dòng)將所有像素值乘255,若有大于1的,則保持不變。
舉例:
writer = SummaryWriter(comment='test_your_comment', filename_suffix="_test_your_filename_suffix")# img 1 random fake_img = torch.randn(3, 512, 512) writer.add_image("fake_img", fake_img, 1) time.sleep(1)# img 2 ones fake_img = torch.ones(3, 512, 512) time.sleep(1) writer.add_image("fake_img", fake_img, 2)# img 3 1.1 fake_img = torch.ones(3, 512, 512) * 1.1 time.sleep(1) writer.add_image("fake_img", fake_img, 3)# img 4 HW fake_img = torch.rand(512, 512) writer.add_image("fake_img", fake_img, 4, dataformats="HW")# img 5 HWC fake_img = torch.rand(512, 512, 3) writer.add_image("fake_img", fake_img, 5, dataformats="HWC")writer.close()這里構(gòu)造了五張圖片,第一張是隨機(jī)產(chǎn)生的三通道圖像,第二張是像素值全為1的三通道圖像,第三張為像素值全為1.1的三通道圖像,第四張為像素值全都小于1的灰度圖像,第五張為像素值全都小于1的三通道圖像,只是通道數(shù)在最后一維,結(jié)果如下圖所示:
第一張:
第二張,像素值全乘了255,1×255即全為255,顯示全白:
第三張,像素值全為1.1,超過(guò)了1,不乘255,因?yàn)橄袼刂堤?#xff0c;顯示接近全黑:
第四張:
第五張:
但是add_image單獨(dú)使用的話有個(gè)缺點(diǎn),就是圖像只會(huì)排成一行,一次顯示一張,通過(guò)拖動(dòng)下面這個(gè)東西來(lái)切換不同的圖像,非常麻煩:
所以接下來(lái)介紹torchvision.utils.make_grid,使用它制作網(wǎng)格圖像再使用add_image進(jìn)行顯示。
功能:制作網(wǎng)格圖像。
主要參數(shù):
舉例:
writer = SummaryWriter(comment='test_your_comment', filename_suffix="_test_your_filename_suffix")split_dir = os.path.join("..", "..", "data", "rmb_split") train_dir = os.path.join(split_dir, "train") # train_dir = "path to your training data"transform_compose = transforms.Compose([transforms.Resize((32, 64)), transforms.ToTensor()]) train_data = RMBDataset(data_dir=train_dir, transform=transform_compose) train_loader = DataLoader(dataset=train_data, batch_size=16, shuffle=True) data_batch, label_batch = next(iter(train_loader))# img_grid = vutils.make_grid(data_batch, nrow=4, normalize=True, scale_each=True) img_grid = vutils.make_grid(data_batch, nrow=4, normalize=False, scale_each=False) writer.add_image("input img", img_grid, 0)writer.close()data_batch是我自己構(gòu)造的一個(gè)包含了16張人民幣圖像的張量,行數(shù)為4,padding和pad_value都用默認(rèn),normalize和scale_each都為False,然后將構(gòu)建好的網(wǎng)格圖像送入add_image,顯示結(jié)果如下所示:
這樣一次性全部顯示要比拖動(dòng)來(lái)的更為直觀。
5.add_graph()
功能:可視化模型計(jì)算圖(數(shù)據(jù)流方向),通常觀察模型結(jié)構(gòu)。
add_graph(self, model, input_to_model=None, verbose=False)主要參數(shù):
舉例:
writer = SummaryWriter(comment='test_your_comment', filename_suffix="_test_your_filename_suffix")# 模型 fake_img = torch.randn(1, 3, 32, 32)lenet = LeNet(classes=2)writer.add_graph(lenet, fake_img)writer.close()from torchsummary import summary print(summary(lenet, (3, 32, 32), device="cpu"))繪制出了計(jì)算圖:
也可以查看LeNet的內(nèi)部結(jié)構(gòu):
但是直接分析計(jì)算圖是比較復(fù)雜的,這里還給出了一個(gè)更直觀的包 torchsummary ,其中的summary函數(shù)可以總結(jié)出每一層網(wǎng)絡(luò)層的輸出尺寸、參數(shù)量以及占用多少內(nèi)存等關(guān)鍵信息,上述LeNet的信息如下:
torchsummary
功能:查看模型信息,便于調(diào)試。
summary(model, input_size, batch_size=-1, device="cuda")主要參數(shù):
總結(jié)
以上是生活随笔為你收集整理的PyTorch框架学习十五——可视化工具TensorBoard的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux学习之嵌入式Linux编程文件
- 下一篇: C语言中的自定义类型