PyTorch线性回归训练损失统计方式及绘图合理性咨询
两种记录方式都是合理的,适用场景不同,没有绝对的对错:
1. 逐batch记录损失的特点
- 优点:不需要额外的计算开销,能完整反映训练过程的细节变化,你可以从波动中快速判断训练是否异常——比如损失突然跳涨大概率是学习率设置过高、梯度爆炸,损失长时间不动可能是梯度消失或者学习率太小。
- 缺点:单batch的损失会受数据分布随机性影响有明显波动,如果你想观察整体收敛趋势,直接绘图看起来会比较杂乱,可以对损失序列做滑动平均处理后再绘制,能得到更平滑的趋势曲线。
2. 逐epoch计算全量训练损失的特点
- 优点:得到的损失值是整个训练集的统计结果,没有单batch的噪声干扰,曲线平滑,很容易观察整体收敛情况,也方便和同维度的验证集损失做对齐对比(通常验证集损失都是按epoch计算的)。
- 缺点:需要额外遍历一次全量训练集,当训练数据量很大时会增加训练耗时,如果你直接把全量训练数据一次性输入模型推理,显存不够的情况下还会触发OOM报错。
你的调整方案的优化建议
你当前写的新增代码有两个可优化的点:
- 不要把batch级损失和epoch级损失存在同一个
training_loss_list里,两种数据的维度含义不同,混在一起绘图会完全看不出趋势,建议分开两个列表存储,按需使用。 - 计算全量训练损失时,不要一次性输入所有训练数据,也不要忘记关闭梯度计算节省显存,正确的写法参考:
# 新增epoch损失存储列表 epoch_training_loss_list = [] for epoch in range(MAX_EPOCH): # 原有batch训练逻辑不变 for i, sampled_batch in enumerate(loader_train): # 原有训练代码不变 pass # 每个epoch结束后计算全量训练损失 model.eval() total_loss = 0 total_sample = 0 with torch.no_grad(): # 关闭梯度计算,大幅节省显存 for sampled_batch in loader_train: X_train = sampled_batch["X"].to(device).float() y_emb_train = sampled_batch["y_emb"].to(device).float() outputs = model(X_train) loss = criterion(outputs, y_emb_train) total_loss += loss.item() * len(X_train) total_sample += len(X_train) avg_epoch_loss = total_loss / total_sample epoch_training_loss_list.append(avg_epoch_loss) model.train()
选择建议
如果只是训练过程中简单监控训练是否正常,用逐batch的损失就足够;如果需要做严谨的实验记录、分析收敛性,建议同时记录逐epoch的平均训练损失,以及对应的验证集损失,方便后续对比分析。
内容的提问来源于stack exchange,提问作者Kadaj13
相关产品推荐
相关产品推荐

