Pytorch-Visdom可視化工具


Visdom相比TensorBoardX,更簡潔方便一些(例如對image數據的可視化可以直接使用Tensor,而不必轉到cpu上再轉為numpy數據),刷新率也更快。

1.安裝visdom

pip install visdom

2.開啟監聽進程

visdom本質上是一個web服務器,開啟web服務器之后程序才能向服務器丟數據,web服務器把數據渲染到網頁中去。

python -m visdom.server

但是很不幸報錯了!ERROR:root:Error [Errno 2] No such file or directory while downloading https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_SVG,所以從頭再來,先pip uninstall visdom卸掉visdom,再手動安裝。

  1. 從網站下載visdom源文件https://github.com/facebookresearch/visdom並解壓
  2. command進入visdom所在文件目錄,比如我的是cd F:\Chrome_Download\visdom-master
  3. 進入目錄后執行pip install -e .
  4. 執行成功后,退回到用戶目錄,重新執行上面的python -m visidom.server
  5. 然后又報錯了,一直提示Downloading scripts, this may take a little while,解決方案見https://github.com/casuallyName/document-sharing/tree/master/static
  6. 直到如圖所示即啟動成功

3.訪問

用chrome瀏覽器訪問url連接:http://localhost:8097

沒想到又又報錯了,頁面加載失敗(藍色空白頁面如下)

在visdom安裝目錄下(我的是F:\Anaconda\Lib\site-packages\visdom),將static文件夾換掉,下載地址為

鏈接:https://pan.baidu.com/s/1fZb-3GSZvk0kRpL73MBgcw
提取碼:np04

直到出現橫條框即visdom可用。

4.可視化訓練

 在之前定義網絡結構(參考上一節)的基礎上加上Visdom可視化。

  • 在訓練-測試的迭代過程之前,定義兩條曲線,在訓練-測試的過程中再不斷填充點以實現曲線隨着訓練動態增長:
1 from visdom import Visdom
2 viz = Visdom()
3 viz.line([0.], [0.], win='train_loss', opts=dict(title='train loss'))
4 viz.line([[0.0, 0.0]], [0.], win='test', opts=dict(title='test loss&acc.',legend=['loss', 'acc.']))

第二行Visdom(env="xxx")參數env來設置環境窗口的名稱,這里什么都沒傳,在默認的main窗口下。

viz.line的前兩個參數是曲線的Y和X的坐標(前面是縱軸后面才是橫軸),設置了不同的win參數,它們就會在不同的窗口中展示,

第四行定義的是測試集的loss和acc兩條曲線,所以在X等於0時Y給了兩個初始值。

  • 為了知道訓練了多少個batch,設置一個全局的計數器:
1 global_step = 0
  • 在每個batch訓練完后,為訓練曲線添加點,來讓曲線實時增長:
1 global_step += 1
2 viz.line([loss.item()], [global_step], win='train_loss', update='append')

這里用win參數來選擇是哪條曲線,用update='append'的方式添加曲線的增長點,前面是Y坐標,后面是X坐標。

  • 在每次測試結束后,並在另外兩個窗口(用win參數設置)中展示圖像(.images)和真實值(文本用.text):
1 viz.line([[test_loss, correct / len(test_loader.dataset)]],
2              [global_step], win='test', update='append')
3 viz.images(data.view(-1, 1, 28, 28), win='x')
4 viz.text(str(pred.detach().numpy()), win='pred',
5              opts=dict(title='pred'))

附上完整代碼:

  1 import  torch
  2 import  torch.nn as nn
  3 import  torch.nn.functional as F
  4 import  torch.optim as optim
  5 from   torchvision import datasets, transforms
  6 from visdom import Visdom
  7 
  8 #超參數
  9 batch_size=200
 10 learning_rate=0.01
 11 epochs=10
 12 
 13 #獲取訓練數據
 14 train_loader = torch.utils.data.DataLoader(
 15     datasets.MNIST('../data', train=True, download=True,          #train=True則得到的是訓練集
 16                    transform=transforms.Compose([                 #transform進行數據預處理
 17                        transforms.ToTensor(),                     #轉成Tensor類型的數據
 18                        #transforms.Normalize((0.1307,), (0.3081,)) #進行數據標准化(減去均值除以方差)
 19                    ])),
 20     batch_size=batch_size, shuffle=True)                          #按batch_size分出一個batch維度在最前面,shuffle=True打亂順序
 21 
 22 #獲取測試數據
 23 test_loader = torch.utils.data.DataLoader(
 24     datasets.MNIST('../data', train=False, transform=transforms.Compose([
 25         transforms.ToTensor(),
 26         #transforms.Normalize((0.1307,), (0.3081,))
 27     ])),
 28     batch_size=batch_size, shuffle=True)
 29 
 30 
 31 class MLP(nn.Module):
 32 
 33     def __init__(self):
 34         super(MLP, self).__init__()
 35         
 36         self.model = nn.Sequential(         #定義網絡的每一層,
 37             nn.Linear(784, 200),
 38             nn.ReLU(inplace=True),
 39             nn.Linear(200, 200),
 40             nn.ReLU(inplace=True),
 41             nn.Linear(200, 10),
 42             nn.ReLU(inplace=True),
 43         )
 44 
 45     def forward(self, x):
 46         x = self.model(x)
 47         return x    
 48 
 49 
 50 net = MLP()
 51 #定義sgd優化器,指明優化參數、學習率,net.parameters()得到這個類所定義的網絡的參數[[w1,b1,w2,b2,...]
 52 optimizer = optim.SGD(net.parameters(), lr=learning_rate)
 53 criteon = nn.CrossEntropyLoss()
 54 
 55 viz = Visdom()
 56 viz.line([0.], [0.], win='train_loss', opts=dict(title='train loss'))
 57 viz.line([[0.0, 0.0]], [0.], win='test', opts=dict(title='test loss&acc.',
 58                                                    legend=['loss', 'acc.%']))
 59 global_step = 0
 60 
 61 
 62 for epoch in range(epochs):
 63 
 64     for batch_idx, (data, target) in enumerate(train_loader):
 65         data = data.view(-1, 28*28)          #將二維的圖片數據攤平[樣本數,784]
 66 
 67         logits = net(data)                   #前向傳播
 68         loss = criteon(logits, target)       #nn.CrossEntropyLoss()自帶Softmax
 69 
 70         optimizer.zero_grad()                #梯度信息清空   
 71         loss.backward()                      #反向傳播獲取梯度
 72         optimizer.step()                     #優化器更新
 73 
 74         global_step += 1
 75         viz.line([loss.item()], [global_step], win='train_loss', update='append')
 76 
 77     
 78         if batch_idx % 100 == 0:             #每100個batch輸出一次信息
 79             print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
 80                 epoch, batch_idx * len(data), len(train_loader.dataset),
 81                        100. * batch_idx / len(train_loader), loss.item()))
 82 
 83 
 84     test_loss = 0
 85     correct = 0                                         #correct記錄正確分類的樣本數
 86     for data, target in test_loader:
 87         data = data.view(-1, 28 * 28)
 88         logits = net(data)
 89         test_loss += criteon(logits, target).item()     #其實就是criteon(logits, target)的值,標量
 90         
 91         pred = logits.data.max(dim=1)[1]                #也可以寫成pred=logits.argmax(dim=1)
 92         correct += pred.eq(target.data).sum()
 93 
 94 
 95     viz.line([[test_loss, 100.* correct / len(test_loader.dataset)]],
 96              [global_step], win='test', update='append')
 97     viz.images(data.view(-1, 1, 28, 28), win='x')
 98     viz.text(str(pred.detach().numpy()), win='pred',
 99              opts=dict(title='pred'))
