首页 文章

RELU的神经网络反向传播

提问于
浏览
26

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

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

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

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

5 回答

  • 8

    如果你有一个由单个ReLU构成的图层,就像你的架构所暗示的那样,那么是的,你会在 0 处杀死渐变 . 在训练期间,ReLU将 0 返回到您的输出图层,如果您使用的是后勤单位,它将返回 00.5 ,而softmax将会压缩它们 . 因此,当前架构下的 0 值对于前向传播部分也没有多大意义 .

    参见例如this . 你可以做的是使用"leaky ReLU",它是 0 的一个小值,例如 0.01 .

    我会重新考虑这个架构,然而,将单个ReLU馈送到一堆其他单元然后应用softmax对我来说没有多大意义 .

  • 2

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

    ReLU函数定义为:对于x> 0,输出为x,即 f(x) = max(0,x)

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

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

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

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

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

  • 1

    这是一个很好的例子,使用ReLU实现XOR:reference,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/

  • 4

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

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

  • 8

    另外,在这里你可以找到caffe框架中的一个实现:https://github.com/BVLC/caffe/blob/master/src/caffe/layers/relu_layer.cpp

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

相关问题