TensorBoard:训练过程可视化
本教程共 60 篇 · 第 30 篇 · 更新于 2026-08-17 · 约 4 分钟阅读
本节目标:学会用 TensorBoard 记录并查看训练曲线、图片和模型结构,学会从 loss 曲线判断模型状态。
训练为什么需要可视化
训练神经网络有点像开飞机:只看仪表上的一串数字,不如看仪表盘直观。loss 在降吗?降得快还是慢?中途有没有抖动?光靠 print 一堆数字,很难有整体感觉。
TensorBoard 就是给训练装上的仪表盘。它是 Google 出品的机器学习可视化工具,PyTorch 内置了对它的支持,记录数据的接口在 torch.utils.tensorboard 里。后面几章会反复用到「记录 + 查看」这套组合,越早熟练越省事。
安装与启动
先装工具包:
pip install tensorboard
用法分两步:训练代码里写日志,然后用命令启动看板。
tensorboard --logdir=runs
浏览器打开 http://localhost:6006,就能看到界面。`—logdir` 指定日志目录,TensorBoard 会递归寻找里面的事件文件。
SummaryWriter:写日志的那支笔
往 TensorBoard 写数据,全靠一个对象 SummaryWriter:
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("runs/exp1") # 日志写到 runs/exp1
之后所有记录都通过它完成。一个 writer 对应一个实验目录,想对比多次实验,就开不同的子目录。writer 创建后,对应目录和事件文件会自动生成,不用手动建文件夹。
记录标量:盯住 loss 曲线
最常见的需求是记录 loss。用 add_scalar(tag, value, step):
import torch
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("runs/linear")
x = torch.arange(-5, 5, 0.1).view(-1, 1)
y = -5 * x + 0.1 * torch.randn(x.size())
model = torch.nn.Linear(1, 1)
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
for epoch in range(50):
y_pred = model(x)
loss = criterion(y_pred, y)
writer.add_scalar("Loss/train", loss.item(), epoch)
optimizer.zero_grad()
loss.backward()
optimizer.step()
writer.close()
跑完这段,启动 TensorBoard,在 SCALARS 页面就能看到 loss 随 epoch 下降的曲线。tag 里的斜杠会自动分组:写 Loss/train 和 Loss/val,两条曲线会归到同一个 Loss 组,对比起来很方便。tag 定下来就别中途改名,否则曲线会断成两截。
训练循环里怎么记
真实训练不会每个 batch 都记录,那样日志又大又慢。常见做法是每 N 步记一次,横轴用全局步数(片段示例,trainloader、running_loss 来自你的训练循环):
global_step = 0
for epoch in range(10):
for i, (inputs, labels) in enumerate(trainloader):
# 前向、反向、更新……训练代码略
if i % 200 == 199:
writer.add_scalar("Loss/train", running_loss / 200, global_step)
running_loss = 0.0
global_step += 1
横轴统一用 global_step(epoch × 每轮步数 + 当前步数),两条曲线才能对齐。训练 loss 和验证 loss 分开记:Loss/train、Loss/val,验证集每个 epoch 结束记一次。
记录图片和模型结构
add_image 能记图片。配合 make_grid,可以把一批图拼成一张大图:
from torch.utils.tensorboard import SummaryWriter
import torch
import torchvision
writer = SummaryWriter("runs/vis")
batch = torch.randn(16, 3, 32, 32) # 假装是 16 张图片
grid = torchvision.utils.make_grid(batch, nrow=4)
writer.add_image("images/samples", grid)
net = torch.nn.Sequential(
torch.nn.Linear(10, 32),
torch.nn.ReLU(),
torch.nn.Linear(32, 1),
)
writer.add_graph(net, torch.randn(8, 10))
writer.close()
add_graph 记录模型结构。在 GRAPHS 页面双击节点可以展开,看数据在各层之间的流向,检查模型是不是按你想的那样搭的。
看权重分布:add_histogram
loss 之外,参数本身也值得盯。add_histogram 记录张量的分布直方图:
# 片段:每个 epoch 记一次,model 是你的模型
for name, param in model.named_parameters():
writer.add_histogram(name, param, epoch)
在 HISTOGRAMS 页面能看到每个参数的分布怎么变化。权重分布一直不动,说明这层没在学;分布发散得离谱,通常是梯度爆炸的前兆。
多实验对比
对比实验是 TensorBoard 的强项。每次实验用独立子目录:runs/exp1、runs/exp2,启动时还是 tensorboard --logdir=runs。看板左侧会列出所有实验,曲线直接叠在一起对比,谁好谁坏一目了然。目录命名带点信息,比如 runs/lr_0.01、runs/lr_0.001,回头找起来不费劲。
Tiptag 命名建议统一风格:大类/小类,比如
Loss/train、Loss/val、Acc/test。TensorBoard 按斜杠分层显示,命名乱了,后面找起来头疼。
记录学习率
学习率是训练里最值得盯的超参数。配合学习率调度器(第 15 章),把它也记成标量:
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5)
for epoch in range(50):
# 训练代码略
writer.add_scalar("LR", optimizer.param_groups[0]["lr"], epoch)
scheduler.step()
把学习率曲线和 loss 曲线叠着看,能解释很多奇怪现象:loss 突然跳一下,看看是不是学习率刚好在那一步衰减了。
使用流程回顾
把整个流程串一遍,一共五步:
- 创建
SummaryWriter,指定日志目录。 - 训练循环里用
add_*系列方法记录数据。 - 训练结束前
close()收尾。 - 命令行运行
tensorboard --logdir=runs。 - 浏览器打开 localhost:6006 查看。
后面章节的示例里,凡是「把 loss 记下来」的地方,都是这套流程的简写。
从曲线判断模型状态
TensorBoard 最实用的场景,是把训练 loss 和验证 loss 画在一起。看两条曲线的相对位置,就能判断模型状态:
- 训练 loss 降、验证 loss 也降:正常,模型在学。
- 训练 loss 降、验证 loss 升:过拟合,该加正则化或早停。
- 训练 loss 几乎不降:学习率太小,或模型太弱。
- loss 剧烈震荡:学习率太大,或 batch 太小。
落实到行动上:过拟合就加 Dropout 或 weight_decay(第 27 章);不收敛就调大学习率;震荡就调小学习率或增大 batch。TensorBoard 帮你发现症状,但下诊断的还是你自己——它给的是数据,不是答案。曲线太抖看不清趋势时,SCALARS 页面左下角的 smoothing 滑杆调大一点,趋势就清晰了。
Tip验证 loss 开始转头向上的那个点,就是「模型开始背答案」的分界线。第 27 章讲的正则化手段,就是用来对付这条上翘曲线的。
还能记什么
除了标量和图片,SummaryWriter 还有一批方法:
add_histogram:记录权重分布,观察训练中参数怎么变化。add_embedding:把高维数据投影到二维、三维空间看聚类。add_figure:直接记录 matplotlib 画的图。add_pr_curve:画每个类别的精确率-召回率曲线。add_hparams:记录超参数,配合指标做实验对比。
这些属于「需要时再查」的能力,入门阶段掌握 add_scalar、add_image、add_graph 就够用了。
常见坑
几个小坑,提前说好:
- 日志目录不一致。训练时写到 runs/exp1,启动看板却指定别的目录,自然看不到数据。
- 忘记
writer.close()。不关闭可能丢掉最后几条记录,训练结束前调用一下最稳。 - 数据没落盘。写入是异步的,长训练中想立刻看到最新曲线,先调
writer.flush()强制写盘;训练结束前close()把缓冲区全部写完。 - 端口被占用。默认端口 6006 被别的程序占了,启动时换个端口:
tensorboard --logdir=runs --port=6007。
NoteJupyter Notebook 里也能用:写日志的代码完全一样,再加两行魔术命令
%load_ext tensorboard和%tensorboard --logdir runs即可。
小结
TensorBoard 是训练过程的监控仪表盘:SummaryWriter 负责记录,浏览器负责展示。先记 loss 曲线,再补图片和模型结构,就够支撑日常训练了。下一章换个角度,看看模型内部长什么样——特征图和梯度可视化。