深度模型中relu激活函数的不足,batch normalization怎么解决梯度消失爆炸的数值问题

目录

1.relu激活函数

提出的原因:

Relu = max(x, 0)的思想:

relu的主要贡献在于:

存在的一些缺点:

2.针对relu的一个不足:输出不是以0为中心,如何解决

3 batch normalization

3.1 BatchNorm的作用是什么呢?

3.2 为什么神经网络在训练开始之前,要对输入的数据做Normalization?

3.3 BatchNorm要解决什么问题?

3.4 BatchNorm的过程

3.5 BatchNorm在TensorFlow中使用的函数

3.6 BatchNorm的推理(Inference)过程——预测过程

3.7 BatchNorm的好处


1.relu激活函数

提出的原因:

sigmod激活函数,求导后,当导数在0位置的时候,导数值最大为0.25,再往后面网络传播的时候,很容易产生梯度消失。

Relu = max(x, 0)的思想:

也很简单,如果激活函数的导数为1,那么就不存在梯度消失爆炸的问题了,每层的网络都可以得到相同的更新速度,relu就这样应运而生。

relu的主要贡献在于:

-- 解决了梯度消失、爆炸的问题

-- 计算方便,计算速度快

-- 加速了网络的训练

存在的一些缺点

-- 由于负数部分恒为0,会导致一些神经元无法激活(可通过设置小学习率部分解决)

-- 输出不是以0为中心的——改动了输入数据的分布,下一层输入数据的分布跟前一层输入数据分布不同,会大大降低模型的训练速度,因为需要不断的适应不同的输入分布,拖慢了训练速度。

问题:输入会是负数吗?什么情况下产生负数?

分析:会。看下图反向传播推导的结果,说明梯度可能为负数,那么在正常传播时,wx+b可能为负。

2.针对relu的一个不足:输出不是以0为中心,如何解决

batch normalization出现了。具有加速网络收敛速度,提升训练稳定性的效果,Batchnorm本质上是解决反向传播过程中的梯度问题。

解决的过程:f2​=f1​(wT∗x+b)对w求导,得到∂f2/∂w​​=∂f2/∂f1​ * ​​x,反向传播式子中有x的存在,所以x的大小影响了梯度的消失和爆炸,batchnorm就是通过对每一层的输出规范为均值和方差一致的方法,消除了x带来的放大缩小的影响,进而解决梯度消失和爆炸的问题,或者可以理解为BN将输出从饱和区拉倒了非饱和区。

3 batch normalization

机器学习领域有个很重要的假设:IID独立同分布假设,就是假设训练数据和测试数据是满足相同分布的,这是通过训练数据获得的模型能够在测试集获得好的效果的一个基本保障。

3.1 BatchNorm的作用是什么呢?

BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布的。(前面也有说到,经过激活函数的非线性变换,会得到一个新的数据分布,作为下一层的输入)

3.2 为什么神经网络在训练开始之前,要对输入的数据做Normalization?

原因在于神经网络学习过程本质上是为了学习数据的分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另一方面,一旦在mini-batch梯度下降训练的时候,每批训练数据的分布不相同,那么网络就要在每次迭代的时候去学习以适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对所有训练数据做一个Normalization预处理的原因。

为什么深度神经网络随着网络深度加深,训练起来越困难,收敛越来越慢?这是个在DL领域很接近本质的好问题。很多论文都是解决这个问题的,比如ReLU激活函数,再比如Residual Network,BN本质上也是解释并从某个不同的角度来解决这个问题的,就是让每一层的数据分布一致,这样网络记忆时,不用去适应新数据分布。

3.3 BatchNorm要解决什么问题?

参考[2]的论文中,讲述了covariate shift的概念:如果ML系统实例集合<X,Y>中的输入值X的分布老是变,这不符合IID假设,网络模型很难稳定的学规律,这不得引入迁移学习才能搞定吗,我们的ML系统还得去学习怎么迎合这种分布变化啊。对于深度学习这种包含很多隐层的网络结构,在训练过程中,因为各层参数不停在变化,所以每个隐层都会面临covariate shift的问题,也就是在训练过程中,隐层的输入分布老是变来变去,这就是所谓的“Internal Covariate Shift”,Internal指的是深层网络的隐层,是发生在网络内部的事情,而不是covariate shift问题只发生在输入层。

