神经网络ReLU输出全0

时间:2018-12-05 17:04:23

标签: python neural-network gradient-descent relu

这是我的项目的链接:https://github.com/aaronnoyes/neural-network/blob/master/nn.py

我已经在python中实现了一个基本的神经网络。默认情况下,它使用S型激活功能,效果很好。我试图比较激活函数之间的学习率变化,所以我尝试实现使用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)

1 个答案:

答案 0 :(得分:0)

您的代码有两个问题:

  • 您也正在将relu应用于输出层。推荐的标准方法是使用身份作为输出层激活进行回归,并使用Sigmoid / softmax进行分类。

  • 您正在使用1的学习率,这是一个很高的方法。 (通常的测试值为1e-2或更小。)

即使在隐藏层中使用relu激活,我也将输出激活更改为S形

React Component

并且使用了较小的学习率

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)))

这是结果:

  

实际输出:[[0.00000] [1.00000] [1.00000] [0.00000]]

     

预测的输出:[[0.10815] [0.92762] [0.94149] [0.05783]]