PointNet笔记(一)

PointNet是由斯坦福大学提出的用于点云分类与分割的深度学习框架。它通过直接使用原始点云数据,避免了体素化带来的数据损失,保持了点云的空间特性。本文详细介绍了PointNet的分类模块实现流程,包括数据处理、TF图谱构建及开始学习三个阶段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章的链接https://blog.youkuaiyun.com/yongxiebin9947/article/details/79368752
PointNet 是斯垣福大学在2016年提出的一种点云分类/分割深度学习框架。众所周知,点云在分类或分割时存在空间关系不规则的特点,因此不能直接将已有的图像分类分割框架套用到点云上,也因此在点云领域产生了许多基于将点云体素化(格网化)的深度学习框架,取得了很好的效果。但是将点云体素化势必会改变点云数据的原始特征,造成不必要的数据损失,并且额外增加了工作量,而 PointNet 采用了原始点云的输入方式,最大限度地保留了点云的空间特征,并在最终的测试中取得了很好的效果。
简单介绍可以参考
http://blog.youkuaiyun.com/yongxiebin9947/article/details/78706591
,主要是那张流程图。文章中的其他地方基本都是对各种方法的比较与数学证明,前者一直在说为啥我这个框架中的这个地方要用这个方法,对理解这个框架用途不大;而后者我直接跳过了,等有兴趣了(N年过后?)再来深究。
这里主要说一下PointNet的程序在分类模块实现的大致流程。
PointNet 官方使用了 tensorflow 实现,代码写的相当工整易读,而这个方法在代码中实现起来也比论文中看起来更简单。其主要分成以下三部分:数据处理 TF图谱构建 开始学习
数据处理,将点云处理成程序可用的格式,具体实现在 provider.py 中,主要包含了数据下载、预处理(shuffle、rotate等)、格式转换(hdf5->txt)
TF图谱构建,绿线框是一些很常规的操作,对应流程图中相对应的部分看看就好了。
红线框部分才是这篇论文一直在强调、证明的部分。下面先看一下第一个红线框中 input_transform_net() 对应的代码部分(下图)。可以看出,文章中的转换矩阵是使用额外一个小网络(T-Net),对其输入训练数据而学习得到的3*K的矩阵(K=3)。
而第二个转换矩阵微微有些不同,由于当进行到这一步的时候,点云已经被处理成了一条条的特征向量(B*N*1*K)。输入不同了,网络结构和参数也自然有了一些变化。最终输出 B*K*K 的转换矩阵。
在网络图谱整体框架搭好之后,就可以用TF提供的API进行训练了。
以上即为 PointNet 分类网络的大致框架。
PointNet++ 是种用于处理点云数据的深度学习架构,它扩展了 PointNet 的能力,通过引入分层特征提取机制来捕捉局部几何结构。尽管官方实现大多数开源项目最初是基于 PyTorch 构建的[^1],但社区已经开发了些在 TensorFlow 2 中实现 PointNet++ 的资源。 ### 在 TensorFlow 2 中实现 PointNet++ #### 1. 实现概述 在 TensorFlow 2 中实现 PointNet++ 需要以下几个关键组件: - **Set Abstraction 层**:这是 PointNet++ 的核心部分,负责从点云中提取局部特征。 - **Farthest Point Sampling (FPS)**:用于选择关键采样点。 - **Grouping Layer**:将点云划分成局部区域。 - **PointNet 模块**:对每个局部区域应用共享权重的 MLP 来提取特征。 - **Feature Propagation 层**:在分割任务中用于上采样并融合高低层特征。 这些模块都可以使用 TensorFlow 2 的 `tf.keras` API 自定义层进行实现。 #### 2. 示例代码片段 以下是个简化的 Set Abstraction 层实现示例: ```python import tensorflow as tf from tensorflow.keras import layers, Model class SetAbstraction(layers.Layer): def __init__(self, npoint, radius, nsample, mlp_channels, **kwargs): super(SetAbstraction, self).__init__(**kwargs) self.npoint = npoint self.radius = radius self.nsample = nsample self.mlp_channels = mlp_channels self.mlps = [] for out_channels in mlp_channels: self.mlps.append( tf.keras.Sequential([ layers.Conv2D(out_channels, kernel_size=1, padding='valid'), layers.BatchNormalization(), layers.ReLU() ]) ) def build(self, input_shape): self.built = True def call(self, xyz, features): # xyz: [B, N, 3] # features: [B, N, C] B, N, _ = tf.shape(xyz) new_xyz = self._farthest_point_sample(xyz, self.npoint) # [B, npoint, 3] grouped_xyz, grouped_features = self._group_points(xyz, features, new_xyz) # Normalize points within each group grouped_xyz -= tf.expand_dims(new_xyz, axis=2) # [B, npoint, nsample, 3] if grouped_features is not None: grouped_features = tf.concat([grouped_xyz, grouped_features], axis=-1) else: grouped_features = grouped_xyz # Reshape and apply MLP B, S, K, D = grouped_features.shape grouped_features = tf.reshape(grouped_features, [-1, K, D]) for mlp in self.mlps: grouped_features = mlp(grouped_features) new_features = tf.reduce_max(grouped_features, axis=2) # [B*S, D'] new_features = tf.reshape(new_features, [B, S, -1]) return new_xyz, new_features def _farthest_point_sample(self, xyz, npoint): # Simplified FPS implementation B, N, _ = tf.shape(xyz) centroids = tf.random.uniform(shape=(B, npoint), maxval=N, dtype=tf.int32) return tf.gather(xyz, centroids, batch_dims=1) def _group_points(self, xyz, features, new_xyz): # Ball query and grouping dist = tf.norm( tf.expand_dims(xyz, axis=2) - tf.expand_dims(new_xyz, axis=1), axis=-1 ) # [B, N, S] idx = tf.argsort(dist, axis=1)[:, :, :self.nsample] # [B, S, K] grouped_xyz = tf.gather(xyz, idx, batch_dims=1) # [B, S, K, 3] if features is not None: grouped_features = tf.gather(features, idx, batch_dims=1) # [B, S, K, C] else: grouped_features = None return grouped_xyz, grouped_features ``` 此代码展示了如何构建个基础的 Set Abstraction 层,适用于分类或分割任务中的特征提取模块。 #### 3. 相关教程与资源 虽然目前尚未有广泛认可的“官方”TensorFlow 2 版本的 PointNet++ 教程,但以下资源可以帮助你进步了解其实现细节: - **GitHub 上的社区实现**:搜索关键词如 `PointNet++ TensorFlow 2` 可以找到多个社区贡献的实现项目。 - **PointNet 系列论文阅读笔记**:许多博客文章详细解析了 PointNet++ 的设计思想,并提供了伪代码或框架建议。 - **TensorFlow 官方文档**:了解如何构建自定义层模型可以显著提升模型实现的灵活性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值