文章目录
硬件配置:
- Windows 11 + WLS2 + Ubuntu-24.04
- Intel®Core™i7-12700H
- NVIDIA GeForce RTX 3070 Ti Laptop GPU
软件环境:
- Pycharm 2025.1.3.1
- Python 3.13.5
- Pytorch 2.7.1+cu128
1 权重衰退

权重衰退(Weight Decay),也称为L2正则化,是深度学习中防止过拟合的常用技术。它通过限制模型参数的大小来控制模型复杂度,从而提高模型的泛化能力。
1.1 核心思想
权重衰退的核心思想是:在优化损失函数的同时,惩罚较大的权重值。具体来说:
硬性限制:直接限制权重参数的L2范数不超过某个阈值 θ θ θ
- 数学表达: m i n L ( w , b ) s u b j e c t t o ∥ w ∥ 2 ≤ θ \mathrm{min}\ \ \mathcal{L}(\mathbf{w},b)\quad\mathrm{subject\;to}\ \ \|\mathbf{w}\|^{2}\leq\theta min L(w,b)subjectto ∥w∥2≤θ
- 这意味着每个权重值都被限制在 [ − θ , θ ] [-\sqrt{θ}, \sqrt{θ}] [−θ,θ]范围内
柔性限制(更常用):在损失函数中添加L2正则项
- 数学表达: min ℓ ( w , b ) + λ 2 ∥ w ∥ 2 \operatorname*{min}\;{\ell(\mathbf{w},b)}+{\displaystyle\frac{\lambda}{2}}\|\mathbf{w}\|^{2} minℓ(w,b)+2λ∥w∥2
- 通过超参数 λ λ λ控制正则化的强度
1.2 原理与推导
在原始损失函数基础上添加L2惩罚项:
J ( w ) = L ( w ) + λ 2 ∣ ∣ w ∣ ∣ 2 J(w)=L(w)+\frac\lambda2||w||^2 J(w)=L(w)+2λ∣∣w∣∣2
其中:
- L ( w ) L(w) L(w):原始损失函数
- λ \lambda λ:正则化系数(超参数)
- ∣ ∣ w ∣ ∣ 2 = ∑ w i 2 ||w||^2=\sum w_i^2 ∣∣w∣∣2=∑wi2:权重向量的L2范数平方
考虑SGD(随机梯度下降)的权重更新过程:
原始SGD更新:
w t + 1 = w t − η ∇ L ( w t ) w_{t+1}=w_t-\eta\nabla L(w_t) wt+1=wt−η∇L(wt)加入L2正则化后的更新:
w t + 1 = w t − η ( ∇ L ( w t ) + λ w t ) = ( 1 − η λ ) w t − η ∇ L ( w t ) w_{t+1}=w_t-\eta(\nabla L(w_t)+\lambda w_t)\\=(1-\eta\lambda)w_t-\eta\nabla L(w_t) wt+1=wt−η(∇L(wt)+λwt)=(1−ηλ)wt−η∇L(wt)
可以看到,每次更新时权重先缩小( 1 − η λ 1-\eta\lambda 1−ηλ)倍,再进行常规的梯度下降,这正是"权重衰退"名称的由来。
1.3 几何解释
用等高线图直观解释权重衰退的作用:
- 原始最优解(仅优化损失 L L L):位于损失函数"谷底"(绿色等高线中心)
- 加入正则项后:相当于增加了以原点为中心的二次约束(黄色等高线)
- 新最优解:位于损失函数与正则项的平衡点(黄绿等高线交界处)
这样,最优解被"拉向"原点,权重值整体变小,模型复杂度降低。

2 丢弃法

2.1 重新审视过拟合
- 当特征多而样本少时,线性模型容易过拟合
- 当样本多而特征少时,线性模型通常不会过拟合
- 线性模型的主要问题:无法考虑特征间的交互作用,必须为每个特征单独指定权重
偏差-方差权衡
- 线性模型:
- 高偏差:只能表示一小类函数
- 低方差:在不同数据样本上结果相似
- 深度神经网络:
- 位于偏差-方差谱的另一端
- 能学习特征间的复杂交互(如"尼日利亚"和"西联汇款"一起出现表示垃圾邮件)
2.2 扰动的稳健性
好模型的标准
- 在未知数据上表现良好
- 经典理论认为简单模型有助于缩小训练-测试差距
- 简单性体现为:小维度、参数小范数
平滑性的重要性
- 函数应对输入微小变化不敏感(如对图像加噪声影响不大)
- Bishop(1995)证明:输入噪声训练 ≈ Tikhonov正则化
- 连接了"函数光滑"和"对噪声适应性"

2.3 丢弃法的提出
Srivastava等(2014)将噪声注入扩展到网络内部层。
- 动机:深层网络需要在各层都增强平滑性
- 名称来源:训练过程中随机"丢弃"一些神经元
- 类比:有性繁殖打破基因共适应 → Dropout打破神经元共适应
噪声注入的关键
- 需要无偏的方式注入噪声
- 使每层期望值等于无噪声时的值
- Bishop方法:对线性模型输入加高斯噪声
- Dropout方法:
- 以概率p将激活值置零
- 通过保留节点的分数(1-p)进行规范化,保持期望不变

2.4 实践
- 以前馈神经网络为例,在训练中使用 Dropout:
- 对隐藏层以概率p随机置零部分神经元
- 相当于每次训练一个不同的子网络
- 前向传播和反向传播都只通过未被丢弃的神经元

- 通常不在测试时使用Dropout
- 直接使用完整网络进行预测

效果
- 防止网络过度依赖任何一个神经元
- 促进网络的鲁棒性和泛化能力
- 类似于一种模型集成方法(训练多个子网络组合)
2.5 通俗理解
Dropout就像在训练神经网络时,每次随机让一部分神经元"请假"。这样做的好处是:
- 防止网络变得懒惰:不让某些神经元过度依赖其他神经元工作,迫使每个神经元都要有独立判断能力
- 增强鲁棒性:就像团队中有成员缺席时仍能正常工作,这样的团队更可靠
- 类似集体智慧:相当于训练了很多不同的子网络,最后组合它们的智慧
2.6 简洁实现
我们使用Fashion-MNIST数据集,定义具有两个隐藏层的多层感知机,每个隐藏层包含256个单元。
将暂退法应用于每个隐藏层的输出(在激活函数之后), 并且可以为每一层分别设置暂退概率: 常见的技巧是在靠近输入层的地方设置较低的暂退概率。 下面的模型将第一个和第二个隐藏层的暂退概率分别设置为0.2和0.5, 并且暂退法只在训练期间有效。
import torch
from torch import nn
from d2l import torch as d2l
dropout1, dropout2 = 0.2, 0.5
num_epochs, lr, batch_size = 10, 0.5, 256
loss = nn.CrossEntropyLoss(reduction='none')
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
net = nn.Sequential(nn.Flatten(),
nn.Linear(784, 256),
nn.ReLU(),
# 在第一个全连接层之后添加一个dropout层
nn.Dropout(dropout1),
nn.Linear(256, 256),
nn.ReLU(),
# 在第二个全连接层之后添加一个dropout层
nn.Dropout(dropout2),
nn.Linear(256, 10))
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights)
trainer = torch.optim.SGD(net.parameters(), lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
