考虑下面的代码块
N = 28 * 28
X = rng.randn(10000, N)
n_groups = group_size = 28
Q = X[:10]
Z = X[:, None] * Q[None] # line 4: multiply every row of Q by every row of X
Z = Z.reshape((len(X), len(Q), n_groups, group_size)).mean(axis=3)
字符串
**Question.**如何重新实现上面的代码片段,以输出Z的相同结果,但没有第4行的昂贵(内存方面等)操作?
我希望这可以通过某种原生Tensor或多维点积来实现。
先谢了。
2条答案
按热度按时间jrcvhitl1#
在Numpy中执行此操作的快速标准方法是使用**
einsum
**:字符串
这不仅明显更快,而且内存效率更高,因为不需要创建 * 临时数组 *。请注意,
einsum
在这种情况下不是最佳的,因为最后一个维度相当小,并且是顺序执行的。如果速度不够快,可以编写优化的并行Numba/Cython代码以获得更好的性能。请注意,
/ group_size
可以应用于Q2
,而不是np.einsum
的结果,以获得更好的性能(因为Q2
更小,这在数学上是等效的)。基准测试
以下是我的i5- 9600 KF处理器使用Numpy 1.24.3的结果:
型
v8wbuo2f2#
Jérôme Richard的基本见解,即这是一个乘法和除法,是正确的,并且可能是最快的,而不绕过Numpy。
einsum
是一个高度广义的矩阵乘积函数,你所拥有的“只是”最后两个维度上的标准矩阵乘积。为了说明,我证明这等价于以下内容:字符串