description: Documentation of the Neuro-evolution of Augmenting Topologies technique in Neataptic authors: Thomas Wagenaar keywords: neuro-evolution, NEAT, genetic=algorithm The built-in NEAT class allows you create evolutionary algorithms with just a few lines of code. If you want to evolve neural networks to conform a given dataset, check out [this](https://github.com/wagenaartje/neataptic/wiki/Network#functions) page. The following code is from the [Agario-AI](https://github.com/wagenaartje/agario-ai) built with Neataptic. ```javascript /** Construct the genetic algorithm */ function initNeat(){ neat = new Neat( 1 + PLAYER_DETECTION * 3 + FOOD_DETECTION * 2, 2, null, { mutation: methods.mutation.ALL popsize: PLAYER_AMOUNT, mutationRate: MUTATION_RATE, elitism: Math.round(ELITISM_PERCENT * PLAYER_AMOUNT), network: new architect.Random( 1 + PLAYER_DETECTION * 3 + FOOD_DETECTION * 2, START_HIDDEN_SIZE, 2 ) } ); if(USE_TRAINED_POP) neat.population = population; } /** Start the evaluation of the current generation */ function startEvaluation(){ players = []; highestScore = 0; for(var genome in neat.population){ genome = neat.population[genome]; new Player(genome); } } /** End the evaluation of the current generation */ function endEvaluation(){ console.log('Generation:', neat.generation, '- average score:', neat.getAverage()); neat.sort(); var newPopulation = []; // Elitism for(var i = 0; i < neat.elitism; i++){ newPopulation.push(neat.population[i]); } // Breed the next individuals for(var i = 0; i < neat.popsize - neat.elitism; i++){ newPopulation.push(neat.getOffspring()); } // Replace the old population with the new population neat.population = newPopulation; neat.mutate(); neat.generation++; startEvaluation(); } ``` You might also want to check out the [target-seeking project](https://github.com/wagenaartje/target-seeking-ai) built with Neataptic. ## Options The constructor comes with various options. The constructor works as follows: ```javascript new Neat(input, output, fitnessFunction, options); // options should be an object ``` Every generation, each genome will be tested on the `fitnessFunction`. The fitness function should return a score (a number). Through evolution, the genomes will try to _maximize_ the output of the fitness function. Negative scores are allowed. You can provide the following options in an object for the `options` argument:
popsize Sets the population size of each generation. Default is 50.
elitism Sets the elitism of every evolution loop. Default is 0.
provenance Sets the provenance of the genetic algorithm. Provenance means that during every evolution, the given amount of genomes will be inserted which all have the original network template (which is Network(input,output) when no network option is given). Default is 0.
mutation Sets the allowed mutation methods used in the evolutionary process. Must be an array (e.g. [methods.mutation.ADD_NODE, methods.mutation.SUB_NODE]). Default mutation methods are all non-recurrent mutation methods. A random mutation method will be chosen from the array when mutation occrus.
selection Sets the allowed selection method used in the evolutionary process. Must be a single method (e.g. Selection.FITNESS_PROPORTIONATE). Default is FITNESS_PROPORTIONATE.
crossover Sets the allowed crossover methods used in the evolutionary process. Must be an array. disabled as of now
fitnessPopulation If set to true, you will have to specify a fitness function that takes an array of genomes as input and sets their .score property.
mutationRate Sets the mutation rate. If set to 0.3, 30% of the new population will be mutated. Default is 0.3.
mutationAmount If mutation occurs (randomNumber < mutationRate), sets the amount of times a mutation method will be applied to the network. Default is 1.
network If you want to start the algorithm from a specific network, specify your network here.
equal If set to true, all networks will be viewed equal during crossover. This stimulates more diverse network architectures. Default is false.
clear Clears the context of the network before activating the fitness function. Should be applied to get consistent outputs from recurrent networks. Default is false.
## Properties There are only a few properties
input The amount of input neurons each genome has
output The amount of output neurons each genome has
fitness The fitness function that is used to evaluate genomes
generation Generation counter
population An array containing all the genomes of the current generation
## Functions There are a few built-in functions. For the client, only `getFittest()` and `evolve()` is important. In the future, there will be a combination of backpropagation and evolution. Stay tuned
createPool() Initialises the first set of genomes. Should not be called manually.
async evolve() Loops the generation through a evaluation, selection, crossover and mutation process.
async evaluate() Evaluates the entire population by passing on the genome to the fitness function and taking the score.
sort() Sorts the entire population by score. Should be called after evaluate()
getFittest() Returns the fittest genome (highest score) of the current generation
mutate() Mutates genomes in the population, each genome has mutationRate chance of being mutated.
getOffspring() This function selects two genomes from the population with getParent(), and returns the offspring from those parents.
getAverage() Returns the average fitness of the current population
getParent() Returns a parent selected using one of the selection methods provided. Should be called after evaluation. Should not be called manually.
export() Exports the current population of the set up algorithm to a list containing json objects of the networks. Can be used later with import(json) to reload the population
import(json) Imports population from a json. Must be an array of networks that have converted to json (with myNetwork.toJSON())