# Normalization综述

## 为什么需要Normalization

在机器学习领域, 有个很重要的假设, independent and identically distributed(简称**i.i.d.**), 即**独立同分布**. 独立同分布假设**训练数据**和**测试数据**数据是满足相同的分布的. 这是使用训练集训练得到的模型能够在测试集上取得好的效果的基础. 满足立同分布的数据能够简化模型训练, 提升模型学习能力, 基本已是共识.

但对于数据$$(X,Y)$$, $$X$$的分布一直在变化, 而不再满足独立同分布的约束, 这种问题就被称为**covariate shift**. 这样学习到的模型在面对不断变化的输入时, 得到的预测结果会很差.

这种问题不止产生在训练和测试阶段分布不一致时, 在训练阶段, 对于由很多层组成的深度学习模型, 每层的参数变化都会该层的输入分布一直变化, 每一层都面临着covariate shift问题. 由于这种问题发生在网络内部的隐层上, 因此被称为**Internal Covariate Shift**问题.

每个隐层的输入数据的分布一直变化, 经过层层叠加, 导致高层的输入分布变化非常剧烈, 迫使高层需要不断地适应底层的参数更新.

ICS导致**每个神经元**的输入不再是独立同分布的, 造成:

* 高层参数需要不断适应新的输入数据分布, 降低训练速度
* 低层输入的变化可能趋向于变大或者变小, 导致高层落入饱和区, 使得学习过早停止, 甚至没有收敛
* 每层的更新都会影响到其它层, 因此每层的参数更新策略需要尽可能的谨慎

简单来说, 会导致网络收敛速度慢, 甚至难以收敛. 而且得到的模型能力也受到影响.

Normalization就是要解决ICS的问题, 使得**每个隐层神经元节点的激活输入分布相对固定下来**.

## Normalization的本质思想

### 启发

Normalization的思路源自图像预处理中常用的操作, **白化**(Whiten). 所谓白化, 即将输入数据处理成均值为0, 方差为单位方差, 经过白化处理后的网络一般收敛更快.

以这种思想为引导, 能不能对每一层的输入都做白化, 从而消除偏移, 加速收敛.

### 表现

以一个神经元为例, 它输入向量为$$\mathbf{x}=\left(x\_{1}, x\_{2}, \cdots, x\_{d}\right)$$, 经过该层的参数作用后, 即$$z=f(\mathbf{x})$$, 得到非线性变换激活函数的输入值, 这就是我们所说的输入值. 由于训练过程中参数的不断变化, 以及网络的加深, $$z$$的分布逐渐发生偏移或者变动. Normalization的思路就是在将输入传入到激活函数之前, 先对其做**平移和伸缩变换**, 将$$z$$的分布规范化为具有固定的均值和方差, 一般会使之趋近于标准正态分布.

将一层神经元的输入向量记为$$\mathbf{z}$$, 则Normalization的思路可以表示为, 其中的$$\mu$$, $$\sigma$$, $$\mathbf{g}$$, $$\mathbf{b}$$都是向量:

$$h=f\left(\mathbf{g} \cdot \frac{\mathbf{x}-\mu}{\sigma}+\mathbf{b}\right)$$

前面说过每个神经元的输入分布变化, 会导致训练速度缓慢. 这一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近, 导致后向传播时低层神经网络的梯度消失. 而Normalization将输入的分布拉回到接近正态分布, 使得激活函数的输入分布在梯度较大的部分, 避免了梯度消失, 从而加快了收敛. 这也是**Normalization能使训练加快的根本原因**.

### 缩放与还原

上面的式子中, 有好理解的平移参数$$\mu$$和缩放参数$$\sigma$$. 但还有着**再平移参数**$$\mathbf{b}$$和**再缩放参数**$$\mathbf{g}$$, 使得最终分布的均值和方差由这两个参数决定.

这是因为, 如果把整个神经网络的每一层, 层中的每一点的输入都统一成**全局一致**的确定范围, 无论前面的层如何学习, 到了下一层, 其输入都会是一致的, 即前面层的学习毫无意义. 甚至对于`sigmoid`这种在0附近是线性函数的激活函数, 网络的每一层都退化层线性计算, 则网络的深度也就没了意义, 整个网络退化层单一层的线性函数模型.

因此, 对于每一层, 层中的每个神经元, 都会由**再平移参数**和**再缩放参数**调整最终的偏移缩放量. 这个参数是在训练过程中学习到的, 使得每个神经元都能够学习到独特的知识, 表现出不同的形式, 保护了**非线性**能力, 同时又保证了其输入不会随着输入的变化而发生大的变化.

## Normalization原理再探讨

以上在说Normalization有效的原因在于能够缓解**Internal Covariate Shift**问题, 但\[How Does Batch Normalization Help Optimization?][https://arxiv.org/abs/1805.11604)这篇论文否定了Normalization在于解决ICS问题](https://arxiv.org/abs/1805.11604\)%E8%BF%99%E7%AF%87%E8%AE%BA%E6%96%87%E5%90%A6%E5%AE%9A%E4%BA%86Normalization%E5%9C%A8%E4%BA%8E%E8%A7%A3%E5%86%B3ICS%E9%97%AE%E9%A2%98), 而是因为起到了**平滑损失平面**的作用, 平滑的损失平面加快了收敛速度.

![](https://3713032588-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LUx2ALWjDXrP_paswc_%2F-M1ppjEeSZrYQSN5Ks16%2F-M1ppl1rZkys8s9ObKf_%2Fv2-eced33baa7d8e7cc410ac12f7818463b_720w.jpg?generation=1583598738240019\&alt=media)

作者证明了在经过Batch Normalization处理后, 损失函数满足Lipschitz连续, 即**损失函数的梯度小于一个常量**, 因此网络的损失平面不会震荡的过于严重. 而且损失函数的梯度也满足Lipschitz连续, 也称为$$\beta$$平滑, 即斜率的斜率也不会超过一个常量.

作者认为当着两个常量的值均比较小的时候, 损失平面就可以看做是平滑的. BN收敛快的原因是由于**BN产生了更光滑的损失平面**.

## 主流Normalization

* [Batch Normalization](https://blessbingo.gitbook.io/garnet/shen-jing-wang-luo/normalization/batch-normalization)
* [Layer Normalization](https://blessbingo.gitbook.io/garnet/shen-jing-wang-luo/normalization/layer-normalization)
* Instance Normalization
* Group Normalization
