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

如何在PyTorch中针对Fashion-MNIST正确使用MSELoss并获取网络前两层的均方误差梯度?

解决Fashion-MNIST中间层MSELoss报错与梯度查看问题

首先,咱们先拆解你遇到的报错原因,再一步步调整代码满足你的需求。

错误根源:张量尺寸不匹配

你看到的RuntimeError: The size of tensor a (128) must match the size of tensor b (96),本质是这两个问题:

  1. model[0].forward(images)输出的是整个批次的特征,形状是(batch_size, 128)(每个样本对应128维第一层输出),但你取了output[0],只拿到第一个样本的128维向量。
  2. 你的labels是当前批次的类别标签,形状是(batch_size,),而Fashion-MNIST训练集最后一个批次的样本数是96(60000 ÷ 128 = 468余96),所以96长度的标签和128长度的单样本特征,维度完全不匹配,导致MSELoss计算失败。

另外,你的需求是查看第一层与第二层之间的输出梯度,但直接用类别标签和128维中间特征计算MSE是不合理的——类别标签是0-9的离散值,和中间层的连续特征语义、维度都不匹配,我们需要调整目标张量的形状和含义。

修改方案:针对中间层计算MSE并查看梯度

假设你的需求是:计算**第一层Linear(784,128)的输出(也就是第二层ReLU的输入)**与目标张量的MSE,然后查看该中间层输出的梯度。以下是调整后的完整训练循环代码:

for e in range(epochs):
    running_loss = 0
    for images, labels in trainloader:
        # Flatten Fashion-MNIST images into a 784 long vector
        images = images.to(device)
        labels = labels.to(device)
        images = images.view(images.shape[0], -1)
        
        optimizer.zero_grad()
        # 获取第一层的输出:形状为(batch_size, 128)
        first_layer_output = model[0](images)
        # 构造和第一层输出形状完全匹配的目标张量,这里用全零张量做示例
        # 你也可以换成其他自定义目标,比如随机初始化的张量
        target = torch.zeros_like(first_layer_output).to(device)
        
        # 计算MSE损失:输入和目标形状完全一致,不会报错
        loss = criterion(first_layer_output, target)
        loss.backward()
        # 查看第一层输出的梯度(可选,按需打印)
        # print("第一层输出的梯度形状:", first_layer_output.grad.shape)
        
        optimizer.step()
        running_loss += loss.item()
    else:
        print(f"Epoch {e+1} 训练损失: {running_loss/len(trainloader):.3f}")
        # 保留原有的验证逻辑,但注意验证时要跑完整模型
        test_loss = 0
        accuracy = 0
        
        with torch.no_grad():
            model.eval()
            for images, labels in testloader:
                images = images.to(device)
                labels = labels.to(device)
                images = images.view(images.shape[0], -1)
                # 验证时跑完整模型得到分类输出
                ps = model(images)
                # 分类任务用NLLLoss更合理(配合模型最后的LogSoftmax)
                test_loss += F.nll_loss(ps, labels).item()
                
                top_p, top_class = ps.topk(1, dim=1)
                equals = top_class == labels.view(*top_class.shape)
                accuracy += torch.mean(equals.type(torch.FloatTensor)).item()
        
        model.train()
        print("Epoch: {}/{}..".format(e+1, epochs),
              "Training loss: {:.3f}..".format(running_loss/len(trainloader)),
              "Test loss: {:.3f}..".format(test_loss/len(testloader)),
              "Test Accuracy: {:.3f}".format(accuracy/len(testloader)))

额外说明

  1. 梯度查看:在loss.backward()之后,你可以通过first_layer_output.grad直接访问第一层输出的梯度张量,查看其形状和数值。
  2. 如果是分类任务想用MSELoss:如果你其实是想做分类但误用了中间层,那需要把类别标签转换成one-hot编码(形状(batch_size,10)),和模型最后一层的10维输出匹配,再计算MSE。
  3. 损失选择:Fashion-MNIST是分类任务,优先用NLLLoss(配合LogSoftmax)或CrossEntropyLoss,MSELoss更适合回归任务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:07:41