You need to enable JavaScript to run this app. Pytorch逻辑回归图像分类训练损失为负不收敛,是否参数未更新?
优惠活动
大模型
产品
解决方案
定价
更多

Pytorch逻辑回归图像分类训练损失为负不收敛,是否参数未更新?

训练异常问题排查结果

已定位的代码硬伤

  • 模型结构冗余且不符合逻辑回归定义
    标准逻辑回归的二分类输出逻辑为:线性层输出 → Sigmoid激活输出0-1区间的预测值。当前代码在Sigmoid层后额外添加的ReLU层属于完全冗余的设计:Sigmoid的输出范围本身就在(0,1)区间,ReLU(取正数部分)对这个范围的输入没有任何调整作用,属于无效代码。
  • 模型参数定义写法存在注册失效风险
    模型初始化时先将线性层存入普通Python列表,后续才转成nn.Sequential封装。虽然当前写法最终能被识别为模型子模块,但这种方式存在注册顺序的边界问题,如果在参数封装前就初始化优化器,会导致所有可训练参数无法被优化器捕获,出现参数不更新、训练不收敛的问题。
  • 损失出现负值的核心诱因
    标准nn.BCELoss的合法输入要求为:预测值在(0,1)区间、标签值在[0,1]区间,此时计算出的损失值必然为非负。出现负值损失通常有两类触发原因:
    1. 标签未做二分类归一化,标签值超出[0,1]范围(比如原标签使用1、2映射类别,未转换为0、1格式),代入交叉熵公式后会算出无意义的负损失值
    2. 训练过程参数更新发散,结合偏大的学习率、未归一化的输入像素值,会导致模型参数更新幅度过大,最终损失完全脱离正常范围

修正方案

  • 简化模型结构,删除冗余的ReLU层,替换为直接定义的线性层:
class LogisticRegression(nn.Module):
    def __init__(self):
        super(LogisticRegression, self).__init__()
        # 直接定义线性层为模型直属属性,避免注册失效
        self.linear = nn.Linear(in_features=28*28, out_features=1)
    
    def forward(self, x):
        # 保留标准逻辑回归的Sigmoid输出
        return torch.sigmoid(self.linear(x))
  • 调整训练循环的梯度处理逻辑,将梯度清零操作移到反向传播前,避免复杂计算流图下的梯度累积问题:
# 每个batch的标准流程
optimizer.zero_grad()
y_predicted = LR_model(images)
total_loss = criterion(y_predicted, labels.unsqueeze(1))
total_loss.backward()
optimizer.step()
  • 额外检查两个前置条件:
    • 输入图像的像素值是否缩放到0-1区间,避免过大的输入值导致参数更新发散
    • 标签值是否统一转换为0、1的二分类格式,确保落在BCELoss的合法输入范围内

内容的提问来源于stack exchange,提问作者racycle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.06 04:54:04