# 神经网络是怎么"学"的：梯度下降与反向传播

> AI 系列第 3 篇。把 1986 年那篇被冷落了 25 年的反向传播论文讲清楚。用"在高维大山上摸黑下山"的比喻，从损失函数 → 梯度 → 梯度下降 → 反向传播一路推到底，最后回答："为什么同一篇论文 1986 没人用、2012 改变了世界？

- URL: https://tenggouwa.com/posts/how-neural-nets-learn/
- 发布: 2026-05-24
- 标签: ai, 神经网络, 梯度下降, 反向传播, ai-series

> AI 系列第 3 篇。上一篇我们看了 AI 圈三十年的派系内战。
> 这一篇钻进**联结主义**的引擎舱——神经网络到底是怎么"学"东西的。

## 0. 还上一篇的"债"

第 1 篇结尾我留了一个钩子：

> "1986 年那篇被冷落了 25 年的反向传播论文，为什么 2012 年突然就改变了世界？"

今天就还这个债。但要回答这个问题，得先把"神经网络怎么学"这件事讲清楚。

我们不上数学。我们用一个生活化的比喻——**在高维大山上摸黑下山**——把所有关键概念串起来。读完你会得到一种"哦原来就这么回事"的感觉。

---

## 1. 先把"学习"这件事拆掉

抛开所有术语，机器"学"东西的过程就三步：

```
$ machine_learn
  step 1: 猜一个答案
  step 2: 看猜得有多差
  step 3: 朝"少差一点"的方向调整自己
  loop until 满意
```

人类小孩学走路也是这套流程：迈步 → 摔倒 → 把腿放对一点 → 再迈步。区别是，人类用感觉、用本能；机器需要把"猜得多差"和"朝哪个方向调"都变成**可以计算的数字**。

这就是机器学习要解决的两个核心问题：

1. **怎么把"差"变成一个数？** —— 损失函数（loss function）
2. **怎么根据这个数，反推应该怎么调？** —— 梯度（gradient）+ 梯度下降（gradient descent）

理解了这两件事，神经网络是怎么训出来的，你就懂了 90%。

---

## 2. 损失函数：把"猜得有多差"变成一个数

假设我们要教一个模型识别手写数字。给它看一张 "7"，它输出 "1"。这就是猜错了——但**错多少**？

直觉答案：差了 6。但这种"减一减"的算法对图像、文字都不适用。我们需要一个更通用的方式来量化错误。

### 一个例子：均方误差（MSE）

最简单的损失函数叫**均方误差**：

```
真实答案: y = 7
模型预测: ŷ = 1
误差     = (y - ŷ)² = (7 - 1)² = 36
```

平方一下，是为了让"差很多"惩罚得比"差一点"重。差 1 就罚 1，差 6 就罚 36，差 10 就罚 100。这正好符合直觉：错得越离谱、越要狠狠调。

### 真实场景：交叉熵

但识别数字这种"分类问题"，更常用的是**交叉熵**（cross-entropy）。它的核心思想是：

**模型输出的应该是"我有多确信这是 7"。** 而不是直接输出一个数字 7。

也就是说，模型对每个可能的数字（0–9）都给一个概率：

```
模型说: 0:1%  1:5%  2:2%  ...  7:60%  ...  9:3%
真实答案是 7。
loss = -log(0.60) ≈ 0.51
```

如果模型对 7 的把握是 99%，loss 就是 `-log(0.99) ≈ 0.01`（几乎没损失）。
如果只有 10%，loss 就是 `-log(0.10) ≈ 2.30`（损失大）。

这样我们就把"猜得有多差"压缩成了**一个标量数字**。所有的训练，都是在追求**让这个数字尽可能小**。

> 一句你可以拿去吹的话：
> **训练神经网络的本质，就是在一个超高维空间里，找到能让 loss 函数最小化的那组参数。**

---

## 3. 梯度：朝哪个方向调，loss 会变小？

OK 现在我们知道 loss 是 0.51。然后呢？怎么调模型？

模型的"参数"是什么？就是神经网络里那些数。一个 GPT-3 有 1750 亿个数。每改一个，loss 都会变一点。问题是：

**我们应该把这 1750 亿个数里的哪一个、朝哪个方向、调多少？**

这就是**梯度**要解决的问题。

### 一维的直觉版

先假设模型只有一个参数 `w`，loss 是 `w` 的函数 `L(w)`。画出来长这样：

```
L(w)
 │      ╱╲
 │     ╱  ╲
 │    ╱    ╲
 │___╱      ╲___
 │              ╲___      ╱
 │                  ╲___╱
 │                  当前在这里
 └────────────────────────── w
```

你现在站在某个点上。**梯度**告诉你的就是：**当前点的斜率是多少**。

