Einsum优化无法进行基本操作 [英] Einsum optimize fails for basic operation

查看:75
本文介绍了Einsum优化无法进行基本操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

随着最近对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