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=1
,tensor
的减少是 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
应该是第一个第二个参数的轴。
我正在尝试对 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=1
,tensor
的减少是 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
应该是第一个第二个参数的轴。