IDM-VTON 人体解析评测指南:深入解读 detectron2 的 DatasetEvaluator 与 inference_on_dataset 评估机制

原创2026-10-02 13:24:312,338 阅读
文章标签:计算机视觉深度学习媒体生成

IDM-VTON 人体解析评测指南:深入解读 detectron2 的 DatasetEvaluator 与 inference_on_dataset 评估机制

本篇文章以 IDM-VTON 仓库 preprocess/humanparsing/mhp_extension/detectron2/docs/tutorials/evaluation.md 为核心骨架,系统讲解 detectron2 标准评测流程:从 DatasetEvaluator 接口的三大生命周期方法,到自定义评测器、inference_on_dataset 调度与多评测器合并,再到内置 COCO/LVIS 评测器与训练流程的自动接缝。读完你将能够在人体解析、语义分割等视觉任务中独立编写、组合并运行可靠的模型评测,并直接复用本仓库的评测配置与工具链。

一、评测的本质:输入/输出对的聚合

评测(Evaluation)是一个将大量 输入/输出 对收集起来并聚合成指标的过程。detectron2 提供了两条路径来完成这件事:

  • 直接使用模型:手动调用模型、解析其输入输出并自行汇总,完全由开发者控制,参考模型使用文档中关于输入输出格式的说明。
  • 基于 DatasetEvaluator 接口:detectron2 官方推荐的标准化方式,评测逻辑被封装为可复用、可组合的组件。

在 IDM-VTON 的预处理链中,人体解析(humanparsing)正是依赖 detectron2 完成语义分割/实例分割推理与评测,因此掌握这套评测机制是理解并复现仓库预处理流水线的关键一环。

二、DatasetEvaluator:评测器的统一接口

接口基类定义在 detectron2/evaluation/evaluator.py 中,其核心契约包含三个方法:

方法 作用 调用时机
reset() 为新一轮评测做初始化,清空上一轮累积的中间状态 一轮评测开始前
process(inputs, outputs) 逐批处理模型输入与输出,累积评测所需信息 每个 batch 推理完成后
evaluate() 汇总所有已处理的数据,输出最终指标字典 全部数据推理完成后

process 的输入为两个 list:inputs 是喂给模型的原始输入(如 dict 列表,包含 height、width、file_name、image_id 等字段),outputs 是 model(inputs) 的返回值(通常为包含 instances 键的 dict 列表)。基类注释明确建议:若输入/输出含有 batch,应通过 zip(inputs, outputs) 逐对消费。evaluate() 的返回值约定为 OrderedDict,形如 {"bbox": {"AP50": 80}},即 任务名 -> {指标名 -> 分数}。

一个完整的自定义评测器示例

原文档给出的 Counter 示例完整展示了三方法的最小实现——统计验证集上检测到的实例总数:

class Counter(DatasetEvaluator):
    def reset(self):
        self.count = 0

    def process(self, inputs, outputs):
        for output in outputs:
            self.count += len(output["instances"])

    def evaluate(self):
        # save self.count somewhere, or print it, or return it.
        return {"count": self.count}

reset 将计数器归零,process 遍历每个 batch 的预测结果累加实例数量,evaluate 以字典形式返回最终统计值。这一模式是编写任意自定义评测器的通用骨架:process 负责"攒数据",evaluate 负责"出结论",reset 保证多轮评测之间状态隔离。

三、inference_on_dataset:一键驱动评测

拿到评测器后,通过 inference_on_dataset(model, data_loader, evaluator) 即可驱动整个评测流程。原文档的用法示例:

val_results = inference_on_dataset(
    model,
    val_data_loader,
    DatasetEvaluators([COCOEvaluator(...), Counter()]))