- 斜率为正 → 往左走 loss 会变小
- 斜率为负 → 往右走 loss 会变小
- 斜率接近 0 → 你可能站在山底（也可能是山顶或者鞍点，后面讲）

### 高维的实际版

现实里参数不止一个。GPT-3 有 1750 亿个参数。这时候 loss 是一个 1750 亿维空间里的"曲面"，无法画出来。

但**直觉是一样的**：每个参数都有自己的偏导数（partial derivative），加起来就是这个 1750 亿维空间里的"下坡方向"。

整个 1750 亿维的偏导数向量，就叫做**梯度**。

> 一句你可以拿去吹的话：
> **梯度就是损失函数曲面在每个参数上的"坡度"。它告诉你：每个参数往哪边动一点，能让 loss 下降最快。**

---

## 4. 梯度下降：在山上摸黑下山

现在到了关键比喻。

想象你被空投到一座非常陡、非常黑的山上。任务是走到山谷底。但是——

- 你没有地图。
- 你看不见周围（漆黑）。
- 你只能感觉脚下当前位置的**坡度**。

你会怎么做？

最朴素的策略是：**用脚感受一下哪个方向是下坡，迈一小步，然后再感一次，再迈一步**。一直循环到坡度变成 0（站在平地了）。

这就是**梯度下降**（gradient descent）。

```
$ gradient_descent --loss_fn=L --params=w
while True:
    g = compute_gradient(L, w)   # 摸一下脚下的坡
    w = w - learning_rate * g    # 沿下坡方向走一小步
    if abs(g) < threshold:
        break                    # 到底了
```

那个 `learning_rate`（学习率）是**步长**。步太大会越过山谷直接撞到对面山坡，步太小会走一辈子也走不到底。这个超参数是炼丹里最重要的一个。

### 三个"摸黑下山"的真实困境

#### 困境 1：局部最小值（local minimum）

你以为到底了，其实只是个小坑：

```
   ╱╲          ╱╲
  ╱  ╲   你   ╱  ╲
 ╱    ╲  ▼   ╱    ╲
╱      ╲___╱      ╲___ ← 真正的山底
```

在二维空间这是个大问题。但在 1750 亿维空间，局部最小值很少见——更常见的是**鞍点**（saddle point）。

#### 困境 2：鞍点（saddle point）

在某些方向是上坡，在另一些方向是下坡：

```
↑ 这个方向上坡
─── ─── ─── ─── ─── 你
         ↓ 这个方向下坡
```

鞍点在高维空间里**到处都是**。好消息是，现代优化器（Adam、AdamW）能比较快地逃出鞍点。

#### 困境 3：梯度消失 / 爆炸

如果网络太深，反向传播时梯度要经过很多层。如果每层都让梯度缩小 0.5 倍，10 层之后就是 0.001 倍——梯度几乎为 0，没法学了。这就是**梯度消失**（vanishing gradient）。

反过来如果每层放大 2 倍，10 层就是 1024 倍——梯度爆炸（exploding gradient），参数瞬间炸到 NaN。

**1986 → 2012 这 25 年深度学习上不去，很大程度上就死在这两件事上。** 直到 ReLU、batch normalization、ResNet 出来才解决。

---

## 5. 反向传播：怎么高效地算梯度？

到这里我们假设"梯度是能算出来的"。但 1750 亿个参数，每个都要算一下偏导数——怎么算才不慢死？

这就是 1986 那篇论文的贡献——**反向传播**（backpropagation）。

### 直觉版：连锁责任追究

想象你是个 CEO，公司年底亏了 1 亿（这就是 loss）。你想知道：

- 销售部该负多少责任？
- 营销部该负多少责任？
- 产品部该负多少责任？

你不会直接问销售部："你为这 1 亿负多少责任？" 那太抽象。你会顺着责任链反推：

```
1 亿 loss
   ▲
   │ 来自销售目标没达成
   ▼
销售部 = -7000 万责任
   ▲
   │ 销售目标 = 营销线索 × 转化率
   ▼
营销部 = -4000 万（线索少了）
产品部 = -3000 万（功能不行所以转化低）
```

**反向**地，从"最终损失"一层一层往回**链式法则求导**，把责任分配到每个部门、每个员工。

这正是反向传播在做的事。Loss 从输出层算起，往前一层一层算每一层的梯度。每一层的梯度怎么算？用**链式法则**（chain rule）——就是高中数学里的：

```
d(f(g(x)))/dx = f'(g(x)) * g'(x)
```

神经网络是一堆函数嵌套：`output = layer_N(... layer_2(layer_1(input)) ...)`。链式法则从最外层 layer_N 开始往里推，每一层算一次乘法，最终把每个参数的梯度算出来。

整个过程只需要走两遍网络：

