Chenfan Blog

Do cool things that matter.

0%

Tesla AI Day 2021 回顾

终于要开始往博客里面写点跟我现在去的新行业相关的东西了。

回顾一下今年特斯拉的 AI day。

Source

直播的原始视频发在了 YouTube 上,这里

发现 B 站刚好有人把完整的 3 小时都搬过来了,就拿过来贴在这里:

顺便 YouTube 评论区置顶的这条贴了视频的几个关键时间点目录:

Join us to build the future of AI → https://www.tesla.com/ai
0:00 - Pre-event
46:54 - AI Day Begins
48:44 - Tesla Vision
1:13:12 - Planning and Control
1:24:35 - Manual Labeling
1:28:11 - Auto Labeling
1:35:15 - Simulation
1:42:10 - Hardware Integration
1:45:40 - Dojo
2:05:14 - Tesla Bot
2:12:59 - Q&A

Let’s go

正片差不多 38 分钟左右开始,一开始上来就放了一段自动驾驶片段。应该是辆 Model 3 或者 Y,可以在中间的中控上看到实时的环境识别和规划路径的可视化效果。左边红色的线是道路边缘,白色和橙色的应该是识别出来的车道线,绿色的是规划出来的目标路径。不得不说视频里面的效果还是很流畅的,中间也经过了一些复杂的交汇车和等待行人的十字路口等等场景。

46 分钟马斯克上来招了一波人 …

Vision @ 48:44

之前演示的视频就是目前特斯拉在车上采用的纯视觉方案,8 个摄像头通过神经网络处理后构建出一个 3 维的向量空间,然后所有的识别和规划都在这个空间中完成。

他们用了 ResNet 作为 Backbone,输入是摄像头采集过来的 1280 * 960 的 12 位原始图像。这里用的直接是摄像头的 RAW 数据,可以减少一些视觉处理算法的预处理等等,理论上能最大限度地保留信息?1280 * 960 这个尺寸不知道是不是他们摄像头的原始尺寸,感觉分辨率偏低,不过输入尺寸太大了确实也影响推理性能。

接下来过一个 BiFPN 去对 Backbone 中的多层数据做一个特征融合。融合后的特征最后再被拿过来做具体的识别和分类。视频里有一页给了 cls 和 reg 的输出尺寸分别是 640 * 480 * 1 和 640 * 480 * 4,猜测 1 大概是描述某个像素点是不是有物体,如果有物体的话输出的 4 则是物体的分类属性。

HydraNets

这里有个重要的点是前面到 BiFPN 为止的数据和特征都是被接下来不同的分类任务共享的,后面接上不同的检测头就可以从原始的图片数据里面分别检测出物体(可以是车、人、其他障碍物等等)、车道线、红绿灯等等。每个检测头都是独立的,比如这里给出的细节是 lane 只用了个简单的全连接,其他的目标识别则是用了更复杂一些的网络。这种 one model + multi task heads 的方式:

  1. 所有任务共享完整的同一组视觉 feature,实际 inference 的时候就很高效了;
  2. 后面用不同的检测头再去做具体类别对象的识别,可以针对每一个不同的对象独立做检测头的 fine tune;
  3. 训练做 fine tune 的时候也可以从下面 cache 住的 feature 开始。

后面出结果的时候也是一帧图片进去,跑完整个网络直接就能同时出来所有不同类型对象的检测结果。


单摄像头拍到的视频帧会少了个很重要的深度信息,因此每个摄像头得到的结果是没办法简单地直接放在一起用的,且单独一个摄像头检测出来的结果也很容易会产生偏差,也会有一个对象可能同时出现在多个摄像头的画面里面的情况。所以接下来是一个叫 occupancy tracker 的部分,需要把所有摄像头识别出来的车道线、物体等等根据它们的空间关系融合到一起去(就是前面视频里面提到的 3 维向量空间)。

“It’s very easily said much more difficult to actually achieve.” Emm … 这句话好像在哪里听过的样子,不过确实这个想想就很麻烦。

