"Einsum优化失败的基础操作"

2024-04-25 00:34:03 发布

您现在位置:Python中文网/ 问答频道 /正文

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

具有以下错误跟踪:

^{pr2}$

我要求einsum做的手术看起来很简单。。。那为什么失败呢?如果我设置“optimize=False”,就可以了。在

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


Tags: 代码numpyfalsetrue参数ab错误np
1条回答
网友
1楼 · 发布于 2024-04-25 00:34:03
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怎么了?在

^{pr2}$

哎呀:

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

所以它是在d上求和。在


注意这个错误-对于优化,它使用tensordot(转置加dot),而不是原来的einsumnditer方法。在

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广播回归(with optimize=True)”

相关问题 更多 >