在 python 中更快地实现 ReLu 导数?

Tal*_*suf 2 python numpy machine-learning deep-learning activation-function

我已将 ReLu 导数实现为:

def relu_derivative(x):
     return (x>0)*np.ones(x.shape)
Run Code Online (Sandbox Code Playgroud)

我也试过:

def relu_derivative(x):
   x[x>=0]=1
   x[x<0]=0
   return x
Run Code Online (Sandbox Code Playgroud)

X 的大小=(3072,10000)。但是计算需要很多时间。有没有其他优化的解决方案?

Div*_*kar 5

方法#1:使用 numexpr

在处理大数据时,如果预期操作可以表示为算术运算,我们可以使用支持多核处理的numexpr模块。在这里,一种方法是 -

(X>=0)+0
Run Code Online (Sandbox Code Playgroud)

因此,要解决我们的案例,那就是——

import numexpr as ne

ne.evaluate('(X>=0)+0')
Run Code Online (Sandbox Code Playgroud)

方法#2:使用NumPy views

另一个技巧是views通过将比较掩码视为int数组来使用,就像这样 -

(X>=0).view('i1')
Run Code Online (Sandbox Code Playgroud)

在性能上,它应该与创建相同 X>=0.

时间安排

比较随机数组上所有已发布的解决方案 -

In [14]: np.random.seed(0)
    ...: X = np.random.randn(3072,10000)

In [15]: # OP's soln-1
    ...: def relu_derivative_v1(x):
    ...:      return (x>0)*np.ones(x.shape)
    ...: 
    ...: # OP's soln-2     
    ...: def relu_derivative_v2(x):
    ...:    x[x>=0]=1
    ...:    x[x<0]=0
    ...:    return x

In [16]: %timeit ne.evaluate('(X>=0)+0')
10 loops, best of 3: 27.8 ms per loop

In [17]: %timeit (X>=0).view('i1')
100 loops, best of 3: 19.3 ms per loop

In [18]: %timeit relu_derivative_v1(X)
1 loop, best of 3: 269 ms per loop

In [19]: %timeit relu_derivative_v2(X)
1 loop, best of 3: 89.5 ms per loop
Run Code Online (Sandbox Code Playgroud)

numexpr基于一个与8线程。因此,随着更多线程可用于计算,它应该会进一步改进。Related post关于如何控制多核功能。

方法 #3:方法 #1 + #2 -

将这两种混合用于大型阵列的最佳一种 -

In [27]: np.random.seed(0)
    ...: X = np.random.randn(3072,10000)

In [28]: %timeit ne.evaluate('X>=0').view('i1')
100 loops, best of 3: 14.7 ms per loop
Run Code Online (Sandbox Code Playgroud)