Python 为什么tensordot/Reforme与kron不一致?

Python 为什么tensordot/Reforme与kron不一致?,python,numpy,matrix,tensor,Python,Numpy,Matrix,Tensor,如果我用形状定义数组X(2,2): 以kronecker产品为例,然后使用 np.kron(X, X).reshape((2, 2, 2, 2)) 我得到一个结果矩阵: array([[[[ 1, 2], [ 2, 4]], [[ 3, 4], [ 6, 8]]], [[[ 3, 6], [ 4, 8]], [[ 9, 12], [12, 16]]]])

如果我用形状定义数组
X
(2,2):

以kronecker产品为例,然后使用

np.kron(X, X).reshape((2, 2, 2, 2))
我得到一个结果矩阵:

array([[[[ 1,  2],
         [ 2,  4]],

        [[ 3,  4],
         [ 6,  8]]],


       [[[ 3,  6],
         [ 4,  8]],

        [[ 9, 12],
         [12, 16]]]])
但是,当我使用
np.tensordot(X,X,axes=0)
时,输出以下矩阵

array([[[[ 1,  2],
         [ 3,  4]],

        [[ 2,  4],
         [ 6,  8]]],


       [[[ 3,  6],
         [ 9, 12]],

        [[ 4,  8],
         [12, 16]]]])

这与第一次输出不同。为什么会这样?我在寻找答案时发现,但我不明白为什么这个解决方案有效,或者如何推广到更高的维度。

我的第一个问题是,为什么你认为它们是一样的

让我们在不改变形状的情况下执行
kron

In [403]: X = np.array([[1, 2],
     ...:               [3, 4]])
     ...:               
In [404]: np.kron(X,X)
Out[404]: 
array([[ 1,  2,  2,  4],
       [ 3,  4,  6,  8],
       [ 3,  6,  4,  8],
       [ 9, 12, 12, 16]])
很容易将动作形象化

[X*1, X*2
 X*3, X*4]
tensordot
通常被认为是
np.dot
的推广,能够处理比普通矩阵积(即一个或多个轴上的积之和)更复杂的情况。但这里没有求和

In [405]: np.tensordot(X,X, axes=0)
Out[405]: 
array([[[[ 1,  2],
         [ 3,  4]],

        [[ 2,  4],
         [ 6,  8]]],


       [[[ 3,  6],
         [ 9, 12]],

        [[ 4,  8],
         [12, 16]]]])
axes
是一个整数而不是一个元组时,该操作有点难以理解。文件说:

``axes = 0`` : tensor product :math:`a\otimes b`
我只是试图解释当轴是标量时会发生什么(这不是小事)

指定
axes=0
相当于提供此元组:

np.tensordot(X,X, axes=([],[]))
在任何情况下,从输出中可以明显看出,这个tensordot产生的数字是相同的——但布局与
kron
不同

我可以用

In [424]: np.tensordot(X,X,axes=0).transpose(0,2,1,3).reshape(4,4)
Out[424]: 
array([[ 1,  2,  2,  4],
       [ 3,  4,  6,  8],
       [ 3,  6,  4,  8],
       [ 9, 12, 12, 16]])
也就是说,我交换了中间的两个轴

省略重塑,我得到的是你从
kron
得到的相同(2,2,2,2):

np.tensordot(X,X,axes=0).transpose(0,2,1,3)

我喜欢
np.einsum
的明确性:

np.einsum('ij,kl->ijkl',X,X)    # = tensordot(X,X,0)
np.einsum('ij,kl->ikjl',X,X)    # = kron(X,X).reshape(2,2,2,2)
或使用广播,这两种产品是:

X[:,:,None,None]*X[None,None,:,:]   # tensordot 0
X[:,None,:,None]*X[None,:,None,:]   # kron
X[:,:,None,None]*X[None,None,:,:]   # tensordot 0
X[:,None,:,None]*X[None,:,None,:]   # kron