Pytorch如何快速計(jì)算余弦相似性矩陣
Pytorch計(jì)算余弦相似性矩陣
之前一直想找一個(gè)可以快速用矩陣相乘(可以直接GPU加速)計(jì)算余弦相似性矩陣的代碼,總算找到了。
代碼是在參考代碼的基礎(chǔ)上進(jìn)行了一些修改以適配自己的任務(wù)。
import torch def calculate_cosine_similarity_matrix(h_emb, eps=1e-8): r''' ''' # h_emb (N, M) # normalize a_n = h_emb.norm(dim=1).unsqueeze(1) a_norm = h_emb / torch.max(a_n, eps * torch.ones_like(a_n)) # cosine similarity matrix sim_matrix = torch.einsum('bc,cd->bd', a_norm, a_norm.transpose(0,1)) return sim_matrix if __name__ == "__main__": x = torch.randn(100, 700) sim_matrix = calculate_cosine_similarity_matrix(x, eps=1e-8) # print(sim_matrix) y = torch.zeros((100,100)) for i in range(100): for j in range(100): y[i,j] = torch.cosine_similarity(x[i].unsqueeze(dim=0), x[j].unsqueeze(dim=0)) print(y-sim_matrix)
輸出結(jié)果:
tensor([[ 0.0000e+00, 0.0000e+00, -1.8626e-09, ..., -1.7462e-09,
-2.2352e-08, -1.6764e-08],
[ 0.0000e+00, -2.3842e-07, -3.7253e-09, ..., -2.6077e-08,
-9.3132e-09, -1.1642e-08],
[-1.8626e-09, -3.7253e-09, 1.1325e-06, ..., -5.3551e-09,
-4.6566e-09, -1.8626e-08],
...,
[-1.7462e-09, -2.6077e-08, -5.3551e-09, ..., 5.9605e-07,
-2.4214e-08, -2.2352e-08],
[-2.2352e-08, -9.3132e-09, -4.6566e-09, ..., -2.4214e-08,
2.3842e-07, 9.3132e-10],
[-1.6764e-08, -1.1642e-08, -1.8626e-08, ..., -2.2352e-08,
9.3132e-10, 3.5763e-07]])
可以說誤差非常小了,非常之nice。
接下來講講為什么這么寫
首先回顧一下余弦相似性(圖源自百度百科):
其實(shí)一開始我理解不了這個(gè)代碼為什么可以實(shí)現(xiàn)(本人比較呆)。
首先我們可以將輸入看作是一個(gè)向量而不是一個(gè)矩陣,那么
a_n = h_emb.norm(dim=1)
得到的是該向量的二范數(shù),接著用
a_norm = h_emb / torch.max(a_n, eps * torch.ones_like(a_n))
可以看作是,至于為什么要加eps是防止0除。
現(xiàn)在你再把原來的向量看回是一個(gè)矩陣,那么最后的
sim_matrix = torch.einsum('bc,cd->bd', a_norm, a_norm.transpose(0,1))
就好理解得到的是一個(gè)相似性矩陣了。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python機(jī)器學(xué)習(xí)庫scikit-learn入門開發(fā)示例
scikit-learn是一個(gè)開源Python語言機(jī)器學(xué)習(xí)工具包,它涵蓋了幾乎所有主流機(jī)器學(xué)習(xí)算法的實(shí)現(xiàn),并且提供了一致的調(diào)用接口。它基于Numpy和scipy等Python數(shù)值計(jì)算庫,提供了高效的算法實(shí)現(xiàn)2022-07-07Python調(diào)用API接口實(shí)現(xiàn)人臉識別
本文主要介紹了Python調(diào)用API接口實(shí)現(xiàn)人臉識別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02Python設(shè)置matplotlib.plot的坐標(biāo)軸刻度間隔以及刻度范圍
這篇文章主要介紹了Python設(shè)置matplotlib.plot的坐標(biāo)軸刻度間隔以及刻度范圍,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06python實(shí)現(xiàn)盲盒抽獎(jiǎng)功能(減庫存)
本文主要介紹了python實(shí)現(xiàn)盲盒抽獎(jiǎng)功能,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Python pandas dataframe之重命名相同列名
這篇文章主要介紹了Python pandas dataframe之重命名相同列名方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09淺談selenium如何應(yīng)對網(wǎng)頁內(nèi)容需要鼠標(biāo)滾動(dòng)加載的問題
這篇文章主要介紹了淺談selenium如何應(yīng)對網(wǎng)頁內(nèi)容需要鼠標(biāo)滾動(dòng)加載的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03