GCNv2的理解历程

纯小白最近因为实习的事情需要了解GCNv2这个算法,论文和github代码链接分别如下

论文链接:https://arxiv.org/pdf/1902.11046v3.pdf

代码地址:https://github.com/jiexiong2016/GCNv2_SLAM

首先简单介绍一下,GCNv2是对GCN(Geometric Correspondence Network)的改进,是一种能够计算图像关键点和描述子的深度神经网络,可以用于作为实时SLAM的前端。其网络结构设计受到了SuperPoint的启发。GCNv2采用了ORB相同格式的二进制描述子,这样它就能够比较容易的替换ORB-SLAM2中的ORB描述子。实验表明,GCNv2在精度上与GCN保持相当,能满足实时性要求(以Jetsom TX2为平台),在无人机上的实验展示了其鲁棒性。

可以看到有很多名词(因为是小白基本刚接触),GCNv2,GCN,SLAM,SuperPoint,ORB-SLAM2,深度神经网络,等。经过一番查阅,大概是弄懂了之间的联系。因此本文打算从卷积开始捋思路,试图解释GCNv2的发展历程。

先放一张关系图。

一、数学中的卷积

一些有用的参考链接:

卷积的重要的物理意义是:一个函数(如:单位响应)在另一个函数(如:输入信号)上的加权叠加。

连续形式:

$$
(f * g)(n)=\int_{-\infty}^{\infty} f(\tau) g(n-\tau) d \tau
$$

离散形式:

$$
(f * g)(n)=\sum_{\tau=-\infty}^{\infty} f(\tau) g(n-\tau)
$$

图像的卷积:

对图像的处理函数(如平滑,或者边缘提取),也可以用一个g矩阵来表示

$$
g=\left[\begin{array}{ccc}
b_{-1,-1} & b_{-1,0} & b_{-1,1} \\
b_{0,-1} & b_{0,0} & b_{0,1} \\
b_{1,-1} & b_{1,0} & b_{1,1}
\end{array}\right]
$$

从卷积定义来看,应该是在x和y两个方向去累加(对应上面离散公式中的i和j两个下标),而且是无界的,从负无穷到正无穷。可是,真实世界都是有界的。例如,上面列举的图像处理函数g假设上是个3x3的矩阵,那么,在除了原点附近以外,其它所有点的取值都为0。所以,真正的计算如下所示: 

​​首先我们在原始图像矩阵中取出(u,v)处的矩阵:

$$
f=\left[\begin{array}{ccc}
a_{u-1, v-1} & a_{u-1, v} & a_{u-1, v+1} \\
a_{u, v-1} & a_{u, v} & a_{u, v+1} \\
a_{u+1, v-1} & a_{u+1, v} & a_{u+1, v+1}
\end{array}\right]
$$

然后将g矩阵翻转180°

$$
g^{\prime}=\left[\begin{array}{ccc}
b_{1,1} & b_{1,0} & b_{1,-1} \\
b_{0,1} & b_{0,0} & b_{0,-1} \\
b_{-1,1} & b_{-1,0} & b_{-1,-1}
\end{array}\right]
$$

则可以得到卷积结果。以上计算的是(u,v)处的卷积,延x轴或者y轴滑动,就可以求出图像中各个位置的卷积,其输出结果是处理以后的图像(即经过平滑、边缘提取等各种处理的图像)。

再深入思考一下,在算图像卷积的时候,我们是直接在原始图像矩阵中取了(u,v)处的矩阵,推而广之,如果如果g矩阵不是3x3,而是7x7,那我们就要在原始图像中取以(u,v)为中心的7x7矩阵进行计算。由此可见,这种卷积就是把原始图像中的相邻像素都考虑进来,进行混合。相邻的区域范围取决于g矩阵的维度,维度越大,涉及的周边像素越多。而矩阵的设计,则决定了这种混合输出的图像跟原始图像比,究竟是模糊了,还是更锐利了。

比如说,如下图像处理矩阵将使得图像变得更为平滑,显得更模糊,因为它联合周边像素进行了平均处理:

$$
g=\left[\begin{array}{lll}
\frac{1}{9} & \frac{1}{9} & \frac{1}{9} \\
\frac{1}{9} & \frac{1}{9} & \frac{1}{9} \\
\frac{1}{9} & \frac{1}{9} & \frac{1}{9}
\end{array}\right]
$$

