使用relu进行梯度下降的影响

时间:2017-11-30 16:11:47

标签: neural-network deep-learning gradient-descent derivative activation-function

relu激活函数不包含衍生物的影响是什么?

How to implement the ReLU function in Numpy实现relu作为(0,矩阵向量元素)的最大值。

这是否意味着梯度下降我们不采用relu函数的导数?

更新:

来自Neural network backpropagation with RELU

本文有助于理解:

  

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作为一个整体。

但是这仍然存在一些混乱,因为神经网络成本函数通常需要激活函数的衍生物,所以对于relu来说这会影响成本函数吗?

1 个答案:

答案 0 :(得分:2)

标准答案是ReLU的输入很少完全为零,例如see here,因此它没有任何显着差异。

具体地,对于ReLU获得零输入,具有该层权重矩阵的一整列的层的输入的整行的点积必须恰好为零。即使你有一个全零输入样本,在最后一个位置仍然应该有一个偏差项,所以我不会真的看到这种情况发生过。

但是,如果您想自己测试,请尝试将00.51处的导数实现为零,并查看是否有任何更改。

PyTorch文档为simple neural network with numpy example提供了一个隐藏图层并重新激活。我在下面用固定的随机种子和三个选项将其复制,用于将ReLU梯度的行为设置为0.我还添加了一个偏差项。

N, D_in, H, D_out = 4, 2, 30, 1

# Create random input and output data
x = x = np.random.randn(N, D_in)
x = np.c_(x, no.ones(x.shape[0]))
y = x = np.random.randn(N, D_in)

np.random.seed(1)

# Randomly initialize weights
w1 = np.random.randn(D_in+1, 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  # grad at zero = 1
    # grad[h <= 0] = 0 # grad at zero = 0
    # grad_h[h < 0] = 0; grad_h[h == 0] = 0.5 # grad at zero = 0.5
    grad_w1 = x.T.dot(grad_h)

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