端到端 MNIST CNN 项目
MNIST 项目连接数据、CNN、训练、验证最佳检查点、测试、错误样本和单样本推理。
学习目标
- 合成灰度批次检查完整训练路径
- 为什么不能用测试准确率选择最佳 epoch?
- 说明:合成批次只验证训练流程,不是 MNIST 性能实验,也不能代替数据集评估。
为什么需要这个概念
端到端手写数字项目把灰度图像转为张量,构建十分类网络,在训练集更新、验证集选模型,并在方案锁定后评估独立测试集。
学习前需要掌握
背景与问题
MNIST 适合练习从原始图像到可恢复模型的完整流程。项目目标不仅是跑出一个准确率,还要让数据划分、形状、训练验证和保存恢复彼此一致。
概念定义
端到端手写数字项目把灰度图像转为张量,构建十分类网络,在训练集更新、验证集选模型,并在方案锁定后评估独立测试集。
直观理解
把每篇单独学过的组件接成一条完整链,任何一处契约错误都可能传到最终预测。
核心原理
常见输入为 ,标签为 的 long 索引,模型输出 原始 logits。归一化统计仅从训练部分估计,随机增强只在语义允许时使用,验证保持确定性。
每个训练批执行清梯度、前向、交叉熵、反向和更新;验证使用 eval 与关闭梯度,按样本汇总损失和正确数。最佳权重按验证规则保存,不能拿测试集挑 epoch。
正式项目还应检查混淆数字和错误样本,保存类别表、配置及预处理,加载后复核固定输入。下面代码仅做无需下载的数据与训练路径烟雾检查,真实 MNIST 评估需另行准备官方数据与独立划分。
数学表达
核心公式
端到端手写数字项目把灰度图像转为张量,构建十分类网络,在训练集更新、验证集选模型,并在方案锁定后评估独立测试集。
变量含义
Nbatch sizeD/H特征或隐藏维度
计算步骤
- 1确认输出为 (4,10),标签为 long。
- 2计算交叉熵并完成一次反向更新。
- 3检查损失有限且模型参数收到梯度。
代码对应位置
示例 1合成灰度批次检查完整训练路径的最小验证:使用完整构造输入核对合成灰度批次检查完整训练路径,输出只表示本例计算。
变量解释
| 变量 | 含义 |
|---|---|
N | batch size |
D/H | 特征或隐藏维度 |
完整数值示例
合成灰度批次检查完整训练路径
已知条件
- 四张全零 28×28 灰度图,构造标签为 0、1、2、3
- 网络为卷积、池化、展平与十分类线性头
计算步骤
- 确认输出为 (4,10),标签为 long。
- 计算交叉熵并完成一次反向更新。
- 检查损失有限且模型参数收到梯度。
计算结果
输出 shape 与任务契约匹配,损失有限,所有训练参数都有梯度。
处理前后对比
- 合成批次只验证训练流程,不是 MNIST 性能实验,也不能代替数据集评估。
合成灰度批次检查完整训练路径
全零图像与编号标签并不构成真实识别任务,因此代码不报告所谓 MNIST 准确率。它的用途是验证所有组件可以连通,并防止不完整的 MNISTCNN、loader 或 evaluate 名称让示例无法独立运行。
正式替换为真实数据后,先保留同样的 shape 与 dtype 检查,再加入独立验证、最佳检查点和最终测试。这样才能把结构正确与任务效果分开核对。
计算与实现步骤
- 确认输出为 (4,10),标签为 long。
- 计算交叉熵并完成一次反向更新。
- 检查损失有限且模型参数收到梯度。
代码实现
示例 1
合成灰度批次检查完整训练路径的最小验证
example_01.py用途:使用完整构造输入核对合成灰度批次检查完整训练路径,输出只表示本例计算。
import torch
from torch import nn
torch.manual_seed(7)
model = nn.Sequential(nn.Conv2d(1, 4, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2), nn.Flatten(), nn.Linear(4 * 14 * 14, 10))
x = torch.zeros(4, 1, 28, 28)
target = torch.tensor([0, 1, 2, 3])
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
model.train()
optimizer.zero_grad(set_to_none=True)
logits = model(x)
loss = nn.CrossEntropyLoss()(logits, target)
loss.backward()
optimizer.step()
print("logits:", tuple(logits.shape), "target dtype:", target.dtype)
print("finite loss:", bool(torch.isfinite(loss)))
print("all gradients present:", all(p.grad is not None for p in model.parameters()))代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
使用完整构造输入核对合成灰度批次检查完整训练路径,输出只表示本例计算。
model- 组合预处理和估计器的模型对象。
loss- 当前预测与目标之间的损失值。
Step 1 · 1–16 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import torch
from torch import nn
torch.manual_seed(7)
model = nn.Sequential(nn.Conv2d(1, 4, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2), nn.Flatten(), nn.Linear(4 * 14 * 14, 10))
x = torch.zeros(4, 1, 28, 28)
target = torch.tensor([0, 1, 2, 3])
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
model.train()
optimizer.zero_grad(set_to_none=True)
logits = model(x)
loss = nn.CrossEntropyLoss()(logits, target)
loss.backward()
optimizer.step()
print("logits:", tuple(logits.shape), "target dtype:", target.dtype)
print("finite loss:", bool(torch.isfinite(loss)))
print("all gradients present:", all(p.grad is not None for p in model.parameters()))代码与数学原理
参数更新由当前梯度与学习率共同决定。
平方误差代码对应均方损失。
预期输出或运行结果
logits: (4, 10) target dtype: torch.int64 finite loss: True all gradients present: True
常见错误 · 5 条
- 首批不检查
- 测试参与调参
- 保存最后非最佳
- 训练前 Softmax
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
实际应用
- 练习完整监督学习项目结构
- 真实 MNIST 训练前的流程检查
常见错误
- 首批不检查
- 测试参与调参
- 保存最后非最佳
- 训练前 Softmax
常见问题
为什么不能用测试准确率选择最佳 epoch?
那会让测试集参与模型选择,最终分数不再是独立检验。应使用验证集选轮次,锁定方案后才评估测试集。
这个示例能说明什么边界?
合成批次只验证训练流程,不是 MNIST 性能实验,也不能代替数据集评估。
推荐学习资料
参考库不会生成虚假资源或无效外部链接。