而如下图像处理矩阵将使得像素值变化明显的地方更为明显,强化边缘,而变化平缓的地方没有影响,达到提取边缘的目的:

$$
g=\left[\begin{array}{ccc}
-1 & -1 & -1 \\
-1 & 9 & -1 \\
-1 & -1 & -1
\end{array}\right]
$$

二、CNN中的卷积

参考:如何理解 Graph Convolutional Network(GCN)? - 知乎 (zhihu.com)

名词解释:卷积神经网络(Convolutional Neural Networks, CNN)

如下图所示,CNN中的卷积本质上就是利用一个共享参数的过滤器(kernel),通过计算中心像素点以及相邻像素点的加权和来构成feature map实现空间特征的提取,当然加权系数就是卷积核的权重系数。

那么卷积核的系数如何确定的呢?是随机化初值,然后根据误差函数通过反向传播梯度下降进行迭代优化。这是一个关键点,卷积核的参数通过优化求出才能实现特征提取的作用,GCN的理论很大一部分工作就是为了引入可以优化的卷积参数。

注:这里的卷积是指深度学习(CNN)中的卷积,与数学中定义的卷积运算严格意义上是有区别的。

 说一下与数学中的卷积的区别。(因为卷积神经网络中都是离散卷积,所以不提连续卷积的问题。)

对于数学来说,卷积核与原始的矩阵乘积,是围绕着中心元素进行180度旋转后,才是对应的元素,主要是为了诸如信号处理、求两个随机变量和的分布等而定义的运算,所以需要“翻转”是根据问题的需要而确定的。

而对CNN来说,所谓的“卷积”,是为了提取图像的特征,其实只借鉴了“加权求和”的特点,本质来说是一种互相关函数计算或者说图像处理中的spatial filter,是在提取图像的每个局部(感受野)范围和卷积核的互相关函数。

总结:数学中的“卷积核”都是已知的或者给定的,卷积神经网络中“卷积核”本来就是trainable的参数,不是给定的,根据数据训练学习的,所以翻不翻转没什么区别,因为无论翻转与否对应的都是未知参数。

三、GCN

CNN的局限性:CNN处理的图像或者视频数据中像素点(pixel)是排列成成很整齐的矩阵。其关键在于图片结构上的平移不变性:一个小窗口无论移动到图片的哪一个位置,其内部的结构都是一模一样的,因此CNN可以实现参数共享。这就是CNN的精髓所在。然而与之相对应,科学研究中还有很多Non Euclidean Structure的数据,典型的生活中图的结构一般来说是十分不规则的,可以认为是无限维的一种数据,所以它没有平移不变性。每一个节点的周围结构可能都是独一无二的,这种结构的数据,就让传统的CNN、RNN瞬间失效。所以很多学者从上个世纪就开始研究怎么处理这类数据了,涌现出了很多方法,例如GNN、DeepWalk、node2vec等等,GCN只是其中一种。

GCN,图卷积神经网络,实际上跟CNN的作用一样,就是一个特征提取器,本质目的是用来提取拓扑图的空间特征。GCN精妙地设计了一种从图数据中提取特征的方法,从而让我们可以使用这些特征去对图数据进行节点分类(node classification)、图分类(graph classification)、边预测(link prediction),还可以顺便得到图的嵌入表示(graph embedding),可见用途广泛。

Graph Convolutional Network(图卷积神经网络)中的Graph是指数学(图论)中的用顶点和边建立相应关系的拓扑图。

spectral domain(谱域)就是GCN的理论基础了。这种思路就是希望借助图谱的理论来实现拓扑图上的卷积操作。从整个研究的时间进程来看:首先研究GSP(graph signal processing)的学者定义了graph上的Fourier Transformation,进而定义了graph上的convolution,最后与深度学习结合提出了Graph Convolutional Network。

Graph Fourier Transformation(图的傅里叶变换)及Graph Convolution(图的卷积)的定义都用到图的拉普拉斯矩阵,那么首先来介绍一下拉普拉斯矩阵

