二. BEV感知算法基础模块讲解

目录

    • 前言
    • 0. 简述
    • 1. 基础模块补充讲解
      • 1.1 2D图像处理
      • 1.2 3D特征之点处理方案
      • 1.3 3D特征之体素处理方案
    • 2. 从2D到3D转换模块
      • 2.1 LSS(Lift,Splat and Shoot)
      • 2.2 Pseudo LiDAR
    • 3. 从3D到2D转换模块
      • 3.1 Explicit Mapping
      • 3.2 Implicit Mapping
    • 4. BEV感知中的Transformer
      • 4.1 空间注意力之STN
      • 4.2 通道注意力之SENet
      • 4.3 混合注意力之CBAM
      • 4.4 Self-Attention
      • 4.5 ViT
      • 4.6 Swin Transformer
      • 4.7 DETR
      • 4.8 DETR3D
    • 总结
    • 下载链接
    • 参考

前言

自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》,链接。记录下个人学习笔记,仅供自己参考

本次课程我们来学习下课程第二章——BEV感知算法基础模块讲解,一起去了解下 BEV 感知算法中的一些基础模块

课程大纲可以看下面的思维导图

0. 简述

接下来进入我们第二章内容的一个讲解,BEV 感知算法基础模块

首先,我们在第一章中主要给大家介绍了 BEV 感知算法中的一些常见的概念,BEV 空间所具有的独特的优势以及我们常见的 BEV 感知算法的一个分类,我们提到 BEV 感知算法可以分为 BEV LiDAR 也就是点云类,还有 BEV Camera 图像类,还有 BEV Fusion 融合类。我们也讲过,无论哪种方法做 BEV 感知算法,设计的核心都是围绕转换模块进行的,那也就是说如何把不同输入的数据统一的映射到 BEV 空间当中,无论是检测任务,分割任务还是轨迹预测任务均是基于已建立的这个 BEV 空间去进行的,所以转换模块是尤其重要的。

出于这个考虑,第二章中我们还是围绕转换模块展开,最后考虑到 Transformer 也是 BEV 感知算法中的一个非常重要的组成部分,我们也会额外给大家补充一下 Transformer 的相关内容。

1. 基础模块补充讲解

正式开始我们第二章内容之前,我们先对 BEV 感知算法涉及到的一些比较基础的模块,尤其是我们在第一章 BEV 感知算法介绍中所涉及到的特征提取模块去进行一个补充讲解

OK,我们正式开始一个补充讲解的过程

1.1 2D图像处理

我们在第一章中讲过 BEV 感知算法是涉及两种模态特征的处理的,一种模态是图像特征,那通常是基础图像处理网络比如说 ResNet,另一种是 3D 点云特征,通常使用点处理方案或者体素处理方案,那我们先做一个基础的图像处理模块的讲解

图像在计算机中是按照顺序排列的一个数字,数值在 0-255 之间,0 表示最暗,255 表示最亮,那么在图像特征提取中输入就是原始图像,我们在第一章中也提到过,输入图像的尺寸是 H × W × 3 H\times W \times 3 H×W×3 分别代表的是图像的高度、宽度和 RGB 彩色图像通道数,那最基础的图像处理网络是以卷积层和池化层组成的,比如下图中的 VGG 网络

二. BEV感知算法基础模块讲解_第1张图片

从图中我们能看到 VGG 网络不断地叠加卷积池化,通过这样不断组合的方式它搭建起了一个很基本的图像处理网络,另外我们也可以看到不同的网络它包含的卷积层数目是有明显区别的,比如 VGGs-16 和 VGG-19,它们最明显的区别就是在卷积层的数量上,一个是 16 层卷积,一个是 19 层卷积。那因此我们可以来思考一个问题,是不是卷积层越多,池化层越多,网络学习得会越好呢?网络是不是对图像的表达能力也就越强呢?

实际的实验中我们发现卷积层和池化层的叠加不但没有出现学习效果越来越好的情况,反而性能是趋近饱和甚至下降的,很多专业的表述中它归结的原因是梯度消失,那为什么会有梯度消失这个现象呢?那我们还是以 VGG 这个网络来举例,比如网络第一层有个梯度 α 1 \alpha_1 α1,第二层也有个梯度 α 2 \alpha_2 α2,那依此类推,第 n n n 层有个梯度 α n \alpha_n αn,那梯度其实是一个累乘的过程,乘下来之后呢,这个梯度会越来越小,网络层数越深梯度越小,最后就消失了

我们把这个过程再细化一下,比如说现在有一个函数 f ( g ( x ) ) f(g(x)) f(g(x)),那这个函数我们对 x x x 去求导的话,根据链式法则我们有:
∂ f ∂ x = ∂ f ∂ g ∂ g ∂ x \frac{\partial f}{\partial x} = \frac{\partial f}{\partial g}\frac{\partial g}{\partial x} xf=gfxg
我们首先是先对 g ( x ) g(x) g(x) 求偏导,然后再乘以 g ( x ) g(x) g(x) x x x 的偏导,那我们发现按照这样的累乘过程去计算之后呢,随着网络层数的加深,后面的偏导数量越多,梯度就越乘越小,换一句比较通俗的解释其实是什么呢,是学着学着我们把最开始的忘了,我们乘到后面,越乘越小,那开始是什么呢,网络已经忘掉了

所以由于这种考虑,我们现在比较常用的是 ResNet 网络提出了一种残差结构,如下图所示:

二. BEV感知算法基础模块讲解_第2张图片

深层特征如果不记得浅层特征怎么办,我们把浅层的特征重新再加上去,通过上图中的一个残差结构,跳接的一个结构,这个时候我们再求偏导会发现除了原本的梯度之外还有额外的梯度保留,所以从一定程度上就避免了梯度消失的问题,那我们为什么要提 ResNet 网络呢,它其实是一个非常重要的网络,是现在很多 BEV 算法图像处理模块的核心,所以这里我们单独给大家引入一下这样的网络一个主要处理方法,其实就是一个残差结构,有选择性的把原本的特征保留住

那对于图像处理网络这块很通俗的讲输入图像通过这个 Backbone 网络,那这个 Backbone 可以是 VGG 也可以是 ResNet,我们比较推荐 ResNet,那大家比较通用的也是 ResNet,可以得到这个图像特征,无论是 ResNet 也好,还是 VGG 也好,它其实实现的全部都是图像数据的一个处理功能,那在 BEV 算法中存在环视图像,环视图像也是一样,那无非就是环视的输入可能存在一个多视角的图像,把这个多视角图像送入 Backbone 网络我们就可以得到环视的图像特征,那这里其实是一个比较简单的图像处理流程

1.2 3D特征之点处理方案

下面我们再来简单看一下 3D 特征是怎么处理的

现阶段的 3D 特征提取我们也讲过可以分为两大类,一类是采用 PointNet 及其变种,比如 PointNet++ 直接对点云进行处理的,也就是我们说的 Point-based,一个基于点的处理方案。另外一种是将点云数据转换成比较规则的体素,通过三维卷积去做特征处理的,我们叫 Voxel-based,一个基于体素或者说网格的处理方案。那两种方案其实没有绝对意义上的这种孰优孰劣,它们各有各不同的特点,我们简单介绍一下利用点的方法是怎么做的,那我们这里给出一种很经典的算法叫做 PointNet++,其框架如下图所示:

二. BEV感知算法基础模块讲解_第3张图片

PointNet++ 的核心动机和主体结构简单总结如下:

  • 核心动机:如何在 3D 特征构造时,感知点的信息?
  • 主体结构:围绕如何提取利用点展开
    • 核心:用两个 set abstraction 组成特征网络,包括 sampling、grouping 和 PointNet

PointNet++ 中作者是利用所在空间的一个距离度量去把点集划分成有重叠的局部区域,那比如原始点集是图中的 P,它把 P 这个点集划分成了很多个局部区域,用虚线的圆圈表示,每个虚线的圆表示划分出来的一个局部区域,我们可以看到局部区域之间是有重叠部分的,划分好局部区域之后,从每个局部区域提取一个特征点,然后再扩大范围,再以提取到的特征点为中心又生成一个局部区域,那这个局部区域又可以得到一个局部特征点。那我们可以知道后面这个局部特征点相比于我们前面获得的局部特征点有什么优势呢,它感受野其实更大了

