块状张量:张量在张量的额叶上


问题内容

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

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

我试图将自己限制为np.tensordot,而不是np.einsum,因为我想稍后将此解决方案翻译为Theano。不幸的是,Theanonp.einsum尚未实现。

在此处输入图片说明

本文改编的关于张量乘法的图形。非张量点答案等效于以下内容

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])

问题答案:

减少是axis=1针对Xaxis=0进行的tensor,因此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与沿着第一轴,即axis=0tensor[:, :, 0],这也正好是整个阵列的第一轴线tensor。现在,这将在所有迭代中继续进行。因此,即使在大画面,我们需要做的是相同的:减少/丧失axis=1Xaxis=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