【调试Bug】网络在训练中输出NaN

首先情况是开始训练正常,网络也在更新,更新后网络就输出了NaN。调试过程:

1. 查看模型权重更新前后的值

复制代码
    print("更新前权重信息:")
    print(f"  权重均值: {fc2.weight.mean().item() if not torch.isnan(fc2.weight.mean()) else 'NaN'}")
    print(f"  最大值: {fc2.weight.max().item() if not torch.isnan(fc2.weight.max()) else 'NaN'}")
    print(f"  最小值: {fc2.weight.min().item() if not torch.isnan(fc2.weight.min()) else 'NaN'}\n")

    权重更新


    print("更新后权重信息:")
    print(f"  权重均值: {fc2.weight.mean().item() if not torch.isnan(fc2.weight.mean()) else 'NaN'}")
    print(f"  最大值: {fc2.weight.max().item() if not torch.isnan(fc2.weight.max()) else 'NaN'}")
    print(f"  最小值: {fc2.weight.min().item() if not torch.isnan(fc2.weight.min()) else 'NaN'}\n")

判断标准

  • 权重 / 偏置的绝对值如果超过1e4,可能导致输出过大。
  • 若训练中权重突然变得极大,说明可能存在梯度爆炸。

2. 发现权重更新前正常,更新后NaN

权重在参数更新后变成了NaN,这说明问题出在反向传播和参数更新环节(梯度计算或优化器步骤导致权重被更新为异常值)。

原因分析:

权重从正常数值突然变成NaN,几乎可以确定是梯度爆炸导致的:

  • 反向传播时计算出的梯度为NaN或极端大值(如1e20),优化器用这些异常梯度更新权重,直接导致权重变成NaN
  • 常见触发点:损失函数计算异常(如NaN损失)、输入数据极端值导致中间激活值爆炸、学习率过高放大梯度影响。

第一步 检查损失函数是否为NaN

如果损失本身输出是NaN,反向传播的梯度必然是NaN,直接导致权重更新异常。在反向传播前检查损失需要。

损失为NaN的常见原因:

  • 损失中包含log(0)(如nn.Softmax输出接近 0 时,torch.log(prob)会趋近于-inf

结果:发现正是损失函数torch.log输出了NaN。

3 解决

限制torch.log的值,NaN的问题得到了解决

相关推荐
CareyWYR1 小时前
苹果芯片Mac使用Docker部署MinerU api服务
人工智能
地平线开发者1 小时前
ReID/OSNet 算法模型量化转换实践
算法·自动驾驶
失散131 小时前
自然语言处理——02 文本预处理(下)
人工智能·自然语言处理
地平线开发者1 小时前
开发者说|EmbodiedGen:为具身智能打造可交互3D世界生成引擎
算法·自动驾驶
mit6.8241 小时前
[1Prompt1Story] 滑动窗口机制 | 图像生成管线 | VAE变分自编码器 | UNet去噪神经网络
人工智能·python
sinat_286945192 小时前
AI应用安全 - Prompt注入攻击
人工智能·安全·prompt
星星火柴9362 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
迈火3 小时前
ComfyUI-3D-Pack:3D创作的AI神器
人工智能·gpt·3d·ai·stable diffusion·aigc·midjourney
艾莉丝努力练剑3 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
Moshow郑锴4 小时前
机器学习的特征工程(特征构造、特征选择、特征转换和特征提取)详解
人工智能·机器学习