0

这是我的项目的链接: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)
4

1 回答 1

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

这是结果:

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

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

于 2018-12-06T09:51:10.803 回答