文章目录
import torch
# 设置随机数种子,以保证结果可重现
torch.manual_seed(0)
a = torch.randn(4, 3)
tensor([[ 1.5410, -0.2934, -2.1788],
[ 0.5684, -1.0845, -1.3986],
[ 0.4033, 0.8380, -0.7193],
[-0.4033, -0.5966, 0.1820]])
余弦相似度的公式如下所示:

可以使用torch自带的余弦相似度计算函数(下面三种用哪一个都可以,效果是一样的):
torch.cosine_similarity(x1, x2, dim=1, eps=1e-08)
torch.nn.CosineSimilarity(x1, x2, dim=1, eps=1e-08)
torch.nn.functional.cosine_similarity(x1, x2, dim=1, eps=1e-08) → Tensor
该函数原文档在:torch官方文档

cosine_similarity中的参数要两个tensor数据,而我们的需求是求一个tensor内的行与行之间的余弦相似度。很显然不能直接使用该函数。
变量a的shape是(4, 3), 求a中的行与行之间的相似性,每行与每行有一个相似度,那么最终得到的结果应该是shape为(4, 4)。这个结果意味着a中的每一行要与包括本行在内的4行都有一个相似度数值。
如下图所示,以第一行与所有行的相似度计算为例:

分别拿着第一行的数据再与右侧所有行的数据按照余弦相似度计算,然后再换第二行的数据再与右侧所有行数据计算。这是正常人类的计算过程。
固然上图中的处理torch 配合for循环依然能够实现。但是torch的一种快捷做法如下图所示,直接将第一行数据复制多份,每一份分别与右侧的每一行计算。

按照这个逻辑,下图则是计算的全过程:

如此就满足torch.cosine_similarity需要输入两个tensor的要求了。左侧的数据是每一行都分别复制了4次,右侧的是整体所有行被复制了4次。

a.unsqueeze(1)得到一个shape为(4,1,3)的tensor,a.unsqueeze(0)得到一个shape为(1,4,3)的tensor。(4,1,3)的tensor要和(1,4,3)的tensor进行运算,必须扩充到同一个shape,这样就都变成了(4,4,3),这就是torch的广播机制(broadcast)。
而在广播过程中,shape为(4,1,3)的tensor要变成(4,4,3)的tensor就只能把后边的3多复制几次。也就实现了上图中的左侧tensor的效果;同理shape为(1,4,3)的tensor要变成(4,4,3)的tensor就只能把后边的(4,3)多复制几次。
因此对于一个shape为(4,3)的tensor,使用下行公式可以得到其行与行的余弦相似度。
similarity = torch.cosine_similarity(a.unsqueeze(1), a.unsqueeze(0), dim=-1)
tensor([[ 1.0000, 0.8499, 0.6155, -0.4228],
[ 0.8499, 1.0000, 0.1493, 0.1182],
[ 0.6155, 0.1493, 1.0000, -0.9087],
[-0.4228, 0.1182, -0.9087, 1.0000]])
上述是一行实现余弦相似度的代码,在代码角度上非常简洁,但是会消耗较多的时间(因为参与计算的维度增大的原因)。下面可以根据公式两行代码实现,由公式可以看出,两行之间的余弦相似度是通过方差归一化后的两行数值内积得到的。
所以方法如下:
a = a / torch.norm(a, dim=-1, keepdim=True) # 方差归一化,即除以各自的模
similarity = torch.mm(a, a.T) # 矩阵乘法
该方法可以不通过扩充快速实现同一tensor矩阵内每行之间的余弦相似度。该方法在CPU上的求解速度几乎是torch.cosine_similarity的10X倍。
如果该内容对您有用,请点击 收藏+点赞
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行
我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO