实验管理与评测脚本说明(mmseg 自定义工具链)

实验管理与评测脚本说明(mmseg 自定义工具链)

本文介绍在本项目(基于 MMSegmentation 1.x)里自建的一套实验管理 + 评测工具,
用于解决"多次跑同一模型不同超参会互相覆盖"“结果难以横向对比”“评测要分尺寸/分子集”
等问题。全部改动只在 my_configs/paths.pytools/*.py不触碰 mmseg 内核
训练/评测的数值与官方 tools/train.py / tools/test.py 完全一致。

涉及文件:

  • my_configs/paths.py:路径与台账核心逻辑(tools/experiment_paths.py 转出供脚本用)
  • tools/train.py:训练(带运行隔离 + 台账)
  • tools/smoke_test.py:单次测试(指标 + 可视化 + 台账)
  • tools/smoke_test_multiscale.py:分划分一键测试(自动发现,数据集无关)

一、实验管理机制:时间戳运行目录 + CSV 台账

1.1 目录规则

1
2
3
4
5
6
7
8
9
work_dirs/
{dataset}/ # 数据集,对应 cfg.dataset_name
{exp_name}/ # 模型/实验标识,对应 cfg.exp_name
{tag}__{timestamp}/ # 单次运行:永不覆盖
*.pth # 权重(CheckpointHook)
{config}.py # 配置快照(mmengine 自动)
{timestamp}/ # 训练日志、vis_data(mmengine 自动)
eval/{ckpt}/ # 该权重的评测结果(见第二、三节)
experiments.csv # 全局实验台账:每次 train/test 追加一行
  • 每次训练自动生成 {tag}__{时间戳} 子目录,因此"同模型不同超参/重训"互不覆盖。
  • tag 是人可读的变体标签(如 c768lr6e-5ablation_c256),用 --tag 传入,
    缺省 run
  • 时间戳保证唯一,无需哈希。

1.2 三个开关(tools/train.py

开关 作用
--tag XXX 设运行标签;目录变成 {exp_name}/XXX__{时间戳}/
--resume-into DIR 复用某个已有运行目录(不加新时间戳),用于续训/有意覆盖该次运行
--resume 从 work_dir 最新 checkpoint 续训(官方原生,常与 --resume-into 合用)
--work-dir DIR 显式指定目录(不加时间戳,兼容老用法)

1.3 实验台账 work_dirs/experiments.csv

每次 train / test 自动追加一行,列:

1
2
3
timestamp, kind(train/test), dataset, exp_name, tag, run_dir,
config, git_commit, lr, batch_size, accum, channels,
max_epochs_iters, loss, metrics
  • train 行记录超参 + 配置 + git 提交 + 运行目录;test 行额外记录 metrics(指标 JSON)。
  • 查看:column -s, -t work_dirs/experiments.csv | less -S,或用 Excel / pandas 打开做
    排序、筛选、画图,调参与消融对比一目了然。

二、单次测试脚本 tools/smoke_test.py

在官方 test 流程之上,增加清晰的输出目录 + 指标 JSON + 多种可视化 + 台账登记

1
python tools/smoke_test.py CONFIG CKPT
  • 指标:跑官方 runner.test(),把指标存为 metrics.json
  • 输出目录:默认 {权重所在运行目录}/eval/{权重名}/,与该次运行绑定,互不覆盖。
  • 可视化(默认开启,--no-save-vis 关闭):在 eval/{ckpt}/visualizations/ 下生成
    • gt_overlay/:原图 + GT 叠加
    • pred_overlay/:原图 + 预测叠加
    • pred_mask/:纯预测 mask(VOC 调色盘)
    • overlay_compare/:GT 叠加 | 预测叠加(左右拼接)
    • mask_compare/:GT mask | 预测 mask(左右拼接)
  • 其它:--tta 测试时增强、--cfg-options k=v 覆盖配置。
  • 测试完成后自动往 experiments.csv 写一行(含指标)。

三、分划分测试脚本 tools/smoke_test_multiscale.py(数据集无关)

一次性在 全量(all) + 各子划分 上用同一权重评测,汇总成表 + JSON,并登记台账。

1
2
python tools/smoke_test_multiscale.py CONFIG CKPT
python tools/smoke_test_multiscale.py CONFIG CKPT --splits small large # 只跑指定划分

3.1 自动发现规则(关键)

以 config 的 test_dataloader.dataset.ann_file(如 ImageSets/Segmentation/test.txt
为基准,取主干 test,在同目录查找所有 test_*.txt 兄弟文件,后缀即划分名:

数据集 同目录下的兄弟文件 自动得到的划分
MultiNatSmoke test_small/medium/large.txt all, small, medium, large
SmokeSeg(Segmentation_origin test_small/medium/large.txt all, small, medium, large
SYN70K test_DS03/SD01/SD02.txt all, DS03, SD01, SD02
SMOKE5K 仅 all

即"只要数据集准备了相应划分文件就能用",不限定数据集、不写死划分名
因此 SmokeSeg 想做分尺寸评测,只要 config 的 ann_file 指向
ImageSets/Segmentation_origin/test.txt 即可自动跑出 small/medium/large。

3.2 输出

  • 每个划分单独评测,结果汇总到 {eval_dir}/stratified_metrics.json + 终端 PrettyTable。
  • 自动关闭可视化 hook,避免重复出图。
  • 末尾登记台账。

注意:若用 batch-averaged 口径(MultiNatSmokeMetric(aggregate='batch')),评测须
单卡且保持 test_dataloader.batch_size 与对齐目标一致,否则数值会变。


四、配置文件里要写什么来配合这套机制

在你的 config 里提供以下字段即可(其余照常):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# —— 实验管理相关 ——
dataset_name = 'MultiNatSmoke' # → work_dirs 第一级;也写进台账
exp_name = 'segformer_mit_b2_align' # → work_dirs 第二级(模型/实验标识)
# tag = 'c768' # 可选:默认标签;一般用命令行 --tag 覆盖
# work_dir 可不写:会自动推断为 work_dirs/{dataset_name}/{exp_name}(作为基础目录)

# —— 分划分评测相关 ——
test_dataloader = dict(
batch_size=32, # 对齐 batch-averaged 口径时需要
num_workers=2, # batch 大时防 /dev/shm 撑爆
dataset=dict(
type='SmokeDataset',
data_root='data/MultiNatSmokeDataset_VOC',
ann_file='ImageSets/Segmentation/test.txt', # ← 分划分发现的基准
# 若数据集划分在别的子目录(如 SmokeSeg),改成对应路径:
# ann_file='ImageSets/Segmentation_origin/test.txt',
...))

# —— 评测指标 ——(二选一)
test_evaluator = dict(type='MultiNatSmokeMetric', aggregate='batch', ...) # 对齐论文口径
# 或 test_evaluator = dict(type='SmokeSegMetric', ...) # 通用烟雾指标

要点:

  1. dataset_name + exp_name 决定 work_dirs 的前两级;运行子目录由脚本自动加时间戳。
  2. 分划分脚本只依赖 test_dataloader.dataset.ann_file 的命名与同目录兄弟文件,无需在
    config 里列出各划分
  3. data_root 用于校验划分文件是否真实存在(不存在的划分自动跳过)。

五、对 MMSegmentation 的影响

零侵入。 所有逻辑都在 my_configs/paths.py 和你自定义的 tools/*.py 里:脚本仍调用
官方的 Runner.from_cfg(cfg)runner.train()/test(),我们只是在建 Runner 前算好
cfg.work_dir(官方也用的标准字段),并在结束后写一个外部 CSV。训练/评测数值与直接用
官方脚本逐字节一致
,唯一区别是输出落点更规整 + 多一份台账。


六、旧结果迁移情况

为统一风格,已把历史松散结果归档为 legacy__{原时间戳}/ 运行目录(内容完整保留):

路径 归档为
work_dirs/MultiNatSmoke/segformer_mit_b2_align/ legacy_c256__20260531_164823/
work_dirs/SMOKE5K/segformer_mit_b3_batch=6/ legacy__20260516_224135/
work_dirs/SMOKE5K/segformer_mit_b3_batch=12/ legacy__20260521_132042/
work_dirs/SmokeSeg/segformer_mit_b3/ legacy__20260517_102843/

注:旧结果是在引入台账之前产生的,因此 experiments.csv 不含它们;新跑的实验会自动登记。


七、常用命令速查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 训练(自动 run__时间戳)
python tools/train.py CONFIG

# 调参/消融:用 --tag 命名变体(互不覆盖)
python tools/train.py CONFIG --tag c768
python tools/train.py CONFIG --tag c256 --cfg-options model.decode_head.channels=256

# 续训/覆盖某次已有运行
python tools/train.py CONFIG --resume-into work_dirs/.../{exp}/{tag}__{ts} --resume

# 单次测试(指标 + 可视化)
python tools/smoke_test.py CONFIG work_dirs/.../{tag}__{ts}/best_*.pth

# 分划分测试(自动发现 small/medium/large 或子集)
python tools/smoke_test_multiscale.py CONFIG work_dirs/.../{tag}__{ts}/best_*.pth

# 看台账
column -s, -t work_dirs/experiments.csv | less -S