- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个奇怪的情况,我可以看到 numpy.einsum
加速了计算,但在 einsum_path
中却看不到。我想量化/解释这种可能的加速,但在某处遗漏了一些东西......
简而言之,我有一个矩阵乘法,其中只需要最终乘积的对角线。
a = np.arange(9).reshape(3,3)
print('input array')
print(a)
print('normal method')
print(np.diag(a.dot(a)))
print('einsum method')
print(np.einsum('ij,ji->i', a, a))
产生输出:
input array
[[0 1 2]
[3 4 5]
[6 7 8]]
normal method
[ 15 54 111]
einsum method
[ 15 54 111]
在大型矩阵上运行时,numpy.einsum
要快得多。
A = np.random.randn(2000, 300)
B = np.random.randn(300, 2000)
print('normal method')
%timeit np.diag(A.dot(B))
print('einsum method')
%timeit np.einsum('ij,ji->i', A, B)
产生:
normal method
17.2 ms ± 131 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
einsum method
1.02 ms ± 7.82 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
我的直觉是,这种加速是可能的,因为 numpy.einsum
能够放弃最终会通过采用对角线而放弃的计算 - 但是,如果我没看错的话,输出numpy.einsum_path
根本没有加速。
print(np.einsum_path('ij,ji->i',A,B,optimize=True)[1])
Complete contraction: ij,ji->i
Naive scaling: 2
Optimized scaling: 2
Naive FLOP count: 1.200e+06
Optimized FLOP count: 1.200e+06
Theoretical speedup: 1.000
Largest intermediate: 2.000e+03 elements
--------------------------------------------------------------------------
scaling current remaining
--------------------------------------------------------------------------
2 ji,ij->i i->i
问题:
numpy.einsum
中 ij,ji->i
路径的加速?最佳答案
path
仅在处理超过 2 个参数时查看替代顺序。只有 2 个参数,分析什么都不做。你的diag(dot)
In [113]: np.diag(a.dot(a))
Out[113]: array([ 15, 54, 111])
使用 einsum
的等价物是:
In [115]: np.einsum('ii->i',np.einsum('ij,jk->ik',a,a))
Out[115]: array([ 15, 54, 111])
但是我们可以跳过中间步骤:
In [116]: np.einsum('ij,ji->i',a,a)
Out[116]: array([ 15, 54, 111])
索引表示法足够灵活,不需要经过完整的点
计算。
获得相同结果的另一种方法是:
In [117]: (a*a.T).sum(axis=1)
Out[117]: array([ 15, 54, 111])
使用 matmul
我们可以在没有 diag
的情况下进行计算,将第一个维度视为“批处理”。但首先需要一些 reshape :
In [121]: a[:,None,:]@a.T[:,:,None]
Out[121]:
array([[[ 15]],
[[ 54]],
[[111]]])
In [122]: np.squeeze(a[:,None,:]@a.T[:,:,None])
Out[122]: array([ 15, 54, 111])
我的时代
normal method
135 ms ± 3.87 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
einsum method
3.09 ms ± 46.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [130]: timeit (A*B.T).sum(axis=0)
8.06 ms ± 78.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [131]: timeit np.squeeze(A[:,None,:]@B.T[:,:,None])
3.52 ms ± 195 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
dot
创建一个 (2000,2000) 数组,然后提取 2000 个元素。
就元素乘法而言,点是:
In [136]: (a[:,:,None]*a[None,:,:]).sum(axis=1)
Out[136]:
array([[ 15, 18, 21],
[ 42, 54, 66],
[ 69, 90, 111]])
对于 A
和 B
,中间产品将是 (2000,300,2000),总结为 (2000,2000)。 einsum
(有效地)进行了 2000 次大小 (300,300) 减少到 (1,) 的计算。
einsum
比 diag/dot
更接近此计算,将大小 2000 维度视为 1d dot
的“批处理”计算:
In [140]: timeit np.array([A[i,:].dot(B[:,i]) for i in range(2000)])
9.46 ms ± 270 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
关于python - numpy.einsum 大大加快了计算速度 - 但 numpy.einsum_path 显示没有加速,我错过了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72858444/
我有 2 个数组,其中一个的大小为: A = np.random.uniform(size=(48, 1000000, 2)) 另一个是 B = np.random.uniform(size=(48)
似乎是 numpy 的 einsum功能不适用于 scipy.sparse矩阵。有没有其他方法可以做这些事情einsum可以处理稀疏矩阵吗? 回应@eickenberg 的回答:我想要的特定 eins
我有以下张量执行, np.einsum('k,pjqk,yzjqk,yzk,ipqt->it', A, B, C, D, E) 而且我注意到,当“z”或“q”在维度上扩展时,执行时间确实受到了影响,尽
考虑下面的 3 个数组: np.random.seed(0) X = np.random.randint(10, size=(4,5)) W = np.random.randint(10, size=
我有一个形状为 (n, n) 的矩阵 A 和另一个形状为 (p, n) 的矩阵 b。我需要得到一个矩阵 C 使得 C[i] = (A * b[i, np.newaxis, :]) * b[i, :,
随着最近对 Numpy (1.14) 的更新,我发现它破坏了我的整个代码库。这是基于将默认的 numpy einsum 优化参数从 False 更改为 True。 因此,以下基本操作现在失败了: a
我已经搜索了一种解决方案,使用 einsum 确定行数不相等但列数相等的 numpy 数组的距离。我尝试了各种组合,但唯一能成功的方法是使用以下代码。我显然遗漏了一些东西,文献和众多线程并没有让我更接
我很熟悉einsum在纽比的运作方式。pytorch也提供了类似的功能:torch.einsum()。在功能和性能方面有什么相同点和不同点?在Py火炬文档中提供的信息相当稀少,没有提供任何关于这方面的
我一直在尝试调试某个模型,该模型在重复几次的层中使用 torch.einsum 运算符。 在尝试分析训练期间模型的 GPU 内存使用情况时,我注意到某个 Einsum 操作显着增加了内存使用量。我正在
我正在尝试将三个数组 (A x B x A) 与维度 (19000, 3) x (19000, 3, 3) x (19000, 3) 相乘,这样最后我得到一个大小为 (19000) 的一维数组,所以我
我正在尝试潜入 einsum符号。此 question and answers帮了我很多。 但是现在我不能掌握einsum的机器计算外积时: x = np.array([1, 2, 3]) y = n
想象一下,我有整数,n,q和具有这些维度的向量/数组: import numpy as np n = 100 q = 102 A = np.random.normal(size=(n,n)) B =
我有两个包含兼容矩阵的 numpy 数组,想计算使用 numpy.einsum 的元素明智的外积.数组的形状是: A1 = (i,j,k) A2 = (i,k,j) 因此数组分别包含 i 个形状为 (
我想使用类似 np.dot 或(最好)np.einsum 的东西来有效地执行它们相同的功能,但使用备用 ufunc 而不是 np.multiply。例如,考虑这两个数组: >>> a array([[
我有两个包含兼容矩阵的 numpy 数组,想计算使用 numpy.einsum 的元素明智的外积.数组的形状是: A1 = (i,j,k) A2 = (i,k,j) 因此数组分别包含 i 个形状为 (
为什么这些输出不同?这是有意的行为吗?我使用的是 tensorflow 1.12 import tensorflow as tf matrix = tf.constant([[1, 2, 3],
我有以下 Einstein Sum (einsum) 表达式, import numpy as np x = np.random.rand(1,8,2,8,10) y = np.random.rand
是否有一种优雅的方法可以根据 einsum 的输入参数预先计算 np.einsum 结果的形状(无需运行计算)? # Given a, b and signature with # a.shape =
我已阅读 einsum manual和 ajcr 的 basic introduction 我在非编码环境中对爱因斯坦求和的经验为零,尽管我尝试通过一些互联网研究来弥补这一点(将提供链接,但还没有超过
我尝试寻找答案,但找不到我需要的东西。如果这是一个重复的问题,我们深表歉意。 假设我有一个形状为 (n, n*m) 的二维数组。我想要做的是这个数组与其转置的外部总和,从而产生形状为 (n*m, n*
我是一名优秀的程序员,十分优秀!