跳到主要内容

正则化技术的概念

正则化技术是什么?

Regularization,中文翻译过来可以称为正则化,或者是规范化。什么是规则?闭卷考试中不能查书,这就是规则,一个限制。同理,在这里,规则化就是说给损失函数加上一些限制,通过这种规则去规范他们再接下来的循环迭代中,不要自我膨胀。

提示

正则化技术的工作原理是在模型的损失函数中添加一个惩罚项,以约束模型的复杂性。这个惩罚项通常与模型参数的大小或复杂性有关。通过添加这个惩罚项,正则化鼓励模型选择更简单、更平滑的函数,从而防止过拟合。

更简单的介绍

假设你要做一道菜,你有很多种调料可以选择,比如盐、酱油、醋、糖等等。如果你用太多的调料,你可能会把菜的原味都掩盖掉,而且对身体不好,这就是过拟合。如果你用太少的调料,你可能会觉得菜太淡,没有味道,这就是欠拟合。所以你要找一个合适的调料数量,既能提升菜的口感,又能保持菜的原味,这就是正则化。

正则化的一种常见方法是在做菜时给自己设定一个预算,比如不能超过10元。这个预算可以看作是对调料的惩罚。如果调料太贵或太多,就会导致预算超支,从而增加做菜的成本。所以做菜时会倾向于选择较便宜或较少的调料,从而降低做菜的复杂度。预算有不同的形式,比如不能超过 10 元的总和,或者不能超过5元的最大值。这些不同的形式对应了不同的正则化方法,比如 L1 正则化和 L2 正则化。

常见的正则化

常见的正则化技术有L1正则化和L2正则化。

  1. L1正则化 (Lasso正则化)

L1正则化在损失函数中添加了模型参数的绝对值之和作为正则项。其形式为:

LL1=L0+λi=1nwiL_{L1} = L_0 + \lambda \sum_{i=1}^{n} |w_i|

其中,L0L_0 是原始的损失函数,wiw_i 是模型的参数,λ\lambda 是正则化系数。

L1正则化的一个特点是它倾向于产生稀疏的权重向量,这意味着模型的许多参数会被设置为零。

  1. L2正则化 (Ridge正则化)

L2正则化在损失函数中添加了模型参数的平方和作为正则项。其形式为:

LL2=L0+λi=1nwi2L_{L2} = L_0 + \lambda \sum_{i=1}^{n} w_i^2

与L1正则化不同,L2正则化不会产生稀疏的权重向量,但它会使权重向量的各个元素都很小。

  1. 图表示例

为了更直观地理解L1和L2正则化,我们可以考虑一个简单的线性回归问题,并观察不同正则化技术对模型参数的影响。下面,我将生成一个图表来展示L1和L2正则化对模型参数的影响。

让我们开始吧!

下面是一个图表,展示了L1和L2正则化对模型参数的影响:

L1 and L2 Regularization

从图中可以看出:

  • L1正则化 (红色): 当模型参数 ww 增加或减少时,正则化惩罚线性增加。这导致了模型参数的稀疏性,因为较小的参数值会被优化为零。

  • L2正则化 (蓝色): 当模型参数 ww 增加或减少时,正则化惩罚呈二次增加。这使得模型的参数都接近于零,但不完全为零。

总之,正则化技术通过在损失函数中添加一个正则项来限制模型的复杂度,从而防止过拟合。选择哪种正则化技术取决于具体的应用和需求。

常见的正则化技术

1. L1正则化(Lasso正则化)

L1正则化通过在损失函数中添加模型权重的绝对值之和作为惩罚项来实现。L1正则化的损失函数可以表示为: J=Joriginal+λiwiJ = J_{\text{original}} + \lambda \sum_{i} |w_i| 其中:

  • JoriginalJ_{\text{original}} 是原始的损失函数。
  • wiw_i 是模型的权重。
  • λ\lambda 是正则化强度参数。

L1正则化的一个有趣的性质是它倾向于产生稀疏权重矩阵,即许多权重为零,这可以用于特征选择。

2. L2正则化(Ridge正则化或权重衰减)

L2正则化通过在损失函数中添加模型权重的平方和作为惩罚项来实现。L2正则化的损失函数可以表示为: J=Joriginal+λ2iwi2J = J_{\text{original}} + \frac{\lambda}{2} \sum_{i} w_i^2 其中的符号与上述L1正则化中的相同。

L2正则化倾向于产生较小的权重值,但不一定是稀疏的。

3. Elastic Net正则化

Elastic Net正则化结合了L1和L2正则化的特性。Elastic Net正则化的损失函数可以表示为: J=Joriginal+λ1iwi+λ2iwi2J = J_{\text{original}} + \lambda_1 \sum_{i} |w_i| + \lambda_2 \sum_{i} w_i^2 其中:

  • λ1\lambda_1λ2\lambda_2 是控制L1和L2正则化强度的参数。

