Einsum优化失败进行基本操作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Einsum优化失败进行基本操作相关的知识,希望对你有一定的参考价值。
随着Numpy(1.14)的最新更新,我发现它打破了我的整个代码库。这是基于将默认的numpy einsum optimize参数从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:ProgramDataAnaconda3libsite-packages
umpycoreeinsumfunc.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:ProgramDataAnaconda3libsite-packages
umpycore
umeric.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)
事实上,即使c_einsum
版本有效,tensordot
也会更快
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 broadcast regression(with optimize = True)”
以上是关于Einsum优化失败进行基本操作的主要内容,如果未能解决你的问题,请参考以下文章
`numpy.einsum` 中的 `out` 参数无法按预期工作
使用 C++ 反转句子中的每个单词需要对我的代码片段进行代码优化
PyTorch 中的 tensordot 以及 einsum 函数介绍