第一:过拟合来源。
关于过拟合是源于模型对于数据的适配性的问题。如果模型容易拟合比较震荡的函数而且数据的随机误差比较大,这个时候就容易发生过拟合现象,也导致了泛化性能不好。
泛化性能差就是说在训练集上效果好但是在测试集上效果差。但是泛化性能差有很多可能:
1.数据量不够,不足以拟合完整的模型。
2.训练集和测试集事实上处于不同的区域,可以去检查训练集任意一点和测试集数据任意一点之间的交叉平均距离,以及训练集和测试集自己本身任意两点的平均距离。如果交叉距离明显大于训练集自己的两点平均距离。那么说明训练集和测试集处于不同的区域。必然不可能泛化好。
3.过拟合,这个情况需要判断。
第二:如何检验过拟合。
检验的方法1:训练集测试集混合切分多重学习法。
举例:
学习的时候先分成大量训练集和少量测试集。然后训练。
这时候比如训练集误差为1%,测试集误差为5%.
然后保存模型再把两个集合混合打乱,重新导入刚才的模型重新训练同样的步数。
这个时候会发现一开始训练集和测试集的误差可能都是1.3%.这个是因为训练集的误差把测试集的误差平均了。继续训练会发现训练集误差会下降,测试集误差会上升。结果可能是训练集误差为1.1%,测试集误差为4.2%
然后再混合打乱重复上面的步骤,如果两三次打乱之后发现:
训练集和测试集的误差还是有一个明显的区别比如训练集误差为1.5%, 测试集误差为4%。这种差别就量化了过拟合的性质。那么说明模型在一部分集合上过拟合,另外一部分集合上误差大。
检验的方法2:批次最大误差与平均误差的比较
训练是一个epoch事实上分为多个批次(batch)。可以检查一个epoch的所有批次中误差的最大值于误差的平均值的比较。如果最大值与平均值相差较大,比如两倍以上,那么说明数据在不同的批次上拟合情况差异较大。也就说明了可能过拟合。
第三:解决过拟合可能的方法。
方法1:改进模型,有些神经网络的层由于其理论性质本身可能导致结果函数的震荡从而导致过拟合。比如BatchNorm, self-Attention. 去掉这样的层会改善过拟合现象。关于这个问题有很多深刻的理论分析。还有一些手段比如dropout,或者降低神经网络层数等等,相当于降低神经网络的解空间。
方法2:加大训练的batch_size. 使得训练的过程更加关注大量数的平均误差值。但是batch_size不能随意加大,因为batch_size太大会导致mini_batch太大,导致随机梯度下降的时候梯度的随机性下降从而导致训练结果不容易逃逸出局部极小值。
方法3:改进数据设计,使得数据设计更加合理。比如如果特征1对应标签1.特征2对应标签2.当我们发现标签1和标签2的区别可能是比较大的时候,那么设计特征1和特征2的参数化的时候就可以把数据设计得使得其区别更大。这样相当于把样本(x,y)的x值整体拉伸,在y值不变的基础上就可以使得数据的震荡性下降。
方法4: 增加数据量,改善采样方法。 数据量的增加可以多样化数据。采样方法更加均匀可以避免数据在少数类型的样本上权重过大。可以的办法比如Gibbs采样,或者数据分类,每一类选取一些样本,或者直接分类学习,每一类一个神经网络。
方法5:换优化器。如果使用了Adam这类优化器,那么就会提高过拟合风险。把Adam换成SGD可以提升模型的泛化性能,但是会增加训练时间。对于这个问题,也有很多理论解释。但是这也取决于数据的形式。如果特征到标签这个映射是平缓的,那么adam是有不错的效果的而SGD会特别慢。但是如果特征到标签这个映射是很震荡的,那么adam优化器的结果会过拟合,SGD就会更好。
方法6:如果有办法把标签的数据变动变得平缓的话,那么对于神经网络的学习是非常有利的。因为神经网络的学习有一个原理叫频率原理,也就是说神经网络喜欢先学习比较平缓的函数,这样得出的模型可能会偏向于平缓。这样的话就不容易过拟合。