You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中LSTM训练循环反向传播时MSELoss出现NaN问题

LSTM训练出现NaN Loss的问题分析与解决方案

可能原因及对应解决方法

1. 梯度爆炸

LSTM训练时易出现梯度爆炸,即便做了数据归一化,反向传播中梯度仍可能急剧放大,导致参数变为NaN。

解决方法:

  • 添加梯度裁剪:在反向传播后限制梯度的最大范数,训练循环中加入:
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
    
    可根据实际情况调整max_norm(如0.5、2.0)。
  • 初始化LSTM权重:手动对LSTM权重做正交初始化,避免初始权重过大:
    for name, param in model.lstm.named_parameters():
        if 'weight' in name:
            nn.init.orthogonal_(param)
    

2. 学习率过高

Adam默认学习率0.001可能适配性差,参数更新幅度过大直接跳到NaN区域。

解决方法:

  • 降低学习率:初始化优化器时设置更小的学习率:
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
    
    可尝试1e-4、5e-5等,逐步调整到合适值。

3. 数据残留异常值

即便做了归一化,原始数据中的NaN、无穷大或极端值仍可能导致计算溢出。

解决方法:

  • 检查并清理数据:转换张量前先排查异常值:
    print(traindf.isna().sum())
    print(traindf.describe())
    
    删除含异常值的样本,或用中位数/均值填充。

4. 训练循环细节疏漏

比如忘记清零梯度导致梯度累积过大,或计算流程有误。

解决方法:

  • 规范训练循环流程:确保每次迭代先清零梯度,流程如下:
    model.train()
    for x, y in train_loader:
        optimizer.zero_grad()  # 必须在迭代开始时清零梯度
        outputs = model(x)
        loss = loss_fn(outputs, y)
        loss.backward()
        torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
        optimizer.step()
        print(loss.item())
    

5. 模型输出数值溢出

可验证前向传播的输出范围,确认是否出现极端值:

outputs = model(x)
print("Output min:", outputs.min().item(), "Output max:", outputs.max().item())

若输出存在极大值,结合梯度裁剪与学习率调整解决。


内容的提问来源于stack exchange,提问作者user17515752

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:25:35