Pytorch 将tensordot与torch一起使用。稀疏张量

Pytorch 将tensordot与torch一起使用。稀疏张量,pytorch,sparse-matrix,tensor,torch,tensordot,Pytorch,Sparse Matrix,Tensor,Torch,Tensordot,是否可以使用类似于火炬稀疏张量的“tensordot”方法 我试图把一个四维张量应用到一个二维张量上。这是可能的使用火炬或numpy。但是,我没有找到使用torch.sparse而不使用“.to_dense()”使稀疏张量密集的方法 更准确地说,以下是我不使用“.to_dense()”时要做的事情: (以下是输出:) 或者,下面是使用numpy的类似代码: import numpy as np tensor4D = np.zeros((4,3,4,3)) tensor4D[0,0,0,0] =

是否可以使用类似于火炬稀疏张量的“tensordot”方法

我试图把一个四维张量应用到一个二维张量上。这是可能的使用火炬或numpy。但是,我没有找到使用torch.sparse而不使用“.to_dense()”使稀疏张量密集的方法

更准确地说,以下是我不使用“.to_dense()”时要做的事情:

(以下是输出:)

或者,下面是使用numpy的类似代码:

import numpy as np

tensor4D = np.zeros((4,3,4,3))
tensor4D[0,0,0,0] = 1
tensor4D[1,1,1,1] = 2
tensor4D[2,2,2,2] = 3
inp = np.random.rand(4,3)

out = np.tensordot(tensor4D,inp)

print(inp)
print(out)
(以下是输出:)


谢谢你的帮助

通过“压缩”tensor4D的前两个和后两个维度,可以将特定的
tensordot
转换为简单的矩阵乘法

简而言之,你想做的是

raw=tensor4D.view(nb_x*nb_y,nb_x*nb_y)@inp.flatten()
out=原始视图(nb_x,nb_y)
但是,由于稀疏张量未实现
视图
重塑
,因此必须手动执行:

sz=tensor4D.shape
系数=火炬张量([[1,sz[1],0,0],[0,0,1,sz[3]])
重塑=torch.sparse.FloatTensor(系数@idx,tensor4D.\u值(),torch.Size([nb_x*nb_y,nb_x*nb_y]))
#一旦我们重塑了tensord4D,一切都将从这里开始
raw=torch.sparse.mm(整形,inp.flatte()[:,无])
out=原始形状(nb_x,nb_y)
打印(输出)
输出是


事实上,这非常有效,谢谢你的回答

在我看来,这种方法的缺点是很难一概而论

事实上,“inp”和“out”应该是图像。在这里,它们是黑白图像,因为只有两个维度:高度和宽度

如果我取RGB图像,那么我必须考虑6D张量作用在3D张量上。我仍然可以运用同样的技巧,将前三个维度“挤压”在一起,最后三个维度“挤压”在一起。然而,在我看来,它将变得更加涉及非常快(也许我错了)。而使用tensordot则更易于推广


因此,我将使用您提出的解决方案,但如果有人找到其他解决方案,我仍然感兴趣。

您是否检查了if
torch.einsum
是否适用于稀疏张量?我刚刚检查过,它不适用于稀疏张量。但是,如果我之前将它们设置为稠密的,那么它就会工作(像tensordot)。移动到6 dims:使用
einsum
tensordot
总是会更容易,因为这两个函数都不支持稀疏张量(现在),我认为除了我的答案中概述的一个,没有真正的替代方案:重塑为2D并应用稀疏点积。推广到6DIM并没有那么复杂:您只需要
coef
成为
2x6
,而不是
2x4
import numpy as np

tensor4D = np.zeros((4,3,4,3))
tensor4D[0,0,0,0] = 1
tensor4D[1,1,1,1] = 2
tensor4D[2,2,2,2] = 3
inp = np.random.rand(4,3)

out = np.tensordot(tensor4D,inp)

print(inp)
print(out)
tensor([[0.4180, 0.0000, 0.0000],
   [0.0000, 0.6025, 0.0000],
   [0.0000, 0.0000, 0.5897],
   [0.0000, 0.0000, 0.0000]])