1. TensorBoard 用途
TensorBoard 是深度学习训练过程中最常用的可视化工具之一,它可以帮助我们直观地观察训练状态,主要用途包括:
- 查看 loss 变化曲线:确认 loss 是否按照我们预想的方式下降,判断模型是否收敛。
- 查看训练输出图像:观察训练到某一步时模型输出的图像是什么样的,便于及时发现问题。
1.1 安装 TensorBoard
在 PyTorch 环境中,TensorBoard 通常已经作为依赖被安装。如果尚未安装,可以通过 pip 直接安装:
bash
pip install tensorboard
安装完成后,可以通过以下命令验证版本:
bash
pip show tensorboard
如果输出类似 Version: 2.8.0 的信息,说明安装成功。
2. TensorBoard 写日志
TensorBoard 的核心操作是通过 SummaryWriter 将训练过程中的标量、图像等数据写入日志文件。下面以记录 y = 2x 这条直线为例,演示如何写入标量日志。
2.1 基本写入流程
python
from torch.utils.tensorboard import SummaryWriter
# 创建一个 logs 文件夹,writer 写的文件都存放在该文件夹下
writer = SummaryWriter("logs")
# 记录 100 个 step 的标量数据
for i in range(100):
writer.add_scalar("y=2x", 2 * i, i)
writer.close()


代码说明:
SummaryWriter("logs"):指定日志保存目录为logs,运行后会自动创建该文件夹。writer.add_scalar(tag, value, step):写入一个标量数据,其中:tag:数据的标识名称,在 TensorBoard 中作为曲线图的标题。value:要记录的具体数值。step:当前的训练步数(横轴)。
writer.close():关闭写入器,确保所有数据刷新到磁盘。
2.2 常用写入方法一览
| 方法 | 用途 | 典型场景 |
|---|---|---|
add_scalar |
记录单个标量 | loss、accuracy、learning rate |
add_scalars |
同时记录多个标量到同一张图 | 对比多个实验曲线 |
add_histogram |
记录参数分布 | 权重、梯度的分布变化 |
add_image |
记录单张图片 | 输入图像、输出结果 |
add_images |
记录多张图片 | 批量展示生成结果 |
add_graph |
记录模型计算图 | 可视化网络结构 |
add_embedding |
记录高维特征向量 | 特征可视化、降维投影 |
add_text |
记录文本信息 | 记录超参数、备注说明 |
3. TensorBoard 读日志
日志写入完成后,需要在浏览器中启动 TensorBoard 服务来查看可视化结果。
3.1 启动 TensorBoard
在 Anaconda 终端中,先激活对应的 Python 环境,然后执行:
bash
tensorboard --logdir=C:\Users\wangy\Desktop\03CV\logs
将终端输出的网址复制到浏览器地址栏并回车,即可看到 TensorBoard 界面。

3.2 指定端口启动
为避免多人共用服务器时端口冲突,可以手动指定端口:
bash
tensorboard --logdir=C:\Users\wangy\Desktop\03CV\logs --port=6008

这样 TensorBoard 就会在 6008 端口启动,访问地址为 http://localhost:6008。

