阶段:S2-数据处理 | 预计耗时:60-75 分钟 | 前置:S2-02 训练验证测试集划分 代码:本篇代码要你自己敲成
model-learn/s2_augmentation.py
学习目标
- 理解数据增强的本质:对同一条数据做保持标签不变的随机变换 = 免费造新数据
- 在 MNIST 500 样本小数据场景实测"旋转增强"能提多少分
- 记住铁律:增强只加在 train 的 transform 里,val/test 只做标准预处理
核心知识
1. 什么变换"保持标签不变"
- 图像:旋转几度、平移几像素、翻转、裁剪、加噪——数字 3 转一点点还是 3
- 文字:同义词替换、回译;表格:加微小噪声
- 反例:上下翻转会把手写 6 变成 9(标签变了!)——增强必须懂数据,不是无脑套
2. 增强为什么能抗过拟合
模型每次看到的是"同一条数据的不同样子",背不下单一版本,只能学规律 → 和 S4 要讲的正则化殊途同归,但更便宜。
3. 本机写法
transforms.Compose([transforms.RandomRotation(10), transforms.ToTensor()])
- 随机变换放在 ToTensor() 之前(它们作用在 PIL 图上)
- torchvision 每次取样本时现场随机——同一张图每个 epoch 长得都不一样
实验任务
任务 1:敲出脚本(30 分钟)
对照组设计(一次只改一个变量,其余全同):
# s2_augmentation.py —— 500 样本上实测旋转增强
import torch, torch.nn as nn
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, Subset
torch.manual_seed(42)
plain = transforms.ToTensor()
aug = transforms.Compose([transforms.RandomRotation(10), transforms.ToTensor()])
train_raw = datasets.MNIST("data", train=True, download=False, transform=plain)
test_ds = datasets.MNIST("data", train=False, download=False, transform=plain)
test_dl = DataLoader(test_ds, batch_size=256)
model = nn.Sequential(nn.Flatten(), nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 10))
def run(train_transform, tag):
torch.manual_seed(42) # 每组实验重置种子,公平对比
global model
model = nn.Sequential(nn.Flatten(), nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 10))
train_ds = datasets.MNIST("data", train=True, download=False, transform=train_transform)
dl = DataLoader(Subset(train_ds, range(500)), batch_size=64, shuffle=True)
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()
for epoch in range(6):
for x, y in dl:
opt.zero_grad(); loss_fn(model(x), y).backward(); opt.step()
@torch.no_grad()
def acc():
n = ok = 0
for x, y in test_dl:
ok += (model(x).argmax(1) == y).sum().item(); n += len(y)
return ok / n
print(f"{tag}: 测试集准确率 = {acc():.4f}")
run(plain, "无增强(对照)")
run(aug, "旋转±10°增强 ")
任务 2:加大剂量(15 分钟)
增强改成 RandomRotation(30) 再跑——增强是不是越猛越好?写进观察记录表。
任务 3:交叉增强(15 分钟)
再加一组 RandomAffine(degrees=10, translate=(0.1, 0.1))(旋转+平移)。三行对比后回答:小数据场景,增强是最便宜的正则化吗?
验收标准
衔接下一阶段
数据侧四大件(Dataset/Loader/划分/增强)已就位 → 进入 S3-01 nn.Module 解剖:换到模型这一侧。