PyTorch深度学习实战(10)——过拟合及其解决方法

PyTorch深度学习实战(10)——过拟合及其解决方法

    • 0. 前言
    • 1. 过拟合基本概念
    • 2. 添加 Dropout 解决过拟合
    • 3. 使用正则化解决过拟合
      • 3.1 L1 正则化
      • 3.2 L2 正则化
    • 4. 学习率衰减
    • 小结
    • 系列链接

0. 前言

过拟合 (Overfitting) 是指在机器学习中,模型过于复杂而导致在训练数据上表现良好,但在新的未见过的数据上表现不佳的现象。直观的讲,可能会在训练过程中出现模型的训练准确率约为 100%,而测试准确率仅有 80% 左右的情况。在本文中,我们直观地介绍训练与测试准确率之间的差异的原因以及解决方法。

1. 过拟合基本概念

在《神经网络性能优化技术》中,我们经常看到这样的现象——训练数据集的准确率通常超过 95%,而验证数据集的准确率大约只为 89%。从本质上讲,这表明该模型在未见过的数据上的泛化程度不高,也表明模型正在学习训练数据集的异常数据,这些情况并不适用于验证数据集。
当模型过度关注于训练数据中的细节和噪音时,会导致过拟合。过拟合通常发生在模型复杂度过高、训练数据量较少或训练数据不平衡的情况下。当模型太过复杂时,它可能在训练数据中学习到了噪声和随机性,并将其视为普遍规律。当训练数据量较少时,模型可能没有足够的样本来全面学习数据的特征分布,从而容易出现过拟合。过拟合现象使得模型对训练数据中的个别特征过于敏感,而无法正确地推广到新的数据。可以使用以下策略降低模型过拟合的影响:

  • 增加训练数据的数量,确保数据集更加全面和多样化
  • 减少模型的复杂度,例如减少参数数量或使用正则化方法
  • 使用交叉验证等技术来评估模型的性能,并进行模型选择
  • 提前停止训练,即在模型开始过拟合之前停止迭代
  • 进行特征选择,删除不相关或冗余的特征
  • 数据预处理,例如归一化/标准化数据,处理异常值等

2. 添加 Dropout 解决过拟合

Dropout 是一种用于减少神经网络过拟合的正则化技术。在训练过程中,Dropout 会随机地将一部分神经元的输出置为 0 (即丢弃),从而降低神经网络对特定神经元的依赖性。具体来说,在每次训练迭代中,Dropout 会以一定的概率随机选择部分神经元,并将其输出置为 0,这意味着每个神经元都有一定的概率被“关闭”,从而迫使网络学习到更加鲁棒和独立的特征表示。

Dropout
通过引入 Dropout,神经网络无法过度依赖某些特定神经元,因为它们的输出可能随时被丢弃。这样可以有效地减少神经网络的复杂性,降低模型对训练数据的噪音和过拟合的敏感性,提高模型的泛化能力。在训练完成后,通常不再应用 Dropout,而是使用所有的神经元进行推理和预测。这是因为在测试阶段,我们希望模型能够充分利用所有可用的神经元来最大限度地提取特征和进行预测。
正常模型训练时,每次计算 loss.backward() 时,都更新模型权重。通常,神经网络中包含数以百万计的参数,因此可能虽然大多数参数有助于训练模型,但某些参数可能会针对训练图像进行微调,从而导致它们的值仅由训练数据集中的少数图像决定,这会导致模型在训练数据上具有较高精度,但在验证数据集上的泛化能力较差。
由于 Dropout 在训练和验证过程中具有不同操作,因此必须预先指定模型的模式为 model.train() (处于训练阶段)或 model.eval() (处于验证阶段)。
定义架构时,在 get_model() 函数中指定 Dropout 如下:

from torch.optim import SGD, Adam
def get_model():model = nn.Sequential(nn.Dropout(0.5),nn.Linear(28 * 28, 1000),nn.ReLU(),nn.Dropout(0.5),nn.Linear(1000, 10)).to(device)loss_fn = nn.CrossEntropyLoss()optimizer = Adam(model.parameters(), lr=1e-3)return model, loss_fn, optimizer

