首页 > 其他分享 >[CVPR2020] RandLA-Net: Efficient Semantic Segmentation of Large-Scale Point Clouds论文浅析

[CVPR2020] RandLA-Net: Efficient Semantic Segmentation of Large-Scale Point Clouds论文浅析

时间:2023-03-20 19:44:06浏览次数:62  
标签:采样 neighbors Segmentation Scale 特征 self PointNet RandLA 浅析

大佬的TensorFlow代码:here
另一个大佬的Pytorch代码:等我看完代码再贴链接,之前那个不太行

keywords


在正式开始讲论文之前,我们先看看效果, 0.04s的inference timeimage
那么咱们正式开始


相关工作

\(_{*篇幅有限,此处不再介绍其他基于投影或基于体素的工作}\)

PointNet++

  • 网络结构
    image

  • 关键组件

    • Samping——FPS(最远点采样)

    顾名思义,每次在点云中采样的点都应该距其他点的距离最远
    举个例子,下图,一个二维欧式空间中,我们需要使用FPS采样4个点;最简单的步骤是:

    1、从七种颜色中随机选择一个 [例,选择二项限的橙猫猫]
    2、寻找距橙猫猫最远的点(欧式距离) [选择一象限的小紫]
    3、寻找距离小紫和橙猫猫都最远的点 [选择三象限的淡淡色]
    4、重复上述步骤,直到采样完成 [最后应该选择四象限的小绿]

    优点:能够尽可能覆盖空间中的所有点
    缺点:计算复杂度高

    下图为一张使用FPS得到的采样点

    image

    • Grouping——ball_query(球查询)

    PointNet++的思路为:在原始点云中采样若干点(后称Centroids),并在Centroids邻域里采样K个点(包括Centroids)构成分组,然后在每个分组内使用PointNet;FPS已经完成了第一步,现在,我们继续使用ball_query找到Centroids周围的K个点
    较于ball_query,大家肯定更熟悉KNN这个算法,所以我们先从KNN入手:

    1、计算周围点和Centroids的距离 [如果使用xyz坐标,就是在欧式空间中的距离;如果使用网络在本层的特征向量,那么就是特征空间中的距离]
    2、每次将距离最近的点与Centroids归为同一组
    3、重复,直到采集到K个点

    ball_query与KNN的区别则在于:ball_query增加了一个参数radius,约束采样点必须在一定半径的球域上,当球域内的点≥待采点K时,同KNN;反之,直接用第一个点的特征补全。

PointCNN

  • 网络结构
    image
  • 说明
    • 由于PointCNN与PointNet++在采样和分组时使用的方法基本相同,即FPS和KNN,此处不再说明,主要就其对于卷积结构的改进进行一些说明。

      在这之前,咱们需要明确一下点云的置换不变性,置换不变性是指点云不管以何种顺序输入网络,都应该得到相同的结果,所以PointNet++使用了PointNet作为每个分组的处理网络,但PointNet这种对每个点单独处理的网络注定不能取得很好地效果;所以,这篇文章提出了一种在点云中的卷积结构,既保证了置换不变性,也能更好地利用邻域内的特征,\(\mathcal{X}conv\)算法如下:
      image


RandLA-Net

对采样策略的分析改进

  • 启发式的采样策略
采样方式 Farthest Point Sampling (FPS) Inverse Density Importance Sampling (IDIS) Random Sampling (RS)
复杂度 \(\mathcal{O}(N^2)\) \(\mathcal{O}(N)\) \(\mathcal{O}(1)\)
  • 基于学习的采样策略
采样方式 Generator-based Sampling (GS) Continuous Relaxation based Sampling (CRS) Policy Gradient based Sampling (PGS)
存在问题 效率太低 内存占用大 在大规模点云上难以收敛

\(_{*部分采样方式我也没用过,各位如果对这部分感兴趣的可以去看看其他教程,我就不在这误人子弟了}\)

可以看出,FPS、IDIS和GS等方法在大规模点云上的效率很低;CRS和PGS等方法也会出现其他问题;所以,作者最后选择了随机的采样策略(即RS),虽然随机采样会带来采样不均匀、丢失关键点等问题,但起码保证了采样过程的效率和稳定性。

网络结构

