Files
yolov26_3d/eval_tools/docs/COMMON_MATCH_COMPARISON_SUMMARY.md
2026-06-24 09:35:46 +08:00

10 KiB
Executable File
Raw Blame History

基于共同匹配集的3D指标对比 - 实现总结

实现概述

已完成基于共同匹配集的3D指标对比功能解决了两个模型匹配样本数量不一致导致无法公平对比的问题。

核心实现

1. 评测器扩展 (evaluator.py)

修改内容

  • 添加 save_detailed_matches 参数到 __init__() 方法
  • 添加 detailed_3d_matches 存储结构
  • 修改 _process_frame_3d() 保存每个匹配对的详细信息:
    • GT唯一ID (基于bbox坐标的MD5哈希)
    • GT和检测的2D bbox
    • GT和检测的3D中心点
    • IoU和置信度
    • 3D误差lateral、longitudinal、heading
    • 距离信息(用于区间统计)
  • evaluate_3d() 中聚合详细匹配数据(支持多进程)
  • generate_report() 中保存 detailed_3d_matches.json

输出文件

  • detailed_3d_matches.json - 包含所有匹配对的详细信息

2. 共同匹配查找工具 (find_common_matches.py)

功能

  • 加载两个模型的详细匹配数据
  • 基于GT唯一ID找出共同匹配的目标
  • 计算匹配统计(总数、共同、独有)
  • 基于共同匹配重新计算3D统计
  • 生成详细的统计报告

核心函数

  • find_common_matches() - 找出共同匹配
  • recompute_3d_stats_from_common_matches() - 重新计算3D统计
  • print_statistics() - 打印匹配统计

输出文件

  • common_matches.json - 包含共同匹配索引和重新计算的统计

3. 模型比较器扩展 (compare_models.py)

修改内容

  • __init__() 添加 common_matches_data 参数
  • compare_3d_metrics() 检测是否使用共同匹配
  • 新增 _compare_3d_metrics_common_matches() 方法:
    • 使用预计算的共同匹配统计
    • 显示匹配统计摘要
    • 生成基于共同匹配的对比
  • main() 添加 --common-matches 参数

使用方式

# 不使用共同匹配(传统方式)
python eval_tools/compare_models.py --model1 m1.json --model2 m2.json

# 使用共同匹配
python eval_tools/compare_models.py \
  --model1 m1.json --model2 m2.json \
  --common-matches common_matches.json

4. 评测脚本扩展 (eval.py)

修改内容

  • 添加 --save-detailed-matches 参数
  • 传递参数到 Evaluator 构造函数
  • 在输出中显示是否保存详细匹配

使用方式

# 普通评测
python eval_tools/eval.py --config config.yaml

# 保存详细匹配
python eval_tools/eval.py --config config.yaml --save-detailed-matches

5. 完整流程脚本 (compare_models_with_common_matches.sh)

功能 自动化执行完整流程:

  1. 评测 Model 1 并保存详细匹配
  2. 评测 Model 2 并保存详细匹配
  3. 找出共同匹配
  4. 生成基于共同匹配的对比报告
  5. 生成传统对比报告(用于参考)

使用方式

bash eval_tools/compare_models_with_common_matches.sh

工作流程

┌─────────────────────────┐
│ Model 1 Eval            │
│ + save-detailed-matches │
└────────────┬────────────┘
             │ detailed_3d_matches.json
             │
             ↓
      ┌─────────────────────────┐
      │ find_common_matches.py  │←──┐
      └─────────────────────────┘   │
             │                       │
             │ common_matches.json   │ detailed_3d_matches.json
             │                       │
             ↓                       │
      ┌─────────────────────────┐   │
      │ compare_models.py       │   │
      │ --common-matches        │   │
      └─────────────────────────┘   │
             │                       │
             ↓                       │
      comparison_report.txt         │
      (based on common matches)     │
                                    │
┌─────────────────────────┐         │
│ Model 2 Eval            │         │
│ + save-detailed-matches │─────────┘
└─────────────────────────┘

数据结构

detailed_3d_matches.json

{
  "case_name": {
    "frame_name": {
      "class_name": [
        {
          "gt_id": "unique_hash",
          "gt_bbox": [x1, y1, x2, y2],
          "gt_center_3d": [x, y, z],
          "det_bbox": [x1, y1, x2, y2],
          "det_center_3d": [x, y, z],
          "iou": 0.89,
          "confidence": 0.87,
          "errors": {
            "lateral": 0.12,
            "longitudinal": 0.15,
            "heading": 0.05
          },
          "distance": {
            "longitudinal": 8.20,
            "lateral": -7.13
          }
        }
      ]
    }
  }
}

common_matches.json

