---
# System prepended metadata

title: Batch Normalization(BN)批标准化
tags: [學習紀錄]

---

# Batch Normalization(BN)批标准化
###### tags:  `學習紀錄`


[toc]

---
## Before Meeting
:::success

:::

[refer](http://proceedings.mlr.press/v37/ioffe15.pdf)
[refer](https://github.com/lawlite19/DeepLearning_Python/blob/master/paper/%EF%BC%88BN%EF%BC%89Batch%20Normalization%20Accelerating%20Deep%20Network%20Training%20by%20Reducing%20Internal%20Covariate%20Shift.pdf)
[refer](https://blog.csdn.net/u013082989/article/details/54293279)
[refer](https://blog.csdn.net/qq_30478885/article/details/78816516)
[refer](https://github.com/sty61010/MachineLearning_Python)
[refer](https://github.com/sty61010/DeepLearning_Python)
[refer]()
[refer]()



---

## Recent Paper

---

### Batch Normalization(BN)批标准化

:::success
#### Abstracion
- 2015年Google提出的Batch Normalization
- 训练深层的神经网络很复杂，因为训练时每一层输入的分布在变化，导致训练过程中的饱和，称这种现象为：internal covariate shift
- 需要降低学习率Learning Rate和注意参数的初始化
- 论文中提出的方法是对于每一个小的训练batch都进行标准化（正态化） 
    - 允许使用较大的学习率
    - 不必太关心初始化的问题
    - 同时一些例子中不需要使用Dropout方法避免过拟合
    - 此方法在ImageNet classification比赛中获得4.82% top-5的测试错误率

:::
:::info
#### Detail
- BN思路
- 大家应知道，一般在训练网络的时会将输入减去均值，还有些人甚至会对输入做白化等操作，目的是为了加快训练。为什么减均值、白化可以加快训练呢，这里做一个简单地说明：
    - 首先，图像数据是高度相关的，假设其分布如下图a所示(简化为2维)。由于初始化的时候，我们的参数一般都是0均值的，因此开始的拟合y=Wx+b，基本过原点附近，如图b红色虚线。因此，网络需要经过多次学习才能逐步达到如紫色实线的拟合，即收敛的比较慢。如果我们对输入数据先作减均值操作，如图c，显然可以加快学习。更进一步的，我们对数据再进行去相关操作，使得数据更加容易区分，这样又会加快训练，如图d
    - ![](https://i.imgur.com/oZeUBDR.png)
    - 白化的方式有好几种，常用的有PCA白化：即对数据进行PCA操作之后，在进行方差归一化。这样数据基本满足0均值、单位方差、弱相关性。作者首先考虑，对每一层数据都使用白化操作，但分析认为这是不可取的。因为白化需要计算协方差矩阵、求逆等操作，计算量很大，此外，反向传播时，白化操作不一定可导。于是，作者采用下面的Normalization方法。


- 在深度学习中，随机梯度下降已经成为主要的训练方法。尽管随机梯度下降法对于训练深度网络简单高效，但需要人为的选择一些参数，比如学习率、参数初始化、权重衰减系数、dropout比例等。这些参数的选择对训练结果至关重要，以至于我们很多时间都浪费在这些的调参上。那么学完这篇文献之后，你可以不需要那么刻意的慢慢调整参数。BN算法的强大之处表现在
    - 可以选择比较大的初始学习率，让训练速度飙涨。以前需要慢慢调整学习率，甚至在网络训练到一半时，还需要想着学习率进一步调小的比例，选择多少比较合适，现在我们可以采用初始很大的学习率，然后学习率的衰减速度也很大，因为这个算法收敛很快。当然这个算法即使你选择了较小的学习率，也比以前的收敛速度快，因为它具有快速训练收敛的特性；
    - 你再也不用去理会过拟合中dropout、L2正则项参数的选择问题，采用BN算法后，你可以移除这两项了参数，或者可以选择更小的L2正则约束参数了，因为BN具有提高网络泛化能力的特性；
    - 再也不需要使用局部响应归一化层了，因为BN本身就是一个归一化网络层；
    - 可以把训练数据彻底打乱（防止每批训练的时候，某一个样本都经常被挑选到）。

- 大家知道，在开始训练神经网络前，都要对输入数据做一个归一化处理，那么具体为什么需要归一化呢？归一化后有什么好处呢？原因在于：
    - 神经网络学习过程本质就是为了学习数据分布，如果训练数据与测试数据的分布不同，那么网络的泛化能力也大大降低；
    - 如果每批训练数据的分布各不相同(batch 梯度下降)，那么网络就要在每次迭代都去学习适应不同的分布，这样将会大大降低网络的训练速度。

- 对于深度网络的训练是一个复杂的过程，只要网络的前面几层发生微小的改变，那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变，那么这一层网络就需要去适应学习这个新的数据分布，所以如果训练过程中，训练数据的分布一直在发生变化，那么将会影响网络的训练速度。
- 大家知道，网络在训练的过程中，除了输入层的数据外（因为一般输入层的数据会人为的对每个样本进行归一化），后边各层的输入数据的分布一直在发生变化的。对于中间各层在训练过程中，数据分布的改变称之为internal covariate shift。NP算法就是为了解决在训练过程中，中间层数据分布发生改变的情况下的数据归一化的。

- BN 
- 就像激活函数层、卷积层、全连接层、池化层一样，BN也属于网络的一层。前面提到网络除了输入层外，其它各层因为前层网络在训练的时候更新了参数，而引起后层输入数据分布的变化。这个时候我们可能就会想，如果在每一层输入时，再加个预处理操作，把它归一化至：均值0、方差为1，然后再输入后层计算，这样便解决了前面所提到的Internal Covariate Shift的问题了。事实上，论文中算法本质原理就是这样：在网络的每一层输入的时候，又插入了一个归一化层，也就是先做一个归一化处理，然后再进入网络的下一层。不过文献提到的归一化层，并不像我们想象的那么简单，它是一个可学习、有参数的网络层。

- ![](https://i.imgur.com/TC9GgPu.png)

:::
:::warning
#### Conclusion
- BN在CNN中的使用
    - 通过上面的学习，我们知道BN层是对于每个神经元做归一化处理，甚至只需要对某一个神经元进行归一化，而不是对一整层网络的神经元进行归一化。
    - 既然BN是对单个神经元的运算，那么在CNN中卷积层上要怎么办？假如某一层卷积层有6个特征图，每个特征图的大小是100*100，这样就相当于这一层网络有6*100*100个神经元，如果采用BN，就会有6*100*100个参数γ、β，这样岂不是太恐怖了。因此卷积层上的BN使用，其实也是使用了类似权值共享的策略，把一整张特征图当做一个神经元进行处理
:::
[refer](https://blog.csdn.net/qq_30478885/article/details/78816516)
[refer]()

[refer]()
[refer]()

[refer]()


---
:::success
#### Abstracion
:::
:::info
#### Detail


:::
:::warning
#### Conclusion

:::
[refer]()

---