Sigmoid和ReLU激活函数思考)
- 引文
- Sigmoid函数
- 梯度消失问题
- 梯度爆炸问题
- 解决方案
- ReLU函数
- 简化模型示例
- 场景设定
- 前向传播
- 对反向传播的影响
- 总结
- 内容精简版
引文
梯度消失和梯度爆炸是神经网络训练中常见的两个问题,特别是在使用Sigmoid激活函数时。这些问题主要是由Sigmoid函数的数学性质引起的。同样在使用ReLU激活函数的时候也会遇到类似由激活函数引起的问题,如果想看ReLU部分引起的神经元失效问题请直接跳转,如果觉得讲的啰嗦也可以直接看最后的精简版本哦。
Sigmoid函数
Sigmoid激活函数定义为:
σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1+e^{-z}} σ(z)=1+e−z1
它的导数(即梯度)为:
σ ′ ( 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。
梯度消失问题
当使用Sigmoid激活函数的网络很深时,实际上就是不断的加权求和激活,不断的加权求和激活不断的加权求和激活不断的加权求和激活不断的加权求和激活,就会导致其在更新最初层导数的时候要不断的利用链式法则解开这嵌套了多层的函数梯度经过多层反向传播会连续乘以这些小于1的数(最大为0.25),导致梯度值迅速减小,最终趋近于0。这就是梯度消失问题,导致深层网络的权重几乎不更新,从而影响网络学习。
梯度爆炸问题
虽然在使用Sigmoid激活函数时梯度消失更为常见,但是梯度爆炸也可能发生,尤其是在网络权重初始化较大,或者==输入数据未经标准化处理时。当梯度的绝对值变得非常大,以至于权重更新过程中出现极端值,==导致数值计算溢出或者网络无法收敛。虽然梯度爆炸与Sigmoid激活函数的直接关系不如梯度消失那么明显,但它们在训练非常深的网络时都可能出现,并且都需要特别注意。
解决方案
为了缓解发生在深度神经网络中的梯度消失问题,学术界和工业界有几种常用的策略:
- 使用ReLU激活函数:ReLU(Rectified Linear Unit)因为其单侧饱和(对正输入,导数恒为1)的性质而受到青睐。这减少了梯度消失的问题,但也要注意ReLU可能导致的激活死亡问题。
- 权重初始化:合适的权重初始化方式(如He初始化或Xavier初始化)可以在训练开始时防止梯度过大或过小。
- 使用残差网络(ResNet)等架构:通过引入跳过连接,即使部分路径上的梯度消失,残差连接也可以帮助保持信息流。
- 批量归一化(Batch Normalization):通过对每层输入进行归一化,可以减少训练过程中参数范围的差异,从而帮助缓解梯度消失或爆炸问题。
ReLU函数
接下里啊重点来了这个 ReLU缺陷问题
在我们之前的讨论中,特别指出了在使用 Sigmoid 激活函数时碰到的梯度消失问题,这一问题主要源于在进行激活函数的求导过程的特性。由于在多层网络中,激活函数的导数需要被连续计算多次,这个过程涉及到大量对 Sigmoid 函数的求导。其导数的值总是小于 1,这种多次求导并相乘的操作,导致了最终的梯度值迅速减小至接近 0 的现象 —— 即梯度消失问题的发生。
因此,这个梯度消失问题主要是由激活函数的数学特性所决定的。简单来说,深度神经网络的本质在于不断进行加权求和与激活的循环操作。当在这样的循环中连续多次应用 Sigmoid 函数时,就会遇到一个情况:多层嵌套的 Sigmoid 函数求导后相乘的结果,导致了一个小于 1 的累乘效应。从而,这个问题归根结底是由 Sigmoid 激活函数的特性所引起的。
这种对 Sigmoid 函数的依赖,尤其是它在网络中多层传播时的影响,成为了导致深度学习模型训练困难的关键。它揭示了选择激活函数时需要考虑的一个重要方面,即该激活函数在进行反向传播时是否会导致梯度消失或爆炸,从而影响模型的学习效率和效果。
说人话 就是在使用sigmoid函数的过程中出现的梯度消失问题就是在求激活函数部分的导数时,由于其结果多层嵌套的原因,要多次对sigmoid的函数求导期,其导数结果小1会出现梯度小时和爆照的问题。因此这个梯度消失主要是由于其激活函数决定的。就是神经网络多层就是不断的加权求和加权求和的遍历,这就会导致计算导数是多个嵌套sigmoid的乘积,结果展示出来的就是小于1的乘积。因此这个问题是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(y−t)2给出)。具体地:
-
权重到加权输入:给定权重 w w w和偏置项 b b b,以及输入 x x x,我们首先计算加权输入 z z z,它是通过权重和输入的乘积再加上偏置项得到的:
z = w x + b z = wx + b z=wx+b
-
加权输入到激活输出:然后,加权输入 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)
-
激活输出到损失:最后,激活输出 y y y被用于损失函数(这里以二次损失函数为例)以计算与目标值 t t t之间的损失 L L L:
L = 1 2 ( y − t ) 2 L = \frac{1}{2}(y - t)^2 L=21(y−t)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} ∂w∂L=∂y∂L⋅∂z∂y⋅∂w∂z
这种方法让我们可以精确地理解每个模型参数是如何影响最终损失的,从而使得我们能够通过梯度下降等优化算法有效地训练神经网络。
先看第一部分损失函数 L L L对输出 y y y的导数为:
∂ L ∂ y = ( y − t ) = ( 0 − 1 ) = − 1 \frac{\partial L}{\partial y} = (y - t) = (0 - 1) = -1 ∂y∂L=(y−t)=(0−1)=−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函数,其导数为,这主要是分段函数啊,实际上ReLU在对啊大于0的数值的时候 y = x y=x y=x的小于0则是 y = 0 y=0 y=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} ∂z∂ReLU(z)={01if z<0if z>0
在这例子中,激活前的值 z = − 1 z = -1 z=−1,因此 ∂ y ∂ z = 0 \frac{\partial y}{\partial z}=0 ∂z∂y=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中出现的比较严重呢,主要是一个权重控制仅仅一个通道的特征生成,这就导致其计算结果都由一个 w w w决定这就是如果 w x + b wx +b wx+b结果小于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 ∂w∂z=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} ∂w∂L=∂y∂L⋅∂z∂y⋅∂w∂z
给出:
∂ L ∂ w = ( − 1 ) ⋅ 0 ⋅ ( − 1 ) = 0 \frac{\partial L}{\partial w} = (-1) \cdot 0 \cdot (-1) = 0 ∂w∂L=(−1)⋅0⋅(−1)=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} ∂z∂ReLU(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 ∂z∂ReLU(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)在反向传播过程中都有可能被更新。这种机制展示了深度学习模型在训练过程中通过结合多个特征和权重以实现复杂函数近似的强大能力。而mobilenet最初设计的深度卷积层通道间不相互作用本身就是孤立了权重,使其计算负值后无法进行参数的更新。而传统卷积则不会考虑这部分问题。因为其最终激活前的结果是多个卷积核参数共同作用的产物。
内容精简版
在我们之前的讨论中,我们特别指出了在使用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激活后为正。因此,即使某些组成部分是负值,整体模型输出仍然保持活跃,且能够正常传递梯度信息,确保所有相关权重在反向传播过程获得有效更新。
此示例清晰展示了通过多权重协同作用,可以有效克服由单个权重或输入导致的激活函数负输出,确保深层神经网络能够持续学习和适应。这表明了激活函数选择对于防止梯度消失和保障网络学习能力的重要性。