Sigmoid引发的梯度消失爆炸及ReLU引起的神经元参数失效问题思考

请添加图片描述

引文

梯度消失和梯度爆炸是神经网络训练中常见的两个问题,特别是在使用Sigmoid激活函数时。这些问题主要是由Sigmoid函数的数学性质引起的。同样在使用ReLU激活函数的时候也会遇到类似由激活函数引起的问题,如果想看ReLU部分引起的神经元失效问题请直接跳转,如果觉得讲的啰嗦也可以直接看最后的精简版本哦。

Sigmoid函数

Sigmoid激活函数定义为:

σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1+e^{-z}} σ(z)=1+ez1

它的导数(即梯度)为:

σ ′ ( z ) = σ ( z ) ⋅ ( 1 − σ ( z ) ) \sigma'(z) = \sigma(z) \cdot (1-\sigma(z)) σ(z)=σ(z)(1σ(z))

Sigmoid函数的输出范围是(0, 1),这意味着它的导数 σ ′ ( z ) \sigma'(z) σ(z)的最大值是0.25。 z z z很大或很小的时候,Sigmoid函数会趋近于0或1,导致其导数趋近于0,其图形上的斜率就很小啊导数就是小于0.25。

梯度消失问题

当网络很深时,再次使用Sigmoid作为激活函数,这个过程实际上就是不断的加权求和激活,不断的加权求和激活不断的加权求和激活不断的加权求和激活不断的加权求和激活,就会导致其在更新最初第一个隐藏层权重的时候,计算导数的过程中,要不断的利用链式法则解开这嵌套了多层的函数。就是要不断的对激活函数求导数,梯度经过多层反向传播会连续乘以这些小于1的数(最大为0.25),导致梯度值迅速减小,最终趋近于0。这就是梯度消失问题,导致深层网络的权重几乎不更新,从而影响网络学习。

梯度爆炸问题

虽然在使用Sigmoid激活函数时梯度消失更为常见,但是梯度爆炸也可能发生,尤其是在网络权重初始化较大,或者==输入数据未经标准化处理时。当梯度的绝对值变得非常大,以至于权重更新过程中出现极端值,==导致数值计算溢出或者网络无法收敛。虽然梯度爆炸与Sigmoid激活函数的直接关系不如梯度消失那么明显,但它们在训练非常深的网络时都可能出现,并且都需要特别注意。

解决方案

为了缓解发生在深度神经网络中的梯度消失问题,学术界和工业界有几种常用的策略:

  • 使用ReLU激活函数:ReLU(Rectified Linear Unit)因为其单侧饱和(对正输入,导数恒为1)的性质而受到青睐。这减少了梯度消失的问题,但也要注意ReLU可能导致的激活死亡问题。
  • 权重初始化:合适的权重初始化方式(如He初始化或Xavier初始化)可以在训练开始时防止梯度过大或过小。
  • 使用残差网络(ResNet)等架构:通过引入跳过连接,即使部分路径上的梯度消失,残差连接也可以帮助保持信息流。
  • 批量归一化(Batch Normalization):通过对每层输入进行归一化,可以减少训练过程中参数范围的差异,从而帮助缓解梯度消失或爆炸问题。

ReLU函数 拯救sigmoid问题的救星

接下里啊重点来了这个 ReLU缺陷问题

sigmoid问题 就是在使用sigmoid函数的过程中出现的梯度消失问题就是在求激活函数部分的导数时,由于其结果多层嵌套的原因,要多次对sigmoid的函数求导数,其导数结果为多个小于0.25的数值做乘积,最终计算的梯度信息变得很好直至为0,会出现梯度消失和爆炸的问题。。

因此这个梯度消失主要是由于其激活函数引起的。就是神经网络多层就是不断的加权求和加权求和的遍历,这就会导致计算导数是多个嵌套sigmoid导数的乘积,结果展示出来的就是小于0.25的乘积。因此这个问题是sigmoid的锅

而最近在学习这个moilenet发现有些参数变成0了,这个也是ReLU激活函数的锅。这个问题具体是怎么导致的呢???

下面是一个简单的损失函数。
首先模型定义下:

