【问题标题】:How to vectorize multiple matrix multiplications in numpy?如何在numpy中向量化多个矩阵乘法?
【发布时间】:2018-05-02 08:54:45
【问题描述】:

对于我的意思的概念性概念,我有 2 个数据点:

x_0 = np.array([0.6, 1.4])[:, None]
x_1 = np.array([2.6, 3.4])[:, None]

还有一个 2x2 矩阵:

y = np.array([[2, 2], [2, 2]])

如果我执行x_0.T @ y @ x_0,我会得到array([[ 8.]])。同样,x_1.T @ y @ x_1 返回array([[ 72.]])

但是有没有一种方法可以一次性执行这两项计算,而不需要 for 循环?显然,这里的加速可以忽略不计,但我正在处理的数据点比这里提供的要多得多。

【问题讨论】:

  • x_s 是如何存储的?
  • 它们是列堆叠的。每列包含一个像素的 RGB 值,并且有 n 列(对于 n 像素)。在np.array举行。

标签: python numpy vectorization


【解决方案1】:

x作为x_0x_1等的列堆叠版本,我们可以使用np.einsum-

np.einsum('ji,jk,ki->i',x,y,x)

混合使用np.einsummatrix-multiplcation -

np.einsum('ij,ji->i',x.T.dot(y),x)

如前所述,x 被假定为列堆叠式,如下所示:

x = np.column_stack((x_0, x_1))

运行时测试-

In [236]: x = np.random.randint(0,255,(3,100000))

In [237]: y = np.random.randint(0,255,(3,3))

# Proposed in @titipata's post/comments under this post
In [238]: %timeit (x.T.dot(y)*x.T).sum(1)
100 loops, best of 3: 3.45 ms per loop

# Proposed earlier in this post
In [239]: %timeit np.einsum('ji,jk,ki->i',x,y,x)
1000 loops, best of 3: 832 µs per loop

# Proposed earlier in this post
In [240]: %timeit np.einsum('ij,ji->i',x.T.dot(y),x)
100 loops, best of 3: 2.6 ms per loop

【讨论】:

  • 谢谢,这似乎有效。我查看了einsum 的文档,虽然它看起来非常强大,但我还不明白它是如何工作的。我会继续看下去的。同样,如果没有einsum,是否可以做到这一点?
  • @KeirSimmons 澄清我在问题下提出的疑问?
  • @KeirSimmons 如果需要额外的内存,更简单的方法是 - (x.T.dot(y)*x.T).sum(1)
【解决方案2】:

基本上,您希望对您拥有的所有x 执行操作(x.T).dot(A).dot(x)

x_0 = np.array([0.6, 1.4])[:, None]
x_1 = np.array([2.6, 3.4])[:, None]
x = np.hstack((x_0, x_1)) # [[ 0.6  2.6], [ 1.4  3.4]]

考虑它的简单方法是将所有 x_iy 相乘

[x_i.dot(y).dot(x_i) for x_i in x.T]
>> [8.0, 72.0]

但这当然效率不高。但是,您可以做到这一点,您可以先对xy 进行点积,然后再乘以自身并在列上求和,即您手动进行点积。这将使计算速度更快:

x = x.T
(x.dot(y) * x).sum(axis=1)
>> array([  8.,  72.])

注意我先转置矩阵是因为我们想将y的列乘以x的每一行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-11
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    相关资源
    最近更新 更多