Einsum优化无法进行基本操作 [英] Einsum optimize fails for basic operation
问题描述
随着最近对Numpy(1.14)的更新,我发现它破坏了我的整个代码库.这是基于将默认的numpy einsum优化参数从False更改为True的.
With the recent update to Numpy (1.14), I found that it breaks my entire codebase. This is based on changing the default numpy einsum optimize argument from False to True.
结果,以下基本操作现在失败:
As a result, the following basic operation now fails:
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",它就可以正常工作.
The operation I'm requesting from einsum seems very simple... so why does it fail? If I set "optimize=False", it works just fine.
我尝试使用einsum_path进行探索,但是无论是否进行了优化,生成的路径信息都是相同的.
I tried exploring with einsum_path but the resulting path info was the same with and without optimization.
推荐答案
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
我看不到此错误有什么优化.
I don't see what optimization has to do with this error.
对于第一个参数,b,d,c
为50,2,2.对于第二个a,c
是50,2.结果应为50,50.但是d
怎么了?
For the first argument b,d,c
are 50,2,2. For the second a,c
are 50,2. The result should be 50,50. But what happened to d
?
In [43]: np.einsum('bdc,ac->abd', a, b).shape
Out[43]: (50, 50, 2)
糟糕:
Oops:
In [49]: np.einsum('bdc,ac->ab', a, b, optimize=False).shape
Out[49]: (50, 50)
所以它是对d
的求和.
请注意错误-经过优化,它使用tensordot
(转置加dot
),而不是原始的einsum
nditer
方法.
Note the error - with optimization, it uses tensordot
(transpose plus dot
), rather than the original einsum
nditer
approach.
c_einsum
是可以处理缺少的d
的人:
c_einsum
is the one that can handle that missing d
:
# If no optimization, run pure einsum
if optimize_arg is False:
return c_einsum(*operands, **kwargs)
尝试了一些时间:
Tried some timings:
默认优化的两步计算:
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 fact c_einsum
is faster even when the tensordot
version works
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
的优点.
This example might be too small to show of the advantages of tensordot/blas
.
在github上看起来像这样-既失败,又有较慢的优化"速度:
Looks like this has been raised on github - both the failures, and the slower 'optimize' speed: https://github.com/numpy/numpy/issues/10343 "einsum broadcast regression (with optimize=True)"
这篇关于Einsum优化无法进行基本操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!