内容来源:
详解PyTorch项目使用TensorboardX进行训练可视化
TORCH.UTILS.TENSORBOARD
在本地显示远程服务器的TensorboardX结果
使用 pip 安装
pip install tensorboardX
从源码安装
git clone https://github.com/lanpa/tensorboardX && cd tensorboardX && python setup.py install
summarywriter1 = SummaryWriter(%target_dir)
runs/日期时间
来保存日志summarywriter2 = SummaryWriter()
runs/日期时间-comment
保存日志文件summarywriter3 = SummaryWriter(comment='experiment')
一般来讲,我们对于每次实验新建一个路径不同的 SummaryWriter,也叫一个 run,如 runs/exp1
、runs/exp2
。
接下来,我们就可以调用 SummaryWriter 实例的各种add_something
方法向日志中写入不同类型的数据了。
add_scalar(tag, scalar_value, global_step=None, walltime=None)
参数
.item()
方法获取其数值。我们一般会使用add_scalar
方法来记录训练过程的 loss、accuracy、learning rate 等数值的变化,直观地监控训练过程。from torch.utils.tensorboard import SummaryWriter
import numpy as np
writer = SummaryWriter('runs/scalar_example')
for n_iter in range(100):
writer.add_scalar('Loss/train', np.random.random(), n_iter)
writer.add_scalar('Loss/test', np.random.random(), n_iter)
writer.add_scalar('Accuracy/train', np.random.random(), n_iter)
writer.add_scalar('Accuracy/test', np.random.random(), n_iter)
在一个路径为 runs/scalar_example 的 run 中分别写入了二次函数数据 quadratic 和指数函数数据 exponential,
在另一个路径为 runs/another_scalar_example 的 run 中写入名称相同但参数不同的二次函数和指数函数数据
writer = SummaryWriter('runs/scalar_example')
for i in range(10):
writer.add_scalar('quadratic', i**2, global_step=i)
writer.add_scalar('exponential', 2**i, global_step=i)
writer = SummaryWriter('runs/another_scalar_example')
for i in range(10):
writer.add_scalar('quadratic', i**3, global_step=i)
writer.add_scalar('exponential', 3**i, global_step=i)
相同名称的量值被放在了同一张图表中展示,方便进行对比观察。同时,我们还可以在屏幕左侧的 runs 栏选择要查看哪些 run 的数据。
一次性添加多个数字数据可以使用add_scalars
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter()
r = 5
for i in range(100):
writer.add_scalars('run_14h', {'xsinx':i*np.sin(i/r),
'xcosx':i*np.cos(i/r),
'tanx': np.tan(i/r)}, i)
writer.close()
# This call adds three values to the same scalar plot with the tag
# 'run_14h' in TensorBoard's scalar section.
注意,该方法需要 pillow 库的支持。
add_image(tag, img_tensor, global_step=None, walltime=None, dataformats='CHW')
参数
形状
默认为 (3,H,W),可以使用torchvision.utils.make_grid()
将一批张量转换为 3xHxW 格式或调用add_images
并让我们完成这项工作。 (1, H, W),(H,W), (H,W,3) 的张量也适用,只要dataformats
传递相应的参数,例如CHW, HWC, HW.
from tensorboardX import SummaryWriter
import cv2 as cv
writer = SummaryWriter('runs/image_example')
for i in range(1, 6):
writer.add_image('countdown',
cv.cvtColor(cv.imread('{}.jpg'.format(i)), cv.COLOR_BGR2RGB),
global_step=i,
dataformats='HWC')
使用 opencv 读入图片,opencv 读入的图片通道排列是 BGR,因此需要先转成 RGB 以保证颜色正确,并且 dataformats 设为 ‘HWC’,而非默认的 ‘CHW’。调用这个方法一定要保证数据的格式正确,像 PyTorch Tensor 的格式就是默认的 ‘CHW’。效果如下,可以拖动滑动条来查看不同 global_step 下的图片:
add_image
方法只能一次插入一张图片。如果要一次性插入多张图片,有两种方法:
make_grid
方法将多张图片拼合成一张图片后,再调用 add_image 方法。add_images(tag, img_tensor, global_step=None, walltime=None, dataformats='NCHW')
参数
from torch.utils.tensorboard import SummaryWriter
import numpy as np
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()
add_histogram(tag, values, global_step=None, bins='tensorflow', walltime=None, max_bins=None)
参数
from tensorboardX import SummaryWriter
import numpy as np
writer = SummaryWriter('runs/embedding_example')
writer.add_histogram('normal_centered', np.random.normal(0, 1, 1000), global_step=1)
writer.add_histogram('normal_centered', np.random.normal(0, 2, 1000), global_step=50)
writer.add_histogram('normal_centered', np.random.normal(0, 3, 1000), global_step=100)
我们使用 numpy
从不同方差的正态分布中进行采样。打开浏览器可视化界面后,我们会发现多出了"DISTRIBUTIONS"和"HISTOGRAMS"两栏,它们都是用来观察数据分布的。其中在"HISTOGRAMS"中,同一数据不同 step 时候的直方图可以上下错位排布 (OFFSET) 也可重叠排布 (OVERLAY)。上下两图分别为"DISTRIBUTIONS"界面和"HISTOGRAMS"界面。
add_graph(model, input_to_model=None, verbose=False, **kwargs)
参数
add_embedding(mat, metadata=None, label_img=None, global_step=None, tag='default', metadata_header=None)
参数
add_embedding
是一个很实用的方法,不仅可以将高维特征使用PCA、t-SNE等方法降维至二维平面或三维空间显示,还可观察每一个数据点在降维前的特征空间的K近邻情况。下面例子中我们取 MNIST 训练集中的 100 个数据,将图像展成一维向量直接作为 embedding,使用 TensorboardX 可视化出来from tensorboardX import SummaryWriter
import torchvision
writer = SummaryWriter('runs/embedding_example')
mnist = torchvision.datasets.MNIST('mnist', download=True)
writer.add_embedding(
mnist.train_data.reshape((-1, 28 * 28))[:100,:],
metadata=mnist.train_labels[:100],
label_img = mnist.train_data[:100,:,:].reshape((-1, 1, 28, 28)).float() / 255,
global_step=0
)
采用 PCA 降维后在三维空间可视化效果如下:
可以发现,虽然还没有做任何特征提取的工作,但 MNIST 的数据已经呈现出聚类的效果,相同数字之间距离更近一些(有没有想到 KNN 分类器)。我们还可以点击左下方的 T-SNE
,用 t-SNE 的方法进行可视化
add_embedding
方法需要注意的几点:
tensorboard --logdir=log_dir