(十五)训练集、验证集与测试集
读一份记录后,不要立即让所有数据都参加参数更新。先按编号分出三组:
| 分组 | 在本项目中的作用 | 回归记录数 | 图形记录数 |
|---|---|---|---|
| 训练集 train | 每批反向求导并更新参数 | 144 | 216 |
| 验证集 val | 每轮观察损失,选择保留哪一轮权重 | 48 | 72 |
| 测试集 test | 模型选择完成后,单独报告最终效果 | 48 | 72 |
# 续写同一文件:training_project/src/readingtorch/data.py
def split_indices(y, task, seed):
# 先划分原始样本,图形按类别分别打乱,维持三组中的类别比例。
generator = torch.Generator().manual_seed(seed)
groups = [torch.arange(len(y))]
if task == "images":
groups = [torch.where(y == label)[0] for label in range(3)]
parts = [[], [], []]
for group in groups:
group = group[torch.randperm(len(group), generator=generator)]
first, second = int(len(group) * 0.6), int(len(group) * 0.8)
for bucket, chunk in zip(
parts, [group[:first], group[first:second], group[second:]]
):
bucket.append(chunk)
return {
name: torch.cat(items) for name, items in zip(["train", "val", "test"], parts)
}
@dataclass
class Bundle:
x: torch.Tensor
y: torch.Tensor
splits: dict
preprocess: dict
source_hash: strtorch.randperm 用给定生成器打乱编号,先取 60%,再取 20%,其余为测试。图形按每个类别分别打乱,每类 120 张分为 72、24、24,之后合并相应编号。三组没有重叠,所有原样本恰好出现一次。
如果把同一原图的裁剪、旋转版本混到三组里,模型可能在测试时遇到训练图的近似副本。实际扩展数据时,先按原始图像或记录来源分组,再在训练组内做增强。同一读者的重复记录、同一时间段的相邻数据,也要先想清希望检验的是哪种新样本,再按读者或时间安排划分。