Laplacian 矩阵的定义为L=D-A(其中一种定义,Combinatorial Laplacian),其中L是Laplacian 矩阵,D是顶点的度矩阵(对角矩阵)(degree matrix),对角线上元素依次为各个顶点的度, A是图的邻接矩阵(adjacency matrix)。如下图,就能很快知道Laplacian 矩阵的计算方法。顶点的度矩阵说明了每个顶点与多少个顶点相连,邻接矩阵说明连接的是哪些点。

 GCN的核心基于拉普拉斯矩阵的谱分解(与特征分解,对角化都是同一个概念)。

卷积定理:函数卷积的傅里叶变换是函数傅立叶变换的乘积,即对于函数 [公式] 与 [公式]两者的卷积是其函数傅立叶变换乘积的逆变换:

$$
f * h=\mathcal{F}^{-1}[\hat{f}(\omega) \hat{h}(\omega)]=\frac{1}{2 \pi} \int \hat{f}(\omega) \hat{h}(\omega) e^{i \omega t} d \omega
$$

关于具体的其他公式推导之类的,可以直接看最开头放的链接,这里就不再赘述了(太麻烦了,而且还挺难)。

然后多层的意思就是。深度学习中最重要的是学习特征:随着网络层数的增加,特征越来越抽象,然后用于最终的任务。对于图任务来说,这点同样适用,我们希望深度模型从图的最初始特征X出发学习到更抽象的特征,比如学习到了某个节点的高级特征,这个特征根据图结构融合了图中其他节点的特征,我们就可以用这个特征用于节点分类或者属性预测。那么图网络就是要学习新特征,用公式表达就是:

$$
H^{(k+1)}=f\left(H^{(k)}, A\right)
$$

这里k指的是网络层数,H^(k),就是网络第k层的特征,其中H^(0)就是X。

在GCN中将CNN和RNN结合训练,同时检测关键点并生成其对应的描述子。并借助刚体变换,通过将source frame中的点warp到reference frame中实现对网络的优化。本质上,GCN就是对warp的学习。整个训练过程聚焦于相机的运动而不是图像内部的运动,这会给匹配带来更好的一致性,并且有助于最终的位姿估计。

四、GCNv2

最初的GCN网络是由ResNet-50和双向循环网络实现的。CNN是实现稠密特征提取的,BRNN是在空间信息的基础上加入时间信息的。该结构已经实现了很好的精度,但是无法实时。一方面,该网络结构本身需要大算力的平台支持,而且,双向结构需要同时对两个或多个frame进行匹配,但是KF会基于当前相机位姿进行动态更新,这进一步增加了计算量。

受SuperPoint只对单个帧进行检测的启发,新设计的网络GCN V2对一张原始图像这种的每个cell(大小为16x16像素)进行独立的预测。(这样和ORB-SLAM中的ORB提取一样,可以使得最终提出的特征点均匀分布在图像中),而相比于SuperPoint删除了一些不必要的参数,并且采用了更低的尺度。池化层被卷基层代替,卷积核大小(kernel)为4X4,步长(stride)为2,填充(padding)为1,网络输入的图像尺寸是320x240。

Inspired by SuperPoint, which uses a simple structure to perform detection using a single frame, we deploy a network with even fewer parameters and working on a lower scale than SuperPoint. Intuitively, the network performs an individual prediction for each grid cell of size 16×16 pixels in the original image. In GCNv2 all the pooling layers are replaced by convolutions with kernel size 4×4, stride 2 and padding 1.

该网络通过卷积的方法,由原始灰度图获得低像素、多通道的概率图(Probability map)和特征图(Feature maps)。再通过上采样(Pixel shuffle)改变概率图的像素大小 (变得和原始灰度图像素大小一样,且单通道),并根据变化后的概率图中各点的概率值确定图中的特征点位置。最后以特征点位置为基础,通过 Feature maps 中的对应值和一个二值化网络层提取出每个特征点对应的二值化描述子

池化:池化的定义比较简单,最直观的作用便是降维,常见的池化有最大池化、平均池化和随机池化。池化层不需要训练参数。最大池化是对局部的值取最大;平均池化是对局部的值取平均;随机池化是根据概率对局部的值进行采样,采样结果便是池化结果。概念非常容易理解,其示意图如下所示。一般在CNN中使用的池化都是不重叠的,但是池化也可以重叠,重叠池化和卷积操作类似,可以定义步长等参数,其和卷积的不同在于:卷积操作将窗口元素和卷积核求内积,而池化操作求最大值/平均值等,窗口的滑动等原理完全相同。

