批量加载器下MSE计算方法及训练MSE的模型模式疑问
回归任务中MSE计算与过拟合判断的模型模式问题
一、MSE的正确计算方式
你的代码中使用了nn.MSELoss(),它默认参数reduction='mean',即每个batch返回的loss.item()是该batch内所有样本的平均MSE。此时计算全局MSE的两种思路及正确性如下:
基于全量样本直接计算(最推荐)
你已经收集了所有训练集的train_preds和train_targets,直接用这两组数据计算全局MSE是最准确的,完全避免batch权重偏差问题:from sklearn.metrics import mean_squared_error train_mse = mean_squared_error(train_targets, train_preds) val_mse = mean_squared_error(val_targets, val_preds)这种方式直接反映所有样本的预测误差均值,是回归任务中标准的评估指标。
除以数据集长度 vs 加载器长度
- 除以
len(train_dataset):如果直接用累加的batch平均loss除以总样本数,结果不准确——因为每个batch的样本数可能不等(比如最后一个batch),每个batch的平均loss应该按样本数加权后再除以总样本数,而非直接累加后除以总样本数。 - 除以
len(train_loader):得到的是所有batch平均MSE的均值,相当于给每个batch平等加权,不管batch样本数多少。这种数值和真实全局MSE存在偏差(尤其是最后一个batch样本数较少时),仅适合训练过程中的快速监控,不能作为最终评估指标。
- 除以
总结:优先用全量预测/真实值直接计算MSE;若必须用batch loss累加,需按每个batch的样本数加权求和后再除以总样本数。
二、计算train_mse判断过拟合时的模型模式
必须将模型切换到**eval()模式**,原因如下:
- 训练模式(
train())下,Dropout、BatchNorm等层处于训练状态:Dropout会随机失活神经元,BatchNorm会使用当前batch的均值/方差,这些都会让训练时的预测结果带有随机性,无法反映模型对训练集的真实拟合能力。 - 评估模式(
eval())下,Dropout关闭,BatchNorm使用训练阶段累计的全局均值/方差,此时得到的train_mse是模型对训练集的真实拟合效果,对比val_mse才能准确判断过拟合:如果train_mse极低但val_mse显著升高,说明模型过拟合;如果两者都偏高,说明模型欠拟合。
对应你的代码,当前收集的train_preds是train()模式下的输出,带有随机性,用来判断过拟合会有误差。更严谨的做法是在eval()模式下重新计算训练集的预测:
# 在计算train_mse前切换到eval模式 model.eval() with torch.no_grad(): train_preds_eval, train_targets_eval = [], [] for features, targets in train_loader: features, targets = features.to(device), targets.to(device) preds = model(features) train_preds_eval.extend(preds.detach().cpu().numpy()) train_targets_eval.extend(targets.cpu().numpy()) train_mse = mean_squared_error(train_targets_eval, train_preds_eval)
内容的提问来源于stack exchange,提问作者mansi
相关产品推荐
相关产品推荐