其实现位于 detectron2/evaluation/evaluator.py,包含几个值得注意的细节:

  • 固定长度要求:data_loader 必须是可迭代且具有长度的对象,因为函数需要据此计算总进度与 ETA。
  • 自动切 eval 模式:通过 inference_context 上下文管理器(evaluator.py)临时将模型切换为 eval() 模式,退出后恢复原训练模式;全程包在 torch.no_grad() 中,不计算梯度。
  • 空评测器兜底:若传入 evaluator=None,函数会创建 DatasetEvaluators([]) 空容器,此时仅做性能基准测试而不做任何评估。
  • 分布式的结果汇聚:多进程场景下由 evaluator.evaluate() 内部负责 comm.gather 汇总,非主进程可返回空 dict 或 None,函数会自动把 None 归一为空字典,方便下游处理。

四、DatasetEvaluators:一次遍历跑多个评测

inference_on_dataset 相对于手动评测的核心优势,正是其第三个参数 DatasetEvaluators——一个把多个评测器组合成单个评测器的包装类(同样定义在 evaluator.py)。

它的组合逻辑非常直观:reset() 依次重置所有子评测器,process() 将同一批输入输出广播给每个子评测器,evaluate() 则串行收集各子评测器结果并合并为一个 OrderedDict。若不同评测器产生了相同的 key,会触发断言错误以提前暴露命名冲突。由此带来的收益是:多类指标(如 COCO 检测 + 自定义计数)可以在一次数据集遍历中全部完成,无需多次跑模型。

五、内置评测器与评测任务体系

detectron2 内置了一批基于标准数据集 API 的 DatasetEvaluator,分布在 detectron2/evaluation/ 目录下:

评测器 适用数据集/任务 实现要点(源码佐证)
COCOEvaluator 目标检测 / 实例分割 / 关键点 依据配置动态决定评测任务:bbox 为默认,MODEL.MASK_ON 时追加 segm,MODEL.KEYPOINT_ON 时追加 keypoints(见 coco_evaluation.py)
LVISEvaluator LVIS 长尾检测/分割 任务推导逻辑类似,仅包含 bbox 与 segm(见 lvis_evaluation.py)
SemSegEvaluator / COCOPanopticEvaluator 语义分割 / 全景分割 从 cfg.MODEL.SEM_SEG_HEAD.NUM_CLASSES 等处读取类别配置
CityscapesEvaluator / PascalVOCDetectionEvaluator 城市场景实例/语义分割、PASCAL VOC 检测 各自对接官方评测协议

以 COCOEvaluator 为例,其 process 阶段把每个 batch 的 Instances 转为 COCO 提交格式(image_id + 类别 + bbox + 分割掩码),evaluate 阶段再调用 pycocotools 的 COCOeval 计算 AP/AR 等指标,并可选地在 output_dir 下导出两份产物:instances_predictions.pth(原始预测,torch 序列化格式)与 coco_instances_results.json(COCO 标准结果格式)。测试集 JSON 若不含标注,评测器会自动跳过本地打分(_do_evaluation = "annotations" in self._coco_api.split_name),示意用户改用评测服务器。

六、与训练流程的无缝集成:DefaultTrainer.test

评测能力被内建到了训练管线中。engine/defaults.py 的 DefaultTrainer.test 方法会遍历 cfg.DATASETS.TEST 中每个数据集:先用 build_test_loader 构建评测数据加载器,再取对应的评测器执行 inference_on_dataset,最后用 print_csv_format 打印 CSV 格式指标(见 evaluation/testing.py),该格式便于直接粘贴进电子表格。

有两个关键集成点需要开发者自行补齐或覆盖:

  1. build_evaluator 必须实现:基类默认抛出 NotImplementedError(defaults.py),并提示要么在子类中实现、要么直接调用评测函数。
  2. 参考实现位于 tools/train_net.py:它依据 MetadataCatalog.get(dataset_name).evaluator_type 这一元数据做 if-else 分派——coco 类型挂 COCOEvaluator,lvis 类型挂 LVISEvaluator,sem_seg 类型挂 SemSegEvaluator,当多种类型并存时自动用 DatasetEvaluators 合并返回。

