phclab's picture
CentralComplex_Chess v1
def2f12 verified
|
Raw History Blame Contribute Delete
5.99 kB
---
license: cc-by-nc-4.0
tags:
- chess
- spiking-neural-network
- connectome
- drosophila
- rsnn
---
# CentralComplex_Chess v1
Synaptic weights for the central complex opponent of **[BeatTheFly](https://phclab.github.io/BeatTheFly/chess/)** -- *A Smart Fruit Fly is playing chess against you*:
a spiking network wired as the real *Drosophila* central complex connectome that plays chess.
**The anatomical connectome gives you wiring, not synaptic strengths. Ours are trained.**
Synaptic weights trained with PHCSSM parallel-scan mode, deployment in sequential RSNN mode ([PHCSSM](https://arxiv.org/abs/2604.01295)).
made by Po-Han Chiang @ NYCU
## What the central complex does in the fly
In the real fly, the central complex keeps track of heading with a ring-shaped “internal compass”, integrates the path travelled, and steers where the fly goes next.
## Architecture
* **Wiring:** MaleCNS v1.0 central complex -- 2,950 neurons (Ring neurons (ER, ExR) 308; PFN columnar neurons 456; PFL output neurons 50; Other central-complex neurons 2,136) and 439,500
neuron-to-neuron connections. The connectivity mask is fixed to the connectome; 338,477 connections
carry a nonzero weight and 0 weights lie off the connectome.
* **Dale's law:** one sign per presynaptic neuron from predicted neurotransmitters (excitatory 1,873,
inhibitory 918, modulatory 159); 0 weights violate it.
* **Inputs:** each ply provides the move token (one of 1,970 UCI moves) and the board after it (789
binary features: piece per square, castling rights, en-passant file, 50-move-clock buckets, seen from the side to move).
Two linear encoders with their own LayerNorm drive only the input population: 764 ring neurons (ER, ExR) and PFN columnar neurons.
* **Neurons:** leaky integrate-and-fire with per-neuron leak, threshold and reset; synaptic delay of one step.
* **Readout:** linear map from the membrane voltage of the output population only: 50 PFL1, PFL2 and PFL3 steering neurons.
* **No dopamine gate and no fast weight** (those belong to the mushroom body).
* **Deployment:** sequential RSNN mode, one timestep per ply, with the neuron state carried across the whole game.
## Data sources
Data source: human games from the [Lichess open database](https://database.lichess.org/) (lichess.org, CC0).
## Evaluation
4,000 held-out Lichess blitz games (1500–1800), compared with the move the human played:
| | overall | opening | early middlegame | middlegame | endgame |
|---|---|---|---|---|---|
| top readout move = human move | 16.7% | 39.3% | 25.8% | 13.2% | 8.4% |
| top readout move is legal | 73.9% | 95.6% | 90.1% | 78.4% | 59.1% |
| move-match, readout restricted to legal moves (as played on the page) | 21.9% | 41.0% | 28.4% | 16.8% | 16.6% |
**Strength:** Plays about as well as a random mover (30–148–22 against random legal moves); loses to a simple material-greedy bot (0–19–181) and to Stockfish at its lowest level. Matches: 200 games per opponent, colours swapped, argmax play.
## Files
* `manifest.json` -- every tensor (file, dtype, shape, bytes), the model scalars and a connectome audit.
* `info.json` -- neuron metadata used by the page (cell classes, hemispheres, soma coordinates).
* `selfcheck_<precision>.json` -- reference moves and logits that the page replays when it loads.
* `chess_uci_vocab.json` -- the move vocabulary.
* `fp16/`, `fp32/` -- raw little-endian arrays.
Two precisions are listed in the manifest: `fp16w32` (default, 18.6 MB: float16 for the
large dense matrices, float32 for the recurrent weights and all small tensors) and
`fp16` (18.0 MB, recurrent weights in float16 as well).
The recurrent weight matrix W[dst, src] is stored in CSC order by source neuron (`W_colptr`, `W_rowidx`, `W_vals`):
each step multiplies W by a sparse binary spike vector, so the engine visits only the columns of the neurons that
spiked. `in_idx` lists the input population and `out_idx` the output population. Dense matrices are stored in the
orientation they are read: `enc_tok_T` [vocab, H] (a move token selects one row), `enc_brd_T` [789, H] (sum of
the active rows) and `dec_w` [vocab, 50] (read against the output population's voltage).
| name | file | dtype | shape |
|---|---|---|---|
| `enc_tok_T` | `fp16/enc_tok_T.bin` | float16 | 1970x2950 |
| `enc_tok_b` | `fp32/enc_tok_b.bin` | float32 | 2950 |
| `ln_tok_w` | `fp32/ln_tok_w.bin` | float32 | 2950 |
| `ln_tok_b` | `fp32/ln_tok_b.bin` | float32 | 2950 |
| `enc_brd_T` | `fp16/enc_brd_T.bin` | float16 | 789x2950 |
| `enc_brd_b` | `fp32/enc_brd_b.bin` | float32 | 2950 |
| `ln_brd_w` | `fp32/ln_brd_w.bin` | float32 | 2950 |
| `ln_brd_b` | `fp32/ln_brd_b.bin` | float32 | 2950 |
| `dec_w` | `fp16/dec_w.bin` | float16 | 1970x50 |
| `dec_b` | `fp32/dec_b.bin` | float32 | 1970 |
| `alpha_exc` | `fp32/alpha_exc.bin` | float32 | 2950 |
| `alpha_inh` | `fp32/alpha_inh.bin` | float32 | 2950 |
| `v_th` | `fp32/v_th.bin` | float32 | 2950 |
| `reset_weight` | `fp32/reset_weight.bin` | float32 | 2950 |
| `in_idx` | `fp32/in_idx.bin` | int32 | 764 |
| `out_idx` | `fp32/out_idx.bin` | int32 | 50 |
| `W_colptr` | `fp32/W_colptr.bin` | uint32 | 2951 |
| `W_rowidx` | `fp32/W_rowidx.bin` | uint16 | 338477 |
| `W_vals` | `fp32/W_vals.bin` | float32 | 338477 |
**Numerical check:** legal top-1 1965/1973 vs the fp32 reference (24 held-out games); 0 of 5,838,050 spike bits differ from the reference on the same weights.
## Limitations
There is no search and no evaluation function: each move is a single timestep of the network, restricted to legal
moves on the page.
## License and attribution
Weights: [CC-BY-NC-4.0](https://creativecommons.org/licenses/by-nc/4.0/). They are derived from the MaleCNS v1.0 connectome (Janelia FlyEM and
collaborators, https://male-cns.janelia.org/, [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/)) and trained with PHCSSM (https://arxiv.org/abs/2604.01295);
please credit both.
## Citation
PHCSSM: https://arxiv.org/abs/2604.01295