GAN训练报错ValueError: torch输入与target张量尺寸不匹配
PyTorch GAN训练判别器阶段张量尺寸不匹配报错排查
报错根因
报错本质是计算损失时,判别器输出的预测值张量和传入的标签张量第一维长度不一致:
- 尺寸为
torch.Size([47, 1])的张量是判别器对当前输入批次的预测输出,代表当前批次实际只有47个样本 - 尺寸为
torch.Size([64, 1])的张量是手动创建的分类标签,长度固定为设置的batch size=64,没有跟随当前批次的实际样本数调整
第0个epoch前期运行正常的原因
PyTorch的DataLoader默认参数drop_last=False,加载数据时不会丢弃最后一个不足设定batch size的批次:
- 第0个epoch遍历的前若干个批次都是满的64个样本,判别器输出尺寸为(64,1),和固定长度的标签尺寸匹配,不会触发错误
- 遍历到epoch的最后一个批次时,数据集剩余样本总数不足64,只剩47个,判别器输出尺寸变为(47,1),和固定为64长度的标签尺寸不匹配,在损失计算、反向传播环节触发报错。
修复方案
二选一即可:
方案1:丢弃最后一个不完整批次(改动最小)
初始化训练集DataLoader时添加drop_last=True参数,直接跳过最后一个凑不满64个样本的批次,所有传入模型的批次样本数固定为64,不需要修改损失计算逻辑:
from torch.utils.data import DataLoader train_loader = DataLoader( dataset=custom_dataset, batch_size=64, shuffle=True, # 保留原有其他参数如num_workers等 drop_last=True # 新增该行 )
方案2:动态生成匹配当前批次尺寸的标签(不浪费样本)
不要在训练循环外提前创建固定长度为64的真/假标签,每轮迭代拿到当前批次数据后,先读取当前批次的实际样本数,再生成对应长度的标签:
# 错误写法:提前写死标签长度 # real_label = torch.ones(64, 1).to(device) # fake_label = torch.zeros(64, 1).to(device) for real_imgs, _ in train_loader: # 先获取当前批次实际样本数 bs = real_imgs.shape[0] # 动态生成对应尺寸的标签 real_label = torch.ones(bs, 1).to(device) fake_label = torch.zeros(bs, 1).to(device) # 判别器训练逻辑保持原有写法即可 # 真样本前向 real_imgs = real_imgs.to(device) d_real_pred = discriminator(real_imgs) d_loss_real = bce_loss(d_real_pred, real_label) # 假样本前向 z = torch.randn(bs, latent_dim).to(device) fake_imgs = generator(z) d_fake_pred = discriminator(fake_imgs.detach()) d_loss_fake = bce_loss(d_fake_pred, fake_label) # 反向传播更新 d_loss = d_loss_real + d_loss_fake d_opt.zero_grad() d_loss.backward() d_opt.step() # 生成器训练部分同理,取当前批次实际大小生成对应标签即可
内容的提问来源于stack exchange,提问作者Sterik
相关产品推荐
相关产品推荐

