让我们澄清一下
matmul
numpy
:
In [8]: A = np.arange(24).reshape(2,3,4); B = np.arange(8).reshape(2,4,1)
In [9]: A@B
Out[9]:
array([[[ 14],
[ 38],
[ 62]],
[[302],
[390],
[478]]])
In [10]: _.shape
Out[10]: (2, 3, 1)
这是在做一件好事
dot
,或最后两个轴上的二维矩阵积。在第一个轴上有效的批处理:
In [11]: A[0].dot(B[0])
Out[11]:
array([[14],
[38],
[62]])
einsum
,而
i
k
轴是1的乘积之和。
In [12]: np.einsum('ijk,ikl->ijl',A,B)
Out[12]:
array([[[ 14],
[ 38],
[ 62]],
[[302],
[390],
[478]]])
我认为这里的问题是
sympy/tensor
模块也可以这样做。
In [13]: from sympy import Array, tensorproduct, tensorcontraction
In [14]: As = Array(A[0])
In [15]: As
Out[15]: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
In [16]: Bs = Array(B[0])
In [17]: Bs
Out[17]: [[0], [1], [2], [3]]
In [18]: tensorproduct(As,Bs)
Out[18]: [[[[0], [0], [0], [0]], [[0], [1], [2], [3]], [[0], [2], [4], [6]], [[0], [3], [6], [9]]], [[[0], [4], [8], [12]], [[0], [5], [10], [15]], [[0], [6], [12], [18]], [[0], [7], [14], [21]]], [[[0], [8], [16], [24]], [[0], [9], [18], [27]], [[0], [10], [20], [30]], [[0], [11], [22], [33]]]]
In [19]: tensorcontraction(_, (1,2))
Out[19]: [[14], [38], [62]]
所以
Out[19]
Out[11]
. 我们可以重复这一点
A[1]
和
sympy/Matrix
类别:
In [20]: from sympy import Matrix
In [21]: Matrix(A[0])*Matrix(B[0])
Out[21]:
Matrix([
[14],
[38],
[62]])
制作3d交响乐
Array
:
In [22]: AS = Array(A)
In [23]: AS
Out[23]: [[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]
In [24]: AS.shape
Out[24]: (2, 3, 4)
In [25]: BS = Array(B)
In [26]: BS.shape
Out[26]: (2, 4, 1)
tensorproduct
生成一个6d阵列:
In [28]: CS = tensorproduct(AS, BS)
In [29]: CS.shape
Out[29]: (2, 3, 4, 2, 4, 1)
拆下中间部分
2
:
In [30]: CS[:,:,:,0,:,:].shape
Out[30]: (2, 3, 4, 4, 1)
In [31]: tensorcontraction(CS[:,:,:,0,:,:],(2,3)).shape
Out[31]: (2, 3, 1)
In [32]: tensorcontraction(CS[:,:,:,0,:,:],(2,3))
Out[32]: [[[14], [38], [62]], [[86], [110], [134]]]
上半场比赛
Out[9]
马特穆尔
添加到
这在很大程度上是因为很难实现所需的“批量”操作
np.dot
np.tensordot
).
np.einsum
这
埃因苏姆
用一个
K
收缩,包含
输出[9]
和
Out[32]
In [80]: np.einsum('ijk,lkn',A,B)
Out[80]:
array([[[[ 14],
[ 38]],
[[ 38],
[126]],
[[ 62],
[214]]],
[[[ 86],
[302]],
[[110],
[390]],
[[134],
[478]]]])
问题是,如何选择正确的子集。
tensorcontraction
CS[:,:,:,0,:,:]
这不是消除重复的正确方法。
In [81]: tensorcontraction(CS, (2,4))
Out[81]: [[[[14], [38]], [[38], [126]], [[62], [214]]], [[[86], [302]], [[110], [390]], [[134], [478]]]]
Out[81]: [[[[14], [38]],
[[38], [126]],
[[62], [214]]],
[[[86], [302]],
[[110], [390]],
[[134], [478]]]
]
和
埃因苏姆
In [96]: np.einsum('ijk,lkn',A,B)[[0,1],:,[0,1],:]
Out[96]:
array([[[ 14],
[ 38],
[ 62]],
[[302],
[390],
[478]]])
我们可以用另一个做同样的事情
埃因苏姆
np.einsum('ijim->ijm', np.einsum('ijk,lkn',A,B))
In[12]
我也可以用这个
Out[81]
对象这个
sympy.Array
显然没有实现与之相同的高级索引
:
In [108]: np.array(Out[81].tolist())[[0,1],:,[0,1],:]
Out[108]:
array([[[14],
[38],
[62]],
[[302],
[390],
[478]]], dtype=object)
我应该记得,在其他情况下,当我试图实施
马特穆尔
使用
NP点
,我必须这样画对角线。实际上
在非合并维度上获取外部产品,我们必须丢弃大部分值。
另一种看待这一点的方式是我们想要
np.dot(A[0], B[0])
np.dot(A[1], B[1])
tesorproduct
(外部产品)也给了我们
np.dot(A[0], B[1])
和
np.dot(A[1], B[0])
.