ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

2020年CVPR 3D点云研究全景:从PointNet到Transformer的架构演进与实操指南

2020年CVPR 3D点云研究全景:从PointNet到Transformer的架构演进与实操指南

1. 为什么值得系统梳理3D点云研究

3D点云这个方向,从2017年前后开始升温,到2020年CVPR的时候已经到了一个相当密集的爆发期。我当时正好在做自动驾驶感知相关的项目,需要系统性地摸一遍当年顶会上的点云论文,看看哪些思路能落地、哪些只是刷榜。说实话,一开始我是按关键词一篇篇搜的,效率极低,后来逼着自己做了一次完整的分类梳理,才发现这里面其实有很清晰的几条技术脉络。

点云和图像最大的不同在于它的无序性、稀疏性和旋转不变性要求。图像是规整的网格,卷积核滑过去就行;点云是一堆散落的(x, y, z)坐标,可能还带强度、法向量、颜色等特征,数量从几千到几十万不等,而且同一个物体换个角度扫描,点的排列顺序完全变了。这就导致直接把2D卷积那套搬过来根本行不通。2020年CVPR上关于点云的工作,本质上都在回答一个问题:如何设计一种既能处理无序集合、又能捕捉局部几何结构、还能扛住旋转和稀疏的网络架构。

这篇总结适合谁看?如果你刚接触点云,想快速建立对整个领域技术版图的认知,那这篇能帮你省掉大量翻论文的时间;如果你已经在做相关项目,想看看当年有哪些被验证有效的设计思路可以借鉴到自己的模型里,那这篇里的方法拆解和实操心得应该对你有用。我会尽量把每个方法的核心动机、关键设计、适用场景和踩坑点讲清楚,而不是只罗列论文标题。

需要提前说明的是,我下面提到的所有方法名和实验数据,都是基于当年公开论文的常见实践总结,具体复现时你还需要结合自己的数据集和任务做调整。点云这个领域迭代很快,2020年的很多思路到今天已经有了演进版本,但底层的问题定义和设计哲学变化不大,所以这份梳理依然有参考价值。

2. 2020年点云研究的四条主线

2.1 从PointNet到点云Transformer的架构演进

2017年的PointNet是点云深度学习的开山之作,它用对称函数(max pooling)解决了无序性问题,但致命缺陷是没有局部特征聚合——每个点独立过MLP,然后全局池化,相当于只学了全局形状,局部细节全丢了。PointNet++用最远点采样加球查询构建了层次化的局部区域,算是补上了这一课。但到了2020年,大家发现这套基于采样和分组的方法有两个硬伤:一是采样本身不可学习,最远点采样是纯几何的,跟任务无关;二是分组后的局部特征提取仍然依赖手工设计的半径参数,不同尺度的物体需要不同的半径,调参成本很高。

CVPR2020上有一批工作试图用可学习的采样和分组来替代手工设计。比如有的方法用Gumbel Softmax做可微的点的选择,让网络自己决定哪些点值得保留;有的方法用注意力机制动态聚合邻域特征,不再固定半径。这些思路的共同点是把归纳偏置从手工规则转移到数据驱动,理论上限更高,但代价是训练更不稳定、对数据量要求更大。

另一条更激进的路线是直接用Transformer处理点云。Transformer的自注意力机制天然适合无序集合,因为它的输出对输入顺序不敏感(只要加上位置编码)。但点云的规模动辄几万个点,标准自注意力的O(N²)复杂度根本扛不住。所以2020年的点云Transformer工作,核心创新基本都在如何降低注意力复杂度或者如何设计适合点云的局部注意力窗口。有的用KNN构建局部图,只在邻域内做注意力;有的用随机采样加全局token来近似全注意力。这些方法在分类和分割任务上确实刷出了更高的精度,但推理速度普遍比PointNet++慢一个数量级,落地时得权衡。

2.2 单帧检测与多帧融合的路线之争

3D目标检测是点云最核心的下游任务之一,2020年CVPR上这个方向的工作特别多。当时主要有两条技术路线:单帧检测和多帧融合。

单帧检测的代表作是各种基于BEV(鸟瞰图)的方法。思路很直接:把点云投影到鸟瞰平面,变成2D图像,然后用成熟的2D检测框架去处理。这样做的好处是计算效率高,因为2D卷积比3D卷积快得多;缺点是高度信息被压缩了,对于重叠物体或者高度差异大的场景,区分度不够。另一类单帧方法是直接在3D空间做检测,比如用3D稀疏卷积提取体素特征,然后接检测头。稀疏卷积的好处是只在前景点上计算,不浪费算力在空体素上,但实现复杂度高,对稀疏模式的设计很敏感。

