过拟合 & 正则化(L1,L2,Dropout)

推荐视频:

什么是 L1 L2 正规化 正则化 Regularization (深度学习 deep learning)_哔哩哔哩_bilibili

如何解决过拟合问题?L1、L2正则化及Dropout正则化讲解_哔哩哔哩_bilibili


过拟合

什么是过拟合?

过拟合是指模型在训练数据上表现良好(损失小,准确率高),但在新数据上表现很差的现象。

如何判断过拟合?

(1) 训练准确率高,测试阶段准确率明显变低;

(2) 训练损失持续下降,但是验证损失先将后升;

如何解决过拟合?

(1) 数据层面:增加数据量,减少对训练集噪声的记忆;数据增强,例如图像翻转、缩放、加噪等;

(2) 模型层面:减少模型参数,降低模型复杂度;

(3) 训练层面:调整训练策略,减少训练轮次,早停等手段;

(4) 正则化: L1,L2,Dropout等方法


L1,L2正则化

什么是正则化?

正则化(Regularization)是在损失函数中加入对模型参数的约束项,目的是让模型参数不过大、防止模型过度学习训练集的细节,从而提升对新数据的预测能力。

以线性回归为例,普通损失函数:

Loss = MSE = \frac{1}{n}\sum_{i=1}^{n}(y_i-\hat{y_i})^2

L1正则化:在损失函数后面加上所有参数绝对值的和,起到“让参数变小,甚至变为0”的作用。

Loss_{L1} = MSE+\lambda \sum_{j=1}^{p}\begin{vmatrix} w_j \end{vmatrix}

L1正则化会让很多参数变为0,实现自动特征选择(有利于高维稀疏数据);

也就是说部分参数会变为0,相当于直接去除部分特征。

L2正则化:在损失函数后加上所有参数的平方和,起到“让参数变小,但不为0”的作用。

Loss_{L2} = MSE+\lambda \sum_{j=1}^{p}w_j^2

  • 其中λ 是正则化系数,控制正则化项权重,w是参数。

L2会参数收缩,把参数压缩接近0,但一般不会变成0。

正则化后参数普遍较小,但不会直接为0,保留了所有特征。

正则化可视化

蓝色等高线为损失函数J(w),正则化的作用是让最终参数点既要尽量靠近损失函数最优点,又不能超出正则化约束区域。

目标是在约束区域内,找到使损失函数最小的点。

从损失函数的极小点出发,画等高线,等高线不断扩大,直到第一次碰到约束边界,这个交点就是正则化下的最优解。

  • 横轴为参数 w1,纵轴为参数 w2​。

  • 蓝色椭圆等高线代表“损失函数”J(θ)的等值线,也就是一组w1,w2损失值一样的点。

  • 橙色圆形/菱形分别是L2和L1正则化的“约束边界”:

L2\begin{vmatrix} w \end{vmatrix}_2 = \sqrt{w_1^2+w_2^2}\leqslant t,边界为圆。

L1\begin{vmatrix} w \end{vmatrix}_1 = \begin{vmatrix} w_1 \end{vmatrix} +\begin{vmatrix} w_2 \end{vmatrix} \leqslant t,边界为菱形。

  • 白色圆点为最优点(损失函数最小且满足正则化约束)。

  • L1的边界拐角容易与坐标轴重合,导致稀疏解(某些参数为0)。

从图像理解L2是收缩,L1产生稀疏:

根据上面动图,其实蓝色等高线可能存在各种方向,这个是不定的。

在各种情况下的等高线扩大,因为L1是菱形,其实和蓝色等高线首次相交的地方更可能是边界的角点(在坐标轴上);

L2是个圆,等高线碰到圆边界通常是某个斜的方向,w1​和w2都不为0,只是都被约束得更小了。


Dropout正则化

dropout是一种在神经网络训练过程中的“随机失活”技术。

核心思想在每一次训练前向传播时,随机“丢弃”一部分神经元(即让它们输出0、不参与本次计算),而不是每次都用全部神经元。

通过随机失活的方式,使得模型不会过多依赖某个“强特征”或“偶然相关的信息”--->让模型更加稳健、泛化能力更强,减少过拟合

一般不用于输入层、卷积层、小模型、小数据。


L1,L2,Dropout区别与关联

正则方法适用场景优点缺点
L1常用于做特征选择(比如logistic/Lasso回归),高维数据优选变量选择,稀疏,易解释有时优化不稳定,稀疏后性能未必最好
L2普遍适用,异常点噪声影响大简单有效,收敛快,理论基础好不会直接产生稀疏性
Dropout深度神经网络,尤其全连接层强大抑制过拟合,提升泛化训练慢,不适合小数据(容易欠拟合)、RNN等
  • Dropout适合深度/宽大网络的“泛化能力提升”,和L1/L2合用可效果更佳。
  • L1/L2可以用于CNN参数,Dropout一般用于MLP/全连接层。
import torch.nn as nn

model = nn.Sequential(
    nn.Linear(1000, 256),
    nn.ReLU(),
    nn.Dropout(p=0.5),      # Dropout
    nn.Linear(256, 10)
)

# L2正则在优化器设置
optimizer = torch.optim.Adam(model.parameters(), weight_decay=1e-5)  # L2正则

# L1正则
l1_lambda = 1e-4
l1_loss = sum(p.abs().sum() for p in model.parameters()) * l1_lambda
loss = criterion(outputs, targets) + l1_loss

