深度学习 余弦相似度

余弦距离,也称为余弦相似度,是用向量空间中两个向量之间的夹角余弦值作为衡量两个个体之间的差异大小的度量。

余弦值越接近于1, 夹角之间的度数越接近0度,也就是两个向量越相似,这就叫做“余弦相似度”。


举例说明:
在这里插入图片描述
通过上图,我们能看出,将两张人脸图片通过卷积神经网路,可以分别得到向量a和向量b

在空间中,向量a和向量b有以下几种情况:
第一种情况:
在这里插入图片描述
向量a和向量b的夹角很小,说明向量a和向量b有很高的相似性。

第二种情况:
在这里插入图片描述
向量a和向量b是相等的,可以表示向量a所表示的人脸图片和向量b所表示的图片是完全相似的,或者说是相同的。

第三种情况:
在这里插入图片描述
向量a和向量b的夹角比较大,说明向量a和向量b有很低的相似性,或者说向量a和向量b所代表的人脸图片是不相同的。


不难理解,余弦相似度就是基于两个向量之间的夹角的大小进行一个相似度的判断。

以二维空间为例

在这里插入图片描述
如果想要计算向量a和向量b之间的夹角,可以通过余弦定理得出:
在这里插入图片描述
假设向量a是 [ x 1 , y 1 ] [x_1, y_1] [x1,y1]、向量b是 [ x 2 , y 2 ] [x_2, y_2] [x2,y2],那么可以将余弦定理改写为下面的形式:
在这里插入图片描述
推导出在这里插入图片描述

数学家已经证明,余弦的这种计算方法对n维向量也成立。假定A和B是两个n维向量,A是 [A1, A2, …, An] ,B是 [B1, B2, …, Bn] ,则A与B的夹角θ的余弦等于:
在这里插入图片描述


我们可以尝试的举个小例子进行详细的理解:

句子A:这只皮靴号码大了。那只号码合适

句子B:这只皮靴号码不小,那只更合适

第一步:分词

句子A:这只/皮靴/号码/大了。那只/号码/合适。

句子B:这只/皮靴/号码/不/小,那只/更/合适。

第二步:列出所有的词。

所有的词:这只,皮靴,号码,大了。那只,合适,不,小,很

第三步:计算词频。

句子A:这只1,皮靴1,号码2,大了1。那只1,合适1,不0,小0,更0

句子B:这只1,皮靴1,号码1,大了0。那只1,合适1,不1,小1,更1

第四步:写出词频向量。

句子A:[1,1,2,1,1,1,0,0,0]

句子B:[1,1,1,0,1,1,1,1,1]

第五步:利用公式进行计算:
在这里插入图片描述
在这里插入图片描述
计算结果中夹角的余弦值为0.81非常接近于1,所以,上面的句子A和句子B是基本相似的。


pytorch计算余弦相似度
在pytorch中,可以使用torch.cosine_similarity函数对两个向量或张量计算余弦相似度,下面是pytorch源码对该函数的定义:

class CosineSimilarity(Module):
    r"""Returns cosine similarity between :math:`x_1` and :math:`x_2`, computed along dim.
    .. math ::
        \text{similarity} = \dfrac{x_1 \cdot x_2}{\max(\Vert x_1 \Vert _2 \cdot \Vert x_2 \Vert _2, \epsilon)}.
    Args:
        dim (int, optional): Dimension where cosine similarity is computed. Default: 1
        eps (float, optional): Small value to avoid division by zero.
            Default: 1e-8
    Shape:
        - Input1: :math:`(\ast_1, D, \ast_2)` where D is at position `dim`
        - Input2: :math:`(\ast_1, D, \ast_2)`, same shape as the Input1
        - Output: :math:`(\ast_1, \ast_2)`
    Examples::
        >>> input1 = torch.randn(100, 128)
        >>> input2 = torch.randn(100, 128)
        >>> cos = nn.CosineSimilarity(dim=1, eps=1e-6)
        >>> output = cos(input1, input2)
    """
    __constants__ = ['dim', 'eps']
 
    def __init__(self, dim=1, eps=1e-8):
        super(CosineSimilarity, self).__init__()
        self.dim = dim
        self.eps = eps
 
    def forward(self, x1, x2):
        return F.cosine_similarity(x1, x2, self.dim, self.eps)

一共有四个参数:

  • x1和x2为待计算余弦相似度的张量;
  • dim:Dimension where cosine similarity is computed. Default: 1【在哪个维度上计算余弦相似度,默认为1】
  • eps:Small value to avoid division by zero.【了避免被零除而设置的一个小数值。】
import torch
import torch.nn as nn

input1 = torch.randn(10)
print(input1)
input2 = torch.randn(10)
print(input2)
cos = torch.cosine_similarity(input1, input2, dim=0)
print("余弦相似度的值为:",cos.item())

运行结果

tensor([-0.6769,  0.3174, -0.5698, -0.6801,  0.7337, -0.2313,  1.1100, -0.7113,
        -0.6971, -0.3375])
tensor([ 0.3479,  0.2553,  0.5036,  0.4689, -0.2355,  0.1993,  0.9669, -1.2789,
         0.6114, -1.0876])
余弦相似度的值为: 0.20675215125083923

Supongo que te gusta

Origin blog.csdn.net/qq_38973721/article/details/112800535
Recomendado
Clasificación