PointNet++改进策略 :模块改进 | x-Conv | PointCNN, 结合局部结构与全局排列提升模型性能

Pasted image 20240910094800

前言

这篇论文介绍了一种名为 PointCNN 的方法,旨在从点云(point cloud)数据中学习特征。传统卷积神经网络(CNN)在处理规则网格数据(如图像)时非常有效,但由于点云是无序且不规则的,直接在其上应用卷积操作会导致形状信息丢失,并对点的排列顺序敏感。

为了解决这一问题,论文提出了一种 X-Conv 操作。该方法通过学习一种 X-transformation 来重新排列点云中的点并加权输入特征。然后,将典型的卷积操作应用于转换后的特征。这种方法将传统的 CNN 扩展到点云特征学习,并命名为 PointCNN

实验表明,PointCNN 在多个基准数据集上达到了与当前最先进方法相当甚至更好的性能。这些数据集包括 3D 形状分类(如 ModelNet40)、分割任务(如 ShapeNet Parts 和 ScanNet),以及 2D 草图分类任务(如 TU-Berlin 和 Quick Draw)。

论文的关键贡献在于提出了适用于点云的卷积操作,并展示了其在多种任务上的有效性。

Pasted image 20240910094823

PointCNN实现细节

PointCNN 是一种针对点云数据进行特征学习的卷积神经网络架构。它的设计初衷是为了克服传统卷积神经网络(CNN)在处理点云数据时遇到的挑战。点云数据是不规则且无序的,因此直接将传统的卷积操作应用在点云上会导致形状信息的丢失,并且对点的排列顺序非常敏感。

PointCNN 的核心思想是引入一种叫做 X-Conv 的操作,这种操作通过学习一个 X-transformation 变换矩阵来同时加权和排列输入点云的数据,使得卷积操作可以更有效地应用于点云。具体来说,X-transformation 将点云的点映射到一个潜在的、或许是规范化的顺序中,然后在变换后的特征上应用卷积操作。

相比于直接对点云进行卷积,PointCNN 通过 X-Conv 操作保留了点云的局部结构信息,同时对点的排列顺序具有不变性。这使得它在点云的各种任务中表现出色,例如3D形状分类、分割任务和草图分类等。

简而言之,PointCNN 是一个能够处理不规则点云数据的通用卷积网络架构,解决了点云数据中的排列问题,并在多个任务上达到了与最先进方法相当甚至更好的性能。
Pasted image 20240910094835

1. X X X-Conv 操作

X X X-Conv 是 PointCNN 的核心操作,它通过学习一个 X X X-转换矩阵,对输入点及其特征进行加权和排序,然后进行卷积操作。整个 X X X-Conv 的过程如下:

输入
  • K K K: 表示点邻域中的 K K K 个点。
  • p p p: 表示当前代表点。
  • P P P: 当前点 p p p K K K 个邻域点的坐标,表示为 P = ( p 1 , p 2 , … , p K ) T P = (p_1, p_2, \dots, p_K)^T P=(p1,p2,,pK)T
  • F F F: 邻域点的特征矩阵,表示为 F = ( f 1 , f 2 , … , f K ) T F = (f_1, f_2, \dots, f_K)^T F=(f1,f2,,fK)T,其中 f i ∈ R C 1 f_i \in \mathbb{R}^{C_1} fiRC1
输出
  • F p F_p Fp: 聚合到代表点 p p p 的输出特征。
