简单讲解torch.sparse.LongTensor

简单讲解torch.sparse.LongTensor,第1张

文章目录
      • 前言
      • 构造
      • 属性和运算

前言
import torch

当一个tensor有特别多0的时候,我们可以使用稀疏矩阵来存储,大家可能都听过的库是sicpy,不过,本文要讲的是torch。


构造

有大量0元素的时候,我们可以使用坐标形式存储稀疏矩阵,例如我们有一个3*3的矩阵,但是只有0,0处有值,值为1,其他地方全为0,那么我们只需要如下做即可:

i = torch.LongTensor([[0],
                          [0]])
v = torch.FloatTensor([1])
a=torch.sparse.FloatTensor(i, v, torch.Size([3,3]))
a


解释:

  1. nnz means: number of non zero elements.即非0元素个数。


  2. 布局就是稀疏矩阵存储格式,我们这里是坐标形式,即coordinate,这个和scipy一样。


注意,我们的稀疏张量格式允许uncoalesced(未合并) 的稀疏张量, 什么意思?如下:

i = torch.LongTensor([[0,0],
                          [0,0]])
v = torch.FloatTensor([1,5])
a=torch.sparse.FloatTensor(i, v, torch.Size([3,3]))
a


可以发现,坐标0,0处值为1,又为5,非常反直觉。


其实,这只是未合并而已,合并的意思就是会加起来,从而变成6,也就是说坐标0,0处的值实际上为6。


a.coalesce()#进行合并 *** 作


注意,默认情况上,如果按照上述方法来构造稀疏矩阵,那么就是未合并状态uncoalesced=True,而不管你是否有重复的坐标。


属性和运算
a.indices()#查看坐标
a.values()#查看非零值
#注意,这个针对的是coalesced的稀疏矩阵才可以。


a._indices()#前面加一个_,这个不需要合并的稀疏矩阵,其会原样返回构造时候的索引。


a.to_dense()#将稀疏tensor转化为稠密tensor。


a *= 1000#所有值乘以1000. a +=1000#这个不允许,因为加1000需要每一个元素都加,直接就破坏了稀疏矩阵结构了,原来0的现在变成了非0.

tensor([[1., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])

两个稀疏矩阵相减,这个也比较容易实现,合并两者的坐标,然后相减即可,如下:

i = torch.LongTensor([[0,0],
                          [0,1]])
v = torch.FloatTensor([1,5])
a=torch.sparse.FloatTensor(i, v, torch.Size([3,3]))
i = torch.LongTensor([[0,0],
                          [0,2]])
v = torch.FloatTensor([1,4])
b=torch.sparse.FloatTensor(i, v, torch.Size([3,3]))
a-b

tensor(indices=tensor([[0, 0, 0],
[0, 1, 2]]),
values=tensor([ 0., 5., -4.]),
size=(3, 3), nnz=3, layout=torch.sparse_coo)

同理,两个稀疏矩阵相加,也是比较容易实现的(因为加法和减法本质上一样),而且此时会重新排列那个indices,排列准则是坐标中的x坐标,从小到大排列。


上面说完了加减乘除,其他的还有按照某个维度求和:

torch.sparse.sum(a,dim=1)

这个也是比较容易实现的,因为只需要找到每一行的索引以及值,然后相加即可。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/569538.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存