当前, 有很多voxel-based的单阶段3D检测器, 然而point-based的单阶段3D检测器仍处于探索中。本文中, 我们第一个提出了一个轻量级的, 高效的point-based的单阶段检测器 (3DSSD), 并在精度和效率方面取得了一个很好的平衡。在这种范式中, 丢弃了现有point-based方法中不可或缺的upsampling layers和refinement stage, 以减少大量的计算成本。我们新颖地提出了用于下采样流程的混合采样策略, 以实现在更少的点上进行检测。为了满足精度和速度的要求, 一个优美的box预测网络被提出, 该box预测网络包括候选点生成层, anchor-free的回归头和具有3D center-ness分配策略。我们的范式是一个优雅的单阶段的anchor-free的框架, 与现有其它方法相比展现出巨大优势。我们在KITTI和nuScenes上评估了3DSSD。3DSSD远超所有voxel-based的单阶段方法, 和2阶段的point-based的方法具有相当的性能, 推理速度超过25FPS, 比以前SOTA的point-based的方法快2倍多。
在点云中做检测, 主要有两种处理点云的方式: voxel-based和point-based。Voxel-based方法由于会导致信息损失, 因此本文主要是针对point-based方法中的一些问题。Point-based的检测方法主要包括两个阶段: (1) 提取点云的特征, 并使用RPN在每个点处生成候选框; 提取点云特征一般设计点云下采样和使用特征传播(feature propagation, FP)进行上采样; (2) Refiment 模块, 主要是对框的进行优化和分类。Point-based的方法往往推理时间比较长。
作者观察到Point-based方法中, FP层和Refiment模块占据了一半的推理时间, 如Table 1所示。但移去这两个模块并不简单。接下来看看作者是怎么思考和解决这个问题的 ?
在点云下采样(FPS等)过程中, 一些前景实例会丢弃不少的点或全部的点, 而FP层是用来恢复这些因下采样丢失的点。为说明这个情况, 作者还统计了在下采样过程中没有丢失的候选框(若候选框中有前景点在该下采样的点云, 则表示该候选框没有丢失)的比例, 如Table 2所示。为了区分作者后面提出的F-FPS (Feature-FPS), 作者这里用D-FPS表示常用的在3D距离空间中的FPS。可以看到当, 当下采样到1024和512个点时, 有35-48%bboxes中点丢失。因此若丢失FP层, 将会导致一些bboxes不能被检测到, 带来性能的下降。
因此, 为移去FP层, 提出了F-FPS, 结合特征空间和距离空间进行点云下采样, 同时提出Fusion Sampling, 来保存更多的前景点和一定数量的背景点。另外, 作者提出了一个精美的bbox预测网络, 使得3DSSD更加地有效和高效。基于此, 作者提出的3DSSD在精度上远超voxel-based单阶段的3D检测器, 和2阶段的point-based方法性能不相上下, 但具有更快的推理速度。
Feature-FPS
作者基于 ( x , y , z ) (x, y, z) (x,y,z)距离空间 L d ( A , B ) L_d(A, B) Ld(A,B)和特征空间距离 L f ( A , B ) L_f(A, B) Lf(A,B)来进行FPS, 即:
C ( A , B ) = λ L d ( A , B ) + L f ( A , B ) , C(A, B) = \lambda L_d(A, B) + L_f(A, B), C(A,B)=λLd(A,B)+Lf(A,B),
λ \lambda λ是平衡因子。作者把这种采样方法称为Feature-FPS (F-FPS)。 λ \lambda λ取不同的值的结果如Table 2所示, 当 λ = 0 \lambda=0 λ=0时, 即只依赖于特征空间采样, 在1024和512个采样点时的points recall已明显高于D-FPS; 同时考虑空间距离和特征距离, 可以看到, points recall可以达到更高的值。 作者对这一现象进行了解释: 如果只依赖特征空间进行采样, 那么属于同一个instance的的多个点(如轮子和窗口上的点)会被采到, 带来了该instance的冗余; 为了增加多样性并使得采样的点尽量分散, 作者同时把空间距离考虑在内了, 就是现在的F-FPS。
Fusion Sampling
通过F-FPS, 大量的instances点被采样到, 看似得到了想要的结果。但这样会导致背景点的数量减少, 进一步导致通过邻域点聚合特征时找不到足够多的点, 影响了特征的表达和分类性能。因此, 在采样点时候, 不仅需要采样到足够的前景点, 而且需要一定数量的背景点来确保分类的正确性。作者提出了fusion sampling, 通过D-FPS和F-FPS分别采取相同数量的点, 作为新的采样点。
Candidate Generation Layer
首先, 根据F-FPS确定初始的seed points, 并采用可学习层进行shift, 使其靠近对应instances的中心, 生成candidates; 然后, 考虑一定邻域内的来自D-FPS和F-FPS的点, 进行group, MLP, MaxPooling, 学习每个candidate的特征。这样就得到了candidates点和特征, 如Figure 1(b)所示。
Anchore-free Regression Head
位置: 预测candidate点和对应instance的偏移量; 尺寸: 回归instance的(1/2)尺寸(太强了); 角度: 12分类问题和回归。
Candidate Label
和FCOS类似, 采用center-ness作为监督: (1) 当前candidate点是否在instance内的二值表示 ( l m a s k l_{mask} lmask); (2) 根据当前candidate点距离instance的平面的远近 l c t r n e s s l_{ctrness} lctrness, 越靠近instance中心, 其值越大。
l c t r n e s s = m i n ( f , b ) m a x ( f , b ) ⋅ m i n ( l , r ) m a x ( l , r ) ⋅ m i n ( t , d ) m a x ( t , d ) 3 , l_{ctrness} = \sqrt[3]{\frac {min(f, b)}{max(f, b)}\cdot \frac {min(l, r)}{max(l, r)} \cdot \frac {min(t, d)}{max(t, d)}}, lctrness=3max(f,b)min(f,b)⋅max(l,r)min(l,r)⋅max(t,d)min(t,d),
( f , b , l , r , t , d ) (f, b, l, r, t, d) (f,b,l,r,t,d)表示candidate point距离instance bbox前, 后, 左, 右, 上和下的距离。[第一次了解到label也能是小数, 如下示例]。
import torch
import torch.nn.functional as F
x = torch.randn(2, 3)
y = torch.tensor([[0, 0, 0.8], [0.7, 0.2, 0.5]])
loss1 = F.binary_cross_entropy_with_logits(x, y, reduction='none')
loss2 = -y * torch.log(torch.sigmoid(x)) - (1 - y) * torch.log(1-torch.sigmoid(x))
print(loss1)
print(loss2)
candidate points分类损失, bbox回归损失和candidate points shifting损失被考虑在内:
L = 1 N c ∑ i L c ( s i , u i ) + λ 1 1 N p ∑ i [ u i > 0 ] L r + λ 2 1 N p ∗ L s , L = \frac{1}{N_c}\sum_iL_c(s_i, u_i) + \lambda_1\frac{1}{N_p}\sum_i[u_i > 0]L_r + \lambda_2\frac{1}{N_p^*}L_s, L=Nc1i∑Lc(si,ui)+λ1Np1i∑[ui>0]Lr+λ2Np∗1Ls,
N c N_c Nc, N p N_p Np 和 N p ∗ N_p^* Np∗分别表示所有candidate points的数量, positive(位于前景instances) candidate points的数量和postive seed points的数量(一开始我误以为 N p N_p Np 和 N p ∗ N_p^* Np∗应该是一样的, 后来发现其考虑的对象是不一样的, 一个是初始的seed points, 一个是偏移后的seed points)。
Candidate point分类: L c L_c Lc表示交叉熵损失函数, s i s_i si和 u i u_i ui分别表示point i i i预测分类分数和GT center-ness值。
Box回归 L r L_r Lr: 包括位置(偏移量)和尺寸的回归, 角度的分类和残差项的回归。另外, 还包括8各顶点的回归(第一次遇到)。
Candidate points shifting: 回归seed points和instance中心之间偏移量。
在KITTI上的性能如Table 3所示, 3DSSD比单阶段的SECOND和PointPillars性能好3-5个点, 和SOTA的STD性能不相上下, 但速度更快一些, 比多传感器算法(F-PointNet, 如F-ConvNet)的性能也好一些。综上, PointPillars在KITTI的Car类别上基本实现了SOTA精度, 而且速度更快。
nuScenes数据集包括1000个场景, 10个类别。每帧大约40k点, 为了预测速率和属性, 常常把当前点云和最近0.5s内的点云合并, 因此得到包含400k的点云。使用voxel size=[0.1, 0.1, 0.1]进行下采样, 得到65536个voxels(16384来自于当前帧, 49152来自于其它帧), 每个voxel采样一个点, 得到65536个点的点云作为网络的输入。
另外, 在nuScenes数据集上新的评估指标NDS(nuScenes detection score)被提出, 它是mean average precision (mAP), mean average errors of location (mATE), size (mASE), oriention (mAOE), attribute (mAAE)和velocity (mAVE):
N D S = 1 10 [ 5 ⋅ m A P + ∑ m T P ∈ T P [ 1 − m i n ( 1 , m T P ) ] , NDS = \frac{1}{10}[5 \cdot mAP + \sum_{mTP \in TP}[1-min(1, mTP)], NDS=101[5⋅mAP+mTP∈TP∑[1−min(1,mTP)],
其中TP表示{ATE, ASE, AOE, AAE, AVE}。
实验结果如Table 4和Table 5所示, 3DSSD在mAP和NDS上明显高于PointPillars, 在各个类别的AP上都高于voxel-based方法 (SECODN和PointPillars)。作者这里只比较了voxel-based方法, 在论文中的解释是point-based的2阶段的检测算法弱于voxel-based的算法。
两个比较有意思的消融实验:
3DSSD的推理时间如Table 9所示, 其明显快于其它的point-based的方法; 和SECODN(40ms)旗鼓相当, 慢于PointPillars。