2025-08-25
算法
00

目录

1. L1正则化(L1 Regularization)
标准损失函数 (无正则化)
加入L1正则化的损失函数
梯度下降分析
2. L2正则化(L2 Regularization)
标准损失函数 (无正则化)
L2正则化的损失函数:
梯度分析
二者对比
如何选择和使用

在训练Ai模型的过程中,常常会遇到一个棘手的问题——过拟合(Overfitting)。当企图增加epoch提高精度的时候,发现accurancy的值始终徘徊,而测试集的损失开始不降反增,则意味着来到了过拟合的阶段,此时要么停止训练,要么选择一些特殊的手段来优化网络,比如本文提到的两种正则化技术:L1正则化和L2正则化。

1. L1正则化(L1 Regularization)

在线性模型中也被称为Lasso回归(Lasso Regression),是另一种广泛用于防止模型过拟合的技术。它与L2正则化非常相似,都是通过在损失函数中添加一个惩罚项来实现的,但惩罚的方式有所不同。

核心思想:L1正则化添加的惩罚项是模型所有参数(权重)的绝对值和。这种惩罚方式有一个非常独特且强大的特性:它倾向于将不重要的特征的权重精确地压缩到零。

我们同样以一个标准的损失函数为基础,看看加入L1正则化项后它会变成什么样。

标准损失函数 (无正则化)

J(w,b)=1mi=1mL(y^(i),y(i))\begin{aligned} {J ( w , b )} & {{}=\frac{1} {m} \sum_{i=1}^{m} L ( \hat{y}^{( i )} , y^{( i )} )} \\ \end{aligned}

加入L1正则化的损失函数

Jregularized(w,b)=1mi=1mL(y^(i),y(i))(Data Loss)+λmj=1nwjL1正则化项(Penalty Term)J_{r e g u l a r i z e d} ( w , b )=\underbrace{\frac{1} {m} \sum_{i=1}^{m} L ( \hat{y}^{( i )} , y^{( i )} )}_{\mathrm{} \, ( \mathrm{D a t a ~ L o s s} )}+\underbrace{\frac{\lambda} {m} \sum_{j=1}^{n} | w_{j} |}_{\mathrm{L 1 正则化项} \, ( \mathrm{P e n a l t y ~ T e r m} )}
  • j=1nwj\sum_{j=1}^{n} | w_{j} | :表示模型中所有权重(同样不包括偏置项 b)的绝对值之和。这在数学上被称为权重的 L1范数,记作w1| | \boldsymbol{w} ||_{1}

  • λλ(Lambda): 同样是正则化参数,控制着正则化的强度。λ越大,模型就越倾向于将更多权重变为零,模型的稀疏性就越强。

  • 1m\frac{1} {m} :缩放因子。

梯度下降分析

在模型训练(如使用梯度下降)时,L1正则化项对梯度的影响是关键。wj| w_{j} |的导数是sign(wj) \mathrm{s i g n} ( w_{j} ) (当wj0w_{j} \neq0),即:

wjwj={1ifwj>01ifwj<0\cfrac{\partial} {\partial w_{j}} | w_{j} |=\begin{cases} {1} & {\mathrm{i f} \, w_{j} > 0} \\ {-1} & {\mathrm{i f} \, w_{j} < 0} \\ \end{cases}

于是,梯度下降的更新规则大致变为:

wj:=wjα[(原始梯度部分)+λmsign(wj)]w_{j} :=w_{j}-\alpha\left[ ( 原始梯度部分 )+\frac{\lambda} {m} \mathrm{s i g n} ( w_{j} ) \right]

与L2的权重衰减不同,L1正则化项在梯度中增加了一个恒定的值,+λmλm+\frac {\lambda}{m} 或-\frac {\lambda}{m} 这意味着,无论权重的大小(只要它不为零),每次更新时都会朝着零的方向被“推”一个固定的步长。

L1的惩罚是恒定的。即使权重已经非常小(例如0.001),它仍然会受到一个固定的“拉力”把它往0拉。这使得权重很容易跨过0点,并被固定在0上。这个就是L1正则化的效果:它迫使模型只保留最有效的特征(权重不为零),而将其他所有无关或冗余的特征“关闭”(权重变为零)

2. L2正则化(L2 Regularization)

在线性模型中也常被称为岭回归(Ridge Regression),是一种在机器学习和统计学中广泛使用的技术,其主要目的是防止模型过拟合(Overfitting)。

举个例子,一个学生参加考试:

  • 没有正则化 (λ=0):只关心考试成绩,可能会用非常复杂的方法去解题(模型权重可以变得很大),即使这些方法只对特定题目有效。这就像模型完美拟合了训练数据,但泛化能力差(过拟合)。

  • 有L2正则化 (λ>0):你现在必须在“提高考试成绩”和“保持作业简洁”之间找到一个平衡。你不会再使用那些虽然能提高一点点分数但极其复杂的方法,因为“简洁度”的扣分会得不偿失。你会倾向于使用更通用、更简单的方法来解题。这就像模型找到了一个权重较小的解,从而获得了更好的泛化能力。

核心思想:在模型的损失函数(Cost Function)中加入一个惩罚项,这个惩罚项是模型所有参数(权重)的平方和。通过这种方式,它会“惩罚”那些值过大的权重,迫使模型在学习时倾向于选择更小、更分散的权重值。

标准损失函数 (无正则化)

J(w,b)=1mi=1mL(y^(i),y(i))\begin{aligned} {J ( w , b )} & {{}=\frac{1} {m} \sum_{i=1}^{m} L ( \hat{y}^{( i )} , y^{( i )} )} \\ \end{aligned}

L2正则化的损失函数:

Jregularized(w,b)=1mi=1mL(y^(i),y(i))(Data  Loss)+λ2mj=1nwj2L2正则化  (Penalty  Term)J_{r e g u l a r i z e d} ( w , b )=\underbrace{\frac{1} {m} \sum_{i=1}^{m} L ( \hat{y}^{( i )} , y^{( i )} )}_{ ( \mathrm{D a t a \; L o s s} )}+\underbrace{\frac{\lambda} {2 m} \sum_{j=1}^{n} w_{j}^{2}}_{\mathbb{L} 2 正则化 \; \mathrm{( P e n a l t y \; T e r m )}}
  • j=1nwj2\sum_{j=1}^{n} w_{j}^{2}:表示所有权重(不包括偏置项 b)的平方和。这在数学上被称为权重的 L2范数的平方,记作w22| | \boldsymbol{w} | |_{2}^{2}
  • 12m\frac {1}{2m}这是一个缩放因子,主要是为了在后续计算梯度时方便(求导后 2 恰好可以被约掉),对正则化的本质没有影响。
  • λλ(Lambda): 这是正则化参数或惩罚系数。它是一个超参数,需要我们手动设置。它控制着正则化的强度。

梯度分析

在模型训练(如使用梯度下降)时,L2正则化项对梯度的影响是让权重在每次更新时都“衰减”一点。 对添加正则化项后的损失函数求导:

wjJregularized=(原始梯度部分)+λmwj\frac{\partial} {\partial w_{j}} J_{r e g u l a r i z e d}= (原始梯度部分)+ \frac{\lambda}{m}w_j

于是,更新规则变为:

wj:=wjα[(原始梯度部分)+λmwj]w_{j} :=w_{j}-\alpha\left[ ( 原始梯度部分)+\frac{\lambda} {m} w_{j} \right]

合并同类项得到:

wj:=wj(1αλm)α(原始梯度)w_{j} :=w_{j} ( 1-\frac{\alpha\lambda} {m} )-\alpha(原始梯度 )

根据公式可以知道:学习率α\alpha 和 惩罚系数λ\lambda 值都很小,mm表示样本数量,比较大。并且三个参数都是正值,所以 1αλm1-\frac{\alpha\lambda} {m} 是一个小于1数值,**这意味着:每次梯度更新,都会衰减,逐渐变小。**因此,L2正则化也被称为权重衰减。

二者对比

特性L2 正则化 (岭回归)L1 正z则化 (Lasso)
惩罚项权重的平方和 (wj2\sum w_j^2)权重的 绝对值和 ( \sum | wjw_j | )
对权重的影响使权重趋向于0,但很难变为精确的0。产生“平滑”的权重分布。能使不重要的特征权重精确地变为0
效果权重衰减(Weight Decay)稀疏性(Sparsity),可用于特征选择。

如何选择和使用

这个选择主要取决于数据特性和建模目标。 L2 正则化 (岭回归)是默认选项,尤其是需要防止过拟合,认为所有特征都可能对结果有贡献时,即使贡献很小,当特征之间存在多重共线性(高度相关)时,L2比L1更稳定。

当数据中存在大量无关或冗余的特征时可以选择尝试L1正则化,或者需要一个可解释性强的模型时。L1会把不重要特征的权重降为零,可以清楚地看到哪些特征是模型做出预测的关键。

注意:如果有一组高度相关的特征,L1可能会随机选择其中一个保留,而将其他的权重设为零。

Example:

import torch import torch.nn as nn import torch.optim as optim # 1. 准备数据 (虚拟数据) X_train = torch.randn(100, 10) # 100个样本, 10个特征 y_train = torch.randn(100, 1) # 对应的目标值 # 2. 定义模型 class SimpleModel(nn.Module): def __init__(self): super(SimpleModel, self).__init__() self.linear1 = nn.Linear(10, 5) self.relu = nn.ReLU() self.linear2 = nn.Linear(5, 1) def forward(self, x): x = self.linear1(x) x = self.relu(x) x = self.linear2(x) return x model = SimpleModel() # 3. 定义损失函数 criterion = nn.MSELoss() # 4. 定义优化器并设置 weight_decay # 这就是L2正则化的关键所在! learning_rate = 0.01 # weight_decay 的值通常是一个小的正数, 比如 1e-4, 1e-5 等 # 这个值就是正则化强度 lambda weight_decay_lambda = 1e-4 # 使用 Adam 优化器,并传入 weight_decay 参数 optimizer = optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay_lambda) # optimizer = optim.SGD(model.parameters(), lr=learning_rate, weight_decay=weight_decay_lambda) # 也可以用SGD # 5. 训练循环 num_epochs = 100 for epoch in range(num_epochs): # 前向传播 outputs = model(X_train) loss = criterion(outputs, y_train) # 反向传播和优化 optimizer.zero_grad() # 清空之前的梯度 loss.backward() # 计算梯度 optimizer.step() # 更新权重 (已包含L2正则化) if (epoch+1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') # 训练后可以查看权重范数,与不加正则化的模型对比会发现权重值更小 total_norm = 0 for p in model.parameters(): if p.grad is not None: param_norm = p.data.norm(2) # 计算L2范数 total_norm += param_norm.item() ** 2 print(f'Sum of squared L2 norms of weights: {total_norm**0.5:.4f}')

在代码中的weight_decay 参数相当于以下公式中的λ\lambda:

wt=wt1α(Joriginal(wt1)+λwt1)w_{t}=w_{t-1}-\alpha( \nabla J_{\mathrm{o r i g i n a l}} ( w_{t-1} )+\lambda w_{t-1} )

或者参考AdamW算法论文中的公式:

θt+1=(1λ)θtαft(θt),\boldsymbol{\theta}_{t+1}=( 1-\lambda) \boldsymbol{\theta}_{t}-\alpha\nabla\boldsymbol{f}_{t} ( \boldsymbol{\theta}_{t} ) ,

本文作者:James

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!