用 numpy 向量化内积
Vectorized inner product with numpy
我需要为存储在 numpy 数组中的向量计算许多内积。
即,用数学术语来说,
Vi = Σk Ai,k B i,k
和
Ci,j = Σk Ai,k Di,j,k
我当然可以使用循环,但我想知道我是否可以以一种我没有想到的巧妙方式使用更高级别的运算符,如 dot
或 matmul
.困扰我的是 np.cross
确实接受向量数组来执行,但是 dot
和 inner
不做我想做的事。
您的数学公式已经为您提供了使用 np.einsum
时定义下标的轮廓。很简单:
V = np.einsum('ij,ik->i', A, B)
转换为 V[i] = sum(A[i][k]*B[i][k])
。
和
C = np.einsum('ik,ijk->ij', A, D)
即 C[i][j] = sum(A[i][k]*D[i][j][k]
您可以在 other question 上阅读有关 einsum
运算符的更多信息。
这些可以通过逐元素乘法和求和来完成:
Vi = Σk Ai,k Bi,k
V = (A*B).sum(axis=-1)
和
Ci,j = Σk Ai,k Di,j,k
C = (A[:,None,:] * D).sum(axis=-1)
einsum
可能会更快,但最好理解这种方法。
要使用 matmul
我们必须添加尺寸以适应
(batch,i,j)@(batch,j,k) => (batch,k)
模式。产品总和维度为 j
。计算速度很快,但这里的应用可能有点乏味。
我需要为存储在 numpy 数组中的向量计算许多内积。
即,用数学术语来说,
Vi = Σk Ai,k B i,k
和
Ci,j = Σk Ai,k Di,j,k
我当然可以使用循环,但我想知道我是否可以以一种我没有想到的巧妙方式使用更高级别的运算符,如 dot
或 matmul
.困扰我的是 np.cross
确实接受向量数组来执行,但是 dot
和 inner
不做我想做的事。
您的数学公式已经为您提供了使用 np.einsum
时定义下标的轮廓。很简单:
V = np.einsum('ij,ik->i', A, B)
转换为 V[i] = sum(A[i][k]*B[i][k])
。
和
C = np.einsum('ik,ijk->ij', A, D)
即 C[i][j] = sum(A[i][k]*D[i][j][k]
您可以在 other question 上阅读有关 einsum
运算符的更多信息。
这些可以通过逐元素乘法和求和来完成:
Vi = Σk Ai,k Bi,k
V = (A*B).sum(axis=-1)
和
Ci,j = Σk Ai,k Di,j,k
C = (A[:,None,:] * D).sum(axis=-1)
einsum
可能会更快,但最好理解这种方法。
要使用 matmul
我们必须添加尺寸以适应
(batch,i,j)@(batch,j,k) => (batch,k)
模式。产品总和维度为 j
。计算速度很快,但这里的应用可能有点乏味。