关于Batch Normalization的理解和认识

1 前言

Batch Normalization作为最近几年来DL的重要成果,已经广泛被证明其有效性和重要性。目前几乎已经成为DL的标配了,任何 有志于学习DL的同学们朋友们都应该好好学一学BN。BN倒过来看就是NB,因为这个技术确实很NB,虽然有些细节处理还解释不清其理论原因,但是实践证明好用才是真的好,别忘了DL从Hinton对深层网络做Pre-Train开始就是一个经验领先于理论分析的偏经验的一门学问,如何理解BatchNorm?请参考论文:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

机器学习领域有个很重要的假设:IID(独立同分布)假设–就是假设训练数据和测试数据是满足相同分布的,这是通过训练数据获得的模型能够在测试集获得好的效果的一个基本保障。而BatchNorm是干啥的呢?BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布的

2 提出Batch Normalization的原因

2.1 面临的问题

根据上面的参考论文,BN是用来解决“InternalCovariate Shift”问题的,那“InternalCovariate Shift”是什么呢?

网络训练过程中参数不断改变导致后续每一层输入的分布也发生变化,而学习的过程又要使每一层适应输入的分布,因此我们不得不降低学习率、小心地初始化。作者将分布发生变化称之为 internal covariate shift,也就是说,如果ML系统实例集合<X,Y>中的输入值X的分布老是变,这不符合机器学习中IID假设。

对于深度学习这种包含很多隐层的网络结构,在训练过程中,因为各层参数老在变,所以每个隐层都会面临covariate shift的问题,也就是在训练过程中,隐层的输入分布老是变来变去,这就是所谓的“Internal Covariate Shift”,Internal指的是深层网络的隐层,是发生在网络内部的事情,而不是covariate shift问题只发生在输入层。

2.2 灵感来源

之前就有研究表明如果在图像处理中对输入图像进行白化(Whiten)操作的话——所谓白化,就是对输入数据分布变换到0均值,单位方差的正态分布——那么神经网络会较快收敛。为什么减均值、白化可以加快训练呢,这里做一个简单地说明。

首先,图像数据是高度相关的,假设其分布如下图a所示(简化为2维)。由于初始化的时候,我们的参数一般都是0均值的,因此开始的拟合y=Wx+b,基本过原点附近,如图b红色虚线。因此,网络需要经过多次学习才能逐步达到如紫色实线的拟合,即收敛的比较慢。如果我们对输入数据先作减均值操作,如图c,显然可以加快学习。更进一步的,我们对数据再进行去相关操作,使得数据更加容易区分,这样又会加快训练,如图d。
在这里插入图片描述
白化的方式有好几种,常用的有PCA白化:即对数据进行PCA操作之后,在进行方差归一化。这样数据基本满足0均值、单位方差、弱相关性。

那么BN作者就开始推论了:图像是深度神经网络的输入层,做白化能加快收敛,那么其实对于深度网络来说,其中某个隐层的神经元是下一层的输入,意思是其实深度神经网络的每一个隐层都是输入层,不过是相对下一层来说而已,那么能不能对每个隐层都做白化呢?这就是启发BN产生的原初想法,而BN也确实就是这么做的,可以理解为对深层神经网络每个隐层神经元的激活值做简化版本的白化操作。

为什么做的简化版的白化操作?因为作者首先考虑,对每一层数据都使用白化操作,但分析认为这是不可取的。因为白化需要计算协方差矩阵、求逆等操作,计算量很大,此外,反向传播时,白化操作不一定可导。

于是,作者采用下面的Normalization方法——通过对每层加权和进行标准化,然后再通过缩放平移来“适度还原”。这样,做到了既不过分破坏输入信息,又抑制了各batch之间各位置点像素分布的剧烈变化带来的学习难度。

3 现在开始讲原理

3.1 BN本质思想