100 
101 
102     test_loss /= len(test_loader.dataset)
103     print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
104         test_loss, correct, len(test_loader.dataset),
105         100. * correct / len(test_loader.dataset)))

Train Epoch: 0 [0/60000 (0%)] Loss: 2.301824
Train Epoch: 0 [20000/60000 (33%)] Loss: 2.285871
Train Epoch: 0 [40000/60000 (67%)] Loss: 2.262092

Test set: Average loss: 0.0112, Accuracy: 3499/10000 (35%)

Train Epoch: 1 [0/60000 (0%)] Loss: 2.226518
Train Epoch: 1 [20000/60000 (33%)] Loss: 2.188961
Train Epoch: 1 [40000/60000 (67%)] Loss: 2.087539

Test set: Average loss: 0.0101, Accuracy: 3653/10000 (37%)

Train Epoch: 2 [0/60000 (0%)] Loss: 1.965714
Train Epoch: 2 [20000/60000 (33%)] Loss: 1.886761
Train Epoch: 2 [40000/60000 (67%)] Loss: 1.871282

Test set: Average loss: 0.0088, Accuracy: 4404/10000 (44%)

Train Epoch: 3 [0/60000 (0%)] Loss: 1.822776
Train Epoch: 3 [20000/60000 (33%)] Loss: 1.687571
Train Epoch: 3 [40000/60000 (67%)] Loss: 1.720948

Test set: Average loss: 0.0079, Accuracy: 4717/10000 (47%)

Train Epoch: 4 [0/60000 (0%)] Loss: 1.589682
Train Epoch: 4 [20000/60000 (33%)] Loss: 1.544680
Train Epoch: 4 [40000/60000 (67%)] Loss: 1.413445

Test set: Average loss: 0.0074, Accuracy: 4807/10000 (48%)

Train Epoch: 5 [0/60000 (0%)] Loss: 1.410685
Train Epoch: 5 [20000/60000 (33%)] Loss: 1.442557
Train Epoch: 5 [40000/60000 (67%)] Loss: 1.318121

Test set: Average loss: 0.0067, Accuracy: 5742/10000 (57%)

Train Epoch: 6 [0/60000 (0%)] Loss: 1.244786
Train Epoch: 6 [20000/60000 (33%)] Loss: 1.322500
Train Epoch: 6 [40000/60000 (67%)] Loss: 1.340830

Test set: Average loss: 0.0059, Accuracy: 6304/10000 (63%)

Train Epoch: 7 [0/60000 (0%)] Loss: 1.295525
Train Epoch: 7 [20000/60000 (33%)] Loss: 1.222254
Train Epoch: 7 [40000/60000 (67%)] Loss: 1.070692

Test set: Average loss: 0.0041, Accuracy: 7704/10000 (77%)

Train Epoch: 8 [0/60000 (0%)] Loss: 0.833216
Train Epoch: 8 [20000/60000 (33%)] Loss: 0.719662
Train Epoch: 8 [40000/60000 (67%)] Loss: 0.654462

Test set: Average loss: 0.0028, Accuracy: 8470/10000 (85%)

Train Epoch: 9 [0/60000 (0%)] Loss: 0.497108
Train Epoch: 9 [20000/60000 (33%)] Loss: 0.509768
Train Epoch: 9 [40000/60000 (67%)] Loss: 0.493004

Test set: Average loss: 0.0023, Accuracy: 8681/10000 (87%)

Tip:一開始viz.images()那一句圖片沒有顯示,需要把第18和26行的代碼注釋掉,顯示數據的時候不需要標准化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM