yolov8 出现loss 为nan

原因:

  混合精度训练是一种通过同时使用 FP16 和 FP32 精度来加速深度学习训练的技术。它可以在不损失模型性能的情况下,显著减少训练时间和内存使用。下面是关于混合精度训练的一些解释:

1. 原理

        混合精度训练利用了 FP16 (16位浮点)和 FP32 (32位浮点)的不同特性。

        FP16 计算速度快,但动态范围和精度较低。FP32 则相反,计算速度较慢但动态范围和精度较高。

        混合精度训练将网络的某些部分(如权重和激活)使用 FP16 表示,而其他部分(如梯度)使用 FP32 表示。这样可以在不损失模型性能的情况下,提高训练速度和减少内存使用。

        Float16 (FP16) 和 Float32 (FP32)的差异:

                FP16 使用 16 bit 表示浮点数,FP32 使用 32 bit。

                FP16 的动态范围和精度较 FP32 更小,但计算速度更快,尤其在 GPU 上。

                FP16 可能会产生溢出和下溢出,导致精度损失。需要特殊处理来避免这些问题

2. 实现

        常见的混合精度训练库包括 NVIDIA 的 APEX 和 PyTorch 内置的 torch.cuda.amp 模块。

        使用时,需要将模型和优化器包装在 FP16 和 FP32 混合精度上下文中,并使用特殊的损失缩放和梯度重scaling技术。

例如在 PyTorch 中,可以使用如下代码启用混合精度训练:

3. 混合精度训练的流程

        将网络中的部分操作使用 FP16 表示,其他部分使用 FP32 表示。通常权重和激活使用 FP16,梯度和损失函数使用 FP32。

        需要使用 loss scaling 技术来避免 FP16 计算时的精度损失。

        在反向传播时,需要使用 gradient scaling 和 gradient clipping 技术来确保梯度的稳定性。

4. 优势

        训练速度提高 2-3 倍

        内存使用降低 2 倍左右

        无需修改原有的训练代码,只需添加少量混合精度相关的代码

        总之,混合精度训练是一种非常实用的技术,可以大幅提高深度学习模型的训练效率,是深度学习从业者必须掌握的技能之一。

这篇博客警示读者在购买用于深度学习的显卡时要避开那些导致RuntimeWarning: All-NaN slice encountered的问题。作者强调这些Tensor核心存在严重缺陷,不适宜进行深度学习任务,建议大家在选购时务必谨慎。

yolov8 出现loss 为nan_第1张图片

方法一:降低cuda和pytorch 版本号

pip3 install torch==1.10.2+cu102 torchvision==0.11.3+cu102 torchaudio===0.10.2+cu102 -f https://download.pytorch.org/whl/cu102/torch_stable.html

方法二:将混合精度训练AMP 设置为False

第一步:找到ultralytics\cfg\default.yaml中的default.yaml文件
将default.yaml中的amp设置为false,如下所示:

amp: False # (bool) Automatic Mixed Precision (AMP) training, choices=[True, False], True runs AMP check


将default.yaml中的half设置为false,如下所示:

half: False  # (bool) use half precision (FP16)


第二步:

找到ultralytics\engine\validator.py中的validator.py文件,如下所示:

将self.args.half = self.device.type != 'cpu' # force FP16 val during training这行代码注释掉

# self.args.half = self.device.type != 'cpu'  # force FP16 val during training



修改之后的代码为:

self.training = trainer is not None
        augment = self.args.augment and (not self.training)
        if self.training:
            self.device = trainer.device
            self.data = trainer.data
            # self.args.half = self.device.type != 'cpu'  # force FP16 val during training
            model = trainer.ema.ema or trainer.model
            model = model.half() if self.args.half else model.float()
            if hasattr(model, 'criterion'):
                if hasattr(model.criterion.bbox_loss, 'wiou_loss'):
                    model.criterion.bbox_loss.wiou_loss.eval()
            # self.model = model
            self.loss = torch.zeros_like(trainer.loss_items, device=trainer.device)
            self.args.plots &= trainer.stopper.possible_stop or (trainer.epoch == trainer.epochs - 1)
            model.eval()

在使用GTX16xx系列显卡训练YOLO系列模型时,可能会遇到训练过程中loss出现nan值或者测试时P/R/map全部为0的问题。这些问题通常是由于显卡硬件和软件配置不当导致的。为了解决这些问题,可以尝试以下几种方法:

  1. 调整学习率:学习率过高可能导致训练过程中的数值溢出或下溢,从而产生nan值。可以尝试减小学习率,以避免这种情况的发生。
  2. 增加梯度下降的步长:在某些情况下,梯度下降的步长过小可能导致训练不稳定,产生nan值。可以尝试增加步长,以提高训练的稳定性。
  3. 开启梯度检查:在训练过程中,可以开启梯度检查来检测梯度的合理性。如果发现梯度不合理(例如梯度过大或过小),可以采取相应的措施进行调整。
  4. 检查数据集:数据集的质量对模型的训练至关重要。如果数据集中存在噪声或异常值,可能会导致训练不稳定或产生nan值。因此,需要仔细检查数据集的完整性、标注的准确性等。
  5. 更新显卡驱动和CUDA版本:显卡驱动和CUDA版本过旧可能导致与YOLO系列模型的兼容性问题。尝试更新到最新版本的驱动和CUDA,以解决潜在的兼容性问题。
  6. 检查模型结构和参数:有时候,模型的结构或参数设置不当也可能导致训练不稳定或产生nan值。可以尝试调整模型的结构或参数,以找到最优的设置。
  7. 使用混合精度训练:混合精度训练是一种提高训练速度的方法,它使用float16和float32两种数据类型进行训练。然而,在某些情况下,混合精度训练可能会导致数值不稳定性,产生nan值。在这种情况下,可以尝试关闭混合精度训练,只使用float32数据类型进行训练。
  8. 检查代码实现:在某些情况下,代码实现可能存在错误或不当之处,导致训练或测试过程中出现问题。仔细检查代码实现,确保符合YOLO系列模型的规范和要求。
    如果尝试了以上方法仍然无法解决问题,可以考虑使用其他版本的YOLO系列模型或更换其他型号的显卡进行训练和测试。同时,也可以参考相关社区和论坛中其他用户的经验和解决方案,以获取更多的帮助和建议。

你可能感兴趣的:(YOLO)