{
  "match_statistics": {
    "model1_total": 440408,
    "model2_total": 491768,
    "common": 425163,
    "model1_unique": 15245,
    "model2_unique": 66605,
    "common_percentage_of_model1": 96.5,
    "per_class": { ... }
  },
  "common_matches": {
    "case_name": {
      "frame_name": {
        "class_name": [
          {
            "gt_id": "unique_hash",
            "model1_idx": 0,
            "model2_idx": 0
          }
        ]
      }
    }
  },
  "model1_3d_stats": {
    "vehicle": {
      "num_samples": 425163,
      "lateral_error": {"mean": 1.3251, "std": 0.8745, ...},
      "longitudinal_error": {"mean": 2.5892, "std": 1.2341, ...},
      "heading_error": {"mean": 0.2256, "std": 0.1234, ...}
    }
  },
  "model2_3d_stats": { ... },
  "model_names": {
    "model1": "mono3d",
    "model2": "yolov5s-300w"
  }
}

使用示例

示例1完整流程推荐

bash eval_tools/compare_models_with_common_matches.sh

示例2手动步骤

# 步骤1评测并保存详细匹配
python eval_tools/eval.py \
  --config eval_tools/configs/eval_config_mono3d.yaml \
  --save-detailed-matches

python eval_tools/eval.py \
  --config eval_tools/configs/eval_config_yolov5.yaml \
  --save-detailed-matches

# 步骤2找出共同匹配
python eval_tools/find_common_matches.py \
  --model1-matches eval_results/model1/detailed_3d_matches.json \
  --model2-matches eval_results/model2/detailed_3d_matches.json \
  --output common_matches.json

# 步骤3比较基于共同匹配
python eval_tools/compare_models.py \
  --model1 eval_results/model1/evaluation_report.json \
  --model2 eval_results/model2/evaluation_report.json \
  --common-matches common_matches.json \
  --output-dir comparison_results

对比报告示例

================================================================================
3D METRICS COMPARISON (COMMON MATCHES ONLY)
================================================================================

Match Statistics:
  mono3d Total Matches: 440,408
  yolov5s-300w Total Matches: 491,768
  Common Matches: 425,163 (96.5% of mono3d)
  mono3d Unique: 15,245 (3.5%)
  yolov5s-300w Unique: 66,605 (13.5%)

VEHICLE (Common Matches: 425,163):
Metric               mono3d          yolov5s-300w    Diff            Change %     
------------------------------------------------------------------------------------
Lateral (m)          1.3251          1.2103          -0.1148         -8.66%       ✓
Longitudinal (m)     2.5892          2.4231          -0.1661         -6.42%       ✓
Heading (rad)        0.2256          0.3098          +0.0842         +37.32%      ✗

Note: 这些统计基于两个模型都成功匹配的目标,排除了只被一个模型匹配的目标。

关键优势

  1. 公平对比只比较相同目标的3D预测质量排除召回率差异的影响
  2. 问题诊断:识别哪些目标一个模型能匹配而另一个不能
  3. 性能分析:可以单独分析各模型独有匹配的特点
  4. 向后兼容:不影响现有评测流程,可选启用
  5. 灵活性:支持传统对比和共同匹配对比两种模式

性能考虑

  • 存储开销detailed_3d_matches.json 约为 evaluation_report.json 的 5-10 倍
  • 时间开销:保存详细匹配会增加约 5-10% 的评测时间
  • 建议:只在需要对比时使用 --save-detailed-matches

文件清单

新增文件

  1. eval_tools/find_common_matches.py - 共同匹配查找工具
  2. eval_tools/compare_models_with_common_matches.sh - 完整流程脚本
  3. eval_tools/COMMON_MATCH_COMPARISON_DESIGN.md - 设计方案文档
  4. eval_tools/COMMON_MATCH_COMPARISON_USAGE.md - 使用指南
  5. eval_tools/COMMON_MATCH_COMPARISON_SUMMARY.md - 本文档

修改文件

  1. eval_tools/evaluator/evaluator.py - 添加详细匹配保存功能
  2. eval_tools/compare_models.py - 添加共同匹配对比功能
  3. eval_tools/eval.py - 添加 --save-detailed-matches 参数

测试建议

建议进行以下测试:

  1. 功能测试

    bash eval_tools/compare_models_with_common_matches.sh
    
  2. 验证测试

    • 检查 detailed_3d_matches.json 是否正确生成
    • 检查共同匹配数量是否合理
    • 验证对比报告中的统计是否基于共同匹配
  3. 性能测试

    • 对比启用/不启用 --save-detailed-matches 的评测时间
    • 检查文件大小是否在预期范围内

下一步扩展(可选)

  1. 独有匹配分析

    • 分析独有匹配的特征(距离、大小、置信度等)
    • 生成独有匹配的可视化
  2. 距离区间对比

    • 支持基于共同匹配的距离区间统计
    • 横向/纵向距离区间的共同匹配对比
  3. 可视化工具

    • 共同匹配 vs 独有匹配的分布图
    • 不同距离/位置的共同匹配率热力图
  4. 性能优化

    • 使用更高效的序列化格式(如 MessagePack
    • 按需加载详细匹配数据

总结

已成功实现基于共同匹配集的3D指标对比功能解决了两个模型匹配样本数量不一致的问题。该方案

  • 确保公平对比相同目标的3D性能
  • 提供独有匹配的统计分析
  • 保持向后兼容性
  • 提供完整的自动化流程
  • 包含详细的使用文档

可以立即使用此功能进行模型对比分析。