Dropout和Batch Norm都是在深度学习中经常用到的方法,可以有效防止过拟合,增加模型的鲁棒性,提升训练效率。今天和大家分享Dropout和Batch Norm的相关内容。
1.Dropout
Dropout通俗理解就是,在神经网络训练的时候,有时因为神经元过多,模型参数过多等原因而导致过拟合,dropout以概率p让一部分神经元失活,从而达到降低过拟合的效果。如下图所示,使用dropout后,一部分神经元不参与训练。
- 在前向传播时,假设有这一层n个神经元,则我们可以假设每个神经元的概率都是0~1(可以通过python得到随机的值),然后小于p的就失活,即不参与训练。
- 在反向传播时,也只对参与训练的神经元进行参数更新。
- 每次训练的时候,又是n个神经元,重新进行dropout
2.Dropout缓解过拟合的原因
1.类似bagging,采用dropout,使得每次训练的时候一部分神经元失活,从而导致dropout后的模型都是不一样的,因为失活的神经元不一样。这就相当于有多个网络进行训练得到最终结果,有点ensemble的感觉。
2.因为dropout程序导致两个神经元不一定每次都在一个dropout网络中出现。这样权值的更新不再依赖于有固定关系的隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况 。迫使网络去学习更加鲁棒的特征 ,这些特征在其它的神经元的随机子集中也存在。换句话说假如我们的神经网络是在做出某种预测,它不应该对一些特定的线索片段太过敏感,即使丢失特定的线索,它也应该可以从众多其它线索中学习一些共同的特征。从这个角度看dropout就有点像L1,L2正则,减少权重使得网络对丢失特定神经元连接的鲁棒性提高。
3.Batch Norm
Batch Norm的提出是为了解决内部协变量偏移(Internal Covariate Shift),即随着参数的不断更新,每一层的输出数据的分布是不断变化的,导致后一层需要重新去拟合新的分布,导致网络学习困难。因此在没有BN的时候,需要采用较小的学习率,缓慢更新,因此学习效率比较低。
使用BN之后,可以采用较大的学习率加快收敛,收敛过程会更加稳定,并且对初始值也不会特别敏感。
那么问题已经摆在那了,是分布在不断变化导致,因此最直接的方式就是在每一层输出后将其归一化为均值为0,方差为1的标准正太分布,但是这会导致每一层的分布都是一样的,从而网络学不到数据中的真正信息。因此作者提出了BN,BN就是在做归一化的时候加入可训练参数,使得每一层的输出的分布差别不大,但是又有属于自身的特性。公式如下,其中k表示第k层,使用BN之后对已经归一化的分布做平移和缩放,平移和缩放分别靠β和γ实现。
- γ和β可以为被一层定制一个自己的分布。
- 如果直接使用均值为0,方差为1的标准正太分布,此时如果使用tanh和sigmoid这类激活函数的话,会使得的部分数据集中在0附近的线性区域,非线性能力减弱,添加γ和β之后可以增强非线性能力。
4.BN和Dropout训练和测试时的差异
4.1 Batch Nrom
对于BN,在训练时,是对每一批的训练数据进行归一化,即用每一批数据的均值和方差。
而在测试时,比如进行一个样本的预测,就并没有batch的概念,因此,这个时候用的均值和方差是全量训练数据的均值和方差,这个可以通过移动平均法求得。
对于BN,当一个模型训练完成之后,它的所有参数都确定了,包括均值和方差,γ和β。
4.2 BN训练时为什么不用全量训练集的均值和方差呢?
因为用全量训练集的均值和方差容易过拟合,对于BN,其实就是对每一批数据进行归一化到一个相同的分布,而每一批数据的均值和方差会有一定的差别,而不是用固定的值,这个差别实际上能够增加模型的鲁棒性,也会在一定程度上减少过拟合。
也正是因此,BN一般要求将训练集完全打乱,并用一个较大的batch值,否则,一个batch的数据无法较好得代表训练集的分布,会影响模型训练的效果。
4.3 Dropout Dropout是在训练过程中以一定的概率的使神经元失活,即输出为0,以提高模型的泛化能力,减少过拟合。而在测试时,应该用整个训练好的模型,因此不需要dropout。
4.4 Dropout 如何平衡训练和测试时的差异呢?
Dropout ,在训练时以一定的概率使神经元失活,实际上就是让对应神经元的输出为0。假设失活概率为p ,就是这一层中的每个神经元都有p的概率失活,如图1的三层网络结构中,如果失活概率为0.5,则平均每一次训练有3个神经元失活,所以输出层每个神经元只有3个输入,而实际测试时是不会有dropout的,输出层每个神经元都有6个输入,这样在训练和测试时,输出层每个神经元的输入和的期望会有量级上的差异。
因此在训练时还要对第二层的输出数据除以(1-p)之后再传给输出层神经元,作为神经元失活的补偿,以使得在训练时和测试时每一层输入有大致相同的期望。
不同层的顺序关系
conv pooling bn 激活函数,由于一开始使用的是sigmoid这类激活函数,因此放在激活函数之前可以较好的保持非线性。但是,后面又提出了ReLU,因此现在也有放在激活函数之后的。
linear dropout
参考:
https://blog.csdn.net/program_developer/article/details/80737724
https://www.zhihu.com/question/356571056
https://blog.csdn.net/songyunli1111/article/details/89071021
《百面深度学习》