Skip to content

心智模型:一图看懂 PyTorch

在钻进每个概念之前,先花 10 分钟把"全景图"装进脑子。后面所有细节都会挂在这张图上。

用做菜理解四大概念

学 PyTorch 最常见的失败方式是:孤立地背 API。换个视角——把训练模型想象成开一家餐厅学做一道新菜

概念英文类比一句话职责
张量Tensor食材一切数据的载体:菜品原料装在标好规格的盒子里
模型Model (nn.Module)厨师定义"食材怎么加工成成品"的规则
损失函数Loss Function品尝打分量化"做出来的菜和理想味道差多远"
优化器Optimizer改进策略根据打分反馈,告诉厨师每一步该往哪个方向调
数据集/加载器Dataset / DataLoader进货渠道把食材按批次清洗、切配后送进后厨

训练循环就是厨师的成长过程:

进货(DataLoader) → 做菜(前向传播) → 品尝打分(计算损失)
→ 分析哪里做差了(反向传播求梯度) → 调整手法(优化器更新参数)
→ 下一批食材,继续……

概念关系图

                        ┌────────────────────────────┐
                        │        训练循环 (train loop)  │
                        └────────────────────────────┘
                                     │ 反复执行
        ┌────────────┬───────────────┼───────────────┬────────────┐
        ▼            ▼               ▼               ▼            ▼
  ┌──────────┐ ┌──────────┐   ┌───────────┐   ┌──────────┐  ┌──────────┐
  │ Dataset/ │→│  模型     │→ │  损失函数  │→ │ Autograd │→ │ 优化器    │
  │ DataLoader│ │nn.Module │   │  nn loss   │  │ 自动求导  │  │ optimizer│
  └──────────┘ └──────────┘   └───────────┘   └──────────┘  └──────────┘
   进货渠道       厨师          品尝打分        分析原因      调整手法
        │            │               │              │            │
        └────────────┴────── 数据流动的形式都是 ──────┴──────┬─────┘
                     ▼                     ▼
              ┌─────────────────────────────────┐
              │   张量 Tensor(一切数据的载体)      │
              │   形状 shape + 数据类型 dtype + 设备 device │
              └─────────────────────────────────┘

记住三个关键流向:

  1. 数据流(前向):DataLoader 吐出张量 → 模型吐出预测张量 → 损失函数吐出一个标量损失。
  2. 梯度流(反向):对标量损失调用 .backward(),梯度沿前向的逆方向流回每个参数张量,写入其 .grad 属性。
  3. 更新流:优化器读取每个参数的 .grad,修改参数值,然后梯度清零,等待下一轮。

新手最容易误解的 5 个地方

误解 1:"张量就是矩阵"

矩阵是二维的,张量是 N 维数组的推广:0 维张量是标量,1 维是向量,2 维是矩阵,3 维以上都是"矩阵的堆叠"。更重要的是,张量不只是数组——它可以带梯度信息、可以在 GPU 上、可以参与自动求导,这是 NumPy 数组做不到的。

误解 2:"backward() 会更新参数"

不会。.backward() 只计算梯度(把结果存进 param.grad)。更新参数必须再调用 optimizer.step(),清零梯度要 optimizer.zero_grad()。这三步是独立的:

python
loss.backward()        # 1. 算梯度,写入 param.grad
optimizer.step()       # 2. 用梯度更新 param.data
optimizer.zero_grad()  # 3. 把 param.grad 清为零(下一轮前重新算)

有个坑:如果忘记 zero_grad(),PyTorch 会把新梯度累加到旧梯度上(这是特性不是 bug,为了支持某些需要累加的场景),训练会莫名其妙不收敛。实战章节会带你亲自踩一次。

误解 3:"shape 不重要,能跑就行"

深度学习代码 80% 的 bug 是形状不匹配。[32, 784][32, 10] 差一个维度,程序要么直接报错,要么静默广播出错误结果(更可怕)。从第一天起就养成 print(x.shape) 的习惯。

误解 4:"训练时和推理时的代码完全一样"

不一样。Dropout(训练时随机丢弃神经元)和 BatchNorm(训练/推理用不同统计量)这类层,在 model.train()model.eval() 下行为完全不同。忘了切换,推理效果会莫名其妙变差。

误解 5:"GPU 是万能的,加了就快"

小数据 + 小模型时,GPU 的数据搬运开销可能让训练更慢。GPU 的优势在于大规模并行矩阵运算,任务太小时体现不出来。另外 CPU→GPU 的数据搬运是显式发生的(.to(device)),不是自动的。

接下来

四个核心概念每个都值得单独展开:

如果只想快速上手,也可以先去环境搭建跑起来,再回头精读这几篇。