基础 · 06

泛化、过拟合与正则化

训练集上 loss 为零不是胜利——泛化才是。偏差-方差权衡、L1 的菱形、L2 的圆形,一篇画清正则化的几何。

16 min read

为什么训练 loss 低不等于好

上一篇我们学了三种线性模型:回归、感知机、logistic。它们都通过最小化损失函数来找最优参数。但这里有一个关键问题——我们最小化的是训练集上的 loss,而我们真正关心的是模型在没见过的数据上表现如何。

这就是泛化(generalization)

举一个极端的例子:用一条 14 阶多项式去拟合 15 个数据点,训练 loss 可以做到 0——曲线精确穿过每个点。但这条曲线在数据点之间疯狂震荡,来一个新数据点大概率预测完全不对。

训练 loss 低只说明模型记住了训练数据,不代表它学到了数据背后的规律。如果模型把噪声也当规律学了,就叫过拟合(overfitting)。反过来,如果模型太简单连趋势都没学到,叫欠拟合(underfitting)

我们真正想要的是介于两者之间的甜蜜点——模型复杂度刚好匹配数据的真实结构。

怎么找到这个甜蜜点? 我们不能用训练集来评判模型——那就像考试时偷看答案。标准做法是把数据分成三份:

  • 训练集(training set):用来训练模型(调参数)
  • 验证集(validation set):用来调超参数(比如多项式阶数、λ\lambda)——它是"裁判"
  • 测试集(test set):最终上线前的终极考试——只能用一次,否则你就在"对着答案做题"了

在本文的交互演示中,你会看到"训练误差"和"测试误差"的对比。记住:我们选模型看验证集,最终评估看测试集。

偏差-方差权衡

为什么过拟合会发生?一个经典的分解给出了答案。把模型的预测误差分解为三个部分:

期望泛化误差=偏差2+方差+不可约误差\text{期望泛化误差} = \text{偏差}^2 + \text{方差} + \text{不可约误差}
  • 偏差(bias):模型的预测平均值和真实值之间的差距。偏差高 = 模型太简单,系统性偏离真相 → 欠拟合
  • 方差(variance):模型对训练数据的敏感度。换一组训练数据,预测就大幅变化 = 方差高 → 过拟合
  • 不可约误差(irreducible error):数据本身的固有噪声,是任何模型预测误差的下限,无论模型多好都无法消除。

关键洞察:偏差和方差是此消彼长的。 模型越复杂,偏差越低(能拟合更复杂的函数),但方差越高(对训练数据的微小变化过度反应)。模型越简单,方差低但偏差高。

模型复杂度偏差方差训练 loss测试 loss
太低高(欠拟合)
刚好最低
太高很低高(过拟合)

这个权衡是所有 ML 的核心张力——无论模型多先进,你都在跟它搏斗。

过拟合的几何:曲线穿过每个点

让我们直观地看这个过程。下面是一个多项式回归的交互演示——用不同阶数的多项式去拟合 20 个带噪声的数据点。真实函数是 y=x3xy = x^3 - x(灰色虚线),一个三次多项式:

多项式阶数3
拟合良好训练 MSE 0.0175测试 MSE 0.0821
训练集测试集真实函数 y = x³ − x
真实函数是三次多项式(灰色虚线)。阶数 = 3 时拟合曲线几乎重合真实函数——过拟合发生在更高阶时,模型开始追逐噪声而非规律。

观察三种情况:

阶数 = 1(直线):模型太简单,一条直线无法捕捉三次曲线的 S 形弯曲。训练和测试误差都高。这是欠拟合。

阶数 = 3:三次多项式完美匹配真实函数的形状。训练误差接近噪声的下限,测试误差最低。这是泛化良好的状态。

阶数 ≥ 9:模型有足够的自由度穿过每一个训练点——训练误差接近零。但曲线在数据点之间追逐噪声,测试误差反而飙升。这就是过拟合的典型症状。

注意一个关键信号:训练误差单调下降,测试误差先降后升。 那个"U 形"测试误差曲线的底部,就是最佳模型复杂度。

