MMSegmentation 1.x 可视化全攻略:训练监控、验证预测与单样本结果渲染
2026/9/16 14:27:59 网站建设 项目流程

MMSegmentation 1.x 可视化全攻略:训练监控、验证预测与单样本结果渲染

【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation

导读

本文围绕 MMSegmentation 1.x 的官方可视化能力展开,系统讲解两大核心场景:训练状态监控(基于 TensorBoard 的标量曲线查看)与数据/结果可视化(验证与测试期间自动保存预测图、单样本语义分割结果渲染)。读完本文,你将掌握TensorboardVisBackend的配置方法、SegVisualizationHook的参数调优、SegLocalVisualizer的编程式调用,并从源码层面理解调色板叠加、类别标签绘制与SegDataSample数据结构的工作机制,可以直接上手复现文中的配置与脚本。


一、训练状态监控:TensorBoard 集成

MMSegmentation 1.x 使用 TensorBoard 监控训练状态。其核心思路是把训练过程中由日志处理器(log processor)产出的标量(学习率、损失、data_time、各类评估指标)通过可视化后端(VisBackend)写入磁盘,再由 TensorBoard 服务读取展示。

1.1 安装 TensorBoard 依赖

按照 TensorFlow 官方安装指南的步骤安装即可,核心命令如下:

pip install tensorboardX pip install future tensorboard

其中tensorboardX用于写入事件文件,tensorboard用于启动可视化服务。

1.2 在配置中添加TensorboardVisBackend

MMSegmentation 的默认运行时配置位于 configs/base/default_runtime.py,其默认只启用本地后端:

vis_backends = [dict(type='LocalVisBackend')] visualizer = dict( type='SegLocalVisualizer', vis_backends=vis_backends, name='visualizer')

要启用 TensorBoard,需要在vis_backends列表中追加TensorboardVisBackend

vis_backends = [dict(type='LocalVisBackend'), dict(type='TensorboardVisBackend')] visualizer = dict( type='SegLocalVisualizer', vis_backends=vis_backends, name='visualizer')

两点说明:

  • LocalVisBackend负责把标量、图片等写入本地vis_data目录,务必保留,因为 TensorBoard 读取的正是该目录下的事件文件;
  • visualizer统一指定为type='SegLocalVisualizer',它是 MMSegmentation 对 MMEngineVisualizer的语义分割定制实现(源码见 mmseg/visualization/local_visualizer.py),训练、验证、测试流程都通过这个实例向外输出可视化数据。

1.3 启动训练并检查标量

以 PSPNet 在 ADE20K 上的训练配置为例,启动一次训练实验:

python tools/train.py configs/pspnet/pspnet_r50-d8_4xb4-80k_ade20k-512x512.py --work-dir work_dir/test_visual

开始训练后,在work_dir下找到vis_data路径,例如:

work_dirs/test_visual/20220810_115248/vis_data

vis_data目录中的标量文件包括学习率、损失函数、data_time等,同时记录了评估指标结果。如果你想记录自定义数据(例如自定义 loss 的中间分量),可以参照 MMEngine 的记录日志教程自行扩展日志记录逻辑,这里不再展开。

使用下面的命令启动 TensorBoard 查看可视化结果:

tensorboard --logdir work_dirs/test_visual/20220810_115248/vis_data

