A NEAT (Neuroevolution of Augmenting Topologies) implementation written in TypeScript, with a UI built with SvelteKit.
Includes 3 demos: Pole balancing (inverted pendulum), Flappy Bird, and bipedal walker.
- Pole balancing:
- Flappy Bird:
- Bipedal walker:
- User interface:
This project evolves fixed-size feed-forward neural networks via natural selection and random mutation of weights/biases.
This is a slight change from the approach that Stanley and Miikkulainen describe in their paper, which mutates by adding edges and vertices to a child graph.
In practice, this change likely negatively impacts learning rate. However, the included demos are simple enough that this approach solves them relatively quickly.
A single vertex in a network. Stores a bias and an array of weights corresponding to each ancestor vertex.
A single layer in a network. Stores an array of nodes, and provides a function for feeding an array of inputs forward through the graph.
A directed graph. Provides functions for crossing over (breeding) with another parent and mutating. A mutation can be one of four types: Set (i.e. weight = val
), add (i.e. weight += val
), disable (i.e. weight = 0
), and invert (i.e. weight *= -1
).
A linearized encoding of a Network. Helps with crossover and mutation.
A single member of a species. Contains a name, a fitness, and a network.
A collection of organisms. Contains a name, as well as helpful information regarding the best performing member of the species.
The main class for performing learning. To create a custom demo, first construct a new class with new NEAT(...)
. Then in a continuous loop, call neat.compete(() => { ... })
and neat.breed()
.