不仅在训练数据上表现好,而且能在新输入上泛化好的算法。在机器学习中,许多策略被显式地设计来减少测试误差(可能会以增大训练误差为代价)。这些策略被统称为正则化。我们将在后文看到,深度学习工作者可以使用许多不同形式的正则化策略。事实上,开发更有效的正则化策略已成为本领域的主要研究工作之一。 在深度学习的背景下,大多数正则化策略都会对估计进行正则化。估计的正则化以偏差的增加换取方差的减少。一个有效的正则化是有利的“交易”,也就是能显著减少方差而不过度增加偏差。我们在第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 则是**正则化**技术 两者经常一起使用,共同提升模型的训练效果和最终性能!