pytorch训练过程中出现NAN问题复盘

问题描述

在centerformer(基于det3d)项目中,我增加了一个和图像的融合处理(paint features),在训练过程中经常到第13/14个epoch打印的日志中出现NAN的现象。

问题分析

根据现象,猜测可能的原因是:
1.数据集中有脏数据 -> 可以通过训练baseline或现有模型resume早期epoch,看能否通过一整个epoch来判定
2.forward过程中已经存在NAN -> 可以通过在backbone和neck处打印torch.isnan(tensor)来判定forward过程中是否有NAN
3.计算的loss中存在NAN -> 可以通过在loss处打印torch.isnan(tensor)来判定
4.计算grad并BP的过程中存在一些特殊点导数值很大趋于∞,导致梯度出现NAN -> 在loss.backward()中添加上下文管理器with autograd.detect_anomaly():监测梯度是否有异常

解决思路

1.首先加入自动梯度异常检测

with autograd.detect_anomaly():
	runner.outputs["loss"].backward()

结果打印的info表明确实存在,并且在MulBackward0里面
在这里插入图片描述
为了进一步定位NAN,把所有有异常的梯度都打印出来:

        for name, param in runner.model.named_parameters():
            if param.grad is not None and torch.isnan(param.grad).any():
                print("nan gradient found")
                print("name:", name)

结果发现从backbone开始到neck以及最后的box_head都是NAN的
在这里插入图片描述
在backbone和neck处打印torch.isnan(tensor)发现NAN是在grad为NAN之后出现的,说明在forward阶段所有tensor都是正常的。于是NAN范围聚集到了loss上。因为默认打印的info是每5个iteration并且是多个gpu的均值,不方便排查,于是在代码中增加print(loss)。
结果发现NAN确实存在loss中,并且是在heatmap的loss里。
在这里插入图片描述
于是聚焦到heatmap loss的计算中,代码如下:
在这里插入图片描述
通过debug进入到里面,发现neg_loss和pos_loss中都存在torch.log(x),这是个比较危险的函数,当x->0时,就会出现NAN。debug时发现确实存在输出为0和1的现象(网络预测得比较好,这也是为什么在第14个epoch才会出现NAN而早期不会出现的原因),于是增加了对out的值域限制。

    eps=1e-5	//注意eps=1e-8太小了,1-eps还是会上溢到1
    out = torch.clamp(out, eps, 1.0-eps)

——————————————————————————————————————————————————————
【详细总结】Pytorch训练模型损失Loss为Nan或者无穷大(INF)原因
torch.clamp()
【问题记录】PyTorch NaN RuntimeError: Function ‘MulBackward0‘ returned nan values in its 0th output. 深度学习
Function ‘MseLossBackward0‘ returned nan values in its 0th output.
Pytorch计算Loss值为Nan的一种情况,如何检测NAN?

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在训练LSTM时出现结果全为NaN问题通常是由于训练过程出现了梯度爆炸或梯度消失的情况。 首先,梯度爆炸可能是由于网络层数较深,导致反向传播时梯度值呈指数级增长。解决这个问题的方法包括:使用梯度裁剪,即设置一个阈值,当梯度超过该阈值时进行裁剪;缩小学习率,降低梯度的更新幅度;权重正则化等方法。 其次,梯度消失可能是由于网络层数较深,反向传播时梯度值太小,使得权重更新几乎没有发生。解决这个问题的方法包括:初始化权重时使用较小的随机数,使得梯度不容易消失;使用ReLU、LSTM等激活函数,可以缓解梯度消失问题;使用Batch Normalization进行归一化等。 此外,还可以对输入数据进行预处理,包括归一化、标准化等,减少数据的变化范围,有助于提高网络的稳定性。 同时,监控损失函数的变化情况,如果损失函数在训练过程出现不稳定或发散的情况,也可能导致结果为NaN。在这种情况下,可以考虑调整损失函数的权重或改变网络结构,以提高训练的稳定性。 总之,解决LSTM训练过程结果全为NaN问题需要综合考虑网络结构、权重初始化、梯度裁剪、学习率等因素,并根据具体情况采取相应的调整策略,以确保训练的稳定性和结果的有效性。 ### 回答2: 当在PyTorch训练LSTM模型时,结果全为NaN(Not a Number),通常是由于以下几个原因导致的。 1. 数据预处理问题:在训练LSTM模型之前,需要对数据进行预处理。检查是否有缺失数据或异常值。如果输入数据包含NaN值,LSTM模型将会返回NaN作为结果。确保数据集不含NaN值,并对数据进行适当的归一化或标准化。 2. 学习率过高:使用的学习率可能过高,导致训练过程发生梯度爆炸或梯度消失的情况。尝试减小学习率,可以通过调整优化器的参数来实现,如减小学习率衰减系数或使用较小的固定学习率。 3. 梯度裁剪不足:LSTM模型存在梯度爆炸的问题,可以尝试增加梯度裁剪的阈值。通过限制梯度值的大小,可以防止梯度爆炸的问题。 4. 网络结构问题:LSTM模型的网络结构可能存在问题。检查网络结构的参数设置,例如隐藏层的大小,网络深度等。过大或过小的网络结构可能导致训练不稳定或结果出现NaN。 5. 默认参数问题:检查训练过程使用的其他参数设置。例如,优化器的选择,损失函数的选择,迭代次数等。尝试更换不同的优化器和损失函数,适当调整迭代次数。 总结来说,当LSTM模型训练过程出现结果全为NaN时,需要仔细检查数据预处理、学习率、梯度裁剪、网络结构和默认参数等方面的问题,并进行相应的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值