转载,侵删。
引例
已知:1000维的feature,近10000的sample,而且数据是稀疏的。首先,尝试一下常用的线性分类器,比如SVM、LR这些,看训练误差和测试误差的差异,这个时候可能出现多种情况。
(1) 如果训练误差远小于测试误差,说明分类器已经过拟合了,考虑如何避免过拟合。
(2) 如果训练误差与测试误差差不多,但是测试误差太大,说明模型复杂度很可能不够。
(3) 如果训练误差与测试误差差不多,而且测试误差已经足够小,结束。
过拟合欠拟合:
**1、从模型方面考虑。**举例说明:本身问题是二次的,用线性模型处理问题就是欠拟合,用三次及更高次处理问题就是过拟合。但是这里未考虑数据量的多少,只是针对本身模型阶次的考虑。而且现实问题,特别是深度模型处理的问题,并不是简单的就能确定模型复杂度的。
2、处理相同的问题时,在数据量多的情况,可以用相对复杂的模型处理问题,在数据量少的情况下,可以用相对简单的模型处理问题。
过拟合,当数据量太少时,模型无法完成充分的训练,容易过度拟合的符合少量的训练数据特征,对测试数据效果不好;欠拟合,数据量太多,模型太简单没有充分的利用到数据。
3、**欠拟合:**根本原因是特征维度过少,模型过于简单,但是数据量很大,所需模型用不完大量数据提供的信息,误差较大;
解决方法:(1)增加特征维度;
**过拟合:**根本原因是特征维度过多,模型假设过于复杂,参数过多,训练数据过少,噪声过多,导致拟合的函数完美的预测训练集,但对新数据的测试集预测结果差。 过度的拟合了训练数据,而没有考虑到泛化能力。
解决方法:(1)减少特征维度;(2)正则化,降低参数值。
过拟合根本原因
图中黑色曲线是正常模型,绿色曲线就是overfitting模型。尽管绿色曲线很精确的区分了所有的训练数据,但是并没有描述数据的整体特征,对新测试数据的适应性较差。
发生过拟合的主要原因可以有以下三点:
(1)数据有噪声
(2)训练数据不足,有限的训练数据
(3)训练模型过度导致模型非常复杂
(1)数据有噪声
所有的机器学习过程都是一个search假设空间的过程!我们是在模型参数空间搜索一组参数,使得我们的损失函数最小,也就是不断的接近我们的真实假设模型,而真实模型只有知道了所有的数据分布,才能得到。往往我们的模型是在训练数据有限的情况下,找出使损失函数最小的最优模型,然后将该模型泛化于所有数据的其它部分。这是机器学习的本质!
假设我们的总体数据如下图所示:
(这里就假设总体数据分布满足一个线性模型y = kx+b,**现实中肯定不会这么简单,数据量也不会这么少,至少也是多少亿级别,但是不影响解释。**反正总体数据满足模型y)
此时我们得到的部分数据,还有噪声的话,如图所示:
(红色数据点为噪声)
那么由上面训练数据点训练出来的模型肯定不是线性模型(总体数据分布下满足的标准模型),比如训练出来的模型如下:
那么我拿着这个有噪声训练的模型,在训练集合上通过不断训练,可以做到损失函数值为0,但是拿着这个模型,到真实总体数据分布中(满足线性模型)去泛化,效果会非常差,因为你拿着一个非线性模型去预测线性模型的真实分布,显而易得效果是非常差的,也就产生了过拟合现象!
我们可以理解地简单些:有噪音时,更复杂的模型会尽量去覆盖噪音点,即对数据过拟合。这样,即使训练误差Ein 很小(接近于零),由于没有描绘真实的数据趋势,Eout 反而会更大。
(2)训练数据不足,有限的训练数据
当我们训练数据不足的时候,即使得到的训练数据没有噪声,训练出来的模型也可能产生过拟合现象,解释如下:
假设我们的总体数据分布如下:
(为了容易理解,假设我们的总体数据分布满足的模型是一个二次函数模型)
我们得到的训练数据由于是有限的,比如是下面这个:
(我只得到了A,B俩个训练数据)
那么由这个训练数据,我得到的模型是一个线性模型,通过训练较多的次数,我可以得到在训练数据使得损失函数为0的线性模型,拿这个模型我去泛化真实的总体分布数据(实际上是满足二次函数模型),很显然,泛化能力是非常差的,也就出现了过拟合现象!
(3)训练模型过度导致模型非常复杂
训练模型过度导致模型非常复杂,也会导致过拟合现象!这点和第一点俩点原因结合起来其实非常好理解,当我们在训练数据训练的时候,如果训练过度,导致完全拟合了训练数据的话,得到的模型不一定是可靠的。
比如说,在有噪声的训练数据中,我们要是训练过度,会让模型学习到噪声的特征,无疑是会造成在没有噪声的真实测试集上准确率下降!
解决过拟合
(1)L1和L2正则:都是针对模型中参数过大的问题引入惩罚项,依据是奥克姆剃刀原理。在深度学习中,L1会趋向于产生少量的特征,而其他的特征都是0增加网络稀疏性;而L2会选择更多的特征,这些特征都会接近于0,防止过拟合。神经网络需要每一层的神经元尽可能的提取出有意义的特征,而这些特征不能是无源之水,因此L2正则用的多一些。
(2)dropout:深度学习中最常用的正则化技术是dropout,随机的丢掉一些神经元。
原理可以参考: https://www.cnblogs.com/hutao722/p/9946047.html
(3)数据增强,比如将原始图像翻转平移拉伸,从而是模型的训练数据集增大。数据增强已经是深度学习的必需步骤了,其对于模型的泛化能力增加普遍有效,但是不必做的太过,将原始数据量通过数据增加增加到2倍可以,但增加十倍百倍就只是增加了训练所需的时间,不会继续增加模型的泛化能力了。
(4)提前停止(early stopping):就是让模型在训练的差不多的时候就停下来,比如继续训练带来提升不大或者连续几轮训练都不带来提升的时候,这样可以避免只是改进了训练集的指标但降低了测试集的指标。
(5)批量正则化(BN):就是将卷积神经网络的每层之间加上将神经元的权重调成标准正态分布的正则化层,这样可以让每一层的训练都从相似的起点出发,而对权重进行拉伸,等价于对特征进行拉伸,在输入层等价于数据增强。
先来思考一个问题:我们知道在神经网络训练开始前,都要对输入数据做一个归一化处理,那么具体为什么需要归一化呢?归一化后有什么好处呢? 原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。
对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。
我们知道网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。Paper所提出的算法,就是要解决在训练过程中,中间层数据分布发生改变的情况,于是就有了Batch Normalization,这个牛逼算法的诞生。
BN层为什么可以防止梯度消失;BN层为什么可以防止过拟合
参考:
https://www.cnblogs.com/eilearn/p/9203186.html
https://www.cnblogs.com/simpleDi/p/10582878.html
https://www.jianshu.com/p/2d8bac43e868
过拟合根本原因 https://www.cnblogs.com/tianqizhi/p/9453646.html