今天主要想写一下DeepLearning 中BatchNorm,文章主要主要的大纲为:
- BN 什么
- 为什么提出BN
- BN 的具体细节是什么
- BN 的改进
- BN数学表达式
- BN的训练和预测
- 总结
BN 是什么
BN 是Batch Normalization 的缩写,是近年来DN的重要成果。如果想说BN是什么必须要先提一下机器学习中重要的IID假设: IID 独立同分布假设,假设的具体含义为:训练数据和测试数据是满足了相同的分布,这样通过训练数据获得的模型在测试集才能获得很好的效果。BN 就是在深层神经网络中使得每一层的输入都保持相同的分布。
为什么提出BN
回答这个问题必须先要回答为什么对于深层神经网络难以训练?。在DL领域中有很多方法都是为了解决这个问题比如:更换激活函数、RestNet等等。
首先,先解释一下 Internal Covariate Shift 问题
Internal Covariate Shift
引用BN 作者说法,Mini-batch SGD 相比于 One Example SGD有两大有点:
- 可以更加把梯度计算的更加准确,这个从训练时反应就可以看出
- 可以使用并行计算,加快训练速度
但是 SGD 存在着一个问题,那就是其超参数很难调整。
是什么倒是原因导致了学习效率差呢?假设在ML系统中有一组输入数据<X,Y>,如果其输入X 的特征分组总是变化,这样就不满足开头说的IID假设了,这就会导致网络非常不稳定。在深度学习模型中,当有很多隐藏层时,各个隐藏测分布就会不断发生变化,这就是所谓的“Internal Covariate Shift"。Internal 就是针对隐藏层而言。
BN的提出
正是有Internal Covariate Shift 问题,能不能让每一层激活函数的输入分布固定下来呢?
其实在CV领域就给出了答案,在CV中为了使输入数据分布固定在均值为0 ,方差为1 的标准正态分布,就采用了所谓的白化(Whiten)操作。BN的灵感也就来源与此。
BN其实就神经网络中每一层都进行了白化操作,具体来说BN就是:对深层神经网络的每一个隐藏层在进行激活函数之前都把输入强制捞回到均值为0,方差为1 的正态分布。这样经过BN后每一层的输入都会保持了相同的分布。也就解决了Internal Covariate Shift 问题。
BN 的具体细节是什么
BN的操作非常直观,因为在深层网络在做非线性激活函数的输入,随着网络深度的加大,其分布逐渐发生便宜。DL训练慢,一般情况下其整体分布逐渐向非线性函数取值区间的上下域靠近。这样就导致了梯度消失(这才是DL收敛速度慢的根本原因)。
BN就是通过一定的规范化手段,把每层神经网络任意神经元输入值的强行拉回标准正态分布。在这里就需要详细的说明一下了。
进行BN的时机是什么时候?
正如前文所述,之所以要进行BN操作,是为了使得每个隐藏层中每个神经元都具有相同的分布,满足IID假设。所以我们在进行时机也就比较清楚了,就是在非线性变换之前。比如某个神经元计算公式为: ,并非对X 进行BN操作,而是对 的结果进行BN,即:。
BN操作后有什么实质作用
现在他们通过BN把激活函数的输入强制为均值为0 ,方差为1 的正态分布了。但是这样的操作会产生什么样的效果,有为什么会有这样的效果呢?
先回答第一个问题:如果我们把激活函数的输入强制为标准正态分布,直接解决了 Internal Covariate Shift 问题,还解决了深度神经网络的梯度消失问题,提高网络训练效率。
正所谓知其然还要知其所以然,为什么会有这样的效果呢?
我们先做这样的假设,假设网络中某个神经元采用的Sigmod激活函数,熟悉DL的同学都很清楚,Sigmod 函数和梯度的公式如下:
Sigmod 和对应导数图形如下图:
从上面图形可以观察到如下结论
- 从Sigmod 图形得到,Sigmod 取值范围为[0,1]
- Sigmod 导数图形得到,Sigmod 值在0.5时,导数取得最大值
- Sigmod 在两个端点时(0,1),对应导数值几乎为0
也就是说对于Sigmod 函数,当X在[-2,2]之间学习效率是最好的,此时对应的梯度非常大。X有轻微的变化,就会存在很大的梯度
如果此时非线性函数输入分布为N(-6,1) 时,则95%的值会落在[-8,-4],这些值的梯度几乎为0,也就是说参数几乎不会发生变化,而如果我们把输入分布强制设置为N(0,1)时,此时95% 数值都会落在[-2,2]之间。此时梯度是很大的。
所以,经过BN操作之后,就避免了DL 中梯度消失问题,加快了收敛速度。
改进BN
通过上文我们知道了,经过BN后把大部分输入都落在激活函数的线性区域内,让他们具有了很大的梯度,提高了收敛速度。
但是,我们知道如果把所有输入都经过线性变换,不管网络有多深,其实仍然是一个线性模型。这样整个网络的表达能力就下降了。所以BN为了保持非线性表达特点,在BN操作后,做了Scale和Shift 操作。具体作为如下公式:
公式中: 表示经过BN操作后的结果,进行了简单变换而 则对结果进行了平移。参数都是需要学习的参数。
BN数学表达式
说了这么多,BN的数学表达式应该是什么样呢?其实这对学过概率论的同学都是非常简单的。BN其实就是一个归一化操作
经过调整后的BN为:
BN的训练和预测
BN的训练过程还是比较清洗的
1. 计算每一个Batch 的均值和方差
2. 将每个一个输入(非线性的输入)x ,进行归一化运算
3. 对每个归一化的 x 进行调整
从训练的流程看,BN是需要计算当前批次数据的均值与方差,但是在预测阶段可能只有一个数值,如何计算均值与方差呢? 其实BN在预测阶段,是将训练时每个Mini-Batch的 记住,之后求他们最终的数学期望。
总结
- BN 解决 Internal Covariate Shift 问题
- BN 解决了梯度消失问题,加快了收敛速度