用正常操作替换 einsum

问题描述 投票:0回答:2

我需要在以下代码中将 einsum 操作替换为标准 numpy 操作:

import numpy as np
a = np.random.rand(128, 16, 8, 32)
b = np.random.rand(256, 8, 32)
output = np.einsum('aijb,rjb->ira', a, b)

预先感谢您的帮助。

python linear-algebra numpy-einsum einsum
2个回答
4
投票

一种选择是对齐到相似的形状并广播乘法,然后

sum
并重新排序轴:

output2 = (b[None, None]*a[:,:,None]).sum(axis=(-1, -2)).transpose((1, 2, 0))

# assert np.allclose(output, output2)

但是效率要低得多,因为它会产生一个大的中间体(形状

(128, 16, 256, 8, 32)
):

# np.einsum('aijb,rjb->ira', a, b)
68.9 ms ± 23.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

# (b[None, None]*a[:,:,None]).sum(axis=(-1, -2)).transpose((1, 2, 0))
4.66 s ± 1.65 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

形状:

# b[None, None].shape
#a  i    r  j   b
(1, 1, 256, 8, 32)

# a[:,:,None].shape
#  a   i  r  j   b
(128, 16, 1, 8, 32)

0
投票
import numpy as np

a = np.random.rand(128, 16, 8, 32)
b = np.random.rand(256, 8, 32)

# Reshape 'a' to (128, 16, 256, 32)
a_reshaped = a.transpose(0, 2, 1, 3).reshape(128, 16, -1)

# Reshape 'b' to (256, 8, 32)
b_reshaped = b.transpose(0, 2, 1)

# Perform matrix multiplication between reshaped 'a' and 'b'
output_reshaped = np.matmul(a_reshaped, b_reshaped)

# Reshape 'output' to (256, 128, 16)
output = output_reshaped.reshape(256, 128, 16).transpose(1, 2, 0)

此代码重塑输入数组 a 和 b,然后使用 np.matmul 执行矩阵乘法。结果被重新调整以匹配所需的输出形状。

© www.soinside.com 2019 - 2024. All rights reserved.