y = R e L U ( w x + b ) y = ReLU(wx +b) y=ReLU(wx+b)
这个过程可以简单地概括为以下几个步骤:从权重 w w w到加权输入 z z z(由 w x + b wx + b wx+b给出),再到激活后的输出 y y y(由 R e L U ( z ) ReLU(z) ReLU(z)给出),最后到损失 L L L(由 1 2 ( y − t ) 2 \frac{1}{2}(y - t)^2 21(yt)2给出)。具体地:

  1. 权重到加权输入:给定权重 w w w和偏置项 b b b,以及输入 x x x,我们首先计算加权输入 z z z,它是通过权重和输入的乘积再加上偏置项得到的:

    z = w x + b z = wx + b z=wx+b

  2. 加权输入到激活输出:然后,加权输入 z z z被送入激活函数(这里以ReLU为例)以计算激活后的输出 y y y

    y = R e L U ( z ) = m a x ( 0 , z ) y = ReLU(z) = max(0, z) y=ReLU(z)=max(0,z)

  3. 激活输出到损失:最后,激活输出 y y y被用于损失函数(这里以二次损失函数为例)以计算与目标值 t t t之间的损失 L L L

    L = 1 2 ( y − t ) 2 L = \frac{1}{2}(y - t)^2 L=21(yt)2

通过这种从输入至输出的正向计算,可以得到损失值,而反向传播算法的目标是通过损失值来优化 w w w b b b,以减少模型的输出与目标之间的差异。

在反向传播过程中,我们利用链式法则依次计算损失函数 L L L关于 y y y y y y关于 z z z、以及 z z z关于 w w w的偏导数,这为我们提供了关于如何调整 w w w(以及 b b b)以减小损失 L L L的方向和幅度的指导。

通过链式法则,我们可以表示为:

∂ L ∂ w = ∂ L ∂ y ⋅ ∂ y ∂ z ⋅ ∂ z ∂ w \frac{\partial L}{\partial w} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial z} \cdot \frac{\partial z}{\partial w} wL=yLzywz

这种方法让我们可以精确地理解每个模型参数是如何影响最终损失的,从而使得我们能够通过梯度下降等优化算法有效地训练神经网络。

先看第一部分损失函数 L L L对输出 y y y的导数为:

∂ L ∂ y = ( y − t ) = ( 0 − 1 ) = − 1 \frac{\partial L}{\partial y} = (y - t) = (0 - 1) = -1 yL=(yt)=(01)=1

这一部分之前没啥问题,这是损失函数决定的基本不出问题。然而,在连接损失函数 y y y z z z的导数时,应该更仔细地考虑整个计算链。

损失函数 L L L关于权重 w w w的导数需要考虑到 y y y如何依赖于 w w w,即通过链式法则考虑 y = R e L U ( z ) y = ReLU(z) y=ReLU(z)。重点在于激活函数ReLU对其输入的导数。

