💡 サンプル¶
mujou の使い方を示すサンプルプログラムの一覧。どれもリポジトリの examples/ にある。サイトのページはこれらをそのまま取り込んでいるので、載っているコードはそのまま実行可能。テストではなく手引きなので、テストでは実行しない。
やりたいことから探す¶
| やりたいこと | プログラム | 詳しい説明 |
|---|---|---|
| とにかく 1 つ動かす | quickstart.py |
1. ネットワークを走らせる |
| ネットワークを分岐させ、合流させる | branching.py |
1. ネットワークを走らせる、Port と Channel |
| 連続時間で変わる状態を持つノードを書く | leaky.py |
2. ノードを書く |
| ノードを決定的にテストする | test_leaky.py |
3. ノードをテストする |
| ノードの中の BP で、ストリームから学び続ける | online_learning.py |
4. ノードの中で学習する |
| 自作の則でノードをまたいで学ぶ | feedback_alignment.py |
更新則 |
| PC-ALM で回帰を数十行で学ぶ | pc_regression.py |
5. PC-ALM で学習する |
| PC-ALM のノードを自分で書く(入力が 2 つ) | pc_merge.py |
PC-ALM |
| PC-ALM で MNIST を学び、BP と比べる | mnist/ |
PC-ALM |
| GPU 上の ResNet で CIFAR-10 を学び、BP と比べる | cifar10/ |
PC-ALM |
| 状態を保存し、その続きから再開する | save_and_restore.py |
6. 保存と再開 |
| 複数のネットワークを一緒に走らせる | group.py |
Group |
| 新しい出力を追い続ける(途中の値は飛ばしうる) | subscribe.py |
ホストの入出力 |
| 実行専用のタイマー、時間の速さ、複数の実行の一時停止 | timers.py |
時間 |
| ノードが例外を投げたときの動きを知る | errors.py |
例外と終了 |
| ネットワークのグラフを描いてブラウザで開く | visualize.py |
ネットワークの可視化 |
各プログラムが示すこと¶
quickstart.py: 2 ノードのネットワークをwith mujou.run(...)で走らせる。ホストはwriteで入力を書き、期待した出力が届くまでwait_forで待つbranching.py: 送るだけのPortを 2 つの枝につなぎ、MultiPortで合流させる。後半はMultiPortがconnectの返した Channel で、相手ごとに違う値をsend_toで送るleaky.py: リーク積分器。連続時間で定義し厳密解で進めるので、どんなdtでも安定する。実行すると 2 つ並べた鎖の入力を切り替え、各出力を送られた時刻の厳密解と比べるtest_leaky.py:leaky.pyのノードをmujou.testingの仮想タイマーと手動の更新でテストする。厳密解との比較、離散アルゴリズムとのビット単位の一致、再開した実行と止めずに続けた実行の一致。uv run pytest examples/test_leaky.pyで実行するonline_learning.py: 教師がホストの書いて変えるaで y = a x + b のバッチを送る。学習するノードは新しいバッチごとに、前のバッチからの時間だけ、素の PyTorch の autograd で学ぶ。ホストは損失が下がり、跳ね上がり、また下がるのを追うfeedback_alignment.py: 2 つのノードが 2 層のネットワークを feedback alignment で学ぶ。両方向の Port、活動と一緒に中継する目標、pc.clock.LearnClockによるサンプルごとに 1 回の学習pc_regression.py:pc.Chainとpc.showで、流れてくるバッチから回帰を学ぶ。損失は各バッチから学ぶ前に測るpc_merge.py: 入力を 2 つ持つ PC-ALM のノードMergeをpc.functionalとpc.clock.LearnClockで書き、2 本の塔を合流させて回帰を学ぶmnist/: 784-256-256-10 のネットワークをpc.Chainで MNIST に学ばせ、同じネットワークを同じ初期重みとバッチで BP でも学ばせる。入口はmain.py。data.pyがデータを読み、metrics.pyが測り、bp.pyが BP の基準を学習させ、watch.pyがノードのdtを数える(--watch)cifar10/: CUDA のデバイスに載せた ResNet-20 をステージごとのノードに分け、pc.Chainとpc.optim.AdamWで CIFAR-10 に学ばせる。同じネットワークを同じ初期重み・バッチ・optimizer で、GPU 上の BP でも学ばせる。入口はmain.py。data.pyがデータを読んで拡張し、resnet.pyがネットワークを組み、少ないノードに切る理由を述べ、metrics.pyが測り、bp.pyが BP の基準を学習させるsave_and_restore.py:run.state_dict()で状態を取得し、torch.saveで保存し、新しいインスタンスにmujou.run(..., state=...)で再開する。再開した実行は専用のタイマーで走るgroup.py:Group(enc=..., dec=...)と、ノードのパス("enc.scale")の付き方subscribe.py:run.subscribeがまず最新の出力を、その後は新しい出力を 1 つずつ返す。breakで止めるtimers.py:Timestamp、時間の速さを変えた実行専用のTimer、グローバルタイマーの速さ、グローバルタイマーを止めて 2 つの実行の状態を同じ時刻で取得すること。一方から再開した実行は専用のタイマーで続くerrors.py: ホストが受け取るNetworkErrorとその__cause__、on_exception→on_stopの順、on_startの例外はmujou.runが送出することvisualize.py: 2 つのネットワークと 1 つのノードからなるネットワークとpc.Chainのページを、走らせずにmujou.viz.to_htmlで書き出す
走らせ方¶
ソースからビルドした環境(インストール)で、リポジトリのルートから実行する。
uv run python examples/quickstart.py
uv run python examples/mnist/main.py
uv run python examples/cifar10/main.py
GPU を使うのは cifar10/ だけで、CUDA が要る。mnist/ と cifar10/ 以外は 15 秒以内に終わる。mnist/ は初回に MNIST(約 11 MB)をダウンロードし、既定の 3 epoch で約 2 分かかる。cifar10/ は初回に CIFAR-10(約 160 MB)をダウンロードし、既定の 3 epoch で RTX 4090 なら約 4 分かかる。