在以上代码中,还在线性激活前添加了 Dropout,训练和验证数据集的损失和准确率变化如下所示:

训练和验证数据集的损失和准确率变化
使用相同的架构,未使用 Dropout 时训练和验证数据集的损失和准确率变化如下所示:

训练和验证数据集的损失和准确率变化
可以看出,训练数据集和验证数据集的准确率之间的差异没有之前模型差距那么大,有效的降低了模型的过拟合。
绘制两种情况下隐藏层的权重直方图,可以看到使用 Dropout 时训练和测试准确率之间的差距低于没有 Dropout 时模型训练和测试准确率的差距:

隐藏层的权重直方图
隐藏层的权重直方图

3. 使用正则化解决过拟合

除了训练准确率远高于验证准确率外,过拟合的另一个特征是网络中的某些权重值显著高于其他权重值,高权重值可能是模型为了拟合训练数据中异常值的表现。正则化是一种惩罚模型中具有较高值的权重的技术,因此,需要同时最小化训练数据的损失以及权重值。在本节中,我们将学习两类正则化:

  • L1 正则化
  • L2 正则化

3.1 L1 正则化

L1 正则化计算如下:
在这里插入图片描述

L 1 l o s s = − 1 n ( ∑ i = 1 n ( y i ∗ l o g ( p i ) + ( 1 − y i ) ) + Λ ∑ j = 1 m ∣ w j ∣ ) L1\ loss=-\frac 1n(\sum_{i=1}^n(y_i*log(p_i)+(1-y_i))+\Lambda \sum_{j=1}^m|w_j|) L1 loss=n1(i=1n(yilog(pi)+(1yi))+Λj=1mwj)
上述公式的第一部分是在以上模型中用于优化的分类交叉熵损失,而第二部分是指模型权重值的绝对值之和, Λ \Lambda Λ 是用于平衡交叉熵损失和权重绝对值的权重系数。L1 正则化通过将权重的绝对值合并到损失值的计算中来确保它惩罚具有较高绝对值的权重,L1 正则化在训练模型的同时进行:

def train_batch(x, y, model, opt, loss_fn):prediction = model(x)l1_regularization = 0for param in model.parameters():l1_regularization += torch.norm(param,1)batch_loss = loss_fn(prediction, y) + 0.0001*l1_regularizationbatch_loss.backward()optimizer.step()optimizer.zero_grad()return batch_loss.item()

在以上代码中,首先初始化 l1_regularization,并对所有层的权重和偏置进行了正则化。torch.norm(param,1) 提供了权重和偏置值的绝对值。此外,使用一个非常小的权重系数 (0.0001) 来平衡参数绝对值之和对损失函数的影响。
使用 L1 正则化后,训练和验证数据集上的损失和准确率的变化如下所示:

损失和准确率的变化
可以看到训练数据集和验证数据集的准确率差异相比没有 L1 正则化时更小。

3.2 L2 正则化

L2 正则化计算如下:
在这里插入图片描述
L 2 l o s s = − 1 n ( ∑ i = 1 n ( y i ∗ l o g ( p i ) + ( 1 − y i ) ∗ l o g ( 1 − p i ) ) + Λ ∑ j = 1 m w j 2 ) L2\ loss =-\frac 1n(\sum_{i=1}^n(y_i*log(p_i)+(1-y_i)*log(1-p_i))+\Lambda \sum_{j=1}^mw_j^2) L2 loss=n1(i=1n(yilog(pi)+(1yi)log(1pi))+Λj=1mwj2)
其中,第一部分是指分类交叉熵损失,而第二部分是指模型权重值的平方和, Λ \Lambda Λ 是用于平衡交叉熵损失和权重平方和的权重系数。与 L1 正则化类似,通过将权重的平方和纳入损失计算来惩罚较高权重值。L2 正则化同样在训练模型的同时进行:

def train_batch(x, y, model, opt, loss_fn):prediction = model(x)l2_regularization = 0for param in model.parameters():l2_regularization += torch.norm(param,2)batch_loss = loss_fn(prediction, y) + 0.01*l2_regularizationbatch_loss.backward()optimizer.step()optimizer.zero_grad()return batch_loss.item()

