使用 ReLU 作为激活函数的注意事项
Posted
技术标签:
【中文标题】使用 ReLU 作为激活函数的注意事项【英文标题】:Considerations for using ReLU as activation function 【发布时间】:2017-05-23 04:25:48 【问题描述】:我正在实现一个神经网络,并想使用 ReLU 作为神经元的激活函数。此外,我正在使用 SDG 和反向传播训练网络。我正在用范式 XOR 问题测试神经网络,到目前为止,如果我使用逻辑函数或双曲正切作为激活函数,它可以正确分类新样本。
我一直在阅读有关使用 Leaky ReLU 作为激活函数的好处,并在 Python 中实现它,如下所示:
def relu(data, epsilon=0.1):
return np.maximum(epsilon * data, data)
np
是 NumPy 的名称。相关的导数是这样实现的:
def relu_prime(data, epsilon=0.1):
if 1. * np.all(epsilon < data):
return 1
return epsilon
使用此功能作为激活我得到不正确的结果。例如:
输入 = [0, 0] --> 输出 = [0.43951457]
输入 = [0, 1] --> 输出 = [0.46252925]
输入 = [1, 0] --> 输出 = [0.34939594]
输入 = [1, 1] --> 输出 = [0.37241062]
可以看出,输出与预期的 XOR 相差很大。那么问题来了,使用 ReLU 作为激活函数有什么特别的考虑吗?
请不要犹豫,向我询问更多上下文或代码。提前致谢。
编辑:导数中有一个错误,因为它只返回一个浮点值,而不是 NumPy 数组。正确的代码应该是:
def relu_prime(data, epsilon=0.1):
gradients = 1. * (data > epsilon)
gradients[gradients == 0] = epsilon
return gradients
【问题讨论】:
修改梯度计算部分后是否有效? @KrishnaKishoreAndhavarapu 修改后我得到了正确的结果,但 10 次中有 5 次。我相信我每次都应该得到正确的结果。这个激活函数显然缺少一些东西。 你确定gradients = 1. * (data > epsilon)
有意义吗?你对泄漏 ReLU 函数的定义是什么?对于某些大于零的数据值,这会将梯度设置为等于 epsilon。
@NickBecker 我对 Leaky ReLU 的定义来自*** (en.wikipedia.org/wiki/Rectifier_(neural_networks)#Leaky_ReLUs)。该行返回一个由 0 和 1 组成的数组。 0 来自所有小于epsilon
的值,而 1 来自所有大于epsilon
的剩余值。在这种情况下,我使用的是epsilon = 0.1
。
当我查看有关 Leaky ReLU 的***部分中的分段函数 f(x)
时,我看到当 x > 0 时为 1 的分段导数,否则为 alpha。不过,我可能会遗漏一些东西。
【参考方案1】:
你的relu_prime
函数应该是:
def relu_prime(data, epsilon=0.1):
gradients = 1. * (data > 0)
gradients[gradients == 0] = epsilon
return gradients
注意数据矩阵中每个值与 0 的比较,而不是 epsilon
。这遵循leaky ReLUs 的标准定义,当x > 0
和epsilon
时创建分段梯度1
。
我无法评论泄漏的 ReLU 是否是 XOR 问题的最佳选择,但这应该可以解决您的梯度问题。
【讨论】:
现在我大部分时间都能得到正确的结果。除了@ArnisShaykh 的回答和你的回答外,我现在了解到激活函数的选择取决于数据值。【参考方案2】:简答
不要将 ReLU 与二进制数字一起使用。它旨在以更大的价值运行。也避免在没有负值时使用它,因为这基本上意味着您使用的不是最好的线性激活函数。最好与卷积神经网络一起使用。
长答案
不能说python代码是否有任何问题,因为我是用Java编写的。但从逻辑上讲,我认为在这种情况下使用 ReLU 是一个糟糕的决定。由于我们预测 XOR,因此您的 NN [0,1] 的值范围有限。这也是 sigmoid 激活函数的范围。使用 ReLU,您可以使用值 [0,infinity] 进行操作,这意味着您永远不会使用大量值,因为它是 XOR。但是 ReLU 仍然会考虑这个值,并且你将得到的错误会增加。这就是为什么你大约有 50% 的时间得到正确答案的原因。事实上,这个值可以低至 0%,高至 99%。故事的寓意 - 在决定使用哪个激活函数时,请尝试将 NN 中的输入值范围与激活函数值的范围相匹配。
【讨论】:
感谢您指出这一事实。我没有考虑。完全有道理。 很高兴有帮助。以上是关于使用 ReLU 作为激活函数的注意事项的主要内容,如果未能解决你的问题,请参考以下文章