天天看點

torch F.cosine_similarity()使用1. dim的作用2. 如何計算兩兩之間的相似度?3. 總結

torch F.cosine_similarity()使用1. dim的作用2. 如何計算兩兩之間的相似度?3. 總結

看名字就知道是算餘弦相似度,但是有個煩人的參數dim,本文主要解決如下幾個問題

  •     dim 參數到底有什麼作用?如何設定dim參數
  •     兩個矩陣使用該函數算餘弦相似度到底是按列向量來算還是按行向量來算?
  •     如果想要算矩陣中每個行向量兩兩之間的相似度,如何計算?

1. dim的作用

  •  實驗一: dim=0
import torch.nn.functional as F
import torch
import math

a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float)
b = torch.tensor([[5, 6], [7, 8]], dtype=torch.float)


def check(vec_a, vec_b):
    dot = 0
    for i in range(len(vec_a)):
        dot += vec_a[i]*vec_b[i]
    vec_a_sq_sum = math.sqrt(sum([item*item for item in vec_a]))
    vec_b_sq_sum = math.sqrt(sum([item*item for item in vec_b]))
    return dot/(vec_a_sq_sum*vec_b_sq_sum)

if __name__ == "__main__":
	res = F.cosine_similarity(a, b, dim=0)
	print(res)
	check1 = check([1,3], [5,7])
	check2 = check([2,4], [6,8])
	print(check1)
	print(check2)
           

如上計算a, b的餘弦相似度,dim=0,得到如下結果: 

tensor([0.9558, 0.9839])
0.95577900872195
0.9838699100999074
           

是以對于二維矩陣,dim=0表示對應列的列向量之間進行cos相似度計算

  • 實驗2: dim = 1
if __name__ == "__main__":
    res = F.cosine_similarity(a, b, dim=1)
    print(res)
    check1 = check([1,2], [5,6])
    check2 = check([3,4], [7,8])
    print(check1)
    print(check2)
           

得到如下結果

tensor([0.9734, 0.9972])
0.973417168333576
0.997164120486613
           

是以dim=1表示相對應的行向量之間的餘弦相似度計算, 預設情況下dim=1,即當不設定dim參數時,是計算行向量之間的相似度

2. 如何計算兩兩之間的相似度?

從上面可以看出,輸入兩個2*2的矩陣,

F.cosine_similarity

函數輸出的是1*2的結果,即指算了對應行或對應列向量之間的相似度,那麼如何計算行向量兩兩之間的相似度呢,即輸入兩個2*2的矩陣,輸出為2*2的相似度矩陣

将上面main函數改成如下:

if __name__ == "__main__":
    x = a.unsqueeze(1)
    y = b.unsqueeze(0)
    print("x", x)
    print("y", y)
    res = F.cosine_similarity(x, y, dim=-1)
    print("res", res)
    check11 = check([1,2], [5,6])
    check12 = check([1,2], [7,8])
    check21 = check([3,4], [5,6])
    check22 = check([3,4], [7,8])

    print(check11, check12, check21, check22)
           

輸出如下結果:

x tensor([[[1., 2.]],
       	 [[3., 4.]]])
y tensor([[[5., 6.],
         [7., 8.]]])
res tensor([[0.9734, 0.9676],
        [0.9987, 0.9972]])
0.973417168333576 0.9676172723968437 0.9986876634765887 0.997164120486613
           

可看到上面程式實作了行向量間兩兩求相似度的需求

個人猜測其原理如下:

x.shape=[2, 1, 2],y.shape=[1, 2, 2],在三維情況下dim=-1(dim=2)表示行,從x中取一行,x_vec.shape = [1,2] , 從y中取一行, y_vec.shape = [2,2],這樣計算相似度為兩個,同理進行下一行計算,有點像numpy中矩陣自動擴充計算類似

3. 總結

如果想要按行計算相似度,dim設定成-1即可,如果要想兩兩計算相似度,需要使用

unsqueeze

函數進行增加矩陣次元。