1. 引言
2018年之后出现较多新的处理点云的深度学习算法。这些文章从面向点云的卷积运算(Convolution for point cloud)着手,试图从更底层理解点云。这篇博客主要参考下面这篇CVPR 2019论文。这篇博客首先分析它的理论,其次讨论PointConv和已有其他框架的关系,最后论文中的综述。
Wenxuan Wu, Zhongang Qi, Fuxin Li: PointConv: Deep Convolutional Networks on 3D Point Clouds. CVPR 2019: 9621-9630
2. 点云卷积层
2.1 蒙特卡罗积分和点云分布
设 是 维实空间的任一点。 表示该空间下函数。它对 维实空间下一个区域 的积分是 。直接计算该积分非常复杂。蒙特卡罗积分法通过对区域 进行分布采样的方式,计算这个积分。计算过程如下所示。其中点集 采样自概率密度函数 。
上式表示点集 并不是个纯粹的随机数,而是按一种概率分布采集的。它对于雷达采集点云的过程是有意义的。雷达会向四周360度无差别的发射激光束,但是空间中只有那些有物体的地方才会发射激光束。对图像而言,视场范围内任意像素点都有对应的RGB值。不严谨地说,有值像素均匀分布于图像。不同于图像,对雷达产生的点云而言,视场范围内并不是所有地方都有点云。有值点云并不是均匀分布于视场,而是有的地方多,有的地方少。采样函数 是对点云分布的一种刻画。
这一段纯属信口开河,可以直接跳过。从另外一种角度讲,对 而言,它在区域 中并不是处处有值,而是在某些地方有值,某些地方没有。如果无差别地对区域 积分耗费计算量,在区域 中有值的区域积分无疑会减少计算量。举个例子,如果使用 计算区域 中的点云个数,那么 只有在 是点云的地方才能等于 。知道点云的分布,计算 将会更快。
2.2 从三维连续卷积到点云卷积
为了便于说明,首先考虑一块足够稠密且连续的点云(想象一个中子星)。它在空间中的 维度特征表示为 。 表示该点的坐标。如果我想对点云做三维卷积,提出关于 维度特征,那么核函数 应该是一个 的矩阵。二维连续卷积的范围并不无限的,而是存在一个感受野,即目标点周围的一块二维区域。推广二维连续卷积,三维连续卷积也存在感受野,设为目标点周围的一块三维区域 (比如一个近邻球)。即在 三维空间下的连续卷积结果为 。它的表达式如下所示。
上式三维卷积的计算量太大。考虑到现实情形是点云并不是稠密且连续的,而是稀疏且分散的,于是想用近似积分法更快地计算它。有两种近似积分法。(i)无差别地在区域 采样计算(黎曼积分)。(ii)有差别地在区域 中按密度分布 采样计算(蒙特卡洛积分)。考虑到点云分布有一定规律,作者采取蒙特卡洛法积分。使用蒙特卡洛法积分的三维卷积就是作者所提出的点云卷积(PointConv)。它的卷积结果为 。
其中 是密度分布的倒数, 。具体原因见2.1节蒙特卡洛法积分定义。为了计算PointConv,还需要定义 和 的具体计算方式。在这篇论文中, 定义为一个多层感知机(MLP)。它的输入是 维向量,输出是 维向量。 定义为一个核函数密度分布(Kernelized Density)和一个感知机的组合。核函数密度分布由区域 的点云位置估计得到。把 处点分布密度(标量)输入到一个感知机(它的输入输出都是1维的,相当于做1D nonlinear transform。并不是对分布密度简单做一个倒数)中,输出一个标量。
为了计算方便,把 干脆指定为目标点周围K个近邻点,那么PointConv可以计算为下式。其中 表示第 个点的第 个特征。 表示 的特征向量。
2.3 点云卷积层的计算图
论文作者在解释完PointConv之后,画了一张PointConv计算图来说明它的计算过程。
图1:PointConv计算图
先看这幅图中的蓝色字体“Compute Inverse Density Scale”,它在计算 。tile是张量扩充操作,使得扩充后的 维度跟 一致,方便做乘法运算。扩充后的 会跟 进行点到点的相乘。这是在计算 ,得到结果 。
再看这幅图中的红色字体“Compute Weight”,它在计算 。对于每一个点中的 维特征向量中的任意一个特征元素,都会放入MLP中,计算出一个 维特征。作者使用 卷积搭建MLP。因此整个 的维度是 。
注意到 的维度和 维度不一样,但是我们又需要做点乘得到 ,于是需要对 的维度做一个扩充,再次使用tile。最后结果需要在 和 维度上做连加,得到 。维度是 ,表示目标点卷积后的特征。
注释:为了让两个不同维度的张量顺利做点乘运算,为了高效率计算,需要把小维度的张量做扩充(Tile)。这是一个常见的技巧。Torch和Tensorflow都支持Tile运算。
入门的萌新可能会问, 的计算公式并不复杂呀,为啥它的计算图会这么复杂。在GPU运算中,最忌讳使用诸如For的迭代语句。这会让运算速率下降几十倍。为了避免任何For,需要设计一个快速的计算方法。
其实这个计算图就是作者代码实现的过程。后文会讲更为效率的实现PointConv方式。
2.4 改进的点云卷积层的计算图
作者认为2.3节中的计算PointConv的过程需要过大的内存。他们又设计了一个轻量快速的计算方式。改进版的计算图如下所示:
图2:改进版PointConv计算图
如果理解了图1,再看图2就不会觉得困难。主要的改动是Compute Weight部分。把其中一个 卷积移动到末尾了。首先说一个改进的结果,它对GPU显存的需求比原版少了64倍。其次说一下感想。图1的计算时根据公式而来,有直观的含义,但是运算量大。图2的计算少了直观含义,但是运算快捷,是作者们用心解决问题的体现。怎么说呢,当你用智慧和勇气直面难题的时候,也许会欣喜发现一个意想不到的解决方法。
原文的推导公式比较清晰易懂。这里就不多说啦。
2.5 基于点云卷积的网络
话不多说,放上作者的网络结构图。
图3:基于PointConv的网络示意图
从样子上看,它是一个Encoding-Decoding(编码器到解码器)架构。跟PointNet结构相近。绿方框表示Feature encode,其实对应于PointNet++中的Sample层和Group层。Interpolation层很直接,不想PointNet++在插值后带上PointNet层。网络结果挺简单的。
3. 个人感想
下面是个人胡扯时间。
在纯点云深度学习处理上,自PointNet++后,近两年的顶会录用的paper喜欢在point卷积上下功夫,100%都是围绕近邻点展开的,给人很多启发和灵感,有很大的学术价值和工业价值。而且编程门槛并不高。对于纯点云非深度学习算法,从邻近点提取特征设计各式各样的描述子,也是老生常谈话题。所以,我感觉这样单纯的发展似乎到了尽头。而且做的实验跟实际的应用有距离。往后的发展应该面向大规模点云(复杂环境下点云分割)或者面向Multi-Sensor场景应用(LiDAR-camera深度补全和3D目标识别),在或者用于点云其他方面的应用(更加鲁棒的点云配准,点云补全,点云和RGB图的重识别)等等。