参考博客
大神链接:
1、https://blog.csdn.net/weixin_44791964?type=blog
2、https://www.jianshu.com/p/b05282e9ca57
背景
Batch Normalization论文是2015年深度学习领域,超级火的一篇论文,论文的全称为《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》
原文链接如下:
链接一https://arxiv.org/abs/1502.03167v3
链接二http://proceedings.mlr.press/v37/ioffe15.pdf
在BN算法出现之前,当前深度学习网络虽然发展迅速,但也面临着参数过多,类似于学习率、参数初始化、权重衰减系数、Drop out比例等,都是需要人为的去选择参数,经常需要大量的时间进行调参,BN算法帮助人们加速这一过程,使得在各类超参的选择上不需要那么多精力。
前景知识
为了减小数据值的大小,也为了保留数据的分布特征,减少网络对不同批次数据分布类型的依赖,我们一般对数据进行归一化处理。当我们将数据输入神经网络时,归一化操作已成为标准操作。
尽管我们在将数据发送到神经网络之前对数据进行了归一化,但后续的神经节点并未进行归一化。虽然我们有各种激活函数来使网络非线性,防止网络节点的输出过大,但是网络的深度训练是一个复杂的过程。只要网络的前几层稍有变化,后面的几层就会积累和扩大。一旦网络某一层的输入数据分布发生变化,那么该层网络需要适应学习这个新的数据分布,所以如果训练数据的分布在训练过程中不断变化,就会影响网络.训练速度。
也就是因为神经网络中间层之间没有进行数据的归一化,所以每次的数据分布在训练过程中都不一样,会很大的影响下一层的输出的数据分布,直接会影响到参数的训练过程,我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。对Google提出的“Internal Covariate Shift”的理解可以参考这个。
那么解决这个问题的方法是什么?
即对中间层也进行数据归一化操作,使得中间层输出的数据分布比较稳定。说起来好像挺容易的,是不是归一化操作,很简单,但是实现起来没那么容易,看这篇文章之前的文章,但是没有人实现过。原因是:如果对中间层的数据逐渐使用现有的归一化方法,会强行改变数据的分布结构,有一种强行将所有数据扭曲成分布模式的感觉。
比如强行变成均值为零、标准差为1的分布。这样的话,会影响到下一层网络可以学习到的东西,无论上一层网络给啥,归一化之后都一样,下一层还学啥,直接摆烂了。
所以我们需要一种算法,能够对中间层数据进行归一化,且最大程度上保留数据的分布特征。我们的厉害的BN算法横空出世(BN算法NB)。
BN算法原理
将BN算法之前,我们还需要了解一种归一化算法–白化算法,这个算法在论文中也有提及到。
美白算法:
白化的目的是去除输入数据中的冗余信息。假设训练数据是一张图像,由于图像中相邻像素之间的强相关性,在用于训练时输入是冗余的;白化的目的是减少输入的冗余。
输入数据集X,经过白化处理后,新的数据X’满足两个性质:
(1)特征之间相关性较低;相当于PCA过程。
(2)所有特征具有相同的方差。
具体公式:
从公式可以看出来,它需要公式一计算协方差矩阵Cov[x],以及产生白花激活的公式二,以及这些变换的导数用于反向传播。要进行完上述的所有过程,我们需要计算的数据量十分的大,这促使我们寻求一种替代方法,以一种可微分的方式执行输入规范化,并且不需要在每次参数更新后分析整个训练集。
为了减少计算量,方便后向计算,论文作者只使用如下公式进行预处理,即近似白化预处理:
训练过程中采用batch 随机梯度下降,上面的指的是每一批训练数据神经元的平均值;然后分母就是每一批数据神经元激活度的一个标准差了。
但是,直接这样做会迫使数据的分布特征为同一类型。为了解决这个问题,作者提出了一个开创性的想法,如下:
其中和;
每个神经元都会有一对这样的参数,。这样做的目的是使归一化后的数据特征的分布特征由数据本身决定,并有可能恢复原来学习到的层。有特色的。
这完美地解决了如何对数据进行归一化和最大程度地不改变数据的分布特征这两个问题。
该算法的具体计算过程在论文中给出如下:
也就是主要分为四个步骤,也就是我们上面提到的步骤:
从步骤可以知道,它是一种小批量的训练方法。
1、计算每一批次的输入数据的平均值。
2、利用步骤一所求得的平均值进行输入数据方差的求取。
3、步骤三中所用的公式和我们上述公式三不一样的地方是加上了。是一个极小值,是为了防止方差为零、或者无线接近于零的情况发生,使得结果无限大的情况发生。
4、利用公式四进行消除归一化所带来的标准化的影响,也可以说是反标准化的一步。
至此,基本的BN的算法就这么多,但是我们上述的是针对于每一批的小样本来说,我们训练完了我们的模型之后,输入很有可能的是单个样本,那个时候我们该如何计算平均值和方差呢?
论文中的方法是:
在训练结束后,参数都是固定化的,BN的参数也是固定化了。一旦固定化,就要有一个确切的值,论文中的最终BN阶段的平均值和方差来自于所有训练样本的平均值和方差,也就是所有小批次的平均值和方差。
具体公式如下:
对于均值来说直接计算所有batch的平均值:
对于标准偏差采用每个batch的无偏估计:
最后测试阶段,BN的使用公式就是:
以上就是BN算法的大致思想和步骤。具体内容,可以深入阅读一下文章。
BN算法的优点
1、Batch Normalization 对每层数据规范化后,可以使用更高的学习率(因为不加以规范之前,每层的数据的分布特性复杂,采用较高学习率容易不收敛),所以网络训练时可以设置较高的初始学习率,加快收敛。
2、你再也不用去理会过拟合中drop out、L2正则项参数的选择问题,采用BN算法后,可以选择更小的L2正则约束参数了,因为BN具有提高网络泛化能力的特性;也不需要使用使用局部响应归一化层了,因为BN本身就是一个归一化网络层;
3、防止过拟合。在网络的训练中,Bn使得一个minibatch中所有样本都被关联在了一起,因此网络不会从某一个训练样本中生成确定的结果,这样就会使得整个网络不会朝这一个方向使劲学习。一定程度上避免了过拟合。
4、防止梯度爆炸和梯度消失,因为规范化之后,数据较为标准,在各个点的梯度都不会过大或者过于小,
BN的代码实现
代码可以参考这里和这里
代码为Pytorch实现的,和上面公式很贴切
版权声明:本文为博主浅冲一下原创文章,版权归属原作者,如果侵权,请联系我们删除!
原文链接:https://blog.csdn.net/To_be_little/article/details/123133744