💡 Examples¶
Working programs that show how to use Mujou, in examples/ of the repository. The pages of this site include them as they are, so the code shown is the code you can run. They are guides, not tests: the test suite does not run them.
By what you want to do¶
| What you want to do | Program | Explained in |
|---|---|---|
| Run something, anything | quickstart.py |
1. Run a Network |
| Branch a network and merge it again | branching.py |
1. Run a Network, Ports and Channels |
| Write a node whose state changes in continuous time | leaky.py |
2. Write a Node |
| Test a node deterministically | test_leaky.py |
3. Test a Node |
| Keep learning from a stream, with BP inside a node | online_learning.py |
4. Learn in a Node |
| Learn across nodes with a rule of your own | feedback_alignment.py |
Update Rules |
| Learn a regression with PC-ALM, in a few lines | pc_regression.py |
5. Learn with PC-ALM |
| Write a node of PC-ALM of your own (with two inputs) | pc_merge.py |
PC-ALM |
| Learn MNIST with PC-ALM, and compare it with BP | mnist/ |
PC-ALM |
| Learn CIFAR-10 with a ResNet on the GPU, and compare it with BP | cifar10/ |
PC-ALM |
| Save the state and resume from it | save_and_restore.py |
6. Save and Resume |
| Run several networks together | group.py |
Groups |
| Follow every new output (values in between may be skipped) | subscribe.py |
Host I/O |
| Use a timer of a run's own, a time scale, or pause several runs | timers.py |
Time |
| See what happens when a node raises | errors.py |
Errors and Shutdown |
| Draw the graph of a network, and open it in a browser | visualize.py |
Visualize a Network |
What each program shows¶
quickstart.py: a two-node network, run withwith mujou.run(...). The host writes an input withwrite, and waits withwait_foruntil the expected output arrivesbranching.py: aPortthat only sends, connected to two branches that aMultiPortmerges; and aMultiPortthat sends a different value to each peer withsend_to, on the channelsconnectreturnedleaky.py: the leaky integrator, a node defined in continuous time and advanced by the exact solution, so that it is stable for anydt. Run, it steps the input of two in a row and compares them with the exact solution at the time each output was senttest_leaky.py: tests of the node ofleaky.pywithmujou.testing, on a virtual timer with manual steps: against the exact solution, bit for bit against the discrete algorithm, and a resumed run against one that did not stop. Run them withuv run pytest examples/test_leaky.pyonline_learning.py: a teacher sends batches from y = a x + b with theathe host writes and changes; a learner learns from each new batch with plain PyTorch autograd, for the time since the last one, and the host follows its loss as it falls, jumps and falls againfeedback_alignment.py: two nodes learn a two-layer network by feedback alignment: two-way ports, a target relayed with the activity, a learning step once per sample withpc.clock.LearnClockpc_regression.py:pc.Chainandpc.showlearn a regression from a stream of batches, measured before each batch is learned frompc_merge.py:Merge, a node of PC-ALM with two inputs written withpc.functionalandpc.clock.LearnClock, joins two towers that learn a regressionmnist/: a 784-256-256-10 network learns MNIST as apc.Chain, and the same network learns by BP from the same initial weights on the same batches.main.pyis the entry point,data.pyloads the data,metrics.pymeasures,bp.pytrains the BP baseline andwatch.pycounts thedtof the nodes (--watch)cifar10/: a ResNet-20 on a CUDA device, with a node for each stage, learns CIFAR-10 as apc.Chainwithpc.optim.AdamW, and the same network learns by BP on the GPU from the same initial weights on the same batches with the same optimizer.main.pyis the entry point,data.pyloads and augments the data,resnet.pybuilds the network and says why it is cut into few nodes,metrics.pymeasures andbp.pytrains the BP baselinesave_and_restore.py: takes the state withrun.state_dict(), saves it withtorch.save, and resumes it in a new instance withmujou.run(..., state=...), on a timer of the resumed run's owngroup.py:Group(enc=..., dec=...), and the paths of the nodes ("enc.scale")subscribe.py:run.subscribeyields the latest output, then each newer one, and stops withbreaktimers.py:Timestamp, aTimerof a run's own at a time scale, the scale of the global timer, and pausing the global timer to take the states of two runs at one time; a run resumed from one goes on on a timer of its ownerrors.py: theNetworkErrorthe host receives and its__cause__, the orderon_exception→on_stop, andmujou.runraising for an exception inon_startvisualize.py:mujou.viz.to_htmlwrites the page of a network of two networks and a node, and of apc.Chain, without running them
How to run them¶
Run them from the root of the repository, in an environment built from source (see Installation).
uv run python examples/quickstart.py
uv run python examples/mnist/main.py
uv run python examples/cifar10/main.py
Only cifar10/ uses a GPU, and needs CUDA. Each finishes within 15 seconds, except mnist/ and cifar10/. mnist/ downloads MNIST (about 11 MB) on its first run, and its defaults (3 epochs) take about 2 minutes. cifar10/ downloads CIFAR-10 (about 160 MB) on its first run, and its defaults (3 epochs) take about 4 minutes on an RTX 4090.