原始 GCN 结构由两个主要部分组成:具有 ResNet50 主干的 FCN [39] 结构和双向循环网络。FCN 适用于密集特征提取,而双向循环网络用于查找关键点位置。与现有方法相比,GCN 具有令人印象深刻的跟踪性能,但它也指出,该公式在应用于实时 SLAM 系统时具有实际局限性。我们确定了两个主要问题:首先,网络架构相当大,因此需要强大的计算硬件,这使得它无法在船上实时运行,例如。用于我们无人机实验的 Jetson TX2; 其次,GCN 推理需要同时输入两帧或多帧,不仅增加了计算量,还增加了算法复杂度。

GCNv2网络结构。橙色块代表卷积层,下面的数字是对应的通道数。在每组块之后应用 ELU 非线性。符号 I 除以某个数字表示当前特征图的分辨率,例如 I/4 表示当前图像中的一个像素代表了原始图像的 4x4 像素。

为了解决这些限制,我们引入了基于单一视图的简化网络结构 GCNv2,提高了效率。与 GCN 一样,GCNv2 同时预测关键点和描述符,即网络输出关键点置信度的概率图和描述符的密集特征图。受 SuperPoint 的启发,GCNv2 被修改为以低分辨率而不是原始分辨率执行预测,并且仅使用单个图像。这是通过首先在低分辨率下预测概率图和密集特征图,然后将 256 通道概率图 pixel shuffle 到原始分辨率,最后对全分辨率概率图执行非极大值抑制并使用这些位置从低分辨率密集特征图中对相应的特征向量进行双线性采样(Bilinear Sampling)(图 2 中的右侧部分)。

Pixel shuffle算法的实现流程如上图,其实现的功能是:将一个H × W的低分辨率输入图像(Low Resolution),通过Sub-pixel操作将其变为rH x rW的高分辨率图像(High Resolution)。但是其实现过程不是直接通过插值等方式产生这个高分辨率图像,而是通过卷积先得到r 2 r^2r2个通道的特征图(特征图大小和输入低分辨率图像一致),然后通过周期筛选(periodic shuffing)的方法得到这个高分辨率的图像,其中r rr上采样因子(upscaling factor),也就是图像的扩大倍率。

非极大值抑制(Non-Maximum Suppression,NMS):顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。即选出置信度最高的候选框,如果当前最高分的候选框重叠面积IoU(交集/并集)大于一定阈值,就将其删除。

GCNv2最终能够同时获得特征点和描述子,而且是二值化的,这和ORB-SLAM2中特征提取环节是一样的,因此GCNv2能够很好地移植到ORB-SLAM2中。整个GCN-SLAM系统的工作过程如下:

  1. 从相机中获得图像,并将其对应的灰度图送入到GCNv2网络中;
  2. 将GCNv2产生的特征点和描述子保存到系统中,用于系统的定位和跟踪;
  3. 与ORB-SLAM2不同的是,GCN-SLAM不采用恒速模型,仅使用特征点匹配的方式完成帧间跟踪定位;
  4. 后续的闭环啥的操作都采和ORB-SLAM2相似,但是由于更换了提取特征的方法,所以要重新构建合适的词袋数据。

detector主要是要从图像中找到有特征的点,detector的输出是图像坐标,然后descriptor就是对detector输出的图像坐标进行描述,描述的方法一般是对特征点的邻域进行编码处理,最后的编码我们一般称为特征向量或者特征。

GCN-SLAM由于精简化了网络结构,计算量相比于作者先前发布的GCN网络有了很大降低,因此该系统能够运行在某些嵌入式设备上,且仍能够获得较好的精度。但是,该网络在训练时使用的样本数据,即真实特征点位置和真实特征匹配关系,是通过角点提取算法和位姿真值数据获得的。感觉这类样本特征点的稳定性不够高,可能会影响网络的稳定性。此外,真实的匹配关系是根据数据集所给的真实位姿获得的,所以训练样本中主要包含的还是位姿信息,即网络主要是以位姿信息为训练的依据。或许可以尝试加入其他高级信息,如语义啥的。但这也是为什么文中说 GCNv2 就是为了位姿估计而生的原因吧。

上述结论的原文链接:GCN-SLAM:基于神经网络提取的特征点和描述子的SLAM_Armergg的博客-CSDN博客_神经网络提取特征点

