1. 前言
点云是无序且没有结构的。这是任何基于点云的深度学习算法所必须考虑的常识。常用的处理方法有:(1)把点云体素化(Voxel)变成BEV图像,把点云的处理转换为图像的处理,在我的前一篇博客有所讨论;(2)使用参数化连续卷积(Parametric Continuous Convolutions)直接提取点云特征,在我的另一篇博客有所讨论;(3)从点云中采样出核心点,获得核心点特征,再经最大池化获得全局特征(Global feature),利用全局特征指导点云分类分割,这是PointNet++方法思想;(4)构建局部图(Local Graph),通过边缘卷积方式获得点的特征,这是EdgeConv思想。本篇博客主要讲解EdgeConv,其次讲解EdgeConv和PointNet++和参数化连续卷积的关系,最后讨论更为开放的内容。主要参考文献是:
Yue Wang et al,Dynamic Graph CNN for Learning on Point Clouds,2018
2. 动态图卷积网络
循序渐进的介绍动态图卷积网络,先从边缘卷积定义着手,再到边缘卷积层搭建,最后到动态图神经网络。
2.1 边缘卷积
Edge Convolution直译为边缘卷积。假设输入是由n个点组成的点云。简单情况下,F=3,即点云只含xyz信息。其实它也可以添加该点的RGB信息和法线信息。对一个目标点来说,通过它最近的k个点,可以建立一个关于的局部图。用索引表示为。根据的局部图,可以得到与附近点的边缘特征(Edge Feature),记为。是自定义的边缘特征提取函数。是一个维向量。是构成的需要学习的超参数。
注释1:这里有一个理论上的“坑”。对这句话“对一个目标点来说,通过它最近的k个点,可以建立一个关于的局部图”,仔细思考能够发现这句话的不严谨之处,即怎样衡量目标点的远近,换言之,即距离的刻画。如果说目标点只有xyz三个特征,距离毫无疑问是3维空间的欧式距离。如果说目标点有N个特征,距离可能是N维空间的欧式距离,或者自定义距离函数。
每个目标点有k个边缘特征。目标点特征应该是这K个边缘点特征的一种聚合操作(Aggregation)的结果,比如求和,相乘,或者最大最小。的特征可以是k个边缘特征之和,或者是K个边缘特征的点积(向量元素间的相乘),或者是k个边缘特征中范数最大。应该注意到这种聚合运算应该是对称的(Symmetric),不会受到K个点排序的影响。所以聚合运算应该是对称的。为了排版简单,使用符号表示对称聚合运算。记目标点的边缘卷积后的特征是。可由下式计算:
在作者给出的边缘卷积定义中,聚合运算和边缘特征提取函数是自定义的。围绕边缘特征提取函数,作者讨论了四种情况:
情况一:,即周围特征加权和,若聚合运算是求和的话,那么边缘卷积变成普通卷积;
情况二:,的输出特征只跟有关,认为代表了周围点的特征,是这一近邻区域的全局特征,那么边缘卷积退化为PointNet形式;它没有考虑周围点的特征;
情况三:,即周围相对特征加权和,仅仅使用局部特征,会丢失全局特征的信息;如果聚合运算是最大池化,那么这种情况跟PointNet++有些相似,也跟参数化连续卷积相似;
情况四,这是情况二和情况三的合并版,从形式上解决了前两个情况的缺点;这是文章作者采用的形式。它一方面保留了全局特征(即特征),同时保留了局部特征(即特征)。如下图所示:
2.2 边缘卷积层
Edge Convolution Layer直译为边缘卷积层。输入是第L层的点云特征,输入点特征的维度是;输出是第L+1层的点云特征,输出点特征的维度是。边缘卷积需要构建关于的近邻图,距离函数是维的欧式距离。或者说的近邻图建立在维欧式空间。计算公式如下所示:
其中输出维度为的特征。符号表示对称聚合运算。其中,采用情况四的方案。作者在实施时候,让每一层的都共享权值,即每一层都是一样的,那么。和PointNet一样,作者设定为多层感知机(MLP)。对称聚合运算符为最大操作(Max),即从K个输出特征中选出一个范数最大的特征作为输出。近邻点个数K的取值可以是20个或者30个。
从上述讨论能够发现,每一层边缘卷积都会建立一个近邻图,而不是一直沿用一样的近邻图。每一层的近邻图关系都可能是变化的,或者说是动态的,所以作者取名为动态图卷积网络(Dynamic Graph CNNs,简称DGCNN)。
2.3 搭建动态图卷积网络
作者设计了一个基于边缘卷积的动态图卷积网络,用于点云分割和识别,如下图所示:
图1:基于边缘卷积的动态图卷积网络示意图
这个网络跟PointNet很相似,因为它们都有Global Feature,即长度为1024的特征,用来指导点云的分割和识别。EdgeConv是边缘卷积模块,内部机理在2.2节讨论。MLP(a1,...,an)指该边缘卷积中特征提取函数构成。聚合操作是最大池化。spatial transform中n*k*6中6值是近邻两点的xyz向量的拼接,用张量n*k*6学习一个3*3的矩阵,然后作用在原始点云上。
注释二:这篇论文对spatial transform叙述非常少。对所预测的3*3的矩阵的描述几乎没有。任意的3*3的矩阵都可行吗?任意的3*3的矩阵作用在点云上没有物理意义。在回顾PointNet的时候,发现spatial transform其实对应PointNet中的T-Net。记这个3*3的矩阵为A。在PointNet中,该矩阵被认定是一个仿射矩阵(Affine Matrix),并且施加一个正则化约束:
这意味着矩阵A是一个旋转矩阵,或是一个对称变化矩阵。即A的作用是对原始点云做旋转或者对称的变换。总而言之,我在PointNet中找到答案。这篇论文对spatial transform的叙述是有逻辑缺陷。
3 对EdgeConv和其他点云处理方式的讨论
这一节是我的个人思考。仅供参考哈。在开篇我讲了四种常见处理点云的方法。读者可能对PointNet++比较熟悉。PointNet++使用最远点采样(Farthest Point Sampling,简称FPS),获得核心点,根据核心点和周围K个近邻点,以核心点为中心建立一个局部坐标系,使用pointnet中的运算(MLP和最大池化),获得这个核心点的特征;反复操作,核心点的特征能够化为一个全局特征向量,指导点云分类工作。不仅如此,PointNet++设定FPS的阈值和K的大小,在不同尺度范围下获取核心点特征,这种操作叫Multi-scale grouping(MSG)。MSG增强了PointNet++的鲁棒性。为了给PointNet++加速,FPS和K近邻都是在Cuda下实现的。基于Tensorflow的FPS和K近邻源码都很复杂(原版PointNet++)。基于Pytorch下的FPS和K近邻有参考意义(也复杂一些)。反正我只用Pytorch下的pointnet++(笑哭)。
或许初次看到PointNet++和EdgeConv,心里会产生疑问,总会觉得它俩都有KNN近邻点操作,就会问出类似它们有哪些异同之类的问题。其实把它们理解的透彻,就知道它们的不同了。EdgeConv建立的近邻图要比PointNet++规模更大,因为EdgeConv没有做采样。但是另一方面,因为每一个点在EdgeConv都有明确近邻关系,所以EdgeConv不会去采用MSG机制。然而,EdgeConv每一层都得根据特征空间距离计算一次近邻图。得到目标点和它近邻点时候,计算目标点特征的方式大同小异,对应2.1节的情况三和情况四。总体而言,我认为EdgeConv的计算复杂度更大,同时考虑到点云中点对关系更细致。然而成也萧何,败也萧何,EdgeConv处理大规模点云的效率也会非常非常低。应该会有工作在EdgeConv上进行。
再讨论一下EdgeConv和参数化连续卷积(Parametric Continuous Convolutions)之间的异同。参数化连续卷积是EdgeConv的特殊情况,因为它的近邻图仅仅根据三维欧式距离空间计算的,所以每一次层的近邻图都是一样的,无需重复计算。其次,参数化连续卷积的计算方式对应于2.1节的情况三。因此参数化连续卷积计算复杂度比EdgeConv低。但是它没有考虑的特征空间距离,没有EdgeConv考虑那么细致。
注释三:貌似还没有论文对比过EdgeConv和参数化连续卷积的性能。
4 几何性深度学习
这篇文章的综述写的也很不错。特别是Geometric Deep Learning这一段写的很出彩。因为我对这一块了解不深,所以只能写一段简单的导语。
Geometric Deep Learning就直译为几何性深度学习。几何性深度学习处理非欧式结构数据(non-Euclidean structured data)。非欧式结构数据可简单定义为这样一段话“对于数据中的某个点,难以定义出其邻居节点出来,或者是不同节点的邻居节点的数量是不同的”,源自这篇博客。非欧式结构数据的例子就是稀疏点云。而欧式结构数据的例子就是图像。
处理非欧式结构数据的主流思路是定义和找出“邻居节点”。而这种目标点和邻近节点的组合方式恰好是图结构(Graph),也可以是流形(Manifold,流形学习这里先不讨论)。处理欧式结构数据的主流方式是卷积。因此,处理非欧式结构的方式可以是图卷积。图卷积神经网络的研究早在2009年就已经开始。从2014年开始,有了更多的发展。