第 1 讲:手把手讲透神经网络与反向传播——构建 micrograd
这一讲讲什么
这是整个系列的地基:2 小时 25 分钟,从一无所有到亲手写出一个能自动求梯度的引擎,并用它训练出你的第一个神经网络。Karpathy 全程只用 Python 和最朴素的标量运算,把「神经网络是怎么学习的」这件事拆到不能再拆:
- 先复习导数到底是什么——不背公式,用数值逼近亲眼看斜率;
- 用一个
Value对象把每一步标量运算连成表达式图,先手动、再自动地沿图反向应用链式法则,这就是反向传播 (backpropagation); - 由此得到一个约 100 行的标量自动求导引擎 micrograd;
- 在它之上用几十行搭出
Neuron → Layer → MLP的迷你神经网络库,写损失函数、跑梯度下降,完整训练一个小网络; - 最后与 PyTorch 对照:你会发现 PyTorch 的 API 和行为跟你刚写的东西一一对应——现代框架只是把同样的原理做到了张量级和工业级。
看完这一讲,反向传播对你不再是黑盒,而是「显然如此」的机制。这正是 Karpathy 在《Yes you should understand backprop》里坚持的观点:这层地基不打好,后面全是空中楼阁。
前置知识
- Python 基础:函数、类、列表推导式能看懂即可;
- 高中导数:对「导数≈斜率」还有模糊印象就够了,视频开头会从头复习;
- 不需要线性代数、不需要微积分技巧、不需要任何机器学习背景。
分段大纲
以下章节译自视频描述中的官方时间轴(时间点若有出入,以 YouTube 原视频描述为准):
| 时间 | 内容 |
|---|---|
| 00:00:00 | 开场 |
| 00:00:25 | micrograd 总览 |
| 00:08:08 | 单输入简单函数的导数 |
| 00:14:12 | 多输入函数的导数(偏导数) |
| 00:19:09 | micrograd 核心 Value 对象及其可视化 |
| 00:32:10 | 手动反向传播示例 #1:简单表达式 |
| 00:51:10 | 单步优化(梯度下降)预览 |
| 00:52:52 | 手动反向传播示例 #2:一个神经元 |
| 01:09:02 | 为每种运算实现 _backward 函数 |
| 01:17:32 | 对整张表达式图实现 backward(拓扑排序) |
| 01:22:28 | 修复节点被多次使用时的反向传播 bug(梯度累加) |
| 01:27:05 | 把 tanh 拆开算:练习更多运算(exp、除法等) |
| 01:39:31 | 用 PyTorch 做同样的事:对照验证 |
| 01:43:55 | 构建神经网络库:多层感知机 (MLP) |
| 01:51:04 | 创建小数据集,编写损失函数 |
| 01:57:56 | 收集神经网络的全部参数 |
| 02:01:12 | 手动做梯度下降优化,训练网络 |
| 02:14:03 | 总结:我们学到了什么,如何迈向现代神经网络 |
| 02:16:46 | 走读 GitHub 上 micrograd 的完整代码 |
| 02:21:10 | 真实世界:深入 PyTorch 源码找对应实现 |
| 02:24:39 | 结语 |
| 02:25:20 | 花絮 :) |
核心概念中文讲解
导数 (derivative) 与梯度 (gradient):导数回答一个非常具体的问题——「我把输入微调一点点,输出会变多少?」本讲不用求导公式,而是直接用定义:取一个很小的 h,算 (f(x+h) − f(x)) / h,这个比值就是斜率。当函数有很多输入时,对每个输入各求一个偏导数,合起来的这组「敏感度」就叫梯度。对神经网络而言,梯度告诉我们:每个权重朝哪个方向、以多大力度影响最终损失——这就是学习的指南针。
链式法则 (chain rule):复合函数的求导法则,也是整个深度学习唯一真正依赖的数学定理。如果 L 依赖 e,e 又依赖 a,那么 a 对 L 的影响 = (a 对 e 的影响)×(e 对 L 的影响)。直觉版本:本地导数乘上游梯度。无论网络多深,梯度就是这样一段一段「乘」回去的——每个节点只需要知道自己这一小步的导数,剩下的交给乘法。
前向传播 (forward pass) 与反向传播 (backward pass):前向传播是「算出结果」:数据从输入一路经过各运算节点,算出每个中间值,直到输出(比如损失)。反向传播是「归因」:从输出出发,沿表达式图反着走,用链式法则把「谁该为损失负多少责」逐节点算出来,写进每个节点的 grad。micrograd 的实现精髓是:每种运算(加、乘、tanh……)在前向计算时顺手挂一个 _backward 闭包,记住「轮到我时该怎么把梯度传给我的输入」。
拓扑排序 (topological sort):反向传播的调用顺序不能乱——算一个节点的梯度之前,所有依赖它的下游节点必须已经算完。把表达式图(一个有向无环图)做拓扑排序、再逆序遍历,恰好保证这一点。micrograd 的 backward() 就是:拓扑排序 + 逆序逐个调用 _backward。另有一个必须内化的细节:节点被多条路径使用时,梯度要累加而不是覆盖——这就是所有框架都需要 zero_grad() 的原因。
神经元 / 层 / 多层感知机 (neuron / layer / MLP):神经元是一个极简的计算单元:输入乘以各自权重 (weight) 求和、加上偏置 (bias),再过一个非线性激活函数(本讲用 tanh)。一组互不相连的神经元并排放,就是一层;把若干层首尾相接,就是多层感知机 (MLP)。关键在于:这些结构全部由 Value 的基本运算搭成,所以表达式图自动记录了一切,loss.backward() 一声令下,几十个参数的梯度同时到账——工程上只需再实现 parameters() 把参数收集起来统一更新。
notebooks 汉化说明
官方仓库为本讲收录了两个 notebook(文件名里的 "roughly" 表示它们是视频过程的粗略代码记录,原版不含文字说明)。我们的汉化版保持全部代码单元原样不动,在文件开头加入授权与使用说明,并在关键节点插入【译者导读】中文说明单元:
- micrograd_lecture_first_half_roughly.zh.ipynb(上半场汉化版)——导数、Value 对象、手动反向传播、拓扑排序与梯度累加 bug;
- micrograd_lecture_second_half_roughly.zh.ipynb(下半场汉化版)——完整版 Value、PyTorch 对照、Neuron/Layer/MLP 与完整训练循环;
- 原始英文版见 官方仓库 lectures/micrograd;随附 LICENSE。
建议用法:边看视频边在本地 Jupyter(或上传到 Colab)里跟着跑;notebook 需要 numpy、matplotlib 和 graphviz(画表达式图用,pip install graphviz 之外还需安装系统的 Graphviz)。
练习
视频描述中附有一份官方练习 Colab:micrograd exercises(Google Colab,英文原版)→。看完视频后你应当有能力独立完成,内容概述:
- 手推导数:给定一个多输入的标量函数,先用微积分写出它的解析梯度 (analytical gradient),再用数值法(包括精度更高的对称差分)验证两者一致;
- 扩展 Value 类:为你的 micrograd 补上更多运算(如
exp、log、除法、幂),使它能支撑 softmax + 负对数似然损失 (negative log likelihood),并对其正确反向传播; - 用 PyTorch 验证:把同样的计算用
torch.Tensor重写一遍,核对你手写引擎算出的梯度与 PyTorch autograd 完全一致。
练习的自我检验标准很朴素:你写的每一个梯度,都能同时被数值法和 PyTorch 双重确认。做到这一步,第 1 讲才算真正过关。
中英术语对照表
| 英文 | 本站译法 | 备注 |
|---|---|---|
| backpropagation | 反向传播 | 本讲主题;简称 backprop |
| derivative / partial derivative | 导数 / 偏导数 | 单输入 / 多输入 |
| gradient | 梯度 | 对各输入的偏导数合称 |
| chain rule | 链式法则 | 复合函数求导法则 |
| forward pass / backward pass | 前向传播 / 反向传播过程 | 先算值,再归因 |
| expression graph / compute graph | 表达式图 / 计算图 | 有向无环图 (DAG) |
| topological sort | 拓扑排序 | 决定 backward 的调用顺序 |
| autograd (automatic differentiation) | 自动求导(自动微分) | micrograd 与 PyTorch 的核心机制 |
| scalar / tensor | 标量 / 张量 | micrograd 用标量,PyTorch 用张量 |
| neuron / layer / MLP (multi-layer perceptron) | 神经元 / 层 / 多层感知机 | 由小到大的三级结构 |
| weight / bias | 权重 / 偏置 | 可训练参数 |
| activation function | 激活函数 | 本讲用 tanh |
| loss function | 损失函数 | 本讲用均方误差 (MSE) |
| gradient descent | 梯度下降 | 沿负梯度更新参数 |
| learning rate | 学习率 | 每步更新的步长 |
| zero grad | 梯度清零 | 因梯度累加而必需;初学者高频 bug |
下一步
完成本讲与练习后,进入课程总览看第 2 讲:构建 makemore——从这里开始踏上通往 GPT 的语言建模之路(汉化中)。也可以顺手读读 micrograd 正式仓库:视频里写的引擎在那里被整理成了干净的百行版本。