python - 多维数组的一维向量点积

标签 python numpy multidimensional-array linear-algebra theano

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

我将首先使用 numpy 准确描述我想做什么。 numpy.tensordotnumpy.dot 似乎总是做一个matrix 产品,而我本质上是在寻找一个批处理等价于 < em>向量 产品。给定 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) 点积会比依赖广播、元素积和求和更快。

最佳答案

在 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!

希望对您有所帮助。

关于python - 多维数组的一维向量点积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42766107/

相关文章:

javascript - 类型错误 : Type error in Javascript when assigning a value to a multidimensional Array

python - 请看我的python石头剪刀布程序

python - symPy 中的 inv() 没有返回正确的值

python-3.x - Python3 字典比较,带有 numpy 数组的嵌套字典

java - 如何将数据存储在以下结构中?

python - 如何从 numpy 数组构造一个 ndarray? Python

python - Keras InvalidArgumentError 与 Model.Fit()

python : efficient bytearray incrementation

python - numpy/pandas 矩阵乘法的多线程?

python - `numpy.random.normal` 在不同的系统上生成不同的数字