计算图有向无环图 (DAG) 拓扑排序实现
Agent 辅助工程检查
前置要求
第 31 天计算图概念与深度优先搜索 (DFS) 算法基础。
学习目标
理解反向传播为何必须依赖后序遍历拓扑排序,确保每一个节点的所有下游消费节点的梯度全部传回后,才执行该节点的反向传播。
操作指引
使用 CLI 查看多路径共享节点图的结构:
python3 projects/autograd/cli.py graph --preset shared-node --format ascii
观察节点 a 同时作为加法项 $(a+b)$ 和乘法项 $(a+b) \cdot a$ 的输入。任意乱序或简单广度优先搜索都会导致 a._backward() 在未接收完全部下游梯度前提前触发。
自主演练与记录
对于表达式 $f = (a + b) \cdot a$,其中 $a = 3.0, b = 4.0$:
1. 跟踪从根节点 $f$ 出发的深度优先搜索 (DFS) 遍历过程。
2. 列出后序遍历访问节点的序列。
3. 验证将其反转后的逆拓扑序:保证根节点 $f$ 在最前,加法节点在中间,输入叶节点 $a, b$ 在最后。
后序 DFS 的核心逻辑:递归访问当前节点 _prev 中的所有子节点;仅当所有子节点都完全处理完毕后,才将当前节点追加到列表中。将最终列表反转,即可保证每个节点排在依赖它的所有后代节点之后。
参考解答:
1. 根节点 $f$ 的依赖集合为 $\{sum, a\}$。
2. 中间节点 $sum$ 的依赖集合为 $\{a, b\}$。
3. DFS 遍历访问 $a$、$b$,处理完毕后将 $sum$ 加入列表,最后加入 $f$。
4. 反转后的反向执行序列:$[f, sum, b, a]$。
当调用 backward() 时,依次执行 $f._backward()$、$sum._backward()$,最终节点 $a$ 完整累加了来自两个方向的全部梯度。
学习者能够不依赖第三方图论库,独立手写 DFS 后序拓扑排序算法构建正确的计算节点执行链。
权威源资源与权利证明
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)
Clear reference implementation of recursive DFS topological sort for reverse-mode ordering.
Graph traversal fundamentals (DFS/BFS)
Local implementation in projects/autograd/engine.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.