从零实现反向传播:ai-engineering-from-scratch Phase 3数学推导与代码实战
【免费下载链接】ai-engineering-from-scratchLearn it. Build it. Ship it for others.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-from-scratch
反向传播(Backpropagation)是让神经网络真正"学会"的算法。没有它,神经网络只是一个昂贵的随机数生成器。本文带你走进开源课程ai-engineering-from-scratch的 Phase 3 深度学习核心阶段,用最少的代码、最清晰的数学推导,从零理解并亲手实现反向传播——一次看懂链式法则、计算图与梯度消失三大核心概念。🚀
为什么需要反向传播?
先看一个现实场景:你的网络有 768 个输入、3072 个隐藏输出,共235 万个权重。它预测错了——但到底"是谁的错"?
| 方法 | 代价 |
|---|---|
| 逐个扰动法(微扰每个权重再前向一次) | 235 万次前向传播 |
| 反向传播 | 1 次前向 + 1 次反向,算出全部梯度 |
这不只是优化技巧,而是"可训练"与"不可能"的分界线。反向传播的本质,就是把微积分中的链式法则,系统性地应用到计算图上。
核心机制:链式法则与计算图
链式法则回顾:若y = f(g(x)),则dy/dx = f'(g(x)) * g'(x)——沿链条相乘导数。
在神经网络中,"链条"就是从输入到损失函数的操作序列:
- 前向传播:值从左到右流动,每个节点计算结果并存下中间值
- 反向传播:梯度从右到左流动,每个节点只做一件事——
接住上游传来的梯度 × 自己的局部导数 = 传给下游的梯度
这种"用内存换速度"的设计(存激活值换一次反向遍历)正是反向传播的核心权衡。📊
完整数学推导:一个两层网络
以下是一个经典两层网络(sigmoid 激活 + MSE 损失)的完整梯度推导:
前向传播 z1 = W1 * x + b1 a1 = sigmoid(z1) z2 = W2 * a1 + b2 a2 = sigmoid(z2) L = (a2 - y)^2 反向传播(链式法则逐步展开) dL/da2 = 2(a2 - y) dL/dz2 = dL/da2 * a2 * (1 - a2) dL/dW2 = dL/dz2 * a1 dL/db2 = dL/dz2 dL/dz1 = (dL/dz2 * W2) * a1 * (1 - a1) dL/dW1 = dL/dz1 * x dL/db1 = dL/dz1每个梯度都是从损失函数回溯的局部导数之积——这就是反向传播的全部。
梯度消失:深网络的隐形陷阱 ⚠️
sigmoid 的输出在 [0, 1] 之间,其导数a(1-a)最大只有 0.25(a = 0.5 时)。这意味着梯度每穿过一层,最多保留 1/4:
- 3 层深:梯度最多剩 0.25³ ≈0.0156
- 10 层深:梯度最多剩 0.25¹⁰ ≈0.000001
早期层几乎收不到梯度,自然"学不动"。这就是梯度消失问题——反向传播算法本身完美无损,问题出在它穿过的激活函数上(这正是后续 ReLU 登场的原因)。
代码实战:7 步从零实现
项目中的完整实现位于 code/main.py(Julia 版本见 code/main.jl),核心只有 6 步:
- Value 节点:每个数字存三样东西——值
data、梯度grad、以及"我是怎么被算出来的" - 运算即图节点:加法和乘法各生成新节点,并在闭包里定义自己的反向函数(乘法的关键:
d(a·b)/da = b) - sigmoid 与损失:反向时复用前向算好的
s,零额外开销 - backward():拓扑排序保证"梯度攒齐了再传播",从损失节点
grad=1.0出发倒序遍历 - Neuron → Layer → Network:神经元 = 加权和 + 偏置 + sigmoid,三层封装即得网络
- 训练循环:
zero_grad() → backward() → 参数按p -= lr * p.grad` 更新
一个容易忽视的细节:累加梯度时必须用+=而不是=,因为一个值可能参与多个运算,总梯度是所有路径的和。
动手验证:XOR 与圆形分类 🧪
跑一遍 code/main.py:
python3 phases/03-deep-learning-core/03-backpropagation/code/main.py你会看到两个实验:
- XOR 问题(2→4→1 网络):损失从随机水平一路降到接近 0,4 个输入全部输出正确
- 圆形分类(2→8→1 网络,在线 SGD + 每轮洗牌):网络不靠任何手工调参,自己发现圆形决策边界,准确率稳步上升
而 PyTorch 里的loss.backward()、optimizer.step()、zero_grad(),和你在上面写的三步完全是同一套算法——工业级封装之下,链式法则从未改变。
继续学习与项目资料
| 资源 | 路径 |
|---|---|
| 本课完整讲义(概念/推导/练习) | phases/03-deep-learning-core/03-backpropagation/docs/en.md |
| Python 实现(含 XOR 与圆形训练) | phases/03-deep-learning-core/03-backpropagation/code/main.py |
| 课前/课后自测题 | phases/03-deep-learning-core/03-backpropagation/quiz.json |
| Phase 3 阶段入口与前置要求 | phases/03-deep-learning-core/README.md |
| 全课程路线图 | ROADMAP.md |
📌本课要点回顾:反向传播 = 链式法则 + 计算图 + 拓扑排序;一次反向遍历算出全部梯度;梯度消失的元凶是激活函数而非算法本身。完成本课练习(给 Value 加relu并对比 XOR 收敛速度)后,就可以进入 04-activation-functions,看 ReLU 如何拯救深层网络。
【免费下载链接】ai-engineering-from-scratchLearn it. Build it. Ship it for others.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-from-scratch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考