正则化总结

欠拟合和过拟合

  • 欠拟合是指模型不能在训练集上获得足够低的误差。

  • 过拟合是指训练误差和测试误差之间的差距太大,神经网络对训练数据进行很好的建模但在看到来自同一问题域的新数据时失败的现象。

    模型容量低,而训练数据复杂度高时,此时模型由于学习能力不足,无法学习到数据集中的“一般规律”,因而导致训练误差高,表现为欠拟合。

    模型容量高,而训练数据简单时,此时模型由于学习能力太强,记住所有的训练数据,却没有理解数据背后的规律,对于训练集以外的数据泛化能力差,表现为过拟合。

解决欠拟合
  • 在模型容量和训练数据复杂度不匹配时,发生了欠拟合现象,常见解决方法有:
  • 增加新特征:可以考虑加入特征组合、高次特征等,来增大假设空间。
  • 增大模型容量:容量低的模型可能很难拟合训练集。
  • 减少正则化参数:正则化的目的是用来防止过拟合的,但是模型出现了欠拟合,则需要减少正则化参数。
解决过拟合

引起过拟合的主演原因如下:

  • 训练数据集问题。如训练样本不均衡,训练集中正样本偏多,那么去预测负样本肯定不准;训练样本数据少,尤其是当比模型参数数量还少时,更容易发生过拟合;训练数据噪声干扰过大,模型会学习很多的噪声特征等。
  • 模型过于复杂。模型参数数量太多,参数取值范围太大,模型已经能够“死记硬背”记下了所有训练数据的信息(记住了不适合于测试集的训练集特性);模型假设的合理性不存在,也就是假设成立的条件实际并不成立。
  • 模型训练迭代次数太多。对数据反复地训练也可能会让模型拟合了训练样本中没有代表性的特征

解决过拟合问题,最重要的减少测试误差而不过度增加训练误差,从而提高模型的泛化能力。通常解决过拟合的方法有:

  • 数据集增强
  • 控制模型容量大小
  • 正则化(Regularization)
  • 丢弃法(Dropout)
  • 提前终止训练(Early Stopping)

正则化(Regularization)

正则化其实就是在原来的目标函数的基础上又加了一项非负项, 并且这个非负项是 w 的函数。 这样的话target不变的基础上得让这个loss变得小一点, 相当于对其产生了一种约束。也可以认为正则化是减小权值方差的一种策略,减小权值的取值范围,从而使得模型求解空间变小,不会拟合出复杂的曲线(函数).

正则化主要用于避免过拟合的产生和减少网络误差,通过将L1范数或者L2范数加入到损失函数中,在损失函数中增加一个惩罚项,在进行反向传播]时就相当于在原来的权重上乘上了一个小于1的系数,使得权重减小,从而使得模型的权重的取值范围减小,即模型的求解空间变小,不会拟合出复杂的曲线(函数),从而达到抑制过拟合的目的,从而限制模型参数的数量以及参数的大小。

  • 通常使用 L2 正则,称为权重衰减(weight decay),一般在优化器中使用,取值一般为0.01,0.001,0.0001;
  • L2 正则:容易计算, 可导, 适合基于梯度的方法,对异常值非常敏感;执行 L2 正则化鼓励权重值趋向于零(但不完全为零)。
  • L1 正则:L1模型可以将 一些权值缩小到零(稀疏,由于它可以提供稀疏的解决方案, 因此通常是建模特征数量巨大时的首选模型);执行 L1 正则化鼓励权重值为0.
  • 直观地说,较小的权重会减少隐藏神经元的影响。在那种情况下,那些隐藏的神经元变得可以忽略不计,神经网络的整体复杂性得到降低。不太复杂的模型通常会避免数据中的建模噪声,因此不会出现过度拟合。
正则化之L1和L2

误差 = 偏差 + 方差 + 噪声

  • 偏差度量了学习算法的期望预测与真实结果的偏离程度, 即刻画了学习算法本身的拟合能力
  • 方差度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动所造成的影响
  • 噪声则表达了在当前任务上任何学习算法所能达到的期望泛化误差的下界。

正则化就是在目标损失函数上面添加一个正则项:

其中 $\alpha$ 是正则化参数,决定了我们对模型进行正则化的程度(惩罚力度),$w$ 是权重。加上正则项,就是希望我们的代价函数小,同时也希望我们这里的 $w_i$ 小,这就是说明每个样本的权重都很小,这样模型就不会太多的关注某种类型的样本, 模型参数也不会太复杂,有利于缓解过拟合现象。

等高线图中:

  • 彩色的圆圈就是损失函数值 $\mathcal{L}$ 等高线,也就是说同一条线上的损失函数值是相等的;
  • 左边菱形代表L1的等高线;右边圆形代表L2的等高线;
  • 假设二维权重下的示意图 $(w_1,w_2)$;

