0703-可视化工具tensorboard和visdom
0703-可视化工具tensorboard和visdom
pytorch完整教程目录:https://www.cnblogs.com/nickchen121/p/14662511.html
一、可视化工具概述
当我们训练神经网络的时候,我们可能希望更加直观地了解训练情况,包括损失曲线、输入图片、输出图片、卷积核的参数分布等信息。这些信息能帮我们更好地监督网络的训练过程,并且能够为参数优化提供方向和数据。
以往我们都是通过 print 打印输出,但是只能打印信息,并且很多数据不够直观。本节我们将介绍两个深度学习中常用的可视化工具——TensorBoard 和 visdom,它们能更直观的体现很多信息。
二、TensorBoard
TensorBoard 起初是 作为 TensorFlow 的可视化工具迅速流行开的,作为和 tf 深度集成的工具,tensorboard 能够展现 tf 的网络计算图,绘制图像生成定量指标图及附加数据,界面如下图所示:
虽然 TensorBoard 和 tf 深度集成,但是 TensorBoard 是一个相对独立的工具,只要用户保存的数据遵循相应的格式,tensorboard 就能读取这些数据并进行可视化。
接下来将会介绍如何在 torch 中使用 tensorboard_logger 进行训练损失的可视化。
tensorboard_logger 是 TeamHG-Memex 开发的一款轻量级工具,它把 TensorBoard 的功能抽取出来,让非 TensorBoard 用户也能使用它进行可视化,但是支持的功能有限。
tensorboard_logger 的安装主要分为以下两步:
- 安装 TensorFlow:建议安装 tf 的 cpu-only 版本,具体安装教程参考 TensorFlow 官方文档 - pip 安装
- 安装 tensorboard_logger:可以通过
pip install tensorboard_logger
命令直接安装
tensorboard_logger 安装结束后,可以通过以下命令直接启动 TensorBoard:tensorboard --logdir <your/running/dir> --port <your_bind_port>
,其中 <your/running/dir>
是当前运行文件所属的文件夹。
下面举例来说明 tensorboard_logger 的使用。
from tensorboard_logger import Logger
# 构建 logger 对象,logdir 用来指定 log 文件的保存路径
# flush_secs 用来指定刷新同步间隔
logger = Logger(logdir='experimient_cnn', flush_secs=2)
for ii in range(100):
logger.log_value('loss', 10 - ii * 0.5, step=ii)
logger.log_value('accuracy', ii**0.5 / 10)
打开浏览器输入 http://localhost:6006
(其中 6006 是默认的 <your_bind_port>
),即可以看到如图所示的结果:
上图左侧的 Horizontal Axis 下有如下三个选项:
- Step:根据步长来记录,log_value 是指如果有步长,则把它作为 x 轴坐标描点划线
- Relative:用前后相对顺序描点划线,可以认为 logger 自己维护了一个 step 属性,每调用一次 log_value 就自动加 1
- Wall:按时间排序描点划线
左侧的 Smoothing 条可以左右拖动,用来调节平滑的幅度。因为默认是 30s 自动刷新数据,因此可以单击页面右上角的刷新按钮立即刷新结果。
虽然 tensorboard_logger 的使用十分简单,但它只能统计简单的数值信息,暂不支持其他功能。
除了 tensorboard_logger,还有专门针对 torch 开发的 TensorBoardX,它封装了更多的 tensorboard 接口,支持记录标量、图片、直方图、声音、文本、计算图和 embedding 等信息,几乎包括和 tf 的 TensorBoard 完全一样的功能,并且使用接口更加简单,有兴趣的同学可以自行学习。
三、Visdom
3.1 visdom 概述
visdom 是 Facebook 专门为 torch 开发的一款可视化工具,它非常轻量级,但是却支持非常丰富的功能,能胜任大多数的科学运算可视化任务,它的可视化界面如下图所示:
visdom 可以创造、组织和共享多种数据的可视化,包括数值、图像、文本,甚至是视频,支持 PyTorch、Torch 和 Numpy。
用户可以通过编程组织可视化空间或通过用户接口为数据打造仪表板,检查实验结果和调试代码。
visdom 中有以下两个重要概念:
- env:环境。不同环境的可视化结果相互隔离,互不影响,使用的时候如果不指定 env,默认使用 main。不同用户、不同的程序一般使用不同的 env。
- pane:窗格。窗格可以用于可视化图像、数值或打印文本等,它可以拖动、缩放、保存和关闭。一个程序可以使用同一个 env 中的不同 pane,每个 pane 可视化或记录某一信息。
如下图所示,当前 env 下有两个 pane,一个用于打印 log,另外一个用于记录损失函数的变化。单击 “clear” 按钮可以清空当前 env 的所有 pane,单击 “save” 按钮可以把当前 env 保存成 json 文件,保存路径位于 ~/.visdom/
目录下。修改 env 的名字后单击 fork,可以将当前 env 另存为新文件。
通过命令 pip install visdom
就可以完成 visdom 的安装。安装完成后,需要通过 python -m visdom.server
命令启动 visdom 服务,或通过 nohup python -m visdom.server &
命令把服务放到后台运行。visdom 服务是一个 Web Server 服务,默认绑定 8097 端口,客户端和服务器间通过 tornado 进行非堵塞交互。
因此在使用 visdom 时有两点需要注意的地方:
- 需要手动指定保存 env,可以在 Web 界面单击 “save” 按钮或在程序中调用 save 方法,否则 visdom 服务重启后,env 等信息会丢失
- 客户端和服务器之间的交互采用 tornado 异步框架,可视化操作不会堵塞当前程序,网络异常也不会导致程序退出
3.2 visdom 的常用操作
visdom 以 Plotly 为基础,支持丰富的可视化操作,下面举例说明一些最常用的操作。
# 启动visdom 服务器
# nohup python -m visdom.server &
import visdom
import torch as t
# 新建一个连接客户端
# 指定 env=u'test1',默认端口为 8097,host 是 'localhost'
vis = visdom.Visdom(env=u'test1')
x = t.arange(1, 30, 0.01)
y = t.sin(x)
vis.line(X=x, Y=y, win='sinx', opts={'title': 'y=sin(x)'})
Setting up a new session...
'sinx'
下面我们逐一分析上述代码:
vis = visdom.Visdom(env=t'test1')
,用于构建一个客户端,客户端除了指定 env 外,还可以指定 host、port 等参数。- vis 作为一个客户端对象,可以使用如下常见的画图函数:
- line:类似 MATLAB 中的 plot 操作,用于记录某些标量的变化,例如损失、准确率等
- image:可视化图片,可以是输入的图片,也可以是 GAN 生成的图片,还可以是卷积核的信息
- text:用于记录日志等文字信息,支持 HTML 格式
- histgram:可视化分布,主要是查看数据、参数的分布
- scatter:绘制散点图
- bar:绘制柱状图
- pie:绘制饼状图
- 更过操作可以参考 visdom 的 GitHub 主页
本节主要介绍深度学习中常见的 line、immage 和 text 的操作。
注:visdom 同时支持 torch 的 tensor 和 numpy 的 ndarray 两种数据结构,但不支持 python 的 int 和 float 等数据类型,因此每次传入时都需要先把数据转成 ndarray 或 tensor。
上述操作的参数一般不同,但有两个参数时绝大多数操作都具备的:
- win:用于指定 pane 的名字,如果不指定,visdom 将自动分配一个新的 pane。如果两次操作指定的 pane 的名字一样,则后者会覆盖前者,因此建议每次操作都指定 win
- opts:用来可视化配置,接收一个字典,常见的 option 包括 title、xlabel、ylabel、width 等,主要用于设置 pane 的显示格式
3.3 visdom.line 可视化和 update 操作
之前说过,每次操作都会覆盖之前的数值,但我们在训练过程中往往需要不断更新数值,如损失值等,这个时候就需要指定参数 update='append'
来避免覆盖之前的数值。
# append 追加数据
for ii in range(0, 10):
# y = x
x = t.Tensor([ii])
y = x
vis.line(X=x, Y=y, win='polynomial', update='append' if ii > 0 else None)
# updateTrace 新增一条线,由于使用了update='append',不会覆盖原来的数据
x = t.arange(0, 9, 0.1)
y = (x**2) / 9
vis.line(X=x,
Y=y,
win='polynomial',
name='this is a new Trace',
update='append')
'polynomial'
3.4 visdom.image(images) 可视化
images 的画图功能可分为如下两类:
- image 接收一个二维或三维向量,H×W 或 3×H×W,前者是黑白图像,后者是彩色图像
- images 接收一个四维向量 N×C×H×W,C 可以是 1 或 3,分别代表黑白和彩色图像。可实现类似 torchvision 中 make_grid 的功能,可以让多张图片拼接在一起。images 也可以接收一个二维或三维的向量,此时它所实现的功能和 image 一致
# 可视化一张随机的黑白图片
vis.image(t.randn(64, 64).numpy())
# 可视化一张随机的彩色图片
vis.image(t.randn(3, 64, 64).numpy(), win='random2')
# 可视化 36 张随机的彩色图片,每一行 6 张
vis.images(t.randn(36, 3, 64, 64).numpy(),
nrow=6,
win='random3',
opts={'title': 'random_imgs'})
'random3'
3.5 visdom.text 可视化
vis.text 用于可视化文本,它支持所有的 html 标签,同时也遵循着 html 的语法标准,下面举例说明。
text = u'''
<h1>Hello visdom</h1><br>
Nick 是不是<b>最帅的</b><br>
……是的'''
vis.text(text=text, win='visdom', opts={'title': u'visdom 和 nick'})
'visdom'