步骤
  1. 局部坐标系变换:首先将邻域点的坐标转换为相对于代表点 p p p 的局部坐标系,即 P ′ ← P − p . P' \leftarrow P - p. PPp.
  2. 升维操作:通过多层感知机(MLP),将每个邻域点的坐标升维到 C δ C_\delta Cδ 维空间,得到 F δ F_\delta Fδ,即 F δ ← MLP δ ( P ′ ) . F_\delta \leftarrow \text{MLP}_\delta(P'). FδMLPδ(P).
  3. 特征拼接:将升维后的坐标特征 F δ F_\delta Fδ 与原始特征 F F F 进行拼接,形成新的特征矩阵 F ∗ F^* F,其形状为 K × ( C δ + C 1 ) K \times (C_\delta + C_1) K×(Cδ+C1) F ∗ ← [ F δ , F ] . F^* \leftarrow [F_\delta, F]. F[Fδ,F].
  4. X X X-转换矩阵的学习:通过一个 MLP 网络,从局部坐标 P ′ P' P 中学习到一个 K × K K \times K K×K X X X-转换矩阵: X ← MLP ( P ′ ) . X \leftarrow \text{MLP}(P'). XMLP(P).
  5. 加权和排序:对拼接后的特征矩阵 F ∗ F^* F 进行加权和排序,得到 F X F_X FX F X ← X × F ∗ . F_X \leftarrow X \times F^*. FXX×F.
  6. 卷积操作:最后,将加权后的特征 F X F_X FX 与卷积核进行卷积操作,输出结果特征 F p F_p Fp F p ← Conv ( K , F X ) . F_p \leftarrow \text{Conv}(K, F_X). FpConv(K,FX).

该过程可以总结为如下公式: F p = X -Conv ( K , p , P , F ) = Conv ( K , MLP ( P − p ) × [ MLP δ ( P − p ) , F ] ) . F_p = X\text{-Conv}(K, p, P, F) = \text{Conv}(K, \text{MLP}(P - p) \times [\text{MLP}_\delta(P - p), F]). Fp=X-Conv(K,p,P,F)=Conv(K,MLP(Pp)×[MLPδ(Pp),F]).

2. PointCNN 网络架构

PointCNN 使用 X X X-Conv 操作递归地应用在点云的不同层级上,实现了层级特征表示。输入到 PointCNN 的是点集 { ( p 1 , f 1 ) , ( p 2 , f 2 ) , … , ( p N , f N ) } \{(p_1, f_1), (p_2, f_2), \dots, (p_N, f_N)\} {(p1,f1),(p2,f2),,(pN,fN)},其中 p i p_i pi 是点的坐标, f i f_i fi 是与点关联的特征。

层级卷积

类似于传统 CNN 的层级卷积,PointCNN 通过多层的 X X X-Conv 逐步减少点的数量,并增大特征维度。层级的每一层通过聚合局部点的特征,得到新的代表点及其特征。对于输入点云 F 1 = { ( p 1 , i , f 1 , i ) } F_1 = \{(p_{1,i}, f_{1,i})\} F1={(p1,i,f1,i)},我们可以递归应用 X X X-Conv,生成新的表示 F 2 = { ( p 2 , i , f 2 , i ) } F_2 = \{(p_{2,i}, f_{2,i})\} F2={(p2,i,f2,i)},其中 ∣ F 2 ∣ < ∣ F 1 ∣ |F_2| < |F_1| F2<F1 且特征维度更高。

每一层的输出可表示为: F l + 1 = X -Conv ( K , P l , F l ) , F_{l+1} = X\text{-Conv}(K, P_l, F_l), Fl+1=X-Conv(K,Pl,Fl), 其中 P l P_l Pl 是第 l l l 层的代表点坐标, F l F_l Fl 是第 l l l 层的特征矩阵, K K K 是邻域点数。

分类与分割任务
  • 分类网络:PointCNN 将通过若干 X X X-Conv 层逐步将输入点聚合为较少的代表点,并最终通过全连接层实现分类。在分类网络中,最后一个 X X X-Conv 层的输出是一个全局表示,通常只保留一个代表点,并应用全连接层进行分类。

  • 分割网络:在分割任务中,PointCNN 采用类似于 U-Net 的架构, X X X-Conv 不仅在卷积部分应用,也在 DeConv 部分应用,以逐步将全局信息传播到高分辨率的点云表示上。

