Tensordot用于numpy中的向量

时间:2019-02-10 18:21:33

标签: python numpy tensordot

我目前正在尝试使用numpy创建矢量的张量点。例如,假设我具有以下变量:

a = [np.array([1, 2]), np.array([3,4])] 
b = [np.array([5,6]), np.array([7,8])]

,我想计算“向量的张量积”,即[a [0] * b [0],a [0] * b [1],a [1] * b [0],a [1] * b [1]]在我们的示例中给出:

a x b = [[5,12], [7,16], [15, 24], [21, 32]]

我已经尝试过使用Tensordot沿不同的轴进行多种组合,但是它从未给我想要的结果:((

例如,我尝试了以下操作:

np.tensordot(a,b)

这给了我array(70)

np.tensordot(a,b, axes = 0) 这给了我

array([[[[ 5,  6],
     [ 7,  8]],

    [[10, 12],
     [14, 16]]],


   [[[15, 18],
     [21, 24]],

    [[20, 24],
     [28, 32]]]])

我还尝试使用不同的轴(例如np.tensordot(a,b, axes = ([0], [1])))没有成功...

有人可以帮我吗? :) 我敢肯定这很简单,但我似乎错过了一些东西

谢谢。

1 个答案:

答案 0 :(得分:2)

In [663]: a = np.array([[1, 2], [3,4]]); b = np.array([[5,6], [7,8]])

这2个数组的简单点(矩阵乘积):

In [664]: a.dot(b)
Out[664]: 
array([[19, 22],
       [43, 50]])

您想要的数组:

In [665]: [a[0]*b[0], a[0]*b[1], a[1]*b[0], a[1]*b[1]] 
Out[665]: [array([ 5, 12]), array([ 7, 16]), array([15, 24]), array([21, 32])]
In [666]: np.array(_)
Out[666]: 
array([[ 5, 12],
       [ 7, 16],
       [15, 24],
       [21, 32]])

np.tensordot是一种概括np.dot的尝试;对于像这样的2d数组,它不能做一些添加的转置不能做的事情。

从这个意义上讲,您的结果不是tensordotdot涉及sum of products;你什么都没做。相反,它看起来更像是外部产品,或者可能是kron的变体。

通过几次试验,我用einsum复制了您的数组:

In [673]: np.einsum('ij,kj->ikj',a,b)
Out[673]: 
array([[[ 5, 12],
        [ 7, 16]],

       [[15, 24],
        [21, 32]]])
In [674]: _.reshape(-1,2)
Out[674]: 
array([[ 5, 12],
       [ 7, 16],
       [15, 24],
       [21, 32]])
einsumdot这样的

tensordot围绕乘积之和构建,但是使我们可以更好地控制哪些轴相乘,哪些轴相加。在这里,我们不总结任何内容。

我可以通过以下方式获得相同的3d阵列:

In [675]: a[:,None,:]*b[None,:,:]
Out[675]: 
array([[[ 5, 12],
        [ 7, 16]],

       [[15, 24],
        [21, 32]]])

tensordot

根据文档,轴的默认值为2:

In [714]: np.tensordot(a,b)
Out[714]: array(70)
In [715]: np.tensordot(a,b,axes=2)
Out[715]: array(70)
  
      
  • axes = 2 :(默认)张量双收缩:数学:a:b
  •   

换句话说,将数组相乘,然后对所有轴求和。在我看来,使用einsum表示法更清楚:

In [719]: np.einsum('ij,ij',a,b)
Out[719]: 70


In [718]: np.tensordot(a,b,axes=0).shape
Out[718]: (2, 2, 2, 2)
  
      
  • axes = 0:张量积:数学:a\\otimes b   :张量积a \ otimes b
  •   
np.einsum('ij,kl',a,b)

我可以看到您想要的结果,或者至少是(2,2,2,2)数组中的Out[673]版本,作为某种对角线子集。

我不像axes的{​​{1}}模式那样使用这些标量。在上一两篇文章中,我为它们感到困惑,但感觉并不好。我更喜欢tensordot的清晰度。

How does numpy.tensordot function works step-by-step?