正则化
正则化防止模型死记硬背训练数据(过拟合),让它学到真正的规律。
Dropout:随机丢弃
Section titled “Dropout:随机丢弃”训练时随机丢弃 比例的神经元,强迫网络不依赖任何单个特征:
import torch.nn as nn
dropout = nn.Dropout(p=0.2)
x = torch.randn(3, 10)output = dropout(x) # 训练时约 20% 的值变为 0print(f"非零比例: {(output != 0).sum().item() / output.numel():.1%}")原理:每次训练迭代,Dropout 创建了一个不同的”子网络”。推理时相当于多个子网络的集成。
| p 值 | 场景 |
|---|---|
| 0.1 | 输入层,轻微正则化 |
| 0.2-0.3 | 隐藏层,常用值 |
| 0.5 | 过拟合严重时 |
Weight Decay:惩罚大权重
Section titled “Weight Decay:惩罚大权重”在损失中加入权重的 L2 范数,鼓励权重保持较小值:
# AdamW 的 weight_decay 是真正的 L2 正则化optimizer = torch.optim.AdamW(model.parameters(), lr=0.001, weight_decay=0.01)数据增强:扩充训练数据
Section titled “数据增强:扩充训练数据”from torchvision import transforms
# 图像增强augment = transforms.Compose([ transforms.RandomHorizontalFlip(p=0.5), transforms.RandomRotation(15), transforms.ColorJitter(brightness=0.2, contrast=0.2), transforms.RandomCrop(32, padding=4),])Early Stopping
Section titled “Early Stopping”验证集损失不再下降时停止训练,防止过拟合:
best_loss = float('inf')patience = 5patience_counter = 0
for epoch in range(epochs): train_loss = train_one_epoch() val_loss = validate()
if val_loss < best_loss: best_loss = val_loss torch.save(model.state_dict(), 'best_model.pt') patience_counter = 0 else: patience_counter += 1 if patience_counter >= patience: print(f"Early stopping at epoch {epoch}") breakLabel Smoothing
Section titled “Label Smoothing”标签不要 100% 确定,给错误类别留一点概率:
# 原始: [1, 0, 0] → 平滑后: [0.933, 0.033, 0.033]criterion = nn.CrossEntropyLoss(label_smoothing=0.1)完整的正则化示例
Section titled “完整的正则化示例”class RegularizedMLP(nn.Module): def __init__(self): super().__init__() self.model = nn.Sequential( nn.Linear(784, 256), nn.BatchNorm1d(256), # 归一化也是正则化 nn.ReLU(), nn.Dropout(0.3), # Dropout nn.Linear(256, 128), nn.BatchNorm1d(128), nn.ReLU(), nn.Dropout(0.2), nn.Linear(128, 10), )
def forward(self, x): return self.model(x)💡 训练时
model.train()→ Dropout 和 BatchNorm 生效;推理时model.eval()→ 自动关闭。