VoxelNet: 基于体素的端到端目标检测
背景分析
基于点云的3D目标检测是各领域如今所关注的重点,与图像的检测不同,LiDAR 提供可靠的深度信息,可用于准确定位对象并表征其形状。但由于 3D 空间的非均匀采样、传感器的有效范围、遮挡和相对姿态等因素,LiDAR 点云稀疏且点密度变化很大。
体素
图片是二维的,单个点叫像素。同理,三维点云中可以想象用一个大的长方体将所有的点云容纳进去,这个长方体就是个大体素,但是点云是稀疏的,所以又要将大的体素化为一个个小的体素进行更加高效的处理。VoxelNet就是在前期运用了Voxel Partition的手段进行处理,之后以端到端的方式从点云中学习判别性特征表示并预测准确的 3D 边界框,避免了手动特征工程引入的信息瓶颈。
算法分析
VoxelNet的架构主要由三部分组成:
- 特征学习网络( Feature learning network)
- 卷积中间层(Convolutional middle layers)
- 区域提案网络(Region proposal network)
特征学习网络( Feature learning network)
这一模块的操作主要就是进行点云的处理。如上图所示又分为5个步骤:体素分块(Voxel Partition),点云分组(Grouping),随机采样(Random Sampling),多层的体素特征编码(Stacked Voxel Feature Encoding),稀疏张量表示(Sparse Tensor Representation)。
体素分块(Voxel Partition)
如上面介绍体素概念一样,先用大的3D空间容纳所有的点云数据,其深度、高度和宽度分别为 ( D , H , W )。再在其内部自定义体素尺寸( v D v_{D} vD, v H v_{H} vH, v W v_{W} vW),则整个数据的三维体素化的结果在各个坐标上生成的体素格(voxel grid)的个数为:( D v D , H v H , W v W \frac{D}{v_{D}},\frac{H}{v_{H}},\frac{W}{v_{W}} vDD,vHH,vWW)。
点云分组(Grouping)
分组就是将所有的点云数据划分到所定义的体素中,但是因为点云是稀疏的,并且在在整个空间中具有高度可变的点密度,所以分组之后体素中的点云个数各不相同,甚至有些体素中就没有点云。
随机采样(Random Sampling)
随机采样就是抽取上面所定义的体素。因为分出的体素比较多,而且很多就没有点云数据,所以随机采样可以减少计算量,有效降低因为点云数据不平衡带来的信息偏差。另外论文中定义了一个体素中所包含最大点云数量T。
多层的体素特征编码(Stacked Voxel Feature Encoding)
这一部分就是对点云进行特征编码,Voxel Feature Encoding简称VFE,是本文的核心思想。
对体素内的点集进行操作:
V = { P i = [ x i , y i , z i , r i ] T P_{i} = [x_{i},y_{i},z_{i},r_{i}]^{T} Pi=[xi,yi,zi,ri]T}
其中 x i , y i , z i x_{i},y_{i},z_{i} xi,yi,zi是第i个点的三维坐标, r i r_{i} ri是接收到的反射率。
将体素内所有点计算平均值作为体素的质心( v x , v y , v z v_{x},v_{y},v_{z} vx,vy,vz)
增加偏移量来扩充所有点的特征数量 : V i n = [ P i = [ x i , y i , z i , r i , , x i − v x , y i − v y , z i − v z ] T ] V_{in} = [P_{i} = [x_{i},y_{i},z_{i},r_{i},,x_{i}-v_{x},y_{i}-v_{y},z_{i}-v_{z}]^{T}] Vin=[Pi=[xi,yi,zi,ri,,xi−vx,yi−vy,zi−vz]T]
之后将处理过的所有点进行fully connected network
(FCN),包含了一个线性映射层,一个批标准化(Batch Normalization),以及一个非线性运算(ReLU),得到逐点的(point-wise)的特征表示。维度从7变为m。
再进行最大池化达到局部聚合的目的,最后,每个 point-wise feature 和 locally aggregated feature 进行拼接,得到最终的特征
V
o
u
t
=
f
i
o
u
t
i
,
.
.
.
,
t
V_{out} ={ f^{out}_{i}}_{i,...,t}
Vout=fiouti,...,t。
注意:所有非空体素都以相同的方式编码,并且它们在FCN中共享相同的一组参数。
稀疏张量表示(Sparse Tensor Representation)
虽然一次lidar扫描包含接近10万个点,但是超过90%的体素格都是空的,使用稀疏张量来描述非空体素格在于能够降低反向传播时的内存和计算消耗。
上述得到的特征可以用4维的稀疏张量表示:C
×
\times
× D’
×
\times
× H’
×
\times
× W’.
卷积中间层(Convolutional middle layers)
我们使用ConvMD ( c i n , c o u t , k , s , p ) (c_{in},c_{out},k,s,p) (cin,cout,k,s,p)来表示一个M维卷积算子,其中 c i n c_{in} cin和 c o u t c_{out} cout是输入和输出通道的数量,k,s和p是m维向量分别根据内核大小、步幅大小和填充大小来确定。当m维的大小相同时,我们使用一个标量来表示例如k=(k,k,k)的大小。
区域提案网络(Region proposal network)
RPN 这个概念来源于 Faster R-CNN 系列,VoxelNet 中也运用到了 RPN,但经过了改良。
输入是卷积中间层提供的特征,整个网络包含三个全卷积块,每个块的第一层通过步长为2的卷积将特征图采样为一半,之后是三个步长为1的卷积层,每个卷积层都包含BN层和ReLU操作。将每一个块的输出都上采样到一个固定的尺寸并串联构造高分辨率的特征图。最后,该特征图通过两种二维卷积被输出到期望的学习目标:
⋆
\star
⋆概率评分图(Probability Score Map )
⋆
\star
⋆回归图(Regression Map)
损失函数(loss function)
将三维真实框的参数定义为:
( x c g , y c g , z c g , l g , w g , h g , θ g x^{g}_{c},y^{g}_{c},z^{g}_{c},l^{g},w^{g},h^{g},\theta ^{g} xcg,ycg,zcg,lg,wg,hg,θg)
其中 x c g 、 y c g 、 z c g x^{g}_{c}、y^{g}_{c}、z^{g}_{c} xcg、ycg、zcg表示中心位置, l g 、 w g 、 h g l^{g}、w^{g}、h^{g} lg、wg、hg表示盒子的长度、宽度、高度, θ g \theta ^{g} θg为围绕z轴的偏航旋转。
检测框参数表示为:( x c a , y c a , z c a , l a , w a , h a , θ a x^{a}_{c},y^{a}_{c},z^{a}_{c},l^{a},w^{a},h^{a},\theta ^{a} xca,yca,zca,la,wa,ha,θa).
残差向量 u ∗ u^{*} u∗包含7个回归目标
各个回归目标的计算如图所示:
其中
d
a
=
(
l
a
)
2
+
(
w
a
)
2
d^{a} = \sqrt{(l^{a})^2+(w^{a})^2}
da=(la)2+(wa)2是锚盒底部的对角线。
则最终的损失函数为:
α,β是平衡相对重要性的平衡常数。
L
c
l
s
L_{cls}
Lcls代表二值交叉熵损失,最后一项
L
r
e
g
L_{reg}
Lreg是回归损失,其中我们使用Smooth L1函数。
高效运行( Efficient Implementation)
gpu被优化用于处理致密张量结构。但是点云分布稀疏。论文设计了一种将点云转换为密集张量结构的方法,其中堆叠的VFE操作可以在点和体素之间并行处理。
图5总结了该方法。初始化一个K×T×7维张量结构来存储体素输入特征缓冲区,其中K是是非空体素的最大数量,T是最大值每个体素的点数,7是每个点的输入编码维度。这些点在处理前是随机化的。对于点云中的每个点,我们检查是否有相应的体素已经存在。这个查找操作是在O(1)中使用一个哈希表有效地执行的,其中体素坐标被用作哈希键。
如果体素已经初始化,那么我们将点插入到体素位置,如果有小于T个点,否则该点将被忽略。如果体素没有被初始化,我们将初始化一个新的体素,将它的坐标存储在体素坐标缓冲区中,然后in插入该点到这个体素位置。体素输入特征和坐标缓冲区可以通过通过点列表来构造,因此其复杂度为O(n)。为了进一步提高内存/计算效率,可以只存储有限数量的体素(K),并忽略来自具有很少点的体素的点。
参考文献:
自动驾驶激光点云 3D 目标检测 VoxelNet 论文简述
无人驾驶汽车系统入门(二十八)——基于VoxelNet的激光雷达点云车辆检测及ROS实现
论文阅读:VoxelNet(3D-detection)+代码复现