多帧融合的思路是把连续几帧的点云对齐后拼接起来,增加点的密度和覆盖范围。理论上信息更多,检测应该更准,但实际做起来有两个大坑:一是运动物体的对齐误差,如果自车在动,静态背景对齐了,动态物体就糊了;二是点云数量暴增导致显存爆炸,几帧拼起来可能十几万个点,训练时batch size只能降到1。2020年有几篇工作专门解决这些问题,比如用运动补偿来对齐动态物体,或者用注意力机制让网络自己学习哪些帧的哪些区域该保留。实测下来,多帧融合在行人检测这种小目标上提升明显,但在车辆检测上提升有限,因为车辆本身点就够多了。

2.3 自监督与弱监督的崛起

标注3D点云数据太贵了。一张图像标注可能几块钱,一帧点云标注可能要几十块,因为标注员需要在3D空间里旋转、缩放、框选,效率极低。所以2020年CVPR上自监督和弱监督的点云工作明显增多。

自监督的核心思路是设计 pretext task,让网络从无标注数据里学有用的表示。常见的有:点云补全(挖掉一块让网络补)、点云去噪(加点噪声让网络还原)、对比学习(同一个物体的不同视角/不同采样应该特征相近)。这些任务本身不是最终目标,但训练出来的backbone迁移到检测或分割任务上时,往往比从头训练效果好,尤其是在标注数据少的情况下。

弱监督则是用少量标注或者粗标注来训练。比如只有3D框的中心点标注,没有完整框;或者只有2D框标注,没有3D框。2020年有工作用2D检测结果投影到3D空间来生成伪标签,再用伪标签训练3D检测器,迭代几轮后效果接近全监督。这条路线的价值在于大幅降低标注成本,但伪标签的噪声会累积,需要设计鲁棒的损失函数来抑制。

2.4 点云补全与生成的质量提升

点云补全的任务是给定部分点云,预测完整形状。这在自动驾驶和机器人抓取里很有用,因为传感器只能看到物体的一面,背面是缺失的。2020年CVPR上的补全工作,主流框架是编码器-解码器结构:编码器把部分点云压成隐向量,解码器从隐向量生成完整点云。关键难点在于如何保证生成的点云既完整又保细节。

早期方法直接用全连接层回归所有点的坐标,结果就是生成的点云糊成一团,细节全丢。2020年的改进主要有两个方向:一是用Transformer做解码器,因为自注意力能捕捉点之间的长程依赖,生成的点分布更均匀;二是引入对抗训练,用判别器区分生成点云和真实点云,逼着生成器提升细节质量。实测下来,对抗训练确实能让点云看起来更“锐利”,但训练不稳定,判别器和生成器的平衡很难调,经常出现模式崩溃——生成器只生成几种固定形状,多样性没了。

另一个值得关注的方向是基于隐式函数的补全。不直接生成点坐标,而是学一个占用函数或符号距离函数,输入任意坐标输出该点是否在物体内部。这样做的好处是分辨率可以任意高,因为函数是连续的,想采多少点就采多少点。但缺点是推理慢,每采一个点都要过一遍网络,实时性差。

3. 核心方法拆解与实操要点

3.1 局部特征聚合的三种设计范式

点云网络的核心是如何聚合局部邻域的特征。2020年CVPR上的方法基本可以归为三类:

第一类是基于图的方法。把每个点看作图的节点,KNN构建边,然后在边上做卷积或注意力。代表工作是DGCNN的后续改进版。这类方法的优势是灵活,图的拓扑可以动态调整;缺点是KNN构建图本身耗时,而且对K的选择敏感——K太小感受野不够,K太大计算量爆炸。我实测下来,K=20到30在大多数场景下比较平衡,但具体还得看点云密度。

第二类是基于连续卷积的方法。不把点云离散成体素或图,而是定义连续卷积核,在任意空间位置都能计算卷积响应。比如用MLP学一个权重函数,输入是邻域点相对于中心点的坐标差,输出是权重。这类方法的优势是对点云密度变化鲁棒,因为卷积核是连续的;缺点是权重函数的设计很关键,设计不好容易过拟合。

第三类是基于注意力机制的方法。用自注意力或交叉注意力来聚合邻域特征,权重由数据驱动。这类方法在2020年很火,因为Transformer在NLP和2D视觉里的成功让大家觉得它也能搞定点云。但点云的注意力有两个特殊问题:一是位置编码怎么设计,2D图像用正弦编码就行,点云得考虑3D几何关系;二是计算复杂度,全注意力O(N²)在几万个点上根本跑不动,必须做局部注意力或稀疏注意力。

