首页 > 其他分享 >模型训练中出现loss为NaN怎么办?

模型训练中出现loss为NaN怎么办?

时间:2024-07-18 17:55:53浏览次数:19  
标签:loss 梯度 模型 torch NaN model grad

在这里插入图片描述

文章目录

一、模型训练中出现loss为NaN原因

1. 学习率过高

在训练的某个阶段,学习率可能设置得过高,导致模型参数更新幅度过大,甚至可能出现数值不稳定的情况。你可以尝试降低学习率,并观察训练过程中的变化。

2. 梯度消失或爆炸

如果模型的某些层出现梯度消失或爆炸的问题,可能会导致loss变得异常低。你可以检查梯度的大小,确保它们在合理范围内。

3. 数据不平衡或异常

训练数据中可能存在异常值或分布不平衡的情况,导致模型在某些批次的训练过程中出现异常。你可以检查数据集,确保数据质量。

4. 模型不稳定

模型架构或训练过程中的某些设置可能导致不稳定,比如过深的网络、过复杂的模型等。你可以尝试简化模型架构或添加正则化项。

5. 过拟合

模型可能在某些阶段已经过拟合到训练数据上,导致训练loss异常低而验证loss较高。你可以通过早停法(early stopping)、正则化、数据增强等方法来缓解过拟合问题。
解决方法

  1. 调节学习率:适当降低学习率,观察训练过程中的变化。
  2. 检查梯度:通过torch.autograd检查梯度的大小,确保没有出现梯度消失或爆炸。
  3. 数据检查:确保数据集没有异常值或分布不平衡的情况。
  4. 模型架构:简化模型架构,增加正则化项,如L2正则化、dropout等。
  5. 验证集监控:通过监控验证集的loss和指标,防止过拟合。\

二、 针对梯度消失或爆炸的解决方案

使用 torch.autograd.detect_anomaly() 和相关工具确实可以帮助你检测和排除训练过程中出现的梯度问题。以下是如何在你的代码中使用这些工具来检测异常和可视化梯度的示例。

1. 使用torch.autograd.detect_anomaly()

这个函数可以帮助检测反向传播过程中出现的异常,并输出具体的错误信息和位置。

import torch

# 定义模型
model = MyModel()

# 定义损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 输入数据
inputs = torch.randn(56, 1024, 28, 28)
targets = torch.randint(0, 10, (56,))

# 在训练过程中使用 detect_anomaly
with torch.autograd.detect_anomaly():
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    loss.backward()
    optimizer.step()

2. 使用 torchviz 可视化计算图

torchviz 是一个可以帮助你可视化计算图的工具,这对于调试复杂的模型非常有用。

首先,安装 torchviz:

pip install torchviz

然后,可以使用以下代码来生成和保存计算图:

from torchviz import make_dot

# 定义模型
model = MyModel()

# 输入数据
inputs = torch.randn(56, 1024, 28, 28)

# 获取模型输出
outputs = model(inputs)

# 创建计算图
dot = make_dot(outputs, params=dict(model.named_parameters()))

# 保存计算图
dot.format = 'png'
dot.render('model_graph')

3. 检查梯度的数值范围

你可以在每个训练步骤之后检查模型中各个参数的梯度,以确保梯度的数值范围正常。

# 定义模型
model = MyModel()

# 定义损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 输入数据
inputs = torch.randn(56, 1024, 28, 28)
targets = torch.randint(0, 10, (56,))

# 在训练过程中使用 detect_anomaly
with torch.autograd.detect_anomaly():
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    loss.backward()

    # 检查梯度数值范围
    for name, param in model.named_parameters():
        if param.grad is not None:
            grad_min = param.grad.min().item()
            grad_max = param.grad.max().item()
            print(f'{name} - grad_min: {grad_min}, grad_max: {grad_max}')
    
    optimizer.step()

4. 调整梯度剪裁

在训练过程中,可以使用梯度剪裁来防止梯度爆炸。以下是如何在 PyTorch 中实现梯度剪裁的示例:

# 定义模型
model = MyModel()

# 定义损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 输入数据
inputs = torch.randn(56, 1024, 28, 28)
targets = torch.randint(0, 10, (56,))

# 在训练过程中使用 detect_anomaly
with torch.autograd.detect_anomaly():
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    loss.backward()
    
    # 梯度剪裁
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
    
    optimizer.step()

通过以上方法,可以更好地检测和调试训练过程中出现的梯度问题,提高模型的训练稳定性和效率。如果在使用过程中发现任何异常或需要进一步调试,请随时提供更多细节。

三、更具体的办法

3.1 可能导致梯度爆炸的部分

  1. ReLU 激活函数的使用:激活函数可参考激活函数汇总
    ReLU 是一种常见的激活函数,但如果输入有较大的正值,经过 ReLU 之后,这些值会直接传递下去,可能导致后续层的梯度爆炸。考虑使用其他激活函数,如 Leaky ReLU 或 SELU,它们在某些情况下对梯度更友好。

    embedding_spatial_786 = torch.nn.functional.relu(embedding_spatial_786, inplace=True)
    
  2. 特征插值:
    插值操作可能会生成较大的值,尤其是在上采样过程中。如果插值后的值过大,可能会导致梯度爆炸。
    upsample_feat = F.interpolate(feat_high, scale_factor=2., mode=‘nearest’)

  3. 特征拼接:
    多个特征拼接后,如果这些特征值过大,会导致拼接后的张量值过大,进而影响后续层的梯度。

    inner_out = self.fpn_blocks[len(proj_feats) - 1 - idx](torch.concat([upsample_feat, feat_low], dim=1))
    
  4. 全连接层:
    全连接层的权重初始化方式可能会导致梯度爆炸。确保使用了合适的初始化方法,如 Xavier 初始化或 He 初始化。

  5. 权重共享:
    如果多个部分共享权重,需要确保这些共享权重不会导致梯度的累积效应。

