首页IT科技point of view(Pointnet/Pointnet++学习)

point of view(Pointnet/Pointnet++学习)

时间2025-05-03 09:21:52分类IT科技浏览4047
导读:一、点云的应用...

一            、点云的应用

二                 、点云的表述 三     、Pointnet 四      、Pointnet++

Pointnet++概述

虽然这篇文章叫PointNet++            ,但和PointNet相比还是有很大的改进            。文章非常核心的一点就是提出了多层次特征提取结构                 。具体来说就是先在输入点集中选择一些点作为中心点                 ,然后围绕每个中心点选择周围的点组成一个区域     ,之后每个区域作为PointNet的一个输入样本      ,得到一组特征                 ,这个特征就是这个区域的特征     。之后中心点不变           ,扩大区域      ,把上一步得到的那些特征作为输入送入PointNet                 ,以此类推           ,这个过程就是不断的提取局部特征,然后扩大局部范围                 ,最后得到一组全局的特征                ,然后进行分类      。文章中还提出了多尺度的方法解决样本不均匀的问题,这些方法对于分类的精度没有贡献            ,但在样本很稀疏的时候的确能让模型更有鲁棒性                 。

1. Abstract

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

2. Introduction

在PointNet++中                 ,作者利用所在空间的距离度量将点集划分(partition)为有重叠的局部区域(可以理解为patch)                 。在此基础上                ,首先在小范围中从几何结构中提取局部特征(浅层特征),然后扩大范围            ,在这些局部特征的基础上提取更高层次的特征                ,知道提取到整个点集的全局特征                。可以发现     ,这个过程和CNN网络的特征提取过程类似            ,首先提取低级别的特征                 ,随着感受野的增大     ,提取的特征level越来越高。

PointNet++需要解决两个关键的问题:第一      ,如何将点集划分为不同的区域;第二                 ,如何利用特征提取器获取不同区域的局部特征            。这两个问题实际上是相关的           ,要想通过特征提取器来对不同的区域进行特征提取      ,需要每个分区具有相同的结构                。这里同样可以类比CNN来理解                 ,在CNN中           ,卷积块作为基本的特征提取器,对应的区域都是n*n的像素区域     。而在3D点集当中                 ,同样需要找到结构相同的子区域                ,和对应的区域特征提取器            。

在本文中,作者使用了PointNet作为特征提取器            ,另外一个问题就是如何来划分点集从而产生结构相同的区域                 。作者使用邻域球球来定义分区                ,或者也可以叫做patch     ,每个区域可以通过中心坐标和半径来确定     。中心坐标的选取            ,作者使用了快速采样算法来完成(farthest point sampling (FPS) algorithm)      。区域半径的选择是一个比较有挑战性的事情                 ,因为输入点集是不均匀的     ,同时区域特征会存在重叠或被遗忘的情况                 。尽管在VGG当中提到      ,CNN使用小的卷积核效果比较好                 ,但这是由于图像是网格化的           ,每个区域是非常规整的      ,如果再PointNet++使用小的半径                 ,网络性能反而很差           。这里可以从直观上想象一下           ,邻域球过小,可能意味着可能看不到足够完整的局部特征      。这个过程也可是使用KNN实现                 。

3. 网络结构

PointNet++是PointNet的延伸                 ,在PointNet的基础上加入了多层次结构(hierarchical structure)                ,使得网络能够在越来越大的区域上提供更高级别的特征           。

网络的每一组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’是新的特征维度。下面详细介绍每一层的作用及实现过程            。

1). Sample layer

使用farthest point sampling选择N’个点           ,至于为什么选择使用这种方法选择点      ,文中提到相比于随机采样                 ,这种方法能更好的的覆盖整个点集                。具体选择多少个中心点           ,数量怎么确定,是由人来指定的     。

2). Grouping layer

这一层使用Ball query方法生成N’个局部区域                 ,根据论文中的意思                ,这里有两个变量 ,一个是每个区域中点的数量K            ,另一个是球的半径            。这里半径应该是占主导的                ,会在某个半径的球内找点     ,上限是K                 。球的半径和每个区域中点的数量都是人指定的     。这一步也可以使用KNN来进行            ,而且两者的对于结果的影响并不大      。

3). PointNet layer

这一层是PointNet                 ,接受N’×K×(d+C)的输入                 。输出是N’×(d+C)           。需要注意的是     ,在输入到网络之前      ,会把该区域中的点变成围绕中心点的相对坐标      。作者提到                 ,这样做能够获取点与点之间的关系(对这一点存疑           ,但感觉有限像Batch Norm?)                 。

4). 对于非均匀点云的处理方法

点云不均匀时      ,每个子区域中如果在分区的时候使用相同的球半径                 ,会导致有些稀疏区域采样点过小           。这个地方插一点自己的想法           ,从一个角度来看,点云的疏密程度是不是可以看做样本属性的一部分?从这个意义上来讲这就不是一个需要克服的缺点。如果担心某些区域采样点过小                 ,是否可以加一个阈值下限                 。

作者提到这个问题需要解决                ,并且提出了两个方法:Multi-scale grouping (MSG) and Multi-resolution grouping (MRG)                。下面是论文当中的示意图。

下面分别介绍一下这两种方法            。第一种多尺度分组(MSG),对于同一个中心点            ,如果使用3个不同尺度的话                ,就分别找围绕每个中心点画3个区域     ,每个区域的半径及里面的点的个数不同                。对于同一个中心点来说            ,不同尺度的区域送入不同的PointNet进行特征提取                 ,之后concat     ,作为这个中心点的特征     。也就是说MSG实际上相当于并联了多个hierarchical structure      ,每个结构中心点数量一样                 ,但是区域范围不同(可以理解成感受野?)           ,PointNet的输入和输出尺寸也不同      ,然后几个不同尺度的结构在PointNet有一个Concat            。

另一种是多分辨率分组(MRG)                 。MSG很明显会影响降低运算速度                 ,所以提出了MRG           ,这种方法应该是对不同level的grouping做了一个concat,但是由于尺度不同                 ,对于low level的先放入一个pointnet进行处理再和high level的进行concat     。感觉和ResNet中的跳连接有点类似      。

在这部分                ,作者还提到了一种random input dropout(DP)的方法,就是在输入到点云之前            ,对点集进行随机的Dropout,比例使用了95%                ,也就是说进行95%的重新采样                 。某种程度有点像数据增强     ,也是提高模型的robustness           。那这些方法效果怎么样呢            ,我们一起来看一下      。

从论文中的这幅分类实验结果图可以看出来                 ,多尺度(MSG,MRG)和单一尺度相比(SSG)对分类的准确率没有什么提升     ,有一个好处是如果点云很稀疏的话      ,使用MSG可以保持很好的robustness                 。对于robustness效果random input dropout(DP)其实贡献更大           。

从论文中的分割实验结果看                 ,使用(MSG+DP)之后的确是比SSG结果提升了           ,在非均匀点云上差距会大一点      ,但是作者并没有给出MSG和DP对于效果提升单独的贡献对比                 ,所以我们很难确定到底是MSG还是DP在这其中起作用了。

4. 通过代码理解核心结构

通过核心代码来理解一下PointNet++中的hierarchical structure(也叫set abstraction layers)到底是这怎工作的           ,上图是3层set abstraction layers(以SSG(单一尺度)为例)                 。

我们以第一层set abstraction layers为例解释一下,对应line9代码(PointNet Set Abstraction (SA) Module)                。假设输入点云数据是(16,1024,3)                 ,也就是一个样本1024个点                ,只有xyz坐标。把它送入到第一层set abstraction layers            。设置的参数:

l0_xyz: <只包含坐标的点> l0_points: <不仅包含坐标,还包含了每个点经过之前层后提取的特征            ,所以第一层没有> npoint = 512: <Sample layer找512个点作为中心点                ,这个手工选择的     ,靠经验或者说靠实验> radius=0.2: <Grouping layer中ball quary的球半径是0.2            ,注意这是坐标归一化后的尺度> nsample=32: <围绕每个中心点在指定半径球内进行采样                 ,上限是32个;半径占主导> mlp=[64,64,128]:<PointNet layer有3层     ,特征维度变化分别是64,64,128> #还有别的参数      ,不太要紧                 ,这里去掉不说

进一步看一下每一层是怎么实现的           ,重点看数据的传递形式                。

SA(512,0.2,[64,64,128]) -> SA(128,0.4,[128,128,256]) -> SA([256,512,1024]) ->

FC1 -> FC2 -> FC(K)

数据首先进行sampling 和 grouping,对应下面代码      ,看一下这个函数如何实现     。

这个函数输入就是上面传进来的                 ,解释一下输出            。

new_xyz: 经过sampling后           ,得到的512个中心点的坐标 idx:是每个区域内点的索引 grouped_xyz:分组后的点集,是一个四维向量(batch_size, 512个区域                 ,每个区域的32个点                ,每个点3个坐标) new_points:也是就是分组后的点集,不过里面存的是特征            ,如果是第一次                ,就等于grouped_xyz     ,可以选择在卷积的时候把坐标和特征进行concat后卷积                 。

采样之后很重要的一点是分区            ,就是上面这个两个函数                 ,如果是使用KNN分区     ,因为只是取每个中心点周围的固定个数的点(即上面提到的32)      ,idx就是这些坐标的索引                 ,点的个数就是(32*512)           ,可以发现      ,原始点云是1024个                 ,这样就必然会导致区域重叠           ,没关系,这是需要的效果     。

ball query后得到的是idx,和pts_cnt                 ,因为是优先根据radius分区                ,每个区域的点的数量是不确定的(最大32),所以pts_count就是计数的            ,每个区域有多少个点                ,方便把idx分开      。

下图是ball query(a)和KNN(b)的示意图     ,一个是半径为主            ,一个是只看点的数量                 。

得到每个区域的点的索引后分组                 ,结果是一个四位向量(batch_size, 512个区域     ,每个区域的32个点      ,每个点3个坐标)                 ,如下图           。这里感觉有个漏洞           ,如果是用ball query得到的      ,每组的点的个数不是32                 ,但这里又没有传入pts_cnt的值           ,那又是怎么知道如何分配idx?

下面来看PointNet层

grouping后的点集进行卷积,可以注意一下                 ,我们上面已经说过                ,new_points是一个4维向量<(batch_size,512, 32, 3)——(batch_size, 512个区域            ,每个区域的32个点                ,每个点对应的特征)>512个区域     ,每个区域32个点      。每个区域的32个点经过PointNet的卷积核池化            ,整合成一组特征                 ,这一组特征就属于每个区域的中心点                 。

参考文献:https://zhuanlan.zhihu.com/p/88238420

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
wordpress sitemap插件(用WordPressSEO中文插件提升网站排名) linux swap和mem(Linux系统swap和zram swap的使用详解)