在 python 中更快地实现 ReLu 导数?
Faster implementation for ReLu derivative in python?
我已经将 ReLu 导数实现为:
def relu_derivative(x):
return (x>0)*np.ones(x.shape)
我也试过:
def relu_derivative(x):
x[x>=0]=1
x[x<0]=0
return x
X 的大小=(3072,10000)。
但它需要很多时间来计算。还有其他优化方案吗?
方法 #1:使用 numexpr
在处理大数据时,如果预期的操作可以表示为算术运算,我们可以使用支持多核处理的numexpr
module。在这里,一种方法是 -
(X>=0)+0
因此,要解决我们的问题,应该是 -
import numexpr as ne
ne.evaluate('(X>=0)+0')
方法 #2:使用 NumPy views
另一个技巧是使用 views
通过将比较掩码视为 int
数组,就像这样 -
(X>=0).view('i1')
在性能上,它应该与创建 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
基于 numexpr
的线程有 8
个。因此,随着更多线程可用于计算,它应该会进一步改进。 关于如何控制多核功能。
方法#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
我已经将 ReLu 导数实现为:
def relu_derivative(x):
return (x>0)*np.ones(x.shape)
我也试过:
def relu_derivative(x):
x[x>=0]=1
x[x<0]=0
return x
X 的大小=(3072,10000)。 但它需要很多时间来计算。还有其他优化方案吗?
方法 #1:使用 numexpr
在处理大数据时,如果预期的操作可以表示为算术运算,我们可以使用支持多核处理的numexpr
module。在这里,一种方法是 -
(X>=0)+0
因此,要解决我们的问题,应该是 -
import numexpr as ne
ne.evaluate('(X>=0)+0')
方法 #2:使用 NumPy views
另一个技巧是使用 views
通过将比较掩码视为 int
数组,就像这样 -
(X>=0).view('i1')
在性能上,它应该与创建 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
基于 numexpr
的线程有 8
个。因此,随着更多线程可用于计算,它应该会进一步改进。
方法#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