在运行test.py时报错:
BEVFormer/projects/mmdet3d_plugin/datasets/nuscnes_eval.py: init()函数报错
assert set(self.pred_boxes.sample_tokens) == set(self.gt_boxes.sample_tokens), \"Samples in split doesn't match samples in predictions."
一、评估流程:
整体流程:
数据预处理:CustomNuScenesDataset
(projects/mmdet3d_plugin/datasets/nuscenes_dataset.py)
加载多帧数据,支持点云和图像的联合输入,增加了夜晚场景的专项处理。
评估流程:NuScenesEval_custom
(projects/mmdet3d_plugin/datasets/nuscnes_eval.py)
提供灵活的评估框架,支持按可见性、场景重叠等条件过滤数据,计算指标并可视化结果。
- 从
results_nusc.json
加载检测结果,包含6019个样本 - 通过
get_night_scenes()
获取val子集中的15个夜晚场景 - 过滤检测结果,只保留这15个夜晚场景的602帧数据
- 将过滤后的结果保存为新的json文件:
filtered_results_nusc.json
- 使用
NuScenesEval_custom
进行评估:- 加载真值(GT)数据
- 计算检测指标(mAP、NDS等)
- 生成评估报告
results_nusc.json 文件中的内容
test/bevformer_base/Fri_Mar_21_01_24_36_2025/pts_bbox/results_nusc.json:
{"meta": {"use_lidar": false,"use_camera": true,"use_radar": false,"use_map": false,"use_external": true},"results": {"sample_token_1": [{"sample_token": "xxx","translation": [x, y, z],"size": [l, w, h],"rotation": [w, x, y, z],"velocity": [vx, vy],"detection_name": "car","detection_score": 0.9,"attribute_name": "vehicle.parked"},// ... 更多检测结果],// ... 更多样本}
}
二、错误原因分析
NuScenesEval_custom
的 load_gt
函数加载了整个 eval_set
**(这里是 val)**的 ground truth
数据,而不是只加载与过滤后预测结果对应的样本。
结果是预测数据只有 602 个样本的 token
,而 ground truth 有 6019 个样本的 token
,导致断言失败。
三、解决方案
修改 NuScenesEval_custom
的初始化逻辑,确保 ground truth
只加载与预测结果匹配的样本 token
,而不是整个 eval_set
的所有样本。可以通过以下步骤实现:
- 获取预测结果的样本
token
: 在加载预测结果后,提取self.pred_boxes.sample_tokens
。 - 过滤
Ground Truth
: 修改load_gt
调用,使用预测结果的样本token
集合来过滤ground truth
数据。 - 更新
_evaluate_single
: 将过滤后的样本token
传递给NuScenesEval_custom
,确保评估只针对这602
个样本。
在projects/mmdet3d_plugin/datasets/nuscnes_eval.py中的__init__中加入:# 只加载与预测结果匹配的 ground truthpred_sample_tokens = set(self.pred_boxes.sample_tokens)if verbose:print(f"Loading ground truth for {len(pred_sample_tokens)} predicted samples...")self.gt_boxes = load_gt(self.nusc, self.eval_set, DetectionBox_modified, verbose=verbose)self.gt_boxes = filter_by_sample_token(self.gt_boxes, pred_sample_tokens, verbose=verbose)# 验证样本 token 匹配assert set(self.pred_boxes.sample_tokens) == set(self.gt_boxes.sample_tokens), \"Samples in split don't match samples in predictions after filtering."