RELU的神经网络反向传播

时间:2015-09-13 03:28:26

标签: neural-network backpropagation

我正在尝试用RELU实现神经网络。

输入图层 - > 1个隐藏层 - > relu - >输出层 - > softmax层

以上是我的神经网络的架构。 我很担心这个relu的反向传播。 对于RELU的导数,如果x <= 0,则输出为0。 如果x> 0,输出为1。 因此,当你计算梯度时,这是否意味着如果x <= 0?

,我会消除梯度

有人可以一步一步地解释我的神经网络架构的反向传播吗?

5 个答案:

答案 0 :(得分:9)

  

如果x <= 0,则输出为0.如果x> 0,输出为1

ReLU功能定义为:对于x&gt; 0输出为x,即 f(x)= max(0,x)

因此,对于导数f'(x),它实际上是:

如果x&lt; 0,输出为0.如果x> 0,输出为1.

未定义导数f'(0)。所以它通常设置为0或者你将激活函数修改为f(x)= max(e,x)的小e。

通常:ReLU是使用整流器激活功能的单元。这意味着它的工作原理与任何其他隐藏层完全相同,但除了tanh(x),sigmoid(x)或您使用的任何激活之外,您将使用f(x)= max(0,x)。

如果您已经为使用sigmoid激活的多层网络编写了代码,那么它实际上只有一行变化。关于前向或后向传播的任何内容都不会在算法上发生变化。如果你还没有更简单的模型工作,那就回过头来开始吧。否则你的问题不是关于ReLUs,而是关于整体实施NN。

答案 1 :(得分:5)

这是一个很好的例子,使用ReLU实现XOR: 参考,http://pytorch.org/tutorials/beginner/pytorch_with_examples.html

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

# N is batch size(sample size); D_in is input dimension;
# H is hidden dimension; D_out is output dimension.
N, D_in, H, D_out = 4, 2, 30, 1

# Create random input and output data
x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])

# Randomly initialize weights
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)

learning_rate = 0.002
loss_col = []
for t in range(200):
    # Forward pass: compute predicted y
    h = x.dot(w1)
    h_relu = np.maximum(h, 0)  # using ReLU as activate function
    y_pred = h_relu.dot(w2)

    # Compute and print loss
    loss = np.square(y_pred - y).sum() # loss function
    loss_col.append(loss)
    print(t, loss, y_pred)

    # Backprop to compute gradients of w1 and w2 with respect to loss
    grad_y_pred = 2.0 * (y_pred - y) # the last layer's error
    grad_w2 = h_relu.T.dot(grad_y_pred)
    grad_h_relu = grad_y_pred.dot(w2.T) # the second laye's error 
    grad_h = grad_h_relu.copy()
    grad_h[h < 0] = 0  # the derivate of ReLU
    grad_w1 = x.T.dot(grad_h)

    # Update weights
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2

plt.plot(loss_col)
plt.show()

有关ReLU衍生物的更多信息,请参阅此处:http://kawahara.ca/what-is-the-derivative-of-relu/

答案 2 :(得分:2)

是的原始Relu功能有您描述的问题。 所以他们后来改变了公式,称其为泄漏的Relu 实质上,Leaky Relu略微倾斜功能的水平部分。欲了解更多信息,请观看:

An explantion of activation methods, and a improved Relu on youtube

答案 3 :(得分:1)

此外,您可以在此处找到caffe框架中的实现:https://github.com/BVLC/caffe/blob/master/src/caffe/layers/relu_layer.cpp

negative_slope指定是否通过将其与斜率值相乘来“泄漏”负值而不是将其设置为0.当然,您应该将此参数设置为零以获得经典版本。

答案 4 :(得分:1)

所以当您计算梯度时,是否表示我杀死了梯度 x <= 0是否合适?

! ‌如果神经元(激活函数输入)的输入和偏差的加权和小于零,并且神经元使用Relu激活函数,则在反向传播期间导数的值为零,并且对该神经元的输入权重不变(未更新)。

有人可以逐步解释我的神经网络架构的反向传播吗?

一个简单的示例可以显示反向传播的一个步骤。此示例涵盖了一个步骤的完整过程。 但是您也可以只检查与Relu相关的部分。这类似于所介绍的架构,为简单起见,每层都使用一个神经元。体系结构如下:

enter image description here

p和g分别代表Relu和S形,b代表偏差。 第1步: 首先,计算输出:

enter image description here

这仅表示输出计算。 “ z”和“ a”分别代表神经元的输入和神经元激活功能的输出值的总和。 所以h是估计值。假设实际值为y。

体重现在通过反向传播更新。

新的权重是通过计算误差函数相对于权重的梯度,并从先前的权重减去该梯度得到的,即:

W = =

在反向传播中,首先计算最后一层的最后一个神经元的梯度。链导数规则用于计算:

enter image description here

上面使用的三个通用术语是:

  • 实际值与估计值之差

  • 神经元输出平方

  • 还有激活器函数的导数(假设最后一层中的激活器函数是S型的),我们有:

enter image description here

上面的语句不一定为零。

现在我们进入第二层。在第二层中,我们将:

enter image description here

它由4个​​主要术语组成:

  • 实际值与估计值之差。

  • 神经元输出平方

  • 下一层连接的神经元的损耗导数之和

  • 激活器函数的派生类,由于激活器函数是Relu,我们将拥有:

如果z2 <= 0(z2是Relu函数的输入):

enter image description here

否则,它不一定为零:

enter image description here

因此,如果神经元的输入小于零,则损失导数始终为零,权重不会更新。

* 重复说明,神经元输入的总和必须小于零才能消除梯度下降。

给出的示例是一个非常简单的示例,用于说明反向传播过程。