由于最近的工作需要使用矩阵中每个样本之间的cxdwl距离,因此记录如何在简便快捷上计算tensor之间的cxdwl距离(使用Pytorch框架)。
在我以前的想法中,是两轮或一轮求每个样本之间的cxdwl距离,但只有看了michuanhaohao/Reid-strong-baseline中的Euclidean_dist (方法的运算后才开始探索新大陆)
一、理论分析
首先从理论上介绍,矩阵间cxdwl距离的快速计算参考了@ 矩阵的博客。 原文是
3359 blog.csdn.net/frank ZD/article/details/80251042
二、代码分析
下面的代码为每行添加必要的注释。 (来源:https://github.com/michuanhaohao/Reid-strong-baseline/blob/master/layers/triplet _ line
defeuclidean_dist(x,y ) :
''''
Args:
x: pytorch Variable,with shape [m,d]
y: pytorch Variable,with shape [n,d]
Returns:
dist: pytorch Variable,with shape [m,n]
''''
m,n=x.size(0),y.size(0) (0) ) ) ) ) ) ) )。
# xx为pow ) )方法对各个数据进行平方操作,然后在axis=1个方向(横向,即第一列指向最后一列的方向)上进行加法运算。 此时,xx的shape经过(m,1 )、expand )方法,扩展n-1次。 此时,xx的形状为) m
xx=Torch.pow(x,2 ).sum (1,keepdim=True ).expand(m,n ) ) ) ) )。
# yy最后进行倒排操作
YY=Torch.pow(y,2 ).sum(1,keepdim=True ).expand(n,m ).t ) ) ) ) )。
dist=xx yy
# torch.addmm (beta=1,input,alpha=1,mat1,mat2,out=None ),此行意味着dist - 2 * x * yT
dist.addmm_(1,-2,x,y.t ) )
# clamp ) )函数限定dist中元素的最大最小范围,最后可以卡方dist得到样本之间的距离矩阵
dist=dist.clamp(min=1e-12 ).sqrt ) # for numerical stability
返回磁盘
三.德谟示威
接下来用简单的demo实现(也便于自己调查最后的结果是否正确) )。
导入途径
defeuclidean_dist(x,y ) :
m,n=x.size(0),y.size(0) (0) ) ) ) ) ) ) )。
xx=Torch.pow(x,2 ).sum (1,keepdim=True ).expand(m,n ) ) ) )。
YY=Torch.pow(y,2 ).sum(1,keepdim=True ).expand(n,m ).t ) ) ) ) )。
dist=xx yy
dist.addmm_(1,-2,x,y.t ) )
dist=dist.clamp(min=1e-12 ).sqrt ) # for numerical stability
返回磁盘
if __name__=='__main__':
x=torch.tensor ([ 1.0,2.0,3.0,4.0 ],[ 2.0,5.0,7.0,9.0 ] ) )
y=torch.tensor ([ 3.0,1.0,2.0,5.0 ],[ 2.0,3.0,4.0,6.0 ] ) )
dist_matrix=euclidean_dist(x,y )
打印(dist _ matrix )是
最终的输出结果如下
tensor ([ 2.6458,2.6458 ],[ 7.6158,4.6904 ] ) )
虽然理论看起来有点麻烦,但jxdl想想,还是很简单的。 本文进行了使用pytorch下的tensor变量的演示,但矩阵的原理也是一样的。 掌握了这种方法后,以后就可以有效地计算矩阵之间的cxdwl距离,而不用循环计算。