实战:CIFAR-10 图像分类
本知识点把 kp-016 的训练循环升级为完整视觉项目:在 CIFAR-10(6 万张 32×32 彩色图、10 类)上用小型 ResNet 配齐增强管道、调度器与检查点,CPU 可跑出 88%+,GPU 半小时可达 93%+。
一句话定义
本知识点把 kp-016 的训练循环升级为完整视觉项目:在 CIFAR-10(6 万张 32×32 彩色图、10 类)上用小型 ResNet 配齐增强管道、调度器与检查点,CPU 可跑出 88%+,GPU 半小时可达 93%+。
直观类比
kp-016 是「驾校场地内开直线」,本节是「第一次上路跑全城」:真实数据、真实增强、真实调度,四个轮子(数据/模型/优化/监控)同时转起来。
为什么重要
这是全库第二个、也是体量最完整的动手锚点:模块 03 的所有纪律(双曲线监控、早停、种子)与模块 04 的全部组件(卷积、块、GAP)在此会师。跑通它的能力可直接迁移到任何「图像分类」形态的任务;它还是 kp-027 调试方法论与 kp-032 迁移学习的天然试验田。
前置知识
- kp-016(训练循环骨架)、kp-018/kp-020(CNN 块与残差)、kp-015(增强管道)、kp-011(调度器)。
- 环境:CPU 需约 1~2 小时/50 epoch,GPU(任意 4GB 显存以上)约 25 分钟。
核心概念
- CIFAR-10:10 类 32×32×3 小图,训练 5 万、测试 1 万,视觉入门标准战场。
- 小型 ResNet 变体:BasicBlock 堆叠(如 [2,2,2] 通道 32/64/128)适配小图。
- 完整配方:随机裁剪+翻转增强、SGD+动量+余弦退火、按样本加权指标、最优检查点。
- 基线思维(baseline mindset):先跑最简可复现版本拿基准分,再单变量改进。
- 过拟合信号(视觉版):增强关掉后训练/验证曲线迅速分叉。
原理与机制
相对 kp-016 的四处升级各有明确动机。数据侧:32×32 彩图信息密度高、5 万样本对 CNN 偏少,增强(kp-015)从「可选项」变成「必需品」——关掉增强的对照实验里验证准确率掉 3~5 个点。模型侧:MLP 换小型 ResNet,动机有二:卷积先验匹配图像(kp-017),残差保梯度(kp-020);通道 32→64→128、空间 32→16→8 的金字塔遵循 kp-018 的「加深通道、缩空间」平衡原则。优化侧:视觉任务用 SGD+动量 0.9、初始 lr=0.05~0.1、余弦退火到 0(kp-011 的经典组合),比 Adam 默认参数上限高约 1~2 个点;weight_decay=5e−4 与增强形成「双重正则」(kp-013)。评估侧:按样本加权、保存最优验证模型、最终只对测试集评估一次(kp-015 的单向闸门)。工作流侧遵循基线思维:第 0 步先跑「1 个 ResNet 块 + 无增强」拿 80% 基线,确认管道无 bug;之后每次只改一个变量(+增强、+深度、换调度),每步记录——这正是 kp-028 实验管理的第一次实战。
公式或模型
本节不适用——理由:本节复用 kp-017 尺寸公式、kp-011 调度公式与 kp-013 正则式,项目价值在于组装与观察,不引入新数学。
图示
项目流水线(四升级对照 kp-016):
数据: MNIST灰度管道 ──► 随机裁剪+翻转增强管道(kp-015)
模型: MLP(784-512-10) ──► ResNet变体 [2,2,2]×(32,64,128) + GAP
优化: Adam 1e-3 恒定 ──► SGD 0.1 + momentum 0.9 + 余弦退火 + wd 5e-4
监控: 单 epoch 打印 ──► 双曲线记录 + 最优检查点 + 单变量实验日志实例或案例
关键代码段(完整版约 120 行,此处给出与 kp-016 的差异部分):
# 模型:小型 ResNet(复用 kp-020 的 Block)
net = nn.Sequential(
nn.Conv2d(3, 32, 3, 1, 1, bias=False), nn.BatchNorm2d(32), nn.ReLU(),
Block(32, 32), Block(32, 64, stride=2), # 32×32 → 16×16
Block(64, 64), Block(64, 128, stride=2), # 16×16 → 8×8
Block(128, 128),
nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Linear(128, 10))
# 优化:视觉经典组合
opt = torch.optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)
sched = torch.optim.lr_scheduler.CosineAnnealingLR(opt, T_max=50)
for epoch in range(50):
train_one_epoch(net, train_loader, opt) # kp-016 五件套
acc = evaluate(net, val_loader)
sched.step() # 每个 epoch 退火一步
save_if_best(net, acc)
# 预期:epoch 10 约 88%,50 epoch 收敛 92~94%(GPU)里程碑检查清单:管道冒烟(过拟合 100 张小样本,训练准确率应到 100%,否则有 bug——kp-027 的第一诊断);增强开关对照;lr 扫描(0.01/0.05/0.1);最终测试集一次评估。
常见误区
- 一次性改多个变量再调参:性能变化无法归因,基线思维要求单变量步进。
- 用测试集反复看结果选 epoch:测试集变验证集,泛化估计被污染(kp-015 纪律在项目里的最大失守点)。
- 直接搬 224×224 的 ImageNet 大架构到 32×32:空间分辨率不匹配导致大量无效下采样,从小图变体起步。
- 没跑冒烟测试就开 50 epoch 长训:bug 代价被放大 50 倍,先过拟合 100 张样本再谈长训。
与其他知识点的关系
本节是 kp-016 的进阶版与 kp-015/011/020 的集成现场;跑通后可自然接入 kp-027 的调试进阶与 kp-028 的完整实验记录;预训练 ResNet 微调版(几分钟到 95%+)是 kp-032 的开胃菜;本项目的损失曲线是 kp-030 诸多误区的活教材。
自测题
- 项目开始时为什么先做「过拟合 100 张样本」的冒烟测试?
答案要点:验证管道与模型有足够能力记住小数据集——若做不到必是 bug(标签错乱、增强破坏标签、学习率过小),避免长训浪费。
- 本项目增强、weight_decay、早停分别属于哪类正则?谁是主力?
答案要点:数据增强为治本型主力;wd 为参数惩罚辅助;早停为过程保险(本配置常由余弦退火代替)。
- 为什么选 SGD+余弦退火而非 Adam 默认?
答案要点:视觉 CNN 上精调的 SGD+动量泛化上限更高(kp-010 结论),配合退火在 50 epoch 预算内更优。
延伸阅读
- 李沐《动手学深度学习》7.7 节「残差网络 ResNet」与其 CIFAR 实践章。
- Krizhevsky 2009 技术报告《Learning Multiple Layers of Features from Tiny Images》(数据集出处)。
学习状态
状态保存在浏览器本地,用于首页与路径页的进度统计。