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

Neural network 使用relu进行梯度下降的影响,neural-network,deep-learning,gradient-descent,derivative,activation-function,Neural Network,Deep Learning,Gradient Descent,Derivative,Activation Function,relu激活函数不包含导数这一事实会产生什么影响 将relu实现为最大值(0,矩阵向量元素) 这是否意味着对于梯度下降,我们不取relu函数的导数 更新: 从 本文本有助于理解: ReLU函数定义为:对于x>0,输出为x,即f(x) =最大值(0,x) 对于导数f’(x),它实际上是: 如果x0,则输出为1 未定义导数f'(0)。所以它通常被设置为0或者你 对于较小的e,将激活函数修改为f(x)=max(e,x) 通常情况下:ReLU是使用整流器激活的装置 功能。这意味着它的工作原理与任何其他隐

relu激活函数不包含导数这一事实会产生什么影响

将relu实现为最大值(0,矩阵向量元素)

这是否意味着对于梯度下降,我们不取relu函数的导数

更新:

本文本有助于理解:

ReLU函数定义为:对于x>0,输出为x,即f(x) =最大值(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的工作多层网络编写了代码 激活它实际上是一行改变。没有关于前进或前进的内容 反向传播在算法上改变。如果你还没拿到 更简单的模型仍然有效,请返回并首先从该模型开始。 否则你的问题不是关于雷卢斯而是关于 将NN作为一个整体来实现


但这仍然留下了一些混乱,因为神经网络成本函数通常采用激活函数的导数,因此对于relu,这会如何影响成本函数?

标准答案是,例如,relu的输入很少精确为零,因此不会产生任何显著差异

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

但是,如果您想自己测试,请尝试将导数设置为0,如
0
0.5
1
,并查看是否有任何变化

PyTorch文档提供一个隐藏层和relu激活。我在下面用一个固定的随机种子和三个选项复制了它,用于将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
N,D_in,H,D_out=4,2,30,1
#创建随机输入和输出数据
x=x=np.random.randn(N,D_in)
x=np.c_ux(x,没有一个(x.shape[0]))
y=x=np.random.randn(N,D_in)
np.随机种子(1)
#随机初始化权重
w1=np.random.randn(D_in+1,H)
w2=np.random.randn(H,D_out)
学习率=0.002
损失_col=[]
对于范围(200)内的t:
#向前传球:计算预测y
h=x点(w1)
h_relu=np.最大值(h,0)#使用relu作为激活函数
y_pred=h_relu.dot(w2)
#计算和打印损耗
损耗=np.平方(y_pred-y).sum()#损耗函数
损失列追加(损失)
打印(t、损耗、y_pred)
#Backprop计算w1和w2相对于损失的梯度
grad_y_pred=2.0*(y_pred-y)#最后一层的错误
grad_w2=h_relu.T.dot(grad_y_pred)
grad_h_relu=grad_y_pred.dot(w2.T)#第二层的错误
grad_h=grad_h_relu.copy()
grad_h[h<0]=0#0时的grad=1

#grad[h这意味着您可能会失去与GD有关的所有保证(wiki称之为定义不清)。更新中的文本没有解决以下问题:(1):这是一个次梯度。(2):次梯度可能用于SGD;但不用于普通GD。