# 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]() ---