A physical computational device that performs Artificial Neural Network calculations through mechanical manipulation---think "abacus for deep learning". This project combines digital tools for fabrication, machine learning infrastructure for weight generation, and educational documentation to create a tangible interface for understanding AI.
A Cybernetic Studio project by Ben Swift, with fabrication support from Sam Shellard at UC's Workshop7.
The concentric rings encode the network---input values, weights, and activations are set and read by sliding the brass markers along laser-cut tracks:
| Top-down view of the computation rings | Setting values by hand |
|---|---|
![]() |
![]() |
Photographs by Andrew Meares.
This monorepo has two peer components:
- Elixir (root): fabrication SVG generation via Ash resources, ML training (Axon/MNIST/poker), and weight export to JSON
- TypeScript (
js/): NPM package providing a digital twin---browser SVG generation, computation animation, and interactive input widgets
Shared resources live at the root: docs/ for Typst templates and ML
documentation, svg/ for generated output, and mise.toml as a unified task
runner.
This project uses mise to manage runtimes (Elixir, Erlang, Node, pnpm). Install mise, then:
mise install # install runtimes
mix deps.get # fetch Elixir dependencies
cd js && pnpm install # install TS dependenciesUnified tasks from the project root:
mise run test # run all tests (Elixir + TS)
mise run build # build all packages
mise run lint # lint TS package
mise run check # type-check TS packageThe easiest way to generate apparatus SVG files is using the Mix tasks:
# Generate with default parameters (1200mm, 36-6-10 network)
mix perceptron
# Custom configuration
mix perceptron --size 1150 --input 36 --hidden 6 --output 10
# Save to specific location
mix perceptron --file /path/to/output.svg
# Include QR code
mix perceptron --qr "https://example.com"
# Use presets (mnist, xor, language)
mix perceptron.generate --preset mnist
# Show help
mix perceptron --help
Once you've built the physical apparatus, you need to train a neural network model and export the weights to set on the radial rings B (input→hidden) and D (hidden→output).
# Train an MNIST model (36x6x10 network) and export weights to JSON
mix perceptron.export_weights
# Custom training parameters
mix perceptron.export_weights --epochs 10 --batch-size 256
# Save to specific file with scaling to apparatus range (±5.0)
mix perceptron.export_weights --output mnist-weights.json --scale --target-max 5.0The MNIST implementation:
- resizes 28×28 MNIST digit images to 6×6 (36 input features)
- trains a 36→6→10 MLP (36 inputs, 6 hidden neurons with ReLU, 10 outputs)
- exports weights to JSON format compatible with Typst and the physical apparatus
For detailed documentation, see docs/mnist-mlp.md.
# Train a poker hand classification model and export weights
mix perceptron.export_poker_weights
# Custom training parameters
mix perceptron.export_poker_weights --epochs 10 --batch-size 256
# Save to specific file with scaling
mix perceptron.export_poker_weights --output poker-weights.json --scale --target-max 5.0The poker hand implementation:
- encodes 5-card poker hands into 36 features (suit + rank bins per card)
- classifies hands into 10 categories (high card, pair, two pair, etc. up to royal flush)
- trains on the UCI Poker Hand dataset (25,010 training samples)
- exports weights to JSON format
For detailed documentation, see docs/poker-mlp.md.
# Create a neural network apparatus for a 25-5-10 network
{:ok, apparatus} = PerceptronApparatus.Board.create(1200.0, 25, 5, 10)
# Render to SVG
svg_output = PerceptronApparatus.Board.render(apparatus)
File.write!("apparatus.svg", svg_output)The js/ package is published as perceptron-apparatus and provides three
entry points:
// SVG generation and animation
import { PerceptronApparatus } from "perceptron-apparatus";
// In-browser MNIST training
import { trainMnist } from "perceptron-apparatus/training";
// Interactive widgets (MNIST input grid, poker hand selector, animator)
import {
MnistInputWidget,
ComputationAnimator,
} from "perceptron-apparatus/widgets";This automatically creates the complete ring sequence:
- Log ring - logarithmic scale ruler
- ReLU ring - ReLU activation function ruler
- Input azimuthal ring - input sliders (0-1 range)
- Weight1 radial ring - input-to-hidden weight sliders (-10 to 10 range)
- Hidden azimuthal ring - hidden layer sliders (0-10 range)
- Weight2 radial ring - hidden-to-output weight sliders (-10 to 10 range)
- Output azimuthal ring - output sliders (0-1 range)
The ring dimensions automatically match the neural network topology:
- Input ring has
n_inputsliders - Weight1 ring has
n_hiddengroups ×n_inputsliders per group - Hidden ring has
n_hiddensliders - Weight2 ring has
n_outputgroups ×n_hiddensliders per group - Output ring has
n_outputsliders
The physical apparatus consists of concentric rings representing different layers and operations in a neural network:
- Log ring: logarithmic scale ruler for slide rule calculations
- ReLU ring: ReLU activation function reference
- Input azimuthal ring (A): input sliders (0-1 range)
- Weight1 radial ring (B): input-to-hidden weight sliders (-10 to 10 range)
- Hidden azimuthal ring (C): hidden layer sliders (0-10 range)
- Weight2 radial ring (D): hidden-to-output weight sliders (-10 to 10 range)
- Output azimuthal ring (E/G): output sliders (0-1 range)
The apparatus performs matrix multiplication and ReLU activation through manual manipulation of these rings, making the computation physically tangible.
A board contains a number of rings, each of which represents a layer in the (MLP) neural network.
SVG classes represent different cut types:
top plate class selectors
top fullfull-depth cutstop sliderfull-depth routed channels for sliderstop etchlight v-cut etchestop etch.heavyheavier v-cut etchestop holefull-depth holes (for screws)
bottom plate class selectors
bottom sliderpartial-depth routed channels (for captive slider/ring bottoms)bottom rotatingpartial-depth routed void for bottom rotating ringbottom holefull-depth holes (for screws)
The project includes Typst templates for generating educational materials:
- Apparatus posters: display trained weights alongside usage instructions
(see
docs/mnist-poster.typanddocs/poker-poster.typ) - Interactive worksheets: blank grids for drawing inputs with step-by-step
algorithm guides (see
docs/grid-and-instructions.typ) - Technical documentation: detailed explanations of the MNIST and poker
implementations (see
docs/mnist-mlp.mdanddocs/poker-mlp.md)
These materials make the apparatus accessible for educational demonstrations and public engagement.
If you use the Perceptron Apparatus, please cite it. Machine-readable citation
metadata lives in CITATION.cff; GitHub's "Cite this
repository" button turns it into APA or BibTeX.
(c) 2024 Ben Swift, with fabrication support from Sam Shellard (Workshop7, University of Canberra).
This project is dual-licensed:
- code (Elixir, TypeScript, and build tooling) under the MIT licence
- documentation, fabrication designs, and educational materials (
docs/, generated SVGs, posters, and worksheets) under Creative Commons Attribution 4.0 International (CC-BY-4.0)


