PyTorch二分类模型训练时损失与准确率恒定问题解决
问题分析与解决方案
你的模型损失和准确率恒定,核心原因是损失函数的输入顺序完全错误,导致模型无法进行有效学习,同时代码还有其他几个细节问题,逐一修复如下:
1. 修正损失函数的输入顺序
nn.BCEWithLogitsLoss()的参数顺序为input, target,即模型输出在前,目标标签在后。你的代码写反了:
# 错误写法 loss=lossfn(y,yHat) # 正确写法 loss=lossfn(yHat, y)
这是模型完全不更新的核心原因——反向传播的梯度方向完全错误,参数无法向正确方向优化,所以损失一直维持在随机猜测的0.693(对应sigmoid输出0.5时的损失)。
2. 移除重复的损失记录
代码中重复执行了batchLoss.append(loss.item()),会让每个batch的损失被记录两次,导致平均损失计算有误,删除其中一行即可:
batchLoss.append(loss.item()) predictions=yHat>0 # 删掉下面这一行重复的损失添加 # batchLoss.append(loss.item())
3. 正确计算测试集准确率
当前代码只取了测试集的第一个batch计算准确率,无法反映模型在整个测试集上的表现,应该遍历整个测试集:
# 错误写法 model.eval() X,y=next(iter(test_loader)) with torch.no_grad(): yHat=model(X) test_acc.append( 100*torch.mean(((yHat>0) == y).float())) # 正确写法 model.eval() test_batch_acc = [] with torch.no_grad(): for X, y in test_loader: yHat = model(X) acc = 100 * torch.mean(((yHat > 0) == y.float()).float()).item() test_batch_acc.append(acc) test_acc.append(np.mean(test_batch_acc))
4. 确保数据类型匹配
检查y的数据类型是否和模型输出yHat一致(比如都是torch.float32),如果y是整数类型,比较时会出现隐性错误,可显式转换:
acc = 100 * torch.mean(((yHat > 0) == y.float()).float())
5. 验证模型结构
确认你的Model类最后一层输出维度正确:二分类任务应该输出单个数值(对应每个样本的logit),比如最后一层应为nn.Linear(in_features, 1),而非多个神经元。
修复后的完整训练循环示例
model=Model() lossfn=nn.BCEWithLogitsLoss() optimizer=torch.optim.Adam(model.parameters(),lr=0.01) epochs=10 train_acc=[] test_acc=[] losses=torch.zeros(epochs) for i in range(epochs): model.train() batchAcc=[] batchLoss=[] for X,y in train_loader: yHat=model(X) # 修正损失函数输入顺序 loss=lossfn(yHat, y) optimizer.zero_grad() loss.backward() optimizer.step() batchLoss.append(loss.item()) predictions=yHat>0 # 确保y是float类型 batchAcc.append(100*torch.mean(((yHat>0) == y.float()).float()).item()) losses[i]=np.mean(batchLoss) train_acc.append(np.mean(batchAcc)) # 修正测试集准确率计算 model.eval() test_batch_acc = [] with torch.no_grad(): for X, y in test_loader: yHat=model(X) acc = 100*torch.mean(((yHat>0) == y.float()).float()).item() test_batch_acc.append(acc) test_acc.append(np.mean(test_batch_acc)) print(f'Epoch:{i+1} loss:{losses[i]:.6f} train accuracy:{train_acc[-1]:.2f} test accuracy:{test_acc[-1]:.2f}')
内容的提问来源于stack exchange,提问作者Kumar
相关产品推荐
相关产品推荐

