在 python numpy 中实现 Relu 导数

Posted

技术标签:

【中文标题】在 python numpy 中实现 Relu 导数【英文标题】:Implement Relu derivative in python numpy 【发布时间】:2018-03-06 18:37:06 【问题描述】:

我正在尝试实现一个函数,该函数计算矩阵中每个元素的 Relu 导数,然后在矩阵中返回结果。我正在使用 Python 和 Numpy。

基于其他交叉验证帖子,x 的 Relu 导数是 当 x > 0 时为 1,当 x

目前,到目前为止,我有以下代码:

def reluDerivative(self, x):
    return np.array([self.reluDerivativeSingleElement(xi) for xi in x])

def reluDerivativeSingleElement(self, xi):
    if xi > 0:
        return 1
    elif xi <= 0:
        return 0

不幸的是,xi 是一个数组,因为 x 是一个矩阵。 reluDerivativeSingleElement 函数不适用于数组。所以我想知道有没有办法使用numpy将矩阵中的值映射到另一个矩阵,比如numpy中的exp函数?

非常感谢。

【问题讨论】:

np.heaviside 【参考方案1】:

您在一个很好的轨道上:考虑矢量化操作。我们定义了一个函数,然后我们将这个函数应用到一个矩阵上,而不是写一个 for 循环。

这个线程回答了你的问题,它替换了所有满足条件的元素。可以修改成ReLU导数。

https://***.com/questions/19766757/replacing-numpy-elements-if-condition-is-met

另外python对函数式编程的支持很好,尽量使用lambda函数。

https://www.python-course.eu/lambda.php

【讨论】:

【参考方案2】:

这是一个向量化的练习。

这段代码

if x > 0:
  y = 1
elif xi <= 0:
  y = 0

可以改写成

y = (x > 0) * 1

这适用于 numpy 数组,因为涉及它们的布尔表达式被转换为所述数组中元素的这些表达式的值的数组。

【讨论】:

我把这段代码放在我的 reluDerivativeSingleElement 函数中。它仍然说它不能与数组一起使用。也许我错误地解释了你的答案? 这没有多大意义——这段代码应该适用于整个数组 为什么不简单地y = (x &gt; 0)*1.0 似乎产生与y = (x &gt; 0) * 1 + (x &lt;= 0) * 0 相同的结果【参考方案3】:

我猜这就是你要找的东西:

>>> def reluDerivative(x):
...     x[x<=0] = 0
...     x[x>0] = 1
...     return x

>>> z = np.random.uniform(-1, 1, (3,3))
>>> z
array([[ 0.41287266, -0.73082379,  0.78215209],
       [ 0.76983443,  0.46052273,  0.4283139 ],
       [-0.18905708,  0.57197116,  0.53226954]])
>>> reluDerivative(z)
array([[ 1.,  0.,  1.],
       [ 1.,  1.,  1.],
       [ 0.,  1.,  1.]])

【讨论】:

谢谢,我复制了 x,这样原来的 x 就不会被修改了。 @Bon,为什么你认为原来的 x 会被修改?我想,xreluDerivative 函数的局部变量,它不应该影响该范围之外的x,不是吗? @RishabhAgrahari x 将是一个通过引用传递的 numpy 数组,因此在 reluDerivative 中修改 x 将修改传递给函数的原始 x @Bon 谢谢。但是你怎么知道x是通过引用传递的,这一般不会发生吧? 只是想指出,这在技术上只是众多编程解决方案之一,因为 ReLU 的导数未定义为 0。因此,在实践中工作的其他常见实现是 x[x&lt;0] = 0 而不是 x[x&lt;=0] = 0 x[x==0] = 1x[x&lt;0] = 0 & x[x==0] = 0.5【参考方案4】:

relu 返回导数的基本函数可以总结如下:

f'(x) = x > 0

因此,使用 numpy 将是:

def relu_derivative(z):
    return np.greater(z, 0).astype(int)

【讨论】:

这似乎是这个线程中提供的最快的实现。【参考方案5】:

当 x 大于 0 时,斜率为 1。 当x小于等于0时,斜率为0。

if (x > 0):
    return 1
if (x <= 0):
    return 0

这可以写得更紧凑:

return 1 * (x > 0)

【讨论】:

这并不能回答问题,虽然更紧凑但可读性较差。【参考方案6】:

这行得通:

def dReLU(x):
    return 1. * (x > 0)

【讨论】:

【参考方案7】:

正如 Neil 在 cmets 中提到的,您可以使用 numpy 的 heaviside 函数。

def reluDerivative(self, x):
    return np.heaviside(x, 0)

【讨论】:

【参考方案8】:
def dRelu(z):
    return np.where(z <= 0, 0, 1)

在我的例子中,这里的 z 是一个 ndarray。

【讨论】:

【参考方案9】:

如果你想使用纯 Python:

def relu_derivative(x):
    return max(sign(x), 0)

【讨论】:

【参考方案10】:
def reluDerivative(self, x): 
    return 1 * (x > 0)

【讨论】:

以上是关于在 python numpy 中实现 Relu 导数的主要内容,如果未能解决你的问题,请参考以下文章

如何从零开始在 Keras 中实现 Leaky ReLU? [关闭]

在Python中实现阈值检测功能

[记录点滴] 一个Python中实现flatten的方法

用犰狳在 C++ 中实现 numpy.polyfit 和 numpy.polyval

在 numpy 中实现零均值和单位方差

如何在 Python 3 和 PyQt5 中实现多核处理?