MMDetection 检测器鲁棒性基准测试实战:图像损坏评测的原理、工具与结果分析
2026/9/20 5:27:12 网站建设 项目流程

MMDetection 检测器鲁棒性基准测试实战:图像损坏评测的原理、工具与结果分析

【免费下载链接】mmdetectionOpenMMLab Detection Toolbox and Benchmark项目地址: https://gitcode.com/gh_mirrors/mm/mmdetection

本文围绕 MMDetection 内置的「图像损坏基准测试(Image Corruption Benchmark)」工具展开,系统讲解其设计来源、底层实现、完整命令行用法与评测指标含义。读完你将掌握如何用tools/analysis_tools/test_robustness.py对任意检测/分割模型施加 15~19 类损坏变换、在 0~5 级严重程度下批量评测,并正确解读 P、mPC、rPC 三类指标,评估模型在真实恶劣场景(如自动驾驶冬季天气)下的鲁棒性。

背景:为什么需要鲁棒性基准测试

目标检测与实例分割模型通常在干净数据集上评测,但真实部署环境往往充满噪声、模糊、恶劣天气与数字失真。MMDetection 提供了 Michaelis 等人在论文Benchmarking Robustness in Object Detection: Autonomous Driving when Winter is Coming(arXiv:1907.07484,2019)中定义的图像损坏基准测试工具,用于量化模型在各类常见损坏(corruption)下的性能退化程度。该基准测试仿照 Dan Hendrycks 与 Thomas Dietterich 在 ICLR 2019 发表的 ImageNet-C 基准测试(Benchmarking Neural Network Robustness to Common Corruptions and Perturbations,arXiv:1903.12261)设计,是评估模型泛化能力与部署可靠性的重要手段。

@article{michaelis2019winter, title={Benchmarking Robustness in Object Detection: Autonomous Driving when Winter is Coming}, author={Michaelis, Claudio and Mitzkus, Benjamin and Geirhos, Robert and Rusak, Evgenia and Bringmann, Oliver and Ecker, Alexander S. and Bethge, Matthias and Brendel, Wieland}, journal={arXiv:1907.07484}, year={2019} }

上图直观展示了同一张自动驾驶场景图像在各类损坏变换(噪声、模糊、天气、数字失真等)严重程度 3 级下的视觉效果,也是后续评测中被施加到输入图像上的典型干扰形态。

基准测试的整体设计

损坏变换来源:imagecorruptions 库

图像损坏变换函数本身并不由 MMDetection 实现,而是来自独立的imagecorruptions库(与 robust-detection-benchmark 同属 bethgelab 组织)。该库可以单独安装:

pip install imagecorruptions

安装后即可在 MMDetection 的评测流程中直接使用。需要注意的是,imagecorruptions属于可选依赖,未安装时评测脚本仍可运行,但在实际施加损坏变换时会抛出RuntimeError('imagecorruptions is not installed')(见 mmdet/datasets/transforms/transforms.py 中Corrupt.transform的守卫逻辑,源码通过try/except ImportErrorcorrupt置为None后再做判空)。

与 ImageNet-C 的差异

与 ImageNet-C 相比,MMDetection 的适配做了三处关键调整:

  1. 支持任意尺寸图像:ImageNet-C 面向固定尺寸的分类图像,而检测任务中图像尺寸任意,损坏变换函数需按原图分辨率生效;
  2. 支持灰度图像:部分检测数据集(如行人检测、遥感场景)包含灰度图,变换函数必须能处理单通道输入;
  3. 解除 Linux 特定库依赖:原版「运动模糊(motion blur)」与「雪(snow)」损坏依赖部分 Linux 专用库,MMDetection 对其进行了修改,避免使用者额外安装这些系统级依赖。

底层实现:Corrupt数据变换

损坏变换在 MMDetection 中被封装为一个标准的注册式数据变换Corrupt(位于 mmdet/datasets/transforms/transforms.py),其设计如下:

  • 通过@TRANSFORMS.register_module()注册到TRANSFORMS注册表,可直接在配置的pipeline中以字典形式使用;
  • 构造参数:corruption(损坏名称,必填)与severity(严重程度,默认 1);
  • 作用对象:将results['img'](要求为np.uint8类型)传入imagecorruptions.corrupt()函数,原地返回损坏后的图像;
  • __repr__输出形如Corrupt(corruption=gaussian_blur, severity=1),便于日志排查。

该变换的单元测试位于 tests/test_datasets/test_transforms/test_transforms.py,测试验证了「加载图像 → 施加Corrupt(corruption='gaussian_blur')」后输出图像仍保持np.uint8类型,以及__repr__的字符串格式。

使用 test_robustness.py 进行鲁棒性评测

MMDetection 提供了专用评测脚本 tools/analysis_tools/test_robustness.py。当前仓库版本支持单张 GPU 测试(多 GPU 测试与检测结果可视化在原文档中标注为未实现)。

