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

PyTorch类内训练函数报错RuntimeError,求排查解决思路

问题排查与解决:PyTorch训练时出现RuntimeError: Boolean value of Tensor with more than one value is ambiguous

错误核心原因

问题出在**CrossEntropyLoss的调用方式错误**:
PyTorch中的nn.CrossEntropyLoss是一个损失类,必须先实例化再传入预测值和标签计算损失。你当前代码中loss = nn.CrossEntropyLoss(pred, y)的写法,会把pred和y当成损失类初始化的配置参数(而非计算损失的输入),导致内部逻辑处理时出现多元素张量的布尔值判断歧义,最终抛出该错误。

两种正确解决方式

方式1:先实例化损失类,再计算损失

# 先实例化损失函数
criterion = nn.CrossEntropyLoss()
# 传入预测值和标签计算损失
loss = criterion(pred, y)

方式2:使用函数式API(需导入torch.nn.functional)

import torch.nn.functional as F
# 直接调用函数计算损失
loss = F.cross_entropy(pred, y)

完整修正后的代码

同时补充两个关键细节:将模型移动到指定设备、优化器初始化放在批量循环外避免状态丢失:

import numpy as np
import os
import sys
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

os.chdir("/Users/zhangzhongheng/Downloads/")
os.getcwd()

# 下载训练数据集
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)

# 下载测试数据集
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)

batch_size = 64

# 创建数据加载器
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

# 验证数据形状
for X, y in test_dataloader:
    print(f"Shape of X [N, C, H, W]: {X.shape}")
    print(f"Shape of y: {y.shape} {y.dtype}")
    break

# 获取训练设备
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")

# 定义模型
class NeuralNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10)
        )
    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits
    def model_train(self,dataloader):
        self.train()
        size = len(dataloader.dataset)
        # 实例化损失函数与优化器
        criterion = nn.CrossEntropyLoss()
        optimizer = torch.optim.SGD(self.parameters(), lr=1e-3)
        for batch, (X, y) in enumerate(dataloader):
            X, y = X.to(device), y.to(device)
            # 计算预测结果与损失
            pred = self.forward(X)
            loss = criterion(pred, y)
            # 反向传播与参数更新
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            # 打印训练日志
            if batch % 100 == 0:
                loss_val, current = loss.item(), batch * len(X)
                print(f"loss: {loss_val:>7f}  [{current:>5d}/{size:>5d}]")

# 初始化模型并移动到指定设备
Model = NeuralNetwork().to(device)
epochs = 5
# 开始训练循环
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    Model.model_train(train_dataloader)
print("Done!")

额外优化提示

  • 优化器建议在类初始化时或全局训练循环外创建,避免每次调用model_train都重新初始化导致优化状态丢失。
  • 模型实例化后必须用.to(device)移动到对应设备,确保模型参数与输入数据在同一设备上,避免跨设备计算错误。

内容的提问来源于stack exchange,提问作者Z. Zhang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:10:28