实操心得:如果你刚入门,建议先从PointNet++的代码跑通,理解采样-分组-特征提取的流程,然后再去看基于图或注意力的方法。直接上Transformer很容易被各种实现细节劝退。

3.2 3D检测中的锚框设计与回归损失

3D检测和2D检测最大的区别在于锚框的设计。2D检测的锚框是矩形,只有宽高和中心点;3D检测的锚框是长方体,有长宽高、中心点、朝向角,有的还带速度。维度多了,锚框的数量就爆炸了。比如2D检测可能9个锚框就够了,3D检测可能要几十个甚至上百个。

2020年CVPR上的3D检测工作,在锚框设计上主要有两种思路:基于锚框和无锚框。基于锚框的方法沿袭2D检测的套路,在每个BEV网格上预设不同尺寸和朝向的锚框,然后回归偏移量。无锚框的方法则直接预测每个点或每个体素到框中心的距离和框的尺寸,省去了锚框设计。无锚框的好处是超参数少,不用调锚框的尺寸和数量;缺点是正负样本分配策略很关键,分配不好容易导致正样本太少、训练不收敛。

回归损失方面,3D检测比2D多了一个朝向角回归。朝向角有个特殊问题:周期性。比如角度0度和360度是一样的,但直接回归数值的话,网络会认为它们差很远。所以2020年的工作普遍用正弦-余弦编码来表示角度,或者用分类加回归的混合方式——先把角度分成几个bin,分类预测在哪个bin,再回归bin内的偏移。实测下来,正弦-余弦编码实现简单,效果也稳定,推荐优先尝试。

3.3 点云补全的解码器选型对比

点云补全的解码器设计直接决定了生成质量。2020年主流的有三种:

解码器类型核心思路优点缺点适用场景
全连接回归直接回归所有点坐标实现简单,推理快点云糊,细节差对细节要求不高的场景
折叠式从2D网格折叠成3D点云点分布均匀,细节较好折叠次数需调参中等精度要求的补全
Transformer自注意力生成点细节好,多样性高推理慢,训练不稳定高精度离线补全

我个人的经验是,如果做实时补全(比如机器人抓取),全连接回归加一个Chamfer Distance损失就够了,虽然糊但速度快;如果做离线高质量补全(比如文物数字化),Transformer加对抗训练效果最好,但得做好训练几天不收敛的心理准备。折叠式是个折中方案,适合大多数场景。

注意事项:Chamfer Distance是点云补全最常用的损失函数,但它有个问题——对异常值敏感。如果生成的点云里有个别点飞得很远,CD损失会很大,导致网络过度惩罚这些点而忽略整体形状。实践中可以加一个截断CD,超过一定距离的就不算损失,或者用Earth Mover's Distance替代,但EMD计算更慢。

3.4 自监督预训练的任务设计技巧

自监督预训练的效果很大程度上取决于pretext task的设计。2020年CVPR上的点云自监督工作,常用的pretext task有:

  • 点云补全:随机挖掉一块,让网络补全。这个任务和下游的检测/分割相关性高,因为都要求理解局部几何。
  • 点云去噪:给点云加高斯噪声,让网络还原干净点云。这个任务能学到鲁棒的局部特征。
  • 对比学习:同一个物体的不同视角或不同采样作为正样本,不同物体作为负样本,用InfoNCE损失拉近正样本、推开负样本。
  • 旋转预测:把点云旋转一个角度,让网络预测旋转了多少。这个任务能学到旋转不变的特征。

实测下来,对比学习加补全的组合效果最好,因为对比学习学全局表示,补全学局部细节,两者互补。但对比学习对数据增强很敏感,增强太弱学不到不变性,增强太强正样本对都认不出来了。我的经验是随机旋转加随机缩放作为增强比较稳,随机裁剪要慎用,因为裁得太狠正样本就完全不像了。

4. 完整实操流程:从数据准备到模型评估

4.1 数据预处理与增强策略

点云数据预处理的第一个问题是坐标归一化。不同数据集的坐标范围差异很大,有的用米,有的用厘米,有的干脆是归一化到[-1, 1]。如果不做统一,网络很难收敛。我的做法是把所有点云减去质心,然后除以最大半径,这样所有点云都在单位球内,尺度一致。

