Python 大矩阵上的余弦相似性

Python 大矩阵上的余弦相似性,python,numpy,pytorch,cosine-similarity,Python,Numpy,Pytorch,Cosine Similarity,我试图计算一个大矩阵(3Mx2048)的所有对之间的余弦距离,并使用pytorch提取前30个相似向量。 下面是我的代码,它工作得很好,但是每次迭代大约需要30秒,这对于300万字向量来说太长了。 有没有加快速度的想法 import torch.nn.functional as F import torch from tqdm import tqdm import gc sym_dict={} tmp_list=[] tot_dict=torch.load('xbx.pt') all

我试图计算一个大矩阵(3Mx2048)的所有对之间的余弦距离,并使用pytorch提取前30个相似向量。 下面是我的代码,它工作得很好,但是每次迭代大约需要30秒,这对于300万字向量来说太长了。 有没有加快速度的想法

import torch.nn.functional as F
import torch
from tqdm import tqdm
import gc



sym_dict={}
tmp_list=[]

tot_dict=torch.load('xbx.pt')


all_tensors = torch.cat([v.unsqueeze(0) for k,v in tot_dict.items()], dim=0)
token_list= [i for i in tot_dict.keys()]

del tot_dict
gc.collect()



for counter ,value in tqdm(enumerate(token_list)):


  uniq_vec=torch.unsqueeze(all_tensors[counter],dim=0)

  dist = 1 - F.cosine_similarity(uniq_vec,all_tensors)
  index_sorted = torch.argsort(dist)


  roll_me=index_sorted[:30].cpu().numpy().tolist()

  for ind in roll_me:
    tmp_list.append(token_list[ind])
  sym_dict.update({value:tmp_list})
  tmp_list=[]



#save .pt file
torch.save(sym_dict,'sym_dict.pt')


直接找到两个矩阵之间的成对距离有效吗?代码如下:

def pairwise_dist(x, y,p=2, eps=1e-6):
    x_a  =x[..., None, :, :]
    y_a  =y[...,None,:]
    dist = torch.pow(torch.abs((x_a - y_a) + eps), p).sum(dim=-1, keepdim=True).squeeze(2)
    return torch.pow(dist, 1/p)

t1 = torch.rand(3, 10)
t2 = torch.rand(4,10)
dist = pairwise_dist(t1,t2, eps=0)
print(dist)
dist
的形状为
4x3
,其中每行表示
t1
的所有向量的距离,向量为
t2


请注意,此处两个向量之间的成对距离与Pytorch的
F.成对距离

直接找到两个矩阵之间的成对距离有效吗?代码如下:

def pairwise_dist(x, y,p=2, eps=1e-6):
    x_a  =x[..., None, :, :]
    y_a  =y[...,None,:]
    dist = torch.pow(torch.abs((x_a - y_a) + eps), p).sum(dim=-1, keepdim=True).squeeze(2)
    return torch.pow(dist, 1/p)

t1 = torch.rand(3, 10)
t2 = torch.rand(4,10)
dist = pairwise_dist(t1,t2, eps=0)
print(dist)
dist
的形状为
4x3
,其中每行表示
t1
的所有向量的距离,向量为
t2


请注意,此处两个向量之间的成对距离与Pytorch的
F.成对距离

一些细节,如张量的形状,每个循环试图做什么等,将使回答更容易使用每个张量的形状(1x2048)表示一个单词嵌入向量。整个矩阵由300万个字向量组成,因此其形状为(3M x 2048)。每个循环将一个向量与整个矩阵进行比较,以使用余弦距离查找前30个最近的向量。3个单词向量中的每一个都应该以这种方式进行比较,这样我们就可以找到每个单词的前30个列表。一些细节,如张量的形状、每个循环试图做什么等,将使回答更容易使用每个张量的形状(1x2048)代表一个单词嵌入向量。整个矩阵由300万个字向量组成,因此其形状为(3M x 2048)。每个循环将一个向量与整个矩阵进行比较,以使用余弦距离查找前30个最近的向量。3百万个字向量中的每一个都应该以这种方式进行比较,这样我们就可以找到每一个字的前30位列表。即使矩阵很小,它也会消耗所有内存(测试10000个字向量)。即使矩阵很小,它也会消耗所有内存(测试10000个字向量)