在以上代码中,正则化的权重参数 (0.01) 略高于 L1 正则化,因为权重通常在 -11 之间,并且执行平方后会得到更小的结果值,如果权重参数较小,将导致在整体损失计算第二项的影响非常小。
使用 L2 正则化后,训练和验证数据集上的损失和准确率的变化情况如下所示:

损失和准确率的变化
可以看到 L2 正则化同样可以令验证和训练数据集的准确率和损失更接近。
最后,我们比较没有进行正则化和使用 L1/L2 正则化的权重,观察网络层的权重分布,如下图所示:

网络层的权重分布

可以看到,与不执行正则化相比,执行 L1/L2 正则化时参数的分布范围非常小,这可能会减少为异常数据更新权重的机会。
我们已经知道了较高的学习率在缩放和未缩放的数据集上均难以得到最佳结果,在下一节中,我们将学习如何在模型开始过拟合时自动降低学习率.

4. 学习率衰减

在以上模型中,我们在模型训练过程中使用恒定的学习率,但是,通常可以将权重快速更新到接近最佳状态,在模型训练后期可以进行缓慢的更新,因为模型训练初期的损失较高,而在后期损失较低。这就需要模型训练初期具有较高学习率,然后随着模型接近最佳的准确率,学习率也需要逐渐降低,因此我们这需要了解在何时降低学习率。
一种常用的方法是持续监控验证损失,如果验证损失在一段 epoch 内没有减少,就降低学习率。PyTorch 提供了调度方法 lr_scheduler,当验证损失在之前的 “x” 个 epoch 内没有减少时,降低学习率:

from torch import optim
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer,factor=0.5,patience=0,threshold = 0.001,verbose=True,min_lr = 1e-5,threshold_mode = 'abs')

在以上代码中,指定如果某个值在接下来的 nepoch (使用 patience参数指定)没有提高指定阈值(使用 threshold 参数指定),则学习率衰减为原来的 0.5 倍(即变为原来的 1/2,使用 factor 参数指定),且使用参数 min_lr 指定学习率的最小值 (不低于 1e-5),并且使用参数 threshold_mode 指定阈值模式(此处使用 abs,以确保超过指定的最小阈值)。接下来,在训练模型时应用 lr_scheduler,并在模型训练时监测验证损失:

trn_dl, val_dl = get_data()
model, loss_fn, optimizer = get_model()
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer,factor=0.5,patience=0,threshold = 0.001,verbose=True,min_lr = 1e-5,threshold_mode = 'abs')train_losses, train_accuracies = [], []
val_losses, val_accuracies = [], []
for epoch in range(30):# print(epoch)train_epoch_losses, train_epoch_accuracies = [], []for ix, batch in enumerate(iter(trn_dl)):x, y = batchbatch_loss = train_batch(x, y, model, optimizer, loss_fn)train_epoch_losses.append(batch_loss) train_epoch_loss = np.array(train_epoch_losses).mean()for ix, batch in enumerate(iter(trn_dl)):x, y = batchis_correct = accuracy(x, y, model)train_epoch_accuracies.extend(is_correct)train_epoch_accuracy = np.mean(train_epoch_accuracies)for ix, batch in enumerate(iter(val_dl)):x, y = batchval_is_correct = accuracy(x, y, model)validation_loss = val_loss(x, y, model, loss_fn)scheduler.step(validation_loss)val_epoch_accuracy = np.mean(val_is_correct)train_losses.append(train_epoch_loss)train_accuracies.append(train_epoch_accuracy)val_losses.append(validation_loss)val_accuracies.append(val_epoch_accuracy)

在以上代码中,指定只要验证损失在连续的 epoch 内没有减少,就激活调度程序,学习率降低 0.5 倍,模型上执行调度程序输出如下:

Epoch     3: reducing learning rate of group 0 to 5.0000e-04.
Epoch     5: reducing learning rate of group 0 to 2.5000e-04.
Epoch     7: reducing learning rate of group 0 to 1.2500e-04.
Epoch    11: reducing learning rate of group 0 to 6.2500e-05.
Epoch    13: reducing learning rate of group 0 to 3.1250e-05.
Epoch    14: reducing learning rate of group 0 to 1.5625e-05.
Epoch    15: reducing learning rate of group 0 to 1.0000e-05.

