Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用我的numpy阵列(3000,3)和(3,23000)进行广播_Python_Numpy_Matrix Multiplication_Tensor_Broadcasting - Fatal编程技术网

Python 如何使用我的numpy阵列(3000,3)和(3,23000)进行广播

Python 如何使用我的numpy阵列(3000,3)和(3,23000)进行广播,python,numpy,matrix-multiplication,tensor,broadcasting,Python,Numpy,Matrix Multiplication,Tensor,Broadcasting,我目前有两个数组,形状为v1=(3000,3)和v2=(3,23000)。3000是一个时间维度,因此v1有3000(1,3)个样本,v2有3000(3,2)个样本。我希望做矩阵乘法并沿着3000维广播,这样我得到3000(1,2)个向量作为回报 我已经尝试过重塑,使v1=(1,33000)和v2=(3,2300),这会给出一个错误,表示形状没有对齐 代码: 使用形状为(3000,3)和v2的v1作为(3,23000),我们可以使用- 这给了我们一个shape(3000,2)的输出 我们可以在n

我目前有两个数组,形状为v1=(3000,3)和v2=(3,23000)。3000是一个时间维度,因此v1有3000(1,3)个样本,v2有3000(3,2)个样本。我希望做矩阵乘法并沿着3000维广播,这样我得到3000(1,2)个向量作为回报

我已经尝试过重塑,使v1=(1,33000)和v2=(3,2300),这会给出一个错误,表示形状没有对齐

代码:


使用形状为
(3000,3)
v2
v1
作为
(3,23000)
,我们可以使用-

这给了我们一个shape
(3000,2)
的输出


我们可以在
np.einsum
中使用
optimize
arg。使用
optimize=True
,它在内部利用
BLAS
,使用
optimize=False
求助于简单的C循环。这种
BLAS
方式也需要一些设置工作。因此,对于经过总和缩减的轴的适当长度,我们可能希望将该标志设置为
True
,否则设置为
False
。在这种情况下,这些轴似乎很短,因此我们最好使用默认值:
optimize=False
input。

我建议您不要使用
optimize=True
标志,因为出于某种奇怪的原因,它是有效的。另外,如果最终需要2D数组作为最终结果,我建议您显式地将2D数组升级为3D,执行批处理矩阵乘法,然后压缩结果数组的单态维数。请查找以下代码:

# sample arrays
In [25]: v1 = np.random.random_sample((3000, 3))
In [26]: v2 = np.random.random_sample((3, 2, 3000))

# Divakar's approach
In [27]: %timeit np.einsum('ij,jki->ik',v1,v2, optimize=True)
80.7 µs ± 792 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# needed for future use
In [28]: res_optimized = np.einsum('ij,jki->ik',v1,v2, optimize=True)

# promoting to 3D array and swapping axes
In [29]: v1 = v1[:, np.newaxis, :]
In [30]: v2 = np.moveaxis(v2, 2, 0)

# perform batch matrix multiplication
In [31]: %timeit np.einsum("bij, bjk -> bik", v1, v2)
47.9 µs ± 496 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# for sanity checking
In [32]: res = np.einsum("bij, bjk -> bik", v1, v2)

In [33]: res.shape, res_optimized.shape
Out[33]: ((3000, 1, 2), (3000, 2))

# squeeze the singleton dimension and perform sanity check with Divakar's approach
In [34]: np.allclose(res.squeeze(), res_optimized)
Out[34]: True
因此,正如我们从上述计时中所看到的,不使用
optimize=True
标志可获得约2倍的加速比。另外,显式地将数组整形为3D可以更好地了解使用
numpy.einsum()
时的情况

注:计时是使用最新的NumPy版本
'1.16.1'



请阅读更多关于

的信息,这等同于矩阵乘法吗?我试图阅读einsum上的文档,但它们让我感到困惑。@seanysull它在引擎盖下对张量(超过2个dims)执行矩阵乘法,利用BLAS将优化标志设置为True,与
np.dot
@Divakar相同。你知道为什么使用
optimize=True
比不使用它时消耗更多的时间吗?(请参见下面我的代码中的计时)。有没有可能它花了很多时间来优化代码?@kmario23您使用的是哪个版本的NumPy?@您是对的。已编辑的问题,并对其进行了评论。谢谢你指出这一点。
np.einsum('ij,jki->ik',v1,v2)
# sample arrays
In [25]: v1 = np.random.random_sample((3000, 3))
In [26]: v2 = np.random.random_sample((3, 2, 3000))

# Divakar's approach
In [27]: %timeit np.einsum('ij,jki->ik',v1,v2, optimize=True)
80.7 µs ± 792 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# needed for future use
In [28]: res_optimized = np.einsum('ij,jki->ik',v1,v2, optimize=True)

# promoting to 3D array and swapping axes
In [29]: v1 = v1[:, np.newaxis, :]
In [30]: v2 = np.moveaxis(v2, 2, 0)

# perform batch matrix multiplication
In [31]: %timeit np.einsum("bij, bjk -> bik", v1, v2)
47.9 µs ± 496 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# for sanity checking
In [32]: res = np.einsum("bij, bjk -> bik", v1, v2)

In [33]: res.shape, res_optimized.shape
Out[33]: ((3000, 1, 2), (3000, 2))

# squeeze the singleton dimension and perform sanity check with Divakar's approach
In [34]: np.allclose(res.squeeze(), res_optimized)
Out[34]: True