image

image
这部分可以被看作结构中的一个layer,我们按照处理顺序对结构进行分析

  • Local Spatial Encoding
  1. 首先,对于输入,这是我们每次通过随机采样后得到的点Input.shape=(N, 3+d),每个点特征维中的3代表其xyz坐标,后面的d代表特征维度。
  1. 接下来,使用KNN采集每个采样点周围的近邻点(欧氏距离),并将其分组,Grouping.shape=(N, K, 3+d)。
  1. 现在,我们已经完成了采样和分组这两步,得到了N个局部点集,接下来,我们需要对每个局部做处理。
  1. 对每个组内的特征,LocalFeature.shape=(K, 3+d),我们将坐标和特征分开处理(实际上,在代码中这部分是分别输入的),对坐标,我们计算每个点和Centroids之间的各种距离,并将这些距离通过concat连接起来,实验证明,这种冗余特征是有益于模型学习的;将这些通过一个MLP后,我们最后得到\(r_{i}^{k}\).shape=(K, d)的特征,公式如下: \(r_{i}^{k}=MLP(p_{i}\oplus p_{i}^{k}\oplus (p_{i}-p_{i}^{k})\oplus ||p_{i}-p_{i}^{k}||)\),将\(r_{i}^{k}\)与\(f_{i}^{k}\)concat起来,我们就得到了组内各点的局部编码。

这一模块的功能是:将组内各点的位置特征进行一定处理之后,与各点原本特征concat,丰富了模型可学习的特征,代码实现如下:

