← cd ../posts

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

2026-05-24

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 玩 10 分钟。试试不同的网络深度、激活函数、学习率,感受一下"调参炼丹"是什么意思。

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