深度学习正则化
偏差和方差
数据集划分
首先我们对机器学习当中涉及到的数据集划分进行一个简单的复习
- 训练集(train set):用训练集对算法或模型进行训练过程;
- 验证集(development set):利用验证集(又称为简单交叉验证集,hold-out cross validation set)进行交叉验证,选择出最好的模型;
- 测试集(test set):最后利用测试集对模型进行测试,对学习方法进行评估。
在小数据量的时代,如 100、1000、10000 的数据量大小,可以将数据集按照以下比例进行划分:
- 无验证集的情况:70% / 30%
- 有验证集的情况:60% / 20% / 20%
而在如今的大数据时代,拥有的数据集的规模可能是百万级别的,所以验证集和测试集所占的比重会趋向于变得更小。
- 100 万数据量:98% / 1% / 1%
- 超百万数据量:99.5% / 0.25% / 0.25%
以上这些比例可以根据数据集情况选择。
偏差与方差的意义
“偏差-方差分解”(bias-variance decomposition)是解释学习算法泛化性能的一种重要工具。
泛化误差可分解为偏差、方差与噪声,泛化性能是由学习算法的能力、数据的充分性以及学习任务本身的难度所共同决定的。
- 偏差:度量了学习算法的期望预测与真实结果的偏离程度,即刻画了学习算法本身的拟合能力
- 方差:度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动所造成的影响
- 噪声:表达了在当前任务上任何学习算法所能够达到的期望泛化误差的下界,即刻画了学习问题本身的难度。
那么偏差、方差与我们的数据集划分到底有什么关系呢?
- 1、训练集的错误率较小,而验证集/测试集的错误率较大,说明模型存在较大方差,可能出现了过拟合
- 2、训练集和测试集的错误率都较大,且两者相近,说明模型存在较大偏差,可能出现了欠拟合
- 3、训练集和测试集的错误率都较小,且两者相近,说明方差和偏差都较小,这个模型效果比较好。
所以我们最终总结,方差一般指的是数据模型得出来了,能不能对未知数据的扰动预测准确。而偏差说明在训练集当中就已经误差较大了,基本上在测试集中没有好的效果。
所以如果我们的模型出现了较大的方差或者同时也有较大的偏差,该怎么去解决?
解决办法
对于高方差,有以下几种方式:
- 获取更多的数据,使得训练能够包含所有可能出现的情况
- 正则化(Regularization)
- 寻找更合适的网络结构
对于高偏差,有以下几种方式:
- 扩大网络规模,如添加隐藏层或者神经元数量
- 寻找合适的网络架构,使用更大的网络结构,如AlexNet
- 训练时间更长一些
不断尝试,直到找到低偏差、低方差的框架。
正则化
比如参数W数量根据特征的数量而定,那么正则化如下
- 损失函数中增加L2正则化
解释:所有w参数的平方和的结果
- 损失函数中增加L1正则化
注:其中,λ 为正则化因子,是超参数。由于 L1 正则化最后得到 w 向量中将存在大量的 0,使模型变得稀疏化,因此 L2 正则化更加常用。
正则化项的理解
在损失函数中增加一项,那么其实梯度下降是要减少损失函数的大小,对于L2或者L1来讲都是要去减少这个正则项的大小,那么也就是会减少W权重的大小。这是我们一个直观上的感受。
- 接下来我们通过方向传播来理解这个其中的L2,对于损失函数我们要反向传播求参数梯度:
前面的默认损失函数的梯度计算结果默认为backprop,那么更新的参数就为
神经网络中的正则化
L1与L2正则化为什么能够防止过拟合
正则化因子设置的足够大的情况下,为了使成本函数最小化,权重矩阵 W 就会被设置为接近于 0 的值,直观上相当于消除了很多神经元的影响,那么大的神经网络就会变成一个较小的网络。
在加入正则化项后,当λ增大,导致
W
[
l
]
W^{[l]}
W[l]减小,
Z
[
l
]
=
W
[
l
]
a
[
l
−
1
]
+
b
[
l
]
Z^{[l]} = W^{[l]}a^{[l-1]} + b^{[l]}
Z[l]=W[l]a[l−1]+b[l]便会减小。由上图可知,在 z 较小(接近于 0)的区域里,函数近似线性,所以每层的函数就近似线性函数,整个网络就成为一个简单的近似线性的网络,因此不会发生过拟合。
Droupout正则化
Droupout论文地址:http://jmlr.org/papers/volume15/srivastava14a.old/srivastava14a.pdf
1、过拟合是一个严重的问题。大型网络的使用速度也较慢,这使得在测试时结合许多不同的大型神经网络的预测来处理过拟合问题变得非常棘手。Dropout是解决这个问题的一种技巧。关键的想法是在训练过程中,从神经网络中随机丢弃神经元(以及它们的连接)
2、在训练过程中,dropout技巧会从指数级的的不同的“稀疏”网络中抽取样本。在测试时,就可以很容易地估计出所有这些稀疏网络的预测结果的平均。这显著地减少了过拟合,并且比其他正则化方法有了很大的改进
3、drop改进了神经网络在视觉、语音识别、文档分类和计算生物学等监督学习任务上的性能,获得了许多基准数据集state-of-the-art结果。
- 定义:Droupout是随机的对神经网络每一层进行丢弃部分神经元操作。
对于网络的每一层会进行设置保留概率,即keep_prob。假设keep_prob为0.8,那么也就是在每一层所有神经元有20% 的概率直接失效,可以理解为0.
Dropout 模型描述
下面我们来讲解dropout的工作过程
-
1、训练过程
1、神经元随机失效,概率为P
2、并且在神经元存在且工作的状态下,权重才会更新,权重更新的越多理论上会变得更大 -
2、测试过程
1、神经元随机失效,概率为0
2、所有的神经元都会参与计算,大于训练时候的任意一个模型的计算量 -
3、模型过程伪代码过程
讲解:
1、如果没有做dropout的标准网络,结构和公式如a图所示;
2、而做过dropout的网络,输入其中 r [ l ] r^{[l]} r[l]表示一个由多个独立的服从相同伯努利分布的变量构成的向量,*表示点乘,即对应元素相乘,第lll层的输出 y [ l ] y^{[l]} y[l]经过dropout变化为 y ^ [ l ] \hat{y}^{[l]} y^[l]。l+1(即L+1)层的输入和输出算法不变。在应用BP训练时,只对子网络的参数求导即可,测试时子网络的桉树需要被缩放。
伯努利分布指的是对于随机变量X有, 参数为p(0<p<1),如果它分别以概率p和1-p取1和0为值。
- 4、结构代码实现-(inverted dropout)
实现随机失活算法,最常用的一种是反向随机失活(inverted dropout) ,这种方式会对每层进行如下代码操作
def dropout(x, level):
if level < 0. or level >= 1:
raise Exception('dropout保持概率在0到1之间')
sample = np.random.binomial(n=1, p=level, size=x.shape)
print(sample)
x *= sample
x /= level
return x
x = np.asarray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=np.float32)
dropout(x, 0.8)
# 其中这步骤在计算的时候对余下的非0的进行扩大倍数,因为p<0。0/x=0,所以0不影响,训练的时候代码可以直接写上
x /= level
- 利用inverted dropout,我们可以在训练的时候直接将dropout后留下的权重扩大1/p 倍,这样就可以使结果的scale保持不变,而在预测的时候也不用做额外的操作了,更方便一些。
问题:为什么需要去做rescale
为什么需要去做rescale
通俗解释:训练的时候只有占比为p 的隐藏层单元参与训练,那么在预测的时候,如果所有的隐藏层单元都需要参与进来,则得到的结果相比训练时平均要大1/p ,为了避免这种情况,就需要测试的时候将输出结果乘以 1/p 使下一层的输入规模保持不变。
数学解释:试的时候不去随机失活?所以为了保证训练和预测的时候期望一样,必须得做scale;我们设置dropout probability为p, 那么该层大约有比例为p的单元会被drop掉,因为每个神经元是否drop就是一次伯努利实验,这层的dropout概率服从伯努利分布,而分布的期望就是np。
例子:
假设keep_prob=p=0.8, z [ l ] = w [ l ] a [ l − 1 ] + b [ l ] z^{[l]} = w^{[l]}a^{[l-1]} + b^{[l]} z[l]=w[l]a[l−1]+b[l],当l - 1(即L-1)层有比例为 1−p=0.2单元drop后, a [ l − 1 ] a^{[l−1]} a[l−1]大约会变为原来的80%(P),为了保证l(L)层的z值期望不变,所以要在 a [ l − 1 ] a^{[l−1]} a[l−1]与dropout矩阵乘积后的权重进行扩大,要除以p,即乘以 1 p \frac{1}{p} p1=10/8(增大)
注意:这个P在这个是保持率,有的时候会特意指定drop prop,那就是1-p为保持率
-
总结:可以在训练时,每个神经单元都可能以概率 p 去除;或者在测试阶段,每个神经单元都是存在的,权重参数w要乘以p,成为:pw
-
5、模型效果对比(论文的实验对比)
在MNIST数据集中的测试,错误率因为增加dropout会有相应提高(p = 0.5用于隐藏层,将p = 0.8用于输入单位)
Droupout为什么有效(如何理解)
- 解释
- 1、减少神经元之间复杂的共适应性。当隐藏层神经元被随机删除之后,使得全连接网络具有了一定的稀疏化,从而有效地减轻了不同特征的协同效应。也就是说,有些特征可能会依赖于固定关系的隐含节点的共同作用,而通过Dropout的话,它强迫一个神经单元,和随机挑选出来的其他神经单元共同工作,达到好的效果。消除减弱了神经元节点间的联合适应性,增强了泛化能力。
- 2、Dropout可以看作是一种随机正则化技术,加入了 dropout 后,输入的特征都存在被随机清除的可能,所以该神经元不会再特别依赖于任何一个输入特征,也就是不会给任何一个输入特征设置太大的权重。通过传播过程,dropout 将产生和 L2 正则化相同的收缩权重的效果。
- 对于不同的层,设置的keep_prob大小也不一致,神经元较少的层,会设keep_prob为 1.0,而神经元多的层则会设置比较小的keep_prob
Dropout实用指南
- 1、dropout会增加训练的时间,通常带有dropout的网络会比不带的标准网络需要2~3倍的训练时间。
- 主要原因在于参数更新非常多,每次训练都要训练不同失去神经元的结构。因此,不是最后一次计算出的梯度需要在测试期间使用。使用的dropout率越高,所需要的训练时间越长,所以需要在训练时间和防止过拟合之间做出权衡。
- 对于线性回归可以使用L2正则化等方法,对于更加复杂的结构,使用具体那种正则化方法不是很明确。
- 2、因为dropout在梯度下降中引入了大量的噪声导致梯度相互抑制,因此学习速率要增加10-100倍。另外一个减少噪声的方法是用momentum,momentum对于标准网络一般采用0.9,对于dropout网络一般是0.95-0.99。两个方法可以同时采用
- 3、防止学习过快导致网络增长太大,一般给隐藏层权重的norm一个上限c,c一般取值3-4
+ dropout和max-normalization、large decaying learning rates and high momentum等组合起来效果更好 - 4、Dropout Rate:一般取值0.5-0.8之间,drop比例p越小,要求隐含层n越大,训练也会越慢
- 5、调试时候使用技巧:
- 先确定网络没问题,再打开dropout训练测试:dropout 的缺点是成本函数无法被明确定义,因为每次会随机消除一部分神经元,所以参数也无法确定具体哪一些,在反向传播的时候带来计算上的麻烦,也就无法保证当前网络是否损失函数下降的。如果要使用droupout,会先关闭这个参数,保证损失函数是单调下降的,确定网络没有问题,再次打开droupout才会有效。