如何解决PyTorch训练时报ValueError: too many values to unpack (expected 2)错误?
错误原因
你遇到的报错核心是两个问题叠加导致的:
- 自定义
Col数据集类的__getitem__方法仅返回单张图像张量,而训练代码中尝试将每个batch解包为inputs, targets两个值,返回值数量不匹配触发报错。 - 数据集划分逻辑错误:
torch.utils.data.random_split接收的参数应为Dataset实例,你错误传入了DataLoader实例,且后续调用train函数时额外追加了.dataset属性,导致遍历对象不符合预期。
解决步骤
步骤1:修改自定义Dataset类,补充标签返回逻辑
默认假设你的图片按类别存放在root_dir的子文件夹下(例如./images/cat/xxx.jpg、./images/dog/xxx.jpg),修改Col类代码如下:
class Col(Dataset): def __init__(self, main_dir, transform): self.main_dir = main_dir self.transform = transform # 生成类别到数字ID的映射 self.class_names = sorted([d for d in os.listdir(main_dir) if os.path.isdir(os.path.join(main_dir, d))]) self.class_to_idx = {cls_name: idx for idx, cls_name in enumerate(self.class_names)} all_images = self.all_img(main_dir = main_dir) self.total_imges = natsort.natsorted(all_images) def __len__(self): return len(self.total_imges) def __getitem__(self, idx): img_loc = os.path.join(self.total_imges[idx]) image = Image.open(img_loc).convert("RGB") tensor_image = self.transform(image) # 提取当前图片所属类别,转换为数字标签 cls_name = os.path.basename(os.path.dirname(img_loc)) target = self.class_to_idx[cls_name] # 返回二元组,匹配训练代码的解包逻辑 return tensor_image, target def all_img(self, main_dir): img = [] for path, subdirs, files in os.walk(main_dir): for name in files: img.append(os.path.join(path, name)) return img
如果你的标签存储逻辑和上述按子文件夹分类的方式不同,只需保证__getitem__返回(图像张量, 标签)的二元组即可。
步骤2:修正数据集划分与DataLoader创建逻辑
将原有的数据集划分代码替换为如下内容:
transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.5457, 0.5457, 0.5457], std=[0.2342, 0.2342, 0.2342]) ]) data = Col(main_dir=root_dir, transform=transform) # 先对Dataset做划分,再分别创建训练、验证的DataLoader train_dataset, val_dataset = torch.utils.data.random_split( data, [round(len(data)*0.7), len(data) - round(len(data)*0.7)] ) train_loader = DataLoader(train_dataset, batch_size=130, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=130, shuffle=False)
步骤3:修正train函数调用参数
调用train函数时直接传入创建好的DataLoader对象即可,不需要追加.dataset:
train(model, optimizer, torch.nn.CrossEntropyLoss(), train_loader, val_loader, epochs=100, device=device)
内容的提问来源于stack exchange,提问作者ZealotTV
相关产品推荐
相关产品推荐

