当前位置: 首页 > web >正文

深度学习的正则化

深度学习正则化

学习⽬标

知道 L2 正则化与 L1 正则化的⽅法
知道随机失活 droupout 的应⽤
知道提前停⽌的使⽤⽅法
知道 BN 层的使⽤⽅法
在设计机器学习算法时不仅要求在训练集上误差⼩,⽽且希望在新样本上的泛化能⼒强。许多机器学习算法都采⽤相关的策略来减⼩测试误差,这些策略被统称为正则化。因为神经⽹络的强⼤的表示能⼒经常遇到过拟合,所以需要使⽤不同形式的正则化策略。
正则化通过对算法的修改来减少泛化误差,⽬前在深度学习中使⽤较多的策略有参数范数惩罚,提前终⽌, DropOut 等,接下来我们对其进⾏详细的介绍。

1. L1L2正则化(回顾)

L1 L2 是最常⻅的正则化⽅法。它们在损失函数( cost function )中增加⼀个正则项,由于添加了这个正则化项,权重矩阵的值减⼩,因为它假定具有更⼩权重矩阵的神经⽹络导致更简单的模型。 因此,它也会在⼀定程度上减少过拟合。然⽽,这个正则化项在 L1 L2 中是不同的。
L2 正则化
这⾥的 λ 是正则化参数,它是⼀个需要优化的超参数。 L2 正则化⼜称为权重衰减,因为其导致权重趋向于 0 (但不全是 0
L1 正则化
这⾥,我们惩罚权重矩阵的绝对值。其中, λ 为正则化参数,是超参数,不同于 L2 ,权重值可能被减少到 0. 因此, L1 对于压缩模型很有⽤。其它情况下,⼀般选择优先选择 L2 正则化。

2.Dropout正则化

dropout 是在深度学习领域最常⽤的正则化技术。 Dropout 的原理很简单:假设我们的神经⽹络结构如下所示,在每个迭代过程中,随机选择某些节点,并且删除前向和后向连接。
因此,每个迭代过程都会有不同的节点组合,从⽽导致不同的输出,这可以看成机器学习中的集成⽅法( ensemble technique )。集成模型⼀般优于单⼀模型,因为它们可以捕获更多的随机性。相似地, dropout 使得神经⽹络模型优于正常的模型。

代码分析

# 这行代码创建了一个 Dropout 层,失活概率为 0.4,即在训练过程中,每个神经元有 40% 的概率被设置为零。
dropout = nn.Dropout(p = 0.4)
# 创建了一个形状为 (1, 4) 的输入张量,值在 0 到 9 之间,并将其转换为浮点数
inputs = torch.randint(0,10,size=(1,4)).float()
# 创建了一个线性层,输入特征维度为 4,输出特征维度为 5
layer = nn.Linear(4,5) 
y = layer(inputs)
print("未失活FC层的输出结果:\n", y)
y =  dropout(y)
print("失活后FC层的输出结果:\n", y)"""
未失活FC层的输出结果:tensor([[-5.5901,  1.1587,  2.6764, -3.0007,  5.9511]],grad_fn=<AddmmBackward0>)
失活后FC层的输出结果:tensor([[-0.0000,  0.0000,  4.4607, -5.0012,  0.0000]], grad_fn=<MulBackward0>)
"""

3.提前停⽌

提前停⽌( early stopping )是将⼀部分训练集作为验证集( validationset )。 当验证集的性能越来越差时或者性能不再提升,则⽴即停⽌对该模型的训练。 这被称为提前停⽌。
在上图中,在虚线处停⽌模型的训练,此时模型开始在训练数据上过拟合。

1. 定义提前停止的逻辑

提前停止需要设置以下参数:
  • patience:允许模型在验证集上性能没有提升的最大 epoch 数。
  • min_delta:验证集性能提升的最小阈值,只有当提升超过此值时才认为性能有改善。
  • best_val_loss:记录当前最佳的验证损失。
  • patience_counter:记录验证损失没有改善的连续 epoch 数。
import torch
import torch.nn as nn
import torch.optim as optim# 定义模型
model = nn.Linear(10, 1)  # 示例模型
criterion = nn.MSELoss()  # 损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01)  # 优化器# 提前停止的参数
early_stopping_patience = 5  # 耐心值
min_delta = 0.001  # 最小性能提升
best_val_loss = float('inf')  # 初始化最佳验证损失
patience_counter = 0  # 耐心计数器# 模拟训练和验证数据
train_loader = [(torch.randn(10, 10), torch.randn(10, 1)) for _ in range(100)]
val_loader = [(torch.randn(10, 10), torch.randn(10, 1)) for _ in range(20)]def validate(model, val_loader, criterion):model.eval()  # 设置为评估模式total_loss = 0with torch.no_grad():for inputs, targets in val_loader:outputs = model(inputs)loss = criterion(outputs, targets)total_loss += loss.item()return total_loss / len(val_loader)# 训练循环
num_epochs = 100
for epoch in range(num_epochs):model.train()  # 设置为训练模式train_loss = 0for inputs, targets in train_loader:optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, targets)loss.backward()optimizer.step()train_loss += loss.item()train_loss /= len(train_loader)# 验证阶段val_loss = validate(model, val_loader, criterion)print(f"Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss:.4f}, Val Loss: {val_loss:.4f}")# 提前停止逻辑if val_loss < best_val_loss - min_delta:best_val_loss = val_losstorch.save(model.state_dict(), 'best_model.pth')  # 保存最佳模型patience_counter = 0  # 重置耐心计数器else:patience_counter += 1if patience_counter >= early_stopping_patience:print("Early stopping triggered...")break

4. 批标准化(BN层)

批标准化 (BN ,Batch Normalization) 2015 年提出的⼀种⽅法,在进⾏深度⽹络训练时,⼤多会采取这种算法,与全连接层⼀样, BN 层也是属于⽹络中的⼀层。
批标准化(Batch Normalization,简称BN)是一种在深度神经网络中常用的技巧,旨在解决训练过程中的内部协变量偏移(Internal Covariate Shift)问题,从而加速训练过程并提高模型的稳定性和性能。内部协变量偏移是指由于网络参数在训练过程中的变化,导致每一层的输入分布也在不断变化,这会使得网络的训练变得困难。
在每⼀层输⼊之前,将数据进⾏ BN ,然后再送⼊后续⽹络中进⾏学习:
批标准化的工作原理
批标准化通过在每一层的输入上进行标准化处理,使得每一层的输入分布保持相对稳定。具体来说,批标准化包括以下步骤:
  1. 计算均值和方差:对于每个小批量(mini-batch)的数据,计算该层输入的均值和方差:
其中, m 是小批量的大小, xi​ 是第 i 个输入样本。
  1. 标准化:使用计算得到的均值和方差,对每个输入样本进行标准化:
其中, ϵ 是一个很小的常数,用于防止除以零的情况。
  1. 缩放和偏移:为了使网络具有足够的表达能力,引入两个可学习的参数 γβ,对标准化后的输入进行缩放和偏移:
其中, γβ 是通过训练学习得到的参数。
PyTorch中的实现在PyTorch中,批标准化可以通过torch.nn.BatchNorm1d、torch.nn.BatchNorm2d 和 torch.nn.BatchNorm3d 等类来实现,分别用于1D、2D和3D数据。

api

torch.nn.BatchNorm2d 是 PyTorch 中用于对二维卷积层输出进行 批量归一化(Batch Normalization)的模块。它通过规范化层的输入来 减少内部协变量偏移,从而加速训练过程并提高模型的泛化能力。
torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
参数名
解释
num_features
输入的通道数(num_channels),即输入张量的第二个维度。
eps
一个数值稳定性的小常数,用于防止除以零。默认值为 1e-5。
momentum
用于更新运行时均值和方差的动量参数。默认值为 0.1。较大的 momentum 会使估计值更依赖于之前的统计信息。
affine
布尔值
  • 如果为 True,则引入可学习的缩放因子(gamma)和偏移因子(beta),用于对归一化后的数据进行仿射变换。
  • 如果设置为False,则不会引入可学习的参数,仅进行归一化
  • 默认值为 True。
track_running_stats
布尔值,如果为 True,则在训练过程中跟踪运行时的均值和方差,并在评估模式下使用这些统计量进行归一化。默认值为 True。
以下是一个使用torch.nn.BatchNorm2d 的示例:
import torch
import torch.nn as nn# 定义 BatchNorm2d 模块
bn = nn.BatchNorm2d(3)  # 假设输入通道数为 3# 创建一个假的输入数据,形状为 [batch_size, num_channels, height, width]
input = torch.randn(4, 3, 10, 10)# 应用 BatchNorm2d 模块
output = bn(input)
print(output.shape)  # 输出形状与输入相同

import torch
import torch.nn as nn# affine参数设为True表示weight和bias将被使用
m = nn.BatchNorm2d(2, eps=1e-05, momentum=0.1, affine=True)  
"""
2:表示输入张量的通道数为2。
eps=1e-05:一个小的常数,用于防止除以零的情况。
momentum=0.1:用于计算运行时均值和方差的动量值。
affine=True:表示会使用可学习的权重和偏置参数。
"""
# 创建一个形状为 (1, 2, 3, 4) 的随机张量,表示一个批量大小为1,通道数为2,高度为3,宽度为4的输入数据。
input = torch.randn(1, 2, 3, 4)
print("input-->", input)
output = m(input)
print("output-->", output)
print(output.size())
print(m.weight)
print(m.bias)
"""
input--> tensor([[[[-0.8234, -1.2278, -0.4963, -2.3977],[-0.8070,  0.2189, -1.0539,  0.0155],[-2.8108, -2.0466,  0.3954, -0.0352]],[[-0.5503, -2.3331, -1.0138, -0.7310],[-1.2487,  0.2061, -1.0572,  0.0954],[ 0.5301, -0.3816,  0.1127,  0.0587]]]])
output--> tensor([[[[ 0.0989, -0.3051,  0.4256, -1.4736],[ 0.1153,  1.1400, -0.1314,  0.9369],[-1.8862, -1.1229,  1.3163,  0.8862]],[[-0.0314, -2.3395, -0.6315, -0.2653],[-0.9356,  0.9479, -0.6877,  0.8046],[ 1.3674,  0.1870,  0.8270,  0.7571]]]],grad_fn=<NativeBatchNormBackward0>)
torch.Size([1, 2, 3, 4])
Parameter containing:
tensor([1., 1.], requires_grad=True)
Parameter containing:
tensor([0., 0.], requires_grad=True)
"""

批标准化层的权重和偏置参数默认初始化为1和0,但可以根据需要进行自定义初始化。

 

import torch
import torch.nn as nn# 创建一个卷积层
conv_layer = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, padding=1)# 创建一个批标准化层
bn_layer = nn.BatchNorm2d(num_features=16)# 创建一个激活函数层
activation_layer = nn.ReLU()# 创建一个输入张量,假设是一个小批量的图像数据
input_tensor = torch.randn(4, 3, 32, 32)  # (batch_size, channels, height, width)# 前向传播
conv_output = conv_layer(input_tensor)
bn_output = bn_layer(conv_output)
activated_output = activation_layer(bn_output)print("卷积层输出的形状:", conv_output.shape)
print("批标准化层输出的形状:", bn_output.shape)
print("激活函数层输出的形状:", activated_output.shape)