3.3 启动流程示意
#mermaid-svg-2dqlsXavOylitHZP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2dqlsXavOylitHZP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2dqlsXavOylitHZP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2dqlsXavOylitHZP .error-icon{fill:#552222;}#mermaid-svg-2dqlsXavOylitHZP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2dqlsXavOylitHZP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2dqlsXavOylitHZP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2dqlsXavOylitHZP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2dqlsXavOylitHZP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2dqlsXavOylitHZP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2dqlsXavOylitHZP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2dqlsXavOylitHZP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2dqlsXavOylitHZP .marker.cross{stroke:#333333;}#mermaid-svg-2dqlsXavOylitHZP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2dqlsXavOylitHZP p{margin:0;}#mermaid-svg-2dqlsXavOylitHZP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2dqlsXavOylitHZP .cluster-label text{fill:#333;}#mermaid-svg-2dqlsXavOylitHZP .cluster-label span{color:#333;}#mermaid-svg-2dqlsXavOylitHZP .cluster-label span p{background-color:transparent;}#mermaid-svg-2dqlsXavOylitHZP .label text,#mermaid-svg-2dqlsXavOylitHZP span{fill:#333;color:#333;}#mermaid-svg-2dqlsXavOylitHZP .node rect,#mermaid-svg-2dqlsXavOylitHZP .node circle,#mermaid-svg-2dqlsXavOylitHZP .node ellipse,#mermaid-svg-2dqlsXavOylitHZP .node polygon,#mermaid-svg-2dqlsXavOylitHZP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2dqlsXavOylitHZP .rough-node .label text,#mermaid-svg-2dqlsXavOylitHZP .node .label text,#mermaid-svg-2dqlsXavOylitHZP .image-shape .label,#mermaid-svg-2dqlsXavOylitHZP .icon-shape .label{text-anchor:middle;}#mermaid-svg-2dqlsXavOylitHZP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2dqlsXavOylitHZP .rough-node .label,#mermaid-svg-2dqlsXavOylitHZP .node .label,#mermaid-svg-2dqlsXavOylitHZP .image-shape .label,#mermaid-svg-2dqlsXavOylitHZP .icon-shape .label{text-align:center;}#mermaid-svg-2dqlsXavOylitHZP .node.clickable{cursor:pointer;}#mermaid-svg-2dqlsXavOylitHZP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2dqlsXavOylitHZP .arrowheadPath{fill:#333333;}#mermaid-svg-2dqlsXavOylitHZP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2dqlsXavOylitHZP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2dqlsXavOylitHZP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2dqlsXavOylitHZP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2dqlsXavOylitHZP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2dqlsXavOylitHZP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2dqlsXavOylitHZP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2dqlsXavOylitHZP .cluster text{fill:#333;}#mermaid-svg-2dqlsXavOylitHZP .cluster span{color:#333;}#mermaid-svg-2dqlsXavOylitHZP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2dqlsXavOylitHZP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2dqlsXavOylitHZP rect.text{fill:none;stroke-width:0;}#mermaid-svg-2dqlsXavOylitHZP .icon-shape,#mermaid-svg-2dqlsXavOylitHZP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2dqlsXavOylitHZP .icon-shape p,#mermaid-svg-2dqlsXavOylitHZP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2dqlsXavOylitHZP .icon-shape .label rect,#mermaid-svg-2dqlsXavOylitHZP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2dqlsXavOylitHZP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2dqlsXavOylitHZP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2dqlsXavOylitHZP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 激活 Python 环境
执行 tensorboard --logdir=日志路径
复制终端输出的网址
浏览器打开 TensorBoard 界面
4. TensorBoard 读图片
除了标量曲线,TensorBoard 还支持可视化训练过程中的图片数据,例如输入样本、模型输出等。
4.1 写入图片示例
python
from torch.utils.tensorboard import SummaryWriter
from PIL import Image
import numpy as np
# 读取第一张图片(蚂蚁)
img_path1 = "Data/FirstTypeData/train/ants/0013035.jpg"
img_PIL1 = Image.open(img_path1)
img_array1 = np.array(img_PIL1)
# 读取第二张图片(蜜蜂)
img_path2 = "Data/SecondTypeData/train/bees_image/17209602_fe5a5a746f.jpg"
img_PIL2 = Image.open(img_path2)
img_array2 = np.array(img_PIL2)
writer = SummaryWriter("logs")
# 1 表示该图片在第 1 步
writer.add_image("test", img_array1, 1, dataformats="HWC")
# 2 表示该图片在第 2 步
writer.add_image("test", img_array2, 2, dataformats="HWC")
writer.close()
代码说明:
PIL.Image.open():读取图片文件。np.array():将 PIL 图像转换为 NumPy 数组,TensorBoard 需要接收数组格式。dataformats="HWC":指定输入数据的维度顺序为高度(H) × 宽度(W) × 通道(C),这是 PIL 读取图片后的默认格式。add_image(tag, img_tensor, global_step):写入一张图片,global_step表示当前步数,同一tag下不同步数的图片可以在 TensorBoard 中滑动查看。

4.2 查看图片
启动 TensorBoard 后,在界面顶部切换到 Images 选项卡,即可看到写入的图片。通过底部的步数滑块,可以对比不同训练阶段的图片变化。
5. 总结
TensorBoard 是 PyTorch 训练流程中不可或缺的调试利器,核心使用流程可以概括为:
- 写日志 :通过
SummaryWriter记录标量、图片、直方图等数据。 - 读日志 :在终端启动
tensorboard --logdir=日志路径,浏览器访问查看。 - 可视化分析:通过曲线判断收敛情况,通过图片检查训练效果。
掌握 TensorBoard 的基本用法,可以让你在训练过程中更高效地定位问题、优化模型。