作者:李志琦,南京大学博士生
TLDR: 别在nuScenes上做开环端到端自动驾驶刷点了。
前言
UniAD
[1]
获得CVPR Best Paper Award后毫无疑问给自动驾驶领域带来了又一个热点: 端到端自动驾驶。同时马老师也在极力的宣传自己的端到端FSD。不过本篇文章只把讨论限定在一个很小的学术方向,基于nuScenes的开环端到端自动驾驶,会给出一些细节的东西,不讨论其它假大空的东西。
因为不能闭环所以被迫选择了开环
以能否得到反馈为标准,端到端自动驾驶的学术研究主要分为两类,一类是在模拟器比如CARLA中进行,规划的下一步指令可以被真实的执行。第二类主要是在已经采集的现实数据上进行端到端研究,主要是模仿学习,参考UniAD。开环的缺点就是无法闭环(好像是废话),不能真正看到自己的预测指令执行后的效果。由于不能得到反馈,开环自动驾驶的测评极其受限制,现在文献中常用的两种指标分别是
•
L2 距离:通过计算预测轨迹和真实轨迹之间的L2距离来判断预测轨迹的质量
•
Collision Rate: 通过计算预测轨迹和其他物体发生碰撞的概率,来评价预测轨迹的安全性
事实上我们发现这两个指标完全不足以评判预测的轨迹的质量,一些技术看似提高了模型在这些指标上的表现,实则带来了其他没有被发现的问题,后续会介绍到。
nuScenes不是为planning设计的
关于开环端到端自动驾驶的测评问题最早在这篇文章
[2]
中提到。在这篇文章中他们仅使用Ego Status就能够获得和现有Sota相比较的结果。但是第一次文章放出来的时候他们的数据好像用错了
[3]
。同时他们错误的认为VAD也用了history trajectory, 但其实VAD
[4]
并没有使用历史轨迹。在AD-MLP中历史轨迹是一个默认使用的选项,当时本人理所应当的认为AD-MLP可能是受益于历史轨迹的使用,并没有特别在意这篇文章的结论。
表1: AD-MLP的实验结果
不过后来实验受挫之后,心态发生了:”从相信端到端到怀疑端到端“的转变后,开始觉得AD-MLP的结论应该是对的。通过可视化很多nuScenes的整体场景,会发现相当比例的场景都是直行,而且速度变化不大,交互很少,如图1所示。考虑到我们对于AD-MLP使用历史轨迹的顾虑,我们复现了一版仅使用当前速度,加速度,转向角和转向指令的MLP网络。如图2所示,为了区分,将我们复现的这个网络记为Ego-MLP。Ego-MLP不使用任何传感器感知信息,监督loss仅为一个L2 Loss。同时我们还有一个更基础的驾驶策略Go Stright: 保持当前速度继续前进。
图1: nuScenes的场景相对简单,直行占比过大
图2:复现的AD-MLP,去掉历史轨迹输入,记为Ego-MLP
表2 实验结果由我们使用统一的Eval代码和策略获得,与之前文献中会有不一样的地方. ID-1,3,4为我们根据开源代码简单修改复现的结果, UniAD和VAD使用BEVFormer生成BEV特征,BEVFormer默认在BEV初始阶段引入can_bus (可以理解为ego status)信息
如表2所示,我们会有如下发现
•
简单的直行策略(ID-7)在2s内的指标都挺高的。
•
Ego-MLP 不使用感知也能取得和现有sota差不多的结果。
第二条其实还可以换个角度这样理解,现有方法比如VAD, UniAD只有在Planner上引入Ego Status才能取得和Ego-MLP相似的效果。所以自然而然有了下面的问题:
Ego Status 引入会降低对感知的依赖
为了探究Perception 和Ego Status的效果,我们向这两个输入分别加扰动。如表3所示,在Planner中已经使用了Ego Status的情况下,就算把所有相机输入全部去掉,感知模块全部崩溃(结果变成0),模型的planning效果依然会在一个非常好的水平。我们相信这并不是一个正常的现象。与之对比的是模型会过渡依赖Ego Status的信息,假如我们改变输入模型的速度,会发现模型预测的轨迹基本会按照我们输入的假的速度去走,哪怕输入图像中事实上隐式地包含了ego的真实速度。如果输入速度全部设置成0的话,模型预测的轨迹基本处于原地不动的状态。
表3
结合上面我们所讨论的仅使用Ego-Status的MLP网络就能获得sota效果,说明对于nuScenes来说,Ego Status就是预测轨迹的一条shortcut, 当模型引入Ego status的时候,自然会降低对于感知信息的利用。这样的表现很难让人相信端到端模型在复杂场景下的表现。
设计一个高效的Baseline 来验证Ego Status的效果
首先,我们实在负担不起在VAD或者UniAD上来做验证实验,举例来说UniAD的第二阶段训练在我们的8*V100上就需要10天。同时,ST-P3
[5]
,一个经常被拿来比较的方法使用了部分不正确的训练和测试数据,产生的结果数值上是不准确的。
因此我们认为我们需要设计一个相对简洁高效的baseline方法能够快速验证我们的想法,并且能够跟现有方法进行有效对比。不同于UniAD的模块化设计,我们使用了一个非常非常简单的设计,如下图所示,我们提出的baseline网络直接使用生成的BEV特征与一个Ego query发生交互,然后通过MLP预测最终的轨迹。与UniAD等方法不同,我们的baseline方法不使用其他任何中间监督,包括但不限于Depth, Detection, Map, Motion 等。最终模型仅使用一个L2 loss来进行轨迹的监督。Ego Status可以在BEV阶段或者最终的MLP阶段选择性加入。我们的模型训练12ep需要大概6个小时。
最终的结果如下表,在BEV和Planner中都使用Ego staus时,我们的方法(ID-12)和VAD-Base(ID-6)基本一致,这能说明我们的方法简单却有效吗?显然不能,这也正是Ego status主导planning性能所带来的影响,使用Ego status后,根本无需复杂设计就能取得和现有sota差不多的结果。在Ego status占据主导地位后,不同方法之间的差异根本体现不出来。事实上我们已经看到了类似的论文把使用ego status所带来的性能提升包装进自己方法里,用来展现自己方法的有效性。这是极其误导人的行为。
看似我们的方法在使用Ego Status时取得了不错的结果,但是从下图中可以看到,在Planner中使用Ego status的方法(Baseline++)似乎只用3k个iter就能收敛了,这显然是模型学到了Ego status到planning的short cut而非从视觉信息中获得有效线索。可视化BEV特征也发现,模型几乎没有从视觉分支中学习到什么有意义的表征。
我们暂时先不讨论为什么我们的方法在不使用ego status的情况下(ID-10)效果也不错的这个现象。
不用Ego Status不就完事了?
既然引入Ego Status会主导planning的学习,假如我们不想让这样的现象发生,那我们不用Ego Status不就完事了吗?第一时间这么想肯定没问题,但是
真的没有使用Ego Status吗?
为什么会有这个问题呢?因为我们发现很多方法会无意识的引入Ego Status。例如,BEVFormer默认使用了can_bus信息,这里面包含了跟自车速度,加速度,转向角相关的信息。这个东西对BEVFormer做感知其实是没啥用的,但是VAD和UniAD拿过来直接做planning话,can_bus就会发挥作用了。类似的Ego信息在感知方法中也经常被使用用来做时序对齐之类的事情。我们重新训练了去掉了can_bus的UniAD 和VAD模型,会发现明显的性能下降。考虑到ego status信息在最新的BEV方法中都被广泛使用,去掉这些信息的使用或者保证不同方法之间的公平比较都是非常困难的事情。一点点Ego status的泄漏都会对最终的planning性能产生巨大的影响。
BEVFormer默认使用的can_bus_info包含ego status
去掉Ego Stutus仍存在的问题
讨论到现在,可能只是简单的认为责任全在ego status,很可惜并不是这样。当我们观察上面的表4,会看到我们的方法Baseline(ID-10)在不使用任何ego status的信息的情况下,可以取得和UniAD(ID-2), VAD(ID-5)这些在BEV上用了ego status的,使用了额外感知,预测任务的模型差不多的效果。 我们再回顾一下我们的Baseline (ID-4)的设置,输入图像256x704, 仅使用GT轨迹,不使用其他中间标注,仅使用L2 loss训练12ep。 为什么这样一个朴素到极致的方法会取得这样的效果?在这里我只给出我的一个猜想,不一定正确。 既然我们能够用ego status几个数值就拟合nuScenes大多数简单场景,说明学习nuScenes 大多数简单场景的planning本身就不是一件具有挑战性的事情,学习这些简单场景下的planning根本就不需要perception map等信息。其他方法使用了更多其他模块,带来更复杂的多任务学习,事实上反而影响了planning 本身的学习,我们也做了一个简单的实验来验证我们的猜想。
表5
如上表所示,Baseline 是原来的(ID-10)的结果,我们在Baseline上添加了一个MapFormer,具体实现做法和UniAD/VAD差不多,这个Baseline+Map模型的初始化是经过Map预训练的。我们可以看到Baseline+Map的结果远远逊色于Baseline。 原因是啥呢?为了消除Map预训练的影响,我们也使用Map预训练的权重作为(ID-10)这个setting的初始化得到了Baseline(init*)这个结果,通过对比Baseline不同初始化,我们可以发现,预训练的Map权重不会导致性能下降,反而会提升性能。问题只会出现在引入Map任务本身了。
我们对比了Baseline和Baseline+Map 在直行命令下的 L2 指标:L2-ST 和左右转指令下的L2指标: L2-LR。 同样还有在直行命令下的碰撞率指标Collision-ST, 在转弯场景下的碰撞率指标Collision-LR。 我们会发现在转弯场景下引入Map只是轻微增加L2距离,并且能够大幅度降低转弯场景下的碰撞率。与之对应的是直行场景下的L2和Collision被double了。考虑到转弯场景通常是更复杂,更需要操作的,而直行场景相对简单,我们猜测是因为引入Map 带来多任务学习的干扰反而影响了这些简单场景的学习。在nuScenes验证集上,直行命令占比87%,因此主导可最终的平均指标。我们可以看到Map引入在转弯场景下实际是没什么负面效果的,但是被平均之后Map的积极效果根本彰显不出来。
表6
表7
如果我们的猜想成立,这说明nuScenes做planning不单单是一个ego status的问题,而是本身全方面的不靠谱。
开环Planning指标
碰撞率指标的多个问题
我们暂时先不讨论L2 distance的问题, 因为好像更多的文章倾向于认可collision rate这个指标。实际上这个指标非常不靠谱,原因有:
•
计算碰撞的时候,其他车的未来轨迹都是回放,没有任何reaction,单从这一点上讲,这个指标就很不靠谱。
•
实际实现的问题,由于预测的轨迹只是一堆xy坐标,没有考虑ego 的yaw angle在未来的变化,计算碰撞的时候也是假设ego car的yaw angle永远保持不变,会造成很多错误的碰撞计算。我们这次也是通过轨迹估算yaw, 统一解决了这个问题。
不考虑yaw angle变化的灰色小汽车会造成很多错误的碰撞计算