随后,提出了BatchNorm的基本思想:能不能让每个隐层节点的激活输入分布固定下来呢?这样就避免了“Internal Covariate Shift”问题了,顺带解决反向传播中梯度消失问题。BN 其实就是在做 feature scaling,而且它的目的也是为了在训练的时候避免这种 Internal Covariate Shift 的问题,只是刚好也解决了 sigmoid 函数梯度消失的问题。

BN不是凭空拍脑袋拍出来的好点子,它是有启发来源的:之前的研究表明如果在图像处理中对输入图像进行白化(Whiten)操作的话——所谓白化,就是对输入数据分布变换到0均值,单位方差的正态分布——那么神经网络会较快收敛,那么BN作者就开始推论了:图像是深度神经网络的输入层,做白化能加快收敛,那么其实对于深度网络来说,其中某个隐层的神经元是下一层的输入,意思是其实深度神经网络的每一个隐层都是输入层,不过是相对下一层来说而已,那么能不能对每个隐层都做白化呢?这就是启发BN产生的原初想法,而BN也确实就是这么做的,可以理解为对深层神经网络每个隐层神经元的激活值做简化版本的白化操作。

3.4 BatchNorm的过程

3.5 BatchNorm在TensorFlow中使用的函数

tensorflow中关于BN(Batch Normalization)的函数主要有两个,分别是:

  • tf.nn.moments
  • tf.nn.batch_normalization
  • tf.layers.batch_normalization
  • tf.contrib.layers.batch_norm

  应用中一般使用 tf.layers.batch_normalization 进行归一化操作。因为集成度较高,不需要自己计算相关的均值和方差。

3.6 BatchNorm的推理(Inference)过程——预测过程

  BN在训练的时候可以根据Mini-Batch里的若干训练实例进行激活数值调整,但是在推理(inference)的过程中,很明显输入就只有一个实例,看不到Mini-Batch其它实例,那么这时候怎么对输入做BN呢?因为很明显一个实例是没法算实例集合求出的均值和方差的。这可如何是好?既然没有从Mini-Batch数据里可以得到的统计量,那就想其它办法来获得这个统计量,就是均值和方差。可以用从所有训练实例中获得的统计量来代替Mini-Batch里面m个训练实例获得的均值和方差统计量,因为本来就打算用全局的统计量,只是因为计算量等太大所以才会用Mini-Batch这种简化方式的,那么在推理的时候直接用全局统计量即可。

  决定了获得统计量的数据范围,那么接下来的问题是如何获得均值和方差的问题。很简单,因为每次做Mini-Batch训练时,都会有那个Mini-Batch里m个训练实例获得的均值和方差,现在要全局统计量,只要把每个Mini-Batch的均值和方差统计量记住,然后对这些均值和方差求其对应的数学期望即可得出全局统计量。

3.7 BatchNorm的好处

  BatchNorm为什么NB呢,关键还是效果好。

①不仅仅极大提升了训练速度,收敛过程大大加快;

②还能增加分类效果,一种解释是这是类似于Dropout的一种防止过拟合的正则化表达方式,所以不用Dropout也能达到相当的效果;

③另外调参过程也简单多了,对于初始化要求没那么高,而且可以使用大的学习率等。

总而言之,经过这么简单的变换,带来的好处多得很,这也是为何现在BN这么快流行起来的原因。

 

参考:

1.深度网络梯度爆炸的原因、产生的影响和解决方法(常用激活函数)

2.论文:https://arxiv.org/abs/1502.03167

3.BN介绍:https://www.cnblogs.com/eilearn/p/9780696.html?tdsourcetag=s_pcqq_aiomsg

4.TF中的BN实现:https://www.cnblogs.com/eilearn/p/9098910.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值