前提条件

  • 已安装 MMDetection 及其运行依赖;
  • 已安装imagecorruptionspip install imagecorruptions);
  • 准备好模型配置文件(${CONFIG_FILE})与预训练权重(${CHECKPOINT_FILE});
  • 准备测试数据集(脚本默认沿用配置中的test_dataloader,并将dataset.test_mode置为True)。

基础用法:全量 benchmark 评测

# single-gpu testing python tools/analysis_tools/test_robustness.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}]

其中--out指定结果 dump 文件(必须为.pkl.pickle后缀,脚本会通过向test_evaluator追加DumpResults虚拟指标将逐级结果写入磁盘);评估指标在当前仓库版本中由配置文件里的test_evaluator决定(脚本不再单独解析--eval,这与旧版命令行略有差异,以当前 test_robustness.py 源码为准)。

按损坏类别筛选

--corruptions支持类别名与具体损坏名两种粒度,类别到具体损坏的映射由脚本内部展开(源码见 tools/analysis_tools/test_robustness.py):

# 只测噪声类 python tools/analysis_tools/test_robustness.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] --corruptions noise # 只测模糊类 python tools/analysis_tools/test_robustness.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] --corruptions blur # 只测天气类 python tools/analysis_tools/test_robustness.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] --corruptions weather # 只测数字失真类 python tools/analysis_tools/test_robustness.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] --corruptions digital

或直接指定任意自定义组合(多个损坏名以空格分隔),例如:

# 高斯噪声、缩放模糊和雪 python tools/analysis_tools/test_robustness.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] --corruptions gaussian_noise zoom_blur snow

完整的损坏类别与成员映射如下(共 4 类 benchmark 损坏 + 1 类 holdout 损坏):

类别成员损坏说明
noisegaussian_noiseshot_noiseimpulse_noise噪声类
blurdefocus_blurglass_blurmotion_blurzoom_blur模糊类
weathersnowfrostfogbrightness天气类
digitalcontrastelastic_transformpixelatejpeg_compression数字失真类
holdoutspeckle_noisegaussian_blurspattersaturate留出类(不计入 benchmark 汇总)

其中benchmark(默认值)对应前 4 类共 15 种损坏,all则在 benchmark 基础上追加 holdout 的 4 种,共 19 种;None表示不施加任何损坏(此时脚本自动将severities固定为[0])。

控制损坏严重程度

--severities控制施加在图像上的损坏强度,取值 0~5,数值越大损坏越强,其中0表示原始图像(不施加任何损坏):

# 仅严重程度 1 python tools/analysis_tools/test_robustness.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] --severities 1 # 严重程度 0、2、4 python tools/analysis_tools/test_robustness.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] --severities 0 2 4

脚本默认值为[0, 1, 2, 3, 4, 5],即一次性评测全部 6 个等级。内部实现上,脚本会为每种损坏×每个严重程度构建独立的test_dataloader:通过copy.deepcopy复制test_dataloader,并在pipeline第 1 个位置(图像加载之后)插入dict(type='Corrupt', corruption=..., severity=...)变换(源码见 tools/analysis_tools/test_robustness.py)。此外,严重程度 0(无损坏)的结果只评估一次,其他损坏的 0 级结果直接复用第一类损坏的 0 级结果,避免重复计算(源码见 tools/analysis_tools/test_robustness.py)。

完整参数速查表

以下为当前仓库版本中test_robustness.py支持的全部命令行参数(源码见 tools/analysis_tools/test_robustness.py):

