在運行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."