9.0 KiB
Executable File
9.0 KiB
Executable File
合并模型评测指南
概述
val_merged_model.py 是专门用于评测合并双ROI模型的脚本。它基于 val.py 的评测逻辑,但针对双ROI模型进行了适配。
功能特性
- 双ROI数据加载:为ROI0和ROI1分别创建数据加载器
- 同步推理:同时对两个ROI进行推理
- 跨ROI结果融合:使用NmsForScale算法合并两个ROI的检测结果,避免重复检测
- 完整指标计算:计算2D mAP和3D指标(深度误差、方向误差、中心点误差)
工作流程
输入数据
↓
ROI0 Dataloader → 推理 → NMS → ↘
跨ROI融合 → 2D/3D指标计算
ROI1 Dataloader → 推理 → NMS → ↗
详细步骤
- 加载合并模型:加载包含
model_roi0和model_roi1的合并模型 - 创建数据加载器:
- ROI0: 裁剪区域 [0, 120, 1920, 1080]
- ROI1: 中心区域 [704, 352],原始图像 [1920, 1080]
- 推理:对两个ROI同时进行前向传播
- NMS:对每个ROI的检测结果独立进行NMS
- 跨ROI融合:使用NmsForScale算法合并检测结果:
- 移除边缘伪影(IoU > 0.9且超出ROI边界)
- 抑制重复检测(IoU > 0.3,保留更靠近ROI中心的检测)
- 移除高度包含的检测(IoU_in > 0.8)
- 指标计算:对融合后的结果计算评测指标
使用方法
基本用法
python eval_tools/val_merged_model.py \
--data data/mono3d.yaml \
--weights release/yolov5s-30w/merged_model.pt \
--imgsz 704 352 \
--batch-size 1
参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
--data |
data/mono3d.yaml |
数据集配置文件路径 |
--weights |
必需 | 合并模型权重文件路径(.pt格式) |
--batch-size |
1 |
批大小(仅支持1) |
--imgsz |
[704, 352] |
推理图像尺寸 [宽度, 高度] |
--conf-thres |
0.001 |
NMS置信度阈值(低值用于AP计算) |
--conf-thres-plot |
0.25 |
可视化和3D指标的置信度阈值 |
--iou-thres |
0.6 |
NMS的IoU阈值 |
--max-det |
300 |
每张图片最大检测数 |
--device |
'' |
设备(如'0'或'cpu') |
--workers |
8 |
数据加载器工作线程数 |
--project |
runs/val_merged |
结果保存目录 |
--name |
exp |
实验名称 |
--verbose |
- | 按类别报告mAP |
--half |
- | 使用FP16半精度推理 |
完整示例
# 基本评测
python eval_tools/val_merged_model.py \
--data data/mono3d.yaml \
--weights release/yolov5s-30w/merged_model.pt \
--imgsz 704 352
# 使用GPU加速和半精度
python eval_tools/val_merged_model.py \
--data data/mono3d.yaml \
--weights release/yolov5s-30w/merged_model.pt \
--imgsz 704 352 \
--device 0 \
--half
# 详细输出(按类别显示mAP)
python eval_tools/val_merged_model.py \
--data data/mono3d.yaml \
--weights release/yolov5s-30w/merged_model.pt \
--imgsz 704 352 \
--verbose
# 自定义输出目录
python eval_tools/val_merged_model.py \
--data data/mono3d.yaml \
--weights release/yolov5s-30w/merged_model.pt \
--imgsz 704 352 \
--project runs/my_eval \
--name merged_exp1
输出结果
控制台输出
评测过程中会实时显示:
Class Images Instances P R mAP50 mAP50-95 Matched Depth(m) Orient(°) Center(m)
all 50 150 0.856 0.823 0.891 0.672 89 2.345 12.678 0.234
- Class: 类别名称
- Images: 处理的图片数量
- Instances: 真实标注数量
- P: 精确率
- R: 召回率
- mAP50: mAP@0.5
- mAP50-95: mAP@0.5:0.95
- Matched: 3D匹配的检测数
- Depth(m): 平均深度误差(米)
- Orient(°): 平均方向误差(度)
- Center(m): 平均中心点误差(米)
最终统计
3D Metrics (Fused ROI0+ROI1):
Total matched: 89
Depth error (abs): 2.345m
Orientation error: 12.678°
Center error: 0.234m
保存的文件
结果保存在 --project/--name 目录下:
confusion_matrix.png: 混淆矩阵图F1_curve.png: F1曲线P_curve.png: 精确率曲线R_curve.png: 召回率曲线PR_curve.png: PR曲线
ROI配置
脚本内置了ROI配置,与 test_val_merged_model.py 保持一致:
# ROI0: 裁剪区域
roi0 = (0, 120, 1920, 1080)
ori_img_size_roi0 = None
# ROI1: 中心区域
roi1 = (704, 352)
ori_img_size_roi1 = (1920, 1080)
# 跨ROI NMS使用的ROI坐标(原始图像坐标系)
roi_list = [
(0, 120, 1920, 1080), # ROI0
(608, 364, 1312, 716) # ROI1在原始图像中的坐标
]
跨ROI NMS算法
NmsForScale 函数实现了跨ROI的检测融合:
-
边缘伪影过滤:
- 计算检测框与ROI的IoU
- 如果IoU > 0.9且检测框超出ROI边界,则移除
-
重复检测抑制:
- 对于来自不同ROI的检测框
- 如果IoU > 0.3(高度重叠)
- 保留距离ROI中心更近的检测
-
包含关系处理:
- 如果一个检测框被另一个检测框高度包含(IoU_in > 0.8)
- 移除被包含的检测框
注意事项
- 批大小限制:合并模型评测仅支持
batch_size=1 - 模型格式:仅支持PyTorch .pt格式的合并模型(包含Model_Merged类)
- 数据集要求:数据集必须包含3D标注(48列标签格式)
- 内存使用:同时加载两个ROI的数据会增加内存使用
- 速度:由于需要推理两个ROI和跨ROI融合,速度会比单ROI评测慢
与单ROI评测的对比
| 特性 | val.py (单ROI) | val_merged_model.py (双ROI) |
|---|---|---|
| 批大小 | 支持任意 | 仅支持1 |
| 数据加载器 | 单个 | 两个(ROI0+ROI1) |
| 推理次数 | 1次/图像 | 2次/图像 |
| NMS | 单次 | 2次独立+跨ROI融合 |
| 结果 | 单ROI检测 | 融合后的全图检测 |
| 速度 | 快 | 较慢(约2倍推理时间) |
| 覆盖范围 | 单个ROI | 全图覆盖 |
故障排除
问题1:模型加载失败
ValueError: Model at xxx is not a merged dual-ROI model
解决方法:确保模型是通过 merge_models_of_2roi.py 创建的合并模型,包含 model_roi0 和 model_roi1 属性。
问题2:数据加载器长度不匹配
WARNING Dataloader lengths mismatch: ROI0=100, ROI1=98
解决方法:检查数据集配置,确保两个ROI访问相同的图像文件。
问题3:路径不匹配
WARNING Path mismatch: xxx vs yyy
解决方法:这通常表示两个数据加载器返回的图像顺序不一致,检查数据集配置和路径。
问题4:内存不足
解决方法:
- 减少
--workers数量 - 使用
--half启用FP16推理 - 在CPU上运行:
--device cpu
相关文件
val.py: 单ROI模型评测脚本merge_models_of_2roi.py: 合并两个ROI模型的脚本test_val_merged_model.py: 合并模型推理测试脚本(仅推理,不计算指标)val_merged_model.py: 本脚本,合并模型完整评测
工作流程示例
完整的训练+合并+评测流程:
# 1. 训练ROI0模型
python train_mono3d.py --data data/mono3d.yaml --roi 0 120 1920 1080 --weights yolov5s.pt
# 2. 训练ROI1模型
python train_mono3d.py --data data/mono3d.yaml --roi 704 352 --ori-img-size 1920 1080 --weights yolov5s.pt
# 3. 评测单个模型(可选)
python val.py --weights runs/train/roi0_exp/weights/last.pt --data data/mono3d.yaml --roi 0 120 1920 1080
python val.py --weights runs/train/roi1_exp/weights/last.pt --data data/mono3d.yaml --roi 704 352 --ori-img-size 1920 1080
# 4. 合并模型
python eval_tools/merge_models_of_2roi.py \
--roi0_model_path runs/train/roi0_exp/weights/last.pt \
--roi1_model_path runs/train/roi1_exp/weights/last.pt \
--save_dir release/merged \
--skip-export # 仅保存合并模型,不导出ONNX
# 5. 评测合并模型
python eval_tools/val_merged_model.py \
--data data/mono3d.yaml \
--weights release/merged/merged_model.pt \
--imgsz 704 352
# 6. 推理测试(可选)
python eval_tools/test_val_merged_model.py \
--source /path/to/test/images \
--weights release/merged/merged_model.pt \
--model-type torchscript
扩展说明
如果需要修改ROI配置,编辑脚本中的以下部分:
# 在 run() 函数中,约第375行
roi0 = (0, 120, 1920, 1080) # 修改ROI0坐标
roi1 = (704, 352) # 修改ROI1尺寸
ori_img_size_roi1 = (1920, 1080) # 修改原始图像尺寸
# 在跨ROI NMS部分,约第431行
roi_list = [
(0, 120, 1920, 1080), # ROI0坐标
(608, 364, 1312, 716) # ROI1在原始图像中的坐标(需要计算)
]
计算ROI1在原始图像中的坐标:
# 如果ROI1是中心裁剪,计算方式:
ori_w, ori_h = 1920, 1080
roi1_w, roi1_h = 704, 352
x1 = (ori_w - roi1_w) // 2 # 608
y1 = (ori_h - roi1_h) // 2 # 364
x2 = x1 + roi1_w # 1312
y2 = y1 + roi1_h # 716