《Born》第8章:自动微分引擎——梯度 Tape 与反向传播
自动微分是深度学习的魔法。Born 的实现基于梯度 Tape——一个记录所有正向运算的日志,反向传播时按逆序回放。
---
梯度 Tape 的工作原理
// 1. 开始录制
tape := autodiff.NewTape()
// 2. 正向运算(全部被记录)
y := tape.MatMul(x, w)
y = tape.Add(y, b)
y = tape.ReLU(y)
loss := tape.MeanSquareError(y, target)
// 3. 反向传播
tape.Backward(loss)
// 4. 梯度现在在每个参数上
gradW := w.Grad()
gradB := b.Grad()
Tape 中的每一条记录:
type OpRecord struct {
OpName string // "MatMul", "ReLU", ...
Inputs []Tensor // 输入张量
Output Tensor // 输出张量
Backward func(grad Tensor) // 反向传播函数
}
---
反向传播 = 链式法则的自动化
以 y = ReLU(x @ w + b) 为例:
正向: 反向:
x @ w ──► z dL/dz = dL/dy ⊙ ReLU'(z)
+ b ──► z dL/db = sum(dL/dz, axis=0)
ReLU ──► y dL/dw = x^T @ dL/dz
MSE ──► L dL/dx = dL/dz @ w^T
Tape 按逆序遍历:MSE → ReLU → Add → MatMul,每个算子调用自己的 Backward 函数,将梯度传递给输入。
---
关键设计:装饰器模式实现 Autodiff
type AutodiffBackend struct {
inner Backend
tape *Tape
}
func (b *AutodiffBackend) MatMul(a, b_ Tensor) Tensor {
result := b.inner.MatMul(a, b_)
b.tape.Record(OpRecord{
OpName: "MatMul",
Inputs: []Tensor{a, b_},
Output: result,
Backward: func(grad Tensor) {
a.SetGrad(grad.MatMul(b_.T()))
b_.SetGrad(a.T().MatMul(grad))
},
})
return result
}
反向传播函数在正向时就被「捕获」到闭包中,不需要运行时查找。
---
内存优化
- 梯度检查点:在大型模型中,可以丢弃中间激活值,反向传播时重新计算
- 梯度累加:多次 backward 的梯度相加,模拟大批量训练
- ClearTape:训练 step 结束后清空 tape,释放内存
📘 《Born》连载技术书,第 8/22 章。
💬 讨论回复 (0)
推荐
🌟 智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。
🎁 领取 2000万 Tokens