在lightglue中,通过dual softmax的使用,我们替换了superglue中的sinkhorn环节。
其具体操作如下:
基于来自图像A的[[1, n, 256])] 维度的特征描述子,以及来自图像B的[1, m, 256]的描述子,首先经过linear层的操作,将其转换为[1, n, 1] 和 [1, m, 1]的特征,对应下列函数中的z0和z1。然后,两张图片的特征向量经过einsum的操作 sim = torch.einsum("bmd,bnd->bmn", mdesc0, mdesc1), 得到了[1,n,m]的矩阵。 然后,基于在两个维度的softmax和转秩操作,我们实现了dual softmax。
之后,我们将z0,z1的数值与dual softmax的数值相结合,并将最后一行,和一列做特殊的填充,我们就实现了lightglue中稍微有点特殊的dual softmax的操作。
def sigmoid_log_double_softmax(
sim: torch.Tensor, z0: torch.Tensor, z1: torch.Tensor
) -> torch.Tensor:
"""create the log assignment matrix from logits and similarity"""
b, m, n = sim.shape
certainties = F.logsigmoid(z0) + F.logsigmoid(z1).transpose(1, 2)
scores0 = F.log_softmax(sim, 2)
scores1 = F.log_softmax(sim.transpose(-1, -2).contiguous(), 2).transpose(-1, -2)
scores = sim.new_full((b, m + 1, n + 1), 0)
scores[:, :m, :n] = scores0 + scores1 + certainties
scores[:, :-1, -1] = F.logsigmoid(-z0.squeeze(-1))
scores[:, -1, :-1] = F.logsigmoid(-z1.squeeze(-1))
return scores