那我们可以发现后面的 PointNet++ 这个过程和 2D 图像处理网络的特征提取过程是非常类似的,首先提取一个很低级别的特征,它的感受野相对而言是比较小的,随着感受野的增大,后续的特征其实是一个高级别的特征,我们得到特征之后可以用来处理不同的任务,PointNet++ 这里处理了分割任务还有分类任务,比如处理分类任务的时候通过全连接层去进行置信度的一个预测,那我们可以得到一个分类得分

我们总结一下,通常所讲的基于点的 3D 特征构造是采样、聚合、特征提取,无非是这个过程重复了很多遍,后续也是采样也要聚合通过特征提取,后续我们就可以得到这个点云的特征,那至于这个特征用来处理什么任务那就是我们可以随机应变的一个事情啦

1.3 3D特征之体素处理方案

我们再来看看体素的方法是怎么做的呢,我们讲的体素的方法是将点云数据划分成比较规则的体素,然后再通过三维卷积去做特征提取,那我们这里给出一种很经典的算法叫做 VoxelNet,其框架如下图所示:

二. BEV感知算法基础模块讲解_第4张图片

VoxelNet 的核心动机和主体结构简单总结如下:

  • 核心动机:如何在 3D 特征构造时,感知点的信息?
  • 主体结构:围绕如何提取利用点展开
    • 核心:将点云先划分为体素,提取体素内特征,进一步的再提取体素的稀疏表示

那我们在理解这种方法之前,我们先理解体素 Voxel,那它是什么意思呢,体素它其实就是将三维世界按照一定空间大小划分成小格子,比如上图中我们假设粉色长方体是一定的空间范围,那其中被划分的每一个小长方体我们就称之为体素,也就是图中的四个小长方体,对每个小长方体内的数据做特征提取,并且用这个提取出来的特征来代表这个小长方体,放回到原本的 3D 空间当中,这就是一个体素化的过程

这么做有什么好处呢,我们在第一章讲到过,一般的点云其实是无序的,通过这样体素化的处理之后把原本无序的点云空间变成了有序排列的,按照一定规则,按照我们划分的区域去进行排列的,这样我们提取完特征之后我们就可以用这个三维卷积去抽取这些三维体素数据了,那我们大家再想一下,3D 体素和什么很类似呢,是不是和 2D 中的每一个 Pixel,每一个像素很类似,3D 体素特征它其实是当前 3D 空间里规律性表达,2D 像素特征同时也是 2D 图像的规律性表达

OK,那我们说完了这点,我们再思考一个问题,是不是所有体素都有特征,比如图中的 1、2、3、4 这四个体素每个都有特征呢,显然也不是,我们刚刚讲过,体素的特征来源是什么呢,是其内部所囊括的点,那内部如果没有点怎么办,那显然就是没有体素的,那显然也就不会包含体素特征了,所以说并不是所有体素均有特征表达的,体素它在形式上与 2D 像素很相似,但它不同点在于 2D 像素其实是一种密集型的表达,而体素是可能存在空值的,是一种稀疏性的表征

无论是基于点的特征提取方案也好,还是基于体素的特征提取方案也好,我们最起码需要知道的东西是什么呢,3D 特征提取输入的是 3D 点云,输出的是提取后的 3D 特征,2D 特征提取输入一般而言是环视图像,输出是提取后的环视图像特征

OK,第二章前言部分我们给大家针对比较基础的特征提取模块进行了一些补充说明,那接下来我们正式进入 2.1 小节的内容,从 2D 到 3D 的转换模块。

2. 从2D到3D转换模块

首先我们思考一个问题,在 BEV 感知算法的设计过程中什么叫转换,在自动驾驶应用中我们最常见的传感器之一是图像传感器,图像传感器往往采集的是环视数据,如下图所示:

二. BEV感知算法基础模块讲解_第5张图片

环视图像包括前视图,后视图,侧视图等等,那我们讲过 BEV 感知算法是基于哪个空间做检测的呢,是基于 BEV 空间做检测的,那输入有 BEV 空间吗,没有,所以说如何将采集到的环视图像数据转换到 BEV 空间,从 2D 到 BEV 是一个很关键的问题

我们之前也强调过无数次,BEV 感知算法的设计核心一定是围绕转换模块去进行的,那我们再想一想,我们怎么样能有效的做转换呢,从环视可以直接到 BEV 吗,环视直接到 BEV 的难点是我们很难界定不同视角下点和点之间的对应关系,那比如图像中的某一个像素点可以对应 BEV 空间的某点,但难点是可能计算机并不知道图像中的某个点位的特征对应的就是它在 BEV 空间中的某个点,所以说我们考虑要怎么将我们的输入端采集到的数据可以对应的转换到 BEV 空间

通常的做法是给这个转换过程去找一个媒介,那这个媒介就是 3D 场景,那我们知道从 3D 到 BEV 是一个相对而言比较容易的事情,3D 场景按照高度维度去进行一个压缩,我们讲拍扁也好,卷积或者用池化也好,对高度维度进行一个压缩我们就可以直接得到 BEV 空间的视图,所以问题只剩一个,我们怎么从 2D 到 3D,它是一个难点

所以这就引出了我们本章第一个正式的内容,从 2D 到 3D 的转换模块要怎么去设计

那为了说清楚 2D 到 3D 的转换过程,我们先从图像生成原理看起,相机是如何将 3D 场景拍摄成一张 2D 图像的呢,我们用下面这个简单的示意图来说明:

二. BEV感知算法基础模块讲解_第6张图片

图中 P ( X c , Y c , Z c ) P(X_c,Y_c,Z_c) P(Xc,Yc,Zc) 是世界坐标中的一个点, p ( x , y ) p(x,y) p(x,y) P P P 投影到图像平面的坐标, O c O_c Oc 是相机原点, O − p − P O-p-P OpP 是一条直线,那因为光是沿直线传播的嘛,从原点 O O O 到世界坐标点 P P P 连成的直线与图像平面所形成的焦点是在图像平面的投影点 p p p,那投影平面与什么有关呢,与相机焦距有关,通过数学表达,有了世界坐标,有了相机参数,我们就可以得到对应的投影出的图像坐标,具体计算公式如上图所示

那其中的相机内参矩阵一般而言是由相机硬件决定的,所以我们可以近似把它认为是常量,那也就是说已知世界坐标,已知相机的内参矩阵我们就可以得到对应的图像坐标,如果这句话表述再说得确定一点,从 3D 坐标投影到 2D 坐标是确定关系,那什么意思呢,也就是说我们这个 3D 点 P P P 投影到 2D 上时它只会投影到 p p p 这个点,而不会投影到其他点上去,那反之,我们再反过来看一下如果从 2D 图像坐标映射到 3D 世界坐标是否也是唯一的呢,通过 2D 图像坐标是否唯一确定了一个 3D 世界坐标呢,那其实这个问题就是一个不确定问题,我们用下面的图来说明:

二. BEV感知算法基础模块讲解_第7张图片

上图是一条射线,其中 o o o 是相机原点, p p p 是 2D 图像平面投影点, P 1 P_1 P1 P 2 P_2 P2 P 3 P_3 P3 是世界坐标点,我们可以发现 P 1 P_1 P1 P 2 P_2 P2 P 3 P_3 P3 投影在图像坐标均是投影到了 p p p 这个点,所以说 2D 图像上的一个像素点对应到 3D 空间是一条射线。我们已知 2D 图像坐标、相机内参矩阵,我们只能得到其在 3D 空间的投影射线,而并没有办法很好的确定映射的点,从 2D 映射到 3D 这个点它的一个具体位置

从公式角度来讲我们也能看出来,比如图像坐标是已知的,相机内参矩阵也是已知的,根据图像坐标和相机内参矩阵去求解世界坐标,世界坐标是包含三个量的,图像坐标其实只有两个量,已知两个量的一个方程组是没有办法求解三个量的,它存在一个无数解的问题,那从 2D 到 3D 的映射关系怎么样才能变成一种一一对应的关系呢

