不仅在训练数据上表现好,而且能在新输入上泛化好的算法。在机器学习中,许多策略被显式地设计来减少测试误差(可能会以增大训练误差为代价)。这些策略被统称为正则化。我们将在后文看到,深度学习工作者可以使用许多不同形式的正则化策略。事实上,开发更有效的正则化策略已成为本领域的主要研究工作之一。
在深度学习的背景下,大多数正则化策略都会对估计进行正则化。估计的正则化以偏差的增加换取方差的减少。一个有效的正则化是有利的“交易”,也就是能显著减少方差而不过度增加偏差。我们在第5章中讨论泛化和过拟合时,主要侧重模型族训练的3种情况:(1)不包括真实的数据生成
(Normalization)和正则化(Regularization)是两个不同的概念,虽然名字相似,但目的和作用完全不同。
不是归一化
我用最通俗的方式来解释这两个概念:
# 用考试来打比方
## **正则化 = 防止"死记硬背"**
想象一个学生准备考试:
**过拟合的学生:**
- 把所有练习题的答案都背下来了
- 练习题100分,但真实考试只有60分
- 因为他只是死记硬背,没真正理解
**正则化就像老师的对策:**
- **L1/L2正则化**:"不许写太复杂的解题步骤,越简单越好"
- **Dropout**:"考试时随机遮住你一半的笔记,逼你真正理解"
- **早停**:"只给你3天复习时间,防止你背答案"
- **数据增强**:"我把题目换个问法,看你是不是真懂了"
## **归一化 = 统一"计量单位"**
想象你在算一道数学题:
**没归一化的情况:**
```Java
小明的零花钱:5元
小明家到学校距离:3000米
小明的考试成绩:98分
问:哪个数字最重要?
```
计算机看到3000最大,以为距离最重要!
**归一化后:**
```Java
零花钱:0.05 (在0-100元范围内)
距离:0.3 (在0-10000米范围内)
成绩:0.98 (在0-100分范围内)
```
现在计算机知道成绩(0.98)才是最重要的!
# 更生活化的例子
## **正则化 = 健身时的"适可而止"**
- **不用正则化**:疯狂练某块肌肉→肌肉拉伤,其他部位薄弱
- **用正则化**:均衡训练→整体协调,真正强壮
具体方法:
- **L2正则化**:每块肌肉都练,但都不要练过头
- **L1正则化**:只练最重要的几块肌肉,其他的放弃
- **Dropout**:今天不练腿,明天不练胸,强迫其他部位代偿
## **归一化 = 做菜时的"统一切法"**
做菜时如果:
- 土豆切成大块(10分钟能熟)
- 胡萝卜切成丝(2分钟就熟)
- 肉切成厚片(15分钟才熟)
**结果**:要么土豆没熟,要么胡萝卜糊了
**归一化就是**:把所有食材切成差不多大小,这样能同时熟!
# 用神经网络训练打比方
## **为什么模型会"过拟合"?**
就像一个AI在学认猫:
- 训练集:看了100张你家橘猫的照片
- 学歪了:以为"猫=橘色+胖+你家沙发"
- 测试时:看到黑猫就不认识了
**正则化**:强迫AI不要记住"你家沙发"这种无关细节
## **为什么需要"归一化"?**
想象AI同时学习:
- 特征1:猫的体重(5-10公斤)= 数值范围5-10
- 特征2:猫的胡须数量(40-50根)= 数值范围40-50
- 特征3:猫叫声频率(700-1000赫兹)= 数值范围700-1000
**没归一化**:AI以为频率最重要(因为数字最大)**归一化后**:所有特征都变成0-1之间,AI能公平对待每个特征
# 一句话总结
- **正则化**:防止模型"死记硬背"训练数据
- 像老师防止学生背答案
- 像健身防止练偏
- 目的:让模型真正"理解"而不是"记住"
- **归一化**:把不同尺度的数据调整到同一标准
- 像把不同货币换算成人民币
- 像把食材切成同样大小
- 目的:让模型能公平对待所有特征
# 实际效果
```python
# 不用正则化
训练集准确率:99% # 背得很熟!
测试集准确率:70% # 一到考试就露馅
# 用了正则化
训练集准确率:92% # 没背答案
测试集准确率:88% # 真正理解了
# 不用归一化
训练100轮才收敛 # 像开车没放手刹
# 用了归一化
训练10轮就收敛 # 轻松多了
```
# 记忆口诀
**正则化**:
> "别学太死,灵活一点"(防止过拟合)
**归一化**:
> "大家站同一起跑线"(统一尺度)
这样理解是不是清楚多了?
# 1. **归一化 (Normalization)**
**目的**:加速训练、稳定梯度、改善收敛
## 常见类型
- **Batch Normalization (BN)**:对每个批次的特征进行标准化
- **Layer Normalization (LN)**:对每个样本的特征进行标准化(Transformer 常用)
- **RMSNorm**:Layer Norm 的简化版(你测试中用到的)
- **Group Normalization**:介于 BN 和 LN 之间
## 作用原理
```python
# Layer Normalization 示例
def layer_norm(x, gamma, beta, eps=1e-5):
mean = x.mean(dim=-1, keepdim=True)
var = x.var(dim=-1, keepdim=True)
x_normalized = (x - mean) / torch.sqrt(var + eps)
return gamma * x_normalized + beta
```
# 2. **正则化 (Regularization)**
**目的**:防止过拟合、提高泛化能力
## 常见类型
- **L1/L2 正则化**:在损失函数中添加权重惩罚项
- **Dropout**:训练时随机丢弃部分神经元
- **权重衰减 (Weight Decay)**:AdamW 中的 weight decay
- **数据增强**:也是一种正则化手段
## 作用原理
```python
# L2 正则化示例
loss = cross_entropy_loss + lambda * sum(p**2 for p in parameters)
# Dropout 示例
def dropout(x, p=0.5, training=True):
if training:
mask = torch.rand_like(x) > p
return x * mask / (1 - p)
return x
```
# 3. **关键区别**
|方面|归一化 (Normalization)|正则化 (Regularization)|
|---|---|---|
|**主要目的**|加速训练、稳定梯度|防止过拟合|
|**作用对象**|激活值/特征|模型参数/结构|
|**使用时机**|前向传播中|训练时(测试时通常关闭)|
|**对性能影响**|提升训练速度和稳定性|提升泛化能力|
# 4. **在 Transformer 中的应用**
```python
class TransformerBlock:
def __init__(self):
self.norm1 = RMSNorm() # 归一化
self.norm2 = RMSNorm() # 归一化
self.dropout = Dropout(p=0.1) # 正则化
def forward(self, x, training=True):
# 归一化稳定训练
x = x + self.dropout(self.attention(self.norm1(x)), training)
x = x + self.dropout(self.ffn(self.norm2(x)), training)
return x
```
所以在你的测试中:
- `test_rmsnorm` 测试的是**归一化**功能
- `test_gradient_clipping` 也可以看作一种训练稳定技术
- 而 AdamW 中的 weight decay 则是**正则化**技术
两者经常一起使用,共同提升模型的训练效果和最终性能!