首页
AI
点云处理: 基于飞桨复现PointNet++

点云处理: 基于飞桨复现PointNet++

热心网友
转载
2025-07-24
来源:https://www.php.cn/faq/1425374.html

本文介绍PointNet++在PaddlePaddle的复现项目。PointNet++通过分层结构提取点云局部特征,解决点集分布不均问题。复现基于ModelNet40数据集,top-1 Acc达92.0,超原论文。说明环境依赖、快速开始步骤,分析代码结构及复现中PaddlePaddle多维索引支持不足的问题与解决方法。

点云处理: 基于飞桨复现pointnet++ - 游乐网

pointnet_plus_plus_paddlepaddle

Paper: PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space

一、项目简介

PointNet++与PointNet相比网络可以更好的提取局部特征。网络使用空间距离(metric space distances),使用PointNet对点集局部区域进行特征迭代提取,使其能够学到局部尺度越来越大的特征。基于自适应密度的特征提取方法,解决了点集分布不均匀的问题。

论文地址:

PointNet++

论文背景:

论文主要解决的是点云分割与点云分类的问题。该方法对PointNet进行了改进。针对PointNet存在的无法获得局部特征,难以对复杂场景进行分析的缺点。PointNet++,通过两个主要的方法进行了改进:

利用空间距离(metric space distances),使用PointNet对点集局部区域进行特征迭代提取,使其能够学到局部尺度越来越大的特征。由于点集分布很多时候是不均匀的,如果默认是均匀的,会使得网络性能变差,所以作者提出了一种自适应密度的特征提取方法。通过以上两种方法,能够更高效的学习特征,也更有鲁棒性。

论文方案介绍

在PointNet++中,作者利用所在空间的距离度量将点集划分(partition)为有重叠的局部区域(可以理解为patch)。在此基础上,在小范围中从几何结构中提取局部特征(浅层特征),然后扩大范围,在这些局部特征的基础上提取更高层次的特征,从而提取到整个点集的全局特征。

PointNet++解决了两个关键的问题:第一,将点集划分为不同的区域;第二,利用特征提取器获取不同区域的局部特征。

在本文中,作者使用了PointNet作为特征提取器,使用邻域球来定义分区,每个区域可以通过中心坐标和半径来确定。中心坐标的选取,作者使用了快速采样算法来完成(farthest point sampling (FPS) algorithm)。区域半径的选择使用了Multi-scale grouping (MSG) and Multi-resolution grouping (MRG)来实现。

论文模型介绍

PointNet++是PointNet的延伸,在PointNet的基础上加入了多层次结构(hierarchical structure),使得网络能够在越来越大的区域上提供更高级别的特征。点云处理: 基于飞桨复现PointNet++ - 游乐网        

网络的每一组set abstraction layers主要包括3个部分:Sampling layer, Grouping layer and PointNet layer。

· Sample layer:主要是对输入点进行采样,在这些点中选出若干个中心点; · Grouping layer:是利用上一步得到的中心点将点集划分成若干个区域; · PointNet layer:是对上述得到的每个区域进行编码,变成特征向量。 每一组提取层的输入是N * (d + C),其中N是输入点的数量,d是坐标维度,C是特征维度。输出是N'* (d + C'),其中N'是输出点的数量,d是坐标维度不变,C'是新的特征维度。

二、复现精度

三、数据集

使用的数据集为:ModelNet40。

ModelNet包含了来自662类的127915个三维形状,其子集Model10包含了来自10类的4899个三维形状,ModelNet40包含了来自40类的12311个三维形状。ModelNet40是常用的三维点云分割数据集,现在是一个用来评判三维点云分割性能的常规benchmark。

四、环境依赖

硬件:GPU、CPU

框架:

PaddlePaddle >= 2.0.0tqdm

五、快速开始

Data Preparation

Download alignment ModelNet and put it in ./dataset/modelnet40_normal_resampled/

Train

python train_modelnet.py --process_data
登录后复制

       

Test

python test_modelnet.py --log_dir path_to_model
登录后复制

       

六、代码结构与详细说明

6.1 代码结构

|—— README.md|—— provider.py    # 点云数据增强|—— ModelNetDataset.py # 数据集定义及加载|── train_modelnet.py       # 训练网络|── test_modelnet.py     # 测试网络|—— models        # 模型文件定义
登录后复制

       

6.2 参数说明

可以在 train_modelnet.py 中设置训练与评估相关参数,具体如下:

