神经网络 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]]