批标准化的优点

  1. 加速训练:批标准化可以减少内部协变量偏移,使得每一层的输入分布保持相对稳定,从而加速训练过程。
  2. 提高模型性能:批标准化可以提高模型的稳定性和性能,尤其是在使用较深的网络时。
  3. 减少对初始化的依赖:批标准化可以减少对初始权重的依赖,使得模型对初始权重的选择更加鲁棒。
  4. 允许使用更高的学习率:由于批标准化可以减少梯度爆炸和梯度消失的问题,因此可以使用更高的学习率进行训练。

批标准化的注意事项

  1. 小批量大小:批标准化依赖于小批量的统计数据,因此小批量的大小不能太小。如果小批量大小太小,计算得到的均值和方差可能会不够准确,从而影响批标准化的效果。
  2. 推理时的行为:在推理(inference)时,批标准化层会使用在训练过程中计算得到的全局均值和方差,而不是当前小批量的均值和方差。这是通过在训练过程中逐步更新全局均值和方差来实现的。
  3. 与Dropout的结合:批标准化和Dropout都是正则化技术,但它们的作用机制不同。在使用批标准化时,可以适当减少Dropout的比例,因为批标准化本身也具有一定的正则化效果。
总结
知道 L2 正则化与 L1 正则化的⽅法
在损失函数( cost function )中增加⼀个正则项,由于添加了这个正则化项,权重矩阵的值减⼩,因为它假定具有更⼩权重矩阵的神经⽹络导致更简单的模型
知道随机失活 droupout 的应⽤
在每个迭代过程中,随机选择某些节点,并且删除前向和后向连接知道提前停⽌的使⽤⽅法
当看到验证集的性能越来越差时或者性能不再提升,⽴即停⽌对该模型的训练
知道 BN 层的使⽤⽅法
利⽤⽹络训练时⼀个 mini-batch 的数据来计算该神经元 xi 的均值和⽅差 , 归⼀化后并重构,因⽽称为 Batch Normalization
http://www.xdnf.cn/news/14506.html