原文首先介绍修改后​​的网络结构,然后详细介绍用于二值化特征描述符和关键点检测器的训练方案。

还有一篇很好的参考博客:论文笔记:GCNv2: Efficient Correspondence Prediction for Real-Time SLAM - 技术刘 (liuxiao.org)

在台式计算机上的推理和匹配时间更全面的比较如图3所示。可以看出,输入的分辨率以粗略的二次方式影响推理时间。与相同分辨率的 GCN 和 SuperPoint 相比,GCNv2 的推理时间更短。 这主要是由于对网络架构的修改。图下文字:这是文中的fig3,是不同方法的效率比较。 为了公平比较,通过对所有方法使用相同数量(1000)的关键点执行最近邻匹配来评估匹配时间。 深色和浅色分别表示在全分辨率(640 × 480)和半分辨率(GCN 为 320 × 256,因为它基于 ResNet,其余为 320 × 240)下对输入的推理时间。

关于二值化的计算:

$$
\text { Forward: } \boldsymbol{b}(\boldsymbol{x})=\operatorname{sign}(\boldsymbol{f}(\boldsymbol{x}))=\left\{\begin{array}{cc}
+1 & \boldsymbol{f}(\boldsymbol{x}) \geq 0 \\
-1 & \text { otherwise }
\end{array}\right.
$$

$$
\text { Backward: } \frac{\partial \boldsymbol{b}}{\partial \boldsymbol{f}}=\mathbf{1}_{|\boldsymbol{f}| \leq 1}
$$

其中 b 是特征 f 的二值化版本。  1|f|≤1 消除了 f 的绝对值大于 1 的单个特征响应的梯度。它是用于反向传播梯度的硬符号函数的所谓直通估计器。 该指示函数在反向传播期间近似二值化,并避免对已经通过决策边界 1 的特征响应进行过度惩罚。

五、SuperPoint

参考链接:

  1. 一种用于SLAM/SFM的深度学习特征点 SuperPoint_网络 (sohu.com)
  2. SuperPoint - 一个网络结构简单清晰的特征点任务网络_嗯对我就是吃不饱的阿德的博客-CSDN博客_superpoint网络

2018年magicLeap发表了一篇文章,基于自监督训练的特征点检测和描述符提取方法,又是一个深度学习用于特征点提取和匹配的方法,与16年的LIFT相比,具有很大的优势。如果使用这种方式提取特征点描述符用于SLAM中,会对前端算法具有很大改善和提升;如果描述符具有优良特性,在定位场景下,可以对季节和环境光照具有更强的鲁棒性。能够同时提取特征点的位置以及描述子。相比于patch-based方法,本文提出的算法能够在原始图像提取到像素级精度的特征点的位置及其描述子

fig3

上图可见Superpoint的网络结构在如今trick横飞的深度学习领域,显得非常朴素。一个标准的特征提取器(encoder)+ 两个decoder head。特征点检测器以及描述子网络共享一个单一的前向encoder,只是在decoder时采用了不同的结构,根据任务的不同学习不同的网络参数。这也是本框架与其他网络的不同之处:其他网络采用的是先训练好特征点检测网络,然后再去进行对特征点描述网络进行训练。

六、PPT

2

GCNv2:是一种能够计算图像关键点和描述子的深度神经网络,可以用于作为实时SLAM的前端。

解决问题:在GCN的基础上提高了计算效率,同时可以替换ORB-SLAM2中的ORB描述子。

改进方法:1)采用类似SuperPoint的网络结构,提高了效率;2)加入了二值化层,生成二值特征。

结论:GCNv2在精度上与GCN保持相当,能满足实时性要求(以Jetsom TX2为平台),在无人机上的实验展示了其鲁棒性。

3

GCNv2  卷积网络 → 上采样 → 特征点→ 描述

GCNv2网络结构

该网络通过卷积的方法,由原始灰度图获得低像素、多通道的概率图(Probability map)和特征图(Feature maps)。再通过上采样(Pixel shuffle)改变概率图的像素大小 (变得和原始灰度图像素大小一样,且单通道),并根据变化后的概率图中各点的概率值确定图中的特征点位置。最后以特征点位置为基础,通过 Feature maps 中的对应值和一个二值化网络层提取出每个特征点对应的二值化描述子

