我们有两个Tensor:
a = np.arange(8.).reshape(4,2,1)
b = np.arange(16.).reshape(2,4,2)
字符串
我们将实施
np.einsum('ijk,jil->kl', a, b)
型
虽然我们可以得到它的结果,但我们一直在坚持了解Tensor元素求和的过程细节。
首先,我们知道如何
np.einsum('jil', b)
型
改变b
Tensor的元素顺序。
但我们无法理解np.einsum('ijk,jil->kl', a, b)
如何合并组合(求和)Tensor元素。
为了跟踪这个过程,我们使用了字符串:
aa=[[['e'],
['r']],
[['t'],
['y']],
[['u'],
['o']],
[['p'],
['q']]]
型
和
bb=[[[ 'x', 'c'],
[ 'v' , 'n'],
[ 'm', 'h'],
[ 'f' , 'd']],
[[ 's', 'w'],
[ 'a','z'],
['j', 'k'],
['l', 'b']]]
型
因为我们想看看不同的元素如何组合合并来获得np.einsum('ijk,jil->kl', aa, bb)
!
然而np.einsum('jil', bb)
工作正常,但它没有向我展示元素求和的细节。
1条答案
按热度按时间p1iqtdky1#
有几种方法可以理解这一点。
一个是使用@Onyambu建议的例子。
字符串
通过将i和j作为输出的索引,输出数组不再具有形状(k,l),而是(i,j,k,l)。此外,没有相乘的元素被求和在一起。输出数组的每个元素是每个原始数组中的一个元素的乘积。
为了回到最初的行为,我们可以通过轴1求和:
型
然后按轴0求和:
型
理解这一点的另一种方法是将其转换为显式循环。
下面的代码与此einsum等效,但速度较慢。(它也不检查A和B的形状是否兼容。)
型
这给了我们同样的结果,
array([[252., 280.]])
。请注意,循环的内部行
ret[k, l] += A[i, j, k] * B[j, i, l]
与einsum下标'ijk,jil->kl'
相似,只是kl
被移到了开头,ijk
用于索引A,jil
用于索引B。更多信息
Understanding NumPy's einsum