分析:

  • 损失函数值 $\mathcal{L}$ 等高线和正则项等高线,分别代表了两个优化问题。对原始的损失函数中添加了正则项之后,优化问题就变成了两个子优化问题的博弈。

  • 左边是涉及 L1 正则项的,其中 A,B,C点产生的损失值是相等的,黑色的菱形(坐标中心) 表示L1正则项的一个等高线,假设$w_1 + w_2 = r,假设r=1$ ,那么菱形框任意一个点产生的正则项值都是1。我们现在考虑A, B,C三点的目标函数,他们的损失值 $\mathcal{L}$ 是相等的,那么这三个点哪个点的Regularization最小呢? C点的正则项是1, 而我们会发现A点和B点的正则项都比C大(其实A,B,C这一条损失值 $\mathcal{L}$ 等高线上就是C的正则项最小), 所以C点的目标函数最小。所以我们如果在L1的情况下找个最优解,既能损失 $\mathcal{L}$ 最小,又能权重最小,那么往往这个最优解就发生在坐标轴上,也就是上面的C点。 这样一个神奇的现象发生了,w1竟然等于0, 就说明参数解有0 的出现了, $w_1$ 就消失了。所以L1正则项一般会产生稀疏的解,也就是有项权重解为 0 。这是因为加上L1之后,我们参数的解往往会发生在坐标轴上导致某些参数的值为0;

  • 右边是涉及 L2 正则项的,其中A’, B’, C’点产生的损失值也是相等的,黑色的圆形(坐标中心) 表示L2正则项的一个等高线,假设$w_1^2 + w_2^2 = r,假设r=1$ 。和上面的分析一样,,如果我们在A’, B’, C’点确定最优解的话,依然是C’点, 因为它在损失值 $\mathcal{L}$ 相等的情况下正则最小。但是我们发现L2正则下不过出现某个参数为0的情况,而是w1和w2都比较小。所以L2正则项的最优的参数值很小概率出现在坐标轴上,因此每一维的参数都不会是0。当最小化 $|w|$ 时,就会使每一项趋近于0。
  • 对于 L1 正则化中,在正则项等高线和损失值等高线相切/相交始终都是在坐标轴上的;最优点会保持在 L1 等高线的断点处,依然在坐标轴上,故某个权重值会变为0。
  • 而 L2 的相切点则只能无限接近坐标轴,惩罚力度再大,都到不了0。
  • 惩罚力度 $\alpha$ 相当于 L1中的菱形在坐标中心处大小 $w_1 + w_2 = \alpha$ ;相当于 L2 中圆形在坐标中心处的大小 $w_1^2 + w_2^2 = \alpha$ 。当损失值 $\mathcal{L}$ 和正则项之和最小时,上述的博弈取得平衡。而此时平衡点一定是相切点/端点。相切点的具体位置,取决于正则项的惩罚力度,也就是公式里的α。每一个平衡点,对应着一个α的设置。当惩罚力度大时,相切/相交点往靠近坐标轴的方向移动,而惩罚力度小时,相切/相交往远离坐标轴的方向移动

L1正则化的特点:

  • 不容易计算, 在零点连续但不可导, 需要分段求导
  • L1模型可以将 一些权值缩小到零(稀疏)
  • 执行隐式变量选择。 这意味着一些变量值对结果的影响降为0, 就像删除它们一样
  • 其中一些预测因子对应较大的权值, 而其余的(几乎归零)
  • 由于它可以提供稀疏的解决方案, 因此通常是建模特征数量巨大时的首选模型
  • 它任意选择高度相关特征中的任何一个, 并将其余特征对应的系数减少到0
  • L1范数对于异常值更具提抗力

L2正则化的特点:

  • 容易计算, 可导, 适合基于梯度的方法
  • 将一些权值缩小到接近0
  • 相关的预测特征对应的系数值相似
  • 当特征数量巨大时, 计算量会比较大
  • 对于有相关特征存在的情况, 它会包含所有这些相关的特征, 但是相关特征的权值分布取决于相关性。
  • 对异常值非常敏感
  • 相对于L1正则会更加准确

为什么增加正则项后会使得权重变小,缩小了模型的权重的取值范围?在 pytorch 中 L2正则项 称为 权值衰减(weight decay),为啥叫衰减?怎么实现衰减的?

  • 模型参数的更新公式:

  • 在损失函数上添加了一个 L2 正则项后 $Loss_{new} = Loss + \frac{\alpha}{2}\sum_{i=1}^{n}w_i^2$ ,那么参数的更新变为:

    唯一的区别是,通过添加正则化项,我们从当前权重(等式中的第一项)中引入了额外的减法。

    换句话说,与损失函数的梯度无关,每次执行更新时,我们都会使权重变小一点。也可以看成参数 $w_i$ 本身发生一个衰减即使移项 $w_i(1-\varepsilon \alpha),其中 \varepsilon \alpha \in(0,1)$。

  • pytorch 中使用 L2 就是在优化器中(例:torch.optim.SGD)指定 weight_decay 这个参数即可。

正则化之Dropout

Dropout叫做随机失活。就是给出一个概率(随机),让某个神经元的权重为0(失活),dropout 意味着在以某种概率P进行训练期间,神经网络的神经元在训练期间被关闭。一般是应用到全连接层(nn.Linear),而且只在训练过程中使用,在推理预测是不使用的。所以一般在pytorch中设置 model.train,model.eval 来限制Dropout和BN。