模型先放到后面说,首先第一个技术点是不同车上摄像头的位置会有偏差,每个摄像头拍到的画面也都会有一定的畸变,每个画面到最后提取完 feature 再去做调整就不太好操作了,效果可能也不好。所以他们直接采用的是前融合的方式,在摄像头的 raw 数据后面加了一个 Rectify 层,在获取到图片数据的时候就用上相机的标定数据等等信息,对图像做去畸变矫正以及变换到一个标准的 virtual common camera 的视角上去。

这样是不是不同车上的数据在最后训练和识别的时候都能够完全统一到一起去了?666

Multi-Camera Fusion

然后回到这个融合模型上,说实话细节部分我还没有完全理解(惭愧…),他们用了个 transformer 来做多目 image 到 BEV(Birds’s-Eye-View?) 空间的转换和 fusion。不同摄像头图片上提取到的 feature 通过 context summary 和 positional encoder 合到一个网络里面去,得到这个 transformer 里面的 Q。每一张图片和它们的 feature 分别变成了 K 和 V。

一开始我想了好久也没理解他这里说的 Query 和 Key/Value 是啥,后来一看这不就是 transformer 结构里面的 QKV 吗,希望应该不是我理解错了。

如果 do all the engineering correctly(听起来确实挺麻烦),Transformer 的最终结果就可以拿来做融合后的最后识别了。输出的 multi-camera features 的尺寸是 20 * 80 * 256。

后面的演示结果里面 Multi-Cam 前融合得到的车道线和物体检测结果都确实要比做后融合的效果要清晰和稳定的多。


下一步是对所有视频帧的数据进行时序融合,只有这样才能进一步确定下来每个检测对象的速度、方向、被遮挡等等的信息。

Feature Queue

每一帧的 feature(20 * 80 * 256 * 60)加上 IMU 中得到的车本身的姿态信息(1 * 1 * 4 * 60)再加上位置编码(1 * 1 * 40 * 60)下采样后得到的 video feature(20 * 80 * 300 * 12)会存放到一个 feature 队列中。Feature 队列中数据的出入队需要同时基于时间和距离信息决定,时间很好理解,太久之前的信息就没有用了。距离信息这里举了个例子是如果在一个路口之前提前看到了车道上对这个路口的车道标识,那后面在路口等待红绿灯时之前的车道标识信息也是可以用上的。

Video Process

在视频信息融合上他们尝试过 3D Conv、transformer、RNN 等等,最后选了个空间 LSTM。车在每一个时间点上的感知能力是有限的,如果把整个感知空间定义成一个很大的二维平面(W * H * C),其实每一次只需要更新车周围的平面位置的数据就好了,车周围平面的 feature 尺寸是 20 * 80 * 256,用 IMU 参数修正之后对应到大二维平面上,每个点都是一个 RNN(???)。(RNN 的详细细节也没完全看懂,后面再细看…)


回顾一下整个网络的结构(假设是所有都放在一个 batch 里面的实现,大胆推测一下每个部分的输入输出):

  1. 8 个 12bit 摄像头原始输入(尺寸应该是 [8, 1280, 960, ?] 不知道是多少 channel)
  2. [8, 1280, 960, ?] -> camera 矫正(大胆猜测尺寸没变,还是 [8, 1280, 960, ?])
  3. RegNet 各个部分输出 [8, 160, 120, 64],[8, 80, 60, 128],[8, 40, 30, 256],[8, 20, 15, 512]
  4. RegNet 输出接 BiFPN,尺寸信息 ppt 里没看到
  5. 图像转 BEV 视角以及 transformer 多摄融合,这里出来之后我理解应该就没有摄像头的数量信息了,输出尺寸直接是 [20, 80, 256],代表的是鸟瞰图里面车周围 20 * 80 单位上的信息
  6. [20, 80, 256] -> 接下来用时间信息和距离信息保持 feature 队列,一次出 60 个单位(帧?)的数据用来作为视频模块的输入,尺寸是 [20, 80, 256, 60]
  7. feature [20, 80, 256, 60] + IMU [1, 1, 4, 60] + position [1, 1, 40, 60] -> 视频队列 [20, 80, 300, 60] -> 下采样 [20, 80, 300, 12]
  8. [20, 80, 300, 12] -> RNN 输出 [20, 80, 300]
  9. 最后接各种检测头到不同的分类任务上

