小白科研笔记:深度连续卷积和它在深度补全中应用

1. 前言

由于LiDAR点云稀疏的特性,根据它得到的LiDAR深度图也是稀疏的。然而相机采集到的信息却是稠密的。这样一种反差对LiDAR-Camera多传感器信息融合造成挑战。Continuous Convolution是近年处理LiDAR-Camera信息融合的方法之一。这篇博客尝试探究Continuous Convolution在深度补全的应用。我将主要参考下面两篇文章:

(1)Shenlong Wang, Simon Suo, Wei-Chiu Ma, Andrei Pokrovsky, and Raquel Urtasun. Deep parametric continuous convolutional neural networks. In CVPR, 2018;
(2)Yun Chen, Bin Yang, Ming Liang, and Raquel Urtasun. Learning joint 2d-3d representations for depth completion. In ICCV 2019;

注:有趣的是这些文章都是Uber Advanced Technologies Group和University of Toronto合作成果。Continuous Convolution的发源地也在这里。

2. 深度连续卷积网络

第二章的讨论是循序渐进的。先从理论层面讲解参数化连续卷积,以及参数化连续卷积层,和它的计算细节;再从应用角度讲解参数化连续卷积层的搭建,以及深度连续卷积网络的实现。这归功于文献(1)的行文严谨。

2.1 参数化连续卷积

为了讨论起见,我把Parametric Continuous Convolutions直译为参数化连续卷积。先介绍连续卷积(Continuous Convolutions)。设连续信号是y(\cdot)(即输入特征图),核函数是g(\cdot),那么核函数卷积在连续信号上将得到连续卷积结果h(\cdot)(即输出特征图)。该过程如下所示:

h(x) = (f*g)(x) = \int_{-\infty}^{\infty} f(y)g(x-y) dy

作者认为获取连续信号y(\cdot)非常困难,因为实际应用中的物理模型非常复杂,并且观测者只能观察到y(\cdot)曲线上数个采样点\{ y_i \}_{i=1}^N。因此实际计算中,不能按照上式计算理想的h(\cdot),但是可以根据观测到的采样点按照下面的公式近似计算h(\cdot)

h(x) \approx \frac{1}{N} \sum_{i=1}^N f(y_i)g(x-y_i)

机器学习通过让h(\cdot)接近于预设值的方式(即训练过程),来学习核函数g(\cdot)的构造。考虑到实际应用的复杂性,核函数也可能是极其复杂的。为了便于学习和训练,依据万能近似定理(Universal approximation theorem),可以把核函数g(\cdot)近似看作是多层感知机(multi-layer perceptron,简称MLP)的输出。因此g(\cdot)可以写成下面所示。\theta是感知机的超参数,需要训练。

g(z; \theta) = MLP(z; \theta)

最终就能得到参数化连续卷积(参数化这个词就起源于超参数\theta):

h(x) \approx \frac{1}{N} \sum_{i=1}^N f(y_i)g(x-y_i) = \frac{1}{N} \sum_{i=1}^N f(y_i) \cdot MLP(x-y_i; \theta)

2.2 参数化连续卷积层

参数化连续卷积层是Parametric Continuous Convolution Layer的直译,它是参数化连续卷积概念的延伸(概念摘出,hhh)。原文这里有些抽象,不便于说明。为了方便讨论,就举个跟深度补全(depth completion)相关的栗子(我这个例子中使用的符号跟原论文是有出入的)。设想一个W \times H的深度图,里面有一部分像素是有深度值的,另一部分像素是没有深度值的。这就是个残缺的深度图。深度补全就希望把那些没有深度值的像素补上深度值。可以说深度补全也是矩阵补全(matrix completion)的特殊情况。设那些有深度值的像素集合记为S= \{ y_i \}_{i=1}^N。假设咱提取了集合S的特征,这些特征集合记为F= \{ f_i \in \textbf{R}^F \}_{i=1}^N,这些特征都是F \times 1的向量。现在咱想利用已知信息S和F来补全一个像素的深度值d_j,这个像素标记为x_j。从参数化连续卷积考虑,d_j的计算方式如下所示:

d_j = \sum_{i=1}^N (f_i)^T(g(x_j - y_i; \theta))

其中g(x_j - y_i; \theta)是MLP层,输出F \times 1的向量。d_j可以看作是已知特征向量的加权和,只不过权值函数由MLP表示,其参数需要学习训练。此外,d_j的计算可以用一个稠密图表示。这是参数化卷积跟图卷积有着密切联系的原因。

