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

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

热心网友 时间:2025-07-24
转载
本文介绍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
登录后复制    
来源:https://www.php.cn/faq/1425374.html

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

同类文章
更多
工信部发布防范 OpenClaw(“龙虾”)开源智能体安全风险“六要六不要”建议

工信部发布防范 OpenClaw(“龙虾”)开源智能体安全风险“六要六不要”建议

工信部发布“六要六不要”,为OpenClaw(“龙虾”)开源智能体安全风险划出红线 近日,工业和信息化部网络安全威胁和漏洞信息共享平台发布了一份重磅文件,针对当前热门的OpenClaw(因其图标酷似龙虾,业内常昵称为“龙虾”)开源智能体,提出了清晰的安全使用指引——“六要六不要”。这份建议可不是空穴

时间:2026-04-02 11:16
荣耀 CEO 李健:荣耀机器人全栈自研,将聚焦消费市场

荣耀 CEO 李健:荣耀机器人全栈自研,将聚焦消费市场

荣耀CEO李健详解机器人战略:全栈自研,聚焦三大核心消费场景 荣耀春季旗舰新品发布会圆满结束后,关于公司未来发展的蓝图更加清晰。在随后的媒体沟通会上,荣耀CEO李健不仅公布了年度销售目标,更首次系统性地阐述了荣耀在机器人领域的完整战略规划与市场布局。 在探讨机器人业务发展方向时,李健明确了荣耀的坚定

时间:2026-04-02 11:14
别只盯着“上门装龙虾赚26万”!看懂OpenClaw背后的“意图入口”大战

别只盯着“上门装龙虾赚26万”!看懂OpenClaw背后的“意图入口”大战

别再只关注“上门装龙虾赚26万”!深度解读OpenClaw背后的“意图入口”新战争 最近科技行业的热潮,充满了戏剧性的现实色彩。一只“红色龙虾”AI智能体搅动了整个市场:有人通过提供安装服务,收取每次五百元,短短几天就赚取二十六万元收入;腾讯大厦前甚至排起长队,大家竞相领取免费的安装体验权限。这场全

时间:2026-04-02 11:00
openclaw安装配置

openclaw安装配置

一、系统要求 在开始安装 OpenClaw 之前,请务必确认您的计算机满足以下最低配置要求。这如同搭建房屋前检查地基,是确保后续安装流程顺利、软件稳定运行的前提。更高的硬件配置将为复杂任务处理和流畅体验提供有力保障。 操作系统:支持 Windows 10 及以上版本、macOS 最新稳定版,以及主流

时间:2026-04-02 10:53
自研第一个SKILL-openclaw入门

自研第一个SKILL-openclaw入门

自研第一个SKILL:手把手教你开发openclaw自定义技能 当你成功构建好openclaw之后,如何让它真正“智能”起来?关键在于为其开发SKILL——这些技能是openclaw的“内功心法”,决定了它能帮你做什么、做多好。 本文将带你亲自动手,从零开始开发你的第一个openclaw自定义技能,

时间:2026-04-02 10:40
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程