You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中神经网络权重不更新问题排查求助

PyTorch模型无学习效果的问题排查与修复

本人是PyTorch新手,搭建了一个简单神经网络,但运行代码时模型无任何学习效果。相同结构的网络在TensorFlow中准确率能快速收敛到1,而PyTorch版本的准确率始终维持在约8%(接近随机猜测水平)。以下是问题代码、特征向量、真实标签及预测结果,经排查发现多个关键错误:


1. 输入特征未做归一化

观察输入特征:

tensor([0, 3739, 4095, 2243, 3077,  518, 2208,  939], dtype=torch.int32)

特征值范围从0到4095,数值跨度极大,会导致网络权重更新不稳定,梯度要么消失要么爆炸。TensorFlow版本大概率做了归一化处理,而PyTorch代码中仅将输入转成float32,未做任何缩放。

修正方法:在HSVData的_load_data中对输入特征做归一化,比如除以最大值4095转成0-1范围:

x = torch.from_numpy(x).to(torch.float32)
x = x / 4095.0  # 归一化到0-1区间

2. 损失函数与输出层不匹配

当前模型输出层用了Softmax(dim=1),却搭配BCELoss(二分类交叉熵)。BCELoss适用于二分类场景,且需要输出是Sigmoid激活后的概率;多分类场景应该使用CrossEntropyLoss,该损失函数内部已经包含Softmax计算,因此输出层不需要额外加Softmax。

修正方法:

  • 移除模型中的Softmax层:
self.nn_stack = nn.Sequential(
    nn.Linear(input_dim, 64),
    nn.ReLU(),
    nn.Linear(64, 64),
    nn.ReLU(),
    nn.Linear(64, 64),
    nn.ReLU(),
    nn.Linear(64, 64),
    nn.ReLU(),
    nn.Linear(64, output_dim)  # 移除Softmax
)
  • 替换损失函数为CrossEntropyLoss:
loss_fn = nn.CrossEntropyLoss()

3. 标签处理错误

当前代码将标签转成one-hot编码,但CrossEntropyLoss不需要one-hot标签,直接传入原始类别索引(整数类型)即可。同时_to_categorical返回的是numpy数组,转成tensor后类型不匹配,还会增加计算开销。

修正方法:

  • 删除_to_categorical方法,标签直接保留原始整数类型:
def _load_data(self, path_to_data):
    with np.load(path_to_data) as f:
        fx, fy = f.files
        x, y = f[fx], f[fy]
        x = torch.from_numpy(x).to(torch.float32)
        x = x / 4095.0  # 归一化
        y = torch.from_numpy(y).to(torch.long)  # 转成long类型的类别索引
        return x, y

4. 验证函数中的计算错误

  • correct初始化为(0, 0)元组,后续累加会报错,应该初始化为整数0。
  • 当前仅比较单个样本的argmax结果,若后续调整batch_size>1会失效,需批量比较所有样本。

修正方法:

def val(model, dataloader):
    model.eval()
    correct = 0  # 修正初始值
    total = 0
    with torch.no_grad():
        for x, y in dataloader:
            pred = model(x)
            # 批量获取预测类别和真实类别,计算正确数
            pred_classes = pred.argmax(dim=1)
            correct += (pred_classes == y).sum().item()
            total += y.size(0)
        print(f"Accuracy: {100 * (correct / total):.2f}%")

5. 训练效率优化

  • batch_size=1会导致训练效率极低,梯度噪声大,建议调整为32或64;验证集不需要shuffle。
train_dl = DataLoader(train_data, batch_size=32, shuffle=True)
val_dl = DataLoader(val_data, batch_size=32, shuffle=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:42:36