1. 正则化是什么
1.1 回顾过拟合
过拟合:训练集上表现好,验证集上表现差。原因有训练数据太少、训练时间太长、模型太复杂。
1.2 正则化的思路
正则化(Regularization)= 在损失函数中加入惩罚项,限制模型复杂度。
训练过程中不仅要把数据拟合好,还要为”模型太复杂”付出代价。模型被迫在”拟合得准”和”保持简单”之间取得平衡。
2. 奥卡姆剃刀:正则化的哲学根基
“如无必要,勿增实体。” —— 14 世纪修士威廉·奥卡姆
| 案例 | 复杂理论 | 简单理论 | 谁的准确度高? |
|---|---|---|---|
| 天文学 | 托勒密地心说(80+ 个本轮均轮) | 哥白尼日心说(7 个圆形轨道) | 简单的那个 |
两个模型都能解释同样的现象 → 更简单的那个更接近本质规律。
深度学习中的正则化,就是奥卡姆剃刀的数学化实现。
3. L1 正则化(Lasso)
3.1 公式
在原始损失函数上加入所有参数绝对值之和:
3.2 惩罚项如何工作
- 新梯度 = 原始梯度 + 正则项梯度
- 的导数: 时为 , 时为
- 每次参数更新时,所有参数往 0 的方向匀速缩减
3.3 效果
L1 惩罚倾向产生稀疏解;坐标下降或近端梯度的软阈值步骤可以得到精确的 0。普通梯度下降只加 时,参数可能在 0 附近往返,不保证自动精确归零。
- 权重为 0 意味着对应特征被完全忽略
- 等价于自动做了特征选择
3.4 怎么设
| 场景 | 调整 |
|---|---|
| 数据量少 | 增大(更易过拟合,需更强约束) |
| 模型复杂 | 增大 |
| 特征多 | 增大 |
| 一般初始值 | 或 |
过大 → 欠拟合; 过小 → 正则化无效。
4. L2 正则化(Ridge / Weight Decay)
4.1 公式
4.2 惩罚项如何工作
- 的导数 =
- 参数离 0 越远,梯度越大(“推回”力度越强)
- 参数越接近 0,梯度越小(“推回”力度越弱)
4.3 效果
L2 倾向整体收缩系数,但通常不产生大量精确的 0;不能断言任何参数都不可能为 0。
所有参数被均匀地往 0 的方向压缩,但不消失。避免模型过度依赖某些特征,同时保留所有特征的贡献。
5. L1 vs L2 — 核心区别
| L1 | L2 | |
|---|---|---|
| 惩罚项 | ||
| 导数 | (常数) | (与参数值成正比) |
| 参数最终状态 | 合适的求解器可产生稀疏解 | 通常整体收缩,不专门诱导稀疏 |
| 常见作用 | 线性模型中可用于特征选择 | 抑制较大系数;与衰减的关系取决于优化器 |
| 使用频率 | 较少 | 默认选择 |
为什么 L1 产生稀疏解而 L2 不产生?
L1:零点不可微,次梯度与软阈值机制使稀疏解成为可能
L2:梯度 = 2θ,惩罚随参数大小变化,通常收缩系数
上述比较描述正则项的作用,实际更新还包含数据损失的梯度。稀疏解是否得到,还与目标函数、正则强度和求解器有关。
一般情况下默认使用 L2 正则化,实际中 L1 使用较少。
6. PyTorch 实现
6.1 手动加入 L2 正则化
l2_norm = sum(param.pow(2).sum() for param in model.parameters())
loss = criterion(outputs, labels) + 1e-4 * l2_norm
6.2 更简单的方式:优化器内置 Weight Decay
以普通 SGD 为例,可以通过 weight_decay 向梯度加入线性收缩项:
optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=1e-4)
注意系数约定:SGD 的 weight_decay=a 对应损失中加入 。因此,上面的 1e-4 * l2_norm 对应 weight_decay=2e-4,不能直接使用同一个系数。AdamW 的解耦衰减也不等价于把 L2 项加进 Adam 的损失,详见权重衰减。
7. 总结
过拟合 → 模型太复杂 → 需要约束 → 正则化
正则化 = 损失函数 + 惩罚项
├── L1:λ·Σ|θ| → 参数可以变成 0(稀疏,特征选择)
└── L2:λ·Σθ² → 倾向缩小参数,通常不诱导稀疏
奥卡姆剃刀:能解释同样现象时,选最简单的那个。
正则化就是剃刀的数学化实现 — 逼着模型在"准确"和"简单"之间找到最优平衡。
实践:
默认用 L2(weight_decay=1e-4)
L1 用于需要自动特征选择的场景
两者也可以组合使用(Elastic Net)