Planning and Control @ 1:13:12

规控这部分咖喱味口音略重,有点不太容易听清楚。

规划上主要的矛盾点在于:

  1. 决策空间是非凸的,适合用离散搜索,连续函数优化(常规的梯度下降等迭代数值求解法等)容易陷到局部最优解里面去
  2. 决策空间又是非常高维的,离散搜索在计算上不好实现(复杂度可能是高维指数级的,计算量爆炸),只能用优化方法做

那折中可行的方案就是把这两种结合起来。首先用粗粒度的搜索从整个决策空间中搜出最优解所在的一个小范围空间(Convex Corridor),然后在这个局部空间里面用优化方法求最优解。

Vector Space -> Coarse Search -> Convex Corridor -> Continuous Optimization -> Smooth Trajectory

这里举了个例子,导航给的路径是过了这个路口之后在下个路口左转:

Turn Left

方案一:过路口后减速,提早左转,可能会需要插到别的车队中去,too uncomfortable(需要过路口后迅速刹车,break pretty harshly)
方案二:过路口后加速冲过去,在左侧的车之前左转,这样会有充足的距离和时间,但是也有错过左转窗口的风险

对这两种方案之间做搜索优化后就可以找到一条特别平顺的路径来完成这个左变道的动作。目前他们的算法可以提前规划 10 秒的决策,实际执行的效果基本上也是非常贴合规划路径的。

下一个例子用来说明的是规划算法除了自身规划以外,还需要给环境中的其他对象的行为也做一个预测。窄道交汇车:

Plan for others

发现前方车辆时,预测出对方车辆的行进路线有大概率会卡死整条道,因此在这里的规划上选择我方向右侧避让(这里是右侧刚好有空间,有点好奇如果没有避让空间会怎么样)。等到后面发现对向车辆停住时,修正对对方的预测,此时中间的路可以通行,因此看到视频里面我方停顿了一下之后马上流畅地继续开过去了。

这个例子感觉做的非常漂亮,已经很像人类老司机会做的判断了。

下面这个才终于是前面提到的粗粒度搜索 + 细粒度优化的例子。视频里面首先搜出一个灰色的凸空间作为接下来路径优化的硬约束,之后再在这个小空间里面去做连续平滑路径的规划。

再往下是搜索算法的选择,给的是一个停车场泊车的例子,蓝框是目前的位置,绿框是最终目标要停到的位置:

Search

启发式搜索(A*)是比较常规的选择,首先对比了两种 A* 的方案:

  1. 基于目标欧式距离的 A*:搜到目标路径一共需要 398320 次,搜索过程中非常容易陷到局部出不来,这种搜索效率基本上不太可用;
  2. 在欧式距离基础上再加上导航信息的 A*:相当于用地图的导航路径做了很大程度的搜索剪枝,效率提高了很多,只需要 22224 次就能够搜到结果了,但是还是不够高效,而且从搜索过程看就会发现其实浪费了很多时间在处理路中间出现的障碍物(行人、桩桶等等)上

他们发现 Heuristic 信息在搜索过程中非常重要,需要一种比导航路径更加有效的全局信息来指导搜索过程,于是他们想到了神经网络。

NN Heuristic

如果把整个规划抽象成全局信息、决策、更新全局信息后再继续决策的过程,本质上就跟 alpha go 要解的是一样的问题了,因此也可以用类似的成熟方案去实现,直接上 NN + 蒙特卡洛搜索。(666666…)其他比如人工干预信息、距离、时间以及某些决策是否会让乘客舒服之类的都可以作为额外的 cost function 加到蒙卡树里面去。

甚至都还没把地图信息加上,就只需要 288 次搜索就能够找到非常好的结果了。(换句话说如果再在这个基础上加上高精地图是不是就更有效了?)

最终的系统架构如下:

Plan & Control Arch

本身感知模块产出的环境信息(基于摄像头得到的鸟瞰图)以及识别出的特定目标就是给规控做路径规划和决策的,现在就是相当于在下面多加了一个 NN Planner 部分,输入是感知 NN 里面某个中间层的 feature 用作 MCTS 的全局信息。


To be continued…