Machine learning benchmark · two brains, one search
The neural network wins.
The engine can judge positions two ways: with classic rules written and tuned by hand, or with a neural network that learned from 1.5 million positions the engine played against itself. We had them play each other 3,000 times, with the same thinking time.
± 13, 3,000 games
1,955 wins, 1,020 losses
average final margin
than the network's first version
3,000 games, same clock
Every deal was played twice with the seats swapped, so neither side got the luckier tiles. 40 ms per move.
- Neural network won 1,955
- Shared 25
- Classic won 1,020
Speed is strength
A network judges better than hand-written rules but costs more per position, so in the same time it looks at fewer of them. Its first version took 2,161 ns per position against the classic engine's 309. Running its first layer the way chess engines do, updating only the inputs a move changes, in exact integer arithmetic, brought that to 704 ns: the same network gained almost 50 Elo. Elo over the classic engine at 40 ms per move; lines show the 95% range.
Fast enough to use what it knows
Before the speed-up the bigger network was too slow to use its knowledge: +6 at equal time. Now each network plays about as well at equal time as at equal positions. Head to head, 128 × 32 and 64 × 16 tie (−10 ± 12 over 3,000 games), so the board keeps the smaller, lighter one.
- Equal positions: what it knows
- Equal time: how it plays
What it sees matters most
Given only the board, the network merely tied. Showing it the board as it would look if the round were scored now was worth 150 Elo.
What it learns from
Learning half from the search's opinion and half from who actually won beat either alone.
How it was built
- Play. The classic engine played 30,000 games against itself; every position became a row of 170 numbers with what happened next.
- Learn. A network with two small hidden layers learned to predict the final score margin. It was trained twice: from scratch in plain Go (no libraries), and with PyTorch on a GPU.
- Plug in. The network replaces the hand-written judgement inside the same search, so the only difference between the two engines is the brain.
- Speed up. Consecutive positions in a search differ by a move or two, so the network's first layer is updated rather than recomputed, in integers so it never drifts. Three times faster, exactly the same answers.
- Prove it. Thousands of games at equal positions and at equal time, every deal played from both seats.
| Go, CPU | PyTorch, RTX 5070 | |
|---|---|---|
| Training time, 64 × 16 | 19 s | 24 s |
| Training time, 128 × 32 | 42 s | 22 s |
| Validation error (points²) | 153.0 | 153.2 |
| Elo at equal time, 64 × 16 (first version) | +66 ± 24 | +64 ± 24 |
The two agree to the decimal, which checks the hand-written training. A network this small is too little work per step for the GPU to pay off; it only pulls ahead on the bigger one.
Which should you use?
Neural network
The stronger player, and the default. Use it when you want the best move.
Classic
Every term is a readable rule you can look up. Use it to see how a hand-built judgement thinks, or to compare the two on a position.
Try both on the board Read the dev log Technical write-up and code
All the numbers
| Experiment | Games | Elo vs classic |
|---|---|---|
| 64 × 16, 40 ms per move (the board's brain) | 3,000 | +112 ± 13 |
| 64 × 16, 200 ms per move | 400 | +111 ± 36 |
| 128 × 32, 40 ms per move | 800 | +135 ± 26 |
| 128 × 32 against 64 × 16, 40 ms per move | 3,000 | −10 ± 12 |
| First version, 64 × 16, 40 ms / 200 ms per move | 3,000 / 400 | +64 ± 13 / +110 ± 35 |
| First version, 32 × 16, equal positions / equal time | 800 / 800 | +96 ± 25 / +62 ± 24 |
| First version, 64 × 16, equal positions / equal time | 800 / 800 | +114 ± 25 / +66 ± 24 |
| First version, 128 × 32, equal positions / equal time | 3,000 / 800 | +141 ± 13 / +6 ± 24 |
| Board only, 128 × 32, equal positions | 400 | −7 ± 34 |
| Target: search value only | 400 | −127 ± 36 |
| Target: outcome only | 400 | −84 ± 35 |
| Target: 25% value, 75% outcome | 400 | −63 ± 34 |
| Target: half and half | 400 | −7 ± 34 |
Equal positions: both sides search 20,000 positions per move. Ranges are 95% confidence. Every result is reproducible with the commands in the write-up.