第二个问题是点云采样。原始点云可能几十万个点,直接训练显存扛不住。常用的采样方法有随机采样、最远点采样和体素采样。随机采样最快但可能漏掉关键点;最远点采样覆盖均匀但O(N²)太慢;体素采样是折中,先划分体素再在每个体素里随机选一个点。我一般用体素采样加随机采样的组合:先体素下采样到几万个点,再随机采样到网络需要的数量。

数据增强方面,点云常用的有:

  • 随机旋转:绕Z轴旋转,模拟不同朝向。注意不要绕X或Y轴大角度旋转,因为地面物体的朝向通常只在水平面变化。
  • 随机平移:在[-0.2, 0.2]米范围内平移,模拟定位误差。
  • 随机缩放:在[0.9, 1.1]范围内缩放,模拟不同大小的物体。
  • 随机丢弃:随机丢掉一定比例的点,模拟遮挡和稀疏。
  • MixUp:把两个点云按一定比例混合,标签也按比例混合。这个在3D检测里效果不错,能提升鲁棒性。

实操心得:数据增强不是越多越好。我试过同时加旋转、平移、缩放、丢弃、MixUp,结果训练损失震荡得厉害,最后精度还不如只加旋转和平移。建议一次加两三种,根据验证集效果逐步调整。

4.2 模型搭建与关键参数配置

以3D检测为例,一个典型的训练配置如下:

# 优化器配置 optimizer = AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4) scheduler = CosineAnnealingLR(optimizer, T_max=100, eta_min=1e-6) # 数据加载 batch_size = 4 # 点云显存占用大,batch size通常很小 num_workers = 8 prefetch_factor = 2 # 训练轮次 epochs = 100 warmup_epochs = 5 # 前5轮线性预热,防止初期梯度爆炸 # 损失权重 loss_weights = { 'cls_loss': 1.0, # 分类损失 'reg_loss': 2.0, # 回归损失,权重通常比分类大 'dir_loss': 0.5, # 朝向损失 }

关键参数里,学习率是最需要调的。点云网络对学习率很敏感,太大容易梯度爆炸,太小收敛慢。我的经验是从1e-3开始试,如果损失震荡就降到5e-4,如果收敛太慢就升到2e-3。权重衰减一般设1e-4到1e-5,太大欠拟合,太小过拟合。Batch size受显存限制,通常只能设2到8,这时候可以用梯度累积来模拟大batch——比如累积4步再更新一次参数,等效batch size就是原来的4倍。

4.3 训练过程监控与调优

训练点云模型时,我重点监控三个指标:总损失、验证集精度和学习率。总损失下降但验证集精度不升,说明过拟合了,得加正则或减模型容量;总损失震荡,说明学习率太大或batch size太小;验证集精度突然掉,可能是遇到了坏数据或梯度爆炸。

调优的顺序一般是:先调学习率,找到使损失下降最快的值;再调数据增强,看验证集精度能不能再提;最后调模型结构,比如加宽网络或加深层数。不要一上来就改模型结构,因为结构改动的影响往往不如学习率和数据增强大。

常见坑:点云训练里BatchNorm经常出问题,因为batch size太小,统计量估计不准。建议用GroupNorm或LayerNorm替代,实测更稳定。另外,Dropout在点云网络里效果一般,因为点云本身就有稀疏性,再Dropout容易丢关键信息。

4.4 评估指标解读与结果分析

3D检测的评估指标主要是mAP(mean Average Precision),但和2D不同的是,3D的IoU计算要考虑朝向角。如果预测框和真实框的朝向差超过一定阈值(比如π/6),即使位置和尺寸都对,IoU也会很低。所以看mAP的时候要分难度级别看——简单、中等、困难,困难级别的mAP更能反映模型的鲁棒性。

点云分割的评估指标是mIoU(mean Intersection over Union),计算每个类别的IoU再平均。这里有个坑:类别不平衡。比如自动驾驶场景里,道路和建筑的点很多,行人和自行车的点很少,如果直接平均,少数类的IoU会被多数类淹没。所以要看每类的IoU,特别关注少数类。

点云补全的评估指标是Chamfer Distance和Earth Mover's Distance。CD衡量生成点云和真实点云的平均最近邻距离,EMD衡量把生成点云“搬”成真实点云的最小代价。CD对异常值敏感,EMD对整体分布更敏感。两个指标要一起看,CD低但EMD高,说明生成的点云有局部飞点;CD高但EMD低,说明整体形状对但细节不够。

5. 常见问题与排查技巧实录

5.1 训练不收敛的排查清单

点云模型训练不收敛是新手最常遇到的问题。我整理了一个排查清单,按优先级排序:

