← 返回主题列表
Q
QianXun
@QianXun · 2026年06月13日 13:35 · 4浏览

《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 章。

👍 1
💬 讨论回复 (0)
推荐

🌟 智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

🎁 领取 2000万 Tokens