文章目录(Table of Contents)
简介
在模型的训练过程中,我们通常会打印许多的统计值来告诉我们训练得怎么样。除了输出为日志之外,我们可以使用 Tensorboard
来做得更好。本文主要是介绍如何使用 Pytorch
结合 Tensorboard
对训练过程进行可视化。
使用之前需要先安装 tensorboard
库:
- pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorboard
参考资料
- Pytorch 官方 Tensorboard 说明,VISUALIZING MODELS, DATA, AND TRAINING WITH TENSORBOARD;
- SummaryWriter 包含的方法,TORCH.UTILS.TENSORBOARD
Tensorboard 使用指南
Tensorboard 添加单个指标
我们可以在 torch.utils
中来 import tensorboard
,接着定义一个 SummaryWriter
来将信息写入 Tensorboard
。
下面来看一个简单的例子,甚至没有「神经网络」,我们使用 Tensorboard
记录一些数字。我们定义了 sin
,cos
和 tan
三个函数。现在通过 add_scalar
来将信息记录在 Tensorboard
中。add_scalar
中输入的值为,「变量的名称,变量的值,当前迭代的次数」:
- import math
- import random
- from torch.utils.tensorboard import SummaryWriter
- for i in range(3):
- writer = SummaryWriter(log_dir='./runs/lr_{}'.format(i)) # create a writer
- funcs = {"sin": math.sin, "cos": math.cos, "tan": math.tan}
- for angle in range(-360, 360):
- angle_rad = angle * math.pi / 180
- for name, fun in funcs.items():
- val = fun(angle_rad) + random.randint(0, 2-i) # i 越大随机性越小
- # name of parameter, its value, current iteration
- writer.add_scalar(name, val, angle)
- writer.close()
运行上面的代码,会生产一个 runs
的文件夹,runs
文件夹下会有三个子文件夹,分别是 lr_0
,lr_1
和 lr_2
。接着在终端运行下面的命令,接着点击地址 http://localhost:6006/
即可查看:
- tensorboard --logdir=runs
对于上面的结果,我们可以看到如下所示的结果:
Tensorboard 中 add_scalar 的参数
下面我们来详细看一下 add_scalar
的使用。下面再看一个简单的例子:
- for iter in range(max_iters):
- output_logs = XXX
- for i,j in output_logs.items():
- writer.add_scalar(tag=i, scalar_value=j, global_step=iter)
其中的三个参数分别是:
tag
,要记录的数字的名字;scalar_value
,记录的数值;gloval_step
,当前的step
步数;
Tensorboard 添加多个指标
如果我们想把上面的 sin
,cos
和 tan
三个函数的结果记录在一个图像上,我们可以使用 add_scalars
来进行记录,下面是一个简答的例子:
- import math
- import random
- from torch.utils.tensorboard import SummaryWriter
- for i in range(3):
- writer = SummaryWriter(log_dir='./runs/lr_{}'.format(i)) # create a writer
- funcs = {"sin": math.sin, "cos": math.cos, "tan": math.tan}
- for angle in range(-360, 360):
- angle_rad = angle * math.pi / 180
- # name of parameter, its value, current iteration
- writer.add_scalars('run_test',
- {
- 'sin':funcs['sin'](angle_rad)+random.randint(0, 2-i),
- 'cos':funcs['cos'](angle_rad)+random.randint(0, 2-i),
- 'tan':funcs['tan'](angle_rad)+random.randint(0, 2-i)
- },
- angle)
- writer.close()
最终的结果如下图所示,可以看到一共运行了 3
次,每次包含 3
个函数的结果在一张图上:
Tensorboard 添加直方图
除了添加单个指标绘制为折线图之外,我们一次可以添加多个值从而绘制直方图(可以用来查看分布)。下面是一个简单的例子,我们添加 10 次,每次的均值 +1:
- import numpy as np
- import random
- from torch.utils.tensorboard import SummaryWriter
- writer = SummaryWriter()
- for i in range(10):
- x_random = np.array([random.random()+i for _ in range(1000)]) # 一组 1000 个随机数
- writer.add_histogram('distribution centers', x_random, i)
- writer.close()
运行上面代码,最终的结果如下图所示:
Tensorboard 记录图片
除了记录数据之外,我们还可以向 Tensorboard
中添加图片。如果是 matplotlib
的图片使用 add_figure
;如果是 pillow
的图片(或是 numpy
的数据),我们使用 add_image
。
首先看一个使用 add_image
来添加图片,我们一共添加了 16 张图片:
- from torch.utils.tensorboard import SummaryWriter
- writer = SummaryWriter()
- for i in range(16):
- img_batch = np.zeros((3, 100, 100))
- img_batch[0] = np.arange(0, 10000).reshape(100, 100) / 10000 / 16 * i
- img_batch[1] = (1 - np.arange(0, 10000).reshape(100, 100) / 10000) / 16 * i
- writer.add_image('my_image', img_batch, i)
- writer.close()
最终的效果如下图所示,我们可以拖动小圆点从而显示不同 step
的结果:
如果想要同时添加多张图片也是一样的,使用 add_image
。下面是添加多张的实例代码(下面的 image_batch
是有一个 batch_size
的维度的,上面的 add_image
是只有三维):
- img_batch = np.zeros((16, 3, 100, 100))
- for i in range(16):
- img_batch[i, 0] = np.arange(0, 10000).reshape(100, 100) / 10000 / 16 * i
- img_batch[i, 1] = (1 - np.arange(0, 10000).reshape(100, 100) / 10000) / 16 * i
- writer = SummaryWriter()
- writer.add_images('my_image_batch', img_batch, 0)
- writer.close()
Tensorboard 添加模型
我们还可以将模型添加到 Tensorboard
中,从而很方便的查看模型的结构。在下面的例子中,我们首先初始化一个网络,接着随机一个输入,最后使用 add_graph
将网络加入 tensorboard
:
- import torch
- import torch.nn as nn
- import torch.nn.functional as F
- from torch.utils.tensorboard import SummaryWriter
- class Net(nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- self.conv1 = nn.Conv2d(1, 6, 5)
- self.pool = nn.MaxPool2d(2, 2)
- self.conv2 = nn.Conv2d(6, 16, 5)
- self.fc1 = nn.Linear(16 * 4 * 4, 120)
- self.fc2 = nn.Linear(120, 84)
- self.fc3 = nn.Linear(84, 10)
- def forward(self, x):
- x = self.pool(F.relu(self.conv1(x)))
- x = self.pool(F.relu(self.conv2(x)))
- x = x.view(-1, 16 * 4 * 4)
- x = F.relu(self.fc1(x))
- x = F.relu(self.fc2(x))
- x = self.fc3(x)
- return x
- net = Net() # 初始化网络
- x_input = torch.rand(1, 1, 28, 28) # 随机一个 input
- # 写入 tensorboard
- writer = SummaryWriter()
- writer.add_graph(net, x_input)
- writer.close()
最终的结果如下图所示,我们可以双击 Net
查看具体的细节(这里因为展开之后太大,所以我们就不放展开之后的图片了),放大查看每一层输入和输出的数据维度:
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论