Reference Implementation:

TensorFlow (Official)PyTorch

七、复现总结与心得

问题

复现主要参考的是PyTorch的pytorch实现,pytorch的大部分api可以在paddlepaddle中找到对应,最困难的地方在于,paddlepaddle没法办法进行二维的索引,对应原实现中的多个部分

def index_points(points, idx):    """    Input:        points: input points data, [B, N, C]        idx: sample index data, [B, S]    Return:        new_points:, indexed points data, [B, S, C]    """    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] = 1    batch_indices = torch.arange(B, dtype=torch.long).to(device).view(view_shape).repeat(repeat_shape)    new_points = points[batch_indices, idx, :]    return new_points
登录后复制

       

def farthest_point_sample(xyz, npoint):    """    Input:        xyz: pointcloud data, [B, N, 3]        npoint: number of samples    Return:        centroids: sampled pointcloud index, [B, npoint]    """    device = xyz.device    B, N, C = xyz.shape    centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)    distance = torch.ones(B, N).to(device) * 1e10    farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)    batch_indices = torch.arange(B, dtype=torch.long).to(device)    for i in range(npoint):        centroids[:, i] = farthest        centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)        dist = torch.sum((xyz - centroid) ** 2, -1)        mask = dist < distance        distance[mask] = dist[mask]        farthest = torch.max(distance, -1)[1]    return centroids
登录后复制

       

def query_ball_point(radius, nsample, xyz, new_xyz):    """    Input:        radius: local region radius        nsample: max sample number in local region        xyz: all points, [B, N, 3]        new_xyz: query points, [B, S, 3]    Return:        group_idx: grouped points index, [B, S, nsample]    """    device = xyz.device    B, N, C = xyz.shape    _, S, _ = new_xyz.shape    group_idx = torch.arange(N, dtype=torch.long).to(device).view(1, 1, N).repeat([B, S, 1])    sqrdists = square_distance(new_xyz, xyz)    group_idx[sqrdists > radius ** 2] = N    group_idx = group_idx.sort(dim=-1)[0][:, :, :nsample]    group_first = group_idx[:, :, 0].view(B, S, 1).repeat([1, 1, nsample])    mask = group_idx == N    group_idx[mask] = group_first[mask]    return group_idx
登录后复制

       

def sample_and_group(npoint, radius, nsample, xyz, points, returnfps=False):    """    Input:        npoint:        radius:        nsample:        xyz: input points position data, [B, N, 3]        points: input points data, [B, N, D]    Return:        new_xyz: sampled points position data, [B, npoint, nsample, 3]        new_points: sampled points data, [B, npoint, nsample, 3+D]    """    B, N, C = xyz.shape    S = npoint    fps_idx = farthest_point_sample(xyz, npoint) # [B, npoint, C]    new_xyz = index_points(xyz, fps_idx)    idx = query_ball_point(radius, nsample, xyz, new_xyz)    grouped_xyz = index_points(xyz, idx) # [B, npoint, nsample, C]    grouped_xyz_norm = grouped_xyz - new_xyz.view(B, S, 1, C)    if points is not None:        grouped_points = index_points(points, idx)        new_points = torch.cat([grouped_xyz_norm, grouped_points], dim=-1) # [B, npoint, nsample, C+D]    else:        new_points = grouped_xyz_norm    if returnfps:        return new_xyz, new_points, grouped_xyz, fps_idx    else:        return new_xyz, new_points
登录后复制

       

这里所有的二维索引都没有办法使用,包括经常使用的mask方法

这里进行了一些妥协,将需要二维索引的地方进行拉直,从而可以将二维索引变为n个一维索引,但是这里肯定对速度有所损失,暂时没有想到好的办法

farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)batch_indices = torch.arange(B, dtype=torch.long).to(device)for i in range(npoint):    centroids[:, i] = farthest    centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
登录后复制

       

farthest = paddle.randint(0, N, (B, ), dtype="int64")for i in range(npoint):    centroids[:, i] = farthest    # centroid = xyz[batch_indices, farthest, :].reshape((B, 1, 3))    centroid = paddle.zeros((B, 1, 3), dtype="float32")    for j in range(3):        centroid[:,:,j] = xyz[:,:,j].index_sample(farthest.reshape((-1, 1))).reshape((B, 1))
登录后复制

       

对于mask的地方,可以直接使用数值运算的方法达到mask的目的

mask = dist < distancedistance[mask] = dist[mask]farthest = torch.max(distance, -1)[1]
登录后复制

       