问题现象可能原因排查方法解决方案
损失一直是NaN学习率太大或数据有NaN打印每步损失和数据范围降学习率,检查数据预处理
损失下降但很慢学习率太小或模型容量不够看梯度范数升学习率,加宽网络
损失震荡batch size太小或学习率太大看损失曲线梯度累积,降学习率
验证集精度不升过拟合或数据增强太强对比训练和验证损失加正则,减增强
某些类别精度极低类别不平衡看每类IoU加类别权重,重采样

我踩过最坑的一次是数据里有NaN,因为点云文件里有些点的坐标是inf,预处理时没检查,结果训练到一半损失突然变NaN。后来养成了习惯,预处理后一定要检查数据范围,用np.isfinite()过滤掉非法值。

5.2 显存不足的优化手段

点云模型显存占用大,尤其是3D检测和补全。如果显存不够,可以按以下顺序尝试:

  1. 减小batch size:最直接,但可能影响BatchNorm,建议换GroupNorm。
  2. 降低点云数量:从几万个点降到几千个,但可能丢细节。
  3. 用混合精度训练:torch.cuda.amp能省30%到50%显存,几乎不影响精度。
  4. 梯度检查点:torch.utils.checkpoint用时间换显存,适合深层网络。
  5. 模型并行:把不同层放到不同GPU上,实现复杂但能训超大模型。

实操心得:混合精度训练是性价比最高的,几乎无脑开。但要注意损失缩放,因为FP16的表示范围小,梯度容易下溢。PyTorch的GradScaler会自动处理,但偶尔还是会出现NaN,这时候可以调大初始缩放因子。

5.3 推理速度优化的实战技巧

点云模型推理慢是落地的大障碍。优化手段主要有:

  • 模型剪枝:去掉不重要的通道或层,能提速2到3倍,但精度可能掉1到2个点。
  • 量化:把FP32转成INT8,提速2到4倍,精度掉得不多,但需要校准数据。
  • TensorRT部署:针对特定硬件优化,提速明显,但转换过程可能遇到不支持的算子。
  • KNN加速:KNN是点云网络里最耗时的操作之一,用FAISS或cuML替代原生实现,能快5到10倍。

我实测下来,KNN加速加混合精度是最容易落地的组合,几乎不改模型结构,推理速度就能翻倍。TensorRT效果更好但坑也多,尤其是自定义算子多的模型,转换经常失败。

5.4 跨数据集泛化的避坑经验

在一个数据集上训好的模型,换到另一个数据集上精度暴跌,这是点云领域的常见问题。原因主要有三个:点云密度不同、传感器类型不同、标注标准不同。

解决思路有:

  • 密度归一化:推理前把点云采样到和训练集相似的密度。
  • 域自适应:用对抗训练让特征在不同域之间对齐。
  • 数据增强:训练时模拟不同密度和噪声,提升鲁棒性。
  • 微调:在目标域上少量标注数据微调,效果最好但需要标注。

我的经验是,如果目标域和源域差异不大(比如都是激光雷达,只是不同品牌),密度归一化加数据增强就够了;如果差异很大(比如激光雷达换深度相机),必须做域自适应或微调,否则精度没法看。

6. 从2020年看后续技术走向

2020年CVPR的点云工作,本质上是在手工设计和数据驱动之间找平衡。PointNet++那套采样-分组-提取的流程,虽然手工设计的成分多,但胜在稳定、可解释、易调试;Transformer那套全数据驱动的思路,理论上限高,但训练成本大、调参难。后来的发展也印证了这一点——纯Transformer的点云模型在2021年后逐渐成熟,但工业界落地时,很多还是用PointNet++的变体,因为稳定比极限精度更重要。

另一个明显的趋势是多模态融合。2020年已经有工作把点云和图像结合起来做检测,用图像提供纹理和语义,用点云提供几何和深度。这个方向后来成了主流,因为单一模态的信息总有盲区。如果你现在做点云相关项目,我建议至少了解一下图像和点云的融合方法,哪怕暂时不用,也能帮你理解点云在整个感知系统里的位置。

最后说一个我自己的体会:点云这个领域,论文里的方法和实际能用的方法之间有很大差距。论文追求的是在标准数据集上刷SOTA,实际项目追求的是在特定场景下稳定运行。我见过太多论文里精度很高但推理要几秒的方法,根本没法上车。所以看论文的时候,除了看精度,一定要看推理速度、显存占用、对超参数的敏感度,这些才是决定能不能落地的关键。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进