Pytorch如何快速计算余弦相似性矩阵

 更新时间:2024年02月26日 09:26:10   作者:Daft shiner  
这篇文章主要介绍了Pytorch如何快速计算余弦相似性矩阵问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Pytorch计算余弦相似性矩阵

之前一直想找一个可以快速用矩阵相乘(可以直接GPU加速)计算余弦相似性矩阵的代码,总算找到了。

代码是在参考代码的基础上进行了一些修改以适配自己的任务。

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)

输出结果:

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。

接下来讲讲为什么这么写

首先回顾一下余弦相似性(图源自百度百科):

其实一开始我理解不了这个代码为什么可以实现(本人比较呆)。

首先我们可以将输入看作是一个向量而不是一个矩阵,那么

a_n = h_emb.norm(dim=1)

得到的是该向量的二范数,接着用

a_norm = h_emb / torch.max(a_n, eps * torch.ones_like(a_n))

可以看作是,至于为什么要加eps是防止0除。

现在你再把原来的向量看回是一个矩阵,那么最后的

sim_matrix = torch.einsum('bc,cd->bd', a_norm, a_norm.transpose(0,1))

就好理解得到的是一个相似性矩阵了。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • python3.4用函数操作mysql5.7数据库

    python3.4用函数操作mysql5.7数据库

    这篇文章主要为大家详细介绍了python3.4用函数操作mysql5.7数据库,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • 关于CUDA out of memory的解决方案

    关于CUDA out of memory的解决方案

    这篇文章主要介绍了关于CUDA out of memory的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • python opencv实现信用卡的数字识别

    python opencv实现信用卡的数字识别

    这篇文章主要介绍了python opencv实现信用卡的数字识别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • Python如何通过百度翻译API实现翻译功能

    Python如何通过百度翻译API实现翻译功能

    这篇文章主要介绍了Python如何通过百度翻译API实现翻译功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • pyqt5对用qt designer设计的窗体实现弹出子窗口的示例

    pyqt5对用qt designer设计的窗体实现弹出子窗口的示例

    今天小编就为大家分享一篇pyqt5对用qt designer设计的窗体实现弹出子窗口的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • Python http接口自动化测试框架实现方法示例

    Python http接口自动化测试框架实现方法示例

    这篇文章主要介绍了Python http接口自动化测试框架实现方法,结合实例形式分析了Python针对http接口测试的相关实现与使用操作技巧,需要的朋友可以参考下
    2018-12-12
  • python 实现两个变量值进行交换的n种操作

    python 实现两个变量值进行交换的n种操作

    这篇文章主要介绍了python 实现两个变量值进行交换的n种操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 使用Selenium破解新浪微博的四宫格验证码

    使用Selenium破解新浪微博的四宫格验证码

    今天小编就为大家分享一篇关于使用Selenium破解新浪微博的四宫格验证码的文章,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • Python读取csv文件分隔符设置方法

    Python读取csv文件分隔符设置方法

    今天小编就为大家分享一篇Python读取csv文件分隔符设置方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • python 如何在 Matplotlib 中绘制垂直线

    python 如何在 Matplotlib 中绘制垂直线

    这篇文章主要介绍了python 如何在 Matplotlib 中绘制垂直线,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下
    2021-04-04

最新评论