反向传播算法推导、激活函数、梯度消失与爆炸

目录

  • 反向传播算法
    • 定义
    • 推导过程
  • 激活函数
    • 定义
    • 性质
    • 常用的激活函数
      • Sigmoid
      • Tanh
      • ReLU
      • softmax
  • 梯度消失与梯度爆炸
    • 起因
    • 出现的原因
    • 表现
    • 解决方案
  • 参考文档

反向传播算法

定义

反向传播(Backpropagation,缩写为BP)是“误差反向传播”的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见方法。 该方法对网络中所有权重计算损失函数的梯度。 这个梯度会反馈给最优化方法,用来更新权值以最小化损失函数。(误差的反向传播)

推导过程

设所有激活函数均为sigmoid函数,记为f(.),每层的加权求和记为net(.),经过激活函数后记为out(.),损失函数记为L。
下面以二输入(x1,x2),二输出(y1,y2),三隐含层为例
反向传播算法推导、激活函数、梯度消失与爆炸_第1张图片
先做 正向传播

反向传播算法推导、激活函数、梯度消失与爆炸_第2张图片
再做 反向传播

反向传播算法推导、激活函数、梯度消失与爆炸_第3张图片
我们看图得知,从w1到y1会经过两条路线。
一条是x1->h1->h3->h5->y1, 另一条是x1->h1->h4->h5->y1
(可以理解为反向的加权求和)
反向传播算法推导、激活函数、梯度消失与爆炸_第4张图片
反向传播算法推导、激活函数、梯度消失与爆炸_第5张图片

激活函数

定义

激活函数 (Activation functions) 对于人工神经网络模型去学习、理解非常复杂和非线性的函数来说具有十分重要的作用。它们将非线性特性引入到神经网络中。在下图中,输入的 inputs 通过加权,求和后,还被作用了一个函数f,这个函数f就是激活函数。引入激活函数是为了增加神经网络模型的非线性。没有激活函数的每层都相当于矩阵相乘。就算你叠加了若干层之后,无非还是个矩阵相乘罢了。
反向传播算法推导、激活函数、梯度消失与爆炸_第6张图片

性质

激活函数有哪些性质?

1、非线性:当激活函数是非线性的,一个两层的神经网络就可以基本上逼近所有的函数。但如果激活函数是恒等激活函数的时候,即f(x) = x,就不满足这个性质,而且如果MLP使用的是恒等激活函数,那么其实整个网络跟单层神经网络是等价的。

2、可微性:当优化方法是基于梯度的时候,就体现的该本质。

3、单调性:当激活函数是单调的时候,单层网络能够保证是凸函数。

4、输出值的范围:当激活函数输出值是有限的时候,基于梯度的优化方法会更加稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是无限的时候,模型的训练更加高效,不过这种情况很小,一般需要更小的learning rate。

为什么使用激活函数?
如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层节点的输入都是上层输出的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,这种情况就是最原始的感知机(Perceptron)了,那么网络的逼近能力就相当有限。正因为上面的原因,我们决定引入非线性函数作为激励函数,这样深层神经网络表达能力就更加强大(不再是输入的线性组合,而是几乎可以逼近任意函数)。

常用的激活函数

激活函数分为两类,饱和激活函数和非饱和激活函数。

饱和激活函数包括sigmoid、tanh;非饱和激活函数包括ReLU、PReLU、Leaky ReLU、RReLU、ELU等。使用“非饱和激活函数”的优势在于两点:(1)"非饱和激活函数”能解决所谓的“梯度消失”问题。(2)它能加快收敛速度。

饱和函数
反向传播算法推导、激活函数、梯度消失与爆炸_第7张图片

Sigmoid

反向传播算法推导、激活函数、梯度消失与爆炸_第8张图片
sigmoid函数能够把输入的连续实值变换为0和1之间的输出。如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1。

在什么情况下适合使用 Sigmoid 激活函数?

1、Sigmoid 函数的输出范围是 0 到 1。由于输出值限定在 0 到 1,因此它对每个神经元的输出进行了归一化;

2、用于将预测概率作为输出的模型。由于概率的取值范围是 0 到 1,因此 Sigmoid 函数非常合适;

3、梯度平滑,避免「跳跃」的输出值;

4、函数是可微的。这意味着可以找到任意两个点的 sigmoid 曲线的斜率;

5、明确的预测,即非常接近 1 或 0。

缺点
1、容易出现梯度消失

2、函数输出并不是zero-centered(零均值)

3、幂运算相对来讲比较耗时

Tanh

反向传播算法推导、激活函数、梯度消失与爆炸_第9张图片
sigmoid与tanh的比较
首先,当输入较大或较小时,输出几乎是平滑的并且梯度较小,这不利于权重更新。二者的区别在于输出间隔,tanh 的输出间隔为 1,并且整个函数以 0 为中心,比 sigmoid 函数更好;

在 tanh 图中,负输入将被强映射为负,而零输入被映射为接近零。

注意:在一般的二元分类问题中,tanh 函数用于隐藏层,而 sigmoid 函数用于输出层,但这并不是固定的,需要根据特定问题进行调整。
反向传播算法推导、激活函数、梯度消失与爆炸_第10张图片

ReLU

反向传播算法推导、激活函数、梯度消失与爆炸_第11张图片
ReLU的优点:
1、解决了梯度消失问题 (在正区间),ReLU的非饱和性可以有效地解决梯度消失的问题, 提供相对宽的激活边界。

