多维阵列沿一维的矢量点产物



我想使用theano沿两个多维阵列的一个维度计算总和。

我将首先使用numpy准确地描述我想做的事情。 numpy.tensordotnumpy.dot似乎总是在做矩阵产品,而我本质上是在寻找相当于 vector product的批处理。给定的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 中进行此特定的计算,该计算没有einsum等效。我需要使用dottensordot或Theano的专业Einsum子集功能batched_dotbatched_tensordot

我希望改变这种方法的原因是性能;我怀疑使用内置(CUDA)DOT产品的速度要比依靠广播,元素的产品和总和更快。

在theano中,三维张量的尺寸都无法广播。您必须明确设置它们。然后,Numpy原则可以正常工作。一种方法是使用T.patternbroadcast。要了解有关广播的更多信息,请参阅此。

您的一个张量中有三个维度。因此,首先,您需要在末端附加单顿维度,然后使该维度可广泛。这两件事可以通过一个命令-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!

我希望这会有所帮助。

相关内容

  • 没有找到相关文章

最新更新