【问题标题】:How can i vectorize this operation?我怎样才能矢量化这个操作?
【发布时间】:2020-11-06 19:01:06
【问题描述】:

我必须执行以下操作数千次,这大大减慢了我的代码:

T = 50
D = 10
K = 20

x = np.random.randn(T, D)
y = np.random.randn(T, K)

result = np.zeros((K, D))

for k in range(K):
    for t in range(T):
        result[k] += y[t, k] * x[t]  # Multiply scalar element in y with row in x

基本上,我试图将矩阵y 的列k 中的每个元素与x 中的相应行相加并将它们相加。我尝试使用np.einsum() 来解决这个问题:

result = np.einsum("ij,ik->jk", y, x)

这至少给了我result.shape == (K, D),但结果不匹配!我怎样才能有效地执行这个操作? np.einsum() 甚至可以做到这一点吗?

【问题讨论】:

  • 你试过np.matmul(np.transpose(y), x)吗?您的公式等于y^T * x,其中乘积是矩阵乘积(如线性代数)
  • 还有矩阵乘法:y.T @ x.
  • 不幸的是 (np.matmul(np.transpose(y), x) != result).sum() 产生 140,所以 200 个元素中有 140 个不相等!
  • y.T @ x 也是如此(当然)
  • 那是浮点错误,看我的回答

标签: python numpy vectorization numpy-einsum


【解决方案1】:

这些操作是相同的。您已经找到了(可能是最快的)矢量化操作。

T = 50
D = 10
K = 20

x = np.random.randn(T, D)
y = np.random.randn(T, K)

result = np.zeros((K, D))

for k in range(K):
    for t in range(T):
        result[k] += y[t, k] * x[t]
           
result2 = np.einsum("ij,ik->jk", y, x)

np.allclose(result, result2)
Out[]: True

问题很可能是您用来确定它们是否“相同”的任何方法中的浮点错误。 np.allclose() 是解决方案。它使用floats 对不同计算方法之间发生的非常小的错误进行四舍五入。

正如 @QuangHoang 在 cmets 中所说,y.T @ x 更具可读性

【讨论】:

  • 天哪,我真的应该用np.allclose()!感谢您提醒我该功能。另外我想弄清楚我的目标是一个简单的矩阵乘法在我试图实现的论文中太隐藏了。感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
相关资源
最近更新 更多