```
forward  pass:  input → ... → loss   （算出损失）
backward pass:  loss  → ... → input  （算出梯度）
```

这就是为什么它叫"反向传播"——梯度从输出层往输入层反向传。

### 为什么这个算法这么重要？

因为它把**算梯度的复杂度**从"指数级"砍到了"线性级"。

没有反向传播之前，每加一层网络，算梯度的计算量爆炸式增长。有了反向传播，你的网络深 100 倍，算梯度也只贵 100 倍（线性增长）——这就让训练**深**的网络变得可行了。

> 一句你可以拿去吹的话：
> **反向传播不是一个"学习算法"，它是一个"求导加速器"。它让训练 100 层的网络从理论上的"几年"变成了实际上的"几小时"。**

---

## 6. 一个手写数字识别的全流程

把上面所有概念串起来。我们要训一个能识别 0–9 手写数字的模型：

```
┌─────────────────────────────────────────────────────────┐
│  Step 1: 随机初始化 1750 亿个参数（瞎猜）                  │
│                                                          │
│  Step 2: 拿一张图（一个 "7"），forward 走一遍              │
│          → 模型输出 "我有 10% 把握是 7"                    │
│                                                          │
│  Step 3: 算 loss = -log(0.10) = 2.30                     │
│                                                          │
│  Step 4: backward 走一遍                                  │
│          → 算出 1750 亿个参数各自的梯度                   │
│                                                          │
│  Step 5: 每个参数 = 当前值 - 0.001 × 它的梯度              │
│          （0.001 是学习率）                              │
│                                                          │
│  Step 6: 回到 Step 2，换一张图。循环 1000 万次。           │
└─────────────────────────────────────────────────────────┘
```

经过 1000 万次循环，模型对 "7" 的把握从 10% 变成 99.5%。

**这就是"训练"。** 整个深度学习圈每天都在做这件事。从 AlexNet 到 GPT-5，本质都是这个循环——只是网络变大了、数据变多了、技巧变巧了。

---

## 7. 回答最初的债：1986 vs 2012

现在可以回头看那个钩子了：**为什么反向传播 1986 年发表，2012 年才改变世界？**

答案不在算法本身。算法 1986 年就是对的。瓶颈在**三件事都没到位**：

### 1. 算力不够

1986 年：一台 SUN 工作站每秒能做几百万次浮点运算。
2012 年：一块 NVIDIA GTX 580 GPU 每秒能做 1.5 万亿次浮点运算。

**6 个数量级**。AlexNet 在两块 GPU 上训了 6 天，1986 年这种规模的训练要花几十年。

### 2. 数据不够

1986 年：手写数字数据集 MNIST 还要等 1998 年才有，且只有 6 万张图。
2012 年：ImageNet 1400 万张图、22000 个类别。

神经网络是"数据饕餮"。没数据它就发挥不出来。

### 3. 工程技巧不够

反向传播光是"对"还不够，要让它**稳**——
- 梯度消失怎么办？2010 年 ReLU 激活函数登场，缓解了大半。
- 训练不稳定怎么办？2015 年 batch normalization。
- 网络太深训不动怎么办？2015 年 ResNet 的残差连接。

这些工程 hack 都是 2010 年代才出现的。没有它们，反向传播在深网络上根本跑不通。

### 还有一件容易被忽视的事：信仰

1986 → 2006 这 20 年，整个 AI 圈在"嘲笑神经网络"。Hinton 那群人坚持下来了——不是因为他们看到了未来，是因为他们**赌对了**。

这是科学史上一个常见的剧情：**一个算法对，时机不对，等 25 年。**

> 一句你可以拿去吹的话：
> **AI 的历史不是"算法的胜利"，是"算法 × 算力 × 数据 × 信仰"的乘积。任何一项为 0，整个乘积就是 0。**

---

## 8. 给你的小作业

1. **用"摸黑下山"的比喻，向一个不懂技术的朋友解释什么叫梯度下降。**
2. **学习率太大、太小、刚好，分别会出现什么现象？画三张示意图。**
3. **去 [playground.tensorflow.org](https://playground.tensorflow.org) 玩 10 分钟。试试不同的网络深度、激活函数、学习率，感受一下"调参炼丹"是什么意思。**

> **下一篇钩子**：神经网络会学了。但要它"看见"——把一张图理解成"猫"、"狗"、"街景"——还需要专门的架构。
> 下一篇我们讲从 1958 年 Frank Rosenblatt 的感知机，到 1998 年 LeCun 的 LeNet，再到 2012 年 AlexNet 的地震——
> 神经网络是怎么从"识别单个像素"，进化成"看懂整张图"的。
> 顺便回答：**今天的 ViT（Vision Transformer）打败 CNN 了吗？** 答案比你想的复杂。