跳出这个例子,给出参数化连续卷积层的一般表示。作为概念上的Layer,它的输入是已知元素集合S= \{ y_i \}_{i=1}^N,该集合对应的特征向量集合F= \{ f_i \in \textbf{R}^F \}_{i=1}^N和目标元素x_j,输出是一个K \times 1的隐含层特征向量h_j=(h_{j,1}, ..., h_{j,K})^T。输出是K维的,那么它的核函数也有K个。因此参数化连续卷积层可以写成:

h_{j,k} = \sum_{i=1}^N (f_i)^T(g_k(x_j - y_i; \theta_k))

x_j - y_i具有几何意义。相当于在x_j建立了一个局部坐标系,把集合S= \{ y_i \}_{i=1}^N的坐标转换到该局部坐标系下。在诸多点云算法中,这种局部坐标系是常用的工具,它能建立目标点和周围点的拓扑联系。

说点题外话。从上式可以发现:h_j的计算离不开S= \{ y_i \}_{i=1}^N和它对应的F= \{ f_i \in \textbf{R}^F \}_{i=1}^N。这种计算形式跟K近邻算法以及支撑向量机(Support Vector Machine,简称SVM)是非常相似的。在SVM中,一个区域预测值的计算时根据Support Vectors对应特征加权和得到的。所以集合S也带有Support的味道。因此在原文中,集合S叫做support domain,译为支撑区域。此外这种“近邻计算”方式跟PointNet也有相似的地方。PointNet的support domain可以看做它均匀采样后的点。总而言之,这种直观的几何式的思想在2017年之后就影响着稀疏点云深度学习的方向。英雄所见略同啊。

2.3 计算细节

h_{j,k}计算量是O(N),计算开销过大,并且实际应用中两个距离相隔很远的像素点之间的关联很小。为了节省计算开销,h_{j,k}的计算只需要使用目标像素x_j附近的那些支撑像素点和对应特征就行了。寻找附近的支撑像素点有两个办法:(1)KNN;(2)以x_j画半径为r的圆。考虑到点云的无序性,KNN的实现需要借助于KD树加速。

注:KD树在CPU上运行很简单,但是处理上万个点云,速度达不到实时要求。KD树在GPU上运行需要Flann的CudaAPI,但是Flann库不太好和python合起来。pyflann貌似不支持GPU下调用。基于Pytorch实现的PointNet++提供了一些近邻搜索的功能函数,也许可以试试吧。

2.4 特殊情况

在一些特殊情况下,参数化连续卷积会向一些常见情形转化。如果集合S= \{ y_i \}_{i=1}^N是完全稠密的(e.g. 没有空洞的深度图),那么参数化连续卷积就会变成普通卷积。如果核函数g(\cdot)是Guassian形式的核函数,那么参数化连续卷积就是一个滤波算法(Filter)或者变成一个条件随机场(CRF)。如果S= \{ y_i \}_{i=1}^N仅仅包括目标元素周围的区域,那么参数化连续卷积对应为一阶空域图卷积(First-order spatial graph convolution)。

注:在论文中,参数化连续卷积的实现依赖于KNN,其实它性质上就等同于一阶空域图卷积了。关于图卷积的知识,后续有空也会做探究。

2.5 参数化连续卷积层的搭建

一个参数化连续卷积层的搭建如下图所示。输入是点云的xyz坐标和它的特征。输出是点云卷积后的特征(维度为O)。

                                                                    图1:参数化连续卷积层的示意图

在这个示意图中,使用KNN方法获取目标点周围的邻近点,作为支撑点(Supporting Points)。图1明确指出需要用KD树来实现KNN。Supporting Points Indices是一个N*K的张量。N是输入点的数量。K指的是某一点周围最近的K个点的索引(Indices)。Suppor Point Coordinates是一个N*K*3的张量,表示某一点周围最近的K个点的相对坐标,即x_j - y_i。Support Point Feature是一个N*K*I的张量I,表示某一点周围最近的K个点的输入特征,对应F= \{ f_i \in \textbf{R}^F \}_{i=1}^N。把Support Point Coordinates输入到两层全连接(FC)层,得到Support Point Weights,它是一个N*K*I*O的张量,对应\{g_o(x_j - y_i; \theta_o)\}_{o=1}^O。Weighted Sum就是h_{j,k}的计算过程。最后得到输出点云特征,它是N*O的张量。理解的话,倒并不难编程。

2.6 深度连续卷积网络的搭建

在2.5节讨论了参数化连续卷积层的搭建,这里将进一步研究深度连续卷积网络(Deep Parametric Continuous CNNs)的搭建。作者给出的点云语义分割示例网络如下图所示:

                                                                     图2:深度连续卷积网络示意图

