Li, Y., et al. “PointCNN: Convolution On X-Transformed Points.” NeurIPS 2018.
博主导读:
在点云深度学习领域,PointNet 系列通过“对称函数”(Max Pooling)解决了点云无序性的问题,但代价是放弃了传统 CNN 强大的卷积操作。我们知道,CNN 之所以在图像上大杀四方,靠的就是卷积核能够在局部区域提取空间相关性。
那么问题来了:能不能在无序的点云上直接通过卷积核提取特征呢?
PointCNN 给出的答案是:能,但需要先“变身”。它提出了X \mathcal{X}X-Conv算子,通过学习一个K × K K \times KK×K的变换矩阵,把无序的邻居点“排列”成潜在的规范顺序,从而让卷积操作再次焕发荣光。
本文将带你拆解这个神奇的X \mathcal{X}X变换,以及它背后关于“置换不变性”的深刻思考。原文链接:PointCNN: Convolution On X-Transformed Points
代码链接:代码链接
1. 核心痛点:为什么点云不能直接卷积?
在图像(Grid)中,数据是规则排列的,卷积核K KK是固定的。比如一个3 × 3 3 \times 33×3的卷积核,左上角的权重永远乘左上角的像素。
但在点云中,有两个致命问题:
- 不规则性 (Irregularity):点云在空间中是连续分布的,没有固定的网格。
- 无序性 (Unordered):对于中心点p pp,它的邻居是{ a , b , c , d } \{a, b, c, d\}{a,b,c,d}。如果你把它们存成[ a , b , c , d ] T [a, b, c, d]^T[a,b,c,d]T,还是[ c , a , b , d ] T [c, a, b, d]^T[c,a,b,d]T,它们代表的几何结构是一样的。
致命后果:如果你直接拿卷积核K KK去卷,输入顺序变了,卷积结果就变了。这导致网络无法学习到稳定的形状信息。
2. 核心创新:X \mathcal{X}X-Conv 算子
PointCNN 的核心思想非常直观:既然顺序是乱的,那我就学一个矩阵X \mathcal{X}X,把你乘到一个“正确”的顺序上,然后再卷!
这个过程被称为X \mathcal{X}X-Transformation。
2.1 算法流程 (Algorithm 1)
假设我们要在中心点p pp处提取特征,周围有K KK个邻居{ p 1 , . . . , p K } \{p_1, ..., p_K\}{p1,...,pK},特征为F i n F_{in}Fin。X \mathcal{X}X-Conv 的步骤如下:
- 局部坐标变换:将邻居坐标减去中心点坐标P ′ ← P − p P' \leftarrow P - pP′←P−p。
- 目的:获得局部几何形状,保证平移不变性。
- 特征升维 (Feature Lifting):F δ ← M L P δ ( P ′ ) F_\delta \leftarrow MLP_\delta(P')Fδ←MLPδ(P′)。
- 目的:把低维的坐标信息映射为高维特征,并与原有特征F FF拼接,形成F ∗ = [ F δ , F ] F_* = [F_\delta, F]F∗=[Fδ,F]。
- 学习X \mathcal{X}X变换矩阵 (重点!):X ← M L P ( P ′ ) \mathcal{X} \leftarrow MLP(P')X←MLP(P′)。
- 这里用一个 MLP 去学习一个K × K K \times KK×K的矩阵。
- 物理含义:这个矩阵负责对K KK个邻居进行加权 (Weighting)和重排列 (Permutation)。
- 注:这里隐含了一个极其重要的转置操作,详见下文深度解析。
- 执行变换:F X ← X × F ∗ F_\mathcal{X} \leftarrow \mathcal{X} \times F_*FX←X×F∗。
- 这一步发生了什么?原本乱序的F ∗ F_*F∗,被X \mathcal{X}X矩阵左乘之后,变成了“规范顺序”的特征F X F_\mathcal{X}FX。
- 标准卷积:F p ← C o n v ( K , F X ) F_p \leftarrow Conv(K, F_\mathcal{X})Fp←Conv(K,FX)。
- 现在特征顺序已经规范了,我们可以放心地用标准卷积核K KK去卷它了!
2.2 核心公式
F p = Conv ( K , MLP ( P − p ) × [ MLP δ ( P − p ) , F ] ) F_p = \text{Conv}\left( K, \, \text{MLP}(P-p) \times [ \text{MLP}_\delta(P-p), \, F ] \right)Fp=Conv(K,MLP(P−p)×[MLPδ(P−p),F])
3. 深度解析:X \mathcal{X}X矩阵到底干了什么?
很多同学看到这里会懵:为什么乘一个矩阵就能解决乱序问题?
我们可以把X \mathcal{X}X矩阵看作是一个“软置换矩阵” (Soft Permutation Matrix)。
3.1 “众筹”排座次
X \mathcal{X}X矩阵的生成是一个“基于内容的加权”过程:当执行X × F \mathcal{X} \times FX×F时,实相当于对特征矩阵进行了行变换。(矩阵乘法,左乘是行变换)。
无论输入的点顺序怎么乱,只要几何形状没变,“左上角”的点永远会把特征投递到“第 1 行”。这样,后续的卷积核K KK就能安心地提取特征了。
3.2 🔥 硬核细节:为什么 MLP 输出X \mathcal{X}X需要转置!!!
在数学推导上,这里有一个容易被忽视的细节,直接关系到代码实现的正确性:
假设邻居点的坐标(K, 3)经过mlp变为(K, K),他们的第一行,完全是由第一个点的坐标得到的。
假设他认为第10个点权重最大。邻居点的特征(K, C)也就把第10个点放在了第一个点的位置。
现在把第10个点和第11个点互换,其他什么都不变,那么邻居点的坐标(K, 3)经过mlp变为(K, K),他们的第一行,完全是由第一个点的坐标得到的,所以也不会变,那么依然会认为第10个点权重最大,但是实际上第10个点和第11个点已经互换了。
这样就完全错误了。
把X × F \mathcal{X} \times FX×F看做是邻居特征的线性变换。至于选择他们的顺序是由所有的点坐标决定的。所有必须要进行转置!!!
4. 网络架构:层级化学习
PointCNN 模仿了传统 CNN 的层级结构(Hierarchical Architecture),这点和 PointNet++ 类似。
- 特征编码 (Encoder):
- 通过堆叠X \mathcal{X}X-Conv 层。
- 每一层通过下采样(如随机采样或最远点采样 FPS)减少点数N NN,同时增加特征维度C CC。
- 感受野(Receptive Field)逐层扩大。
- 空洞卷积 (Dilated Convolution):
- 为了扩大感受野而不增加计算量,PointCNN 在点云上引入了空洞卷积的概念。
- 做法:在找K KK个邻居时,先找K × D K \times DK×D个,然后均匀抽样K KK个。
- 分割网络 (Decoder):
- 类似于 U-Net,使用X \mathcal{X}X-Conv 作为反卷积(DeConv),并将编码层的特征通过 Skip Connection 传过来。
5. PyTorch 核心代码复现
Talk is cheap, show me the code. 我们来实现一个简化版的XConv,帮助理解数据流。
importtorchimporttorch.nnasnndefindex_points(points,idx):"""根据索引提取点"""# points: [B, N, C], idx: [B, N, K]device=points.device B=points.shape[0]view_shape=list(idx.shape)view_shape[1:]=[1]*(len(view_shape)-1)repeat_shape=list(idx.shape)repeat_shape[0]=1batch_indices=torch.arange(B,dtype=torch.long,device=device).view(view_shape).repeat(repeat_shape)new_points=points[batch_indices,idx,:]returnnew_pointsclassXConv(nn.Module):def__init__(self,in_channels,out_channels,k=16,dim=3):super(XConv,self).__init__()self.k=k# 1. 学习 X 变换矩阵的 MLP (输出 K*K)# 注意:这里输出的是 K*K,需要 reshapeself.mlp_x=nn.Sequential(nn.Linear(dim,64),nn.ELU(),nn.Linear(64,k*k))# 2. 卷积层 (相当于 Algorithm 1 中的 Conv)# 输入维度是 in_channels + dim (因为做了feature lifting)# 这里的卷积核高度是 K,宽度是 C_delta + C1,相当于做深度卷积self.conv=nn.Sequential(nn.Conv2d(k,out_channels,kernel_size=(1,in_channels+dim)),nn.BatchNorm2d(out_channels),nn.ELU())defforward(self,p,x,idx):""" p: (B, N, 3) - 坐标 x: (B, N, C) - 特征 idx: (B, N, K) - 邻居索引 """B,N,_=p.shape# 1. 获取邻居坐标# neighbor_p: (B, N, K, 3)neighbor_p=index_points(p,idx)# 2. 局部坐标变换 (P' = P - p)# p_local: (B, N, K, 3)p_local=neighbor_p-p.unsqueeze(2)# 3. 获取邻居特征并拼接 (Feature Lifting)ifxisnotNone:neighbor_x=index_points(x,idx)# 拼接坐标和特征: [P', F] -> (B, N, K, C+3)feature_star=torch.cat([p_local,neighbor_x],dim=-1)else:feature_star=p_local# 4. 学习 X 变换矩阵# (B, N, K, 3) -> (B, N, K, K*K) -> (B, N, K, K)# 每一个邻居点预测一个 K 维向量,K 个邻居拼成 KxKX_mat=self.mlp_x(p_local).view(B,N,self.k,self.k).transpose(-1,-2)# 5. 应用 X 变换 (X * F_star)# (B, N, K, K) @ (B, N, K, C+3) -> (B, N, K, C+3)# 这一步通过矩阵乘法实现了特征的加权和重排feature_transformed=torch.matmul(X_mat,feature_star)# 6. 卷积# 此时 feature_transformed 已经被 "排序" 好了out=self.conv(feature_transformed)returnout6. 实验结果与可视化 (Results)
6.1 性能表现
PointCNN 在ModelNet40上达到了92.2%的准确率,在ScanNet上达到了92.5%。这些成绩在当时都达到了 SOTA (State-of-the-Art) 水平,证明了X \mathcal{X}X-Conv 在处理点云分类和分割任务上的强大能力。
6.2 可视化证明 (X \mathcal{X}X真的有用吗?)
为了验证X \mathcal{X}X变换矩阵是否真的起到了“排序”和“规范化”的作用,论文作者通过 t-SNE 可视化了变换前后的特征分布。
在一个已经训练好的网络中,但通常取中间某一层(如第 2 或第 3 层X \mathcal{X}X-Conv),因为那里的特征既有局部几何信息,又有一定的语义抽象。
在Modelnet40中,不同的物体选取15个局部点,然后经过网络。图a是完全没有X \mathcal{X}X的操作,图b是经过一层的X \mathcal{X}X-Conv但是有打乱了点,图c是经过X \mathcal{X}X但没有Conv,也就是重新排序的点。
注意,点维度是C,邻居是K,t-sne的输入维度是K*C,也就是说,图b是把邻居点随机的拼接,图c是把邻居点按顺序拼接!!!
- 变换前 (F ∗ \mathcal{F}_*F∗或F o \mathcal{F}_oFo):特征分布是模糊、混杂的 (Fuzzy/Blended)。这说明在没有X \mathcal{X}X介入时,由于输入点的无序性,网络很难区分不同几何结构的特征,大家“乱成一锅粥”。
- 变换后 (F X \mathcal{F}_\mathcal{X}FX):特征分布变得非常紧凑 (Concentrated)和有区分度 (Discriminative)。
💡 结论:
这直接证明了X \mathcal{X}X变换成功地将乱序的输入“规范化” (Canonicalized)了。它就像一个自动整理器,把特征摆放到了卷积核熟悉的位置,使得卷积操作可以有效地提取几何信息。
7. 总结 (Conclusion)
PointCNN 是点云深度学习中非常有野心的一个工作。
- 它没有妥协于 Max Pooling 这种“简单粗暴”的对称函数,而是硬刚“无序性”问题。
- 它通过学习一个X \mathcal{X}X变换矩阵,实现了对无序点云的隐式排序 (Implicit Ordering)和加权 (Weighting)。
- 这使得经典的 CNN 架构(卷积、下采样、上采样)可以被近乎无缝地迁移到点云领域,重新利用了空间局部相关性。
虽然现在的 SOTA 更多被 Transformer(如 Point Transformer)占据,但 PointCNN 关于“Canonical Ordering” (规范化排序)的思考依然极具价值。它告诉我们:与其设计复杂的对称函数,不如教网络自己学会“整理队形”。
📚 参考文献
[1] Li, Y., et al. “PointCNN: Convolution On X-Transformed Points.” NeurIPS 2018.
💬互动话题:
你理解为什么点云不能直接使用卷积了么?
你知道为什么X \mathcal{X}X-Conv 算子需要转置么?
你明天t-SNE可视化的输入到底是什么么?
📚 附录:MLP点云网络系列导航
本专栏致力于用“人话”解读 3D 点云领域的硬核论文,从原理到代码逐行拆解。
🔥 欢迎订阅专栏:【点云特征分析_顶会论文硬核拆解】持续更新中…
本文为 CSDN 专栏【深度学习-论文讲解】原创内容,转载请注明出处。