有向非巡回グラフ(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.