相关文章:

  • Web server failed to start. Port XXX was already in use.
  • Python day32
  • Nginx超快速入门
  • 基于经济学季刊方法测算的中国城市蔓延指数
  • 【Dv3Admin】系统异步任务配置文件解析
  • 朴素贝叶斯:用条件逻辑照亮未知
  • 七 医学影像云平台-影像检验互联互认平台建设中遇到的问题
  • WIP数据,有bad wafer/lot,追踪设备/机台问题
  • Java 变量类型转换的选择题
  • react小白学习快速上手
  • Appium+python自动化(二十四) - 元素等待
  • 在虚拟机 银河麒麟|ubuntu 中安装和配置NVIDIA显卡驱动
  • 设计模式精讲 Day 2:工厂方法模式(Factory Method Pattern)
  • 多模态学习路线(3)——MLLMs主流大模型
  • 基于统计检验与机器学习模型对牛油果数据的分析与预测
  • Python 文件操作详解
  • 算法题(170):地毯填补问题
  • Proteus8.17-安装说明
  • 揭开MongoDB的神秘面纱:从陌生到初识
  • 【Elasticsearch】文档(一):新增 删除
  • vue中的h渲染函数
  • Java项目中使用到的技术——《异步调用》
  • java+vue+SpringBoo摄影师分享交流社区(程序+数据库+报告+部署教程+答辩指导)
  • 大模型笔记6:微调
  • Go多个协程实现顺序打印
  • 华为OD机试_2025 B卷_运维日志排序(Python,100分)(附详细解题思路)
  • sudo apt-get install openssh-serve安装失败解决
  • 自定义Spring Boot Starter开发指南
  • JS当中怎么定义一个类
  • 【Quest开发】初始项目环境配置