权重衰减
了解权重衰减(L2正则化)的数学原理,掌握正则化技术在防止过拟合中的应用

展开文章目录
1. 从特征数量限制到权重大小控制
多项式回归的拟合测试让我们感性地意识到:“限制特征的数量”可用于缓解过拟合问题。让我们继续深入这个话题。
1.1 多项式复杂度的组合爆炸
多项式模型的阶数越高,模型的容量也就越大。对于具有个变量的阶多项式,其项数组合可能的个数有:

1.2 权重分布的理想状态
2. 惩罚权重向量的大分量
2.1 范数特性的利用
我们已经知道,范数比范数更容易受异常值的影响。利用这一特性,为了防止因单个变量具有过高的权重而导致过拟合,我们可以在损失函数中增加一个惩罚项来约束模型的复杂性。
正则化方法对比
L2正则化(权重衰减)
- 别名:Tikhonov正则化、岭回归
- 特点:对权重向量的大分量施加巨大惩罚
- 效果:平滑地减小所有权重,不会产生稀疏解
- 应用:最广泛使用的正则化技术之一
L1正则化(套索回归)
- 特点:范数是对模型参数简单性的度量
- 效果:一些特征的权重往往被直接置为零
- 应用:权重集中在一小部分特征上,实现特征选择和稀疏性
- 算法:构成套索回归(lasso regression)算法
2.2 L2正则化的数学表达
以线性回归模型中的损失函数为例,将范数作为惩罚项引入后,结合了权重衰减的新损失函数为:
参数说明
参数详解
- :原始损失函数
- :引入了正则化项的损失函数
- :权重衰减因子,属于超参数(是为了简化梯度计算而特意引入的常数因子)
- :权重向量范数的平方
L2正则化项的具体形式
对于向量,正则化表示为:
2.3 正则化算法对比
3. 权重衰减中的参数更新
3.1 梯度计算
在梯度下降法中(以 Mini-Batch SGD 为例),需要计算的梯度。
梯度分解
梯度计算
原损失函数的梯度:
这是不包含正则化项的原始梯度。
惩罚项的梯度:
这个梯度与权重向量本身成正比。
3.2 参数更新公式
结合两部分梯度,参数更新表示为:
等价变换
我们可以将上式重写为:
3.3 收缩因子的作用
权重衰减的直观理解
权重衰减理解
数学表达:
每次参数更新时,权重都会被乘以一个小于1的因子,这导致权重逐渐”衰减”到更小的值。
物理类比:
就像摩擦力会逐渐减慢运动物体的速度一样,权重衰减会逐渐减小模型参数的大小,防止它们变得过大。
实际应用:
- 防止模型过度拟合训练数据
- 提高模型的泛化能力
- 使模型对输入的小变化更加鲁棒
4. 权重衰减的实现要点
4.1 超参数选择
- 权重衰减系数:通常在[10^{-6\},10^{-2\}]范围内选择
- 学习率:需要与权重衰减系数协调选择
- 验证集调优:通过验证集性能选择最佳的值
4.2 实现注意事项
4.3 与其他正则化技术的结合
权重衰减可以与其他正则化技术结合使用:
5. PyTorch中的权重衰减实现
5.1 优化器中的权重衰减
在PyTorch中,大多数优化器都支持weight_decay参数:
import torch
import torch.nn as nn
import torch.optim as optim
# 定义模型
model = nn.Linear(10, 1)
# 使用权重衰减的优化器
optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=1e-4)
# 或者使用Adam优化器
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)
5.2 手动实现权重衰减
def train_with_weight_decay(model, data_loader, criterion, lr=0.01, weight_decay=1e-4):
for batch_idx, (data, target) in enumerate(data_loader):
# 前向传播
output = model(data)
loss = criterion(output, target)
# 手动添加L2正则化项
l2_reg = torch.tensor(0.)
for param in model.parameters():
l2_reg += torch.norm(param, p=2)
total_loss = loss + weight_decay * l2_reg
# 反向传播
total_loss.backward()
# 参数更新
with torch.no_grad():
for param in model.parameters():
param -= lr * param.grad
param.grad.zero_()
5.3 不同参数组的权重衰减
# 对不同层设置不同的权重衰减
optimizer = optim.Adam([
{'params': model.conv_layers.parameters(), 'weight_decay': 1e-4},
{'params': model.fc_layers.parameters(), 'weight_decay': 1e-3},
{'params': model.bias_params, 'weight_decay': 0} # 偏置项不使用权重衰减
], lr=0.001)
参考资料
如果这篇记录对你有帮助,可以留下一句回应。

DISCUSSION
讨论与回应
欢迎补充细节、指出问题,或分享与这篇文章有关的经验。
昵称与邮箱为必填项,邮箱仅用于头像和回复通知,不会公开。网址可以留空。