Width and depth change a network in different ways.
Every neuron receives values from the preceding layer, multiplies them by learned weights, adds a bias, and applies the activation function. “More neurons” and “more layers” both increase capacity, but they do not add the same kind of capacity.
Input layer · 4 neurons
What the bird can observe
Height
The bird’s vertical position. It is normalized from −1 at the ceiling to +1 at the ground.
Velocity
How quickly the bird is moving vertically. Negative means rising; positive means falling.
Distance
The horizontal distance from the bird to the left edge of the next pipe, scaled to the canvas width.
Gap
The vertical position of the next pipe opening’s center, normalized to the same −1…+1 range as height.
Output layer · 1 neuron
One decision: jump
The output neuron uses sigmoid to produce a value between 0 and 1. When it rises above 0.52, the bird jumps; otherwise gravity continues pulling it down.
This is a direct action score, not a prediction of height or distance. The live brain highlights the output whenever the jump threshold is crossed.
Width
More neurons in a layer
Gives that layer more parallel detectors. Several neurons can specialize in different situations—for example: falling quickly, approaching a gap from below, or already being safely centered.
Depth
More hidden layers
Adds stages of reasoning. Later layers can combine patterns found by earlier layers, building a more composed rule before the final flap decision.
Reading a shape
4 → 6 → 1 means four observations, six hidden neurons, and one flap probability. Entering 4 3 2 creates three hidden layers: 4 → 4 → 3 → 2 → 1.
The genome grows differently
Changing 4 → 4 → 1 to 4 → 8 → 1 adds width and grows the genome from 25 to 49 genes. Adding depth with 4 → 4 → 3 → 2 → 1 creates 46 genes.
Why more is not always better
Extra capacity can express subtler strategies, but evolution must discover and preserve more useful weights. With only four inputs and one decision, Flappy Bird often needs a small network rather than the largest one.
Width adds parallel detectors. Depth adds successive stages. Every added connection or bias becomes another gene evolution must search.
Parent selection
Selection controls which behaviors survive indirectly.
The algorithm never edits a bird because it made a mistake. It only changes how likely each completed network is to become a parent. Stronger pressure exploits current winners; weaker pressure preserves diversity.
Tournament
Sample four birds at random and keep the best. Repeat whenever a parent is needed. It strongly favors good birds without letting one score monopolize every child.
Fitness proportionate
Give each bird a probability equal to its share of total fitness. A bird with twice the fitness receives roughly twice the chance, so outliers can dominate.
Rank based
Sort birds first, then assign probability by position instead of raw score. The distance between scores no longer matters, producing steadier pressure.
Animate
Choose a method above. Each parent moves through sample, evaluate, and add-to-pool stages before the next draw begins.
Genome crossover
Crossover builds a child from two complete networks.
Weights and biases are flattened into a genome. Both parents share the same architecture, so corresponding positions describe the same connection. Crossover combines those positions before mutation.
Uniform
Flip a coin at every gene. This explores many combinations, but can separate groups of weights that only work well together.
One point
Choose one split and copy the left side from one parent and the right side from the other. Blocks remain intact, although the split ignores network boundaries.
Average
Set every child gene halfway between both values. Changes are smooth and conservative, but an especially useful extreme value may be diluted.
Animate
Choose a method above. Each child pauses while its parents are chosen and its genes are combined.
Mutation
Mutation introduces values that neither parent contained.
After crossover, every gene receives an independent chance to change. Selected genes receive Gaussian noise, so small changes are common and large jumps are possible but rare.
if random() < rate: gene′ = gene + Normal(0, strength)
Mutation rate
The percentage of weights and biases changed in each child. At 10%, a 100-gene network changes about ten genes on average.
Mutation strength
The standard deviation of the added noise. At 0.36, roughly two thirds of changes lie between −0.36 and +0.36.
Exploration versus preservation
Too little can freeze the population around a mediocre strategy. Too much destroys useful inherited structure and approaches random search.
Every child now pauses while its genes are tested, changed, and added to the mutated population. The current mutation rate and strength are shown in the animation.
Activation functions
Activation decides how a neuron responds to its weighted input.
Without an activation function, stacked layers collapse into one linear transformation. Nonlinearity lets the network express rules such as “flap only when low, falling, and near a pipe.”
Tanh
Maps values to −1…1. It is smooth and zero-centered, making positive and negative internal signals natural. Large inputs saturate near the limits.
ReLU
Returns zero below zero and the original value above it. It does not saturate positively, but a neuron receiving only negative inputs becomes inactive.
Sigmoid
Maps values to 0…1. It is interpretable as a gate but not zero-centered and becomes insensitive at both extremes. The final output always uses sigmoid so it represents a flap probability.
The same input produces different ranges and sensitivities.
Fitness function
Fitness defines what evolution considers successful.
A genetic algorithm can only optimize the number it receives. The current function rewards surviving every frame and adds a much larger step whenever the bird clears a pipe.
fitness = survival frames + (pipes passed × 480)
Why reward survival
Early random birds may clear no pipes. One point per frame still distinguishes immediate crashes from behavior that approaches the first gap.
Why add 480 per pipe
At 60 steps per second, a pipe is worth eight seconds of survival. Clearing obstacles therefore dominates merely hovering safely.
Example and limitations
A bird surviving 300 frames and clearing two pipes earns 300 + 2 × 480 = 1,260. There is no gap-centering reward, flap penalty, or death penalty.
Fitness rises gradually with time and jumps by 480 whenever a pipe is cleared.
Optimization outside the model
Hyperparameter optimization searches for a better learning setup.
Evolution learns the network’s weights and biases. Hyperparameter optimization sits one level above that process: it runs several complete experiments with different settings, then compares how well those settings generalize.
Learned parameters
Weights and biases
These values live inside each brain. Selection, crossover, and mutation change them throughout a run.
Hyperparameters
The rules of the run
Architecture, activation, selection, crossover, mutation rate, and mutation strength are chosen before evolution begins.
best setup = arg max mean unseen fitness(setup, evaluation seeds)
Define a fair objective
Compare configurations using the same population size, generation budget, and held-out pipe seeds. One lucky run is not enough; average several independent runs.
Choose a search strategy
Grid search checks a fixed lattice. Random search samples combinations and often covers large spaces more efficiently. Adaptive methods use earlier trials to decide which settings to test next.
Avoid optimizing the test set
Use training runs to evolve weights, validation runs to choose hyperparameters, and a final untouched test set to estimate performance. Reusing the test set simply moves overfitting up one level.
Every dot is a full evolutionary run. The best-so-far line improves only when a trial generalizes better than all previous trials.
Model compression
Pruning removes connections the trained network can live without.
A dense network gives every neuron every possible incoming connection. After training, many weights may contribute little. Pruning sets selected weights to zero, creating a smaller effective network whose behavior should be measured again.
prune connection if |weight| < threshold
Magnitude pruning
Remove weights closest to zero first. It is simple and often effective, but magnitude is only a proxy: a small weight can still matter when its input is large.
Unstructured versus structured
Unstructured pruning removes individual connections. Structured pruning removes whole neurons or layers, producing a network that is easier to make genuinely smaller and faster.
Prune, evaluate, recover
Prune gradually, test on held-out pipe patterns, then allow a short recovery evolution. Stop when additional sparsity causes an unacceptable performance drop.
A useful pruning point removes many connections while remaining before the sharp performance collapse.
Generalization
Overfitting is learning the example instead of the rule.
A network can become excellent on the situations it repeatedly sees while becoming worse at unfamiliar ones. Training performance alone cannot reveal this—the model must be evaluated on data or environments that were not used to evolve it.
The repeating environment
Training uses one seeded sequence of five pipe heights, repeated forever. Evolution can gradually exploit the order and timing of that exact loop.
The unseen environment
Testing freezes the best trained brain and replaces the loop with genuinely random pipe heights. No further selection, crossover, or mutation occurs during the test.
The generalization gap
If the fixed-pattern score keeps improving while the unseen-pattern score stalls or falls, the growing difference is evidence of overfitting.
The useful point is not the highest training score—it is the point where performance on unseen situations is strongest.
Separate experimentReady
This simulator has its own population and state. It does not replace or reset the random-environment simulation. It uses a snapshot of the current architecture and evolution parameters when training begins.
Start training to evolve on the repeating five-pipe sequence.
ModeReady
Generation—
Alive—
Best score0
Speed
Run at least one training generation to unlock the test.
TODO
Turn this toy example into a rigorous overfitting measurement.
Evaluate the saved brain on several held-out random seeds and compare the average score, rather than drawing a conclusion from one potentially easy or difficult test.
Plot measured training fitness and held-out fitness after every generation, replacing the illustrative curve above with results from the running experiment.
Clarify what is being learned: this feed-forward brain sees the next gap height directly, so it can overfit the limited training situations but cannot explicitly memorize the five-pipe order.