4、数据增强策略:BEV空间下的数据增强、时序增强、对抗样本生成

数据增强这事,在2D感知里大家玩得都很溜了。但到了BEV空间,情况就完全不一样了。我刚开始做BEV项目时,直接把2D的随机裁剪、颜色抖动搬过来用,结果模型在验证集上直接崩了。为什么?因为BEV空间有它自己的几何约束和物理意义。

说白了,BEV下的数据增强,核心就一句话:不能破坏空间一致性。你想想看,BEV特征是从多视角图像投影到鸟瞰平面的,每个像素都对应着真实世界的物理位置。你要是像2D那样随便裁一刀,空间关系就全乱了。

4.1 BEV空间下的几何增强

我个人习惯把BEV增强分成两类:全局变换局部扰动

全局变换包括旋转、缩放、平移。这些操作在BEV空间里是保形的,不会破坏物体间的相对位置关系。但要注意,旋转角度不能太大。我试过±30°的随机旋转,结果模型把路边的树认成了行人——因为旋转后树冠的形状和行人太像了。嗯,这里要注意,建议旋转范围控制在±15°以内

经验值参考:

增强类型推荐范围注意事项
旋转±15°超过20°会导致语义混淆
缩放0.8~1.2配合相机内参同步调整
平移±2米避免物体移出感知范围

局部扰动就更有意思了。比如对某个目标单独做微小的位置抖动,或者对路面区域做局部扭曲。我在项目中遇到过一个问题:模型对静止车辆检测很好,但对正在变道的车辆经常漏检。后来加了局部位置扰动,让车辆在BEV空间里模拟变道轨迹,效果立竿见影。

一个小技巧:局部扰动要和时序增强配合使用。先做位置扰动,再在时序上做平滑,这样模型学到的就是真实的运动模式,而不是噪声。

4.2 时序增强:让模型学会看“动”的东西

单帧BEV感知有个天然缺陷:它不知道物体是静止的还是运动的。你想想看,一个停在路边的车和一个正在等红灯的车,在单帧里看起来一模一样。但时序信息能告诉你答案。

时序增强,说白了就是让模型学会利用历史帧的信息。我常用的方法有三种:

  1. 帧率随机采样:训练时随机跳过一些帧,模拟不同车速下的观测密度。比如原本10Hz的数据,我随机降到5Hz或8Hz。这样模型就不会过度依赖固定的时间间隔。
  2. 时序遮罩:随机遮掉某几帧的某个区域,强迫模型从前后帧推断被遮掉的内容。这招对遮挡场景特别有效。
  3. 运动轨迹插值:对连续帧中的同一目标,在BEV空间里做线性或样条插值,生成更密集的轨迹点。我试过用三次样条插值,模型对急刹车和急转弯的检测召回率提升了8%。

我曾经踩过一个坑:时序增强时,如果历史帧和当前帧的视角变化太大(比如车辆转弯),直接做特征对齐会导致严重的伪影。后来我加了一个“视角一致性检查”,只有前后帧的重叠区域超过70%才做时序增强。这个阈值是我调了三天试出来的。

4.3 对抗样本生成:给模型打“预防针”

对抗样本在BEV感知里是个大问题。2D的对抗攻击只需要改几个像素,BEV的对抗攻击可以伪装成真实世界的物理变化。比如在路面上贴几块黑色胶带,就能让模型把车道线识别成障碍物。

我常用的对抗样本生成方法:

  • FGSM(快速梯度符号法):在BEV特征空间里加一个小的扰动,方向是损失函数梯度的反方向。简单粗暴,但效果不错。
  • PGD(投影梯度下降):FGSM的迭代版本。我一般迭代5~10步,步长0.01。再多就容易过拟合到对抗样本上,反而降低了正常场景的精度。
  • 物理可实现的对抗补丁:这个最实用。在BEV空间里生成一个补丁,然后投影回多视角图像,检查它是否能在真实物理世界中实现(比如颜色是否可打印、形状是否合理)。
# 一个简单的BEV对抗样本生成示例(伪代码)
def generate_bev_adversarial(bev_feature, gt_labels, model, epsilon=0.1):
    # 前向传播
    pred = model(bev_feature)
    loss = compute_loss(pred, gt_labels)
    
    # 计算梯度
    grad = autograd.grad(loss, bev_feature)[0]
    
    # 生成对抗扰动
    perturbation = epsilon * sign(grad)
    
    # 约束扰动在物理可实现范围内
    perturbation = clip_to_physical_range(perturbation)
    
    # 生成对抗样本
    adv_bev = bev_feature + perturbation
    
    return adv_bev

我的个人习惯:对抗样本的强度不要一开始就拉满。我通常从epsilon=0.01开始,每训练一个epoch增加0.01,到0.1为止。这样模型有个适应过程,不会一下子被“打懵”。

4.4 增强策略的组合与调度

数据增强不是越多越好。我见过有人把旋转、缩放、时序遮罩、对抗样本全堆在一起,结果模型训练了三天都不收敛。为什么?因为增强之间的冲突太大了。

我建议的策略:

  • 训练初期(前20%的epoch):只用几何增强,让模型先学会基本的空间结构。
  • 训练中期(20%~70%):加入时序增强,让模型理解运动模式。
  • 训练后期(70%~100%):加入对抗样本,提升鲁棒性。

另外,增强的强度也要动态调整。比如对抗样本的epsilon,我习惯在验证集上跑一个“鲁棒性指标”——如果模型在对抗样本上的精度下降超过10%,就降低epsilon;如果下降不到5%,就增加epsilon。说白了,就是让模型始终处于“舒适区边缘”。

最后说一句:数据增强不是万能药。如果你的BEV模型在基础场景上精度都不够,先别急着加增强。先把baseline跑好,再考虑这些花活。我见过太多人一上来就堆增强,结果连最简单的直道都检测不准。

嗯,这一章就到这里。下一章我们会聊BEV感知的模型轻量化,那才是真正考验工程能力的地方。