目前的模型需要计算余弦距离,作为两个向量的距离,然后发现代码有两部分。第一部分是距离的计算,第二部分是L2范数归一化的使用。L2范数的话是这样计算的。
由于我的是一列向量的距离所以,上面就是某一列的L2范数,代码实现如下:
x_norm = x.norm(p=2, dim=1, keepdim=True)
x_norm = x_norm.clamp(min=1e-7)
x =x.div(x_norm)
上面是pytorch的代码,每个数值都会除以L2范数,其实上面仔细一开你会发现L2范数其实就是余弦距离的下面部分的两个绝对值了。
通过L2归一化后的参数我们就可以直接对应位置相乘相加即可得到了余弦距离。具体的数学推到如下:
distmat = 1 - qf.mm(gf.t())
我们可以看出余弦距离和欧式距离的公式,是一个单调函数(图像类似于单位元的第一象限部分),也就意味着,两者在归一化为单位向量的时候计算相似度结果完全一样。只不过余弦相似度是值越大月相似,欧式距离是值越小越相似。所以我们通过L2范数归一化除了更方便的计算余弦距离,同时也可以让我们的欧式距离替代余弦距离的使用。
而在我们项目中,其实可以先通过L2范数,然后在tripletloss中,无论用什么距离都是一样的了。