【问题标题】:Tensormultiplication with einsum与 einsum 的张量乘法
【发布时间】:2021-04-22 22:46:42
【问题描述】:

我有一个张量 phi = np.random.rand(n, n, 3) 和一个矩阵 D = np.random.rand(3, 3)。我想将矩阵D 沿phi 的最后一个轴相乘,以便输出具有(n, n, 3) 的形状。这个我试过了

np.einsum("klj,ij->kli", phi, D)

但我对这个符号完全没有信心。基本上我想做的

res = np.zeros_like(phi)           
for i in range(n):
    for j in range(n):
        res[i, j, :] = D.dot(phi[i, j, :])

【问题讨论】:

  • 哪些轴应该相乘,哪些轴要通过求和来减少?从您想要的输出形状来看,您似乎想要将每个数组中的最后一个轴相乘并减少D 中的第一个轴?这个符号是ijk,lk->ijk(这和你写的几乎一样)。
  • 您在问题中写的是将两个数组中的最后一个轴相乘 并且 还减少了两个数组中的最后一个轴。
  • 什么是转换?考虑乘法和求和指定轴。每个下标将表示一个轴。通过在两个操作数中重复一个下标,您就是在告诉 einsum multiply 这两个轴。通过在所需输出中省略下标,您将告诉 einsum 沿此轴 sum
  • 谢谢,但预期的操作不正是您使用 einsum 解决方案所做的 - np.einsum("klj,ij->kli",phi,D) 吗?或者您是否正在寻找有关它为什么起作用的一些解释?
  • 对于较小的n,您可以比较两个计算。

标签: numpy numpy-einsum


【解决方案1】:

您将phi 视为n, n 向量数组,每个向量都将左乘以D。因此,您希望保持形状的 n, n 部分保持原样。向量的最后一个(唯一)维度应该与矩阵的最后一个维度相乘并求和(向量隐式为 3x1):

np.einsum('ijk,lk->ijl', phi, D)

np.einsum('ij,klj->kli', D, phi)

通过np.matmul@ 运算符)使用广播可能要简单得多:

np.squeeze(D @ phi[..., None])

如果您不介意末尾的额外单位尺寸,可以省略squeeze

【讨论】:

  • @dba。在第一个 einsum 中有错字,现在修复它。
猜你喜欢
  • 1970-01-01
  • 2016-06-17
  • 2018-11-19
  • 1970-01-01
  • 2020-09-05
  • 2019-09-10
  • 2023-03-07
  • 1970-01-01
  • 2017-08-21
相关资源
最近更新 更多