困困的晴啊 2025-07-28 11:34 采纳率: 0%
浏览 7

RUAS算法NAN报错

RUAS低光增强代码复现,只更换了数据集,运行train.py,但在第150step的时候就nan了
2025-07-26 04:48:35,653 gpu device = 2
2025-07-26 04:48:35,653 args = Namespace(batch_size=1, gpu=2, report_freq=50, seed=2)
2025-07-26 05:19:09,974 train 050 0.332135 0.010473
2025-07-26 05:19:12,571 train 100 0.261804 0.003910
2025-07-26 05:19:15,217 train 150 0.374308 inf
2025-07-26 05:19:17,864 train 200 nan nan
2025-07-26 05:19:20,476 train 250 nan nan
2025-07-26 05:19:23,128 train 300 nan nan
2025-07-26 05:19:25,754 train 350 nan nan
2025-07-26 05:19:28,275 train 400 nan nan
2025-07-26 05:19:31,051 train 450 nan nan
2025-07-26 05:19:33,840 train 500 nan nan
2025-07-26 05:19:36,497 train 550 nan nan
2025-07-26 05:19:39,260 train 600 nan nan
2025-07-26 05:19:42,074 train 650 nan nan
2025-07-26 05:19:44,842 train 700 nan nan
2025-07-26 05:19:47,501 train 750 nan nan
2025-07-26 05:19:50,135 train 800 nan nan

  • 写回答

5条回答 默认 最新

  • 檀越@新空间 2025-07-28 11:35
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    在使用 RUAS(Recurrent Unsupervised Attention System) 算法进行低光增强代码复现时,遇到 NAN 报错 是一个常见的问题。根据你提供的日志信息,可以看到训练在第 150 步后出现了 infnan,说明模型的损失值或梯度中出现了异常数值。


    可能的原因分析

    1. 数据输入异常

    • 数据集中存在 无效图像全黑/全白图像
    • 图像尺寸不一致或格式错误,导致模型无法处理。

    2. 学习率设置过高

    • 如果学习率过大,可能导致梯度爆炸(Gradient Explosion),从而产生 infnan

    3. 模型结构不稳定

    • 某些层(如卷积、残差块等)设计不当,容易引发数值溢出。
    • 使用了 Sigmoid 或 Softmax 等激活函数,若输入值过大也可能导致 inf

    4. 权重初始化不当

    • 权重初始化不规范,可能导致某些层输出过大。

    5. 正则化不足

    • 缺乏梯度裁剪(Gradient Clipping)或权重衰减(Weight Decay),导致梯度爆炸。

    解决方案

    以下是针对上述问题的详细解决步骤:

    1. 检查并清洗数据集

    重点:确保所有图像都是有效的,并且尺寸一致。

    import cv2
    import os
    
    def is_valid_image(path):
        try:
            img = cv2.imread(path)
            if img is None or img.size == 0:
                return False
            return True
        except Exception as e:
            print(f"Error reading image {path}: {e}")
            return False
    
    # 遍历数据集目录,过滤掉无效图像
    valid_files = [f for f in os.listdir("your_dataset_path") if is_valid_image(os.path.join("your_dataset_path", f))]
    

    建议:在训练前对图像进行归一化处理(如 0~1 范围)。


    2. 调整学习率和优化器配置

    重点:降低学习率,防止梯度爆炸。

    # 原始学习率
    # optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
    
    # 修改后的学习率(可尝试 1e-5)
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-5)
    

    建议:可以使用 torch.optim.lr_scheduler 动态调整学习率。


    3. 添加梯度裁剪(Gradient Clipping)

    重点:防止梯度爆炸。

    from torch.nn.utils import clip_grad_norm_
    
    # 在每次反向传播后添加梯度裁剪
    clip_value = 1.0
    clip_grad_norm_(model.parameters(), clip_value)
    

    4. 检查模型结构中的潜在问题

    重点:避免使用可能导致数值不稳定的操作(如 Sigmoid、Softmax)。

    例如,检查是否在最后的输出层使用了 sigmoid

    # 不推荐:
    output = torch.sigmoid(output)
    
    # 推荐(如果使用 BCEWithLogitsLoss):
    output = output  # 不加激活函数
    

    5. 添加权重初始化策略

    重点:使用标准初始化方法(如 Kaiming、Xavier)。

    def weights_init(m):
        if isinstance(m, nn.Conv2d):
            nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
            if m.bias is not None:
                nn.init.constant_(m.bias, 0)
        elif isinstance(m, nn.BatchNorm2d):
            nn.init.constant_(m.weight, 1)
            nn.init.constant_(m.bias, 0)
    
    model.apply(weights_init)
    

    6. 添加日志监控和调试

    重点:实时监控损失值、梯度、参数范围。

    import torch
    
    def log_gradient_norm(model):
        total_norm = 0
        for p in model.parameters():
            if p.grad is not None:
                param_norm = p.grad.data.norm(2)
                total_norm += param_norm.item() ** 2
        total_norm = total_norm ** (1. / 2)
        print(f"Gradient norm: {total_norm}")
    
    # 在训练循环中调用
    log_gradient_norm(model)
    

    总结

    | 问题 | 解决方案 | |------|----------| | 数据异常 | 清洗数据,确保图像有效 | | 学习率过高 | 降低学习率,使用动态调整 | | 梯度爆炸 | 添加梯度裁剪 | | 模型结构问题 | 检查激活函数和输出层 | | 权重初始化 | 使用 Kaiming/Xavier 初始化 | | 调试困难 | 添加日志监控,观察梯度和参数变化 |


    如果你能提供 部分代码片段(如训练循环、模型定义等),我可以进一步帮你定位具体问题所在。

    评论

报告相同问题?

问题事件

  • 创建了问题 7月28日