训练和验证数据集的准确率和损失随时间变化如下:

请添加图片描述

通过使用调度程序,即使对模型进行了 30 个(或更多) epoch 的训练,也没有严重的过拟合问题,这是因为当学习率衰减的极小时,权重的更新也变得非常小,因此训练和验证准确率之间的差距也非常小。

小结

过拟合是指机器学习模型在训练集上表现很好,但在测试集或未见过的数据上表现较差的现象。过拟合是由于模型在训练过程中过度拟合了训练数据的特点和噪声,导致了对训练样本的过度依赖和泛化能力不足。为了解决过拟合问题,选择适当的方法需要对具体问题和数据进行分析,并在模型构建和调优过程中进行实验和验证。在实践中,通常需要权衡模型的复杂度和泛化能力,以获得更好的结果。

系列链接

PyTorch深度学习实战(1)——神经网络与模型训练过程详解
PyTorch深度学习实战(2)——PyTorch基础
PyTorch深度学习实战(3)——使用PyTorch构建神经网络
PyTorch深度学习实战(4)——常用激活函数和损失函数详解
PyTorch深度学习实战(5)——计算机视觉基础
PyTorch深度学习实战(6)——神经网络性能优化技术
PyTorch深度学习实战(7)——批大小对神经网络训练的影响
PyTorch深度学习实战(8)——批归一化
PyTorch深度学习实战(9)——学习率优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/84847.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023年第2季社区Task挑战赛升级新玩法,等你来战!

第1季都有哪些有趣的作品? 在大家的共建下,FISCO BCOS开源生态不断丰富完善,涌现了众多实用技术教程和代码:基于数字身份凭证的业务逻辑设计,贡献了发放数字身份凭证的参考实现;提供企业碳排放、慈善公益等…

【idea】点击idea启动没反应

RT 点击idea启动的时候没反应,接着百度报错,基本跟他们的也不一样。 首先我是做版本升级。其次,我之前是破解的。如果你也是跟我一样的话,那问题可能就处在破解上了 解决方式 首先,是跟大部分解决思路一样。先找到项…

苍穹外卖系统07

哈喽!大家好,我是旷世奇才李先生 文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】更有我为大家准备的福利哟,回复【项目】获取我为大家准备的项目 最近打算把我手里之前做的项目分享给大家&#…

年至年的选择仿elementui的样式

组件&#xff1a;<!--* Author: liuyu liuyuxizhengtech.com* Date: 2023-02-01 16:57:27* LastEditors: wangping wangpingxizhengtech.com* LastEditTime: 2023-06-30 17:25:14* Description: 时间选择年 - 年 --> <template><div class"yearPicker"…

CTFSHOW php命令执行

目录 web29 过滤flag web30 过滤system php web31 过滤 cat|sort|shell|\. 这里有一个新姿势 可以学习一下 web32 过滤 &#xff1b; . web33 web34 web35 web36 web37 data伪协议 web38 短开表达式 web39 web40 __FILE__命令的扩展 web41 web42 重定向…

【无标题杭州生物制药公司【阿诺医药】申请纳斯达克IPO上市】

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;杭州生物制药公司阿诺医药&#xff08;Adlai Nortye&#xff09;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&#xff0c;股票代码为&am…

7个顶级开源数据集来训练自然语言处理(NLP)和文本模型

推荐&#xff1a;使用 NSDT场景编辑器快速助你搭建可二次编辑的3D应用场景 NLP现在是一个令人兴奋的领域&#xff0c;特别是在像AutoNLP这样的用例中&#xff0c;但很难掌握。开始使用NLP的主要问题是缺乏适当的指导和该领域的过度广度。很容易迷失在各种论文和代码中&#xff…

unity修改单个3D物体的重力的大小该怎么处理呢?

在Unity中修改单个3D物体的重力大小可以通过以下步骤实现&#xff1a; 创建一个新的C#脚本来控制重力&#xff1a; 首先&#xff0c;创建一个新的C#脚本&#xff08;例如&#xff1a;GravityModifier.cs&#xff09;并将其附加到需要修改重力的3D物体上。在脚本中&#xff0c…