### L1/L2正则化 L1正则化L2正则化是在损失函数中添加额外的正则化项,以约束模型的复杂度,从而防止过拟合。 #### L1正则化 L1正则化是在原始的损失函数基础上加上权重参数的绝对值之。其正则化项为 $\lambda\sum_{i} |w_i|$,其中 $\lambda$ 是正则化系数,$w_i$ 是模型的权重参数。L1正则化会使部分权重变为零,从而实现特征选择,减少模型复杂度。以下是在PyTorch中手动实现L1正则化的代码示例: ```python import torch import torch.nn as nn # 定义一个简单的线性模型 model = nn.Linear(10, 1) criterion = nn.MSELoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 假设输入目标 inputs = torch.randn(16, 10) targets = torch.randn(16, 1) # 计算原始损失 outputs = model(inputs) loss = criterion(outputs, targets) # 计算L1正则化项 l1_lambda = 0.001 l1_reg = torch.tensor(0., requires_grad=True) for param in model.parameters(): l1_reg = l1_reg + torch.norm(param, 1) # 加上正则化项 loss = loss + l1_lambda * l1_reg # 反向传播优化 optimizer.zero_grad() loss.backward() optimizer.step() ``` #### L2正则化 L2正则化是在原始的损失函数基础上加上权重参数的平方。其正则化项为 $\lambda\sum_{i} w_i^2$。L2正则化会使权重参数的值变小,但不会使其变为零,能让模型的权重分布更加平滑,减少模型对个别特征的依赖。在PyTorch中,可以通过优化器的 `weight_decay` 参数来实现L2正则化: ```python import torch import torch.nn as nn # 定义一个简单的线性模型 model = nn.Linear(10, 1) criterion = nn.MSELoss() # 设置weight_decay参数实现L2正则化 optimizer = torch.optim.SGD(model.parameters(), lr=0.01, weight_decay=0.001) # 假设输入目标 inputs = torch.randn(16, 10) targets = torch.randn(16, 1) # 计算损失 outputs = model(inputs) loss = criterion(outputs, targets) # 反向传播优化 optimizer.zero_grad() loss.backward() optimizer.step() ``` ### Dropout Dropout是一种在训练过程中随机忽略一部分神经元的技术。在训练时,每个神经元有一定的概率(通常为0.2 - 0.5)被暂时从网络中丢弃,这样可以使模型学习到更加鲁棒的特征,减少神经元之间的共适应问题,从而降低过拟合的风险。在测试阶段,所有神经元都会被使用,但输出会乘以一个保留概率。以下是在PyTorch中使用Dropout的代码示例: ```python import torch import torch.nn as nn # 定义一个包含Dropout的简单神经网络 class SimpleNet(nn.Module): def __init__(self): super(SimpleNet, self).__init__() self.fc1 = nn.Linear(10, 20) self.dropout = nn.Dropout(0.5) self.fc2 = nn.Linear(20, 1) def forward(self, x): x = torch.relu(self.fc1(x)) x = self.dropout(x) x = self.fc2(x) return x model = SimpleNet() ``` ### 早停 早停是一种基于验证集性能的正则化方法。在训练过程中,将数据集分为训练集、验证集测试集。在每个训练周期结束后,在验证集上评估模型的性能。如果验证集的性能在连续多个周期内不再提升(例如,验证集的损失不再下降或准确率不再上升),则停止训练,选择在验证集上性能最好的模型作为最终模型。以下是一个简单的早停实现示例: ```python import torch import torch.nn as nn import numpy as np # 假设模型、训练集、验证集优化器已经定义 model = nn.Linear(10, 1) criterion = nn.MSELoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 训练数据验证数据 train_inputs = torch.randn(100, 10) train_targets = torch.randn(100, 1) val_inputs = torch.randn(20, 10) val_targets = torch.randn(20, 1) # 早停参数 patience = 5 best_val_loss = np.inf epochs_no_improve = 0 for epoch in range(100): # 训练模型 model.train() optimizer.zero_grad() outputs = model(train_inputs) loss = criterion(outputs, train_targets) loss.backward() optimizer.step() # 在验证集上评估模型 model.eval() with torch.no_grad(): val_outputs = model(val_inputs) val_loss = criterion(val_outputs, val_targets) # 检查验证集损失是否有改善 if val_loss < best_val_loss: best_val_loss = val_loss epochs_no_improve = 0 # 保存最佳模型 torch.save(model.state_dict(), 'best_model.pth') else: epochs_no_improve += 1 # 如果连续多个周期验证集损失没有改善,则停止训练 if epochs_no_improve == patience: print(f'Early stopping at epoch {epoch}') break ``` ### 数据增强 数据增强是通过对原始训练数据进行一系列的变换,生成新的训练数据,从而增加训练数据的多样性。常见的数据增强方法包括图像领域的翻转、旋转、缩放、裁剪、亮度调整等,以及文本领域的同义词替换、插入、删除等。在图像分类任务中,使用 `torchvision` 库进行数据增强的代码示例如下: ```python import torchvision.transforms as transforms # 定义数据增强变换 transform = transforms.Compose([ transforms.RandomHorizontalFlip(), # 随机水平翻转 transforms.RandomRotation(10), # 随机旋转10度 transforms.ToTensor() # 转换为张量 ]) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小老大MUTA️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值