gpt4 book ai didi

python - Einsum 优化基本操作失败

转载 作者:太空宇宙 更新时间:2023-11-04 02:32:55 26 4
gpt4 key购买 nike

随着最近对 Numpy (1.14) 的更新,我发现它破坏了我的整个代码库。这是基于将默认的 numpy einsum 优化参数从 False 更改为 True。

因此,以下基本操作现在失败了:

a = np.random.random([50, 2, 2])
b = np.random.random([50, 2])

np.einsum('bdc, ac -> ab', a, b, optimize=True)

错误跟踪如下:

ValueError                                Traceback (most recent call last)
<ipython-input-71-b0f9ce3c71a3> in <module>()
----> 1 np.einsum('bdc, ac -> ab', a, b, optimize=True)

C:\ProgramData\Anaconda3\lib\site-packages\numpy\core\einsumfunc.py in
einsum(*operands, **kwargs)
1118
1119 # Contract!
-> 1120 new_view = tensordot(*tmp_operands, axes=
(tuple(left_pos), tuple(right_pos)))
1121
1122 # Build a new view if needed

C:\ProgramData\Anaconda3\lib\site-packages\numpy\core\numeric.py in
tensordot(a, b, axes)
1301 oldb = [bs[axis] for axis in notin]
1302
-> 1303 at = a.transpose(newaxes_a).reshape(newshape_a)
1304 bt = b.transpose(newaxes_b).reshape(newshape_b)
1305 res = dot(at, bt)

ValueError: axes don't match array

我向 einsum 请求的操作看起来很简单……那为什么会失败呢?如果我设置“optimize=False”,它工作得很好。

我尝试使用 einsum_path 进行探索,但得到的路径信息在优化和未优化的情况下是相同的。

最佳答案

In [40]: a=np.ones((50,2,2),int); b=np.ones((50,2),int)
In [41]: np.einsum('bdc,ac->ab', a, b)
...
ValueError: axes don't match array

我不明白优化与此错误有什么关系。

对于第一个参数,b,d,c 是 50,2,2。对于第二个 a,c 是 50,2。结果应该是 50,50。但是 d 发生了什么?

In [43]: np.einsum('bdc,ac->abd', a, b).shape
Out[43]: (50, 50, 2)

糟糕:

In [49]: np.einsum('bdc,ac->ab', a, b, optimize=False).shape
Out[49]: (50, 50)

所以它在 d 上求和。


注意错误 - 优化后,它使用 tensordot(转置加 dot),而不是原始的 einsum nditer 方法。

c_einsum 是可以处理丢失的 d 的那个:

# If no optimization, run pure einsum
if optimize_arg is False:
return c_einsum(*operands, **kwargs)

尝试了一些时机:

默认优化的两步计算:

In [64]: timeit np.einsum('abd->ab', np.einsum('bdc,ac->abd', a, b))
288 µs ± 518 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

所需的c_einsum更快

In [65]: timeit np.einsum('bdc,ac->ab', a, b, optimize=False)
170 µs ± 83.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

事实上,即使 tensordot 版本有效,c_einsum 也更快

In [67]: timeit np.einsum('bdc,ac->abd', a, b,optimize=False)
73.1 µs ± 46.6 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [68]: timeit np.einsum('bdc,ac->abd', a, b,optimize=True)
207 µs ± 6.97 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

这个例子可能太小,无法展示 tensordot/blas 的优势。

看起来这已在 github 上提出 - 失败和较慢的“优化”速度:https://github.com/numpy/numpy/issues/10343 “einsum 广播回归(使用 optimize=True)”

关于python - Einsum 优化基本操作失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48727096/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com