竞赛项目 深度学习图像风格迁移 - opencv python

文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习图像风格迁移 - opencv python 该项目较为新颖&#xff0c;适合作为竞赛课题…

NLP 时事和见解【2023】

一、说明 AI的新闻当然不是即时的&#xff0c;但作为趋势和苗头&#xff0c;我们不得不做出自己的决定。比如&#xff0c;一些软件的支持是否持续&#xff0c;哪些现成的软件将不再使用&#xff0c;等等。 图片来自中途 以下是NLPlanet为您选择的有关NLP和AI的每周文章&#x…

vi 编辑器入门到高级

vi 编辑器的初级用法vi 编辑器的工作模式1. 命令模式2. 文本输入模式3. 状态行vi 工作模式切换存储缓冲区 vi 编辑器命令1. 启动 vi2. 文本输入3. 退出 vi4. 命令模式下的 光标移动5. 命令模式下的 文本修改6. 从 命令模式 进入 文本输入模式7. 搜索字符串8. vi 在线帮助文档 v…

【雕爷学编程】Arduino动手做(201)---行空板硬件控制之基础GPIO的使用

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

腾讯云轻量应用服务器端口怎么打开?图文方法来了

腾讯云轻量应用服务器端口放行在哪设置&#xff1f;在防火墙中可以开启端口号&#xff0c;腾讯云轻量应用服务器端口怎么开通&#xff1f;在轻量服务器管理控制台的防火墙中开启端口&#xff0c;如果是CVM云服务器在安全组中开通&#xff0c;腾讯云服务器网以轻量应用服务器开通…

升级你的GitHub终端认证方式:从密码到令牌

升级你的GitHub终端认证方式&#xff1a;从密码到令牌 前言 GitHub官方在2021年8月14日进行了一次重大改变&#xff0c;它将终端推送代码时所需的身份认证方式从密码验证升级为使用个人访问令牌&#xff08;Personal Access Token&#xff09;。这个改变引起了一些新的挑战&am…

《合成孔径雷达成像算法与实现》Figure3.6

代码复现如下&#xff1a; clc clear all close all%参数设置 TBP 100; %时间带宽积 T 10e-6; %脉冲持续时间%参数计算 B TBP/T; …

网络:CISCO、Huawei、H3C命令对照

思科、华为、锐捷命令对照表 编号思科华为锐捷命令解释1 2writesavesave保存3456 如果你所处的视图为非系统视图&#xff0c;需要查看配置的时候&#xff0c;需要在该配置命令前加do。 在特定的视图之下&#xff0c;有对应的特定命令。例如&#xff0c;在接口视图下的ip addre…

2023年,App运行小游戏,可以玩出什么创意?

疫情过后&#xff0c;一地鸡毛。游戏行业的日子也不好过。来看看移动游戏收入&#xff1a;2022年&#xff0c;移动游戏收入达到920亿美元&#xff0c;同比下降6.4%。这告诉我们&#xff0c;2022年对移动游戏市场来说是一个小挫折。 但不管是下挫还是上升&#xff0c;移动游戏市…

LC-杨辉三角

LC-杨辉三角 链接&#xff1a;https://leetcode.cn/problems/pascals-triangle/submissions/ 上图就是一个杨辉三角&#xff0c;每个数等于他左上角的数与右上角的数之和。 第一行就是一个1&#xff1b;第二行是两个1&#xff1b;第三行的2就是它肩膀上两个1之和,其余的类似。…

【Linux 网络】网络层协议之IP协议

IP协议 IP协议所处的位置网络层要解决的问题IP协议格式分片与组装网段划分特殊的IP地址IP地址的数量限制私网IP地址和公网IP地址路由 IP协议所处的位置 IP指网际互连协议&#xff0c;Internet Protocol的缩写&#xff0c;是TCP/IP体系中的网络层协议。 网络层要解决的问题 网络…

JavaScript数据结构【进阶】

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录 使用 splice() 添加元素使用 slice() 复制数组元素使用展开运算符复制数组使用展开运算符合并数组使用 indexOf() 检查元素是否存在使用 for 循环遍历数组中的全部元素创建复杂的多维数组将键值对添加到对象…