论文工作地址:https://psarlin.com/superglue/
论文地址:https://arxiv.org/abs/1911.11763
讲解PPT:https://psarlin.com/superglue/doc/superglue_slides.pdf
论文源码:https://github.com/magicleap/SuperGluePretrainedNetwork
摘要&介绍
如上图所示,SuperGlue是一个神经网络,通过共同找到对应关系和拒绝不可匹配的点来匹配两组局部特征。它作为手工或学习的前端和后端之间的中端。使用图神经网络和注意力机制来解决一个分配优化问题。能够优雅地处理部分点的可见性和遮挡,从而产生一个部分分配。
网络结构
SuperGlue主要由两大部分组成。注意力图神经网络:使用关键点编码器将关键点位置p和它们的视觉描述符d映射到一个单一的向量。接着使用交替的自注意力和交叉注意力层(重复L次)来创建更强大的表示f。最优匹配层:创建一个M乘N的得分矩阵。用dustbins增强该矩阵。使用Sinkhorn算法找到最优配对。
注意力图神经网络:
1.1为关键点编码器:每个关键点的初始表示结合了其视觉外观描述子和位置,编码器使用多层感知器(MLP)将关键点位置嵌入到高维向量中;
1.2为复用图神经网络:作为一个单一的完整图,其节点是两个图像的关键点。图有两种类型的无向边,它是一个多路复用图。图内边连接同一图像内的所有其他关键点,图间边连接关键点到另一图像中的所有关键点;
1.3为注意力聚::注意机制执行聚合并计算消息。图内边基于self_atten,而图间边基于cross_atten。与数据库检索类似,基于它们的属性,检索某些元素的值。消息被计算为值的加权平均值。关键、查询和值是图神经网络的深层特征的线性投影。最终匹配描述符是线性投影。
最优匹配层:这一部分产生一个部分分配矩阵。与标准的图匹配公式相似,可以通过计算一个得分矩阵S对所有可能的匹配进行评分,并在约束下最大化总得分来获得分配P。这等价于解决一个线性分配问题。
2.1为得分预测:将成对得分表示为匹配描述符的相似度;
2.2为遮挡和可见性:为了让网络压制某些关键点,每个集合都增加了一个"dustbin",以便未匹配的关键点被明确地分配到它。得分S被增强为S¯,通过添加一个新的行和列来完成。
2.3为Sinkhorn算法:上述优化问题的解决方案对应于最优传输问题。它是匈牙利算法的一个可微版本,传统上用于二部匹配,该算法包括沿行和列迭代地标准化exp(S¯),与行和列Softmax类似。经过T次迭代后,我们删除dustbin并恢复P。
Attentional Graph Neural Network注意力图神经网络
1.1 Keypoint Encoder关键点编码器
如上图所示,是采用MLP全连接层将三维的特征点[x,y,conf]升维成与描述子一致的256维。随后在下一个步骤中与描述子做一个加法运算,得到的结果送入图神经网络。下面是具体的代码实现和维度变化情况:
1.2&1.3注意力图神经网络
这一步进行的步骤就是论文中的公式3。代码中输入是编码器输出,图像0的描述子集合desc0和图像1的描述子集合desc1。如上图中代码所示,在__init__()中首先会构建一个18层AttentionalPropagation的网络模型,每层是self或者cross(二者交叉进行)。其余forward的在代码注释里说明,需要注意的是,每个layer其实就是一次AttentionalPropagation。在这其中,主要进行的操作过程就是公式3中的后半部分,在这里面会先计算message,随后进行一次MLP(输入维度为256*2,message||x)。
message的计算由多头注意力机制MultiHeadedAttention实现(本文中使用的是4-head)。
多头注意力机制MultiHeadedAttention
MultiHeadedAttention的作用就是计算message,其输入输出以及执行过程如上图代码注释所示。(公式5中把q分开写是因为q的取值是固定的,k和v是一致的不固定)
具体的注意力聚合机制实现则是在函数attention里。
Optimal matching laye最优匹配层
sinkhorn算法概述
在经过图神经网络之后得到了n*m的权重矩阵S:
- 行列各添加一行和一列dustbin,为了将没有匹配上的分配进入dustbin。
- 设定预期的目标行a和目标列和b,再结合实际的行和和列和进行标准化。
- 标准化的过程为:行方向标准化->列方向标准化->循环进行。(标准化过程中的计算方式为:每个元素除以自己的实际行和,再乘以预期行和;列标准化也是如此)
具体的功能在函数log_optimal_transport和log_sinkhorn_iterations中实现:
在执行完sinkhorn算法后,得到最终的分配矩阵。