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
相关产品推荐
相关产品推荐