为什么dropout可以抑制过拟合呢?dropout通过随机失活神经元,使得模型参数减少,网络变得简单,不会拟合出较为复杂的曲线,事实上也就相当于正则。

就是每一层,让某些神经元不起作用,这样就就相当于把网络进行简化了(左边和右边可以对比),我们有时候之所以会出现过拟合现象,就是因为我们的网络太复杂了,参数太多了,并且我们后面层的网络也可能太过于依赖前层的某个神经元,加入Dropout之后, 首先网络会变得简单,减少一些参数,并且由于不知道浅层的哪些神经元会失活,导致后面的网络不敢放太多的权重在前层的某个神经元,这样就减轻了一个过渡依赖的现象, 对特征少了依赖, 从而有利于缓解过拟合。

关于Dropout还有一个注意的问题,就是数据的尺度变化。 这个是什么意思呢? 我们用Dropout的时候是这样用的: 只在训练的时候开启Dropout,而测试的时候是不用Dropout的,也就是说模型训练的时候会随机失活一部分神经元, 而测试的时候我们用所有的神经元,那么这时候就会出现这个数据尺度的问题, 所以测试的时候,所有权重都乘以1-drop_prob, 以保证训练和测试时尺度变化一致,drop_prob是我们的随机失活概率。

pytorch 中的 torch.nn.Dropout(p=0.5, inplace=False):p就是随机失活概率。第一点就是Dropout加的时候注意放置的位置,第二点就是由于Dropout操作;模型训练和测试是不一样的,上面我们说了,训练的时候采用Dropout而测试的时候不用Dropout, 那么我们在迭代的时候,就得告诉网络目前是什么状态,如果要测试,就得先用.eval()函数告诉网络一下子,训练的时候就用.train()函数告诉网络一下子。Pytorch在实现Dropout的时候, 是权重乘以 $\frac{1}{1-p}$ 的,也就是除以1-p, 这样就不用再测试的时候权重乘以1-p了, 也没有改变原来数据的尺度.

Questions
  • L1和L2 哪个抑制过拟合的效果好?

    L1正则化和L2正则化在抑制过拟合方面有不同的效果,具体哪个效果更好取决于问题的性质、数据集的大小、网络架构以及其他因素一般来说,L2会比L1好,L2平滑权重,L1是稀疏权重,有的权重直接为0。实际中还是得交叉验证来评估!

    L1正则化:

    • L1正则化倾向于使权重稀疏,即将某些权重归零。这有助于进行特征选择,从而排除对模型不重要的特征。
    • 当数据集中存在大量不相关的特征时,L1正则化可能会更有效,因为它可以显著减少不相关特征的影响。
    • L1正则化对异常值更敏感,可能会将异常值的权重置零,从而降低模型对异常值的拟合。

    L2正则化:

    • L2正则化通过限制权重的大小来避免过度拟合,但它不会强制使权重为零,而是使权重接近零。
    • L2正则化可以平滑权重,降低权重之间的差异,有助于提高模型的稳定性。
    • 当数据集的特征之间存在共线性时,L2正则化可能会更有效,因为它可以减少共线性的影响。
  • L1和L2 哪个收敛更快?

    A:在正则化对收敛速度的影响方面,通常情况下,L2正则化(也称为权重衰减)可能会比L1正则化更有利于快速收敛。这是因为L2正则化将权重的平方项添加到损失函数中,这可以使权重的更新变得更加平稳,有助于避免参数变化过大,从而导致更快的收敛。

    L1正则化在优化中可能导致稀疏权重,其中某些权重变为零。这可能会导致一些梯度在某些情况下突然变为零,从而减缓收敛速度。然而,这也取决于初始权重、学习率和其他优化算法的细节。

  • Dropout 应用在深层好还是浅层好?

    Dropout是一种用于训练神经网络的正则化技术,旨在减少过拟合问题。它通过在每次训练迭代中随机地将一部分神经元的输出置为零,从而强制网络不依赖于特定神经元的存在,从而提高泛化能力。

    关于将Dropout应用于深层还是浅层网络,有一些一般性的观点:

    1. 深层网络: 在深层网络中使用Dropout通常是有益的,因为深层网络更容易出现过拟合问题。由于深层网络具有更多的参数和表示能力,它们可以更好地拟合训练数据,但同时也更容易记住噪声或训练数据的细节,导致泛化性能下降。在这种情况下,Dropout可以帮助减少神经元之间的过度依赖,从而提高网络的泛化能力。
    2. 浅层网络: 浅层网络相对于深层网络具有较少的参数和复杂性,因此它们通常具有更好的泛化能力,而且过拟合的风险较低。在一些情况下,添加Dropout可能不如在深层网络中明显有效,因为浅层网络已经具有一定的简化能力,能够更好地应对泛化问题。

    总之,Dropout的效果通常在网络的复杂性和数据集的大小之间变化。在训练数据较少、网络较深或容易过拟合的情况下,Dropout通常会带来显著的改善。然而,如果网络相对浅并且数据集足够大,可能不需要过多地使用Dropout。

Reference: 正则化 ; L1和L2的正确姿势