学习Pytorch深度学习运行AlexNet代码时关于在Pycharm中解决 “t >= 0 t < n_classes” 的断言错误方法

在学习深度学习的过程中,遇到了一个报错:

 这跑的代码是AlexNet的代码实现。

运行时出现报错:

C:\cb\pytorch_1000000000000\work\aten\src\ATen\native\cuda\Loss.cu:257: block: [0,0,0], thread: [4,0,0] Assertion `t >= 0 && t < n_classes` failed.

解决方案:

当你遇到 CUDA error: device-side assert triggered 和具体的断言错误 t >= 0 && t < n_classes,这通常指示在 CUDA 上运行的某些操作遇到了问题,大多数情况下是由于标签值 t 超出了期望的范围。这里的问题发生在执行损失函数计算时,具体来说是在 PyTorch 的底层 CUDA 代码中。

问题的主要源头:

由于错误提示 t >= 0 && t < n_classes,你需要确保所有标签值都在正确的范围内。对于分类任务,标签值 t 应该是一个非负整数,并且小于类别总数 n_classes。如果你的数据集标签不是从 0 开始的,你需要将它们转换为从 0 开始。

在合适的位置定义:确保 n_classes 在你尝试使用它进行断言检查之前已经被定义。这通常意味着你需要在加载数据集、初始化数据加载器之前,或在定义模型之处确定 n_classes 的值。

这里我的代码中已经指定:

由于错误报告显示断言失败发生在损失计算时,一个可能的原因是某些样本的标签不在 [0, n_classes-1] 的范围内。你可以添加一些代码在损失计算之前检查标签值:

增添代码段:

        if not (labels.min() >= 0 and labels.max() < n_classes):
            print("不满足条件的标签值:", labels[labels < 0], labels[labels >= n_classes])

 以及:

n_classes = 102  # 根据你的具体任务设置这个值, 这里对应num_classes=102

继续运动代码进行测试,出现如下报错:

 从提供的输出信息来看,断言错误是因为存在标签值等于 102,这超出了预期的类别范围 [0, n_classes-1]。假设 n_classes 应该是 102(意味着有效的标签范围是从 0101),标签值 102 显然是无效的,因为它等于类别总数,超出了最大有效索引。

解决方案

  1. 校正类别总数:首先确认 n_classes 的值是否正确。如果你的任务确实有 102 个类别(例如,Flowers102 数据集),那么 n_classes 应该设置为 102,并且你需要确保所有标签都在 [0, 101] 的范围内。

  2. 修正数据标签:由于出现了 102 作为标签值,这可能是由于数据标签在某个步骤中被错误地分配或转换。你需要回溯到数据处理的步骤,找出为什么会有 102 这样的标签值出现,并进行修正。如果是因为数据集自带的标签从 1 开始计数,那么你需要将所有标签减 1 以转换为从 0 开始计数:

增添代码:

# 假设 `labels` 是你的标签张量
labels = labels - 1

测试和验证

在进行了上述修正之后,再次运行你的代码,并使用之前添加的打印语句来验证所有标签值是否都在正确的范围内。如果没有进一步的断言错误,那么这意味着问题已经被解决。如果问题依然存在,可能需要进一步调查数据处理流程中的每一个步骤,确保在任何地方都没有引入标签错误。

再一次运行代码,发现没有报错,代码运行正常:

模型开始了训练,问题得到了解决!!!

最后给出优化后的完整python代码:

文件:main_AlexNet.py

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms, models
from tqdm import *
import numpy as np
import matplotlib.pyplot as plt
import sys
from AlexNet import AlexNet
import os
# os.environ['CUDA_LAUNCH_BLOCKING'] = '1'

# 设备检测,若未检测到cuda设备则在CPU上运行
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 设置随机种子
torch.manual_seed(0)

# 定义模型、优化器、损失函数
model = AlexNet(num_classes=102).to(device)
optimizer = optim.SGD(model.parameters(), lr=0.002, momentum=0.9)
criterion = nn.CrossEntropyLoss()