启动后浏览器打开 TensorBoard 默认地址(通常为http://localhost:6006)即可看到 loss、lr、mIoU 等曲线随迭代的变化。


二、数据和结果的可视化

2.1 验证/测试期间自动可视化:SegVisualizationHook

MMSegmentation 提供了SegVisualizationHook,它是一个用于在模型验证和测试期间可视化 ground truth 与预测分割结果的钩子,源码位于 mmseg/engine/hooks/visualization_hook.py。其核心配置位于default_hooks中(执行器层面的钩子装配逻辑可参见 MMEngine 的 Runner 教程)。

SegVisualizationHook的关键参数:

参数默认值作用
drawFalse是否绘制预测结果。为False时钩子完全不生效,不绘制也不存储任何结果
interval50可视化采样间隔(以迭代/iter 为单位)。设为 1 时保存每一次推理结果
showFalse是否直接弹窗显示绘制图像。为True时只显示不存储,vis_backends会被排除
wait_time0show=True时窗口显示的间隔(秒)
backend_argsNone实例化文件后端的参数(依赖 mmcv>=2.0.0rc4、mmengine>=0.2.0)

例如,在 configs/base/schedules/schedule_20k.py 中修改SegVisualizationHook配置,将draw置为True以启用网络推理结果的存储,interval设为 1 表示保存每次推理结果:

default_hooks = dict( timer=dict(type='IterTimerHook'), logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), param_scheduler=dict(type='ParamSchedulerHook'), checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=2000), sampler_seed=dict(type='DistSamplerSeedHook'), visualization=dict(type='SegVisualizationHook', draw=True, interval=1))

从源码看,该钩子在after_val_iter中每self.interval个验证迭代触发一次(total_curr_iter = runner.iter + batch_idx能被interval整除时),读取outputs[0].img_path对应的图片,调用self._visualizer.add_datasample完成绘制;在after_test_iter中则对每个测试样本逐个可视化(stepself._test_index递增标记)。因此:

  • 验证阶段:启动训练实验后,可视化结果会在 validation loop 中存储到本地文件夹;
  • 测试阶段:对一个数据集启动评估模型时(如python tools/test.py ...),每个样本的预测结果同样会被存储。

本地可视化的存储结果保存在$WORK_DIRS/vis_data/vis_image下,例如:

work_dirs/test_visual/20220810_115248/vis_data/vis_image

另外,如果在vis_backends中同时添加了TensorboardVisBackend(见上文 1.2 节配置),还可以运行下面的命令在 TensorBoard 的 IMAGES 面板中查看这些预测图:

tensorboard --logdir work_dirs/test_visual/20220810_115248/vis_data

2.2 可视化单个数据样本:SegLocalVisualizer

当你想脱离训练/验证流程、独立可视化某个样本(例如调试数据集、检查标注质量)时,建议直接使用SegLocalVisualizer

SegLocalVisualizer是继承自 MMEngineVisualizer类的子类,专门面向 MMSegmentation 的可视化需求(语义分割掩码叠加、类别标签绘制、深度图绘制等)。其构造参数包括nameimagevis_backendssave_dirclassespalettedataset_namealpha(掩码透明度,默认0.8)等,注册于VISUALIZERS注册表。

以下是官方示例脚本(Cityscapes 样本)。首先下载示例数据:

wget https://user-images.githubusercontent.com/24582831/189833109-eddad58f-f777-4fc0-b98a-6bd429143b06.png --output-document aachen_000000_000019_leftImg8bit.png wget https://user-images.githubusercontent.com/24582831/189833143-15f60f8a-4d1e-4cbb-a6e7-5e2233869fac.png --output-document aachen_000000_000019_gtFine_labelTrainIds.png

然后编写脚本对其进行可视化:

