介绍
正则化(Regularization)是 为防止模型过拟合、提升泛化能力,而设计的一系列策略/手段
核心逻辑
在模型训练过程中引入“额外约束”,平衡模型的“拟合能力”和“泛化能力”——既让模型能学到训练数据的规律,又不让它过度记住训练数据的噪声/特例。
类比
可以用一个简单的比喻理解:
- 未正则化的模型:一个死记硬背的学生,能背下所有练习题,但换个题型就不会;
- 正则化后的模型:一个理解知识点的学生,掌握核心规律,能应对新题型。
过拟合的根源 & 正则化的解决思路
先明确过拟合的核心原因,才能理解正则化的作用逻辑:
| 过拟合根源 | 正则化的解决思路 |
|---|---|
| 模型复杂度太高(参数过多) | 降低模型复杂度(如Dropout丢弃神经元、L1稀疏化权重) |
| 训练数据少/有噪声 | 扩充有效数据(数据增强)、惩罚噪声拟合(权重衰减) |
| 训练迭代过多 | 提前终止训练(早停) |
正则化的分类
按约束方式,正则化手段可分为三大类:
(1)参数约束类
直接对模型的可训练参数(权重/偏置)施加约束,避免参数取值极端:
L2正则化(权重衰减):
- 原理:损失函数 +=
λ * ||W||²(权重的L2范数),惩罚过大的权重,让权重分布更平滑; - 特点:最常用、最基础,几乎所有模型都适用;
- PyTorch实现:优化器中
weight_decay参数。
- 原理:损失函数 +=
L1正则化:
- 原理:损失函数 +=
λ * ||W||₁(权重的L1范数),让部分权重趋近于0,实现特征稀疏化; - 特点:适合高维特征、小样本场景,使用频率低于L2。
- 原理:损失函数 +=
(2)结构约束类
通过改变模型的训练结构,降低模型对局部特征的依赖:
Dropout(随机丢弃):
- 原理:训练时随机丢弃部分神经元,迫使模型不依赖单一神经元,学习更鲁棒的特征;
- 特点:深度学习专属,尤其适合全连接层、Transformer的FFN层。
归一化(BN/LN):
- 原理:对层输出做均值0、方差1的归一化,稳定训练过程,间接降低过拟合风险;
- 特点:既是训练加速工具,也是轻量正则化手段,Transformer中必用LayerNorm。
(3)训练过程约束类
从训练流程上限制模型的过度拟合:
早停(Early Stopping):
- 原理:监控验证集性能,当性能不再提升时停止训练,避免模型“死记”训练数据;
- 特点:所有模型必备,无额外计算成本。
数据增强:
- 原理:对训练数据做随机变换(如图像翻转、文本同义词替换),扩充有效训练样本;
- 特点:从源头解决“数据少”的问题,泛化效果最好的正则化手段之一。
正则化原则
(1)强度调优
正则化强度(如Dropout的p、权重衰减的λ)需适中:
- 过强:模型欠拟合(训练集/验证集效果都差);
- 过弱:模型仍过拟合(训练集效果好,验证集效果差);
- 常用经验值:
- 权重衰减:
1e-5 ~ 1e-3; - Dropout:
0.1 ~ 0.5(大模型用0.1~0.3,小模型用0.3~0.5)。
- 权重衰减:
(2)组合使用
单一正则化效果有限,实际项目中通常组合使用:
- 基础组合:权重衰减(L2) + 早停;
- 深度学习组合:权重衰减 + Dropout + LayerNorm + 数据增强;
- 小样本组合:权重衰减 + L1 + 早停 + 数据增强。
(3)推理阶段注意事项
部分正则化工具在推理时需关闭:
- Dropout、BatchNorm:通过
model.eval()切换到评估模式; - 权重衰减、L1、早停、数据增强:仅作用于训练阶段,推理无影响。
简单示例
正则化训练流程
import torch
import torch.nn as nn
import torch.optim as optim
# 1. 定义带正则化的模型
class SimpleModel(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(10, 20)
self.ln = nn.LayerNorm(20) # 归一化(轻量正则化)
self.dropout = nn.Dropout(p=0.2) # Dropout正则化
self.fc2 = nn.Linear(20, 2)
def forward(self, x):
x = self.ln(torch.relu(self.fc1(x)))
x = self.dropout(x) # 训练时生效
return self.fc2(x)
# 2. 初始化模型、优化器(权重衰减=L2正则化)
model = SimpleModel()
optimizer = optim.Adam(model.parameters(), lr=1e-3, weight_decay=1e-4) # L2正则化
loss_fn = nn.CrossEntropyLoss()
# 3. 训练流程(含早停)
best_val_loss = float('inf')
patience = 5
counter = 0
for epoch in range(100):
# 训练模式(启用Dropout/LN训练模式)
model.train()
# 模拟训练数据(实际需替换为真实数据加载)
x_train = torch.randn(32, 10)
y_train = torch.randint(0, 2, (32,))
output = model(x_train)
loss = loss_fn(output, y_train)
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 验证阶段(早停逻辑)
model.eval()
with torch.no_grad():
x_val = torch.randn(16, 10)
y_val = torch.randint(0, 2, (16,))
val_output = model(x_val)
val_loss = loss_fn(val_output, y_val)
# 早停判断
if val_loss < best_val_loss:
best_val_loss = val_loss
torch.save(model.state_dict(), 'best_model.pth')
counter = 0
else:
counter += 1
if counter >= patience:
print("早停触发,停止训练")
break
# 4. 推理阶段(关闭正则化)
model.eval()
with torch.no_grad():
x_test = torch.randn(1, 10)
pred = model(x_test)
print("推理结果:", pred.argmax(dim=1).item())
总结
- 正则化的核心是平衡拟合与泛化,通过添加约束防止模型过拟合;
- 正则化分为参数约束(L1/L2)、结构约束(Dropout/LN)、训练约束(早停/数据增强)三类;
- 实践中需组合使用正则化工具,并调优强度,推理时关闭Dropout等训练专属正则化。