numpy - 点积之和

标签 numpy tensorflow matrix-multiplication dot-product numpy-einsum

如何使用 1000 个不同的 (8,16) 权重矩阵将 100 个 8 元素向量转换为 10 个 16 元素向量? 10 个输出向量中的每一个都是 100 个点积的总和:

A = np.random.randn(100,8)
W = np.random.randn(1000,8,16)
B = []

for i in range(10):
  sum = np.zeros((1,16))
  for j in range(100):
    sum += np.dot(A[j], W[i*100+j])   
  B.append(sum)
B = np.asarray(B)     #B.shape=(10,16)

Numpy 或 TensorFlow 中是否有相应的函数?我查看了 Numpy 中的 dot、tensordot、einsum 和 matmul,但我仍然不确定哪一个是正确的选择。

编辑:我刚刚意识到我实际上想在对点积求和之前产生一个中间结果:(100,8)x(10,100,8,16) -> (10,100,16)。

我猜这可以通过将 (100,8) reshape 为 (1,100,1,8) 和将 (1000,8,16) reshape 为 (10,100,8,16) 并执行 np. einsum('ijkl,ijlm->ijm', A, B) 但我不确定它是否会正确广播 1 到 10。

根据@Divakar 的评论,np.einsum('jk,ijkl->ijl', V, W.reshape(10,100,8,16)) 可以解决问题。

最佳答案

在一行中,它是

B1 = np.einsum('ij,ikjl', A, np.reshape(W, (100, 10, 8, 16), order='F'))

np.allclose(B.squeeze(), B1) 测试它你需要的地方.squeeze因为你的 B 有一个尺寸为 1 的额外维度。

解释:你的 W 形状很难看,它的大小为 1000 的第一个维度实际上应该分成 10 个大小为 100 的 block (实际上你在循环中进行索引操作)。这就是 reshape 的目的。需要 Fortran 风格的顺序,因为我们想通过最快地更改第一个索引来取出 W 的元素。

之后就是简单的爱因斯坦求和:在 j 上进行矩阵乘法,在 i 上添加 100 个结果。

关于numpy - 点积之和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47317882/

相关文章:

python numpy 加速 2d 重复搜索

python - Keras 掩蔽层作为 lstm 层的输入

python - tensorflow 服务 : When to use it rather than simple inference inside Flask service?

python - 如何将 keras(h5) 文件转换为 tflite 文件?

c - 使用 rand() 函数进行随机数的矩阵乘法

python - 使用 numpy.savetxt 保存 utf-8 编码的文本

python - 作为函数一部分的舍入曲线拟合

numpy - 为什么特征向量与对应特征值的乘积不等于原矩阵与特征向量的乘积?

python - 使用 Numpy/SciPy 进行线条平滑

python - 用于文档分类的 scipy/sklearn 稀疏矩阵分解