VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection
进一步的VoxelNet的代码复现和网络理解,移步这里
摘要
准确检测 3D 点云中的物体是许多应用的核心问题,例如自主导航、家政机器人。将高度稀疏的 LiDAR 点云与区域提议网络(RPN),在这项工作中,我们提出 VoxelNet,一个通用的 3D 检测网络, 将特征提取和边界框预测统一为一个单阶段、端到端的可训练深度网络。VoxelNet 将点云划分为等间距的 3D 体素,并通过引入体素特征编码(VFE)层转换每个体素内的一组点,引入的统一特征表示。这样,将点云编码为描述性体积表示,然后将其连接到RPN以生成检测。在KITTI上的实验表明 VoxelNet 优于最先进的技术,基于 LiDAR 的 3D 检测方法大有优势。此外,我们的网络学习了一个判别各种几何形状的对象的表示,在行人的 3D 检测方面取得令人鼓舞的结果。
1. 简介
基于点云的 3D 对象检测是各种现实世界应用的重要组成部分,例如自主导航、家政机器人 和增强/虚拟现实。与基于图像的检测相比,LiDAR 提供了可靠的深度信息,可用于准确定位对象并表征其形状 。然而,与图像不同的是,由于 3D 空间的非均匀采样、传感器的有效范围、遮挡和相对位姿等因素,LiDAR 点云是稀疏的并且具有高度可变的点密度。为了应对这些挑战,许多方法手动制作了特征表示为 3D 对象检测而调整的点云。几种方法将点云投影到透视图中并应用基于图像的特征提取技术。其他方法将点云光栅化为 3D 体素网格,并使用手工制作的特征对每个体素进行编码。然而,这些手动设计选择引入了信息瓶颈,阻碍了这些方法有效利用 3D 形状信息和检测任务所需的不变性。图像识别和检测任务的重大突破是由于从手工制作的特征转向机器学习的特征。
由于使用 LiDAR 获得的典型点云包含约 100k 点,因此会导致计算和内存要求很高。将 3D 特征学习网络扩展到更多数量级的点和 3D 检测任务是我们在本文中解决的主要挑战。区域提议网络(RPN)是一种高度优化的算法,用于有效的目标检测 。然而,这种方法要求数据密集并以张量结构(例如图像、视频)进行组织,而典型的 LiDAR 点云并非如此。在本文中,我们缩小了用于 3D 检测任务的点集特征学习和 RPN 之间的差距。
我们提出了 VoxelNet,一个通用的 3D 检测框架,它同时从点云中学习判别特征,表示并以端到端的方式预测准确的 3D 边界框,如图 2 所示。我们设计了一种新颖的体素特征编码(VFE) 层,通过将逐点特征与局部聚合特征相结合(参考PointNet),实现体素内的点间交互。堆叠多个 VFE 层学习用于表征局部 3D 形状信息的复杂特征。具体来说,VoxelNet 将点云划分为等间距的 3D 体素,通过堆叠 VFE 层对每个体素进行编码,然后 3D 卷积进一步聚合这些局部体素的特征,将三维特征的点云转换为高维特征表示。最后, 使用RPN产生检测结果。这种高效的算法受益于稀疏点结构和体素网格上的高效并行处理。
图 1. VoxelNet 直接在原始点云上运行(无需特征工程),并使用单个端到端可训练网络产生 3D 检测结果。
我们在 KITTI 提供的鸟瞰图检测和完整的 3D 检测任务上评估 VoxelNet。实验结果表明,VoxelNet 大大优于最先进的基于 LiDAR 的 3D 检测方法。我们还证明,VoxelNet 在从 LiDAR 点云中检测行人和骑自行车的人方面取得了令人鼓舞的结果。我们还证明,VoxelNet 在从 LiDAR 点云中检测行人和骑自行车的人方面取得了令人鼓舞的结果。
1.2.贡献
• 我们提出了一种新颖的端到端可训练深度架构,用于基于点云的 3D 检测,VoxelNet,它直接在稀疏 3D 点上运行,避免了手动特征工程引入的信息瓶颈。
• 我们提出了一种实现VoxelNet 的有效方法,该方法受益于稀疏点结构和体素网格上的高效并行处理。
• 我们在 KITTI 基准上进行实验,并表明 VoxelNet 在基于 LiDAR 的汽车、行人和骑车人检测基准中产生了最先进的结果。
2.VoxelNet
在本节中,我们将解释 VoxelNet 的网络结构、损失函数以及实现网络的有效算法。
图 2. VoxelNet 结构。Feature Learning Network 网络将原始点云作为输入,在空间上划分为体素,并将每个体素内的点转换为表征形状信息的向量 Voxel-wise Feature 表示。整个空间被表示为稀疏的 4D 张量(CDH*W)。卷积中间层 Convolutional Middle Layers 处理 4D 张量以聚合空间上下文。最后,RPN 生成 3D 检测框。
2.1 VoxelNet 结构
VoxelNet 由三个功能块组成:特征学习网络、卷积中间层和RPN,如图 2 所示。
2.1.1 Feature Learning Network
划分体素 --将给定的一个点云,在 3D 空间细分为等间距的体素,如图 2 所示。假设点云处于 XYZ 三轴空间,要划分的所有点云区域定为 D、H、W。自定义每个体素的长宽高为 v D 、 v H v_D 、 v_H vD、vH 和 v W v_W vW 。这样如图,生成的粉色网格数为 D ′ = D / v D , H ′ = H / v H , W ′ = W / v W D' = D/v_D ,H' = H/v_H ,W' = W/v_W D′=D/vD,H′=H/vH,W′=W/vW 。这里,为简单起见,我们假设 D、H、W 是 v D 、 v H 、 v W v_D 、 v_H 、 v_W vD、vH、vW 的倍数。
分组 --我们根据这些点所在的体素对它们进行分组。由于距离、遮挡、物体的相对姿态和非均匀采样等因素,LiDAR点云是稀疏的,并且在整个空间中具有高度可变的点密度。因此,分组后,一个体素将包含可变数量的点。图2显示了一个示例,其中Voxel-1的点明显多于Voxel-2和Voxel-4,而Voxel-3不包含任何点。
随机抽样 --通常,LiDAR点云由10万个点组成。直接处理所有点不仅会增加计算平台的内存/效率负担,而且整个空间中高度可变的点密度可能会使检测产生偏差。为此,我们从体素中随机抽取一个固定数量T的点 。这种抽样策略有两个目的,(1)节省计算量; (2) 减少体素之间的点不平衡,从而减少采样偏差,并为训练增加更多变化。
堆叠体素特征编码 --关键的创新是VFE层。我们在下一段中使用VFE Layer-1来描述细节。图3显示了VFE第1层的架构。
将粉色框体V表示为包含t个LiDAR点的非空体素,其中pi为第 i 个点的XYZ坐标和反射率。
V
=
{
p
i
=
[
x
i
,
y
i
,
z
i
,
r
i
]
T
}
V=\{p_i=[x_i,y_i,z_i,r_i]^T \}
V={pi=[xi,yi,zi,ri]T}。首先,通过局部均值,计算为V中所有点的质心
(
v
x
,
v
y
,
v
z
)
(v_x,v_y,v_z)
(vx,vy,vz)。然后,我们用相对于质心的相对偏移量来增加每个点的特征维度并获得输入特征集
V
=
{
p
i
^
=
[
x
i
,
y
i
,
z
i
,
r
i
,
x
i
−
v
x
,
y
i
−
v
y
,
z
i
−
v
z
]
T
}
V=\{\hat{p_i}=[x_i,y_i,z_i,r_i,x_i-v_x,y_i-v_y,z_i-v_z]^T \}
V={pi^=[xi,yi,zi,ri,xi−vx,yi−vy,zi−vz]T}。接着,每个
p
i
^
\hat{p_i}
pi^通过全连接网络(FCN)转换到特征空间,获得逐点特征
f
i
\mathbf{f}_{i}
fi,从而完成对体素包含点云的表面形状的编码。FCN 由线性层、批归一化 (BN) 层和整流线性单元 (ReLU) 层组成。在获得逐点特征
f
i
\mathbf{f}_{i}
fi后,使用逐元素的 Max Pooling层处理
f
i
\mathbf{f}_{i}
fi, 获得体素V的局部聚合特征。最后,我们用
f
~
\tilde{f}
f~对每个
f
i
f_i
fi进行扩充拼接,以形成逐点级联特征
f
i
o
u
t
=
[
f
i
,
f
i
~
]
f^{out}_i=[f_i,\tilde{f_i}]
fiout=[fi,fi~]。因此我们得到输出特征集
V
o
u
t
=
{
f
i
o
u
t
}
V_{out} =\{f^{out}_i\}
Vout={fiout}(注意::输入:
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}=\{\hat{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} 输出:
V
o
u
t
=
{
f
i
o
u
t
}
V_{out} =\{f^{out}_i\}
Vout={fiout})。所有非空体素都以相同的方式编码,并且它们在 FCN 中参数共享。
我们使用 V F E − i ( c i n , c o u t ) VFE-i(c_{in} , c_{out} ) VFE−i(cin,cout) 来表示第 i 个 VFE 层,将输入 c i n c_{in} cin维度特征转换为 c o u t c_{out} cout维度的输出特征。线性层学习大小为 c i n × ( c o u t / 2 ) c_{in} × (c_{out} /2) cin×(cout/2) 的矩阵,逐点连接产生维度 c o u t c_{out} cout的输出。
因为输出特征结合了逐点特征和局部聚合特征,堆叠 VFE 层对体素内的点交互进行编码,并使最终特征表示能够学习描述性形状信息。将 VFE-n 的输出通过FCN和 Max pooling 转换,来获得体素特征,其中 C 是体素特征的维度,如图 2 所示。
稀疏张量表示 --通过处理非空体素,我们获得一组体素特征,每个体素特征关联到特定体素的空间坐标。获得的体素特征列表可以表示为一个稀疏的 4D 张量,大小为 C × D ′ × W ′ × H ′ C \times D' \times W' \times H' C×D′×W′×H′,如图 2 所示。虽然点云包含 ∼100k 点,但超过 90%的体素通常是空的。将非空体素特征表示为稀疏张量,极大地降低了反向传播期间的内存使用和计算成本,这是我们高效实现的关键步骤。
2.1.2 Convolutional Middle Layers
我们使用 ConvM D ( c i n , c o u t , k ⃗ , s ⃗ , p ⃗ ) D(c_{in} , c_{out} , \vec{k}, \vec{s}, \vec{p}) D(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 ) \vec{k} = (k, k, k) k=(k,k,k)。每个Convolutional Middle Layers依次应用3D卷积、BN层和 ReLU层。Convolutional Middle Layers在聚合体素特征过程中,逐渐扩展感受野,并增加更多的上下文特征来描述点云形状。
2.1.3 Region Proposal Network
最近,RPN 已成为性能最佳的对象检测框架的重要组成部分。在这项工作中,我们对RPN 架构进行了几项关键修改,并将其与特征学习网络和卷积中间层相结合,形成端到端的可训练管道。我们的 RPN 的输入是 Convolutional Middle Layers 提供的特征图。本文RPN的网络架构如图 4 所示。该网络具有三个完全卷积层块。每个块的第一层通过步长为 2 的卷积将特征图下采样一半,然后是步长为 1 的卷积序列(×q 表示滤波器的 q 次应用)。在每个卷积层之后,应用 BN 和 ReLU 操作。然后我们将每个完全卷积层块的输出上采样到固定大小,并连接以构建高分辨率特征图。最后,将该特征图映射到需要网络学习的目标:(1)概率分数特征图和(2)回归特征图。
图 4. RPN网络架构
2.2. Loss Function
检测框这里,本文设定了正样本框
N
p
o
s
N_{pos}
Npos和负样本框
N
n
e
g
N_{neg}
Nneg,并设定3D目标框为
(
x
c
g
,
y
c
g
,
z
c
g
,
l
g
,
w
g
,
h
g
,
θ
g
)
(x_c^g,y_c^g,z_c^g,l^g,w^g,h^g,\theta^g)
(xcg,ycg,zcg,lg,wg,hg,θg),分别表示物体中心、长宽高、绕Z轴旋转角度。为了使正样本框能够有效的回归到真实框,定义了残差向量u 包含了物体中心、长宽高、绕Z轴旋转角度7个量的变化值
Δ
\Delta
Δ。
Δ
x
=
x
c
g
−
x
c
a
d
a
,
Δ
y
=
y
c
g
−
y
c
a
d
a
,
Δ
z
=
z
c
g
−
z
c
a
h
a
Δ
l
=
log
(
l
g
l
a
)
,
Δ
w
=
log
(
w
g
w
a
)
,
Δ
h
=
log
(
h
g
h
a
)
,
Δ
θ
=
θ
g
−
θ
a
\begin{aligned}\Delta x =\frac{x_{c}^{g}-x_{c}^{a}}{d^{a}}, \Delta y=\frac{y_{c}^{g}-y_{c}^{a}}{d^{a}}, \Delta z=\frac{z_{c}^{g}-z_{c}^{a}}{h^{a}} \Delta l=\log \left(\frac{l^{g}}{l^{a}}\right),\Delta w=\log \left(\frac{w^{g}}{w^{a}}\right), \Delta h=\log \left(\frac{h^{g}}{h^{a}}\right), \Delta \theta=\theta^{g}-\theta^{a} \end{aligned} \quad\quad \quad
Δx=daxcg−xca,Δy=daycg−yca,Δz=hazcg−zcaΔl=log(lalg),Δw=log(wawg),Δh=log(hahg),Δθ=θg−θa
d a = ( l a ) 2 + ( w a ) 2 d^{a}=\sqrt{\left(l^{a}\right)^{2}+\left(w^{a}\right)^{2}} da=(la)2+(wa)2,其中 d 是锚盒底部的对角线。在这里,我们的目标是直接估计定向的 3D 框,并使用对角线 d 均匀地归一化 Δ x \Delta x Δx 和 Δ y \Delta y Δy ,
L = α 1 N p o s ∑ i L c l s ( p i p o s , 1 ) + β 1 N n e g ∑ j L c l s ( p j n e g , 0 ) + 1 N p o s ∑ i L r e g ( u i , u i ∗ ) \begin{aligned}L=\alpha \frac{1}{N_{\mathrm{pos}}} \sum_{i} L_{\mathrm{cls}}\left(p_{i}^{\mathrm{pos}}, 1\right)+\beta \frac{1}{N_{\mathrm{neg}}} \sum_{j} L_{\mathrm{cls}}\left(p_{j}^{\mathrm{neg}}, 0\right)+ \frac{1}{N_{\mathrm{pos}}} \sum_{i} L_{\mathrm{reg}}\left(\mathbf{u}_{i}, \mathbf{u}_{i}^{*}\right) \end{aligned} \quad\quad \quad L=αNpos1i∑Lcls(pipos,1)+βNneg1j∑Lcls(pjneg,0)+Npos1i∑Lreg(ui,ui∗)
L c l s L_{cls} Lcls 本质上是个二分类交叉熵损失函数: L c l s ( p i , p i ∗ ) = l o g [ p i × p i ∗ + ( 1 − p i ∗ ) ( 1 − p i ) ] L_{cls}(p_i,p_i^*)=log[p_i\times p_i^*+(1-p_i^*)(1-p_i)] Lcls(pi,pi∗)=log[pi×pi∗+(1−pi∗)(1−pi)], L c l s L_{cls} Lcls中的 p i ∗ p_i^* pi∗ 表示产生的anchor是否有物体,有为1,没有为0。
p i p_i pi分别表示正负预测框经过 s o f t m a x softmax softmax的概率值,。 u i u_i ui和表示网络的回归输出、 u i ∗ u_i^* ui∗表示正样本框与GT的计算值,(意味着网络本身在推理物体的位置偏差而不是具体位置,并在Loss计算时用正样本与真实框的偏差作为GT)。前两项是正负样本的归一化分类损失,因此使用交叉熵损失BCE, α \alpha α 和 β \beta β 是平衡常数。最后的位置回归使用SmoothL1函数。
2.3 高效实现
GPU 处理点云的问题是:1)点云在空间上稀疏分布,2)每个体素都有可变数量的点。因此,我们设计了一种将点云转换为密集张量的方法,这种张量可以被GPU并行处理,其中堆叠VFE层操作完成了点云到体素特征的转换。
图5 高效实施示意图
初始化一个 K × T × 7 维的tensor,用来存储 Voxel Feature ,K表示非空体素的数量,T是每个体素的最大点数,7是每个点编码的特征维度。对于点云中任意一个点去查找它所在的voxel是否初始化,如果已经初始化了就检查是否大于T个点,如果没有就添加该点,否则舍弃该点。如果这个voxel没有初始化,就初始化一个voxel,将其坐标存储在voxel buffer中,并将该点插入到该体素位置。建立了input buffer之后,堆叠的VFE仅涉及点级别和voxel级别密集操作,该操作可以在GPU上并行计算。在VFE中的concate之后,把没有点的特征再次设置为0。使用存储的坐标缓冲区,将计算的稀疏体素结构重新组织到密集体素网格。
构建体素输入缓冲区后,堆叠VFE仅涉及点级和体素级密集操作,可在GPU上并行计算。请注意,在VFE中的连接操作之后,我们将对应于空点的特征重置为零,这样它们就不会影响计算的体素特征。最后,使用存储的坐标缓冲区,我们将计算的稀疏体素结构重新组织到密集体素网格。以下卷积中间层和RPN操作在密集体素网格上工作,可以在GPU上有效实现。
3.训练细节
在本节中,我们将解释VoxelNet的实现细节和训练过程。
3.1.网络细节
我们的实验设置基于KITTI数据集的LiDAR规范。
汽车检测 对于此任务,我们分别考虑沿Z、Y、X轴在
[
−
3
,
1
]
×
[
−
40
,
40
]
×
[
0
,
70.4
]
[-3,1] \times[-40,40] \times[0,70.4]
[−3,1]×[−40,40]×[0,70.4]米范围内的点云。投影在图像边界之外的点被移除。我们选择
v
D
=
0.4
,
v
H
=
0.2
,
v
W
=
0.2
v_{D}=0.4, v_{H}=0.2, v_{W}=0.2
vD=0.4,vH=0.2,vW=0.2米的体素大小,这导致
D
′
=
10
,
H
′
=
400
,
W
′
=
352
D′=10,H′=400,W′=352
D′=10,H′=400,W′=352。我们将 T = 35 设置为每个非空体素中随机采样点的最大数量。我们使用两个VFE层
V
F
E
−
1
(
7
,
32
)
VFE-1(7,32)
VFE−1(7,32)和
V
F
E
−
2
(
32
,
128
)
VFE-2(32,128)
VFE−2(32,128)。最终的FCN将VFE-2输出映射到
R
128
\mathbb{R}^{128}
R128的128维的特征空间。因此,我们的特征学习网络生成了一个形状为
128
×
10
×
400
×
352
128 × 10 × 400 × 352
128×10×400×352的稀疏张量
为了聚和体素的特征,我们使用了三个中间卷积层,依次为:
C
o
n
v
3
D
(
128
,
64
,
3
,
(
2
,
1
,
1
)
,
(
1
,
1
,
1
)
)
Conv3D(128,64,3,(2,1,1),(1,1,1))
Conv3D(128,64,3,(2,1,1),(1,1,1))
C
o
n
v
3
D
(
64
,
64
,
3
,
(
1
,
1
,
1
)
,
(
0
,
1
,
1
)
)
Conv3D(\space\space64, 64,3,(1,1,1),(0,1,1))
Conv3D( 64,64,3,(1,1,1),(0,1,1))
C
o
n
v
3
D
(
128
,
64
,
3
,
(
2
,
1
,
1
)
,
(
1
,
1
,
1
)
)
Conv3D(128,64,3,(2,1,1),(1,1,1))
Conv3D(128,64,3,(2,1,1),(1,1,1))
最终生成一个
64
×
2
×
400
×
352
64 × 2 × 400 × 352
64×2×400×352的张量,进一步经过维度转换,生成
128
×
400
×
352
128× 400 × 352
128×400×352的张量输入到RPN网络,其中尺寸对应于3D张量的通道、高度和宽度。图4说明了此任务的详细网络架构,我们仅使用一种锚尺寸
l
a
=
3.9
,
w
a
=
1.6
,
h
a
=
1.56
l^a=3.9,w^a=1.6,h^a=1.56
la=3.9,wa=1.6,ha=1.56, 以
z
c
a
=
−
1.0
z_{c}^{a}=-1.0
zca=−1.0米为中心,旋转两次,0度和90度。我们的
a
n
c
h
o
r
anchor
anchor匹配标准如下:如果
a
n
c
h
o
r
anchor
anchor具有与ground truth的最高IoU或者其与ground truth的IoU高于0.6(鸟瞰视图),则
a
n
c
h
o
r
anchor
anchor被认为positive。如果
a
n
c
h
o
r
anchor
anchor和所有ground truth框之间的IoU小于0.45,则
a
n
c
h
o
r
anchor
anchor被认为是negative。如果他们在区间0.45≤IoU≤0.6的任何ground truth,我们把
a
n
c
h
o
r
anchor
anchor忽略。我们在公式2中设置
α
=
1.5
\alpha=1.5
α=1.5和
β
=
1
\beta=1
β=1
在训练期间,我们使用随机梯度下降(SGD),前150个epoch的学习率为0.01,最后10个epoch的学习率降低到0.001。我们使用16个点云的批大小。
3.2.数据增强
在少于4000个训练点云的情况下,从头开始训练我们的网络将不可避免地遭受过拟合。为了减少这个问题,我们引入了三种不同形式的数据增强。增强的训练数据是即时生成的,无需存储在磁盘上
第一种形式的数据增强,将扰动独立地应用于每个ground truth 3D边界框以及框内的那些LiDAR点。具体来说,围绕Z轴,我们通过均匀分布的随机变量 Δ θ ∈ [ − π / 10 , + π / 10 ] \Delta \theta \in[-\pi / 10,+\pi / 10] Δθ∈[−π/10,+π/10]相对于 ( x c , y c , z c ) \left(x_{c}, y_{c}, z_{c}\right) (xc,yc,zc)旋转 b i \mathbf{b}_{i} bi和相关的 Ω i \Omega_{i} Ωi。然后我们将平移(Δx, Δy, Δz)添加到 b i \mathbf{b}_{i} bi的XYZ分量和 Ω i \Omega_{i} Ωi中的每个点,其中Δx、Δy、Δz独立于均值为零和标准差1.0的高斯分布。为了避免物理上不可能的结果,我们在扰动后在任何两个框碰撞测试,如果检测到碰撞,则恢复到原始状态。由于扰动被独立地应用于每个ground truth框和相关联的激光雷达点,网络能够从比原始训练数据多得多的变化中学习。
其次,我们将全局缩放应用于所有ground truth框 b i \mathbf{b}_{i} bi和整个点云M。具体来说,我们将每个 b i \mathbf{b}_{i} bi 的XYZ坐标和三维,以及M中所有点的XYZ坐标与从均匀分布[0.95,1.05]中抽取的随机变量相乘。如基于图像的分类和检测任务所示,引入全局尺度增强提高了用于检测具有各种尺寸和距离的物体的网络的鲁棒性。
最后,我们将全局旋转应用于所有ground truth框 b i \mathbf{b}_{i} bi和整个点云M。旋转沿Z轴和(0,0,0)周围应用。全局旋转偏移量是通过从均匀分布 [ − π / 4 , + π / 4 ] [-\pi / 4,+\pi / 4] [−π/4,+π/4]中采样确定的。通过旋转整个点云,我们模拟车辆转弯。