PointNet++具体实现详解
Pointnet++
Pointnet系列是直接使用三维数据处理点云的代表之作。Pointnet++为Pointnet系列的第二篇文章。Pointnet++的分析文章有很多,但我发现大多数文章也就是对其思想进行一些探究,其思想固然重要,但代码的分析也必不可少。本文将深入探究其代码,尝试恢复整个运算过程,从运算过程的角度帮助读者更好地理解PointNet++的思想。话不多说,直接上图。
- 图的解释
- 虚线大框:一个虚线框代表一个完整的子网络,对应代码中的一个class
- 红色小框:每个子网络的名称
- 蓝色小块:一个蓝色小块代表一个tensor,蓝色小框的第一行为tensor的名称,第二行为tensor的尺寸(也有特别个例为操作,例如插值和选取最近3个点的操作)
- 橘色小块:一个子网络的输出
- 箭头:一种操作,没有标的大部分为resize或者permutation操作,也有concatenate操作
- PointNet网络结构
- 特征提取操作:由一些SA子网络构成
- SA1:输入xyz,输出new_xyz, feature
- 对输入的xyz做permutation,然后使用Furtherst Point Sample方法寻找4096个最远点
- 提取这4096个最远点作为new_xyz,作为下一层的输入
- 寻找对于new_xyz中的每个点,在给定的距离内寻找点(BallQuery),得到grouped_xyz,给定的距离不同,寻找到的点的数量不同,从而分为两支。
- 按照grouped_xyz的id对feature进行选取,在SA1中feature就是xyz,所以没有变化
- 使用MLP对feature提取特征并做maxpooling操作得到高级特征。
- 对在BallQuery中不同距离下得到的高级特征记性concatenate操作,得到子网络的feature输出。
- SA2:输入SA1.new_xyz,SA1.feature,输出new_xyz,feature
- 不同于SA1的地方在于SA2的MLP的输入是由SA1.new_xyz和SA1.feature进concatenate操作而成
- 所以,不同于SA1的第4步,按照grouped_xyz的id选取的是concatenate后的feature,而不是xyz
- SA3
- SA4
- SA1:输入xyz,输出new_xyz, feature
- Upsampling操作:由一些FP子网络构成
- FP1:输入SA4.new_xyz,SA4.feature,SA3.new_xyz,SA3.feature,输出feauture
- 对于 SA3.new_xyz中的每个点,寻找SA4.new_xyz中的3个最近点
- 对这3个最近点,记录id,并计算距离,然后通过距离的倒数计算权重
- 使用这个3个最近点的特征进行加权平均求取SA3.new_xyz的点的feature
- 得到的feature与SA3.feature进行concatenate操作
- 通过MLP和MaxPooling得到FP1的输出,feature。SA3.new_xyz中的每个点对应一个feature,从而完成了Upsampling
- FP2
- FP3
- FP4
- FP1:输入SA4.new_xyz,SA4.feature,SA3.new_xyz,SA3.feature,输出feauture
- 分类头:使用conv1d完成最后的分类
- 特征提取操作:由一些SA子网络构成
注意:本文PointNet++的子网络数量与原文不同,tensor的尺寸也与原文不同。网络和tensor是按照PointRCNN中PointNet++的实现总结的。但具体的计算过程与PointNet++相同。