Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Build Your Own ChessFly Model

You will start with a published chess program that uses a real fruit-fly brain map. Then you will build a small model of your own on top of that network’s activity.

You do not need a neuroscience background. You do not need to be a strong chess player. Chess is a game for two players, White and Black, who take turns moving pieces on an 8 by 8 board.

By the end of this notebook, you will be able to:

  1. Use the published ChessFly game and say what that game does, and does not, show.

  2. Tell the fixed pretrained network apart from the small scorer you train.

  3. Load real chess positions and the network’s numerical activity.

  4. Create a model, train it, and compare a second version on held-out positions.

  5. Say what matching a reference move does, and does not, prove.

Two programs stay fixed. The published network is the connectome and the pretrained ChessFly numbers. Playing the hosted game does not change them. Your move scorer is a new, smaller model. Its weights change only when you run a training cell in this notebook.

The hosted game and the training box each ask your browser to download the published files. This notebook does not verify that those two downloads share a cache. You may see the files load twice. The first load is about 148 MB. This notebook has not been run on DataHub yet.

0. Warmup

In the cell below, answer this question: What would a computer need, besides a diagram of a brain, before it could choose a chess move?

Add your response here:

1. Explore the published model

A connectome is a map of nerve cells and the connections among them. FlyWire published that map for one adult female fruit fly: 138,639 neurons and 15,091,983 connections. ChessFly follows that map. The assigned reading about a male fly is a different animal and a different dataset.

Here is the path of one position in the hosted game:

chess position
    → input encoder
    → connectome-based network
    → output decoder
    → move scores
    → search chooses a move

The encoder turns the board into signals. The network passes those signals along the mapped connections. The decoder turns the result into a score for each move. Search looks ahead, then the app plays one move.

Training is how those adjustable numbers were set, before you opened this notebook. Developers kept the wiring fixed and trained the numbers on millions of chess examples. Inference is using the finished numbers to answer a new position. The moves you play in the box below are inference. They do not train the model, and they do not train the scorer you will build later.

The hosted game uses its original decoder and search. The scorer you build in the later sections is a separate piece. It reads the network’s activity and scores legal moves. It does not replace the game’s decoder.

The next cell opens the hosted game. The chess calculations happen in your browser. You need an internet connection. A progress box titled Loading the fly brain shows the download. When it finishes, the Brain tab names the neuron count, the connection count, and a backend: WebGPU or JS.

WebGPU lets this game use your computer’s graphics processor for model calculations inside the browser. If the tab says JS or JS fallback, the same game ran in ordinary browser code. Write down which label you see. That label describes your computer. It is not a score for the move.

If the box stays blank, open the same game in a new tab: https://mlabonne-chessfly.static.hf.space/

Make a few moves

Wait until the loading box closes. You play White, the pieces closer to You. The model plays Black, the pieces closer to Drosophila.

  1. Click one of your white pieces.

  2. Click a highlighted square.

  3. Wait until thinking… stops. The black piece that moves is the model’s reply.

  4. Open the Moves tab if you want the written labels. You do not need to judge whether the move was good.

New game, under the Brain / Moves / About tabs, clears the board.

Predict

Before you move, write one guess: what will the model do after your first move? A guess such as “move a black pawn” is enough.

Add your response here:

Compare

Play two or three moves. In the cell below, write the reply you actually saw, and the backend label from the Brain tab (WebGPU or JS).

Add your response here:

Reflect

The hosted game is using numbers that were trained earlier. Which stage did you just perform, training or inference? What in the app tells you that?

Add your response here:

2. Load real chess positions and network activity

The file data/lichess_lab.csv has 60 real positions from public Lichess games. Stockfish, a chess engine, supplied the reference move for each position. That move is called the target. It is one strong program’s first choice, not a fact about every good move.

Each row has a job that was assigned before any training:

  • pool rows are the only rows you may train on.

  • validation rows are for comparing two versions of your scorer.

  • test rows are for one final look, after that comparison.

The next code cell prints a short preview, not all 60 rows.

The box after that runs the same published network in your browser and sends the activity to Python. Activity here means a list of numbers, one per readout neuron. A readout neuron is one of 41,692 neurons whose response the network already uses when it reads a position. Each activity feature you will choose later is one of those numbers.

This training box runs that network in ordinary browser JavaScript so Python can receive the neuron numbers. The game in the previous section can use WebGPU. This box does not. It may download the published files again.

Run the next cell, then press Load the real network in the box. Wait until the status line says that Python received the activity matrix and prints a shape. Then run the cell after the box.

If you run that cell too early, it stops and tells you to load the network first.

When the status line says Python received the activity matrix, run the next cell.

You should see a shape (60, 41692). The 60 rows are the chess positions, in the same order as the file. The 41,692 columns are readout neurons. Each number is that neuron’s response to that position.

Reflect

The shape you just printed has one column per readout neuron. Which program computed the fly network: the browser, or this Python cell?

Add your response here:

3. Inspect a chess position

A move such as f4g2 names two squares. The piece travels from the square f4 to the square g2. The letter is the column, from a to h, left to right for White. The number is the row, from 1 to 8. On the board below, White’s pieces are capital letters and sit toward the bottom.

Stockfish’s move for that position is the reference move. Other legal moves can also be reasonable. The gold outline marks the reference move’s squares.

The bars are a small slice of the activity: 12 of the 41,692 readout responses for this one position. A feature, in the next section, means one of those neuron responses, kept because it varies across your training rows.

Predict

Before any training, every score is tied, so the scorer picks the alphabetical baseline. For the position above, write that baseline move. Do you expect training on a dozen positions to match Stockfish on new positions? Why or why not?

Add your response here:

4. Create and train model_v1

