1 BN快速了解一下
BN有什么用:
- 防止梯度消失/爆炸
- 加快训练速度
- 弱化初始化的影响
- 还有一定的正则化作用
BN都做了啥:
- 将所在层输入的线性变换结果z=wa+b标准化为0均值、单位方差的正态分布$\hat z$
- 将$\hat z$进行一定的调整$\tilde z = \gamma \hat z + \beta$
但是BN到底是什么原理,在看似统一的解释背后却有不少争议。
2 梯度问题
我们都知道,在反向传播时,网络深度的增加会让累乘的梯度造成严重后果:消失或爆炸。非线性激活函数虽然赋予了NN强大的表达能力,但是训练过程的目标是良好分类,于是参数的不断调整使得激活函数的输入会慢慢跑到极端。例如sigmoid和tanh,输入会向左右两侧跑,梯度接近0,传播几次就消失了。
对于ReLU而言,虽然ReLU一定程度上解决了梯度消失问题、简化了梯度计算、提供了一定的稀疏连接避免过拟合,但是在稀疏连接这一点上又有了问题:大梯度反向传播导致更新后梯度为0,“杀死”神经元。适量的杀死神经元相当于dropout起到了正则化作用,但是太多的神经元被杀死就降低了模型的表达能力。
一个朴素的想法就是,如果能让输入分布在非线性激活函数接近线性的位置,梯度就能很好地传播下去。于是对每一层,在线性变换之后、激活函数之前,加上一层BN。对于mini-batch中的样本,上一层的输出a即本层的输入,经线性变换后为z=wa+b,设z的均值为$\mu$,方差为$\sigma$,则将其变换到均值为0、单位方差的正态分布的过程为:
$$
\hat z = \frac{z-\mu}{\sqrt {(\sigma+\epsilon)}}
$$
这一步,就是BN做的第一件事。此时$\hat z$可以保证分布在sigmoid中间区域了,但几乎是线性的,又导致新的问题——非线性不够,模型表达能力不强。所以BN要做第二件事,把上述正态分布再进行反标准化:
$$
\tilde z = \gamma \hat z+\beta
$$
注意到如果$\gamma = \mu,\beta=\sigma$,$\tilde z$就回到了z。但是E(z)和D(z)是受数据影响的,而$\gamma,\beta$是独立的参数,是学习得到的。于是这一步的意义就是根据标准化对结果的影响来调整标准化的程度。
既然多了参数要学习,计算量其实增加了。但是有了BN之后梯度比较好,收敛速度快了很多(深层网络,通常浅层网络用BN起不到什么效果)。
3 Internal Coviarate Shift
梯度的解释是最常见的BN原理的解释,也是最直观的。在提出BN的这篇文章里,挖得更深了些——BN解决了Internal Coviarate Shift(ICS)。
ICS是不一致分布导致的问题。因为一层的参数总是在变化,导致这一层的输出分布发生变化。虽然输入样本会做标准化,但是在隐层是没有标准化操作的,那么在每个mini-batch在隐层中进入下一层的时候分布都是不同的。从这个角度来说,不同的分布导致了不同的优化方向,这样在训练的时候走的路就比较曲折。
每个隐层加BN,就实现了每层标准化。很多人在这里会和数据白化作对比,说BN就是简化改进版的白化加到了隐层。
4 平滑(2018年7月更新)
在一篇2018年5月份的MIT的论文中,研究者却认为BN的成功和减少ICS并没有明确的关系(甚至ICS和训练的表现关系都是不确定的),并提出,BN的原理实际上是将优化问题的解空间变得更加平滑,改善了损失函数和梯度的Lipschitzness从而让梯度更稳定,可以使用大的学习速率。
研究者特意在BN后边加了随机噪声提高ICS,但训练仍然比无BN的好,由此证明BN带来的有效性和ICS没关系。
改善Lipschitzness让损失函数的变化速率变小了,梯度的变化幅值也变小了。这一点理论挺深,我的直观理解是,BN实施的多次变换就像人穿衣服一样,没穿衣服的时候身体形态暴露无遗,一件之后变得平缓,多件衣服足以遮盖一些体态上的问题(这里的体态问题可以理解为解空间中一些不好的区域,比如梯度消失的鞍点、梯度爆炸尖角等)。
文章做了一些实验证实,BN确实降低了参数的灵敏度,也就提高了loss的鲁棒性。