import mmcv import os.path as osp import torch # `PixelData` 是 MMEngine 中用于定义像素级标注或预测的数据结构, # 详情可参考 MMEngine 的数据结构教程(PixelData 章节)。 from mmengine.structures import PixelData # `SegDataSample` 是 MMSegmentation 中定义的不同组件之间的数据结构接口, # 它包含 ground truth、语义分割预测结果和预测 logits。 from mmseg.structures import SegDataSample from mmseg.visualization import SegLocalVisualizer out_file = 'out_file_cityscapes' save_dir = './work_dirs' image = mmcv.imread( osp.join( osp.dirname(__file__), './aachen_000000_000019_leftImg8bit.png' ), 'color') sem_seg = mmcv.imread( osp.join( osp.dirname(__file__), './aachen_000000_000019_gtFine_labelTrainIds.png' # noqa ), 'unchanged') sem_seg = torch.from_numpy(sem_seg) gt_sem_seg_data = dict(data=sem_seg) gt_sem_seg = PixelData(**gt_sem_seg_data) data_sample = SegDataSample() data_sample.gt_sem_seg = gt_sem_seg seg_local_visualizer = SegLocalVisualizer( vis_backends=[dict(type='LocalVisBackend')], save_dir=save_dir) # 数据集的元信息通常包括类名的 `classes` 和 # 用于可视化每个前景颜色的 `palette`。 # 所有类名和调色板都在 mmseg/utils/class_names.py 中定义。 seg_local_visualizer.dataset_meta = dict( classes=('road', 'sidewalk', 'building', 'wall', 'fence', 'pole', 'traffic light', 'traffic sign', 'vegetation', 'terrain', 'sky', 'person', 'rider', 'car', 'truck', 'bus', 'train', 'motorcycle', 'bicycle'), palette=[[128, 64, 128], [244, 35, 232], [70, 70, 70], [102, 102, 156], [190, 153, 153], [153, 153, 153], [250, 170, 30], [220, 220, 0], [107, 142, 35], [152, 251, 152], [70, 130, 180], [220, 20, 60], [255, 0, 0], [0, 0, 142], [0, 0, 70], [0, 60, 100], [0, 80, 100], [0, 0, 230], [119, 11, 32]]) # 当 `show=True` 时,直接显示结果; # 当 `show=False` 时,结果将保存在本地文件夹中。 seg_local_visualizer.add_datasample(out_file, image, data_sample, show=False)

运行后,可视化图像结果和其对应的 ground truth 图像可以在./work_dirs/vis_data/vis_image/路径找到,文件名是out_file_cityscapes_0.png

脚本要点解读:

  1. PixelData(**gt_sem_seg_data)用像素级数据构造 MMEngine 数据结构,sem_seg的 shape 为(1, H, W)
  2. data_sample.gt_sem_seg = gt_sem_seg把标注挂载到SegDataSample上,可视化器据此取到gt_sem_seg字段;
  3. dataset_meta中的classespalette必须一一对应(数量相等),否则会触发断言错误(见set_dataset_meta中的assert len(classes) == len(palette));
  4. add_datasampleshow=False、未指定out_file时,会把绘制结果交给LocalVisBackend写入save_dir/vis_data/vis_image/

三、源码级深度解析

3.1SegLocalVisualizer的绘制流程

SegLocalVisualizer(mmseg/visualization/local_visualizer.py)的核心绘制链路如下:

  • add_datasample(name, image, data_sample, draw_gt=True, draw_pred=True, show=False, wait_time=0, out_file=None, step=0, with_labels=True):入口方法,同时绘制 GT 与预测。当两者都存在时,左右拼接为一张图(np.concatenate((gt_img_data, pred_img_data), axis=1)),左侧为 ground truth,右侧为预测结果;show=True时忽略所有后端直接弹窗;指定out_file时用mmcv.imwrite(mmcv.rgb2bgr(drawn_img), out_file)落盘,否则交给add_image写入后端。
  • _draw_sem_seg(image, sem_seg, classes, palette, with_labels=True):按palette把每个类别的像素填充为对应颜色生成彩色掩码,再与原始图像按color_seg = image * (1 - self.alpha) + mask * self.alpha融合(alpha默认 0.8,即掩码透明度);随后为每个类别调用_get_center_loc计算该类连通区域的中心位置,用 OpenCV 绘制类别名称文本标签(字号随图像尺寸自适应缩放,小图thickness=1,大图thickness=2)。
  • set_dataset_meta(classes, palette, dataset_name):当未显式传入classes/palette时,会以dataset_name(默认'cityscapes')为键,从 mmseg/utils/class_names.py 的get_classes/get_palette中自动获取类名与调色板,并写入self.dataset_meta

