过拟合

135 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

欠拟合和过拟合

首先我们通过图像的角度看看过拟合与欠拟合情况。

img

image.png

上面两张图分别是线性模型与逻辑回归模型的表现,左边的是欠拟合,右边的是过拟合,中间是合理拟合程度。

左边图:他的模型简单,模型学习能力不足,不能够很好的拟合数据,在训练集中会出现较高的损失值,样本结果偏差大,导致泛化能力弱。

中间图:模型很好的拟合了数据,曲线都穿过了样本或者包含样本,很明显的显示损失值比左边图较低。

右边图:模型复杂,学习能力过强,曲线完全穿过样本点,在训练集上出现很低的损失值,导致泛化能力弱,在测试集和新数据上的表现很差。

欠拟合(underfitting)

  • 模型复杂度低
  • 特征量少

其实出现欠拟合的情况,比较好处理,解决方法:

  • 调参
  • 换复杂度高的模型
  • 增加样本的特征
  • ….

一般是前两种方法就可以解决的,我们在训练过程中更多的解决过拟合的问题。

过拟合(Overfitting)

过拟合就是损失函数值极小但泛化性能差的情况。就是训练集的损失函数值很小,但是验证集/测试集上的损失函数值很大。

造成的原因:

  • 训练集样本不足。
  • 训练数据具有噪声,会影响真实特征。
  • 模型复杂。

解决方案

增加训练数据

解决的根本方法,需要一定量的数据才能去学习,数据量不够,可以选择制作假数据,提高数据量。

降低模型复杂度

这一种比较直接的方法,移除一些层或者减少神经元,目的减少学习参数,更好的拟合数据。

L1/L2正则化

对损失函数引入额外的信息,使得参数渐渐变小,模型趋于简单,来防止过拟合以及提高模型泛化能力的方法。目的就是降低模型权重,让模型变得简单。

以下以线性回归模型作为例子进行说明:

损失函数:Loss=1ni=1n12(y^(i)y(i))2.Loss=\frac{1}{n} \sum_{i=1}^n \frac{1}{2} \left(\hat{y}^{(i)} - y^{(i)}\right)^2.

L1 正则化的损失函数:Loss=121ni=1n(y^(i)y(i))2+λw.Loss=\frac{1}{2}\frac{1}{n} \sum_{i=1}^n \left(\hat{y}^{(i)} - y^{(i)}\right)^2+\lambda|w| .

L2 正则化的损失函数:Loss=121ni=1n(y^(i)y(i))2+λw2.Loss=\frac{1}{2}\frac{1}{n} \sum_{i=1}^n \left(\hat{y}^{(i)} - y^{(i)}\right)^2+\lambda|w|^{2} .

可以发现L2 正则化使用平方函数来进行约束,L1就是简单的利用绝对值进行约束。其中λ\lambda 是超参数,ww是参数。

当你的ww越大,多项式较多,模型复杂度在提高,拟合的曲线比较曲折,这就出现了过拟合情况,为避免ww出现较大的值,在损失函数上加上一个与ww相关的值,也就是正则化,在进行梯度下降时候,就会减掉这个正则化,比之前ww就会变得更加小,拟合曲线就会比较平滑,抑制过拟合出现情况。

L1与L2正则化让ww变小的原理是不同的:

  • L1能产生等于0的权值,即能够剔除某些特征在模型中的作用(特征选择),即产生稀疏的效果
  • L2可以得迅速得到比较小的权值,但是难以收敛到0,所以产生的不是稀疏而是平滑的效果

为什么正则化能够起到减小ww的效果呢?(以L1为例,L2与L1一致,可自行推导)

从数学角度去解释:

L1正则化的损失函数的求导及梯度更新公式

wj=wjα[1mi=1[(y^(i)y(i))xj(i)]+λm]w_{j}=w_{j}-\alpha\left[\frac{1}{m} \sum_{i=1}\left[\left(\hat{y}^{(i)} - y^{(i)}\right)x_{j}^{(i)}\right]+\frac{\lambda}{m} \right]
wj=wjαλmα[1mi=1(y^(i)y(i))xj(i)]w_{j}=w_{j}-\alpha\frac{\lambda}{m}-\alpha\left[\frac{1}{m} \sum_{i=1}\left(\hat{y}^{(i)} - y^{(i)}\right)x_{j}^{(i)}\right]

其中α\alphaλ\lambda是超参数。

上面公式推导可以看出,在梯度下降过程中,每次ww都会减去一个固定的值αλm\alpha\frac{\lambda}{m},也就是说每次更新都会固定减小一个设置的特定值(例如0.1),经过迭代就可以让ww减小甚至达到0。当ww为0时候,他的作用就是剔除某些特征在模型中的作用(特征选择)。

L2正则化的损失函数的求导及梯度更新公式

wj=wjαλmwjα[1mi=1(y^(i)y(i))xj(i)]w_{j}=w_{j}-\alpha\frac{\lambda}{m}w_{j}-\alpha\left[\frac{1}{m} \sum_{i=1}\left(\hat{y}^{(i)} - y^{(i)}\right)x_{j}^{(i)}\right]

如果损失函数加入的是L2的正则化,与L1不同的是他不是减小固定值,而是变为原来的1αλm1-\alpha\frac{\lambda}{m}倍,权值始终都在减小,不断变小,经过迭代就会收敛到很小的值趋近于0。

L1/L2的选择情况:

  • 如果你做模型压缩,选择L1
  • 其他情况比较偏向于L2。

dropout机制

Dropout指的是在训练过程中,按一定的比率(比如50%)随机的丢弃一部分的神经元,这些神经元不参与后面的计算过程。目的在一定程度减小模型复杂度,防止参数过分依赖训练数据,增加参数对数据集的泛化能力。

img

删除一些神经元,如下图:

img

主要是删除了一些神经元后,可以减小网络对某些神经元的依赖,让网络增加泛化能力,不依赖特定神经元。

early stopping

为了获得性能良好的神经网络,训练过程中可能会经过很多次 epoch(遍历整个数据集的次数,一次为一个epoch)。

如果epoch数量太少,网络有可能发生欠拟合;

如果epoch数量太多,则有可能发生过拟合。

Early stopping旨在解决epoch数量需要手动设置的问题。具体做法:每个epoch(或每N个epoch)结束后,在验证集上获取测试结果,随着epoch的增加,如果在验证集上发现测试误差上升,则停止训练,将停止之后的权重作为网络的最终参数。

其实这种方式需要你实时观察损失函数的情况,在合适的位置停止训练,是一种比较主观的方式。

参考: