import torch import numpy as np import torch.nn as nn import torch.nn.functional as F from PIL import Image from torchvision import transforms from torchvision import models,datasets torch.__version__
'1.3.0'
4.2.2 visualization in PyTorch using Tensorboard
Introduction to Tensorboard
Tensorboard is a built-in visualization tool of tensorflow. It visualizes the information of the log file output by tensorflow program, which makes the understanding, debugging and optimization of tensorflow program more simple and efficient.
The visualization of tensorboard depends on the log file output by the tensorboard program, so the tensorboard and tensorflow programs run in different processes.
TensorBoard provides us with an extremely convenient and powerful visual environment. It can help us understand the learning process, data distribution, performance bottleneck and so on.
Although tensorboard is a built-in visualization tool of tensorflow, they run in different processes, so a great God on Github has applied tensorboard to pytoch Link here
Tensorboard installation
First, you need to install tensorboard
pip install tensorboard
~~Then install tensorboardx~~
~~ pip install tensorboardx ~~
In versions after pytorch 1.1, the SummaryWriter function is built in, so there is no need to install tensorboardx
After installation, execute independent commands like visdom
tensorboard --logdir logs can be started. The default port is 6006, which can be opened in the browser http://localhost:6006/ You can see the web page.
It should be noted here that the css of Microsoft's Edge browser cannot be loaded and displayed normally in chrome
page
Unlike visdom, tensorboard artificially distinguishes multiple tags for different types, and each tag page represents different types.
Let's make a brief introduction according to different page functions. For more details, please refer to the official website
SCALAR
The scalar data is summarized and recorded, which is usually used to visualize the change curve with the number of iterations, accuracy (val acc), loss (train/test loss), learning rate, weight of each layer and biased Statistics (mean, std, max/min) in the training process
IMAGES
Visualize the training / test images or feature maps used in the current round of training
GRAPHS
The structure and information on the visual calculation diagram are usually used to show the structure of the network
HISTOGRAMS
Visualize the value distribution of tensor and record the histogram of variables (statistical tensor changes with the number of iteration rounds)
PROJECTOR
Full name: Embedding Projector for visualization of high-dimensional vectors
use
Before using it, please confirm to execute tensorboard --logdir logs and ensure http://localhost:6006/ The page can be opened normally
Image display
First, introduce the relatively simple functions, and view the images in our training set and data set. Here, we use the ready-made images for display. Here is a picture of a cat on wikipedia here
Introduce tensorboardX package
# The reference here should also be modified to the reference of torch #from tensorboardX import SummaryWriter from torch.utils.tensorboard import SummaryWriter
cat_img = Image.open('./1280px-Felis_silvestris_catus_lying_on_rice_straw.jpg') cat_img.size
(1280, 853)
This is a picture of 1280x853. We first turn it into a picture of 224x224, because vgg16 will be used later
transform_224 = transforms.Compose([ transforms.Resize(224), # Here we need to explain that the Scale has expired. Use Resize transforms.CenterCrop(224), transforms.ToTensor(), ]) cat_img_224=transform_224(cat_img)
Display the picture in tebsorboard:
writer = SummaryWriter(log_dir='./logs', comment='cat image') # The logs here should be the same as the parameter of -- logdir writer.add_image("cat",cat_img_224) writer.close()# Execute close to refresh immediately, otherwise it will refresh automatically every 120 seconds
Browser access http://localhost:6006/#images You can see the picture of the cat
Update loss function
Update the loss function and training batch. We use simulation display like visdom. Here we use the SCALAR page of tensorboard
x = torch.FloatTensor([100]) y = torch.FloatTensor([500]) for epoch in range(30): x = x * 1.2 y = y / 1.1 loss = np.random.random() with SummaryWriter(log_dir='./logs', comment='train') as writer: #You can directly use python's with syntax to automatically call the close method writer.add_histogram('his/x', x, epoch) writer.add_histogram('his/y', y, epoch) writer.add_scalar('data/x', x, epoch) writer.add_scalar('data/y', y, epoch) writer.add_scalar('data/loss', loss, epoch) writer.add_scalars('data/data_group', {'x': x, 'y': y}, epoch)
Browser access http://localhost:6006/#scalars You can see the graphics
Visualization of high-dimensional vectors using project
The principle of project is to project high-dimensional vectors into three-dimensional coordinate system (dimensionality reduction) through PCA, T-SNE and other methods. The embedded PROJECTOR reads data from the checkpoint file saved during the operation of the model. By default, the principal component analysis (PCA) is used to project the high-dimensional data into the 3D space, or the T-SNE projection method can be selected by setting. Here is a simple demonstration.
We still use the mnist code in Chapter 3
BATCH_SIZE=512 EPOCHS=20 train_loader = torch.utils.data.DataLoader( datasets.MNIST('data', train=True, download=True, transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])), batch_size=BATCH_SIZE, shuffle=True)
class ConvNet(nn.Module): def __init__(self): super().__init__() # 1,28x28 self.conv1=nn.Conv2d(1,10,5) # 10, 24x24 self.conv2=nn.Conv2d(10,20,3) # 128, 10x10 self.fc1 = nn.Linear(20*10*10,500) self.fc2 = nn.Linear(500,10) def forward(self,x): in_size = x.size(0) out = self.conv1(x) #24 out = F.relu(out) out = F.max_pool2d(out, 2, 2) #12 out = self.conv2(out) #10 out = F.relu(out) out = out.view(in_size,-1) out = self.fc1(out) out = F.relu(out) out = self.fc2(out) out = F.log_softmax(out,dim=1) return out model = ConvNet() optimizer = torch.optim.Adam(model.parameters())
def train(model, train_loader, optimizer, epoch): n_iter=0 model.train() for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() output = model(data) loss = F.nll_loss(output, target) loss.backward() optimizer.step() if(batch_idx+1)%30 == 0: n_iter=n_iter+1 print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) #Compared with the previous training methods, the following contents are mainly added out = torch.cat((output.data, torch.ones(len(output), 1)), 1) # Because it is projected into 3D space, we only need three dimensions with SummaryWriter(log_dir='./logs', comment='mnist') as writer: #Use add_embedding method for visual display writer.add_embedding( out, metadata=target.data, label_img=data.data, global_step=n_iter)
Save time here and train only once
train(model, train_loader, optimizer, 0)
Train Epoch: 0 [14848/60000 (25%)] Loss: 0.352312 Train Epoch: 0 [30208/60000 (50%)] Loss: 0.202950 Train Epoch: 0 [45568/60000 (75%)] Loss: 0.156494
Open http://localhost:6006/#projector You can see the effect.
At present, there is also a problem with the test projection. The test can not be displayed according to the code in the official website document. We are looking for the reason
Draw network structure
In pytorch, we can use print to directly print the network structure, but this method has poor visualization effect. Here, we use GRAPHS of tensorboard to realize the visualization of network structure.
Because pytorch uses dynamic graph calculation, we need to manually carry out a forward propagation
Use the model built by pytoch for demonstration
vgg16 = models.vgg16(pretrained=True) # Download the pre trained model here print(vgg16) # Print this model
VGG( (features): Sequential( (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU(inplace=True) (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU(inplace=True) (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (6): ReLU(inplace=True) (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (8): ReLU(inplace=True) (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (11): ReLU(inplace=True) (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (13): ReLU(inplace=True) (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (15): ReLU(inplace=True) (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (18): ReLU(inplace=True) (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (20): ReLU(inplace=True) (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (22): ReLU(inplace=True) (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (25): ReLU(inplace=True) (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (27): ReLU(inplace=True) (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (29): ReLU(inplace=True) (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) ) (avgpool): AdaptiveAvgPool2d(output_size=(7, 7)) (classifier): Sequential( (0): Linear(in_features=25088, out_features=4096, bias=True) (1): ReLU(inplace=True) (2): Dropout(p=0.5, inplace=False) (3): Linear(in_features=4096, out_features=4096, bias=True) (4): ReLU(inplace=True) (5): Dropout(p=0.5, inplace=False) (6): Linear(in_features=4096, out_features=1000, bias=True) ) )
Make some adjustments to the picture before forward transmission
transform_2 = transforms.Compose([ transforms.Resize(224), transforms.CenterCrop((224,224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ])
Use the picture of the previous cat for forward propagation
vgg16_input=transform_2(cat_img)[np.newaxis]# Because pytorch is performed in batches, we create a data set with batch 1 vgg16_input.shape
torch.Size([1, 3, 224, 224])
Start forward propagation and print out the value
out = vgg16(vgg16_input) _, preds = torch.max(out.data, 1) label=preds.numpy()[0] label
287
Display the structure diagram on the tensorboard
with SummaryWriter(log_dir='./logs', comment='vgg161') as writer: writer.add_graph(vgg16, vgg16_input)
For version 1.3 of pytoch, there is a problem with the measured SummaryWriter when processing the structure diagram (or what parameters need to be added, which I haven't found yet), so I suggest you continue to use tensorboardx.