从过拟合到泛化能力
要训练好一个神经网络,光有"猜+约"的智慧还不够,我们还需要掌握"适度"的艺术!
还记得我们之前用函数拟合数据点的例子吗?当我们面对这样一组数据:
| x | f(x) | y |
|---|---|---|
| 2 | 4 | |
| 3 | 4.5 | |
| 4 | 5 | |
| 5 | 5.5 | |
| 6 | 6.1 |
如果我们用一个极其复杂的函数,比如10次多项式,去完美拟合这5个点,会发生什么?
看!这个函数完美地穿过了每一个训练数据点,损失函数几乎为零。但当我们用新数据测试时,比如x=2.5,预测值y=10,而真实值可能是4.25。这就是过拟合——模型在训练数据上表现极好,但在新数据上表现很差。
用一句话概括:过拟合就是"死记硬背标准答案,遇到新题彻底懵圈"
类似于面向结果编程,样例都能过,但一遇到其他数据就抓瞎了。
而模型在未知数据上的表现力就是泛化能力。
那我们该怎么解决过拟合呢?
以下列举五种方法。
最简单的方法就是在过拟合之前,提前停止训练。
还有一个简单的方法就是减少模型的复杂度。
奥卡姆剃刀原理:如非必要,勿增实体。
比如在上述例子中,如果用线性函数可以解释,就不要用10次多项式。在同等解释力的情况下,简单的模型往往比复杂的模型更好。
除此之外,我们也可以通过增加训练数据量来解决这个问题。数据越充足,模型越不容易过拟合。
如果实在没有更多数据,我们也通过对现有数据进行旋转、翻转、裁剪等操作,人工创造出更多训练样本。在也就是所谓的“数据增强”
上述方法听着都好随便啊?有没有看着正经一点的方法呢?有的,那就是正则化。
如果在训练的过程中,我们发现如果让w增加999,可以让损失函数L下降0.01,那么我们要不要改变w?肯定不要。函数曲线抖动地剧烈无比,损失函数却只下降一点点,捡了芝麻丢了西瓜。
那么在实际训练中,我们要怎么判断一个改变值不值得去做呢?
我们可以在损失函数中,将参数本身的值(绝对值)加进去,如果总体增加就不值得去做(L下降一点点,w变大很多),反之,如果总体减小就值得去做。如此便可以抑制参数的野蛮增长。
或
这就是L1正则化。
如果把绝对值换成平方,就是L2正则化:
就是惩罚项,
则是正则化系数,用以控制惩罚力度。
当然,我们还有别的招:随机丢弃
这是神经网络里特有的一招狠活,学名Dropout。
原理极其粗暴:
每次训练,随机让部分神经元"带薪休假"。(暂时不让它们工作)。
训练时:每个神经元以概率 p 保留,1−p 丢弃
测试时:所有神经元上岗,但权重按比例缩小
每个神经元都不敢偷懒依赖别人(因为不知道下一秒谁会被干掉),被迫学会单独提取最核心的特征,而不是几个神经元串通一气记死答案。
就像那个成语“滥竽充数”,齐宣王突然要求"每人单独吹竽",让南郭先生这个混子无处藏身。Dropout迫使每个神经元独立成才,而非抱团作弊。
说到底,AI 的训练过程,就是一场在“记得太死”和“啥也没学会”之间的平衡艺术。
而所谓的调参、加正则化、用 Dropout,其实都是在给那个急于表现、拼命想弯的神经网络当头泼一盆冷水:
“别背答案,去学规律。”