class LocalSpatialEncoding(nn.Module):
    def __init__(self, d, num_neighbors, device):
        super(LocalSpatialEncoding, self).__init__()

        self.num_neighbors = num_neighbors
        self.mlp = SharedMLP(10, d, bn=True, activation_fn=nn.ReLU())

        self.device = device

    def forward(self, coords, features, knn_output):
	# KNN
        idx, dist = knn_output
        B, N, K = idx.size()

	# concat position feature
        extended_idx = idx.unsqueeze(1).expand(B, 3, N, K)
        extended_coords = coords.transpose(-2,-1).unsqueeze(-1).expand(B, 3, N, K)
        neighbors = torch.gather(extended_coords, 2, extended_idx)
        concat = torch.cat((
            extended_coords,
            neighbors,
            extended_coords - neighbors,
            dist.unsqueeze(-3)
        ), dim=-3).to(self.device)

	# concat r and f
        return torch.cat((
            self.mlp(concat),
            features.expand(B, -1, N, K)
        ), dim=-3)
  • Attentive Pooling
    实际上,这个部分就相当于PointNet中的MaxPooling结构,如果我们不讨论内部结构,那么这个模块完成的任务就是将\(\hat{f_{i}^{k}}\).shape=(K, 2d)通过pooling变为output.shape=(1, d'),后面作者也做了实验证明了他提出的Attnpool确实更有效。

formula of maxpool and attnpool

\(maxpool = \max(Linear(feature))\)

\(attnpool = Linear\{\sum[feature\odot softmax(Linear(feature))]\}\)

上述公式描述了Attentive pooling的实现,可以发现,作者使用类似注意力机制的方式得到了各特征各分量的注意力得分,使用element-wise multiplication与feature相乘。下面是代码实现,很简单。

        # computing attention scores
        scores = self.score_fn(x.permute(0,2,3,1)).permute(0,3,1,2)

        # sum over the neighbors
        features = torch.sum(scores * x, dim=-1, keepdim=True) # shape (B, d_in, N, 1)

        return self.mlp(features)

至此,我们完成了RandLA-Net中基本单元的构建,我们姑且把它称为RandLA-Net Vanilla(笑),接下来就像ResNet一样,往上堆layer就行了(暴言)

  • Dilated Residual Block
    这部分在结构上没啥内容可讲,实际上就是两层RandLA-Net Vanilla加上一个残差连接而已;剩下的内容留到实验部分一起说。
    image

在讲实验之前,先来看看整体的模型结构先,确实是堆layer(笑)
image

实验

\(_{*作者的训练设备AMD 3700X @3.6GHz CPU + NVIDIA RTX2080Ti GPU.}\)

  • 关于各种采样方式的效率
    image
    很直观,可以看到随机采样在效率和内存占用上都有非常优秀的表现

  • 消融实验
    image
    对这个表做一些解释:

(1)去掉LocalSE模块

可以看出,去掉LocalSE模块后,对mIoU的影响较大,因为这种组内的局部几何关系在点云中是很有必要的;之前也提到,PointNet就缺少这种点与点之间的几何关系特征。

(2~4)将AttnPool换为Max、Mean、SumPool

证明了作者的AttnPool要优于其它池化方式

(5)简化残差模块

不知道各位是否还记得之前我们埋的坑?随机采样的策略可能会导致关键点的丢失,从而导致模型效果不好这里作者分析,如果使用两层RandLA-Net Vanilla之后再进行残差连接,那么每个采样点都会学到周围\(K^2\)范围内的点特征[可以理解为感受野],感受野大了,采样点能够学到关键点的概率也就增大了;所以,效果也就更好。

  • 对比实验
    无非是突出了自己的方法使用的点云规模更大,效果更好了。毕竟是顶会,没点SOTA怎么行。
    image

写在最后

姑且算是讲完了,我也要去跑复现了,到时候有心得就再开一坑。PS:没想到搞复现最难的不是看代码,是下数据集,semanticKITTI...

标签:采样,neighbors,Segmentation,Scale,特征,self,PointNet,RandLA,浅析
From: https://www.cnblogs.com/myblog-paper/p/17220432.html

相关文章

  • TCP协议得物联网安全浅析
    公司做物联网项目,后端采用java+netty开发,端口如果直接暴露使之容易被扫描攻击。故实现自定义TCP头,这样可以在握手阶段就丢弃数据包,达到提高攻击门槛的目的。 在......
  • 数据大屏最简单自适应方案 scale
    使用scale适配大屏。实现数据大屏在任何分辨率的电脑上均可安然运作。无需特定编写rem单位,也不需要考虑单位使用失误导致适配不完全。您即使全部用position去定位在其他屏......
  • 从OTA测试变革浅析OTA测试系统升级方向
    小标题1:OTA测试的变革  自去年以来,OTA逐渐开始从少数“高端玩家”的卖点,成为汽车行业普遍应用的功能,各传统或新兴OEM都逐步开始在OTA上做布局,而随之而来的就是整个OTA......
  • Tomcat源码浅析
    1.Tomcat的功能和架构1.1.Tomcat有两大功能Http服务器功能:Socket通信(Tcp/IP),解析Http报文。Servlet容器功能:Servlet处理具体的业务请求。1.2.Tomcat架构Tomcat是套......
  • 浅析前端自动部署工具deploy-cli-service和vscode使用sftp自动部署插件
    一、前端自动部署工具deploy-cli-service1、先安装deploy-cli-service依赖//全局安装deploy-cli-servicenpminstalldeploy-cli-service-g//本地安装deploy-cl......
  • Spring-IOC理论浅析
    IOC理论最开始时业务实现:UserDao接口UserDaoImpl实现类UserService业务接口UserServiceImpl业务实现类在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们......
  • 关于sklearn中StandardScaler的使用方式
    在机器学习中经常会使用StandardScaler进行数据归一化,注意一旦调整好StandardScaler以后就保存下来,后面如果进行测试单个时,可以进行加载并对其进行标准化StandardScaler......
  • 查询性能: TDengine 最高达到了 InfluxDB 的 37 倍、 TimescaleDB 的 28.6 倍
    在上一篇文章《写入性能:TDengine最高达到InfluxDB的10.3倍,TimeScaleDB的6.74倍》中,我们基于TSBS 时序数据库(TimeSeriesDatabase)性能基准测试报告对三大数据库......
  • 浅析三款大规模分布式文件系统架构设计
    什么是文件系统当提到文件系统,大部分人都很陌生。但我们每个人几乎每天都会使用到文件系统,比如大家打开Windows、macOS或者Linux,不管是用资源管理器还是Finder,都是在......
  • Tailscale搭建教程
    ailscale是一款基于WireGuard的虚拟组网工具。不懂的话你就理解为它是一个非常方便的局域网架设工具。这个工具主要实现了,多终端启动服务后,共同处于同一个局域网并有固定......