【问题标题】:Efficiently computing multiple tensor inner products高效计算多个张量内积
【发布时间】:2020-03-21 08:19:41
【问题描述】:

我正在使用一个k x k x k x k 张量(比如S)和一个大小为(n, k) 的数组X。大致而言,X 的行对应于图的节点特征。对于每对边(比如e = (u, v)e' = (u_, v_)),我想计算一个新元素,如下所示:

elt = np.sum(S * np.multiply.outer(np.outer(X[u, :], X[v, :]), np.outer(X[u_, :], X[v_, :])))

我想知道是否有一种方法可以更有效地执行此操作,而不是在索引上使用 4 个嵌套循环。 如果我只使用一对节点并且S 只是一个k x k 矩阵,则可以简单地写为

all_elts = X @ S @ X.T

但是,我不确定这如何推广到多个维度。非常感谢任何帮助!

【问题讨论】:

  • 对于@,最后两个维度执行dot sum-of-products。其他维度是“批量”维度,遵循正常的broadcasting 规则。虽然不一定是最快的,np.einsum 是表达复杂产品的便捷工具。
  • 对于einsum 认为result_?,?,? = sum(?,?,?) S_i,j,k,l X_?,? X_?,?。填写 ?索引。
  • @hpaulj:谢谢!我不知道numpy 实现了爱因斯坦符号。

标签: python numpy multidimensional-array scipy tensor


【解决方案1】:

这里有一个例子来说明如何使用einsum()

import numpy as np
from itertools import product

n = 4
x = np.random.randn(n, n)
S = np.random.randn(n, n, n, n)

res = np.zeros((n, n, n, n))
for i, j, k, l in product(range(n), range(n), range(n), range(n)):
    res[i, j, k, l] = np.sum(S * np.multiply.outer(np.outer(x[i, :], x[j, :]), np.outer(x[k, :], x[l, :])))

res2 = np.einsum("efgh,ae,bf,cg,dh->abcd", S, x, x, x, x)
np.allclose(res, res2)

【讨论】:

  • 可能应该保留 (n, k), k=4 符号只是为了发出警告,即大的 n 值可能会导致内存错误,因为您正在构建一个 (n,n,n,n) 形状的数组。
猜你喜欢
  • 1970-01-01
  • 2021-05-19
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 2021-01-25
相关资源
最近更新 更多