# 设置训练集的数据变换,进行数据增强
transform_train = transforms.Compose([
    transforms.RandomRotation(30),  # 随机旋转 -30度到30度之间
    transforms.RandomResizedCrop((224, 224)),  # 随机比例裁剪并进行resize
    transforms.RandomHorizontalFlip(p=0.5),  # 随机水平翻转
    transforms.RandomVerticalFlip(p=0.5),  # 随机垂直翻转
    transforms.ToTensor(),  # 将数据转换为张量
    # 对三通道数据进行归一化(均值,标准差), 数值是从ImageNet数据集上的百万张图片中随机抽样计算得到
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 对数据进行归一化
])

# 设置测试集的数据变换,进行数据增强
transform_test = transforms.Compose([
    transforms.Resize((224, 224)),  # resize
    transforms.ToTensor(),  # 将数据转化为张量
    # 对三通道数据进行归一化(均值,标准差),数值是从ImageNet数据集上的百万张图片中随机抽样计算得到
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

# 加载训练数据,需要特别注意的是Flowers102数据集,test簇的数据量较多些,所以这里使用"test"作为训练集
train_dataset = datasets.Flowers102(root='./data/flowers102', split="test",
                                    download=False, transform=transform_train)
# 实例化训练数据加载器
train_loader = DataLoader(train_dataset, batch_size=256, shuffle=True, num_workers=6, drop_last=False)
# 加载测试数据,使用“train”作为测试集
test_dataset = datasets.Flowers102(root='./data/flowers102', split="train",
                                   download=False, transform=transform_test)
# 实例化测试数据加载器
test_loader = DataLoader(test_dataset, batch_size=256, shuffle=False, num_workers=6, drop_last=False)

# 设置epoch数并开始训练
num_epochs = 500  # 设置epoch数
n_classes = 102  # 根据你的具体任务设置这个值, 这里对应num_classes=102
loss_history = []  # 创建损失历史记录列表
acc_history = []  # 创建准确率历史记录列表

# tqdm用于显示进度条并评估任务时间开销
for epoch in tqdm(range(num_epochs), file=sys.stdout):
    # 记录损失和预测正确数
    total_loss = 0
    total_correct = 0

    # 批量训练
    model.train()
    for inputs, labels in train_loader:

        labels = labels - 1

        if not (labels.min() >= 0 and labels.max() < n_classes):
            print("不满足条件的标签值:", labels[labels < 0], labels[labels >= n_classes])

        # 将数据转换到指定计算资源设备上
        inputs = inputs.to(device)
        labels = labels.to(device)

        # 预测、损失函数、反向传播
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # 记录训练集loss
        total_loss += loss.item()

    # 测试模型,不计算梯度
    model.eval()
    with torch.no_grad():
        for inputs, labels in test_loader:
            # 将数据转换到指定计算资源设备上
            inputs = inputs.to(device)
            labels = labels.to(device)

            # 预测
            outputs = model(inputs)
            # 记录测试集预测正确数
            total_correct += (outputs.argmax(1) == labels).sum().item()

    # 记录训练集损失和测试集准确率
    loss_history.append(np.log10(total_loss))  # 将损失加入损失历史记录列表,由于数值有时较大,这里取对数
    acc_history.append(total_correct / len(test_dataset))  # 将准确率加入准确率历史记录列表

    # 打印中间值
    # 每50个epoch打印一次中间值
    if epoch % 50 == 0:
        tqdm.write("Epoch: {0} Loss: {1} Acc: {2}".format(epoch, loss_history[-1], acc_history[-1]))

# 使用Matplotlib绘制损失和准确率的曲线图
plt.plot(loss_history, label='loss')
plt.plot(acc_history, label=' ')
plt.legend()
plt.show()

# 输出准确率
print("Accuracy:", acc_history[-1])

文件:AlexNet.py

import torch
import torch.nn as nn
from torchinfo import summary

# 定义AlexNet的网络结构
class AlexNet(nn.Module):
    def __init__(self, num_classes=1000, dropout=0.5):
        super().__init__()
        # 定义卷积层
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        # 定义全连接层
        self.classifier = nn.Sequential(
            nn.Dropout(p=dropout),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(p=dropout),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

# 查看模型结构以及参数量,input_size表示示例输入数据的维度信息
# summary(AlexNet(), input_size=(1,3,224,224))

将epoch改为100,得到如下训练结果:

 可见模型还未收敛,大家可以自行调节参数来尝试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/380492.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

抽象springBoot报错

Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. 中文翻译&#xff1a;无法配置DataSource&#xff1a;未指定“url”属性&#xff0c;并且无法配置嵌入数据源。 DataSource 翻译&#xff1a;数据源 得…

数据结构入门(1)数据结构介绍

目录 前言 1. 什么是数据结构&#xff1f; 2.什么是算法&#xff1f; 3.数据结构和算法的重要性 前言 本文将开始介绍计算机里的数据结构。 数据结构是指数据对象中元素之间的关系&#xff0c;以及对这些关系的操作。数据结构可以分为线性结构和非线性结构。 线性结构是…

Python相关的基础模块

Python相关的基础模块 在编写远程控制工具之前&#xff0c;先要介绍用Python编写远程控制工具时所需要的 相关模块&#xff0c;为接下来编写工具打下基础。 1.subprocess模块 subprocess模块的主要作用是执行外部的命令和程序。当我们运行Python的时 候&#xff0c;其实也是在运…

32串口数据包

目录 一.数据包格式 &#xff08;1&#xff09;HEX数据包 &#xff08;2&#xff09;文本数据包 二.代码实现 &#xff08;1&#xff09;串口收发HEX数据包 (2)串口收发文本数据包&#xff08;该程序没有写出来&#xff0c;暂时找不到错误&#xff0c;以后再看&#xff09;…

蓝桥杯每日一练(python)B组

###来源于dotcpp的蓝桥杯真题 题目 2735: 蓝桥杯2022年第十三届决赛真题-取模&#xff08;Python组&#xff09; 给定 n, m &#xff0c;问是否存在两个不同的数 x, y 使得 1 ≤ x < y ≤ m 且 n mod x n mod y 。 输入格式&#xff1a; 输入包含多组独立的询问。 第一…

浅谈应该遵守的伦敦银交易规则

做伦敦银投资的朋友应遵守伦敦银交易规则&#xff0c;伦敦银交易规则不是指那些伦敦银交易技巧&#xff0c;而是在这个市场中要遵循的一些约定&#xff0c;下面我们就来讨论一下。 风险管理。风险管理即指投资者控制自己一笔乃至整体交易的风险&#xff0c;没有风险管理意识的投…

技术精英求职必备:Java开发工程师简历制作全指南

投简历找工作嘛&#xff0c;这事儿其实就跟相亲差不多&#xff0c;得让对方一眼就看上你。 在这场职场的‘相亲’中&#xff0c;怎样才能让你的简历脱颖而出&#xff0c;成为HR眼中的理想‘对象’呢&#xff1f;来&#xff0c;我给你支几招&#xff0c;让你的简历更吸引人。 …

前端又又出新框架,这次没有打包了

最近&#xff0c;前端开发领域又迎来了一个新框架——ofa.js。它的独特之处在于&#xff0c;不依赖于现有的 nodes/npm/webpack 前端开发工作流程。与jQuery类似&#xff0c;只需引用一个脚本&#xff0c;您就能像使用React/Vue/Angular一样轻松地开发大型应用。 极易上手 如果…

八卦图与二进制

名称二进制乾111坤000震100艮001离101坎010兑110巽011 1.卦象从下往上排&#xff0c;称为初爻、二爻、上爻&#xff0c;长线为1&#xff0c;短线为0&#xff0c;可以根据卦象记忆对应的二进制&#xff0c;二进制数也从下往上排。 2.注意&#xff1a;在使用二进制时&#xff0…

【精选】java初识多态 多态调用成员的特点

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

SQL拆分字段内容(含分隔符)

问题描述&#xff1a; 在做数据迁移的过程中&#xff0c;我们希望对表中的某个字段根据分隔符进行拆分&#xff0c;得到多条数据&#xff0c;原代码有点意思&#xff0c;因此记录一下。 我们假设某条数据如下&#xff1a; IDSTRS1公司名称不能小于四个字&#xff0c;行业类别…

Unity学习笔记之【IK反向动力学操作】

反向动力学Inverse Kinematics 反向动力学&#xff0c;简称IK。相较于正向动力学&#xff0c;反向动力学旨在子级对父级产生的影响。 使用IK&#xff0c;可以实现根据目标位置或方向来计算并调整角色的关节&#xff08;骨骼&#xff09;链&#xff0c;以使角色的末端&#xff…

关节点检测

https://www.bilibili.com/video/BV19g4y1777q/?p2&spm_id_frompageDriver 关节点检测全流程 YOLO:单阶段&#xff0c;快&#xff1b; MMPose&#xff1a;双阶段&#xff0c;准&#xff1b; 标注工具Labelme 用Labelme标注样本数据集

FastDFS 分布式集群搭建详解

文章目录 前言1、整体架构2、安装配置FastDFS集群2.1 配置tracker2.2 配置storage 3、启动集群4、查看集群情况5、nginx配置5.1 配置storage的四台机器的nginx5.2 配置tracker的两台机器的nginx5.3 配置统一入口 前言 阅读本文章之前请先看上一篇单机版FastDFS安装配置详解&am…

为什么在产品设计和制造过程中要采用FMEA——SunFMEA软件

在产品设计和制造过程中&#xff0c;FMEA是一种非常重要的工具&#xff0c;用于评估潜在的故障模式及其对产品性能的影响。通过分析产品设计或流程中可能出现的故障模式&#xff0c;并评估其对产品性能和客户满意度的潜在影响&#xff0c;来预测和防止产品在生产和运行过程中出…

深入解析Linux中HTTP代理的工作原理

亲爱的Linux探险家们&#xff0c;准备好一起探索HTTP代理背后的神秘面纱了吗&#xff1f;在这个数字世界里&#xff0c;HTTP代理就像是一个神秘的中间人&#xff0c;默默地在你和互联网之间穿梭&#xff0c;为你传递信息。那么&#xff0c;这个神秘的中间人到底是如何工作的呢&…

vue3 的setup和生命周期

vue3 的setup和生命周期 许多文章认为setup执行时间在beforeCreate 和created 之间&#xff0c;但是通过实际测试发现setup调用在beforecreate之前。 export default {beforeCreate() {console.log(beforeCreate running....);},created() {console.log("created runnin…

制度下降算法c语言

#include<stdio.h> #include<string.h> int location0; //遍历字符串的当前位置 char arr[20]"idid*id#"; void error(); //错误提示函数 /* 每一个非终结符都构造一个函数 */ void E(char t); void Ep(char t); void T(char t); void Tp(char t);…

[职场] 公务员面试停顿磕巴常见吗 #学习方法#知识分享#知识分享

公务员面试停顿磕巴常见吗 面试时说话磕巴简直是太常见了&#xff0c;对于一个新问题&#xff0c;让人在短时间内&#xff0c;并且仅仅是三分钟内&#xff0c;就组织起一个答案&#xff0c;还无法全部打手稿&#xff0c;这对于连上个讲台都会脸发红的人来说&#xff0c;简直是一…

【51单片机Keil+Proteus8.9】门锁控制电路

门锁控制电路 二、设计思路 电路设计 1.电源部分&#xff1a;使用BATTERY为整个电路提供电源&#xff0c;可以在电路中加入一个电 源开关&#xff0c;以便控制电源的开启和关闭。 2.处理器部分&#xff1a;使用AT89C51芯片作为主处理器&#xff0c;通过编写程序实现门锁的 …