Supporting Points Indices的概念在图1已经说明了。支撑点集是连续卷积必要输入之一。支撑点集就是目标点的近邻点,通过KD树调用KNN的方式实现。ContConv-x-y就是连续卷积层。xy分别表示其内两层FC层的神经元个数,这个在图1有体现。因此ContConv-x-y输出是N*y的张量。Concat处对应的残差连接(Residue connections)。PointNet系列也有池化和残差连接的网络方式。网络也会考虑batch normalization。语义分割旨在确定每一点的分类,多分类问题需要用到softmax。分类问题常用的损失函数就是交叉熵(Cross-Entropy)。

2.7 总结

稀疏点云是无序并且稀疏的。从稀疏点云上学习特征,会考虑到目标点的特征和它周围点特征的关联。具体实现的办法会有很多。其中,参数化连续卷积和PointNet系列就是近几年较为成功的方法之一。

3. 连续卷积在深度补全上的应用

主要讨论文献(2)。这篇文献的核心创新点有两个:(1)提出2D-3D fuse block;(2)提出带2D-3D fuse block的深度补全网络。网络效果当时排KITTI深度补全榜首,现在排前五。现有的top深度补全网络大多都是细节复杂的,要么网络设计有很多技巧设计复杂损失函数训练过程,要么需要额外数据集等各种数据增强方法。这篇文章的简洁和直观的几何含义吸引了我(笑哭笑哭)。在这一章,我会按照创新点的顺序逐次讲解。

3.1 2D-3D融合模块

2D-3D融合模块是2D-3D fuse block的直译。该模块使用了连续卷积的概念。深度补全的概念在第2.2节的例子中讲解了,这里就不再重复。深度补全旨在利用稠密RGB信息去引导LiDAR深度图的补全。回到这篇论文,在2D-3D fuse block这个词中,2D指RGB特征,3D指的是点云特征(深度图反投影而成)。fuse值RGB特征和点云特征的融合。所以作者设计2D-3D融合模块是期望有效处理RGB-D信息。2D-3D融合模块如下图所示:

                                                                      图3:2D-3D fuse block示意图

2D-3D融合模块输入是一个张量为C \times H \times W的2D输入特征图,以及一个张量为N \times 3的点云。它的输出是同尺寸的C \times H \times W的2D特征图。LiDAR-camera的外参数是已知量,这样可以把点云投影在成像平面上,进而通过缩放,确定点云在2D输入特征图上的位置。2D-3D融合模块由两个部分组成,分别是multi-scale 2D convolution network和3D continuous convolution network。

首先介绍多尺度2D卷积网络(multi-scale 2D convolution network)。作者把2D卷积标记为conv(k, s, c),其中k是核函数的尺寸,s是卷积stride参数,c是输出通道数。多尺度2D卷积网络由两个分支组成,分别是conv(3,1,C)分支和conv(3,2,C)分支。每次卷积之后使用Batch normalization和ReLU激活函数。原理比较简单。

其次介绍3D连续卷积网络(3D continuous convolution network)。考虑到雷达点云是稀疏的,对稀疏点云做卷积,就会需要参数化连续卷积。这已经在第二章做了详细讲解。具体实现过程是这样的:(0)前提条件,获取点云的KNN近邻点索引;(1)获取N \times 3的点云的特征N \times C。把点云投影在2D输入特征图上,投影点的特征就是对应点云的特征。(2)N \times 3的点云做连续卷积。对于目标点x_i,它的连续卷积特征h_i可以计算方式如下所示。(3)把N \times 3点投在一张空白C \times H \times W2D特征图上,投影点在空白2D特征图上的特征是连续卷积的结果。

h_i = W(\sum_{k} MLP(x_i-x_k) * f_k )

其中x_kx_i的近邻点。f_k是点x_k对应特征。MLP是两层全连接层,第一层包含C/2个神经元,而第二层包含C个神经元。W是一个C*C的权值矩阵。MLP的计算同样包含Batch normalization和ReLU激活函数。

最后把多尺度2D卷积网络和3D连续卷积网络的结果拼接起来得到,做些卷积处理,得到2D-3D fuse block的输出。

3.2 深度补全网络

理解了2D-3D fuse block,再看深度补全网络就会非常简单。网络原理图如下图所示。 把2D-3D fuse bloc叠起来即可,因为它的输入输出的2D特征图尺寸一样。损失函数设计比较简单,这里就不讨论了。

                                                                                 图4:深度补全网络

3.3 总结

2D-3D fuse block思想很直观,结构有很好的扩展性。也许有更为广泛的用途。2D-3D fuse block核心是连续卷积,它在3d目标识别也能发挥巨大的作用,可以参考我的另外一篇博客

发布了58 篇原创文章 · 获赞 36 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_39732684/article/details/104917675