从上述实现可以推断:alpha直接控制分割掩码与原始图像的叠加透明度;with_labels控制是否在掩码上绘制类别名;而step参数用于标记写入后端时的迭代步数,在验证钩子中即取当前迭代号。

3.2 数据载体:SegDataSamplePixelData

SegDataSample定义于 mmseg/structures/seg_data_sample.py,继承自 MMEngine 的BaseDataElement,是 MMSegmentation 各组件之间传递数据的接口,主要字段包括:

  • gt_sem_segPixelData):语义分割的 ground truth;
  • pred_sem_segPixelData):语义分割的预测结果;
  • seg_logitsPixelData):预测的 logits。

其中PixelData是 MMEngine 中专门描述像素级标注/预测的数据结构,承载(1, H, W)的类别索引张量。这也是 2.2 节脚本中PixelData(**gt_sem_seg_data)data_sample.gt_sem_seg = gt_sem_seg两行代码的意义所在。

3.3 类名与调色板:class_names.py

get_classes(dataset)get_palette(dataset)位于 mmseg/utils/class_names.py:

  • 内部通过dataset_aliases字典把数据集别名(如'cityscapes''ade20k''coco_stuff164k''isaid'等)映射到标准名称,再调用对应的xxx_classes()/xxx_palette()函数;
  • 例如cityscapes_classes()返回 19 个类名(roadsidewalkbuilding……bicycle),cityscapes_palette()返回一一对应的 19 组 RGB 颜色——这正是 2.2 节脚本中手写dataset_meta的等价来源;
  • 传入无法识别的数据集名称时抛出ValueError,传入非字符串类型时抛出TypeError

因此在大多数场景下,你并不需要手写palette,直接通过SegLocalVisualizer(dataset_name='cityscapes')即可自动加载,显式传入的classes/palette优先级更高。

3.4 钩子与可视化器的协同(以测试验证)

SegVisualizationHook(mmseg/engine/hooks/visualization_hook.py)在__init__中通过Visualizer.get_current_instance()拿到配置中声明的SegLocalVisualizer单例;验证时按interval采样、测试时逐样本调用add_datasample,把SegDataSample(含 GT 与预测)交给可视化器统一渲染。这一链路在仓库测试中也有覆盖:

  • tests/test_visualization/test_local_visualizer.py:验证SegLocalVisualizer的构造、dataset_meta设置、add_datasample绘制与保存行为;
  • tests/test_engine/test_visualization_hook.py:验证钩子在不同draw/interval/show组合下的行为(如draw=False时不产生输出)。

如果你需要阅读官方提供的第二个可视化示例,可以参考仓库中另一篇进阶文档 docs/zh_cn/user_guides/visualization_feature_map.md,它演示了如何使用SegLocalVisualizer绘制特征图;而本文所述方法与 docs/zh_cn/user_guides/4_train_test.md(训练与测试)、docs/zh_cn/user_guides/3_inference.md(推理)配合使用,可以覆盖从训练监控到结果分析的全流程可视化需求。


四、小结

MMSegmentation 1.x 的可视化体系以SegLocalVisualizer为枢纽、以SegVisualizationHook为自动触发机制、以LocalVisBackend/TensorboardVisBackend为输出通道:

  • 训练监控:在 configs/base/default_runtime.py 的vis_backends中加入TensorboardVisBackend,训练后用tensorboard --logdir查看标量曲线;
  • 验证/测试自动化可视化:在default_hooks中配置SegVisualizationHook(draw=True, interval=...),结果自动落盘到$WORK_DIRS/vis_data/vis_image,也可在 TensorBoard IMAGES 面板查看;
  • 单样本可视化:用SegLocalVisualizer配合SegDataSampledataset_meta编程式渲染,控制show/out_file/alpha/with_labels等参数即可灵活输出。

掌握这套可视化工具链,可以显著提升训练排障与结果分析的效率:损失曲线异常时查看标量趋势,分割边界模糊时直接查看预测图与 GT 的并排对比,从而快速定位模型与数据的问题。

【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询