多分类训练模型绘图失败求助:ValueError维度不匹配问题
问题分析与解决方案
错误原因
你遇到的ValueError: x and y must have same first dimension, but have shapes (100,) and (938,),本质是绘制损失曲线时x轴和y轴数据长度不匹配:
- 你的训练循环设置了
no_epochs = 100,train_loss列表最终会存入100个元素(每个epoch的平均训练损失)。 - 训练集MNIST有60000条数据,
batch_size=64,所以训练迭代次数是60000//64=937,即itr+1=938。如果你的绘图代码错误地用了训练迭代次数(938个)作为x轴,和仅100个元素的train_loss配对,就会触发维度不匹配错误。
另外你的代码还缺失验证循环,val_loss始终是空列表,后续绘图也会出问题。
修复步骤
1. 补全完整的训练+验证循环
先把训练和验证逻辑补全,确保train_loss和val_loss都能正确收集每个epoch的损失:
no_epochs = 100 train_loss = list() val_loss = list() best_val_loss = float('inf') # 初始化为无穷大,更适合后续判断最优模型 for epoch in range(no_epochs): total_train_loss = 0 total_val_loss = 0 # 训练阶段 model.train() for itr, (image, label) in enumerate(train_dataloader): if torch.cuda.is_available(): image = image.cuda() label = label.cuda() optimizer.zero_grad() pred = model(image) loss = criterion(pred, label) total_train_loss += loss.item() loss.backward() optimizer.step() total_train_loss = total_train_loss / (itr + 1) train_loss.append(total_train_loss) # 验证阶段(之前代码缺失这部分) model.eval() with torch.no_grad(): # 验证阶段不需要计算梯度,节省资源 for itr, (image, label) in enumerate(val_dataloader): if torch.cuda.is_available(): image = image.cuda() label = label.cuda() pred = model(image) loss = criterion(pred, label) total_val_loss += loss.item() total_val_loss = total_val_loss / (itr + 1) val_loss.append(total_val_loss) print(f"Epoch {epoch+1}/{no_epochs}, Train Loss: {total_train_loss:.4f}, Val Loss: {total_val_loss:.4f}")
2. 正确绘制损失曲线
用epoch数作为x轴(长度100),和train_loss、val_loss(长度均为100)配对,保证维度一致:
import matplotlib.pyplot as plt plt.figure(figsize=(10, 6)) plt.plot(range(1, no_epochs+1), train_loss, label='训练损失') plt.plot(range(1, no_epochs+1), val_loss, label='验证损失') plt.xlabel('Epoch(训练轮次)') plt.ylabel('Loss(损失值)') plt.title('训练与验证损失变化曲线') plt.legend() plt.show()
3. 额外优化建议
- 你的Adam优化器
lr=0.1过大,MNIST任务建议用lr=0.001,否则模型训练会不稳定,损失可能震荡甚至不收敛。 - 初始
best_val_loss=1不合理,改为float('inf')能确保第一次验证损失一定会触发最优模型的判断逻辑。
内容的提问来源于stack exchange,提问作者Onalenna Mpape
相关产品推荐
相关产品推荐

