神经网络 ReLU 输出全 0
Neural Network ReLU Outputting All 0s
这是我项目的 link:https://github.com/aaronnoyes/neural-network/blob/master/nn.py
我已经在 python 中实现了一个基本的神经网络。默认情况下,它使用 sigmoid 激活函数并且效果很好。我试图比较激活函数之间学习率的变化,所以我尝试实现一个使用 ReLU 的选项。但是当它运行时,权重都立即下降到 0.
if (self.activation == 'relu'):
d_weights2 = np.dot(self.layer1.T, (2*(self.y - self.output) * self.relu(self.output, True)))
d_weights1 = np.dot(self.input.T, (np.dot(2*(self.y - self.output) * self.relu(self.output, True), self.weights2.T) * self.relu(self.layer1, True)))
当我尝试应用梯度下降时,我几乎可以肯定问题出在我程序的第 54-56 行(如上所示)。我该如何解决这个问题,这样程序才能真正适当地更新权重?我的relu实现如下:
def relu(self, x, derivative=False):
if derivative:
return 1. * (x > 0)
else:
return x * (x > 0)
您的代码有两个问题:
您也在将 relu 应用于输出层。推荐的标准方法是使用身份作为回归的输出层激活和 sigmoid/softmax 的分类。
您使用的学习率为 1,这太高了。 (通常测试值为1e-2和更小。)
即使在隐藏层中使用 relu 激活,我也将输出激活更改为 sigmoid
def feedforward(self):
...
if (self.activation == 'relu'):
self.layer1 = self.relu(np.dot(self.input, self.weights1))
self.output = self.sigmoid(np.dot(self.layer1, self.weights2))
return self.output
def backprop(self):
...
if (self.activation == 'relu'):
d_weights2 = np.dot(self.layer1.T, (2*(self.y - self.output) * self.sigmoid(self.output, True)))
d_weights1 = np.dot(self.input.T, (np.dot(2*(self.y - self.output) * self.relu(self.output, True), self.weights2.T) * self.relu(self.layer1, True)))
并使用较小的学习率
# update the weights with the derivative (slope) of the loss function
self.weights1 += .01 * d_weights1
self.weights2 += .01 * d_weights2
这是结果:
Actual Output : [[ 0.00000] [ 1.00000] [ 1.00000] [ 0.00000]]
Predicted Output: [[ 0.10815] [ 0.92762] [ 0.94149] [ 0.05783]]
这是我项目的 link:https://github.com/aaronnoyes/neural-network/blob/master/nn.py
我已经在 python 中实现了一个基本的神经网络。默认情况下,它使用 sigmoid 激活函数并且效果很好。我试图比较激活函数之间学习率的变化,所以我尝试实现一个使用 ReLU 的选项。但是当它运行时,权重都立即下降到 0.
if (self.activation == 'relu'):
d_weights2 = np.dot(self.layer1.T, (2*(self.y - self.output) * self.relu(self.output, True)))
d_weights1 = np.dot(self.input.T, (np.dot(2*(self.y - self.output) * self.relu(self.output, True), self.weights2.T) * self.relu(self.layer1, True)))
当我尝试应用梯度下降时,我几乎可以肯定问题出在我程序的第 54-56 行(如上所示)。我该如何解决这个问题,这样程序才能真正适当地更新权重?我的relu实现如下:
def relu(self, x, derivative=False):
if derivative:
return 1. * (x > 0)
else:
return x * (x > 0)
您的代码有两个问题:
您也在将 relu 应用于输出层。推荐的标准方法是使用身份作为回归的输出层激活和 sigmoid/softmax 的分类。
您使用的学习率为 1,这太高了。 (通常测试值为1e-2和更小。)
即使在隐藏层中使用 relu 激活,我也将输出激活更改为 sigmoid
def feedforward(self):
...
if (self.activation == 'relu'):
self.layer1 = self.relu(np.dot(self.input, self.weights1))
self.output = self.sigmoid(np.dot(self.layer1, self.weights2))
return self.output
def backprop(self):
...
if (self.activation == 'relu'):
d_weights2 = np.dot(self.layer1.T, (2*(self.y - self.output) * self.sigmoid(self.output, True)))
d_weights1 = np.dot(self.input.T, (np.dot(2*(self.y - self.output) * self.relu(self.output, True), self.weights2.T) * self.relu(self.layer1, True)))
并使用较小的学习率
# update the weights with the derivative (slope) of the loss function
self.weights1 += .01 * d_weights1
self.weights2 += .01 * d_weights2
这是结果:
Actual Output : [[ 0.00000] [ 1.00000] [ 1.00000] [ 0.00000]]
Predicted Output: [[ 0.10815] [ 0.92762] [ 0.94149] [ 0.05783]]