用于链接张量产品的Python成语是什么?

时间:2017-08-18 21:43:49

标签: python numpy tensorflow

Numpy的outer使其论点变得平坦。因此,无法链接outer来实现(matrix) tensor product的数学定义,例如可能in Mathematica

TensorProduct[a, b, c]

然而,通过使用参数的维度重新整形结果,可以“恢复”此功能,例如

np.outer(a, np.outer(b, c)).reshape(a.shape + b.shape + c.shape)

但我想知道这是否真的是正确的做法。是否有一个我已经缺少的API已经这样做了。也许TensorFlow有我错过的东西?

2 个答案:

答案 0 :(得分:2)

NumPy ufunc的outer method并未展平:

outer = numpy.multiply.outer
result = outer(a, outer(b, c))

答案 1 :(得分:1)

np.outer的代码只是:

return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out)

因此,对于2个1d数组,它与a[:,None] * b[None,:]相同,换句话说,(n,1)数组的元素乘积与(1,m),产生a(n,米)。第二个None是自动的,但我希望将其包括在内以便人性化。

同样的想法可以扩展到2d数组(产生3d)或几个数组。

In [65]: a,b,c = np.ones(2),np.ones(3),np.ones(4)
In [66]: np.outer(a, np.outer(b, c)).reshape(a.shape + b.shape + c.shape)
Out[66]: 
array([[[ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.]],

       [[ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.]]])
In [67]: _.shape
Out[67]: (2, 3, 4)
In [68]: a[:,None,None]*b[None,:,None]*c[None,None,:]
Out[68]: 
array([[[ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.]],

       [[ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.]]])

更一般地说:

In [69]: a,b,c = np.ones((2,2)),np.ones((1,3)),np.ones(4)
In [70]: np.outer(a, np.outer(b, c)).reshape(a.shape + b.shape + c.shape)
....
In [71]: _.shape
Out[71]: (2, 2, 1, 3, 4)

In [73]: a[...,None,None,None]*b[None,None,...,None]*c[None,None,...]
...
In [74]: _.shape
Out[74]: (2, 2, 1, 3, 4)

并使用ufunc outer

In [77]: np.multiply.outer(a, np.multiply.outer(b,c)).shape
Out[77]: (2, 2, 1, 3, 4)

显式广播比这个ufunc外部更啰嗦,但可以给你更多控制权。

另一种方法:

In [84]: np.einsum('ij,kl,m',a,b,c).shape
Out[84]: (2, 2, 1, 3, 4)