3.2 解决方案

  1. 梯度剪裁:
    在反向传播过程中使用梯度剪裁,可以防止梯度爆炸。你可以在 optimizer.step() 之前加上梯度剪裁。

    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
    
  2. 使用更稳定的激活函数:
    尝试使用 Leaky ReLU 或 SELU,它们在某些情况下对梯度更友好。

  3. 检查权重初始化:
    确保所有层的权重初始化方式合理,避免初始值过大。

    for m in model.modules():
        if isinstance(m, (nn.Conv2d, nn.Linear)):
            nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
    
  4. 监控梯度值:
    在每次反向传播后,监控梯度的值,确保梯度不会爆炸。

    for name, param in model.named_parameters():
        if param.grad is not None:
            grad_min = param.grad.min().item()
            grad_max = param.grad.max().item()
            print(f'{name} - grad_min: {grad_min}, grad_max: {grad_max}')
    

Enjoy~

∼ O n e   p e r s o n   g o   f a s t e r ,   a   g r o u p   o f   p e o p l e   c a n   g o   f u r t h e r ∼ \sim_{One\ person\ go\ faster,\ a\ group\ of\ people\ can\ go\ further}\sim ∼One person go faster, a group of people can go further​∼

标签:loss,梯度,模型,torch,NaN,model,grad
From: https://blog.csdn.net/ThomasCai001/article/details/140523765

相关文章

  • AI Earth——基于决策树模型淮河流域冬小麦提取应用app
    应用介绍:本应用依据利用Landsat-8数据,基于潘力、夏浩铭、王瑞萌等研究论文(基于GoogleEarthEngine的淮河流域越冬作物种植面积制图)中提出的利用作物在不同物候期内卫星影像的光谱存在差异的特征,通过计算作物时间序列的皈依化植被指数(NDVI),选取越冬作物生长旺盛期NDVI最大......
  • LLM大模型新手训练指南
    基础用于语言建模的最常见架构是Transformer架构,由Vaswani等人在著名论文《AttentionIsAllYouNeed》中提出。我们不会在这里讨论该架构的具体细节,因为我们必须讨论导致并促成其创建的所有旧技术。Transformer使我们能够训练具有惊人推理能力的大型语言模型(LLM......
  • 隐马尔可夫模型之概率计算问题
    前向算法    算法目标:计算给定隐马尔可夫模型和观测序列的概率。    算法步骤:通过递归计算前向概率来实现,其中表示在时刻状态为并且观测到部分序列的概率。初始化在初始时刻,计算所有状态的初始前向概率:,其中,是初始状态概率,是状态生成观测的概率。递归计......
  • 【LLM大模型】《开源大模型食用指南》全网发布,轻松助你速通llm大模型!
    前言《开源大模型食用指南》是一个围绕开源大模型、针对国内初学者、基于AutoDL平台的中国宝宝专属大模型教程,针对各类开源大模型提供包括环境配置、本地部署、高效微调等技能在内的全流程指导,简化开源大模型的部署、使用和应用流程,让更多的普通学生、研究者更好地使用......
  • 大模型网信办备案全网最详细说明【附流程+附件】
    本文共分为以下几个章节一、大模型算法备案的强制性二、生成式人工智能(大语言模型)安全评估要点三、大模型备案必备材料+重点说明四、大模型备案填报流程五、大模型备案时间成本对比六、备案建议附录、过程性材料一、大模型算法备案的强制性1、强制要求备案(1)《办法》第六条......
  • 多进程模型
    多进程模型基于最原始的阻塞网络I/O,如果服务器要支持多个客户端,其中比较传统的方式,就是使用多进程模型,也就是为每个客户端分配一个进程来处理请求。服务器的主进程负责监听客户的连接,一旦与客户端连接完成,accept()函数就会返回一个「已连接Socket」,这时就通过fork()函数创......
  • 使用gradio部署微调后的模型
    文章目录概要整体架构流程技术细节小结概要使用gradio部署微调后的模型整体架构流程gradio前期学习,以下是一些常见的输入输出组件,有些即可输入也可输出gr.Audio(sources=['microphone','upload'],#音频输入sources,支持录制或者上传音频文件......
  • 含光AI心理大模型:AI 心理助手,随时待命,伴你左右
    “我感觉自己毫无用处,做什么都不顺。”“焦虑让我窒息,没人能帮我。”……在当今这个快速变化的世界,我们每个人都可能会遇到压力和挑战,这些压力和挑战有时会让我们感到焦虑、失落,甚至自我怀疑。我们的内心可能充满了未被听见的声音,这些声音是我们情感状态的真实写照,它们渴望......
  • 大模型的短期记忆和上期记忆各自的使用场景
    吾名爱妃,性好静亦好动。好编程,常沉浸于代码之世界,思维纵横,力求逻辑之严密,算法之精妙。亦爱篮球,驰骋球场,尽享挥洒汗水之乐。且喜跑步,尤钟马拉松,长途奔袭,考验耐力与毅力,每有所进,心甚喜之。 吾以为,编程似布阵,算法如谋略,需精心筹谋,方可成就佳作。篮球乃团队之艺,协作共进,方显力......
  • ACFI3008 Financial Analysis and Valuation
    ACFI3008FinancialAnalysisandValuationTrimester2,20241. BelowisanarticlepublishedonThe Motley Fool,August7, 10:39amAESTWhyistheResMedsharepricesinkingagainonMonday?ResMedsharesarehavingaverytoughtimethismonth.TheMotl......