参数取值/默认说明
config(位置参数)必填测试配置文件路径
checkpoint(位置参数)必填模型权重文件
--out.pkl/.pickle保存预测结果为 pickle 文件,供离线评估
--corruptions默认benchmark,可选all/benchmark/noise/blur/weather/digital/holdout/None及 19 种具体损坏名指定损坏变换类型
--severities默认[0,1,2,3,4,5]损坏严重程度等级
--work-dir默认取配置或 config 文件名保存评估指标文件的目录
--summaries默认False为每种损坏和严重程度打印汇总
--show开关展示检测结果(需--out--show-dir之一)
--show-dir字符串保存绘制了检测结果的图像目录
--wait-time默认 2展示间隔(秒)
--seed默认None随机种子,用于复现损坏变换的随机性
--launchernone/pytorch/slurm/mpi,默认none任务启动器
--local_rank默认 0本地进程编号
--final-printsP/mPC/rPC,默认mPC最终打印的鲁棒性指标
--final-prints-aggregateall/benchmark,默认benchmark汇总全部结果或仅汇总 benchmark 损坏
--cfg-optionsxxx=yyy键值对覆盖配置项,支持列表/嵌套结构(如key="[a,b]"

其中--out--show--show-dir三者至少指定其一,否则脚本会断言失败(源码见 tools/analysis_tools/test_robustness.py)。

评测指标解读:P、mPC、rPC

评测完成后,--out对应的结果文件(形如${out 前缀}_results.pkl)记录了每种损坏在各严重程度下的完整评估结果。汇总统计与打印由 tools/analysis_tools/robustness_eval.py 完成,其核心逻辑如下:

  • P(Performance on Clean Data):干净数据上的性能,即严重程度 0 的结果,作为基准参照;
  • mPC(Mean Performance under Corruption):所有损坏×非零严重程度的平均性能。当aggregate='benchmark'时仅统计前 15 种 benchmark 损坏,即mPC = np.mean(results[:15, 1:, :]);当aggregate='all'时统计全部损坏;
  • rPC(Relative Performance under Corruption):相对性能保持率,rPC = mPC / P,反映模型在损坏下保留了多大比例的精度,是评估鲁棒性最直观的指标。

针对不同数据集,脚本支持两类统计方式(源码见 tools/analysis_tools/robustness_eval.py):

  • COCO 风格(cococityscapes:按taskbbox/segm)输出 mAP、mAP_50、mAP_75、mAP_s、mAP_m、mAP_l 等完整指标;
  • Pascal VOC(voc:仅支持 bbox 任务与 AP50 指标,输出形式为各类别 AP 的均值。

在 test_robustness.py 中,脚本会根据cfg.dataset_type是否为VOCDataset自动选择 VOC 或 COCO 风格的汇总逻辑。

模型鲁棒性测试结果(COCO 2017val)

下表为各模型在 COCO 2017 val 上的鲁棒性测试结果(来自 docs/zh_cn/user_guides/robustness_benchmarking.md),其中 "box AP clean" 为干净数据上的 box AP,"box AP corr." 为损坏数据下的 box AP,"box %" 为两者比值(即 rPC),mask 列同理:

ModelBackboneStyleLr schdbox AP cleanbox AP corr.box %mask AP cleanmask AP corr.mask %
Faster R-CNNR-50-FPNpytorch1x36.318.250.2---
Faster R-CNNR-101-FPNpytorch1x38.520.954.2---
Faster R-CNNX-101-32x4d-FPNpytorch1x40.122.355.5---
Faster R-CNNX-101-64x4d-FPNpytorch1x41.323.456.6---
Faster R-CNNR-50-FPN-DCNpytorch1x40.022.456.1---
Faster R-CNNX-101-32x4d-FPN-DCNpytorch1x43.426.761.6---
Mask R-CNNR-50-FPNpytorch1x37.318.750.134.216.849.1
Mask R-CNNR-50-FPN-DCNpytorch1x41.123.356.737.220.755.7
Cascade R-CNNR-50-FPNpytorch1x40.420.149.7---
Cascade Mask R-CNNR-50-FPNpytorch1x41.220.750.235.717.649.3
RetinaNetR-50-FPNpytorch1x35.617.850.1---
Hybrid Task CascadeX-101-64x4d-FPN-DCNpytorch1x50.632.764.743.828.164.0

从上表可以观察到两个规律:其一,模型在损坏图像上的 AP 普遍大幅下降,单阶段与两阶段检测器的 rPC 大多在 50%~57% 区间,说明常见损坏对检测性能的破坏相当显著;其二,更强的骨干网络与可变形卷积(DCN)通常带来更高的绝对精度,也在一定程度上提升了 rPC——例如 Faster R-CNN X-101-32x4d-FPN-DCN 的 box % 达到 61.6%,显著高于 R-50-FPN 的 50.2%,表明模型容量与特征自适应能力有助于提高鲁棒性。

注意事项与使用建议

  1. 结果存在随机性:由于部分损坏变换(如噪声、模糊)内部带有随机过程,测试结果可能略有不同。若需严格复现,可通过--seed指定随机种子(脚本会在每轮测试前调用runner.set_randomness(args.seed),源码见 tools/analysis_tools/test_robustness.py);
  2. 依赖安装:务必先pip install imagecorruptions,否则评测会在第一个损坏变换处因RuntimeError中断;
  3. 评估范围benchmark模式默认只统计 15 种核心损坏;如需将 holdout 类(speckle_noisegaussian_blurspattersaturate)纳入统计,需使用--corruptions all并配合--final-prints-aggregate all
  4. 多 GPU 支持现状:当前仓库的鲁棒性评测脚本仅支持单 GPU 测试,多 GPU 与检测结果可视化在原文档中标记为待实现;
  5. 结果解读视角:对比box %(rPC)比单纯对比损坏下的绝对 AP 更有意义,因为它剔除了模型基础精度差异,反映的是模型在损坏下的相对保持能力;同时建议在报告中同时给出 P 与 mPC,便于读者还原绝对水平。

综上,MMDetection 的鲁棒性基准测试工具链由三个层次构成:底层的Corrupt数据变换(mmdet/datasets/transforms/transforms.py)负责施加损坏,中间的 test_robustness.py 负责批量调度评测,顶层的 robustness_eval.py 负责汇总输出 P/mPC/rPC。这套工具可无缝复用到你训练好的任意 MMDetection 模型上,是衡量模型在恶劣环境下部署可靠性的标准实践。

【免费下载链接】mmdetectionOpenMMLab Detection Toolbox and Benchmark项目地址: https://gitcode.com/gh_mirrors/mm/mmdetection

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

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

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

立即咨询