GCN-SLAM可以在Jetson TX2上以20Hz运行,在Intel i7-7700HQNVIDIA 1070上以大约80Hz运行。简化版的网络GCNv2-tiny速度更快,可以在TX2上达到40Hz

4

如右图所示即为实现网络结构的代码部分

GCNv2-tiny版本主要是把 conv2 和之后的卷积通道数减半,以达到压缩参数,进一步减少计算量的目的

5

GCN  具有 ResNet50 主干的 FCN 结构 双向循环网络

对比GCN网络结构 

FCN 适用于密集特征提取,而双向循环网络用于查找关键点位置。与现有方法相比,GCN 具有令人印象深刻的跟踪性能,但作者指出,该公式在应用于实时 SLAM 系统时具有实际局限性。我们确定了两个主要问题:首先,网络架构相当大,因此需要强大的计算硬件,这使得它无法在船上实时运行,例如。用于我们无人机实验的 Jetson TX2; 其次,GCN 推理需要同时输入两帧或多帧,不仅增加了计算量,还增加了算法复杂度。

对比此,GCNv2保持了精度的同时,引入了基于单一视图的简化网络结构,提高了效率

6

SuperPoint  Encoder Decoder

对比SuperPoint网络结构

一个标准的特征提取器(encoder+ 两个decoder head。特征点检测器以及描述子网络共享一个单一的前向encoder,只是在decoder时采用了不同的结构,根据任务的不同学习不同的网络参数

Interest Point Decoder部分(detection)将feature map的维度扩展到N x H/8 x W/8 x 65使用softmax计算概率

Descriptor Decoder部分,计算了一个半稠密的角点特征描述子集合(H/8 * W/8),再由resize操作拓展到全图

对比此,GCNv2 是在 Descriptor Decoder 部分中直接把 Keypoints 拿过来使用而取代了 SuperPoint 相应的部分

7

1) 一些定义

  • 𝑓 : 𝑐𝑜𝑛𝑣𝐷 中提取的压缩尺度的特征图(feature maps)
  • 𝑜 :由GCNv2产生的概率图(Probability map)转换成与原始灰度图像像素大小相同的概率图
  • 𝑓^𝑐𝑢𝑟 、 𝑓^𝑡𝑎𝑟 :分别表示当前帧和目标帧。需要在这两帧间找出匹配特征点,并完成帧间位姿估计
  • 𝐿_𝑓𝑒𝑎𝑡 、𝐿_𝑑𝑒𝑡 :descriptor 的损失函数与 detector 的损失函数
  • 总的 Loss 是 𝐿_𝑓𝑒𝑎𝑡 与 𝐿_𝑑𝑒𝑡 的和,不过赋予了不同权重,在 GCNv2 中分别赋予权重 100 和 1

2) 二值化特征

 为了获取描述子的二值特征,定义了一个 Binary activation layer,它的定义如下

$$
\text { Forward: } \boldsymbol{b}(\boldsymbol{x})=\operatorname{sign}(\boldsymbol{f}(\boldsymbol{x}))=\left\{\begin{array}{cc}
+1 & \boldsymbol{f}(\boldsymbol{x}) \geq 0 \\
-1 & \text { otherwise }
\end{array}\right.
$$

$$
\text { Backward: } \frac{\partial \boldsymbol{b}}{\partial \boldsymbol{f}}=\mathbf{1}_{|\boldsymbol{f}| \leq 1}
$$

添加这样一个二值化层的原因在于,作者发现这样比直接让网络输出 -1+1 之间的数值效果更好(可能网络更好训练)

3) 检测子的学习:损失函数与样本生成

GCN 没有像其他一些 local feature 网络一样学习一张热力图之类,而是直接生成了一张表示是否为关键点的二值。转换后的概率图 𝑜o 各点只在01取值,其中1表示该点是特征点,0则表示不是。那么整个检测子就变成了一个分类问题。所以使用的就是分类问题的 Cross-entropy loss,由于正负样本数不均衡,所以使用 weighted cross-entropy loss(加权交叉熵)。检测子 loss 如下:

$$
\begin{aligned}
L_{d e t}=L_{c e}\left(\boldsymbol{o}^{c u r}\left(\boldsymbol{x}^{c u r}\right)\right)+L_{c e}\left(\boldsymbol{o}^{t a r}\left(\boldsymbol{x}_{+}^{t a r}\right)\right) \\
\end{aligned}
$$

