04-Labs与Notebook实操指南
# MIT 6.S191 Labs 与 Notebook 实操指南
目标:看 MIT 6.S191 时,不只停留在视频和 slides,而是能真正跑通 lab 或最小 notebook,并把运行结果转成学习证据。这里不假设你已经是工程熟手,而是按跨专业学习者的方式,把操作拆成可检查步骤。
1. 为什么必须跑代码
深度学习最容易产生“听懂幻觉”。你看视频时可能觉得 forward、loss、gradient 都很顺,但一跑代码就会遇到包版本、路径、数据下载、shape、dtype、GPU/CPU 设备、训练时间等问题。这些问题不是额外麻烦,而是理解深度学习的必要部分。
跑代码的目标不是立刻做出高性能模型,而是确认四件事:
- 输入数据是什么形状。
- 模型输出是什么形状。
- loss 是否能计算。
- 训练若干步后 loss 或指标是否有合理变化。
2. 实操总流程
flowchart TD
A["打开 lab/notebook"] --> B["先不全运行,浏览目录"]
B --> C["确认依赖和数据来源"]
C --> D["运行导入包 cell"]
D --> E["运行数据加载 cell"]
E --> F["打印样本和 shape"]
F --> G["运行模型定义 cell"]
G --> H["只训练少量 step"]
H --> I["记录 loss/metric"]
I --> J["写入 Obsidian 学习证据"]
重要原则:第一次不要直接 Run All。先分段运行,知道每个 cell 在做什么。
3. 环境检查
在 notebook 第一格加上:
import sys
import platform
print("Python:", sys.version)
print("Platform:", platform.platform())
如果用 PyTorch:
import torch
print("Torch:", torch.__version__)
print("CUDA available:", torch.cuda.is_available())
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Device:", device)
如果没有 GPU,不要慌。学习阶段可以先用小 batch、小模型、少量 step 在 CPU 上跑。你的目标是理解流程,不是训练大模型。
4. 数据检查
任何 lab 都先问:
- 数据从哪里来?
- 样本单位是什么?
- 标签是什么?
- train/test split 是否清楚?
- 数据是否需要 normalization、tokenization、resize 或 padding?
最小检查代码:
print(type(X))
print(type(y))
print("X shape:", getattr(X, "shape", None))
print("y shape:", getattr(y, "shape", None))
如果是 DataLoader:
batch = next(iter(train_loader))
print(type(batch))
如果 batch 是 (inputs, labels):
inputs, labels = batch
print(inputs.shape)
print(labels.shape)
print(labels[:10])
5. 模型检查
不要只看模型名字。要问:
- 输入维度是什么?
- 中间 hidden dimension 是多少?
- 输出维度对应什么?
- 最后一层是否和任务匹配?
分类任务常见输出:
logits = model(inputs)
print(logits.shape) # 应该通常是 (batch, num_classes)
语言模型常见输出:
logits = model(input_ids)
print(logits.shape) # 通常是 (batch, seq_len, vocab_size)
生成模型或 diffusion 的输出可能是预测噪声、重建样本或 latent 表示,必须回到课程说明确认。
6. Loss 检查
loss 不是随便选的。不同任务对应不同 loss。
| 任务 | 模型输出 | 标签 | loss |
|---|---|---|---|
| 多分类 | logits (batch, classes) | 类别编号 (batch,) | CrossEntropyLoss |
| 二分类 | logit/probability | 0/1 | BCEWithLogitsLoss |
| 回归 | 连续值 | 连续值 | MSELoss |
| 语言模型 | token logits | next token | cross entropy |
| diffusion | predicted noise | true noise | MSE |
PyTorch 多分类例子:
criterion = torch.nn.CrossEntropyLoss()
logits = torch.randn(8, 5)
labels = torch.randint(0, 5, (8,))
loss = criterion(logits, labels)
print(loss.item())
注意:CrossEntropyLoss 输入应该是 logits,不要手动先 softmax。
7. 小样本过拟合测试
如果你不确定模型是否能训练,可以做小样本过拟合测试:只取很少数据,让模型反复训练,看能否把训练 loss 降下来。如果连小样本都学不会,可能代码、标签、loss 或模型连接有问题。
small_X = X[:16]
small_y = y[:16]
for step in range(100):
logits = model(small_X)
loss = criterion(logits, small_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if step % 20 == 0:
print(step, loss.item())
这不是最终评估,只是 debugging 手段。
8. 结果记录模板
每次跑 lab 后写:
Lab 名称:
对应 Lecture:
运行日期:
Python/Torch 版本:
设备:CPU/GPU
输入数据 shape:
标签 shape:
模型输出 shape:
loss 类型:
训练步数:
初始 loss:
结束 loss:
是否报错:
报错原因:
修复方法:
这次运行说明了什么:
这次运行不能说明什么:
这份记录比截图更有价值,因为它能证明你理解了代码和结果。
9. 常见 lab 报错排查顺序
| 顺序 | 检查点 | 为什么 |
|---|---|---|
| 1 | 文件路径 | 数据或模型权重找不到最常见 |
| 2 | 包版本 | 教学 notebook 常因版本变动报错 |
| 3 | 数据下载 | 网络失败会导致空文件或缺文件 |
| 4 | shape | 线性层、CNN、attention 都依赖维度 |
| 5 | dtype | 分类标签常需要 LongTensor |
| 6 | device | CPU/GPU 混用会报错 |
| 7 | loss | 输出和标签格式不匹配 |
| 8 | batch size | 显存不足时先调小 |
10. 报错时给 AI 的提示词
我在跑 MIT 6.S191 的 lab/notebook,遇到下面报错。请先解释报错含义,再按路径、包版本、数据、shape、dtype、device、loss 的顺序帮我排查。不要重写整个 notebook,只给最小检查代码和最小修改方案。我的目标是理解这次错误暴露的概念短板。
报错:
【粘贴完整报错】
相关代码:
【粘贴出错 cell 和前一个 cell】
11. 如何把 lab 变成报告语言
不要写:“我运行了代码,结果如下。”这太弱。应该写:
本 lab 用一个最小神经网络完成分类任务。输入张量形状为(batch, features),模型输出为(batch, classes)的 logits。训练目标是 cross entropy loss。运行中我重点检查了输入 shape、标签 dtype、输出 shape 和 loss 变化。训练若干 step 后 loss 从 ____ 降到 ____,说明训练循环可以正常更新参数。但这只是在小规模样本上的运行结果,不能直接证明模型具有良好泛化能力,还需要 train/test split、验证集指标和错误样本分析。
这种表达适合课程作业,也适合组会汇报。