4、主流数据集与评测指标:nuScenes、Waymo、SemanticKITTI等,IoU、mIoU、BEV mAP等指标详解
在BEV与Occupancy联合训练的实际工程落地中,数据集与评测指标决定了模型优化的方向与最终性能的可信度。很多初学者在跑通模型后,往往因为对数据标注格式理解不深、对指标计算口径混淆,导致实验对比失真或调优方向错误。本章将系统梳理自动驾驶领域三大主流数据集——nuScenes、Waymo、SemanticKITTI——的传感器配置、标注体系与适用场景,并深入剖析IoU、mIoU、BEV mAP等核心指标的计算原理、代码实现要点与工程陷阱,帮助你在实际训练与评估中建立科学的量化基准。
上图展示了三大数据集与核心指标之间的对应关系。在实际工程中,我们需要根据任务目标选择合适的数据集:如果做多模态BEV感知,nuScenes是首选;如果关注大规模点云Occupancy,Waymo的高精度激光雷达标注更具优势;而SemanticKITTI则提供了最细粒度的逐点语义标注,适合作为Occupancy监督信号的来源。下面我们逐一展开。
4.1 三大主流数据集深度对比
4.1.1 nuScenes:多模态BEV感知的黄金标准
核心原理:nuScenes由Motional(原nuTonomy)发布,是目前学术界和工业界使用最广泛的自动驾驶多模态数据集。它包含1000个场景,每个场景约20秒,关键帧采样频率为2Hz,共约40k个关键帧。传感器配置包括6个相机(覆盖360°视野)、5个毫米波雷达和1个激光雷达(32线)。其标注体系覆盖23类物体,但官方评测只关注10类(如车辆、行人、自行车等)。
判断方法:选择nuScenes时,你需要确认以下条件是否满足:
- 任务需要多模态融合(相机+雷达+激光雷达)
- 需要BEV视角下的3D检测与跟踪
- 需要预测模块(轨迹、速度、加速度)
- 需要与官方排行榜对比(nuScenes leaderboard)
案例拆解:假设你正在训练一个BEV感知模型,输入为6路相机图像,输出为BEV平面上的3D检测框。使用nuScenes时,你需要将相机外参、内参以及激光雷达点云投影到BEV网格中。关键参数包括:BEV网格范围(通常为[-50m, 50m]×[-50m, 50m]),网格分辨率(0.5m或0.25m)。在数据预处理阶段,需要将3D标注框转换为BEV视角下的2D框(中心点+朝向角+尺寸),并计算中心点距离匹配。
实战要点:nuScenes的标注格式为JSON,每个关键帧包含6个相机的图像路径、校准参数、标注框(3D框的8个角点坐标)。在训练时,建议将相机图像resize到固定尺寸(如256×704),并保持宽高比不变,避免畸变影响BEV投影精度。
4.1.2 Waymo Open Dataset:大规模高精度点云Occupancy
核心原理:Waymo Open Dataset由Waymo公司发布,包含1150个场景,每个场景20秒,共约200k帧。传感器配置为5个激光雷达(1个中距+4个短距)、5个相机。其最大优势在于激光雷达点云密度极高(中距激光雷达64线),非常适合Occupancy网络的监督训练。标注类别包括车辆、行人、骑行者三类,但每个类别附带速度、加速度等运动属性。
操作流程:使用Waymo进行Occupancy训练时,推荐以下流程:
- 将点云体素化,体素尺寸通常为0.1m或0.2m
- 为每个体素分配语义标签(车辆/行人/骑行者/背景)
- 生成Occupancy ground truth:对每个体素计算是否被占据,以及占据类别
- 训练时使用加权交叉熵损失,背景类权重降低(如0.2),前景类权重提高(如1.0)
常见误区:很多初学者直接使用Waymo的3D框标注来生成Occupancy标签,但3D框是轴对齐的,无法覆盖物体的精细形状。正确做法是使用点云语义分割结果(如PointNet++或SPVCNN)生成稠密语义标签,再体素化。
4.1.3 SemanticKITTI:逐点语义标注的Occupancy监督源
核心原理:SemanticKITTI基于KITTI Vision Benchmark,提供了22个序列(00-21),其中序列00-10用于训练,11-21用于测试。它包含超过43k帧的激光雷达点云,每帧约120k个点,每个点都有19类语义标签(如道路、人行道、建筑、车辆、行人等)。这是目前最细粒度的点云语义标注数据集。
判断方法:SemanticKITTI适合以下场景:
- 需要稠密语义Occupancy预测(不仅仅是二值占据)
- 需要评估模型在复杂城市场景下的泛化能力
- 需要与基于激光雷达的SOTA方法对比(如MonoScene、TPVFormer)
案例拆解:假设你使用SemanticKITTI训练Occupancy网络,输入为单目相机图像,输出为3D体素网格上的语义类别。你需要将点云投影到体素网格中,体素尺寸设为0.2m,网格范围为[0m, 51.2m]×[-25.6m, 25.6m]×[-2m, 4.4m]。训练时,背景类(如道路、建筑)占据绝大多数体素,导致类别不平衡。解决方案是使用类别加权损失,或者使用Focal Loss。
| 数据集 | 传感器配置 | 标注粒度 | 场景数 | 适用任务 | 主要局限 |
|---|---|---|---|---|---|
| nuScenes | 6相机+5雷达+1激光 | 3D框+BEV语义 | 1000 | 多模态BEV检测 | 激光雷达线数低 |
| Waymo | 5激光+5相机 | 3D框+点云语义 | 1150 | Occupancy预训练 | 类别较少 |
| SemanticKITTI | 1激光+2相机 | 逐点语义 | 22序列 | 稠密Occupancy | 传感器较老 |
4.2 核心评测指标详解
4.2.1 IoU与mIoU:Occupancy的黄金指标
核心原理:IoU(Intersection over Union)计算预测区域与真实区域的交集面积除以并集面积。在Occupancy任务中,每个体素被视为一个像素,IoU计算的是预测占据体素集合与真实占据体素集合的重合度。mIoU则是所有类别IoU的算术平均值。
计算公式:
IoU_class = TP_class / (TP_class + FP_class + FN_class)
mIoU = (1/N) * Σ IoU_class
其中TP为真正例(预测为正且真实为正),FP为假正例(预测为正但真实为负),FN为假负例(预测为负但真实为正)。
操作流程:在评估Occupancy模型时,推荐以下步骤:
- 将预测的体素概率图通过argmax转换为类别标签
- 将预测标签与ground truth逐体素比较
- 计算每个类别的混淆矩阵(TP/FP/FN)
- 计算各类IoU,再求平均得到mIoU
风险提示:在计算mIoU时,如果某个类别在ground truth中不存在(例如测试场景中没有行人),该类的IoU应设为0还是忽略?标准做法是忽略该类别,只计算存在类别的平均。否则,缺失类别会拉低mIoU,导致不公平对比。
4.2.2 BEV mAP:nuScenes官方检测指标
核心原理:BEV mAP(mean Average Precision)是nuScenes官方采用的检测指标,它不同于传统的3D IoU匹配,而是使用BEV平面上的中心点距离匹配。具体来说,预测框与真实框在BEV平面上的中心点距离小于2m(车辆)或1m(行人/自行车)即视为匹配成功。
计算流程:
1. 将预测框投影到BEV平面,计算中心点坐标
2. 对每个类别,按置信度降序排列预测框
3. 对每个预测框,找到距离最近且未匹配的真实框
4. 若距离小于阈值,则记为TP,否则为FP
5. 计算Precision-Recall曲线,求AP
6. 所有类别AP平均得到mAP
案例拆解:假设你的BEV模型在nuScenes验证集上输出100个车辆预测框,真实框有80个。经过中心点距离匹配后,有70个预测框匹配成功(TP),30个预测框未匹配(FP),同时有10个真实框未被匹配(FN)。则Precision=70/100=0.7,Recall=70/80=0.875。通过改变置信度阈值,可以得到完整的PR曲线,计算曲线下面积即为AP。
经验提醒:BEV mAP对中心点距离阈值非常敏感。在联合训练中,建议同时报告2m和1m两个阈值下的mAP,以全面评估模型在不同精度要求下的表现。此外,nuScenes还提供了NDS(NuScenes Detection Score),它综合了mAP、mATE(平均平移误差)、mASE(平均尺寸误差)、mAOE(平均朝向误差)、mAVE(平均速度误差)和mAAE(平均属性误差),是更全面的评估指标。
4.2.3 联合训练中的指标协同
核心原理:在BEV与Occupancy联合训练中,单一指标无法全面反映模型性能。Occupancy分支关注几何与语义完整性(mIoU),BEV检测分支关注目标定位精度(mAP)。两者需要协同优化,但存在潜在冲突:Occupancy要求稠密预测,可能产生过多假阳性体素;BEV检测要求稀疏精确,可能忽略背景细节。
判断方法:建议采用以下评估矩阵:
| 评估维度 | 指标 | 阈值/标准 | 联合训练目标 |
|---|---|---|---|
| 几何完整性 | Occupancy IoU | IoU>0.5 | ≥0.45 |
| 语义准确性 | mIoU | 19类平均 | ≥0.35 |
| 目标检测 | BEV mAP | 中心距离2m | ≥0.45 |
| 综合性能 | NDS | nuScenes官方 | ≥0.55 |
常见误区:很多团队在联合训练时只关注mIoU,导致BEV检测性能下降。正确做法是设置多任务损失权重,并在验证集上同时监控两个指标。如果mIoU提升但mAP下降,说明Occupancy分支过于激进,需要降低其损失权重或增加BEV检测的难例挖掘。
实战复盘:在某量产项目中,我们使用nuScenes预训练+Waymo微调的方式训练Occupancy网络。初始阶段mIoU为0.28,BEV mAP为0.38。通过调整损失权重(Occupancy损失权重从1.0降至0.6),并引入BEV检测的Focal Loss,最终mIoU提升至0.34,BEV mAP提升至0.47。关键操作包括:①在Occupancy分支使用类别加权损失,背景类权重0.2;②在BEV检测分支使用中心点距离匹配时,对难例(距离在1-2m之间的样本)进行上采样;③每5个epoch在验证集上同时计算两个指标,若mAP下降超过0.02则回滚模型。
4.3 指标计算工程化实现
4.3.1 高效mIoU计算代码模板
在实际工程中,直接使用Python循环计算mIoU效率极低。推荐使用向量化实现:
import numpy as np
def compute_mIoU(pred, target, num_classes):
"""
pred: (N,) 预测类别索引
target: (N,) 真实类别索引
num_classes: 类别总数
"""
iou_list = []
for cls in range(num_classes):
pred_mask = (pred == cls)
target_mask = (target == cls)
intersection = np.logical_and(pred_mask, target_mask).sum()
union = np.logical_or(pred_mask, target_mask).sum()
if union == 0:
continue # 忽略不存在的类别
iou = intersection / union
iou_list.append(iou)
return np.mean(iou_list)
注意事项:当处理大规模体素网格(如200×200×16=640k个体素)时,建议使用PyTorch的GPU张量操作,避免CPU内存瓶颈。同时,在分布式训练中,需要跨GPU汇总混淆矩阵,再计算mIoU。
4.3.2 BEV mAP的工程陷阱
核心原理:BEV mAP计算中最容易出错的是匹配策略。nuScenes官方使用贪心匹配:对每个预测框,按置信度降序,找到距离最近且未匹配的真实框。如果多个预测框匹配到同一个真实框,只有置信度最高的那个记为TP,其余记为FP。
操作流程:
- 将预测框和真实框都转换到BEV坐标系(x, y, yaw)
- 计算预测框中心点与真实框中心点的欧氏距离
- 按类别分别处理,不同类别使用不同距离阈值
- 使用匈牙利算法或贪心算法进行匹配
风险提示:在联合训练中,如果Occupancy分支输出的语义分割结果被用于过滤BEV检测框(例如去除落在道路上的车辆框),需要确保过滤逻辑不引入系统性偏差。建议在验证集上对比有无过滤的mAP差异,若差异超过0.05,则需要调整过滤策略。
4.4 数据集与指标的选择策略
核心原理:选择数据集和指标时,需要根据任务阶段和目标来决定。研究阶段可以使用SemanticKITTI快速验证算法可行性;工程落地阶段使用nuScenes进行多模态融合验证;大规模预训练使用Waymo提升泛化能力。
判断方法:以下决策树可以帮助你快速选择:
- 如果任务需要稠密语义Occupancy → SemanticKITTI + mIoU
- 如果任务需要多模态BEV检测 → nuScenes + BEV mAP + NDS
- 如果任务需要大规模预训练 → Waymo + Occupancy IoU
- 如果任务需要联合训练 → nuScenes + 双指标监控
案例拆解:某自动驾驶公司需要开发一个BEV感知系统,要求同时输出3D检测框和可行驶区域。他们选择nuScenes作为主数据集,使用BEV mAP评估检测性能,使用mIoU评估可行驶区域分割。在训练过程中,他们发现mIoU在0.3左右停滞,而BEV mAP已经达到0.5。分析后发现,可行驶区域类别在BEV网格中占比过大(约60%),导致模型偏向预测背景。解决方案是使用类别加权损失,将可行驶区域权重从1.0降至0.5,同时增加边界体素的权重(通过距离变换生成权重图)。调整后mIoU提升至0.38,BEV mAP保持稳定。
经验总结:在联合训练中,建议每5个epoch保存一次checkpoint,并在验证集上同时计算mIoU和BEV mAP。如果两个指标同时提升,说明模型在良性收敛;如果一个指标提升而另一个下降,需要检查是否存在任务冲突。此外,建议使用TensorBoard或Weights & Biases记录每个类别的IoU,以便定位性能瓶颈类别。