其中𝒙^𝑐𝑢𝑟表示特征点在当前帧𝑓^𝑐𝑢𝑟中的位置, 𝒙_+^𝑡𝑎𝑟是𝒙^𝑐𝑢𝑟在目标帧𝑓^𝑡𝑎𝑟中真实匹配点的位置。 𝒐^𝑐𝑢𝑟、 𝒐^𝑡𝑎𝑟分别是𝑓^𝑐𝑢𝑟、𝑓^𝑡𝑎𝑟对应的由GCNv2网络输出的概率图在𝒙_+^𝑡𝑎𝑟、𝒙^𝑐𝑢𝑟像素位置上的点的值。其中 𝐿_𝑐𝑒 ()是计算加权交叉熵的函数, 𝛼_1和𝛼_2是正负样本权重系数:

$$
\begin{aligned}
L_{c e}(\boldsymbol{o}(\boldsymbol{x}))=&-\alpha_{1} \sum_{i} c_{\boldsymbol{x}_{i}} \log \left(\boldsymbol{o}\left(\boldsymbol{x}_{i}\right)\right) \\
&-\alpha_{2} \sum_{i}\left(1-c_{\boldsymbol{x}_{i}}\right) \log \left(1-\boldsymbol{o}\left(\boldsymbol{x}_{i}\right)\right)
\end{aligned}
$$

文章中先用 16X16 的小框对原图进行分割,以一个框为操作单位,从框中 Shi-Tomasi 角点 (即𝒙^𝑐𝑢𝑟)生成检测子,然后根据数据集提供的图像间的真实位姿,进行 warp 操作获得这些角点的真实匹配特征点 (即𝒙_+^𝑡𝑎𝑟)。以此为样本数据,根据所给的损失函数来完成对网络的特征提取环节的训练。这样生成样本能够反映关键点的跟踪能力,也就是在不同帧关键点位置的鲁棒性。

9

在计算描述子环节的网络训练中,作者使用了 Triplet Loss 损失函数,如下:

$$
\begin{gathered}
L_{\text {feat }}=\sum_{i} \max \left(0, d\left(\boldsymbol{x}_{i}^{c u r}, \boldsymbol{x}_{i,+}^{t a r}\right)-d\left(\boldsymbol{x}_{i}^{c u r}, \boldsymbol{x}_{i,-}^{\text {tar }}\right)+m\right) \\
\end{gathered}
$$

其中𝒙_𝑖^𝑐𝑢𝑟表示 anchor, 𝒙_(𝑖,+)^𝑡𝑎𝑟表示 positive,𝒙_(𝑖,−)^𝑡𝑎𝑟表示 negative,m 是一个距离修正项。距离函数 d 是汉明距离,其公式如下:

$$
\begin{gathered}
d\left(\boldsymbol{x}^{c u r}, \boldsymbol{x}^{\text {tar }}\right)=\left\|\boldsymbol{b}^{c u r}\left(\boldsymbol{x}^{c u r}\right)-\boldsymbol{b}^{\text {tar }}\left(\boldsymbol{x}^{\text {tar }}\right)\right\|_{2}
\end{gathered}
$$

triplet loss:用于特征点相似性的区分,使其与真值更近,离负样本更远

整个训练过程是:

  1. 首先从训练集中随机选一个样本,称为Anchor(记为x_a)。
  2. 然后再随机选取一个和Anchor属于同一类的样本,称为Positive (记为x_p)
  3. 最后再随机选取一个和Anchor属于不同类的样本,称为Negative (记为x_n)

三元组的三个样本最终得到的特征表达计为,三元组的三个样本最终得到的特征表达计为:

$$
f\left(x_{i}^{a}\right) f\left(x_{i}^{p}\right) f\left(x_{i}^{n}\right)
$$

triplet loss的目的就是让Anchor这个样本的feature和positive的feature直接的距离比和negative的小,还要让x_a与x_n之间的距离和x_a与x_p之间的距离之间有一个最小的间隔α,于是最终得到的是

$$
\begin{aligned}
&\left\|f\left(x_{i}^{a}\right)-f\left(x_{i}^{p}\right)\right\|_{2}^{2}+\alpha<\left\|f\left(x_{i}^{a}\right)-f\left(x_{i}^{n}\right)\right\|_{2}^{2} \\
&\forall\left(f\left(x_{i}^{a}\right), f\left(x_{i}^{p}\right), f\left(x_{i}^{n}\right)\right) \in \mathcal{T} .
\end{aligned}
$$

