缺陷案例实战:精准定位梯度覆盖 Bug
Agent 辅助工程检查
前置要求
第 32 天梯度累加机制与数值梯度检验。
学习目标
通过构造极简复现用例 (MRE),在数值差分比对下精准定位出因覆盖赋值导致隐蔽梯度错误的具体节点与代码缺陷。
操作指引
使用 CLI 运行梯度缺陷诊断排查命令:
python3 projects/autograd/cli.py diagnose --bug-type overwrite-accumulation
观察诊断程序如何在表达式 $f = (a + b) \cdot a$ 中隔离出节点 a,展示其解析梯度 $7.0$ 与数值差分梯度 $10.0$ 之间高达 $30\%$ 的相对误差。
自主演练与记录
1. 写出能够可靠触发梯度覆盖缺陷的极简复现代码 (MRE)。
2. 解释为何类似 $z = x \cdot y$ 这样的单分支测试用例即使在存在该缺陷时依然能够通过 gradcheck。
3. 在 _backward() 中指出修复该缺陷的关键代码修改。
在无分叉(每个变量只被使用一次)的线性图结构中,每个节点只有一个消费端,此时累加 (+=) 和直接赋值 (=) 恰好产生相同数值。缺陷只会在变量被多次复用分支时显现。
参考解答:
1. 极简复现用例:$a = \text{Value}(3.0); b = \text{Value}(4.0); f = (a + b) * a; f.\text{backward}()$。
2. 因为在非分叉图中,每个节点只接收一次反向梯度回传,赋值 (=) 碰巧等于累加结果,掩盖了真实缺陷。
3. 将所有算子的 _backward() 闭包中的 self.grad = ... 统一修改为 self.grad += ...。
学习者能够构造出区分累加与覆盖实现的极简测试用例,并准确解释其数学原理。
权威源资源与权利证明
micrograd: A tiny scalar-valued autograd engine
对应章节 / 时间戳: micrograd/engine.py: class Value (_backward closures and backward() topological sort); README 'Example usage'
验证版本与日期: commit a9a9f94 (Verified: 2026-10-30)
Direct demonstration of how simple variable reuse creates branching DAGs requiring accumulation.
Autograd backward pass and multivariable calculus
Local diagnostic harness in projects/autograd/diagnostics.py.
对比候选资源与选型分析 (2)
Production scale, but too large and complex for tracing by hand in introductory lessons.
Vectorized autograd; micrograd's pure scalar model is pedagogical for hand backprop.