gpt4 book ai didi

python - numpy.vectorize : Why so slow?

转载 作者:行者123 更新时间:2023-12-05 01:19:11 25 4
gpt4 key购买 nike

scipy.special 中的 expit 函数是一个向量化的 sigmoid 函数。它计算 1/(1+e^(-x)),这很复杂,可能涉及泰勒级数。

我了解了“快速 sigmoid”,1/(1 + abs(x)),它应该更快——但是内置的 expit 函数大大优于它,即使我将它作为 lambda 表达式传递给numpy.vectorize.

这是测试它们的一种方法:

from scipy.special import expit
data = np.random.rand(1000000)

内置的、复杂的 sigmoid 速度很快:

%prun expit(data)

3 function calls in 0.064 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.064 0.064 0.064 0.064 <string>:1(<module>)
1 0.000 0.000 0.064 0.064 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

较简单的 sigmoid 大约慢 20 倍:

%prun np.vectorize( lambda x: (x / (1 + abs(x)) + 1) / 2 )(data)

2000023 function calls in 1.992 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
1000001 1.123 0.000 1.294 0.000 <string>:1(<lambda>)
1 0.558 0.558 1.950 1.950 function_base.py:2276(_vectorize_call)
1000001 0.170 0.000 0.170 0.000 {built-in method builtins.abs}
4 0.098 0.025 0.098 0.025 {built-in method numpy.core.multiarray.array}
1 0.041 0.041 1.991 1.991 function_base.py:2190(__call__)
1 0.000 0.000 0.068 0.068 function_base.py:2284(<listcomp>)
1 0.000 0.000 1.992 1.992 {built-in method builtins.exec}
1 0.000 0.000 1.991 1.991 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 function_base.py:2220(_get_ufunc_and_otypes)
1 0.000 0.000 0.000 0.000 function_base.py:2162(__init__)
1 0.000 0.000 0.000 0.000 function_base.py:2242(<listcomp>)
2 0.000 0.000 0.000 0.000 numeric.py:414(asarray)
1 0.000 0.000 0.000 0.000 {built-in method numpy.core.umath.frompyfunc}
1 0.000 0.000 0.000 0.000 function_base.py:2266(<listcomp>)
2 0.000 0.000 0.000 0.000 {built-in method builtins.isinstance}
1 0.000 0.000 0.000 0.000 {built-in method builtins.len}
1 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

最佳答案

我只引用 vectorize docstring :“提供 vectorize 函数主要是为了方便,而不是为了性能。实现本质上是一个 for 循环。”

您想使 1/(1 + abs(x)) 变快。 numpy 有一个名为 numpy.abs 的函数(也称为 numpy.absolute——它们是同一对象的不同名称)。它计算其参数的每个元素的绝对值,并在 C 代码中执行此操作,因此速度很快。此外,Python 内置函数 abs 知道如何将参数分派(dispatch)给具有方法 __abs__ 的对象,numpy 数组会这样做,因此您也可以使用 Python 的 abs() 计算 numpy 数组的元素绝对值。不过,在下文中,我将使用 np.abs

下面是一个使用 np.abs 的例子:

In [25]: x = np.array([-2, -1.5, 0, 5, 10])

In [26]: np.abs(x)
Out[26]: array([ 2. , 1.5, 0. , 5. , 10. ])

这是 scipy.special.expit1.0/(1 + np.abs(x)) 对大型数组 x 的性能比较:

In [34]: from scipy.special import expit

In [35]: x = np.random.randn(100000)

In [36]: %timeit expit(x)
1000 loops, best of 3: 771 µs per loop

In [37]: %timeit 1.0/(1 + np.abs(x))
1000 loops, best of 3: 279 µs per loop

所以 1.0/(1 + np.abs(x))expit(x) 快很多。

关于python - numpy.vectorize : Why so slow?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40955550/

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