于是目标函数为:

$$
\sum_{i}^{N}\left[\left\|f\left(x_{i}^{a}\right)-f\left(x_{i}^{p}\right)\right\|_{2}^{2}-\left\|f\left(x_{i}^{a}\right)-f\left(x_{i}^{n}\right)\right\|_{2}^{2}+\alpha\right]_{+}
$$

距离用欧式距离度量,+表示[  ***  ]内的值大于零的时候,取该值为损失,小于零的时候,损失为零。

深度学习干货学习(2)—— triplet loss_每天都要深度学习的博客-CSDN博客

target 的正样本:通过ground-truth计算得到。也就是将 current 帧的 feature 投影到 target 帧,然后通过寻找最近临的方式获得正样本,投影方式如下:

$$
\boldsymbol{x}_{i,+}^{\operatorname{tar}}=\boldsymbol{\pi}^{-1}\left(\mathbf{R}_{g t} \boldsymbol{\pi}\left(\boldsymbol{x}_{i}^{c u r}, z_{i}\right)+\boldsymbol{t}_{g t}\right)
$$

本质其实就是刚体的旋转和平移变换

机器学习包括有监督学习(supervised learning),无监督学习(unsupervised learning),和半监督学习(semi-supervised learning)。

在*有监督学习中,数据是有标注的,以(x, t)的形式出现,其中x是输入数据,t是标注.正确的t标注是ground truth 错误的标记则不是。(也有人将所有标注数据都叫做ground truth)

由模型函数的数据则是由(x, y)的形式出现的。其中x为之前的输入数据,y为模型预测的值。

标注会和模型预测的结果作比较。在损耗函数(loss function / error function)中会将y 和 t 作比较,从而计算损耗(loss / error)。

机器学习里经常出现ground truth这个词,能否准确解释一下? - 知乎

 10

负样本的选取和GCN略有不同,GCN是选取所有特征点中除了正样本以外,离正样本最近的点。而此处是按照右面的流程选取的负样本,该函数会根据阈值 c 返回负样本,也就是大于某个距离的认为是负样本(由于 k nearest 排序,返回的可以认为是最接近正样本的负样本),相比于之前的变化在于多一Relaxed Criteria用于帮助选择,只有负样本和正样本之间的距离大于这个值时才会被选中,可以减小噪声的影响

 其中的  𝑏b 表示量化成二值特征(256bit)的向量

输入:当前特征点 𝒙^𝑐𝑢𝑟 的描述子,𝑘 个匹配度 (与 𝒙^𝑐𝑢𝑟 描述子距离最近) 最高的特征点 𝒙_𝑘 的位置以及它们的描述子, 𝒙^𝑐𝑢𝑟 的真实匹配特征点 𝒙_+^𝑡𝑎𝑟  ,阈值 𝑐 

输出:找出与 𝒙_+^𝑡𝑎𝑟 在像素坐标上距离较大(大于 𝑐 )的特征点,记为 𝒙_−^𝑡𝑎𝑟  ,并返回 𝒙_−^𝑡𝑎𝑟 的描述子。如果没找到符合条件的特征点则什么都不返回

GCN-SLAM:基于神经网络提取的特征点和描述子的SLAM_Armergg的博客-CSDN博客_神经网络提取特征点

11

七、其他

什么是libtorch

Pytorch-1.0最瞩目的功能就是生产的大力支持,推出了C++版本的生态端(FB之前已经在Detectron进行了实验),包括C++前端和C++模型编译工具。

对于我们来说,之后如果想要部署深度学习应用的时候,只需要在Python端利用Pytorch进行训练,然后使用torch.jit导出我们训练好的模型,再利用C++端的Pytorch读取进行预测即可,当然C++端的Pytorch也是可以进行训练的。因为我们使用的C++版的Pytorch实际上为编译好的动态链接库和头文件,官方提供已经编译好的下载包。之后我们将其称之为libtorch,也就是Pytorch的C++端

参考:

利用Pytorch的C++前端(libtorch)读取预训练权重并进行预测 - Oldpan的个人博客PyTorch C++ API libtorch 简介_Adenialzz的博客-CSDN博客

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值