沿多维数组的一维矢量点积

时间:2017-03-13 14:28:15

标签: python numpy multidimensional-array linear-algebra theano

我想使用Theano计算两个多维数组的一个维度的和积。

我将首先使用numpy准确描述我想要做的事情。 numpy.tensordotnumpy.dot似乎总是使用矩阵产品,而我本质上是在寻找一个 vector 产品的批量等效产品。鉴于xy,我想像这样计算z

x = np.random.normal(size=(200, 2, 2, 1000))
y = np.random.normal(size=(200, 2, 2))

# this is how I now approach it:
z = np.sum(y[:,:,:,np.newaxis] * x, axis=1)

# z is of shape (200, 2, 1000)

现在我知道numpy.einsum可能会在这里帮助我,但是我想再次在 Theano 中进行这个特殊的计算,它没有{{1}等价的。我需要使用einsumdot或Theano的专业einsum子集函数tensordotbatched_dot

我希望改变我的方法的原因是性能;我怀疑使用内置(CUDA)点产品将比依赖广播,元素产品和总和更快。

1 个答案:

答案 0 :(得分:1)

在Theano中,三维和四维张量的维度都不是可播放的。你必须明确地设置它们。那么Numpy原则就可以了。一种方法是使用T.patternbroadcast。要阅读有关广播的更多信息,请参阅this

其中一个张量中有三个维度。首先,您需要在末尾附加单个维度,然后使该维度成为可广播的。只需一个命令即T.shape_padaxis即可实现这两件事。整个代码如下:

import theano
from theano import tensor as T
import numpy as np

X = T.ftensor4('X')
Y = T.ftensor3('Y')
Y_broadcast = T.shape_padaxis(Y, axis=-1)  # appending extra dimension and making it 
                                           # broadcastable
Z = T.sum((X*Y_broadcast), axis=1)  # element-wise multiplication
f = theano.function([X, Y], Z, allow_input_downcast=True)

# Making sure that it works and gives correct results

x = np.random.normal(size=(3, 2, 2, 4))
y = np.random.normal(size=(3, 2, 2))

theano_result = f(x,y)
numpy_result = np.sum(y[:,:,:,np.newaxis] * x, axis=1)
print np.amax(theano_result - numpy_result)  # prints 2.7e-7 on my system, close enough!

我希望这会有所帮助。