3. 数据增强

为了提高模型的泛化能力,PointCNN 使用了随机采样和输入点集顺序打乱的数据增强策略。在训练时,PointCNN 随机采样 N ∼ N ( 1024 , 12 8 2 ) N \sim \mathcal{N}(1024, 128^2) NN(1024,1282) 个点作为输入,并在每个批次中对输入点的顺序进行打乱。这对于训练一个对点集输入顺序不敏感的模型至关重要。

4. 效率优化

在实现中, X X X-Conv 的复杂度为 O ( K 3 ) O(K^3) O(K3),并且使用了深度可分离卷积来进一步减少计算复杂度。整个操作过程均为可微分的,因此 PointCNN 可以使用反向传播进行训练。

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 PointNet++ 加注意力机制改进的代码示例: ```python import tensorflow as tf def get_attention_weight(x, y, dim): """ 获取注意力权重 :param x: 输入特征向量 :param y: 相关特征向量 :param dim: 特征向量维度 :return: 注意力权重 """ w = tf.Variable(tf.random_normal([dim, 1], stddev=0.1), name='attention_w') b = tf.Variable(tf.zeros([1]), name='attention_b') z = tf.matmul(tf.concat([x, y], axis=1), w) + b a = tf.nn.softmax(z) return a def get_attention_feature(x, y, dim): """ 获取注意力特征向量 :param x: 输入特征向量 :param y: 相关特征向量 :param dim: 特征向量维度 :return: 注意力特征向量 """ a = get_attention_weight(x, y, dim) f = tf.concat([x, y], axis=1) * a return f def pointnet_plus_plus_attention(x, k, mlp, is_training): """ PointNet++ 加注意力机制改进 :param x: 输入点云数据,shape为(batch_size, num_points, num_dims) :param k: k-NN 算法中的 k 值 :param mlp: 全连接网络结构 :param is_training: 是否为训练 :return: 输出结果,shape为(batch_size, num_points, mlp[-1]) """ num_points = x.get_shape()[1].value num_dims = x.get_shape()[-1].value with tf.variable_scope('pointnet_plus_plus_attention', reuse=tf.AUTO_REUSE): # 首先进行 k-NN 建模,找到每个点的 k 个最近邻点 # 根据每个点与其 k 个最近邻点的距离,计算点之间的权重 dists, idxs = knn(k, x) # 将点特征和最近邻点特征进行拼接 grouped_points = group(x, idxs) grouped_points = tf.concat([x, grouped_points], axis=-1) # 对拼接后的特征进行全连接网络处理 for i, num_output_channels in enumerate(mlp): grouped_points = tf_util.conv1d(grouped_points, num_output_channels, 1, 'mlp_%d' % i, is_training=is_training) # 对每个点和其最近邻点进行注意力权重计算 attention_points = [] for i in range(num_points): center_point = tf.expand_dims(tf.expand_dims(x[:, i, :], axis=1), axis=1) neighbor_points = tf.gather_nd(grouped_points, idxs[:, i, :], batch_dims=1) attention_feature = get_attention_feature(center_point, neighbor_points, num_dims * 2) attention_points.append(tf.reduce_sum(attention_feature, axis=1, keep_dims=True)) # 将注意力特征向量拼接起来,作为输出结果 output = tf.concat(attention_points, axis=1) return output ``` 在这个代码中,我们使用了 `get_attention_weight` 函数来获取注意力权重,并使用 `get_attention_feature` 函数来获取注意力特征向量。在 PointNet++ 加注意力机制改进中,我们对每个点和其 k 个最近邻点计算了注意力权重,然后用注意力权重加权求和得到了注意力特征向量,最后将所有注意力特征向量拼接起来作为输出结果。 请注意,这只是一个简单的示例,实际上,PointNet++ 加注意力机制改进的实现要比这个复杂得多。如果您需要更复杂的实现,建议参考相关论文或其他开源实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值