此外,训练循环中的 EvalHook(cfg.TEST.EVAL_PERIOD, test_and_save_results)(defaults.py)保证按配置周期自动执行评测,评测结果可通过 CommonMetricPrinter、JSONWriter 与 TensorboardXWriter 三类 writer 实时记录。命令行方面,--eval-only 标志可跳过训练直接评测,配合 MODEL.WEIGHTS 指定权重文件即可,例如:

python tools/train_net.py --num-gpus 1 --eval-only \
    --config-file configs/Misc/parsing_inference.yaml \
    MODEL.WEIGHTS /path/to/model_final.pth

评测结束后还可通过 cfg.TEST.EXPECTED_RESULTS((task, metric, expected, tolerance) 元组列表)做结果验证,不达标时 verify_results(testing.py)会以非零退出码标记失败。

七、内置速度基准:评测之外的额外收益

inference_on_dataset 在评测之外还提供了精确的推理速度基准。源码实现中有几个工程细节:

  • 5 个 warmup batch:num_warmup = min(5, total - 1),前 5 个 batch 不计入统计,用于排除 CUDA 预热与显存分配抖动。
  • 纯计算时间:对每个 batch 用 time.perf_counter() 计时,并在 CUDA 可用时执行 torch.cuda.synchronize() 确保 GPU 算子真正完成,从而测得"纯推理计算时间"。
  • 实时进度与 ETA:每 5 秒输出一次 Inference done {i}/{total}. {s:.4f} s / demo. ETA=...,结束后汇总打印 Total inference time 与 Total inference pure compute time(均为每设备、每张图的平均耗时,并标注设备数),且日志格式带 grep 可解析标记,便于脚本化提取性能数据。

八、在 IDM-VTON 人体解析管线中的落地

仓库将上述评测机制直接用于人体解析模型的推理与验证。parsing_inference.yaml 提供了可直接运行的评测/推理配置,要点如下:

MODEL:
  MASK_ON: True
  WEIGHTS: "./finetune_ouput/model_final.pth"
  ROI_HEADS:
    NMS_THRESH_TEST: 0.95
    SCORE_THRESH_TEST: 0.5
    NUM_CLASSES: 1
SOLVER:
  IMS_PER_BATCH: 1
  STEPS: (30000, 45000)
  MAX_ITER: 50000
  BASE_LR: 0.02
INPUT:
  MIN_SIZE_TRAIN: (640, 864)
  MAX_SIZE_TRAIN: 1440
TEST:
  AUG:
    ENABLED: True
DATASETS:
  TRAIN: ("CIHP_trainval",)
  TEST: ("CIHP_test",)
OUTPUT_DIR: "./inference_output"
  • 单类别(NUM_CLASSES: 1)掩码模型(MASK_ON: True)配合 CIHP 人体解析数据集,评测时会由 build_evaluator 自动挂载语义分割/实例分割类评测器。
  • TEST.AUG.ENABLED: True 对应 tools/train_net.py 中的 test_with_TTA:评测时启用测试时增强(TTA),结果写入 OUTPUT_DIR/inference_TTA 目录,且返回的指标 key 会统一追加 _TTA 后缀以区分。
  • 默认评测产物落在 cfg.OUTPUT_DIR/inference(build_evaluator 的 output_folder 默认值),同时配合 测试配置 下各 *_inference_acc_test.yaml,可在小数据子集上快速验证评测链路是否正确。

九、小结:从接口到实战的评测闭环

detectron2 的评测体系由三块拼图构成:接口(DatasetEvaluator 的 reset/process/evaluate 契约)、调度(inference_on_dataset 统一驱动并附带速度基准)、组合与集成(DatasetEvaluators 合并多评测器、DefaultTrainer.test 与 EvalHook 自动接入训练循环)。在 IDM-VTON 中,这套机制支撑着人体解析模型 CIHP 数据集的评测与验证:既可开箱即用地跑通 parsing_inference.yaml,也可继承 DatasetEvaluator 编写自定义指标评测器,在单次数据集遍历中同时获得检测/分割指标与自定义统计结果。掌握这三点,即可在任何 detectron2 系视觉任务中落地标准、可复现、可量化的模型评测流程。

登录后查看全文
IDM-VTON