正则化技术通常在模型训练过程中与其他优化算法(如梯度下降)一起使用,以最小化包含正则化项的损失函数。不同类型的正则化技术在不同的应用场景中可能更为有效,选择哪种正则化技术通常取决于具体的应用和问题。

权重衰减(L2)怎么使用?

权重衰减是一种正则化技术,用于防止机器学习模型过拟合。在神经网络和线性回归等模型中,权重衰减主要通过在损失函数中添加一个与模型权重相关的惩罚项来实现。

具体来说,权重衰减是L2正则化的一种形式。对于神经网络,损失函数 JJ 通常由两部分组成:原始损失(如交叉熵损失或均方误差)和正则化项。权重衰减的损失函数可以表示为: J=Joriginal+λ2iwi2J = J_{\text{original}} + \frac{\lambda}{2} \sum_{i} w_i^2 其中:

  • JoriginalJ_{\text{original}} 是不包含正则化的原始损失。
  • wiw_i 是模型的权重。
  • λ\lambda 是正则化参数,通常称为权重衰减系数。它决定了正则化的强度。

权重衰减的主要思想是鼓励模型使用较小的权重,而不是较大的权重。这是基于一个观察:具有较小权重的模型往往更简单,更不容易过拟合。通过添加一个与权重的平方成正比的惩罚项,模型在训练过程中会受到鼓励,使其权重尽可能小。

在实践中,权重衰减可以通过以下方式实现:

  1. 在每次权重更新时,首先将权重乘以一个小于1的因子(通常接近1,如0.99)。
  2. 然后再进行常规的基于梯度的权重更新。

这种方法确保权重在每次更新时都会略微减小,从而实现权重衰减的效果。

在许多深度学习框架中,如PyTorch和TensorFlow,权重衰减可以直接作为优化器的一个参数来设置,从而简化了其应用。

在PyTorch中,使用权重衰减非常简单。大多数优化器,如 torch.optim.SGDtorch.optim.Adam,都有一个 weight_decay 参数,你可以设置这个参数来应用权重衰减。

以下是如何在PyTorch中使用权重衰减的示例:

import torch.optim as optim

# 定义模型、损失函数等...
model = ... # 你的模型
criterion = ... # 你的损失函数

# 使用SGD优化器并设置权重衰减
optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=0.1)

在上面的代码中,我们设置了 weight_decay 参数为0.1,这意味着L2正则化项将被添加到损失函数中。

当你使用权重衰减时,优化器会自动为你处理正则化,你不需要在损失函数中手动添加任何东西。

选择合适的权重衰减系数 λ\lambda 是一个超参数调优的问题。太大的 λ\lambda 可能会导致模型欠拟合,而太小的 λ\lambda 可能不足以防止过拟合。通常,你可以通过交叉验证来选择一个合适的 λ\lambda 值。

PyTorch 正则化使用例子

该示例将展示如何在线性回归模型中应用L1和L2正则化,并通过图形展示训练过程中的损失变化。

import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

# 设置随机种子以确保结果的可重复性
torch.manual_seed(42)

# 生成模拟数据
# linspace 函数的主要目的是在指定的开始和结束值之间生成一个均匀间隔的数值序列。
# torch.linspace(start, end, steps) 返回值是一个一维张量,其中包含从 start 到 end 的 steps 个均匀间隔的数值。
x = torch.linspace(-1, 1, 100).view(100, 1)
y = 2 * x + torch.randn(x.size()) * 0.3

# 定义线性回归模型
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(1, 1)

def forward(self, x):
return self.linear(x)

# 实例化模型
model = LinearRegression()

# 定义MSE损失函数
criterion = nn.MSELoss()

# 使用SGD优化器,并设置L2正则化系数为0.1
optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=0.1)

# 训练模型
num_epochs = 100
losses = []
for epoch in range(num_epochs):
# 前向传播
outputs = model(x)
loss = criterion(outputs, y)

# 手动添加L1正则化
l1_regularization = torch.norm(model.linear.weight, 1)
loss += 0.1 * l1_regularization

# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()

# 记录损失
losses.append(loss.item())

# 绘制损失变化图
plt.plot(losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Loss vs. Epoch with L1 and L2 Regularization')
plt.show()

代码说明:

  1. 数据生成:我们创建了一个简单的线性关系的数据集,并添加了一些噪声。
  2. 模型定义:定义了一个简单的线性回归模型。
  3. 损失函数和优化器:使用均方误差作为损失函数,并选择SGD作为优化器。通过weight_decay参数,我们为模型添加了L2正则化。
  4. 训练循环:在每个epoch中,我们首先进行前向传播以获取模型的输出,然后计算损失。我们手动添加了L1正则化项到损失中。然后进行反向传播和优化步骤。
  5. 绘图:我们记录了每个epoch的损失,并在训练结束后绘制了损失变化图。

运行上述代码后,您将看到一个损失随着epoch数增加而减少的图,这表明模型正在学习。L1和L2正则化帮助模型避免过拟合,并使其更加健壮。

最后输出的图