BN的基本思想其实很简单:
因为深层神经网络在做非线性变换前的激活输入值(就是那个x=WU+B,U是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这导致后向传播时低层神经网络的梯度消失,这是训练深层神经网络收敛越来越慢的本质原因。

而BN就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度。

那么把激活输入x调整到这个正态分布有什么用?

首先我们看下均值为0,方差为1的标准正态分布代表什么含义:
在这里插入图片描述
这意味着在一个标准差范围内,也就是说64%的概率x其值落在[-1,1]的范围内,在两个标准差范围内,也就是说95%的概率x其值落在了[-2,2]的范围内。那么这又意味着什么?我们知道,激活值x=WU+B,U是真正的输入,x是某个神经元的激活值,假设非线性函数是sigmoid,那么看下sigmoid(x)其图形:
sigmoid
及sigmoid(x)的导数为:G’=f(x)*(1-f(x)),因为f(x)=sigmoid(x)在0到1之间,所以G’在0到0.25之间,其对应的图如下:
在这里插入图片描述
假设没有经过BN调整前x的原先正态分布均值是-6,方差是1,那么意味着95%的值落在了[-8,-4]之间,那么对应的Sigmoid(x)函数的值明显接近于0,这是典型的梯度饱和区,在这个区域里梯度变化很慢,为什么是梯度饱和区?请看下sigmoid(x)如果取值接近0或者接近于1的时候对应导数函数取值,接近于0,意味着梯度变化很小甚至消失。而假设经过BN后,均值是0,方差是1,那么意味着95%的x值落在了[-2,2]区间内,很明显这一段是sigmoid(x)函数接近于线性变换的区域,意味着x的小变化会导致非线性函数值较大的变化,也即是梯度变化较大,对应导数函数图中明显大于0的区域,就是梯度非饱和区。

3.2 BN算法流程

数据归一化(Normalization via Mini-Batch Statistics)方法很简单,就是要让数据具有0均值和单位方差,如下式:
image.png

但是作者又说如果简单的这么干,会降低层的表达能力。比如下图,在使用sigmoid激活函数的时候,如果把数据限制到0均值单位方差,那么相当于只使用了激活函数中近似线性的部分,这显然会降低模型表达能力。
image.png

为此,作者又为BN增加了2个参数,用来保持模型的表达能力,于是最后的输出为:
在这里插入图片描述
上述公式中用到了均值E和方差Var,需要注意的是理想情况下E和Var应该是针对整个数据集的,但显然这是不现实的。因此,作者做了简化,用一个Batch的均值和方差作为对整个数据集均值和方差的估计。整个BN的算法如下:
在这里插入图片描述

实际测试网络的时候,我们依然会应用下面的式子:
在这里插入图片描述

  • 特别注意: 这里的均值和方差已经不是针对某一个Batch了,而是针对整个数据集而言。

因此,在训练过程中除了正常的前向传播和反向求导之外,我们还要记录每一个Batch的均值和方差,以便训练完成之后按照下式计算整体的均值和方差:
在这里插入图片描述
那到底改把BN放在哪儿呢?作者在文章中说应该把BN放在激活函数之前,这是因为Wx+b具有更加一致和非稀疏的分布。但是也有人做实验表明放在激活函数后面效果更好。这是实验链接,里面有很多有意思的对比实验:https://github.com/ducha-aiki/caffenet-benchmark

3.3 在具体的网络中详细说明BN

3.3.1 原始神经网络的结构

一个经典的神经网络,它的某一个隐层如图所示。
在这里插入图片描述
为了和原始论文统一,将之前常见的加权和符号 z ⃗ \vec{z} z 改用 x ⃗ \vec{x} x 表示。即上一层输出的激活值为 a ⃗ \vec{a} a ,那么经过本层加权和 W a ⃗ + b ⃗ W\vec{a}+\vec{b} Wa +b 处理后,获得加权和 x ⃗ \vec{x} x ,然后经过本层激活后即输出 σ ( x ⃗ ) \sigma(\vec{x}) σ(x )

3.3.2 加入BN的神经网络

加入BN之后的网络结构如图所示
在这里插入图片描述

总体上来说,对于本层的加权和 x ⃗ \vec{x} x ,BN先进行标准化求出 x ⃗ ^ \hat{\vec{x}} x ^,再进行缩放和平移求出 y ⃗ \vec{y} y ,这个 y ⃗ \vec{y} y 取代了原始的 x ⃗ \vec{x} x 进行激活,关键就是标准化、缩放平移这两个环节。

3.3.3 BN的前向传播

认识BN的困难在于维度太多了!大脑里至少能联想到三个维度:batch_size维度(时间顺序维度)、网络层维度(结构横向维度)、向量维度(结构纵向维度)。

所以,当你了解加入BN的神经网络的结构图,那么下图里用一个究极简明的例子,说明了BN到底在干啥,如果完全理解了下图中的内容,后面关于标准化、缩放平移只需要扫一眼黑体字即可。
在这里插入图片描述

(1) 标准化:
标准化即对一组数据中的每个数字,减均值再除以标准差(给方差开个根号),就可把一个该组数据转换为一个均值为0方差为1的标准正态分布。

Batch Normalization的数据组的构造方法:一个batch上所有m个样本分别进行前向传播时,传到这个隐层时所有m个 x ⃗ \vec{x} x 的每个维度,分别构成一个数据组。

在原始论文里,用下标B指的正是一个batch(也就是我们常说的mini-batch),包含m个样本。这也就是为啥叫Batch Normalization的原因。

  • 对这m个 x ⃗ \vec{x} x ,在每一个维度上标量们,分别求均值和方差。
  • 得到的均值 μ \mu μ和方差 σ 2 \sigma^2 σ2分别对应该层的每个神经元维度。

只要我们求得均值 μ \mu μ和方差 σ 2 \sigma^2 σ2,就可以进行标准化了:

x i ^ = x i − μ σ 2 \hat{x_{i}}=\frac{x_{i}-\mu}{\sqrt{\sigma^2}} xi^=σ2 xiμ

为避免分母为0的极端情况,工程上可以给分母增加一个非常小的小数 ϵ \epsilon ϵ(例如 1 0 − 8

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值