对于ReLU函数,其导数为,这主要是分段函数:
R e L U ( z ) = { 0 if  z < 0 z if  z > 0 ReLU(z)= \begin{cases} 0 & \text{if } z < 0 \\ z & \text{if } z > 0 \end{cases} ReLU(z)={0zif z<0if z>0
导数计算结果:

∂ R e L U ( z ) ∂ z = { 0 if  z < 0 1 if  z > 0 \frac{\partial ReLU(z)}{\partial z} = \begin{cases} 0 & \text{if } z < 0 \\ 1 & \text{if } z > 0 \end{cases} zReLU(z)={01if z<0if z>0

在这例子中,激活前的值 z = − 1 z = -1 z=1,因此 ∂ y ∂ z = 0 \frac{\partial y}{\partial z}=0 zy=0。这意味着,后面没啥计算的必要了都是0.如果是 R e L U ( w x + b ) ReLU(wx +b) ReLU(wx+b) w x + b wx +b wx+b小于0则梯度信息 w w w的梯度就是不会更新。

但是为什么这个问题在mobilenet中出现的比较严重呢,在传统的CNN中没被讨论过呢。上文中可以看到 z z z的取值仅仅通过主要是一个权重 w w w控制,这看起来就像是深度可分离卷积仅仅一个卷积核控制一个通道的特征生成,这就导致其计算结果都由一个 w w w决定, w x + b wx +b wx+b结果小于0,被激活就是0的结果是不会更新的。

先把这部分计算看一下到底为0会不会更新:

接下来考虑如何从 x x x w w w的导数。在这个例子中,输入 x = − 1 x=-1 x=1,因此:

∂ z ∂ w = x = − 1 \frac{\partial z }{\partial w} = x = -1 wz=x=1

结合上述内容:

∂ L ∂ w = ∂ L ∂ y ⋅ ∂ y ∂ z ⋅ ∂ z ∂ w \frac{\partial L}{\partial w} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial z} \cdot \frac{\partial z}{\partial w} wL=yLzywz

给出:

∂ L ∂ w = ( − 1 ) ⋅ 0 ⋅ ( − 1 ) = 0 \frac{\partial L}{\partial w} = (-1) \cdot 0 \cdot (-1) = 0 wL=(1)0(1)=0

最终就是计算不出来梯度信息了。

如何改善这个问题呢????

ReLU(Rectified Linear Unit)激活函数在神经网络中的应用非常广泛,因为它简单且效果良好,有助于解决梯度消失问题,并加速神经网络的收敛。然而,ReLU也有其缺陷,比如所谓的“死亡ReLU”问题。这是指当网络中的一个神经元的输出始终为0时,该神经元对于梯度下降算法就没有贡献,因为它对于损失函数的梯度也为0,导致权重无法得到更新。

如果某个卷积核的权重 w w w乘以输入 x x x后加上偏置 b b b(即 w x + b wx + b wx+b)得到的值为负数,那么通过ReLU激活后的输出会是0,导致该权重在接下来的梯度下降过程中不会被更新。但是,如果有使用两组参数 w 1 x 1 + w 2 x 2 w_1x_1 + w_2x_2 w1x1+w2x2,并且使得整体输出为正数,则即使 w 1 x 1 w_1x_1 w1x1部分的计算结果为负,整体的激活输出仍然为正,这就保证了在梯度反向传播时, w 1 w_1 w1有机会被调整和优化。

但是有些伙伴可能发现了我“并没有考虑 x 1 x_1 x1为负数”的情况,在图像处理的上下文中通常不会出现,因为像素值通常在0到255之间。这意味着,如果权重被初始化为负数,那么单个卷积核可能就无法有效地被优化。然而通过将多个权重组合在一起,即便单一权重或激活值为负,通过整体的正输出值,也能保证相关权重在训练过程中得到适当的更新。

总结来说,通过增加权重组合,可以有效减少因初始化问题导致的“死亡ReLU”问题。这种权重的组合策略,提供了一种方式来确保即使某些权重初始化不理想,网络仍然有机会在训练过程中调整这些参数,从而避免了单一卷积核因激活输出始终为0而停滞不前的情况。

举个例子:

简化模型示例

假设有一个简单的神经网络层,该层有两个输入 x 1 x_1 x1 x 2 x_2 x2,和对应的权重 w 1 w_1 w1 w 2 w_2 w2,无偏置项(为了简化)。该层的输出通过ReLU激活函数。因此,输出 y y y可以表示为:

y = R e L U ( z ) = R e L U ( w 1 x 1 + w 2 x 2 ) y = ReLU(z) = ReLU(w_1x_1 + w_2x_2) y=ReLU(z)=ReLU(w1x1+w2x2)

场景设定

假设输入和权重值如下:

  • 输入: x 1 = − 2 , x 2 = 3 x_1 = -2, x_2 = 3 x1=2,x2=3
  • 权重: w 1 = 2 , w 2 = 2 w_1 = 2, w_2 = 2 w1=2,w2=2

前向传播

进行前向传播计算:

z = w 1 x 1 + w 2 x 2 = 2 ( − 2 ) + 2 ( 3 ) = − 4 + 6 = 2 z = w_1x_1 + w_2x_2 = 2(-2) + 2(3) = -4 + 6 = 2 z=w1x1+w2x2=2(2)+2(3)=4+6=2

因此,经过ReLU激活后的输出 y y y为:

y = R e L U ( 2 ) = 2 y = ReLU(2) = 2 y=ReLU(2)=2

即使 w 1 x 1 w_1x_1 w1x1的贡献是负的(具体来说是-4),这样是直接使用激活函数就是0,以后就没法更新了,但是将这部分输出和 w 2 x 2 w_2x_2 w2x2的正贡献(+6)进行融合足以抵消这个负面影响,使得 z z z为正值2。因此,在这个简化模型中,即使某些组成部分是负的,整体输出仍然是正的。

那么为正有什么意义呢,如果采用单组权重很有可能这个 w 1 w_1 w1不在更新了,但是可以看到在两个权重的情况下, w 1 w_1 w1还是可以依赖于 w 2 w_2 w2 R e L U ( z ) ReLU(z) ReLU(z)做的贡献实现参数的更新,不停止更新这个权重才有效啊因此:

对反向传播的影响

在反向传播中,ReLU激活函数的导数为:

∂ R e L U ( z ) ∂ z = { 1 if  z > 0 , 0 otherwise. \frac{\partial ReLU(z)}{\partial z} = \begin{cases} 1 & \text{if } z > 0, \\ 0 & \text{otherwise.} \end{cases} zReLU(z)={10if z>0,otherwise.

对于我们的例子来说 z = 2 z=2 z=2,因此 ∂ R e L U ( z ) ∂ z = 1 \frac{\partial ReLU(z)}{\partial z} = 1 zReLU(z)=1。也就是说允许某些神经元计算出负数输出的情况下还能利用梯度信息更新。(另一个参数在这个过程中起到了巨大的贡献)

总结

因此,在包含ReLU激活函数的神经网络中,即使某些权重(如 w 1 w_1 w1)和输入的组合(如 w 1 x 1 w_1x_1 w1x1)贡献了负值,但只要整体加权和( z z z)为正,ReLU激活后的神经元就可以对损失函数的梯度做出响应,并且所有相关的权重( w 1 w_1 w1 w 2 w_2 w2)在反向传播过程中都有可能被更新。这种机制展示了深度学习模型在训练过程中通过结合多个特征和权重以实现复杂函数近似的强大能力。

传统卷积则不会考虑这部分问题。如果一个参数比作一个通道的卷积核,那么多个参数加权求和就是传统CNN的解决方式,将多个通道互联从而减少ReLU中出现的问题,因为其最终激活前的结果是多个卷积核参数共同作用的产物。因此不会出现参数无法更新的情况。

而mobilenet最初设计的深度卷积层通道间不相互作用本身就是孤立了权重,可以看成一个通道间仅仅使用了一个卷积核,就是一组 w x wx wx使其计算负值后无法进行参数的更新,因此人家V2给出的解决方案就是多个卷积核实现的人海战术,具体的请大家接着会看mobilenetV2的博文讲解。

内容精简版

在我们之前的讨论中,我们特别指出了在使用Sigmoid激活函数时碰到的梯度消失问题,这一问题主要源于激活函数的求导过程的特性。特别是在深层神经网络结构中,一个激活函数的导数可能会被连续计算多次,这种过程涉及到大量对Sigmoid函数的求导。由于其导数值总是小于1,经过多次求导并相乘后,最终的梯度值迅速减小至接近0,引发了所谓的“梯度消失”问题。

基本上,深度神经网络的核心操作包括连续的加权求和和激活。在这种结构下,连续多次应用Sigmoid函数会遇到一个挑战:由多层嵌套的Sigmoid函数导出的导数乘积,导致最终梯度值不足,产生小于1的累乘效应。这个问题的根本原因在于Sigmoid激活函数的数学特性。

Sigmoid函数的这种特性,尤其是在网络多层传播时的影响,成为了深度学习模型训练面临的一个关键挑战。它揭示出,选择激活函数时,需要考虑该函数在反向传播时是否会引起梯度消失或爆炸现象,这直接影响模型的学习效率和最终性能。

而近期在学习MobileNet时发现的某些参数变为0的问题,同样源自ReLU激活函数的特性。这个问题究竟是如何产生的呢?简而言之,当我们对通向ReLU函数的输入进行求导时,如果输入的加权和(例如 w x + b wx + b wx+b)小于0,则导数为0,导致权重 w w w的更新停滞,因为反向传播中将没有梯度信息传递。

为了阐述这个问题,我们设立了一个模型,其中包含两个输入 x 1 x_1 x1 x 2 x_2 x2和相应的权重 w 1 w_1 w1 w 2 w_2 w2。模型的输出通过ReLU函数激活,并且没有偏置项 b b b来简化计算。

在有两个权重的情况下,即使 w 1 x 1 w_1x_1 w1x1的贡献是负的,与 w 2 x 2 w_2x_2 w2x2的正向贡献结合仍然足以抵消负面影响,保证整体输出 y y y在ReLU激活后为正。因此,即使某些组成部分是负值,整体模型输出仍然保持活跃,且能够正常传递梯度信息,确保所有相关权重在反向传播过程获得有效更新。

此示例清晰展示了通过多权重协同作用,可以有效克服由单个权重或输入导致的激活函数负输出,确保深层神经网络能够持续学习和适应。这表明了激活函数选择对于防止梯度消失和保障网络学习能力的重要性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这个男人是小帅

请小弟喝杯咖啡☕️鼓励下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值