pytorch训练几次后爆显存 pytorch训练模型识别数学公式

本文针对pytorch模型训练中出现的精度不提升、甚至低于随机猜测的问题进行深入探讨。核心原因存在模型评估阶段对正确预测数量的累积方式不当,以及输入数据维度处理和标签维度的潜在错误。教程将详细分析这些常见错误,并提供正确的代码实现,帮助训练开发者有效诊断并解决模型效果不佳的困境,确保模型评估的准确性。引言:模型训练精度困扰的困扰
在深度学习模型开发过程中,开发者经常会遇到模型训练效果不理想,甚至在经过数百个Epoch后,其在测试集上的表现仍然不如随机假设的情况。遇到这种问题,许多人会首先尝试调整批量大小、网络层数、学习率或纪元数量等超参数,但往往徒劳无功。这不仅令人沮丧,也阻碍了模型的进一步优化。实际上,有时问题的根源并不是出自模型架构或训练算法本身,而提出数据处理流程、维度匹配或最常见的——模型性能评估逻辑中的计算错误。原始代码分析与潜在问题诊断
为了更好地理解并解决此类问题,我们假设提供的PyTorch代码进行逐一分析,并指出其中可能导致模型精度异常的关键点。 数据加载与损耗
代码中定义了SDSS和testSDSS两个几乎四个的数据集类,都是从SDSS.csv文件中加载数据。重复定义:这种定义是不必要的。通常,一个数据集类足够,然后通过torch.utils.data.random_split或手动加载不同的文件来创建训练集和测试集。数据维度:self.x_data = torch.from_numpy(xy[:,, 1:]):特征数据,形状为 [n_samples, n_features] (例如 [N, 5])。self.y_data = torch.from_numpy(xy[:, [0]]):标签数据,形状为 [n_samples, 1] (例如 [N, 1])。这种形状对于分类任务的 CrossEntropyLoss 而言,通常需要进一步处理为 [n_samples]。2. 模型架构
NeuralNet是一个简单的两层全连接网络,中间使用LeakyReLU激活函数,输出层直接连接到num_classes,没有显式的softmax,这与nn.CrossEntropyLoss的内部实现是兼容的。3. 训练循环中的关键问题
训练循环遵循了PyTorch的标准模式:前向传播、损失计算、逆向传播、优化器更新。然而,其中几个关键的维度处理问题:
问题A:输入数据维度处理错误inputs = torch.flatten(inputs)在训练循环的每次迭代中,都执行了inputs = torch.flatten(inputs)。解析:DataLoader通常会输出形状为[batch_size,input_size]的批次数据。如果 input_size 为 5,那么输入的形状为 [batch_size, 5]。由此执行 torch.flatten(inputs) 将其转换为 [batch_size * 5]。然而,模型中的第一个线性层 self.l1 = nn.Linear(input_size, hide_size) 期望的输入是 [batch_size, input_size]。
这种维度不匹配会导致模型在接收数据时出现问题,或者更认知地,模型会尝试将 [batch_size * 5] 解释为 [batch_size, 5],从而导致失败或模型无法学习。正确的做法是删除这行代码。
问题B:标签数据维度处理 labels = torch.flatten(labels) 在训练循环中,标签也被展平处理。解析: nn.CrossEntropyLoss期望分类任务的标签是形状为 [batch_size] 的1D张量,其中包含类别索引(0到num_classes-1)。由于原始标签 self.y_data 是 [n_samples, 1],经过 DataLoader 批处理后为 [batch_size, 1]。因此可以执行扁平化确实将其转换为 [batch_size]。但是,更语义化且更推荐的做法是使用 labels.squeeze(1)来移除单维度。
问题C:训练步数统计 n_total_steps = len(dataset)在训练循环外,n_total_steps 被设置为 len(dataset),即总样本数。解析:在 print 语句中,step {i 1}/{n_total_steps} 中的 n_total_steps 应该表示批次的总数量,无样本总数。正确的应该是 len(data_loader)。4. 评估循环:精度计算的核心错误
这是导致模型精度“低于随机猜测”的最关键因素。
音刻
AI音视频录制和笔记工具 107 查看详情
错误代码:# ...n_ Correct = 0n_samples = 0for input, labels in test_loader: # ... _,predictions = torch.max(outputs, 1) n_samples = labels.shape[0] n_ Correct = (predictions == labels).sum().item() # 核心错误在!acc = 100 * n_ Correct / n_samplesprint(f'accuracy = {acc}')登录后复制
问题解析:在for循环中,每次迭代处理一个批次时,n_ Correct = (predictions == labels).sum().item() 这行代码都会重新赋值n_ Correct。这意味着n_ Correct变量在当前批次处理后都会被当前批次的正确预测数覆盖,而不是立即将所有批次的正确预测数累加起来。最终,当循环结束时,n_ Correct 将只包含最后一批训练的正确预测数量。因此,计算出的 acc 值将是极低的,完全无法反映模型在整个测试集上的真实性能。解决方案与修改
针对上述诊断出的问题,我们将进行以下修改:修改精度:将评估循环中的 n_ Correct = ... 变为 n_ Correct = ...。输入修改维度: 转移训练并评估循环中对输入的展平操作。 修改标签变量:和评估循环中对标签的 flatten 操作改为 labels.squeeze(1)。修改训练步数统计:将 n_total_steps 的计算方式改为 len(data_loader)。优化数据集类:建议合并SDSS和testSDSS,并使用random_split进行数据集划分。
以下是修改后的关键代码片段:import torchimport torch.nn as nnimport numpy as npfrom torch.utils.data import Dataset, DataLoaderimport torch.optim# 设备配置device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 优先使用GPU# 超参数input_size = 5hidden_size = 10num_classes = 3num_epochs = 100batch_size = 10learning_rate = 0.0001#修改后面的Dataset类,支持训练/测试划分类SDSSDataset(Dataset): def __init__(self, filepath='SDSS.csv'): xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32,skiprows=0) self.n_samples = xy.shape[0] self.x_data = torch.from_numpy(xy[:, 1:]) # 特征 self.y_data = torch.from_numpy(xy[:, [0]]) # 标签,形状 [n_samples, 1] def __getitem__(self,index): # 返回特征和标签,标签这里不做挤压,之后DataLoader处理 return self.x_data[index], self.y_data[index] def __len__(self): return self.n_samples# 加载数据集并进行训练/测试集划分full_dataset = SDSSDataset()train_size = int(0.8 * len(full_dataset)) # 80 用于训练test_size = len(full_dataset) - train_size # 20 用于测试train_dataset, test_dataset = torch.utils.data.random_split(完整数据集, [train_size, test_size])data_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True, num_workers=0)test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False, num_workers=0)# 模型定义 (不变)class NeuralNet(nn.Module): def __init__(self, input_size, hidden_size, num_classes):
super(NeuralNet,self).__init__() self.l1 = nn.Linear(input_size,hidden_size) self.relu = nn.LeakyReLU() self.l2 = nn.Linear(hidden_size,num_classes) defforward(self,x): out = self.l1(x) out = self.relu(out) out = self.l2(out) return outmodel = NeuralNet(input_size,out) hidden_size, num_classes).to(device) # 将模型迁移到设备# 损失函数和优化器 (不变)criterion = nn.CrossEntropyLoss()optimizer = torch.optim.Adam(model.parameters(), lr登录后复制
以上就是PyTorch模型训练不收敛精度计算错误排查与修改的详细,更多请关注乐哥常识网其他相关文章!相关标签: csv ai 深度学习 pytorch csv文件 red 架构 print for 循环 len 算法 pytorch 大家都在高效看:Python中将JSON格式的列表字典数据导出为CSV文件如何使用python爬取线上商品信息? Python数据处理:将JSON字典列表写入高效CSV文件 python以字典方式写入csv文件实现步骤 Python csv模块读取列表:幕后机制与实践指南
