(二十三)过拟合与验证集选择
训练损失衡量模型对参与更新的样本拟合得怎样。把已见样本拟合得更紧,也可能把噪声一起记住,需要用未参与更新的数据继续观察。
# 项目文件:demos/overfit_curve.py
import torch
x = torch.linspace(-1, 1, 9, dtype=torch.float64)
y = x.square() + torch.tensor([0.2, -0.2, 0.15, -0.2, 0.1, 0.2, -0.15, 0.2, -0.2])
val_x = torch.linspace(-0.95, 0.95, 80, dtype=torch.float64)
for degree in [2, 8]:
design = torch.stack([x**power for power in range(degree + 1)], dim=1)
weights = torch.linalg.lstsq(design, y).solution
train_error = ((design @ weights - y) ** 2).mean()
val_design = torch.stack([val_x**power for power in range(degree + 1)], dim=1)
val_error = ((val_design @ weights - val_x.square()) ** 2).mean()
# 同一组训练点拟合得更紧,不代表未参加拟合的点误差更小。
print(
"次数",
degree,
"训练误差",
round(train_error.item(), 6),
"验证误差",
round(val_error.item(), 6),
)这份演示在九个 的训练点上加入固定扰动,分别拟合二次和八次多项式;另取八十个点检查原来的平方关系。八次多项式可以几乎经过所有带噪训练点,但点与点之间会弯折,验证误差反而更大。
完整项目每轮只比较验证损失,改善时复制一份独立权重,记住对应轮数;训练最后一轮未必就是选中的一轮。测试集在整个选择流程之后单独读取。
可以通过增加合适样本、减小模型、加入正则化或在验证效果不再改善时停止,继续比较同一任务。第一步仍是核对划分、标签和预处理,再根据训练与验证曲线判断问题出在哪一段。