笔记参考了这两篇论文的作者的讲解,b站链接放在了文末。
Relation-Shape CNN
Relation-Shape CNN
Relation-Shape Convolutional Neural Network for Point Cloud Analysis
作者认为通过感知点云的形状特征可以更好的完成点云上的分类、分割等任务,因此需要设计一种可以描述某区域内点云形状的编码 f P s u b f_{P_{sub}} fPsub,在设计时,作者选用了球体区域。建模如下:
f P usb = σ ( A ( { T ( f x j ) , ∀ x j } ) ) , d i j < r ∀ x j ∈ N ( x i ) \mathbf{f}_{P_{\text {usb }}}=\sigma\left(\mathcal{A}\left(\left\{\mathcal{T}\left(\mathbf{f}_{x_{j}}\right), \forall x_{j}\right\}\right)\right), d_{i j}<r \forall x_{j} \in \mathcal{N}\left(x_{i}\right) fPusb =σ(A({
T(fxj),∀xj})),dij<r∀xj∈N(xi)
即学习以 x i x_i xi为中心,以 r r r为半径的球形邻域内各个点与中心点的关系,首先对邻域中的每个点进行特征变换 T \mathcal{T} T,然后进行特征聚合 A \mathcal{A} A,最后使用一个非线性变换 σ \sigma σ得到结果。
为了能够实现置换不变性, T \mathcal{T} T中的参数必须是共享的, A \mathcal{A} A则必须是对称的。但传统卷积 T ( f x j ) = w j ⋅ f x j \mathcal{T}(f_{x_j})=w_j · f_{x_j} T(fxj)=wj⋅fxj的权重参数并不是共享的,为了解决这一问题,作者认为应从点与点之间的关系中进行学习,具体的:
T ( f x j ) = w i j ⋅ f x j = M ( h i j ) ⋅ f x j \mathcal{T}\left(\mathbf{f}_{x_{j}}\right)=\mathbf{w}_{i j} \cdot \mathbf{f}_{x_{j}}=\mathcal{M}\left(\mathbf{h}_{i j}\right) \cdot \mathbf{f}_{x_{j}} T(fxj)=wij⋅fxj=M(hij)⋅fxj
预先定义几何特征编码 h i , j h_{i,j} hi,j,然后将低维度的关系特征用MLP M \mathcal{M} M映射到高纬度空间, h i , j = [ 3 D E u c l i d e a n d i s t a n c e , x i − x j , x i , x j ] h_{i,j}=[3D Euclidean distance,x_i-x_j,x_i,x_j] hi,j=[3DEuclideandistance,xi−xj,xi,xj]。因为在设计时采用的是与刚体变换无关的欧氏距离,对于刚体变换也有一定的鲁棒性,但并没有真正解决这一问题。
分割网络设计参考了PointNet++的上采用。论文最主要的亮点是设计了Relation-Shape Conv,RSConv的实现主要在pytorch_utils.py中。
源码学习
以分割网络为例,网络模型位于models目录下的rscnn_msn_seg.py,参数设置位于cfgs目录下的config_msn_partseg.yaml,训练使用train_partseg.sh. (果然还是更喜欢pytorch一些,感觉比tf写起来简洁清晰)
The code is heavily borrowed from Pointnet2_PyTorch.
rscnn_msn_seg.py
分割模型总共设置了4层PointnetSAModuleMSG,2层PointnetSAModule、4层PointnetFPModule和2层conv1d,其中PointnetSAModuleMSG用于提取局部特征,PointnetSAModule用于提取全局特征(global pooling),仅对forward部分添加了注释。各层的实现细节在pointnet2_modules.py中。
class RSCNN_MSN(nn.Module):
r"""
PointNet2 with multi-scale grouping
Semantic segmentation network that uses feature propogation layers
Parameters
----------
num_classes: int
Number of semantics classes to predict over -- size of softmax classifier that run for each point
input_channels: int = 6
Number of input channels in the fea