mask = dist < distancemask = mask.astype("int64")mask_index = paddle.nonzero(mask)if mask_index.size > 0:    distance = distance * (1 - mask.astype("float32")) + dist * mask.astype("float32")
登录后复制

       

总结

目前的paddlepaddle可以支持大多数pytorch的API,但是其对于多维索引的支持不足,非常影响使用体验,而多维索引又是一个在日常的研究以及工程中,非常常规的功能,这里需要改进。

安装依赖

In [ ]
!python3 -m pip install tqdm
登录后复制    

解压缩数据集

In [ ]
%cd /home/aistudio/data/data50045/!unzip modelnet40_normal_resampled.zip
登录后复制    

解压缩代码并链接数据集

In [ ]
%cd /home/aistudio/!unzip pointnet_plus_plus_paddlepaddle-main.zip%cd pointnet_plus_plus_paddlepaddle-main/
登录后复制    In [ ]
%mkdir /home/aistudio/pointnet_plus_plus_paddlepaddle-main/dataset%cp -r /home/aistudio/data/data50045/modelnet40_normal_resampled /home/aistudio/pointnet_plus_plus_paddlepaddle-main/dataset
登录后复制    

训练模型

In [2]
%cd /home/aistudio/pointnet_plus_plus_paddlepaddle-main/!python3 train_modelnet.py --process_data
登录后复制    

测试

In [ ]
%cd /home/aistudio/pointnet_plus_plus_paddlepaddle-main/!python3 test_modelnet.py --log_dir path_to_log
登录后复制    

免责声明

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章

爱彼迎CEO切斯基:ChatGPT不成熟,阿里通义千问高效又实惠

爱彼迎首席执行官布莱恩·切斯基近日在接受媒体采访时透露,公司目前尚未将应用程序与OpenAI的ChatGPT进行技术整合。他指出,尽管ChatGPT在生成式人工智能领域表现突出,但其现有连接工具的成

2025-10-23.

荣耀AI投入超百亿:升级HONOR AI Connect平台 共建智慧生态

在荣耀AI终端生态大会上,荣耀董事长吴晖提出“得AI者得天下,得终端者得未来”的论断,强调人工智能技术正以颠覆性力量重构终端产业生态。他指出,智能体将取代传统交互方式,成为连接人与数字世界的核心入口

2025-10-23.

字节跳动Seed团队发布Seed3D+1.0:单图生成高质量3D模型

字节跳动Seed团队近日宣布,正式推出其最新研发的3D生成大模型——Seed3D 1 0。这款模型具备从单张图像直接生成高质量仿真级3D模型的端到端能力,为3D内容创作领域带来了突破性进展。在性能对

2025-10-23.

Meta优化AI部门架构,裁员600人紧追行业竞争

meta公司近期对其人工智能部门展开大规模调整,宣布裁减约600名员工。此次裁员由首席人工智能官亚历山大·王通过内部备忘录披露,旨在精简组织架构、提升运营效率。被裁岗位主要涉及AI基础设施团队、基础

2025-10-23.

阿里夸克上线对话助手,Qwen模型融合搜索能力提升AI体验

阿里巴巴旗下智能应用夸克近日正式推出对话助手功能,该产品基于阿里自研的Qwen最新闭源大模型构建,成为国内首个将搜索服务与智能对话深度整合的AI工具。这一创新被视为夸克 "C计划 "战略的重要突破,此前

2025-10-23.

热门教程

更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程

最新下载

更多
逃跑吧少年oppo
逃跑吧少年oppo 休闲益智 2025-10-23更新
查看
寻光之旅
寻光之旅 角色扮演 2025-10-23更新
查看
点灯2叩门怨
点灯2叩门怨 角色扮演 2025-10-23更新
查看
风筝
风筝 动作冒险 2025-10-23更新
查看
地铁跑酷华为
地铁跑酷华为 休闲益智 2025-10-23更新
查看
崩溃大陆正
崩溃大陆正 角色扮演 2025-10-23更新
查看
贪婪的旅行者国际
贪婪的旅行者国际 休闲益智 2025-10-23更新
查看
忍者必须死3手游vivo
忍者必须死3手游vivo 飞行射击 2025-10-23更新
查看
克拉克拉
克拉克拉 休闲益智 2025-10-23更新
查看
地铁跑酷内置菜单
地铁跑酷内置菜单 休闲益智 2025-10-23更新
查看