TensorboardX
pytorch有一個工具借鑒了tensorboard
pip install tensorboardX
有查看變量的數值、監聽曲線等功能
如何使用
新建SummaryWriter()實例
要把監聽的數據,比如說要監聽dummy_s1[0](y
坐標)存放到data/scalar1中,n_iter是哪一個epoch的(即x坐標,n_iter時間戳的數據)
tensorboard本質上是抽取numpy的數據,如果要跟tensor直接做轉換的話,需要把tensor轉換到cpu上
Visdom
visdom可以接收tensor,且運行效率更高,因為tensorboard會把數據寫到文件里面去,經常會導致監聽文件非常大
如何安裝visdompip install visdom
安裝完成之后需要開啟監聽的進程,visdom本質上是可一個web服務器,程序向web服務器丟數據,這個web服務器會把數據渲染到網頁上去
,因此確保程序在運行之前要確保開啟visdompython -m visdom.server
在windows上可能會遇到這個問題
如果遇到這個問題,從0開始安裝
- 先把現在安裝的visdom卸載
pip unstall visdom
- 從官方網頁下載最新的源代碼visdom
- 進入visdom目錄中運行
pip install -e.
這樣安裝會省略很多麻煩
退回到用戶目錄運行python -m visdom.server
功能
畫一條曲線,比如train loss
創建一條直線viz.line([0.],[0.],win='train_loss',opts=dict(title='train loss'))
首先給一個初始的點,這里只有一個點,第一個[0.]的意思是Y賦值為0,第二個[0.]的意思是X賦值為0,win是一個唯一的標識符可以理解為id,還有另外一個id叫env,visdom每一個大的窗口是一個env,這個窗口可以理解為程序,一個程序里面可能有很多小窗口,env不指定的話默認是main,會在main窗口里面創建小窗口,查詢現有的窗口有沒有train_loss這個id,沒有的話就會創建一個win,opts會配置額外的配置信息,比如把窗口名字命名成train_loss,可以很好的識別倒是的train_loss,還是test_loss
通過這句話會創建一個train_loss窗口,點只有[0,0]
viz.line([loss.item()],[global_step],win='train loss',update='append')
,在訓練的時候把數據逐步添加進去,X坐標是[global_step](時間戳),Y坐標是[loss.item()],對于非image數據傳入的還是一個numpy數據,但是image可以直接接收tensor,需要指定update操作時append,添加在當前的直線后面
多條曲線
一個曲線占用一個窗口的話,會使得窗口非常多
比如要同時看train loss 和 test loss,此時Y要同時傳入兩個數值[Y1,Y2],legend接收list,代表了Y1的label和Y2的label
兩條線范圍不一樣,loss是0到100,accuracy是0到1,看起來會很奇怪
visual X
可視化
data是[batch,1,28,28]的tensor,如果使用tensorboardX的話必須復制到cpu上,即.cpu().numpy()數據才能傳給tensorboard
還可以看字符串,把pred的值轉換成string類型
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transformsfrom visdom import Visdomdef load_data(batch_size):train_loader = torch.utils.data.DataLoader(datasets.MNIST('mnist_data', train=True, download=True,transform=transforms.Compose([transforms.ToTensor(),# transforms.Normalize((0.1307,), (0.3081,))])),batch_size=batch_size, shuffle=True)test_loader = torch.utils.data.DataLoader(datasets.MNIST('mnist_data', train=False, transform=transforms.Compose([transforms.ToTensor(),# transforms.Normalize((0.1307,), (0.3081,))])),batch_size=batch_size, shuffle=True)return train_loader, test_loaderclass MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.model = nn.Sequential(nn.Linear(784, 200),nn.LeakyReLU(inplace=True),nn.Linear(200, 200),nn.LeakyReLU(inplace=True),nn.Linear(200, 10),nn.LeakyReLU(inplace=True),)def forward(self, x):x = self.model(x)return xdef training(train_loader, device, net, viz, global_step):for batch_idx, (data, target) in enumerate(train_loader):data = data.view(-1, 28 * 28)data, target = data.to(device), target.cuda()logits = net(data)loss = criteon(logits, target)optimizer.zero_grad()loss.backward()# print(w1.grad.norm(), w2.grad.norm())optimizer.step()global_step += 1viz.line([loss.item()], [global_step], win='train_loss', update='append')if batch_idx % 100 == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader),loss.item()))def testing(test_loader, device, net, viz, global_step):test_loss = 0correct = 0for data, target in test_loader:data = data.view(-1, 28 * 28)data, target = data.to(device), target.cuda()logits = net(data)test_loss += criteon(logits, target).item()pred = logits.argmax(dim=1)correct += pred.eq(target).float().sum().item()viz.line([[test_loss, correct / len(test_loader.dataset)]],[global_step], win='test', update='append')viz.images(data.view(-1, 1, 28, 28), win='x')viz.text(str(pred.detach().cpu().numpy()), win='pred',opts=dict(title='pred'))test_loss /= len(test_loader.dataset)print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset),100. * correct / len(test_loader.dataset)))global netif __name__ == '__main__':batch_size = 200learning_rate = 0.01epochs = 10train_loader, test_loader = load_data(batch_size)device = torch.device('cuda:0')net = MLP().to(device)optimizer = optim.SGD(net.parameters(), lr=learning_rate)criteon = nn.CrossEntropyLoss().to(device)# 需要啟動Visdom# python -m visdom.serverviz = Visdom()viz.line([0.], [0.], win='train_loss', opts=dict(title='train loss'))viz.line([[0.0, 0.0]], [0.], win='test', opts=dict(title='test loss&acc.',legend=['loss', 'acc.']))global_step = 0for epoch in range(epochs):training(train_loader, device, net, viz, global_step)testing(test_loader, device, net, viz, global_step)