Skip to content

💡 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 with with mujou.run(...). The host writes an input with write, and waits with wait_for until the expected output arrives
  • branching.py: a Port that only sends, connected to two branches that a MultiPort merges; and a MultiPort that sends a different value to each peer with send_to, on the channels connect returned
  • leaky.py: the leaky integrator, a node defined in continuous time and advanced by the exact solution, so that it is stable for any dt. Run, it steps the input of two in a row and compares them with the exact solution at the time each output was sent
  • test_leaky.py: tests of the node of leaky.py with mujou.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 with uv run pytest examples/test_leaky.py
  • online_learning.py: a teacher sends batches from y = a x + b with the a the 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 again
  • feedback_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 with pc.clock.LearnClock
  • pc_regression.py: pc.Chain and pc.show learn a regression from a stream of batches, measured before each batch is learned from
  • pc_merge.py: Merge, a node of PC-ALM with two inputs written with pc.functional and pc.clock.LearnClock, joins two towers that learn a regression
  • mnist/: a 784-256-256-10 network learns MNIST as a pc.Chain, and the same network learns by BP from the same initial weights on the same batches. main.py is the entry point, data.py loads the data, metrics.py measures, bp.py trains the BP baseline and watch.py counts the dt of the nodes (--watch)
  • cifar10/: a ResNet-20 on a CUDA device, with a node for each stage, learns CIFAR-10 as a pc.Chain with pc.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.py is the entry point, data.py loads and augments the data, resnet.py builds the network and says why it is cut into few nodes, metrics.py measures and bp.py trains the BP baseline
  • save_and_restore.py: takes the state with run.state_dict(), saves it with torch.save, and resumes it in a new instance with mujou.run(..., state=...), on a timer of the resumed run's own
  • group.py: Group(enc=..., dec=...), and the paths of the nodes ("enc.scale")
  • subscribe.py: run.subscribe yields the latest output, then each newer one, and stops with break
  • timers.py: Timestamp, a Timer of 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 own
  • errors.py: the NetworkError the host receives and its __cause__, the order on_exception → on_stop, and mujou.run raising for an exception in on_start
  • visualize.py: mujou.viz.to_html writes the page of a network of two networks and a node, and of a pc.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.