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

本文深入探讨ReLU激活函数的原理,包括解决梯度消失问题及计算优势,同时剖析其缺陷如神经元失活与输出分布偏移。针对ReLU的不足,介绍了BatchNormalization(BN)技术,解释其如何通过标准化层间输入分布,加速网络收敛,提升训练稳定性,并解决内部协变量偏移问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

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这么快流行起来的原因。

-------- 看下面的内容,好像真的明白了BN存在的意义---------

在机器学习领域中,有一个重要的假设:独立同分布假设,也就是假设训练数据和测试数据是满足相同分布的,否则在训练集上学习到的模型在测试集上的表现会比较差。而在深层神经网络的训练中,当中间神经层的前一层参数发生改变时,该层的输入分布也会发生改变,也就是存在内部协变量偏移问题(Internal Covariate Shift),从而造成神经层的梯度消失,模型收敛过慢的问题。

Batch Normalization(BN,批量标准化)就是一种解决内部协变量偏移问题的方法,它通过对神经网络的中间层进行逐层归一化,让每一个中间层输入的分布保持稳定,即保持同一分布。

下面从以下四个方面来深入理解Batch Normalization的原理。

1、内部协变量偏移问题

2、训练时的Batch Normalization

3、推断时的Batch Normalization

4、Batch Normalization的优点

一、内部协变量偏移问题

1、内部协变量偏移问题的产生

在传统机器学习中,一个常见的问题是协变量偏移(Covariate Shift),大致的意思就是数据会随着时间而变化,用旧数据训练好的模型去预测新数据时,结果可能会不准确。输入数据可以看做是协变量,机器学习算法要求输入数据在训练集和测试集上满足同分布,这样把模型用来预测新的数据,才能有较好的结果。

而深层神经网络中的内部协变量偏移(Internel Covarian Shift)可以拆分为“中间”和“协变量偏移”两部分来理解。中间二字指的是神经网络的中间层(隐藏层),协变量偏移则与传统机器学习中的概念类似。在深层神经网络中,中间层的输入也就是前一层的输出,前一层的参数变化会导致该中间层的输入(WU+b)的分布发生较大的差异。在用随机梯度下降来训练网络时,每次参数更新都会导致神经网络中间层的输入分布发生变化。这就会造成同一次迭代时中间层与中间层之间的输入分布不一致,在不同的迭代轮次中同一中间层的输入分布也发生变化。而这就是内部协变量偏移问题。

传统机器学习的协变量偏移问题是源于测试集与训练集中输入分布的不一致,而深层神经网络中的内部协变量偏移问题的含义稍有不同,是不同中间层的输入分布不一致。

那么内部协变量偏移问题又是如何导致梯度消失的呢?

2、内部协变量偏移导致梯度消失

我们换一种说法,深层神经网络在做非线性变换之前的输入值(WU+b)随着网络深度的加深,或者在每一轮迭代中,其分布逐渐发生变动,一般是整体分布逐渐往非线性激活函数的y值区间的上下限两端靠近,从而导致反向传播时底层神经网络的梯度消失,从而使得神经网络收敛得越来越慢。

以sigmoid激活函数来举例,sigmoid函数是个两端饱和函数,也就是输入值(WU+b)是非常大的负值或者非常大的正值时,其导数会接近于0;而当输入值在0附近时,sigmoid函数近似于一个线性函数,导数在0.25以下,但远离0值。下面是sigmoid函数的导数。

首先假设输入值的分布在没有发生改变之前服从标准正态分布,即均值为0,方差为1,那么由概率论的知识可以得到,有95%的概率这个输入值落在[-2,2]的范围内,也就是sigmoid函数接近于线性变换的区域,从上图中目测(简陋点哈哈)导数在(0.1, 0.25)的范围内,因此不会发生梯度消失问题。

然后如果输入值的分布发生了偏移,服从均值为-6,方差为1的正态分布,那么有95%的概率输入值落在[-8, -4]的区间中(均值加减两倍方差),从上图可以看到,sigmoid函数的导数在这个区间上明显趋近于0,也就是落在了梯度饱和区。那么梯度变化就会很小乃至消失。

同样,如果输入值的分布偏移到正态分布的右边,比如服从均值为6,方差为1的正态分布,则sigmoid函数的值接近于1,同样其导数值也趋近于0。

好,明白了内部协变量偏移会导致梯度消失的原理,并且明白了如果输入值的分布满足均值为0,方差为1的条件,那么就可以比较好地解决梯度消失问题,那么一个当然的想法就是,对神经网络的每一个中间层进行标准归一化,把每一个中间层的输入值强行从越来越偏的画风中拉回到又红又专的状态(均值为0,方差为1的标准分布) ,使得输入值落在非线性函数对输入比较敏感的区域。这样就能让梯度保持在比较大的水平,加快学习和收敛的速度。

二、训练时的Batch Normalization

先声夺人,首先说明四点:

第一点是Batch Normalization是基于小批量随机梯度下降(Mini-Batch SGB)的;

第二点是Batch Normalization是放在激活函数之前,可以视为一层;

第三点是Batch Normalization在标准归一化之后,减弱了神经网络的非线性表示,需要附加缩放和平移来变换取值区间;

