【问题标题】:Numpy: How to perform the outer product of four vectors and then summing them?Numpy:如何执行四个向量的外积然后求和?
【发布时间】:2019-12-15 13:17:48
【问题描述】:

A = [a1, a2]B = [b1, b2]C = [c1, c2]D = [d1, d2]

A, B, C, D 的外积只是:

[
    [
        [[a1*b1*c1*d1, a1*b1*c1*d2], [a1*b1*c1*d1, a1*b1*c2*d2]], 
        [[a1*b2*c2*d1, a1*b2*c1*d2], [a1*b2*c2*d1, a1*b2*c2*d2]]
    ],
    [
        [[a2*b1*c1*d1, a2*b1*c1*d2], [a2*b1*c2*d1, a2*b1*c2*d2]], 
        [[a2*b2*c1*d1, a2*b2*c1*d2], [a2*b2*c2*d1, a2*b2*c2*d2]]
    ]
]

在 numpy 中,外积因此是一个形状为 (2, 2, 2, 2) 的数组。我知道该怎么做。问题是,我有 100 个这种 A、B、C、D。它们是通过固定 k 从 A_k、B_k、C_k、D_k 中取出的。所以它们实际上是形状 (2, 100) 或 (100, 2) 的数组。实际上可能是 (20, 100) 或 (100, 20)。我用2来简化写作。我想做的是:把这种外积做100次,然后总结。即:求和 100 个形状为 (2, 2, 2, 2) 的数组。如何使用 numpy 有效地做到这一点?如果更好,是否有任何 GPU 加速方法可以做到这一点?

如果 A、B、C、D 只是一维数组,我知道该怎么做。以下一行代码可以正常工作:

a[:, None, None, None] * b[None, :, None, None] * c[None, None, :, None] * d[None, None, None, :]

【问题讨论】:

    标签: python-3.x numpy tensor


    【解决方案1】:

    numpy.einsum 加上 numpy.sum 仔细选择轴应该可以满足您的需求。

    【讨论】:

    • 只是einsum 应该与np.einsum('ij,ik,ir,il->jkrl', A, B, C, D) 类似。
    • 同意 - 对 einsum 的单个调用可能比多个 einsum 调用 + sum 调用更有效,因为整个操作在编译的 C 代码中处理一次,而不会返回到 python。另一方面,如果您是第一次使用 einsum,多次调用可能更容易编写。我会先用简单的方法编写它,然后再重构。
    • 非常感谢!真的工作。同样只需要一行代码:
    • 虽然 einsum 可以做我想做的事情并且比使用许多 for 循环快得多,但它仍然不够快。我需要对这种外积求和数百次。每个 einsum 大约需要 3 分钟来计算。做 400 个这样的 einsum 需要 1200 分钟。有没有更快的方法来做到这一点?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 2018-05-25
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    相关资源
    最近更新 更多