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有我错过的东西?
答案 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)