【发布时间】:2021-07-24 06:34:15
【问题描述】:
NumPy 的tensordot 和einsum 函数之间的异同有详细记录,并在本论坛中进行了广泛讨论(例如[1]、[2]、[3]、[4]、[5]) .但是,我遇到了一个使用einsum 进行矩阵乘法的实例,我发现使用tensordot 进行复制非常困难,如果不是不可能的话:如果我们的两个数组是,
>>> A = np.array([[0, 1], [1, 0]])
>>> B = np.arange(2 ** 4).reshape((2, 2, 2, 2))
是否存在一行tensordot 等价于以下内容?
>>> np.einsum("ab,ibjk->iajk", A, B)
array([[[[ 4, 5],
[ 6, 7]],
[[ 0, 1],
[ 2, 3]]],
[[[12, 13],
[14, 15]],
[[ 8, 9],
[10, 11]]]])
根据我的发现,答案似乎是“否”。问题出现在输出维度iajk 的索引中。这里,数组A 的维度a 出现在数组B 的维度i 和j 之间。如果输出维度的索引改为aijk,np.tensordot(A, B, (1, 1)) 会正常工作。为了确定,我使用所有可能的轴进行了测试,
>>> output_einsum = np.einsum("ab,ibjk->iajk", A, B)
>>> axes_A = [-2, -1, 0, 1]
>>> axes_B = [-4, -3, -2, -1, 0, 1, 2, 3]
>>> for i in axes_A:
... for j in axes_B:
... output_tensordot = np.tensordot(A, B, axes=(i, j))
... if np.allclose(ouput_einsum, output_tensordot):
... print(i,j)
...
并发现没有任何允许的轴组合产生所需的结果。请注意,B 的维度将axes 参数的每个元素的长度限制为一。使用tensordot 不能在一行中重现具有交错输出尺寸的einsum 函数是否正确?如果是这样,是否存在多行解决方法?
【问题讨论】:
-
Tensordot 使用 reshape 和 transpose 将问题简化为简单的
dot。einsum更为笼统,但在这种情况下,我怀疑它所缺少的只是结果的转置。 -
您在
tensordot中指定的所有内容都是b,即共享的产品总和维度。
标签: python arrays numpy numpy-einsum tensordot