解决RuntimeError: CUDA error: device-side assert triggeredCUDA kernel errors...CUDA_LAUNCH_BLOCKING=1

完整报错

RuntimeError: CUDA error: device-side assert triggeredCUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.For debugging consider passing CUDA_LAUNCH_BLOCKING=1.
 其实出现这种情况的原因,(由于我本人遇见bug比较多)我踩得坑分为两种 ,不知道还会不会有更多原因也是报如上错误!!!!

第一种情况(常见,通常不能完整训练1轮数据)

 如果您已经查到过本方法,并且未解决的话,可以直接看第二种情况~~~
 相信大家也查阅了很多如上述错误的帖子了,大部分都是说大家的标签设置不对!简单来说:拿VOC格式数据举例子: 假设您需要要做一个2分类,数据信息呢又都在VOC种类数据集中的 “Annotations” 文件夹之中的 “.xml” 文件中,但是数据不干净,不小心掺杂了其他数据集的 “.xml” 文件,图片也放进对应文件夹的话,就会导致数据标签多了1或者多类别, 所以再train数据集的时候,开始还能正常运行,当dataload加载到那个多余的 “.xml” 文件信息时就会在您提供的label.txt文件里面找不到这个分类,出现如上错误。在此给出一个检查所有Annotations 文件夹之中一共有多少个label的代码:

  •   假设现在的标签为allowed_labels = ['1', '2', '3', '0'], 以下代码会找出不是设定的标签值,且输出错误标签的绝对路径以及包含所有标签的labels.txt标签文件。
import os
import xml.etree.ElementTree as ET

from tqdm import tqdm


def getClsTxt(xmlDir, cls_txt, allowed_labels):
    """
    xmlDir        : XML directory path
    cls_txt       : Output cls file path
    allowed_labels: List of allowed labels
    """

    invalid_label_paths = []  # List to store paths of XML files with invalid labels

    for name in tqdm(os.listdir(xmlDir)):
        xmlFile = os.path.join(xmlDir, name)
        with open(xmlFile, "r+", encoding='utf-8') as fp:
            tree = ET.parse(fp)
            root = tree.getroot()

            invalid_labels = set()
            for obj in root.iter('object'):
                cls_element = obj.find('name')
                if cls_element is not None:
                    cls = cls_element.text
                    invalid_labels.add(cls)
                    if cls not in allowed_labels:
                        invalid_label_paths.append((xmlFile, cls))  # Store both XML path and invalid label

            set_cls.update(invalid_labels)

    if invalid_label_paths:
        print("Invalid labels found in the following XML files:")
        for path, invalid_label in invalid_label_paths:
            print(f"{path}, Error category is: {invalid_label}")
    else:
        print("No invalid labels found.")

    with open(cls_txt, "w+") as ft:
        for i in set_cls:
            ft.write(i + "\n")


if __name__ == '__main__':
    set_cls = set()
    xmlDir = "output/VOC-1205/Annotations"
    cls_txt = "output/VOC-1205/labels.txt"
    allowed_labels = ['1', '2', '3', '0']

    getClsTxt(xmlDir, cls_txt, allowed_labels)

 运行如下代码可以自动帮您生成所有 “.xml” 文件中出现过的label,并写入labels.txt中!然后您可以对比一下和自己原来训练所用的标签能否对应上。
 第一种情况的错误,如果您的数据加载代码没问题包含了所有的数据,一般会在第一轮训练不完就报此错误~~~

第二种情况(不常见,报错轮次随机)

 下图可见,作者训练了41轮次快结束时候报错,前面40多轮都是正常训练的,有时候不到三轮就报这个错误了,采用第一种情况的解决方法,对照了我自己的label种类发现都是没有问题的!出现这种问题的原因在于作者在魔改网络模型结构不精所致,可以细心的发现下图最底下报错日志多了一行。如下
/pytorch/aten/src/ATen/native/cuda/Loss.cu:115: operator(): block: [19,0,0], thread: [0,0,0] Assertion input_val >= zero && input_val <= one failed.
 该报错一下就能看出是loss函数的问题,原因是没有在魔改的层加上归一化层,可以在该层加上BatchNorm2d,或者在head层最后加上sigmoidsofmax激活函数即可解决。
在这里插入图片描述
也可以查看标签的范围:

assert targets.max() > 1 or targets.min() < 0, "label error max{} min{}".format(targets.max(), targets.min())

第三种情况(训练不报错,验证报错如上错误)

  再次更新这篇博文,如果您上述两种情况都尝试过了,还是不行且每次训练不报错,都是在验证集上报错时,我这边有一个方法,对我是有效的,可以尝试一下,在读取数据时候将num_workers改为0。

DataLoader(num_workers=0)

总结错误

  错误原理:因为我这个是目标检测的错误,我看很多评论区小伙伴也都报这个错误(有些是分割领域的)。因为这个帖子是我早期学习的时候写的,当时不知道分割也会遇见这种错误,很多错误我也没有办法去复现解决,所以我可以在这里提供一下两种错误的错误原理是什么,大家根据自己的数据写对应错误的脚本或者清洗数据,或者修改模型和loss函数。光看这个泛泛的报错确实比较难解决,知道了错误原理,才能进一步修改错误。

  1. 第一种,类别标签和你网络的最后一层对不上。通俗来说,就是你的任务(检测,分割,追踪等等)标签类别少了,或者多了。仔细观察你的数据格式,写一个作者那样类似的功能脚本,清洗一下所有的标签类别(gpt写好你的数据格式名称,在遍历所有数据时,提取每一个标签文件的标签,然后存set容器并打印即可)。
  2. 第二种,你的网络最后一层的输出值域是否能和你的选取的loss函数的定义域对应上,有的loss函数的只支持[0, 1],读者网络最后输出给loss的是[-1, 1],也会报这个错误。
  3. 第三种,Windows似乎不支持DataLoader(num_workers=0)num_workers > 1的情况。在算力和内存资源充足linux下num_workers > 1没有什么问题。(此条不确定是否正确,我遇见的时候是这样的)
  • 53
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 39
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锦鲤AI幸运

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值