Numpy 张量:张量正面切片上的 Tensordot

Numpy tensor: Tensordot over frontal slices of tensor

我正在尝试对 3D 张量的正面切片执行矩阵乘法,如下所示。如果 X.shape == (N, N)Y.shape == (N, N, Y),则结果张量的形状应为 (N, N, Y).

实现此目的的正确 np.tensordot 语法是什么?

我试图将自己限制在 np.tensordot,而不是 np.einsum,因为我想稍后将此解决方案转换为 Theano。不幸的是,Theano 还没有 np.einsum 实现。

改编自 this paper 关于张量乘法的图形。 非tensordot答案等价于下面

tensor = np.random.rand(3, 3, 2)
X = np.random.rand(3, 3)

output = np.zeros((3, 3, 2))
output[:, :, 0] = X.dot(tensor[:, :, 0])
output[:, :, 1] = X.dot(tensor[:, :, 1])

X 的减少是 axis=1tensor 的减少是 axis=0,因此基于 np.tensordot 的解决方案是 -

np.tensordot(X,tensor, axes=([1],[0]))

解释:

让我们以您的迭代解决方案进行解释,并在其中进行第一次迭代:

output[:, :, 0] = X.dot(tensor[:, :, 0])

在点积中,第一个输入是X,其形状是(N x N),第二个输入是tensor[:, :, 0],它是沿着最后一个轴的第一个切片及其形状是 (N x N)。该点积导致沿 X 的第二个轴(即 axis=1 和沿第一个轴(即 tensor[:, :, 0]axis=0)的减少,这也恰好是第一个轴整个数组 tensor。现在,这将在所有迭代中继续进行。因此,即使在大局中,我们也需要做同样的事情:减少/减少 X 中的 axis=1 和张量中的 axis=0,就像我们所做的一样!


整合@hlin117的回答

np.tensordot(X,tensor, axes=([1],[0]))

时间:

>>> N = 200
>>> tensor = np.random.rand(N, N, 30)
>>> X = np.random.rand(N, N)
>>> 
>>> %timeit np.tensordot(X, tensor, axes=([1], [0]))
100 loops, best of 3: 14.7 ms per loop
>>> %timeit np.tensordot(X, tensor, axes=1)
100 loops, best of 3: 15.2 ms per loop

看起来上面的内容等同于以下内容:

np.tensordot(X, tensor, axes=1)

axes=1,因为(如果axes参数是标量)N应该是第一个参数的最后一个轴,而N应该是第一个第二个参数的轴。