我们还是以上面的射线举例,那比如射线上的三个点 P 1 P_1 P1 P 2 P_2 P2 P 3 P_3 P3 投影到图像上都是 p p p,那如果说我们现在知道投影的点是离相机最远的那个点,那我们就唯一确定了 P 3 P_3 P3 这个点,如果说我们知道投影到 p p p 这个点是距离我们最近的那个点,那我们就知道是 P 1 P_1 P1 这个点投影成 p p p 的,所以说如果我们已知 p p p 是某个深度值 3D 对应的投影点,我们就能把这个关系去做成一个一一对应的关系,那从公式表达上,如果 Z c Z_c Zc 是已知的,那其实就变成了一个方程组的求解问题,而且这个解是唯一解

OK,我们总结一下,从 3D 到 2D 的投影其实是确定关系的投影,从 2D 到 3D 的投影一个像素点是对应一条射线的,如果我们想把这个射线 2D 到 3D 的这样一个投影映射关系做成一种一一对应的关系,我们就需要知道一个深度值,那只有深度已知我们才能知道它的一个具体的预测位置,所以说从 2D 到 3D 的转换模块那个最重要呢,深度坐标最重要,我们后续看到的很多算法中的 2D 到 3D 的转换过程其实都离不开深度估计这个问题的讨论的

2.1 LSS(Lift,Splat and Shoot)

我们这里看一个比较经典的从环视图像 2D 到 BEV 空间的一个转换算法,叫 LSS(Lift, Splat and Shoot),这篇工作是 NVIDIA 发表于 ECCV2020 一个很经典的模块,很多 BEV 感知算法比如像 CaDDN、BEVDet 都是基于 LSS 算法去做一些改进的,同时它也是 2D 到 3D 转换的一个很经典的算法,其框架如下图所示:

二. BEV感知算法基础模块讲解_第8张图片

LSS 的核心动机和主体结构简单总结如下:

  • 核心动机:如何构建 BEV 空间?
  • 主体结构:围绕深度分布展开
    • 核心:利用 Lift 模块做深度分布,利用 Splat 做特征映射,利用 Shoot 做结果预测

我们讲过很多次看一个框架从输入输出看起,输入是多视角图像,输出是 BEV 空间特征,所以核心过程就是它中间的这个网络,那其实就是一个 2D 到 BEV 空间的一个转换过程,我们前面也讲过这个转换过程是需要媒介的,媒介是什么呢,是 3D 空间,先将环视数据映射到 3D 空间,然后 3D 空间去投影到 BEV,我们也可以拍扁到 BEV 上,那所以这个算法其实是围绕这个过程展开的

首先第一步我们怎么把环视数据映射到 3D 场景中呢,映射过程中哪个方面最重要呢,深度估计最重要,所以第一个模块它的主要作用是做深度估计分布的,通过有效的深度估计可以将环视图像的点投影到 3D 空间当中,然后第二个模块,有了 3D 空间,把 3D 空间去做一个 Encoder,可以把它 Encoder 到 BEV 空间,那也就是后面做的第二个模块,有了 BEV 空间之后,我们就可以做后续的一系列子任务,比如像分割也好,检测也好,轨迹预测也好等等,后续可以做各种各样的预测任务

那这三个模块哪一个最关键呢,是从 2D 到 3D 的转换模块,图像上的每个像素点怎么映射到它对应的 3D 空间当中,那这个过程其实是最重要的,接下来我们就看一看它的 2D 到 3D 是怎么做的,如下图所示:

二. BEV感知算法基础模块讲解_第9张图片

我们之前一直在强调从 2D 到 3D 的转换过程中什么信息最重要呢,深度信息,有了深度信息之后 2D 和 3D 空间才能建立一种一一对应的关系,那所以在这个算法当中 Lift 作为一个 2D 到 3D 的转换器其实也离不开对深度信息的一个估计,我们在图像成像原理的章节中讲解过图像中的每一个像素与空间中的一条射线是对应的,那也就是说像素点对应一条射线,是点线的对应关系,如果我们知道了深度之后呢,就变成了点与点之间的对应关系,它这个算法也无外乎这个过程,那在上图中相机发出一条射线,世界范围内射线上的所有点投影到图像上全都是同一个像素点

所以 LSS 的做法是将这个射线离散化为 D D D 段,每一个段都对应一个概率分布,我们怎么理解这个东西呢,那我们知道像素点对应空间的一条射线,那也就是说像素点投影在 3D 空间中的对应点存在于这个射线上的任何位置,换而言之一个像素点它可能是同一条射线上任何一个点投影过来的,那具体是哪个点呢,这里建模的概率分布就是用于估计该像素点落在对应深度的一个概率,那我们举一个例子,如下图所示:

二. BEV感知算法基础模块讲解_第10张图片

我们以上图中的像素点 p p p 为例,那这个像素点来源于哪个深度点呢,它这里给了个概率分布,可能来源于 d 2 d_2 d2 点的概率是最大的假设是 0.5,那比如其他位置 d 3 d_3 d3 点可能只有 0.01, d 1 d_1 d1 稍微高一点有 0.2,这条射线其实是一个深度离散化的射线,它的深度值其实是一种离散处理的,这个意思就是说我们这条射线上可能的深度值只有我们预定义的 D D D 个,像素点也只能投影到这 D D D 个位置,那至于投影到哪个位置的可能性最高,这就是所说的概率分布起的作用

那除了这个概率分布以外,LSS 还为每个像素分配了长度为 C C C 的一个特征向量,其实就是 feature c \bold{c} c 像素特征,feature c \bold{c} c 乘以它对应的深度值的概率分布我们可以得到一个特征图,前面的 α \alpha α 是它的深度分布,那比如它落在某个点的概率只有 0.01,乘上特征之后这个值就会特别特别小,比如说它落在另外一个点的概率很高有 0.9,那乘上原始的 feature c \bold{c} c 之后它维持在原样的概率就很大了,那依次类推,我们刚讲过一条射线划分多少个深度值呢,划分为 D D D 个,所以特征图的纵轴是它像素的特征维度,横轴是深度离散值的个数,所以每个像素点它分布在 3D 空间当中最终的特征维度是 D × C D\times C D×C

但是这个特征图放在平面上可能不是特别好理解,那我们可以把这个视角转换一下,如下图所示:

二. BEV感知算法基础模块讲解_第11张图片

上图是一个投影射线, p p p 是图像中的一个像素点,映射到 3D 空间之后就变成了一条投影射线,这个图是怎么对应到深度图的呢,它其实就是把这条射线划分成 D D D 段,每个位置表示有一个深度概率分布值,那这个位置对应的特征是图像像素的原始特征,比如说 c \bold{c} c 乘上它的深度概率分布 α 1 \alpha_1 α1,后续的每个点都是,那它是这样的一个关系。按照它这个做法之后可以得到一系列的离散特征,我们把所有像素点都按照这样一个射线深度离散化的过程做完之后呢,可以得到 3D 空间的离散的特征表达,我们再直接拍扁,比如做个池化,做个卷积都可以,我们最后能得到最终的 BEV 特征,这个过程其实就是我们讲的 LSS 算法的核心过程

我们再来总结一下 LSS 是怎么做到环视到 BEV 空间的一个转换的呢,我们首先第一步先做离散的深度分布,将像素的特征按照概率分布可以映射到不同的深度值上,那这个其实是对 3D 空间特征利用图像特征去进行一个补全的一个过程,当补完之后我们再拍扁到 BEV 空间去做预测,那这就是一个完整的流程

我们一再强调 LSS 算法中这个深度分布是一个什么值呢,是一个离散值,它所以其实是把一个连续深度预测的一个任务变成一个分类任务,分多少类呢,分 D 类,虽然最后的深度位置会有一定的偏差,那它这样做的一个好处,它其实把这个问题简化了很多

2.2 Pseudo LiDAR

那我们再来看一下,LSS 是一个离散深度分布,那能不能做连续的深度预测呢,也是可以的,我们通常把这种做法叫做 Pseudo LiDAR 的方法,也就是一个伪点云

二. BEV感知算法基础模块讲解_第12张图片

Pseudo LiDAR 的核心动机和主体结构简单总结如下:

  • 核心动机:如何重建图像连续深度而非离散深度分布?
  • 主体结构:围绕连续深度预测展开
    • 核心:先预测深度图,再根据原始图像和深度图映射到 3D 点云空间

