我过去一直在使用np.tensordot
,没有任何问题,但是我现在的例子,我很难理解结果。在
对于np.tensordot(d * y, r, axes=((1, 2, 3), (2, 3, 4))).shape
,我希望得到(6, 5)
的形状,但是我得到了(6, 6, 5)
。但是,当我在axis0上运行tensordot
6次时,我会得到预期的结果,但我宁愿让tensordot
在一次调用中为我完成这项工作。这怎么了?在
>>> import numpy as np
>>> d = np.random.rand(6, 7, 1, 2)
>>> y = np.random.rand(6, 7, 1, 2)
>>> r = np.random.rand(6, 5, 7, 1, 2) > 0.5
>>>
>>> np.tensordot(d * y, r, axes=((1, 2, 3), (2, 3, 4))).shape
(6, 6, 5)
>>> np.tensordot((d * y)[0], r[0], axes=((0, 1, 2), (1, 2, 3))).shape
(5,)
>>> np.tensordot((d * y)[1], r[1], axes=((0, 1, 2), (1, 2, 3))).shape
(5,)
>>> np.tensordot((d * y)[2], r[2], axes=((0, 1, 2), (1, 2, 3))).shape
(5,)
...
>>> np.tensordot((d * y)[5], r[5], axes=((0, 1, 2), (1, 2, 3))).shape
(5,)
在
tensordot
中,每个轴都是:所以当你写
tensordot(d * y, r, axes=((1, 2, 3), (2, 3, 4)))
时,你在计算:其中
^{pr2}$dy ≡ d * y
。你想要计算的是请注意,
i
出现了两次,但没有被求和。这意味着i
在这里实际上是受约束的(可以把它看作一个隐式的Kronecker delta)。因此,这并不是tensordot
自己就能完成的。在最简单的方法是使用
einsum
并显式声明所需的内容:由于
einsum
可以看到您试图计算的整个表达式,因此它应该能够找到一种相对最佳的方法来执行此计算。在考虑一个更简单的例子:
这相当于:
^{pr2}$这不是
ij,ij->i
。它是未列出的轴上的外部产品,而不是逐个元素。在您有},并想对(7,1,2)求和。它在(6)和(6,5)上做一个外积。在
(6, 7, 1, 2)
和{我想
np.einsum('i...,ij...->ij',d,r)
可以满足你的需要。在在封面下,
tensordot
会重塑和交换轴,这样问题就变成了一个2dnp.dot
调用。然后根据需要进行重塑和交换。在更正;我不能在“点”维度中使用省略号
方法:
时间安排
另一个解决方案是使用
@
(matmul)运算符相关问题 更多 >
编程相关推荐