Files
yolov26_3d/eval_tools/docs/README_VAL_MERGED.md

304 lines
9.0 KiB
Markdown
Raw Normal View History

2026-06-24 09:35:46 +08:00
# 合并模型评测指南
## 概述
`val_merged_model.py` 是专门用于评测合并双ROI模型的脚本。它基于 `val.py` 的评测逻辑但针对双ROI模型进行了适配。
## 功能特性
1. **双ROI数据加载**为ROI0和ROI1分别创建数据加载器
2. **同步推理**同时对两个ROI进行推理
3. **跨ROI结果融合**使用NmsForScale算法合并两个ROI的检测结果避免重复检测
4. **完整指标计算**计算2D mAP和3D指标深度误差、方向误差、中心点误差
## 工作流程
```
输入数据
ROI0 Dataloader → 推理 → NMS → ↘
跨ROI融合 → 2D/3D指标计算
ROI1 Dataloader → 推理 → NMS → ↗
```
### 详细步骤
1. **加载合并模型**:加载包含 `model_roi0``model_roi1` 的合并模型
2. **创建数据加载器**
- ROI0: 裁剪区域 [0, 120, 1920, 1080]
- ROI1: 中心区域 [704, 352],原始图像 [1920, 1080]
3. **推理**对两个ROI同时进行前向传播
4. **NMS**对每个ROI的检测结果独立进行NMS
5. **跨ROI融合**使用NmsForScale算法合并检测结果
- 移除边缘伪影IoU > 0.9且超出ROI边界
- 抑制重复检测IoU > 0.3保留更靠近ROI中心的检测
- 移除高度包含的检测IoU_in > 0.8
6. **指标计算**:对融合后的结果计算评测指标
## 使用方法
### 基本用法
```bash
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半精度推理 |
### 完整示例
```bash
# 基本评测
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` 保持一致:
```python
# 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的检测融合
1. **边缘伪影过滤**
- 计算检测框与ROI的IoU
- 如果IoU > 0.9且检测框超出ROI边界则移除
2. **重复检测抑制**
- 对于来自不同ROI的检测框
- 如果IoU > 0.3(高度重叠)
- 保留距离ROI中心更近的检测
3. **包含关系处理**
- 如果一个检测框被另一个检测框高度包含IoU_in > 0.8
- 移除被包含的检测框
## 注意事项
1. **批大小限制**:合并模型评测仅支持 `batch_size=1`
2. **模型格式**仅支持PyTorch .pt格式的合并模型包含Model_Merged类
3. **数据集要求**数据集必须包含3D标注48列标签格式
4. **内存使用**同时加载两个ROI的数据会增加内存使用
5. **速度**由于需要推理两个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`: 本脚本,合并模型完整评测
## 工作流程示例
完整的训练+合并+评测流程:
```bash
# 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配置编辑脚本中的以下部分
```python
# 在 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在原始图像中的坐标
```python
# 如果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
```