我正在实现一个神经网络,并希望使用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
回答:
你的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
时梯度为1
,否则为epsilon
,从而创建了一个分段梯度。
我无法评论Leaky ReLUs是否是解决XOR问题的理想选择,但这应该能解决你的梯度问题。