Pointnet++个人笔记
前言
Pointnet提取的全局特征能够很好地完成分类任务,由于网络将所有的点最大池化为了一个全局特征,因此局部点与点之间的联系并没有被网络学习到,导致网络的输出缺乏点云的局部结构特征,因此PointNet对于场景的分割效果十分一般。在点云分类和物体的Part Segmentation中,这样的问题可以通过中心化物体的坐标轴部分地解决,但在场景分割中很难去解决。
因此作者在此基础上又提出了能够实现点云作多层特征提取的Pointnet++网络,网络结构如下:
Qi et al. PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space. NIPS 2017.
网络的基本组成
下面介绍上图中的网络设计,传统的CNN在进行特征学习时,使用卷积核作为局部感受野,每层的卷积核共享权值,进过多层的特征学习,最后的输出会包含图像的局部特征信息。通过改变中借鉴CNN的采样思路,采取分层特征学习,即在小区域中使用点采样+成组+提取局部特征(S+G+P)的方式,包含这三部分的机构称为Set Abstraction。
- Sampling:利用FPS(最远点采样)随机采样点;
- Grouping:利用Ball Query划一个R为半径的圈,将每个圈里面的点云作为一簇;
- Pointnet: 对Sampling+Grouping以后的点云进行局部的全局特征提取。
以2D点图为例,整个SA(Set Abstraction)三步的实现过程表示如下:
每层新的中心点都是从上一层抽取的特征子集,中心点的个数就是成组的点集数,随着层数增加,中心点的个数也会逐渐降低,抽取到点云的局部结构特征。
## 针对非均匀点云情况
当点云不均匀时,每个子区域中如果在分区的时候使用相同的球半径,会导致部分稀疏区域采样点过小。
文中提出多尺度成组 (MSG)和多分辨率成组 (MRG)两种解决办法。
简单概括这两种采样方法:
- 多尺度成组(MSG):对于选取的一个中心点设置多个半径进行成组,并将经过PointNet对每个区域抽取后的特征进行拼接(concat)来当做该中心点的特征,个人认为这种做法会产生很多特征重叠,结果会可以保留和突出(边际叠加)更多局部关键的特征,但是这种方式不同范围内计算的权值却很难共享,计算量会变大很多。
- 多分辨率成组(MRG):对不同特征层上(分辨率)提取的特征再进行concat,以上图右图为例,最后的concat包含左右两个部分特征,分别来自底层和高层的特征抽取,对于low level点云成组后经过一个pointnet和high level的进行concat,思想是特征的抽取中的跳层连接。当局部点云区域较稀疏时,上层提取到的特征可靠性可能比底层更差,因此考虑对底层特征提升权重。当然,点云密度较高时能够提取到的特征也会更多。这种方法优化了直接在稀疏点云上进行特征抽取产生的问题,且相对于MSG的效率也较高。
在该网络中作者使用了对输入点云进行随机采样(丢弃)random input dropout(DP)方法。Dropout的设计本身是为了降低过拟合,增强模型的鲁棒性,结果显示对于分类任务的效果也有不错的提升,作者给了一个对比图:
本文中使用的缩写说明:
- SA:set abstraction 点集抽取模块
- FC:fully connected layers 全连接层
- FP:feature
propagation 特征传播模块(跨层连接,多个全连接)
SA模块的代码实现
- utils/pointnet_util.py/ 中采样成组的代码具体实现。
1 | def sample_and_group(npoint, radius, nsample, xyz, points, knn=False, use_xyz=True): |
以上是SA和FP部分的代码实现,接下来对分类任务的代码进行解读。
单尺度成组(SSG)分类网络的实现
以最基础的单尺度采样分组设计为例,结合代码了解模型的搭建过程。
- models/pointnet2_cls_ssg.py /
1 | def get_model(point_cloud, is_training, bn_decay=None): |
文章给出了针对ModelNet40S数据集上的分割模型的效果比较:
相比于Pointnet的结果,Pointnet++在此有小幅度的提升。
对于分割部分,会单独进行一次总结,文中给出的分割效果对比图:
结果显示在场景分割网络中,准确度关系为:MSG+DP > MRG+DP > SSG> PointNet
源码其余部分的介绍不详细展开,根据个人理解将源码的结构与功能设计展示如下:
结语
本文主要结合代码层面总结了pointnet++网络设计以及分类任务的实现。重点理解pointnet++是如何利用set abstraction(SA)这种结构学习到局部结构上的特征,并通过跳步连接和多尺度采样(MSG+DP)来提高模型对点云的分割准确性。可以注意到pointnet++中在特征提取时使用pointnet网络,但是最后的结果的鲁棒性在不添加其他设计的情况下没有原网络好,并且作者没有继续使用T-net进行点云对齐的方法。接下来将在此基础上继续进行更多相关论文的学习。
源码地址:
1.原论文实现代码
https://github.com/charlesq34/pointnet2
2.基于pytorch实现:
https://github.com/erikwijmans/Pointnet2_PyTorch
https://github.com/yanx27/Pointnet_Pointnet2_pytorch
- 作者: Chris Yan
- 链接: https:/Yansz.github.io/2020/03/16/pointne2学习笔记/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!