我正在为一个应用程序使用 logistic sigmoid。我比较了使用 scipy.special 函数 expit 与使用 sigmoidal 的双曲正切定义的时间。

我发现双曲正切的速度快了 3 倍。这里发生了什么?我还在排序数组上测试了时间,看看结果是否有任何不同。

这是一个在 IPython 中运行的例子:

In [1]: from scipy.special import expit 
 
In [2]: myexpit = lambda x: 0.5*tanh(0.5*x) + 0.5 
 
In [3]: x = randn(100000) 
 
In [4]: allclose(expit(x), myexpit(x)) 
Out[4]: True 
 
In [5]: timeit expit(x) 
100 loops, best of 3: 15.2 ms per loop 
 
In [6]: timeit myexpit(x) 
100 loops, best of 3: 4.94 ms per loop 
 
In [7]: y = sort(x) 
 
In [8]: timeit expit(y) 
100 loops, best of 3: 15.3 ms per loop 
 
In [9]: timeit myexpit(y) 
100 loops, best of 3: 4.37 ms per loop 

编辑:

机器信息:

  • Ubuntu 16.04
  • 内存:7.4GB
  • 英特尔酷睿 i7-3517U CPU @ 1.90GHz × 4

Numpy/Scipy 信息:

In [1]: np.__version__ 
Out[1]: '1.12.0' 
 
In [2]: np.__config__.show() 
lapack_opt_info: 
    libraries = ['openblas', 'openblas'] 
    library_dirs = ['/usr/local/lib'] 
    define_macros = [('HAVE_CBLAS', None)] 
    language = c 
blas_opt_info: 
    libraries = ['openblas', 'openblas'] 
    library_dirs = ['/usr/local/lib'] 
    define_macros = [('HAVE_CBLAS', None)] 
    language = c 
openblas_info: 
    libraries = ['openblas', 'openblas'] 
    library_dirs = ['/usr/local/lib'] 
    define_macros = [('HAVE_CBLAS', None)] 
    language = c 
blis_info: 
  NOT AVAILABLE 
openblas_lapack_info: 
    libraries = ['openblas', 'openblas'] 
    library_dirs = ['/usr/local/lib'] 
    define_macros = [('HAVE_CBLAS', None)] 
    language = c 
lapack_mkl_info: 
  NOT AVAILABLE 
blas_mkl_info: 
  NOT AVAILABLE 
 
In [3]: import scipy 
 
In [4]: scipy.__version__ 
Out[4]: '0.18.1' 

请您参考如下方法:

编辑:

我会让以后的人引用 this question .


总结有用评论的结果:

"Why is using tanh definition of logistic sigmoid faster than scipy's expit?"

回答:不是; tanhexp C 函数在我特定的机器上发生了一些有趣的事情。

事实证明,在我的机器上,tanh 的 C 函数比 exp 更快。为什么会这样的答案显然属于另一个问题。当我运行下面列出的 C++ 代码时,我看到了

tanh: 5.22203 
exp: 14.9393 

当从 Python 调用时,这与 tanh 函数的 ~3 倍增长相匹配。奇怪的是,当我在具有相同操作系统的另一台机器上运行相同的代码时,我得到了 tanhexp 的相似计时结果。

#include <iostream> 
#include <cmath> 
#include <ctime> 
 
using namespace std; 
 
int main() { 
    double a = -5; 
    double b =  5; 
    int N =  10001; 
    double x[10001]; 
    double y[10001]; 
    double h = (b-a) / (N-1); 
 
    clock_t begin, end; 
 
    for(int i=0; i < N; i++) 
        x[i] = a + i*h; 
 
    begin = clock(); 
 
    for(int i=0; i < N; i++) 
        for(int j=0; j < N; j++) 
            y[i] = tanh(x[i]); 
 
    end = clock(); 
 
    cout << "tanh: " << double(end - begin) / CLOCKS_PER_SEC << "\n"; 
 
    begin = clock(); 
 
    for(int i=0; i < N; i++) 
        for(int j=0; j < N; j++) 
            y[i] = exp(x[i]); 
 
    end = clock(); 
 
    cout << "exp: " << double(end - begin) / CLOCKS_PER_SEC << "\n"; 
 
 
    return 0; 
} 


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

python - 在 python 中以相反的顺序柯里化(Currying)