
该教程解析PyTorch训练循环中损失统计的常见错误,指出running_loss / 10000应为running_loss / 100,并给出修正后的完整实现与关键注意事项。
该教程解析pytorch训练循环中损失统计的常见错误,指出`running_loss / 10000`应为`running_loss / 100`,并给出修正后的完整实现与关键注意事项。
在PyTorch模型训练中,实时监控损失(loss)是调试和评估训练过程的关键环节。但初学者常因对统计逻辑理解偏差,导致打印出的损失值严重失真——正如问题中所示:代码每处理100个mini-batch就执行一次打印,却将累计损失除以10000,而非正确的100。
问题根源分析:
- running_loss += loss.item() 在每个batch后累加当前batch的标量损失;
- if i % 100 == 99 表示每满100个batch(即索引 i = 99, 199, 299...)触发一次统计;
- 此时 running_loss 包含恰好100个batch的损失之和,因此平均损失应为 running_loss / 100;
- 原代码中除以 10000 会导致输出值被人为缩小100倍(例如真实均值为2.1,显示为0.021),严重误导训练判断。
✅ 修正后的训练函数片段如下:
def train(net, trainloader, epochs, use_gpu=True):
net.train()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
device = torch.device("cuda" if use_gpu and torch.cuda.is_available() else "cpu")
print(f"Training {epochs} epoch(s) w/ {len(trainloader)} batches each")
for epoch in range(epochs):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
images, labels = data[0].to(device), data[1].to(device)
optimizer.zero_grad()
outputs = net(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 100 == 99: # 每100个batch打印一次平均损失
avg_loss = running_loss / 100 # ✅ 正确:除以实际累加的batch数
print(f"[{epoch + 1}, {i + 1}] loss: {avg_loss:.3f}")
running_loss = 0.0 # 重置,为下一组100个batch做准备
⚠️ 重要注意事项:
- 避免整除陷阱:确保使用浮点除法(如 / 100),而非整数除法(// 100),否则可能截断小数;
- 边界一致性:若trainloader总batch数不能被100整除,最后不足100个batch的损失将被丢弃——如需完整统计,可在循环结束后补充 if running_loss != 0: print(...);
- 梯度清零位置:optimizer.zero_grad() 必须在每次前向传播前调用,否则梯度会跨batch累积,引发训练异常;
- 设备同步:当使用GPU时,loss.item() 会自动将标量从GPU内存拷贝到CPU,无需额外.cpu()操作。
掌握这一基础统计逻辑,不仅能准确解读训练日志,更是构建可靠训练管道的第一步。务必养成「累加数量 = 除数」的验证习惯,让每一次print都真正反映模型的学习状态。