当然,控制多项式阶数是一种粗暴的防过拟合方法——直接砍掉特征。在实际中,我们往往保留所有特征(高维模型),但通过限制权重参数的大小来给模型"戴上紧箍咒"——让它不那么容易"扭曲"去迎合噪声。这就引出了正则化

L2 正则:圆形约束

知道了过拟合的原因,怎么防止它?核心思路:限制模型复杂度。 最常用的方法是正则化(regularization)——在损失函数里加一项惩罚项,惩罚"太大"的参数。

L2 正则化(Ridge 回归 / weight decay):

Lreg=L+λw2=L+λiwi2\mathcal{L}_{\text{reg}} = \mathcal{L} + \lambda \|\mathbf{w}\|^2 = \mathcal{L} + \lambda \sum_i w_i^2

λ\lambda 控制惩罚力度。λ\lambda 越大,模型被"推"向更小的权重。

约束优化视角:L2 正则等价于带约束的优化问题:

minwL(w)s.t.w2t\min_{\mathbf{w}} \mathcal{L}(\mathbf{w}) \quad \text{s.t.} \quad \|\mathbf{w}\|^2 \leq t

为什么惩罚项 λw2\lambda \|\mathbf{w}\|^2 等价于约束 w2t\|\mathbf{w}\|^2 \leq t?这是拉格朗日乘子法的结论(凸优化篇讲过):惩罚力度 λ\lambda 越大,相当于约束半径 tt 越小。

约束区域是一个圆形(高维是球)。想象损失函数的等高线就像在碗底滴水后不断向外扩散的椭圆水波——最优解就是水波向外扩张时,第一次触碰到圆形约束边界的那个点。通常两个权重都不为零。

L1 正则:菱形约束与稀疏

L1 正则化(Lasso):

Lreg=L+λw1=L+λiwi\mathcal{L}_{\text{reg}} = \mathcal{L} + \lambda \|\mathbf{w}\|_1 = \mathcal{L} + \lambda \sum_i |w_i|

区别只是把平方换成了绝对值。但这个微小的变化带来了截然不同的几何:约束区域变成了菱形(高维是多面体)。

菱形的特点是有尖角。同样想象水波向外扩散——等高线(椭圆形)在菱形的尖角处更容易相切——而尖角恰好落在坐标轴上,意味着某个 wi=0w_i = 0

这就是 L1 正则化的核心特性:产生稀疏解。 某些权重精确为零,等于模型自动做了特征选择。

在二维空间,菱形只有 4 个顶点;但在 1000 维空间,L1 约束的多面体有海量的"棱"和"角"刺向各个坐标轴,导致极高概率发生坐标轴上的相切,从而直接"砍掉"大量无用特征。这就是为什么 L1 在高维特征选择中如此有效。

拖动下面的约束半径看 L1 和 L2 的区别:

约束半径 t1.00
约束最优:w₁ = 0.97, w₂ = 0.24
无约束最优w₁w₂
L2 正则的约束区域是圆形。最优解是 loss 等高线与圆的切点——通常两个权重都不为零。
拖动半径 tt 改变约束强度。

L1 vs L2 对比:

特性L2(Ridge)L1(Lasso)
约束形状圆(球)菱形(多面体)
权重都非零,趋向小的值部分精确为零
稀疏性
特征选择
概率解释高斯先验拉普拉斯先验
适用场景权重都重要只有少数特征有用

还有 Elastic Net = L1 + L2 的混合,兼得稀疏性和稳定性。

概率视角:正则化项可以理解为对参数的先验分布概率篇里贝叶斯推断的延伸)。L2 假设权重服从高斯分布(倾向小的、非零的值),L1 假设权重服从拉普拉斯分布(倾向集中在零附近、偶尔有大的尖峰)。这解释了为什么 L1 更容易产生精确为零的权重。

最朴素的真理:更多的数据能治愈过拟合。 当数据点密密麻麻填满空间时,再复杂的模型也难以通过疯狂震荡来"作弊"。在深度学习时代,"加数据"往往是比调正则化更有效的解法——这也是为什么 LLM 要用几万亿 token 来训练。

这个想法在前沿里