输入是原始图像以及图像对应的深度图,有了图像有了深度我们讲过什么,图像上的像素点有了深度值之后,它和 3D 空间的关系就是种一一对应的关系,每一个像素点都可以投影到 3D 空间当中,那因此我们就得到了右边这样一个伪点云,我们之所以称作为伪点云是因为我们所生成的点云数据并不是来源于真实的传感器采集的,而是从图像投影映射过来的,所以称为伪点云,它形式上和点云很类似,只不过采集的传感器并不是真正的激光雷达

那这种方法有什么好处呢,我们首先看这种方法其实是生成了一些点云的,我们也讲过这个点云数据和真实点云数据我们可以认为几乎是一样的,除了没有一些反射值之类的东西,那所有这个伪点云是可以直接用通用的 3D 框架去处理预测的,非常方便。那它有什么缺点呢,我们从来源看,伪点云是怎么来的呢,从深度值过来的,那也就是说如果深度预测得不准,那伪点云其实位置也都是错的,点云的位置都错了,最后的预测结果显然也都是不准,所以伪点云最大的一个问题是来源的这个深度估计的误差,深度估计存在误差,导致生成的伪点云存在误差,所以导致我们最后很难获得一个比较准确的预测结果

OK,我们这里总结一下,我们为什么要做 2D 到 3D 的一个转换呢,是因为我们利用图像去生成 BEV 的时候,我们需要先转换到 3D 空间,再从 3D 空间中去生成 BEV,那从 2D 到 3D 这个转换什么最重要呢,深度值最重要,有了深度值我们就可以做一一对应的关系。那深度怎么做呢,我们主要分为两种,一种是我们前面一直在讲的离散深度分布,那所谓离散就是说我们把一条射线划分为 D D D 个离散区域,我们这条射线上只存在这 D D D 个分布值。另一种是我们伪点云方法所用的连续深度分布,我们一般用的是一个深度的估计网络,会得到一个连续的深度预测。

那本节内容我们主要围绕从 2D 到 3D 的转换进行的,接下来下一节内容我们从另外一个视角看看能不能做 3D 到 2D 的转换生成呢

3. 从3D到2D转换模块

这节开始我们讲解 2.2 小节的内容,从 3D 到 2D 的转换模块, 我们再来看一下什么是从 2D 到 3D 的转换

二. BEV感知算法基础模块讲解_第13张图片

对于图像上的一个点,通过离散深度分布或者连续深度分布值,我们去找其对应在 3D 空间位置上的一个关系,从图像上看这其实是一个正向的过程,我们从 2D 到 3D,从 3D 到 BEV,那这个其实是一个正向的过程,那从 3D 到 2D 的映射是什么呢?它其实是一个正好相反的过程

比如 3D 空间有一个点,我们要去找其映射在 2D 平面上的位置,那也就是一个逆过程。我们上一节内容中讲的 LSS 算法是从 2D 到 BEV 空间的一个过程,2D 先转换到 3D,3D 再拍扁到 BEV,是 2D 到 BEV 的一个过程,那从 3D 到 2D 的做法呢,比如有一个空的 BEV Map 已经给你建立好了,我们怎么去填充这个 BEV Map 呢,我们当前已经建立好的这个 BEV 空间当中每一个点的特征应该是什么呢

那从 3D 到 2D 转换模块的思路,它其实就是在我们已有的 BEV 空间的基础上,我们怎么去找 BEV 空间上所对应的点在 2D 空间中的位置,那也就是说我们在 BEV 上有一个点,那这个 BEV 空间的点怎么对应到 2D 空间当中呢,对应的输入在哪里,那如果我们找到了这个输入,我们利用输入这个像素位置的特征填充到当前 BEV 当中是不是就建立了一个完整的 BEV Map,这个其实就是从 3D 到 2D 的基本思路。

OK,我们带着这个理解来看一下一些比较基础的网络是怎么做的

3.1 Explicit Mapping

这里给大家看一下 BEV 感知算法中非常经典的 DETR3D 网络,其结构如下图所示:

二. BEV感知算法基础模块讲解_第14张图片

DETR3D 的核心动机和主体结构简单总结如下:

  • 核心动机:从 3D 到 2D 构建 BEV 空间,是否需要完整构建 BEV 空间?
  • 主体结构:利用 3d object query 进行 2d image feature 查询
    • 核心:并没有完整地表示出整个 BEV 空间,而是一种稀疏表达,效率较高

按照我们的老套路,看一个网络首先从输入输出来看,输入是 2D 环视图像,输出是 3D 预测结果,从输入到输出是一个以 2D 为输入,以 3D 特征为输出的一个网络,那输出是什么呢,是预测结果,基于什么特征的预测呢,基于 3D 特征的一个预测,那从输入到输出是一个以 2D 为输入,以 3D 特征为输出的网络,那这个网络具体怎么做的呢,之后在相关的论文讲解部分我们会给大家详细介绍,这里我们主要关注里面的核心部分,如何得到 3D 特征,也就是说我们怎么样从 2D 到 3D,怎么样从 3D 到 2D,这个转换模块是怎么做的

我们首先明确图中提到的 Object Queries 是一个和 DETR 一样的随机生成的一堆初始化的框的序列,它类似于先生成一堆 2D 图像当中讲的 anchor box,那不过这里的 box 最后是会被一个 loss 梯度回传,是会重新更新的一堆 box。图中蓝色的线是我们的第一个步,通过一个子网络预测 query,对 query 预测一个三维空间的参考点,那这个参考点起什么作用呢,那比如在 BEV 空间中我们有一个参考点,我们利用相机参数,可以将这个 3D 的参考点先反投影回图像当中可以得到其在图像上所对应的位置,拿这个位置的特征,对原始的 3D 参考点的位置的特征,也就是我们所对应的 Object Queries 去做一个补充,利用图像上的特征对初始化的 Queries 做一个优化,其实是一个 refine 的过程,那这样的其实就是一个从 3D 到 2D 的映射过程

有了 3D 初始化的 Query,我们得到其对应的预测的 3D 参考点,这个所谓的参考点是会被反投影到 2D 图像上的。我们也讲过 3D 到 2D 的投影是一一对应的关系,投影到 2D 图像上之后把它对应在 2D 位置上的特征拿来补充进 3D reference point 当中,去对我们原始的 Query 做优化处理的过程。特征的来源方向是什么呢,是基于 3D 的位置用 2D 的信息做补充,用 2D 的特征去补全我们 3D 的点的特征,那这个其实就是一个很典型的从 3D 到 2D 的转换模块,先有 3D 初始点,然后去找对应的 2D 位置,3D 是第一步,2D 是第二步,那所以我们说它是一个从 3D 到 2D 的过程。

除了环视图像算法可以这么做以外,其实还有多模态的输入也是可以用这种转换网络去做的,也是基于这样 3D 到 2D 的一个转换模块去做的。我们再来看一个网络,那这个网络叫 FUTR3D 是清华大学提出的一种多模态融合的 BEV 方案,应该是第一个比较通用的可以使用不同传感器的端到端的 3D 目标检测的框架,其网络框架如下图所示:

二. BEV感知算法基础模块讲解_第15张图片

FUTR3D 的核心动机和主体结构简单总结如下:

  • 核心动机:从 3D 到 2D 构建 BEV 空间
  • 主体结构:围绕特征查询展开
    • 核心:利用不同的骨干网络提取多模态特征,再根据查询点聚合多模态特征

看这个框架还是老套路,从输入输出看起,我们讲它是一个多模态的 BEV 框架,输入显然是包含多传感器的输入,第一个是图像输入,第二个是点云输入,第三个是雷达输入,输出是什么呢,是我们需要的 3D 检测结果,图像通过图像特征提取框架得到图像特征,点云通过点云特征提取框架得到点云体素特征,雷达通过雷达的 Backbone 可以得到雷达的 point feature,每一个雷达点位置的特征,那这些特征要怎么融合到 3D 空间当中呢,这个其实就是我们这里讲的 3D 到 2D 转换模块起的作用

图中提了一个 3D reference point,我们称之为参考点,参考点的作用是什么呢,有了参考点我们就可以通过参考点投影到不同模态上,从不同模态的不同位置拿不同的特征,它是一个取特征,采样特征的一个过程,那对于图像部分有了 3D 点可以投影到图像上,和 DETR3D 一样投影到图像上拿图像特征;点云部分参考 reference point 在 3D 空间上的坐标投影到点云的 BEV 特征上,采集对应位置的特征;对于雷达,根据每一个投影后的 reference point 的位置选取离它最近的圆形区域内 10 个雷达点的特征然后聚合在一起作为这个 3D 参考点的特征