2、Sigmoid和Tanh激活函数均需要计算指数, 复杂度高, 而ReLU只需要一个阈值即可得到激活值。ReLU 函数中只存在线性关系,因此它的计算速度比 sigmoid 和 tanh 更快。计算速度非常快,只需要判断输入是否大于0。

3、收敛速度远快于sigmoid和tanh

4、ReLU使得一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的互相依存关系,缓解了过拟合问题的发生

缺点
1、ReLU 函数的输出为 0 或正数,不是zero-centered

2、对参数初始化和学习率非常敏感;

3、ReLU 函数的输出均值大于0,偏移现象和神经元死亡会共同影响网络的收敛性。

4、存在神经元死亡,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。这是由于函数导致负梯度在经过该ReLU单元时被置为0, 且在之后也不被任何数据激活, 即流经该神经元的梯度永远为0, 不对任何数据产生响应。 当输入为负时,ReLU 完全失效,在正向传播过程中,这不是问题。有些区域很敏感,有些则不敏感。但是在反向传播过程中,如果输入负数,则梯度将完全为零,sigmoid 函数和 tanh 函数也具有相同的问题。有两个主要原因可能导致这种情况产生: (1) 非常不幸的参数初始化,这种情况比较少见; (2) learning rate太高导致在训练过程中参数更新太大,会导致超过一定比例的神经元不可逆死亡, 进而参数梯度无法更新, 整个训练过程失败。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法。

softmax

反向传播算法推导、激活函数、梯度消失与爆炸_第12张图片
Softmax 激活函数的主要缺点是:

1、在零点不可微;

2、负输入的梯度为零,这意味着对于该区域的激活,权重不会在反向传播期间更新,因此会产生永不激活的死亡神经元。

梯度消失与梯度爆炸

起因

目前优化神经网络的方法都是基于BP,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化。其中将误差从末层往前传递的过程需要链式法则(Chain Rule)的帮助,因此反向传播算法可以说是梯度下降在链式法则中的应用。

而链式法则是一个连乘的形式,所以当层数越深的时候,梯度将以指数形式传播。梯度消失问题和梯度爆炸问题一般随着网络层数的增加会变得越来越明显。在根据损失函数计算的误差通过梯度反向传播的方式对深度网络权值进行更新时,得到的梯度值接近0特别大,也就是梯度消失或爆炸。梯度消失或梯度爆炸在本质原理上其实是一样的。

出现的原因

直接原因
(1)梯度消失
1、隐藏层的层数过多
2、采用了不合适的激活函数(更容易产生梯度消失,但是也有可能产生梯度爆炸)

(2)梯度爆炸
1、隐藏层的层数过多
2、权重的初始化值过大

根本原因
(1)隐藏层的层数过多
从深层网络角度来讲,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。因此,梯度消失、爆炸,其根本原因在于在于反向传播算法的不足。
多个隐藏层的网络可能比单个隐藏层的更新速度慢了几个个数量级
(2)激活函数
BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整,计算梯度包含了是对激活函数进行求导,如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸,如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失。
(3)初始权重过大
当网络初始权重比较大的情况下,当反向传播的链式相乘时,前面的网络层比后面的网络层梯度变化更快,最终的求出的梯度更新将以指数形式增加,将会导致梯度爆炸。所以,在一般的神经网络中,权重的初始化一般都利用高斯分布(正态分布)随机产生权重值。

表现

(1)梯度消失的表现:
模型无法从训练数据中获得更新,损失几乎保持不变

(2)梯度爆炸的表现:
模型型不稳定,更新过程中的损失出现显著变化;
训练过程中,模型损失变成 NaN

解决方案

梯度消失和梯度爆炸问题都是因为网络太深,网络权值更新不稳定造成的,本质上是因为梯度反向传播中的连乘效应。对于更普遍的梯度消失问题,可以考虑一下以下方案解决:
(1)用ReLU、Leaky-ReLU、P-ReLU、R-ReLU、Maxout等替代sigmoid函数。
思想也很简单,如果激活函数的导数为1,那么就不存在梯度消失爆炸的问题了,每层的网络都可以得到相同的更新速度。
(2)用Batch Normalization。
那么反向传播过程中权重的大小影响了梯度消失和爆炸,BN就是通过对每一层的输出规范为均值和方差一致的方法,消除了 权重带来的放大缩小的影响,进而解决梯度消失和爆炸的问题,或者可以理解为BN将输出从饱和区拉到了非饱和区(比如Sigmoid函数)。
(3)LSTM的结构设计也可以改善RNN中的梯度消失问题。
在RNN网络结构中,由于使用Logistic或者Tanh函数,所以很容易导致梯度消失的问题,即在相隔很远的时刻时,前者对后者的影响几乎不存在了,LSTM的机制正是为了解决这种长期依赖问题。
(4)ResNet残差网络
相比较以往的网络结构只是简单的堆叠,残差中有很多跨层连接结构,这样的结构在反向传播时具有很大的好处。
(5)预训练加微调
此方法来自Hinton在2006年发表的一篇论文,Hinton为了解决梯度的问题,提出采取无监督逐层训练方法,其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程是逐层预训练;
在预训练完成后,再对整个网络进行“微调”(fine-tunning)。此思想相当于是先寻找局部最优,然后整合起来寻找全局最优。
(6)梯度剪切
梯度剪切这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。

参考文档

反向传播算法推导
常用激活函数
梯度消失与梯度爆炸

你可能感兴趣的:(反向传播算法推导、激活函数、梯度消失与爆炸)