Edit the training list. Use pool indexes only. Validation and test indexes are refused, and no model is created if you include one.

n_features is how many readout neurons the scorer may use. The helper keeps the neurons whose activity varies the most on your training rows only. Validation and test rows do not vote.

The scorer then gives each legal move a score. Two kinds of numbers go into that score. One kind is the activity of the neurons you kept. The other kind describes the move. Training changes only the weights that combine them. The legal move with the highest score is the prediction.

Optional note. The move description is 33 fixed numbers, and those numbers are not trained. For f4g2 they mark the start file f, the start rank 4, the end file g, the end rank 2, and a constant 1. That is 8 + 8 + 8 + 8 + 1. With 16 activity features, the new model has 16 × 33 = 528 trainable numbers, all starting at zero.

Predict

Index 3 is a validation position. What should the helper do if you add 3 to train_rows?

Add your response here:

You should see weight length 0.0000. If you asked for 16 features, you should see 528 trainable numbers. The settings printed here are stored on the model. Changing a variable later does not change this model until you create or train again.

The plots show training loss and the share of training rows whose reference move the scorer matched. They do not show validation or test results.

Running this cell again continues from the current weights. It does not start over. For a fresh fit, call reset_scorer(model_v1) or create the model again.

Optional. model_v1.weight_length is the size of the weight numbers. It is a diagnostic that the numbers changed. It is not a measure of chess play.

Reflect

Training agreement can rise while the model is still weak on new positions. What do the plots measure, and what do they leave out?

Add your response here:

5. Check validation positions

Validation rows were not used to choose features or to fit. The table shows the alphabetical baseline, your model’s move, and the Stockfish reference. Every model move should be legal on that board.

A checked fit on indexes 0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, and 13 matched the reference move on 11 of those 12 training positions and on 0 of 12 final test positions. Indexes 3, 8, and 13 are validation rows in this file, so that list is not a legal training set here. That result is a generalization problem. It is not evidence of strong chess play. Your own training and validation counts are the numbers this notebook prints. The final test is a later cell, used once.

Stockfish top-move agreement is one narrow metric. It is not a complete chess-strength assessment. A disagreement does not automatically mean a bad move. It means the scorer’s top legal move was not Stockfish’s first choice.

Reflect

Your model may agree with Stockfish on several training rows and miss validation rows. Does a training match mean the model is a strong chess player?

Add your response here:

6. Build model_v2 and compare fairly

model_v2 is a new object. Creating it does not reset model_v1.

Change exactly one stored setting: the number of features, the learning rate, or the number of rounds. The cell starts from the settings saved on model_v1, then you edit one of them. The comparison reads those saved settings, not whatever the variables say after a later edit.

Use the same training rows. The comparison table uses the validation rows, the same rows as the previous section.

If you change the learning rate or the number of rounds, the new model copies model_v1’s features and its original starting weights, then trains from that start. If you change the number of features, the new model chooses its own neurons and still starts at zero.

Running Train again on a model that already has trained weights continues training. A fair comparison needs a fresh model, or reset_scorer before the new training run.

You should see the sentence Fair comparison: only n_features differs if you left the learning rate and the round count alone and set features to 8. model_v1’s weight length should be unchanged.

Final test

The next cell is the one look at the test rows. Use it after you have chosen settings with the validation table. Going back to change the model because of this table means the test rows were used for model choice, and the number is no longer a clean final check.

Reflect

Reset cleared model_v2. What happened to model_v1? If you wanted a new fair comparison, why is resetting or creating a fresh model required?

Add your response here:

7. Optional: turn off connections in stored order

This section does not train a model. It changes connections inside the browser, then sends a new activity matrix to Python.

The button turns off the first 2,000,000 connections in stored order. That means the first 2,000,000 entries of the published weight array. It is not a named brain region or a chosen circuit. Restore writes those same numbers back. The published website is not changed.

An activity sum adds readout numbers. It is not a measure of intelligence or of chess performance.

Run the next cell first. It saves model_v1’s weights and the intact activity. Then scroll up to the fly box, press the turn-off button, and wait until the status says Python received a new activity matrix. Then run the comparison cell. After that, press Restore and run the last cell in this section.

Press Restore the first 2,000,000 connections in stored order. Wait until the status says Python received the restored activity matrix. Then run the next cell.

Reflect

Did the activity change while the scorer’s weights stayed fixed? After restore, did the activity come back? What does an activity sum tell you, and what does it leave out?

Add your response here:

8. Reflection and sources

Answer in the cell below.

  1. In the hosted game, which part was training and which part was inference?

  2. Your scorer can match training rows and miss new rows. What does that say about generalization?

  3. ChessFly uses a female fruit fly’s connectome. The assigned article is about a male fly. What can a connectome-based chess model establish about a living fly, and what can it not establish?

Add your response here:

Sources

  • ChessFly model card and weights: huggingface.co/mlabonne/chessfly. The hosted game and the training box load files from mlabonne-chessfly.static.hf.space. If the game box stays blank, open that link directly.

  • The wiring is the FlyWire reconstruction of an adult female fruit fly brain, CC BY-NC 4.0. Activity is computed in the browser and is not saved in this folder.

  • The assigned Google article is a different map, a male fly brain and nerve cord: Januszewski and Jain, Google Research Blog, 3 September 2026.

  • Positions and Stockfish reference moves: Lichess/chess-position-evaluations, CC0. How data/lichess_lab.csv was built and split is in data/README.md.

  • Helper code: fly_scorer.py trains the scorer, fly_board.py draws a position, and fly_activity.py is the browser handoff. The two earlier notebooks, ChessFly_DataHub_prototype.ipynb and ChessFly_train_readout_prototype.ipynb, are still in this folder.