第四点是由于附加了平移变换(加上一个常数),相当于给神经层加了偏置,因此标准归一化之前的输入值不用再加偏置(本来是WU+b,现在只要WU就行)。

那么,接下来慢慢说明。

1、标准归一化

对每个中间层的神经元的输入值做BN,可以视为在每个中间层之前加上了一个BN层,它位于计算输入值WU(第三点说明了这里不加偏置)之后,进行非线性变换之前。

用小批量梯度下降来训练神经网络,假设batch size是m,在第t层的输入值x=WU的维度是d,也就是一个输入值表示为x = (x(1), x(2),..., x(d)),那么首先对x的每一个维度的值都进行标准归一化:

这个标准归一化的含义是:第t层中第k个神经元(即x的第k个维度)的输入值,减去m个样本在该层的输入值第k个维度的均值E(xk),并且除以其标准差(Var(xk)开方)来进行转换。

要注意的是,本来E(xk)和Var(xk)表示x的第k维度在整个数据集上的期望和方差,可是由于是使用小批量梯度下降算法,所以用m个样本在第k维度的均值和方差来估计。计算的方程如下

2、缩放和平移变换

对输入值x进行标准归一化会使得取值集中在0附近,如果使用sigmoid函数或者tanh激活函数,那么这个取值区间刚好是接近线性变换的区间,这会减弱非线性激活函数的表示能力。因此,为了不让标准归一化对网络的表示能力产生不良影响,就需要附加缩放(scale)和平移(shift)变换来改变标准归一化后值的区间,在一定程度上恢复网络的非线性表示能力。那么每个神经元就会增加两个调节参数

,分别用来进行缩放和平移操作,可以通过训练来学习这两个参数。

有意思的是,这个缩放和平移变换其实是标准归一化的反向操作,当缩放参数为

,平移参数为

时,可以把值恢复到标准归一化之前的值x。

还要因为标准归一化后加了平移变换,相当于在计算输入值时加了偏置,因此在进行标准归一化之前的输入值不需要再加偏置,也就是输入值为WU,而不是WU+b。

那么Batch Normalization的算法流程如下:

当然,得到这个BN操作之后的值yi,后面该干嘛干嘛,把它输入到非线性激活函数中得到该中间层的输出。

三、推断时的Batch Normalization

运用Batch Normalization对输入值进行调整的深层神经网络,在训练阶段,是用小批量梯度下降来进行优化的,也就是每轮迭代都把batch size 个样本喂给模型,通过计算这若干个样本的均值和方差,来进行BN操作。那么在推断(Inference,我觉得测试和预测都算推断吧)阶段,每次只输入一个样本,没有多个样本可以求均值和方差,那么如何对输入值做Batch Normalization呢?

也比较简单,因为幸运的是此时模型已经训练完毕了,那我们可以用整个数据集上的均值μ和方差σ来代替每次小批量样本的均值和方差,然后在推断阶段就使用这两个全局统计量来进行BN操作。

那整个数据集上的均值和方差如何得到呢?这样做,在小批量梯度下降的每轮迭代中,都会输入batch size 个样本,然后得到这些样本的均值和方差,那么每次都把这些样本的均值和方差记录下来。整个数据集都迭代完毕后,再对得到的所有均值和方差求数学期望,就可以得到全局的均值和方差:

用全局的均值和方差来进行标准归一化,就完成了BN操作的第一步。

那么还有第二步啊,对标准归一化后的输入值进行缩放和平移变换。由于在训练阶段结束后,中间层中每个神经元对应的缩放参数γ和平移参数β都已经求出来了,那么就可以直接用来进行变换。由于在推断阶段,无论是样本的均值和方差,还是缩放参数和平移参数都已经是常数了,不再变化了,那么为了计算更快速,就把标准归一化和缩放、平移变换这两步的参数整合到一起,存放起来,当输入新样本时,直接调用就好了。这也就是把公式进行了以下变换:

四、Batch Normalization的优点

1、通过标准归一化,使得输入值的均值为0,方差为1,而不是绝对值非常大的数,就可以大大提升训练速度,加快模型收敛。

2、带有轻微的正则化效果,与Dropout类似。Dropout通过给隐藏层的神经元以一定的概率乘以0或者1,而给隐藏层的激活值增加了噪音。相比之下,BN操作通过对输入值减去均值和进行缩放,也给隐藏层的神经元添加了轻微的噪音。

3、使得调参过程简单了不少。使用梯度下降法对参数进行优化学习时,非常关键的一个问题是如何合理地初始化参数值,为此提出了Xavier初始化和He初始化等方法,而使用BN操作后,对于参数初始化的要求就没那么高了。而且也可以使用大的学习率。

4、使用饱和型激活函数,比如sigmoid函数和tanh函数,也不怕出现梯度消失问题了。

一句话,妈妈再也不用担心我在训练神经网络时出现梯度消失问题啦!

以上这句话是假的,还需要配合其他方法,来得到更好的效果。

参考:

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

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

3.BN介绍:深度学习—BN的理解(一) - 深度机器学习 - 博客园

4.TF中的BN实现:深度学习—BN的理解(二) - 深度机器学习 - 博客园

5.从原理到例子讲解了为什么用BN:深度学习之Batch Normalization - Luv_GEM - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值