那这些采样好的特征通过级联的方式,在经过一个 MLP 网络投射到一个共同的特征空间当中,这个特征就是后续可以用来做预测的特征,那所以说 FUTR3D 这个过程当中特征生成的方式是什么样的,我们先有的是什么呢,先有的是 3D reference point,它是第一步,从 3D reference point 投影到不同模态上采样不同模态的特征,它这个思路是一致的,先有 3D 点然后去采样不同模态的特征融合得到最终的一个检测结果

我们总结一下,无论是我们讲的 DETR3D 还是这里提到的 FUTR3D 均是利用 3D 空间的参考点去对应到 2D 或者多模态的输入当中采样对应的特征,是先有 3D 然后到 2D 的过程,采样后的特征去进行一个聚合的预测,我们把这种具有显性参考点的方式叫做 Explicit Mapping 显性映射,那也就是说我们有参考点,参考点的位置是一个显性的位置关系,我们把这种方式叫做显性映射的方式,那也就是我们知道我们现在要的就是这个参考点的特征,我们别的都不要,我们只要这个参考位置

那这里是我们讲的第一种叫显性映射,我们再来看一下隐式映射是怎么做的

3.2 Implicit Mapping

我们说隐性映射之前我们再来看一下 DETR3D 的框架,如下图所示:

二. BEV感知算法基础模块讲解_第16张图片

像 DETR3D 首先是有 Query 去预测一系列的 3D reference point,一般有 N 个参考点,然后利用相机参数将参考点反投影回 2D 图像,对 2D 图像的特征进行采样,最后根据采样得到的 2D 特征预测 3D 目标,那这会有什么问题,我们思考一下。那显然如果我的参考点就不对了,投影回的图像位置是不是处于无效的位置,也就是说可能处于目标区域之外,导致采样到无效的图像特征,那后续的检测显然也不会得到正确的结果

还有一个什么问题呢,我们讲像 DETR 的方法是先有 reference point 然后才有 feature,是一个从 point 到 feature 的一个过程,point 显然是一个局部特征,比如对一个 BEV 空间而言,我们只会补全某几个点的特征,对于其他位置呢,其实是一个空值,所以说像 DETR3D 的方法,它适应的是稀疏的局部特征,可能会导致模型对于全局特征的表达能力不够,因为其他都是空值,没有特征的表达,所以说对于全局特征的学习不够充分

那因此很多研究者就思考,很多算法针对这个问题它会想能不能摆脱参考点的限制,让网络可以自适应的学习到 2D 特征到 3D 空间的一种对应关系,另外一个就是我们能不能做一种全局的特征表达呢,那如果脱离了这个 reference point 的限制,我们是没有提前的显式的知道位置的,那所以这个过程我们称之为隐式映射的过程,我们没有一个显性的参考点提供 3D 的初始位置,我们把这种过程就称之为一种隐式的过程。

那基于我们上面讲到的这个思路,PETR 就是这么做的,那像 PETR、DETR3D 在后续的论文讲解章节当中我们也会给大家详细介绍,我们这里是围绕其中的一个从 3D 到 2D 转换的基础模块去给大家把其中的核心内容拿出来先讲一下

PETR 是旷世在 2022 年初的工作,它其实是 DETR3D 的一个改进版,在没有增加额外训练数据量的情况下性能是比 DETR3D 要好的,其网络框架如下图所示:

二. BEV感知算法基础模块讲解_第17张图片

PETR 的核心动机和主体结构简单总结如下:

  • 核心动机:从 3D 到 2D 构建 BEV 空间,是否需要显性的 2D-3D 映射关系?
  • 主体结构:构造 3d object query 和 2d image feature 间的关系
    • 核心:将 3D 坐标的位置信息编码为图像特征,生成 3D position-aware 的特征

同样我们先看一下这个网络输入输出都是什么,输入是我们熟悉的一个 Multi-view images 多视角图像,还有一个输入叫 3D Coordinates Generator,3D 点生成器,那输出是什么呢,是检测结果,利用环视图像和 3D 点生成器生成出来的结果作为输入可以得到最终的 3D 检测结果,那输入环视图像和输出检测结果这两部分我们都很熟悉了,所以这里重点来看一下所谓的 3D World space 是什么东西

这个模块是叫 3D 坐标生成,该模块前面是图像平面,后面是 3D 世界空间,那我们从图像平面到 3D 的过程是不是我们之前讲过的从 2D 到 3D 的转换,所以这个模块的功能其实实现的就是从 2D 到 3D 空间的一个映射过程,将相机视锥的覆盖区域映射到 3D 空间当中,可以生成 3D 空间的一系列的坐标点,那为什么要得到这个空间呢,我们就得联系一下 PETR 的核心内容来看,PETR 的动机是学习 2D 图像特征和 3D 空间位置之间的一种隐式对应关系,那所以输入得有 2D 特征,那 3D 空间位置在哪呢,我们给它生成出来了,所以这个模块主要功能是生成 3D 的位置坐标

有了位置坐标,有了图像特征,输入到 3D 位置编码器当中,那这个编码器是干什么的呢,它的作用就是学习图像特征和位置坐标之间的一个对应关系,之后学习好的特征我们认为它已经是有了 2D 图像和 3D 位置一个相互对应关系后的特征,送入解码器,那后面的过程其实和我们所讲的 DETR3D 其实都是基本类似的,送入解码器之后就可以去预测一个比较准确的检测结果。PETR 的详细网络我们在之后的内容讲解中也会详细介绍的,我们这里是主要对于它的隐式映射的部分先做一个基础了解

OK,我们回顾一下,在这一小节当中,我们主要讲了从 3D 到 2D 的一个映射过程,主要有以 DETR3D 为代表的显性映射方法和以 PETR 为代表的隐式映射方法,像 DETR3D 和 FUTR3D 将显性的 3D 参考点投影到 2D 空间当中做特征采样,PETR 则是通过网络去自适应的学习 3D 和 2D 空间的一个对应关系,所以我们称它为一个隐式过程,它并没有一种显性的位置表示关系

无论是 2.1 小节我们讲的从 2D 到 3D 的转换还是本节所讲的 3D 到 2D 的转换,它们全都是 BEV 感知算法比较基础也是比较核心的模块,后续如果涉及到论文讲解部分,涉及到不同算法的详细转换还会做进一步的讲解

4. BEV感知中的Transformer

前两节的内容我们主要涉及到转换模块,包括 2D 到 3D 和 3D 到 2D 的讲解,本节内容我们主要围绕 Transformer 展开,因为 Transformer 已经是 BEV 感知算法当中不可或缺的一个很重要的内容

我们在说 Transformer 之前,我们先要明白 Transformer 是干什么的,其实从本质上来讲 Transformer 是一种注意力机制,那什么是注意力呢,简单来说就是选择重要的信息,而忽视不重要的信息。在计算机视觉当中,注意力机制是非常多的,远远不止 Transformer 一种,包括通道注意力,空间注意力、混合注意力等等,我们先从常见的注意力机制入手,我们再来看看 Transformer 是怎么做的,与这些通道注意力、空间注意力有什么不同

4.1 空间注意力之STN

空间注意力机制一个比较具有代表性的模型是空间变化神经网络,我们叫 STN(Spatial Transformer Network),那 STN 可以对各种形变的数据在空间中进行转换,并且能够自动捕获重要区域的特征

二. BEV感知算法基础模块讲解_第18张图片

我们举个例子,比如上图中像手写数字分类这个数据集当中运用空间注意力它一共包含了四个步骤,第一个步骤通过随机平移缩放把它们输入到空间注意力网络当中,通过空间注意力机制它可以识别出来数字是否有平移,是否缩放,是否旋转,它可以预测出变换前的这个数字,那也就是说没有经过变换的数字是怎样的,然后拿处理好的数字去做预测。这样一个好处就是我们可以把特征更聚焦,我们可以得到一个比较好的特征表达形式,那这个就叫空间注意力,所谓的空间注意力是在空间层面上

比如一张图像的宽高分别为 W 和 H,空间注意力是作用在什么范围上的呢,是作用到 H × W H\times W H×W 这个平面上的,哪一个区域是我们需要额外关注的特征,这个就是空间注意力所起的作用,通过空间注意力的操作,我们可以得到空间范围内,平面范围内或者说 3D 立体视觉范围内哪一块是我们需要额外关注的部分,那这个叫空间注意力机制,我们这里的 STN 也仅仅是空间注意力当中一种比较具有代表性的网络结构

4.2 通道注意力之SENet

另外我们说一下通道注意力,通道注意力其实是一个非常重要的注意力,我们在后续的很多 BEV 感知算法当中也能看到,通道注意力是在哪里去做注意力呢,我们刚讲到空间注意力是在 H × W H\times W H×W 这个维度上去做的注意力,通道注意力顾名思义是在通道上做的注意力,对于一张特征图而言,它的特征是 H × W × C H\times W \times C H×W×C,这个 C C C 是通道数,我们看经过通道注意力之后特征图会有什么变化呢,那 SENet 就是一个典型的通道注意力算法

二. BEV感知算法基础模块讲解_第19张图片

输入特征之后,特征输出是什么呢,输入特征是一个全白的图,通道维度是 C C C,经过通道注意力之后不同通道的颜色不一样了,其实就意味着它们乘上了不同的权重,我们可以假设颜色比较深的地方权重比较大,颜色比较浅的地方权重比较小,那么我们得到的特征图,颜色比较深的地方特征被加强了,颜色比较浅的地方特征被削弱了,那这个加强和削弱是在哪个维度上做的呢,在通道维度上做的,所以后续网络在预测的过程当中会更关注重点也就是颜色深的部分,而忽略被削弱的部分也就是颜色浅的部分

二. BEV感知算法基础模块讲解_第20张图片

那上面也是一种通道注意力叫做 GSoP,我们来看看这个通道注意力是不是和 SENet 一样的思路,这里的输入是蓝色的,它把特征表达方式换了一下,注意力在通道 C C C 这个维度去做的,输入是蓝色的,权重都是一样的,输出明显有了区别,有深色的,有浅色的,我们同样假定颜色比较深的地方权重比较大,颜色比较浅的地方权重比较小,那么得到的特征图颜色比较深的地方特征被加强了,颜色比较浅的地方特征被削弱了,所以通道注意力是在通道这个维度去做的,目的是挑选一些比较强的通道特征去做重点关注,同时忽略一些语义不明显的通道特征

我们可以总结一下,空间注意力是在 H × W H\times W H×W 这个维度上去做的,通道注意力是在 C C C 这个维度上去做的,那么这两种注意力冲突吗,大多数认为是不冲突的,甚至可以合并为一种串行结构,同时利用两种注意力去对特征进行增强,这其实就是混合注意力的模式

4.3 混合注意力之CBAM

混合注意力比较有代表性的算法是 CBAM,那首先输入是一个中间特征图,特征图先输入到通道注意力模块对通道特征去做加强,然后输入到空间注意力模块对空间维度去做加强,通过两个注意力模块的操作之后,它最终的特征图同时运用了两种注意力机制,网络可以自适应的细化特征

二. BEV感知算法基础模块讲解_第21张图片

二. BEV感知算法基础模块讲解_第22张图片

我们大家可以思考一个问题,我们这里看到的是一种串行的结果,先通过通道注意力,再通过空间注意力,可以得到我们最后的特征,那比如说我们这里能否采用并行的方式呢,比如说有通道特征,有空间特征,然后去对两种不同的特征去做融合输出得到最后的特征,能否采用这样并行的方式

另外一种大家可以再想一下,如果输入了特征之后,先通过空间注意力模块再通过通道注意力模块这样会有影响吗,那其实这篇工作当中作者也给出了经验结论,从分类任务上来看的话,我们刚讲的这两种额外的方式会有一点影响,但影响相对而言是比较小的,所以说这个只是一个比较确切的一个过程,那大家在做实验的时候可以对这些相关的顺序做一些消融的实验

4.4 Self-Attention

我们下面回归到本节的一个正题 Transformer,Transformer 到底是什么呢,我们前面讲了这么多的注意力,我们讲通道注意力是在通道维度上去做的注意力,空间注意力是在空间 H × W H\times W H×W 这个维度上去做的注意力,混合注意力是在两个层面都有的,对输入特征做注意力之后可以得到强化后或者削弱后的特征

那所以我们强调第一个事情,Transformer 是干嘛的呢,它其实就是一个特征提取模块,输入一个特征然后是经过一个 Transformer 我们可以得到输出特征,无非就是我们得到的这个输出特征是经过某些强化的

我们再来看第二件事情,既然是 Transformer 是一个注意力模块,那它与之前的注意力有什么区别呢,我们讲通道注意力是在通道 C C C 这个维度上做的,某个通道重要一点我们就多关注一点。空间注意力是在 H × W H\times W H×W 这个范围做的,哪个区域重要我们就对这个区域多关注一点,Transformer 是在什么层面去做的注意力呢,是针对什么的注意力呢

Transformer 是针对序列而言的,给定的输入序列各个位置之间彼此影响力的大小,序列那当然可以包括文本序列,比如我是周同学,那它就是一个文本序列,会计算这五个字之间的一个关系;或者时间序列,Transformer 的注意力机制是作用在序列内部的,是计算两两之间的关系,所以我们称之为 Self-Attention,它这种自注意力机制是自己和自己之间的一个关系,具体怎么做的呢,如下图所示:

二. BEV感知算法基础模块讲解_第23张图片

那比如输入的特征序列是 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 2 \boldsymbol a^{\boldsymbol 2} a2 a 3 \boldsymbol a^{\boldsymbol 3} a3 a 4 \boldsymbol a^{\boldsymbol 4} a4,输出特征怎么包含 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 2 \boldsymbol a^{\boldsymbol 2} a2 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 3 \boldsymbol a^{\boldsymbol 3} a3 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 4 \boldsymbol a^{\boldsymbol 4} a4 之间的一个关系呢,那这里它就用到了三个非常关键的转换量,一个叫 Query,一个叫 Key,一个叫 Value,Query 我们叫查询向量,它是一种查询机制,用于查询和其余特征之间的一个关系,那当然它也包括查询和它自身的一个关系,比如以 a 1 \boldsymbol a^{\boldsymbol 1} a1 为基准,我们想计算 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 2 \boldsymbol a^{\boldsymbol 2} a2 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 3 \boldsymbol a^{\boldsymbol 3} a3 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 4 \boldsymbol a^{\boldsymbol 4} a4 它们之间的一个关系,拿 a 1 \boldsymbol a^{\boldsymbol 1} a1 哪个向量去算呢,拿查询向量去算,查询向量是为了计算与其他特征之间的关系的

那第二个 Key 叫键值向量,是用来被计算相似度的,我们比如以 a 1 \boldsymbol a^{\boldsymbol 1} a1 为基准,我们想计算 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 2 \boldsymbol a^{\boldsymbol 2} a2 之间的一个相似度,我们刚刚讲过要计算以 a 1 \boldsymbol a^{\boldsymbol 1} a1 为基准,计算 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 2 \boldsymbol a^{\boldsymbol 2} a2 之间的相似度,我们怎么算呢,拿 a 1 \boldsymbol a^{\boldsymbol 1} a1 的 Query 去查 a 2 \boldsymbol a^{\boldsymbol 2} a2 的 Key,所以说以 a 1 \boldsymbol a^{\boldsymbol 1} a1 的 Query 向量和 a 2 \boldsymbol a^{\boldsymbol 2} a2 的 Key 向量计算相似度我们叫 α 1 , 2 ′ \alpha'_{1,2} α1,2,那就是以 a 1 \boldsymbol a^{\boldsymbol 1} a1 为基准, a 1 \boldsymbol a^{\boldsymbol 1} a1 a 2 \boldsymbol a^{\boldsymbol 2} a2 的相似度可以得到一个相似度值,叫 α 1 , 2 ′ \alpha'_{1,2} α1,2,同理我们如果想计算 a 1 \boldsymbol a^{\boldsymbol 1} a1 a 3 \boldsymbol a^{\boldsymbol 3} a3 之间的一个关系,拿哪个算呢,拿 a 1 \boldsymbol a^{\boldsymbol 1} a1 的 Query 和 a 3 \boldsymbol a^{\boldsymbol 3} a3 的 Key 计算可以得到 α 1 , 3 ′ \alpha'_{1,3} α1,3,同理也可以得到 α 1 , 4 ′ \alpha'_{1,4} α1,4

当然它最后也需要和它自己做一个相似度我们得到 α 1 , 1 ′ \alpha'_{1,1} α1,1,我们都算完之后呢,去对四个值做一个 softmax,那比如我发现 a 1 \boldsymbol a^{\boldsymbol 1} a1 和它自己最有关系, α 1 , 1 ′ \alpha'_{1,1} α1,1 值可能是 0.5, 和 a 2 \boldsymbol a^{\boldsymbol 2} a2 可能有点关系, α 1 , 2 ′ \alpha'_{1,2} α1,2 值可能是 0.3,和 a 3 \boldsymbol a^{\boldsymbol 3} a3 a 4 \boldsymbol a^{\boldsymbol 4} a4 它俩关系不大, α 1 , 3 ′ \alpha'_{1,3} α1,3 α 1 , 4 ′ \alpha'_{1,4} α1,4 可能就只有 0.1,那这些值是什么呢,其实是一个权重,其实就是表示了序列内部的相关性, a 1 \boldsymbol a^{\boldsymbol 1} a1 a 3 \boldsymbol a^{\boldsymbol 3} a3 关系不大,权重就是 0.1,和自己关系大,权重就是 0.5,那有了这个权重之后呢,我们就可以做加权,这个加权拿哪个向量算呢,拿 Value 向量, a 1 \boldsymbol a^{\boldsymbol 1} a1 的 Value 乘以 a 1 \boldsymbol a^{\boldsymbol 1} a1 和它自己的相关度权重 α 1 , 1 ′ \alpha'_{1,1} α1,1 得到一个特征,和 a 2 \boldsymbol a^{\boldsymbol 2} a2 的相关度呢,拿 a 2 \boldsymbol a^{\boldsymbol 2} a2 的 Value 乘以 α 1 , 2 ′ \alpha'_{1,2} α1,2,所有值算完之后合在一起我们就得到 a 1 \boldsymbol a^{\boldsymbol 1} a1 和序列当中其它元素之间的一个关系了

那我们讲到这里,我们总结一下 Transformer 中的 attention 是做什么事情呢,是输入的一段特征序列通过 self-attention 的机制,输出包含序列内关系的特征,输入的是序列特征,输出的也是序列特征,当然我们这里是输出的 b 1 \boldsymbol b^{\boldsymbol 1} b1,其实同理还输出了 b 2 \boldsymbol b^{\boldsymbol 2} b2 b 3 \boldsymbol b^{\boldsymbol 3} b3 b 4 \boldsymbol b^{\boldsymbol 4} b4,不同输出的序列特征包含序列中各元素之间的一个关系

关于 Self-attention 和 Transformer 的内容博主这里强烈建议大家去观看下李宏毅老师的视频讲解

视频链接:【机器学习2021】自注意力机制(Self-attention) 【机器学习2021】Transformer

博文讲解:AutoCV番外:Transformer

4.5 ViT

那 Transformer 是怎么做的,我们进一步按照视觉领域 Transformer 的发展历程来给大家梳理一下,我们刚讲过 Transformer 输入的是序列特征,序列特征在 NLP 任务中是天然存在的,比如说我是周同学,那我们说的一句话其实就是一个序列,话中每一个字是一个序列元素,但图片它其实本身不是一个很天然的序列任务,图片是一张一张的嘛。所以说我们如果想用 Transformer 处理视觉任务,我们要怎么做呢,我们首先的任务是需要把图片转换为序列表示,我们怎么样从图片去得到一堆序列是我们要做的第一件事情

那 ViT 是非常经典的一个视觉模型,非常非常经典,这个大家需要做一些了解的,那 ViT 是怎么把图像转换成序列的呢,它的框架如下图所示:

二. BEV感知算法基础模块讲解_第24张图片

ViT 的核心动机和主体结构简单总结如下:

  • 核心动机:如何让 Transformer 处理视觉任务?
  • 主体结构
    • 核心:将图像转换为序列化表示,一张图片无重叠切分成固定大小的 Patches

ViT 作者提出的思路其实非常简单,图像可以切分成大小相同的图像块,图像按照 3x3 的比例切分成 9 个块,每一个块我们称之为一个 Patch,每一个 Patch 可以提取图像特征,映射到固定的维度,这个维度值在 ViT 论文中给的是 768,每一个 Patch 的图像都可以映射成一定维度的特征向量,那这样一个 Patch 块的处理我们就可以把完整的一个输入图像转换成一个图像序列

那我们思考一个问题,图像序列转换的过程中,从图像到图像序列转换的这个过程什么信息损失了呢,有没有信息损失呢,那其实很明显,位置信息损失了,我们大家可以想一下 Transformer 它并不知道输入的这个序列它来自哪里,它是不知道这个事情的,那也就是说它无法衡量原本图中的空间位置关系,所以说除了分割 Patch 进行序列化的操作之外呢,ViT 作者还引入了 Position Embedding 这个操作,一个位置编码

那这个操作其实就是把图像上每一个 Patch 的位置信息编码合到视觉特征当中,位置和视觉两种特征合到一起之后,一起送入到我们所谓的 Transformer Encoder,我们上面讲过输入 Transformer 的是序列特征,输出的是什么呢,也是序列特征,它们的不同点仅仅在于输出的特征是包含了输入特征两两元素之间的关系的,因此我们知道 Transformer Encoder 的输入如果是 9 个特征,输出也应该是 9 个特征

ViT 这个模型提出之初是用来处理图像分类任务的,所以说它通过一个 MLP Head 把我们的输出特征又重新通过映射,通过预测的关系可以得到图像的类别,ViT 是 Transformer 从 NLP 领域迁移到 CV 领域一个非常重要的突破,我们可以看到它对原始的 Transformer Encoder 其实没有做出很大的改动的,它沿用的还是传统的 NLP 中 Transformer 的一个架构

它重要的点就是将图像做了一些序列化的处理,它这个方法在大规模的数据集上效果非常好,而且它还有个什么好处呢,我们可以把这个 ViT 理解为一个图像的 2D 图像处理网络,我们输入了一个图像,可以得到图像特征,那它实现的是不是我们 2D Backbone 的一个功能,所以说很多任务当中 ViT 也是可以作为一个比较基础的 2D 图像处理网络来去用的

4.6 Swin Transformer

那在 ViT 之后呢,我们这里要提的第二个有关 Transformer 的工作叫 Swin Transformer,这里就简单看一下它和 ViT 的一个主要区别,这就是 ViT 的改进版,它有什么区别呢,如下图所示:

二. BEV感知算法基础模块讲解_第25张图片

首先第一我们在提到 ViT 在生成 Patch 的时候是将整张图片进行划分的,所以说它的 self-attention,它的一个自注意力机制是在全图做的,Patch 划分的过程是在全图划分的,所以我们在计算 Patch 之间两两关系的时候是在全图做的,当然对于图像分类任务来说像 ViT 的划分是足够的,因为图像分类是对于全局特征要额外关注的,在实际的应用当中比如像安防监控,自动驾驶场景当中,目标往往并不会占据图像中很大的一个区域,所以这时候用 ViT 的效果就不是很好

Swin Transformer 做的事情是先将图像换分为 window,划分为很多很多的小块,小块内部我们再划分 Path,在做 self-attention 之后是基于 window 内部做的,就是每个块内去做的 self-attention,至于 Swin Transformer 后续的详细的模块处理这些都是围绕我们怎么建立这个 window 展开的,我们这里就不再详细说了

那大家也了解一下 Swin Transformer 也是可以作为一个比较基础的 2D 图像 Backbone 去做的,输入图像我们通过 Swin Transformer 我们可以得到图像特征,至于得到了图像特征之后去做什么任务,那就是我们后续自由定义的一些任务了

4.7 DETR

OK,以上就是 Transformer 在视觉领域最基本的,最开始的应用,随着技术的不断更替,Transformer 在 2D 目标检测领域的开山之作,大家耳熟能详的 DETR 也就诞生了

那这份工作其实是 Facebook 在 ECCV2020 中提出的非常非常经典的工作,我们在目标检测领域里面讨论 Transformer 其实都是离不开这份工作的,那我们接下里看一看为什么我们之前讲的 ViT 它仅仅能实现图像分类的功能,而 DETR 是可以实现目标检测的功能,下面是 DETR 的核心框架图:

二. BEV感知算法基础模块讲解_第26张图片

它其实包含两个部分,一个是 transformer encoder,一个是 transformer decoder,encoder 叫编码器,编码什么呢,将图像可以编码为特征,后面我们叫 decoder 解码器,那它解码什么呢,将特征可以解码为后续的检测结果,也就是图中黄色的,红色的检测框,那也就是说通过编码器加解码器,输入原始图像输出可以得到检测结果,

OK,我们再来看编码器是怎么做的,其实编码器和我们之前讲的 ViT 是一个结构,输入图像的 Patch 我们可以输出图像 Patch 的序列特征,那这其实就是 ViT 的核心内容嘛,唯一不同点在于这里输入的并不是原始图像,而是经过 CNN 处理之后的图像,图像经过 CNN 处理之后通过 Patch 化的一些处理,然后通过 transformer encoder 我们可以得到序列化的图像特征

所以说 transformer encoder 我们了解了之后我们也明白其实可以作为一个 2D Backbone 存在的,输入图像通过 transformer encoder 我们可以得到图像特征,那只不过这个图像特征是经过编码处理的,经过序列化处理之后的,拥有一个自注意力关系的一个特征

那另外一个问题,我们讲的 transformer encoder 它如果可以作为一个 2D Backbone 存在的话,它和我们传统上讲的比如像 ResNet 有什么区别呢,我们讲的 Transformer 能起到什么作用呢,我们为什么要用 Transformer Encoder 而不用传统的 ResNet 呢

那其实 Transformer Encoder 其中内含了 self-attention 就是我们自注意力的操作,那 self-attention 它会便于网络提取不同位置不同物体之间的相互关系,做到真正理解图片上所表达出来的信息,那比如图中有一个桌子,那桌子上面很有可能有杯子、还有筷子,它们之间是有关系的,比如水边可能有鸟,湖里面可能有鱼,那这些关系是对于我们目标检测任务非常有效的,所以说用 Transformer Encoder 去建模这种关系是它的核心内容,所以 Transformer 的优势在于可以很好的建模这样一种关系

以上的 transformer encoder 我们说是一个 ViT 的过程,ViT 直接利用这个输出的特征去做分类任务的,那我们这里 DETR 想实现目标检测要做什么呢,那就是后续 transformer decoder 来做的事情,那对于解码部分,当你有了图像特征之后,有了一个 object queries,这个 Query 其实就决定了模型最终预测多少个框,通过 Query 和特征我们在 decode 里面会进行 self-attention 操作,并得到最后的输出的框,文中作者设置的是 100,也就是说无论什么图片我们都会预测 100 个框,那对应的 transformer decoder 也会输出 100 个是经过注意力映射之后的物体,然后将它们同时喂给一个 FFN,我们可以得到 100 个框的位置和类别得分,因为是多分类,所以这个类别其实是 K+1,包含背景类别

通过这样的 Encoder 和 Decoder 的结构我们就能实现 Transformer 在 2D 目标检测当中的应用,Transformer 在目标检测当中如果想做好应用的话,其实分为两步的,第一步是 Transformer Encoder,Encoder 这个部分的主要目的是对图像进行一个编码,那这种编码与我们传统所讲的 2D Backbone 一个显著区别在于 Transformer 的编码可以更好的关注图片内的一个相互关系,比如说物体与物体的关系,物体和背景的关系等等,那这种关系对检测来说无疑是非常有用的,比如鸟一般是成群结队的,有一个鸟的地方旁边大概率还有一个鸟,像这种关系对于我们检测是非常有利的。另外一个是 Transformer Decoder,那这个 Decoder 的部分其实是用 object queries 就是我们的目标 Query 去查询特征,查询好的特征用于我们最后的检测任务

那这个其实是 Transformer 在 2D 目标检测的一个应用,那对于我们 3D 目标检测 Transformer 有什么应用呢

4.8 DETR3D

那这里我们又要把在转换模块小节中提到的 DETR3D 那出来讲了,那 DETR3D 模型是一个非常经典的 Transformer 在 3D 目标检测当中的应用,那了解了我们上面讲解的基础模块之后我们再来看这个网络其实非常简单

二. BEV感知算法基础模块讲解_第27张图片

DETR3D 的核心模块在哪呢,其实是图中的彩色区域,我们在这个区域输入 object query,输出的是检测结果,那这个其实就是我们刚才提到的 Decoder 模块,有了特征有预设的 3D object query 可以得到 3D 的检测结果,我们再来看和 2D 的 DETR 有什么不同呢,显然它缺少的是 Transformer Encoder 这个部分,DETR3D 的特征提取网络用的是比较基础的,ResNet+FPN 的结构,通过 3D 参考点到 2D 中提取对应的点的特征,那这个部分在 2.2 小节我们讲的已经比较详细了,大家如果遗忘了可以去复习一下

到此为止我们大家可以看一下 BEV 感知中的 Transformer 和我们常见的 CV 中的 Transformer 是并没有什么太大区别的,它们都是共通的,无非是针对 3D 检测这个任务设计了一些额外的 2D 到 3D 或者 3D 到 2D 的处理模块

以上就是我们第二章的所有内容,我们主要讲了 BEV 感知算法中的 2D 到 3D 的转换模块,3D 到 2D 的转换模块,以及一些比较基础的后续很多网络都涉及到一个注意力机制,还有 Transformer 结构等等

那在第三章和第四章,我们会对 BEV 感知算法的主流方法会进行逐个的介绍,会对其中涉及到的详细的基础模块也会有更详细的讲解,此外也会挑选一些经典算法看看它们的代码是怎么实现的

总结

本章我们主要讲解了 BEV 感知算法当中的一些基础模块,包括 2D 到 3D 的转换模块,我们以 LSS 和 Pseudo LiDAR 算法为例讲解了如何去做一个 2D 到 3D 的转换,我们主要是通过离散或者连续的深度分布值去找 3D 空间位置上的一个关系。此外我们还讲解了从 3D 到 2D 的逆转换过程,包含显性映射方法如 DETR3D、FUTR3D,通过将显性的参考点投影到 2D 空间中做特征采样;还有隐式映射方法如 PETR,通过网络自适应的学习 3D 到 2D 空间的一个对应关系。最后我们讲解了 BEV 感知算法中的 Transformer,它内含了 self-attention 自注意力模块,与传统的通道或者空间注意力模块不同,self-attention 是针对序列而言的,是计算输入序列各个位置之间的一种关系。我们还围绕视觉领域中 Transformer 的发展历程简单介绍了 ViT、Swin Transformer、DETR、DETR3D 等经典算法。

下一章节我们会讲解几个主流的基于 Camera 和 LiDAR 融合的 BEV 感知算法,包括 BEV-SAN、BEVFusion,敬请期待

下载链接

  • 论文下载链接【提取码:6463】
  • 数据集下载链接【提取码:data】

参考

  • [1] Qi et al. Pointnet++: Deep hierarchical feature learning on point sets in a metric space

  • [2] Zhou et al. Voxelnet: End-to-end learning for point cloud based 3d object detection

  • [3] Philion et al. Lift, splat, shoot: Encoding images from arbitrary camera rigs by implicitly unprojecting to 3d

  • [4] Wang et al. Pseudo-lidar from visual depth estimation: Bridging the gap in 3d object detection for autonomous driving

  • [5] Wang et al. Detr3d: 3d object detection from multi-view images via 3d-to-2d queries

  • [6] Chen et al. Futr3d: A unified sensor fusion framework for 3d detection

  • [7] Liu et al. Petr: Position embedding transformation for multi-view 3d object detection

  • [8] Jaderberg et al. Spatial transformer networks

  • [9] Hu et al. Squeeze-and-excitation networks

  • [10] Gao et al. Global second-order pooling convolutional networks

  • [11] Woo et al. Cbam: Convolutional block attention module

  • [12] Dosovitskiy et al. An image is worth 16x16 words: Transformers for image recognition at scale

  • [13] Liu et al. Swin transformer: Hierarchical vision transformer using shifted windows

  • [14] Carion et al. End-to-end object detection with transformers

你可能感兴趣的:(BEV感知,自动驾驶,视角转换,注意力机制,Transformer)