第 01 课 · 代码工程版 · 可直接复现

单层服装分类网络:环境、管线与排错

面向动手复现:给定相同种子与超参数,任何机器应得到约 80% 验证准确率、7850 参数、5 epoch 收敛。本页给出最小可运行管线、形状断言、日志解读与 6 类常见失败。

0 复现目标1 环境2 数据管线3 模型定义4 训练5 评估排错6 扩展实验7 上线清单

0 · 复现目标与口径

成功标准
summary Total 7,850;5 epoch 后 val_accuracy ≈ 0.82–0.84,val_loss 0.50→0.45;训练 accuracy 0.79→0.85。
冻结口径
7850 / ~80% / 扩展 50890→~87%。种子固定时全场可比;不固定则期望相近、方差稍大。
三版分工
本页只讲“跑起来与排错”;概念推导见 深度学习讲解版;直觉故事见 文科叙事版;公式细节见数学全解。

1 · 环境与版本锁定

# 建议:Python 3.10+;首次缺包现场安装一次即可
try:
    import tensorflow as tf
except ModuleNotFoundError:
    # %pip install tensorflow
    import tensorflow as tf
tf.random.set_seed(42)  # 锁定初始化与 shuffle,保证可比
print('TF:', tf.__version__)
print('GPU:', tf.config.list_physical_devices('GPU') or '无(CPU 可跑)')
预期:TF 2.x 正常输出版本号;无 GPU 不阻塞,CPU 约 1–2 分钟跑完 5 epoch。若安装后仍报 GPU 相关警告,可忽略(自动回退 CPU)。

2 · 数据管线:形状与值域先行

fashion_mnist = tf.keras.datasets.fashion_mnist
(train_images, train_labels), (valid_images, valid_labels) = fashion_mnist.load_data()
# 关键修复:原始 uint8 0–255,必须重标度,否则损失初值过大、梯度爆炸
train_images = train_images / 255.0
valid_images = valid_images / 255.0
# 形状断言:跑通前先 assert,比事后查 log 快
assert train_images.shape == (60000, 28, 28)
assert valid_images.shape == (10000, 28, 28)
assert train_images.min() >= 0 and train_images.max() <= 1.0
检查点正确值错值含义
shape(60000,28,28) / (10000,28,28)下载截断或版本错
max()≤1.0忘记 /255,损失初值会到十几
train_labels.max()9(类别数 10)用此推导 Dense 输出维度,勿硬编码
红线:验证集不得参与任何拟合(包括归一化统计、调参窥视后回灌)。本课归一化系数为常数 255,无泄漏风险;若改用均值方差,必须只在训练集上估计。

3 · 模型定义:三层与 7850 的来源

number_of_classes = int(train_labels.max() + 1)  # 10,由数据推导
model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(28, 28)),  # 新版推荐:Input 独立声明
    tf.keras.layers.Flatten(),  # (b,28,28)→(b,784),0 参数
    tf.keras.layers.Dense(number_of_classes)  # W:(784,10)+b:(10,)=7850
])
model.summary()  # 验收:Dense 7,850 / Total 7,850 (30.66 KB)

计算:784×10+10=7850。Flatten 只重塑;旧写法 Flatten(input_shape=...) 在新版 Keras 会告警,统一用 Input。

验收:flatten: (None,784) 0,dense: (None,10) 7850。任一数字不对即结构错,无需继续训练。

4 · 训练:编译与 fit 日志

model.compile(optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=5, verbose=2,
    validation_data=(valid_images, valid_labels))
参数本课取值改动后果
from_logitsTrue(输出为 logits)False 会对概率再 softmax,损失错误
optimizeradam(默认 lr≈1e-3)SGD 亦可收敛但更慢,需调 lr
epochs51 则欠拟合约 75%;20 则验证损失大概率回升
validation_data验证集整体仅评估,不产生梯度

正常日志形如:Epoch 1/5 - accuracy: 0.79 - loss: 0.59 - val_accuracy: 0.82 - val_loss: 0.50 → Epoch 5/5 - accuracy: 0.85 - loss: 0.41 - val_accuracy: 0.84 - val_loss: 0.45。若首 epoch loss > 5,优先检查是否忘记 /255。

5 · 评估与排错:曲线、预测形状、错例

# 曲线:两线对照,单看一条无意义
plt.plot(history.history['loss'], label='train'); plt.plot(history.history['val_loss'], label='val')
plt.plot(history.history['accuracy'], label='train acc'); plt.plot(history.history['val_accuracy'], label='val acc')
# 预测:必须带 batch 维;输出 (n,10),argmax 即类别
logits = model.predict(train_images[0:10])  # (10,10)
preds = logits.argmax(axis=1)
# 错例挖掘:前 500 验证样本找 4 个错的
import numpy as np
p_all = model.predict(valid_images[:500], verbose=0).argmax(axis=1)
wrong = np.where(p_all != valid_labels[:500])[0][:4]
现象定位修复
predict 报形状错喂了 (28,28)改 [i:i+1] 或 expand_dims → (1,28,28)
训练 loss 降、验证 loss 升过拟合本课 5 epoch 极少见;若出现检查是否重复 fit 累加
loss 降、acc 不动校准改善、边界未动检查标签、阈值,而非一味加 epoch
6↔0、4↔3 集中错线性容量不足(预期内)非 bug;见下一节加层验证

6 · 扩展实验:64 单元隐藏层

# 独立模型,不污染原 model;对比 7850 vs 50890
model2 = tf.keras.Sequential([tf.keras.layers.Input(shape=(28,28)),
    tf.keras.layers.Flatten(), tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(number_of_classes)])
model2.compile(optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy'])
model2.fit(train_images, train_labels, epochs=5, verbose=2,
    validation_data=(valid_images, valid_labels))
# 参数 (784*64+64)+(64*10+10)=50890;val_accuracy 约 0.86–0.87

变量:epochs=1 观察欠拟合幅度;Dense(64) 改 128 观察收益递减。每次只改一处并记录种子,否则不可比。

7 · 上线前清单

summary 为 7850;max()≤1.0;number_of_classes==10 由数据推导而非硬编码。
Input 独立声明;from_logits=True 与无激活输出配对;验证集未参与拟合。
5 epoch 日志落在 0.79→0.85 / 0.82→0.84 区间;首 epoch loss 若 >5 立即停查归一化。
predict 均带 batch 维;错例集中于易混类属预期;扩展实验单独建模。
需概念推导时转 深度学习讲解版;需直觉时转 文科叙事版;公式细节见 数学全解。

输入课堂口令

本页为课后材料,需课堂口令进入