整理桌面
This commit is contained in:
94
node_modules/neataptic/mkdocs/templates/articles/agario.md
generated
vendored
Normal file
94
node_modules/neataptic/mkdocs/templates/articles/agario.md
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
description: How to evolve neural networks to play Agar.io with Neataptic
|
||||
authors: Thomas Wagenaar
|
||||
keywords: neuro-evolution, agar.io, Neataptic, AI
|
||||
|
||||
Agar.io is quite a simple game to play... well, for humans it is. However is it just as simple for artificial agents? In this article I will tell you how I have constructed a genetic algorithm that evolves neural networks to play in an Agario.io-like environment. The following simulation shows agents that resulted from 1000+ generations of running the algorithm:
|
||||
|
||||
<div id="field" height="500px"></div>
|
||||
|
||||
_Hover your mouse over a blob to see some more info! Source code [here](https://github.com/wagenaartje/agario-ai)_
|
||||
|
||||
As you might have noticed, the genomes are performing quite well, but far from perfect. The genomes shows human-like traits: searching food, avoiding bigger blobs and chasing smaller blobs. However sometimes one genome just runs into a bigger blob for no reason at all. That is because each genome **can only see 3 other blobs and 3 food blobs**. But above all, the settings of the GA are far from optimized. That is why I invite you to optimize the settings, and perform a pull request on this repo.
|
||||
|
||||
### The making of
|
||||
The code consists of 3 main parts: the field, the player and the genetic algorithm. In the following few paragraphs i'll go into depth on this topics, discussing my choices made. At the bottom of this article you will find a list of improvements I have thought of, but not made yet.
|
||||
|
||||
If you have any questions about the code in the linked repo, please create an issue on [this](https://github.com/wagenaartje/neataptic) repo.
|
||||
|
||||
#### The field
|
||||
The field consists of 2 different objects: food and players. Food is stationary, and has no 'brain'. Every piece of food has a static feeding value. Once food has been eaten, it just moves to a new location on the field. Players on the other hand are capable of making decisions through neural networks. They slowly decay in size when not replenished (either by eating other players or food).
|
||||
|
||||
The field has no borders; when a blob hits the left wall, it will 'teleport' to the right wall. During tests with a bordered field, the entire population of genomes tended to stick to one of the walls without ever evolving to a more flexible population. However, having borderless walls comes with a problem of which a fix has not yet been implemented: genomes that are for example near the left wall, won't detect blobs that are close to the right wall - even though the distance between the blobs can be very small.
|
||||
|
||||
**Some (configurable) settings**:
|
||||
|
||||
* There is one food blob per ~2500 pixels
|
||||
* There is one player per ~12500 pixels
|
||||
|
||||
#### The player
|
||||
The player is a simplified version of the player in the real game. A genome can't split and shoot - it can only move. The output of each genomes brain consists of merely a movement direction and movement speed.
|
||||
|
||||
Genomes can't accelerate, they immediately adapt to the speed given by their brain. They can only eat other blobs when they are 10% bigger, and they can move freely through other blobs that are less than 10% bigger. Each genome will only see the 3 closest players and the 3 closest food blobs within a certain radius.
|
||||
|
||||
**Some (configurable) settings**:
|
||||
|
||||
* A player must be 10% bigger than a blob to eat it
|
||||
* The minimal area of a player is 400 pixels
|
||||
* The maximal area of a player is 10000 pixels
|
||||
* The detection radius is 150 pixels
|
||||
* A player can see up to 3 other players in its detection radius
|
||||
* A player can see up to 3 food blobs in its detection radius
|
||||
* The maximum speed of a player is 3px/frame
|
||||
* The minimal speed of a player is 0.6px/frame
|
||||
* Every frame, the player loses 0.2% of its mass
|
||||
|
||||
#### The genetic algorithm
|
||||
The genetic algorithm is the core of the AI. In the first frame, a certain amount of players are initialized with a neural network as brain. The brains represent the population of a generation. These brains are then evolved by putting the entire population in a single playing field and letting them compete against each other. The fittest brains are moved on the next generation, the less fit brains have a high chance of being removed.
|
||||
|
||||
```javascript
|
||||
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();
|
||||
```
|
||||
|
||||
The above code shows the code run when the evaluation is finished. It is very similar to the built-in evolve() function of Neataptic, however adapted to avoid a fitness function as all genomes must be evaluated at the same time.
|
||||
|
||||
The scoring of the genomes is quite easy: when a certain amount of iterations has been reached, each genome is ranked by their area. Better performing genomes have eaten more blobs, and thus have a bigger area. This scoring is identical to the scoring in Agar.io. I have experimented with other scoring systems, but lots of them stimulated small players to finish themselves off if their score was too low for a certain amount of time.
|
||||
|
||||
**Some (configurable) settings**:
|
||||
|
||||
* An evaluation runs for 1000 frames
|
||||
* The mutation rate is 0.3
|
||||
* The elitism is 10%
|
||||
* Each genome starts with 0 hidden nodes
|
||||
* All mutation methods are allowed
|
||||
|
||||
### Issues/future improvements
|
||||
There are a couple of known issues. However, most of them linked are linked to a future improvement in some way or another.
|
||||
|
||||
**Issues**:
|
||||
|
||||
* Genomes tend to avoid hidden nodes (this is really bad)
|
||||
|
||||
**Future improvements**:
|
||||
|
||||
* Players must be able to detect close players, even if they are on the other side of the field
|
||||
* Players/food should not be spawned at locations occupied by players
|
||||
* The genetic algorithm should be able to run without any visualization
|
||||
* [.. tell me your idea!](https://github.com/wagenaartje/neataptic)
|
97
node_modules/neataptic/mkdocs/templates/articles/classifycolors.md
generated
vendored
Normal file
97
node_modules/neataptic/mkdocs/templates/articles/classifycolors.md
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
description: Classify different colors through genetic algorithms
|
||||
authors: Thomas Wagenaar
|
||||
keywords: color classification, genetic-algorithm, NEAT, Neataptic
|
||||
|
||||
Classifying is something a neural network can do quite well. In this article
|
||||
I will demonstrate how you can set up the evolution process of a neural network
|
||||
that learns to classify colors with Neataptic.
|
||||
|
||||
Colors:
|
||||
<label class="checkbox-inline"><input class="colors" type="checkbox" value="red" checked="true">Red</label>
|
||||
<label class="checkbox-inline"><input class="colors" type="checkbox" value="orange">Orange</label>
|
||||
<label class="checkbox-inline"><input class="colors" type="checkbox" value="yellow">Yellow</label>
|
||||
<label class="checkbox-inline"><input class="colors" type="checkbox" value="green" checked="true">Green</label>
|
||||
<label class="checkbox-inline"><input class="colors" type="checkbox" value="blue" checked="true">Blue</label>
|
||||
<label class="checkbox-inline"><input class="colors" type="checkbox" value="purple">Purple</label>
|
||||
<label class="checkbox-inline"><input class="colors" type="checkbox" value="pink">Pink</label>
|
||||
<label class="checkbox-inline"><input class="colors" type="checkbox" value="monochrome">Monochrome</label>
|
||||
|
||||
<a href="#" class="start" style="text-decoration: none"><span class="glyphicon glyphicon-play"></span> Start evolution</a>
|
||||
|
||||
<pre class="stats">Iteration: <span class="iteration">0</span> Best-fitness: <span class="bestfitness">0</span></pre>
|
||||
<div class="row" style="margin-top: -15px;">
|
||||
<div class="col-md-6">
|
||||
<center><h2 class="blocktext">Set sorted by color</h3></center>
|
||||
<div class="row set" style="padding: 30px; margin-top: -40px; padding-right: 40px;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<center><h2 class="blocktext">Set sorted by NN</h3></center>
|
||||
<div class="row fittestset" style="padding-left: 40px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
### How it works
|
||||
The algorithm to this classification is actually _pretty_ easy. One of my biggest
|
||||
problem was generating the colors, however I stumbled upon [this](https://github.com/davidmerfield/randomColor)
|
||||
Javascript library that allows you to generate colors randomly by name - exactly
|
||||
what I needed (but it also created a problem, read below). So I used it to create
|
||||
a training set:
|
||||
|
||||
```javascript
|
||||
function createSet(){
|
||||
var set = [];
|
||||
|
||||
for(index in COLORS){
|
||||
var color = COLORS[index];
|
||||
|
||||
var randomColors = randomColor({ hue : color, count: PER_COLOR, format: 'rgb'});
|
||||
|
||||
for(var random in randomColors){
|
||||
var rgb = randomColors[random];
|
||||
random = rgb.substring(4, rgb.length-1).replace(/ /g, '').split(',');
|
||||
for(var y in random) random[y] = random[y]/255;
|
||||
|
||||
var output = Array.apply(null, Array(COLORS.length)).map(Number.prototype.valueOf, 0);
|
||||
output[index] = 1;
|
||||
|
||||
set.push({ input: random, output: output, color: color, rgb: rgb});
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
```
|
||||
|
||||
_COLORS_ is an array storing all color names in strings. The possible colors are
|
||||
listed above. Next, we convert this rgb string to an array and normalize the
|
||||
values between 0 and 1. Last of all, we normalize the colors using
|
||||
[one-hot encoding](https://www.quora.com/What-is-one-hot-encoding-and-when-is-it-used-in-data-science).
|
||||
Please note that the `color`and `rgb` object attributes are irrelevant for the algorithm.
|
||||
|
||||
```javascript
|
||||
network.evolve(set, {
|
||||
iterations: 1,
|
||||
mutationRate: 0.6,
|
||||
elisitm: 5,
|
||||
popSize: 100,
|
||||
mutation: methods.mutation.FFW,
|
||||
cost: methods.cost.MSE
|
||||
});
|
||||
```
|
||||
|
||||
Now we create the built-in genetic algorithm in neataptic.js. We define
|
||||
that we want to use all possible mutation methods and set the mutation rate
|
||||
higher than normal. Sprinkle in some elitism and double the default population
|
||||
size. Experiment with the parameters yourself, maybe you'll find even better parameters!
|
||||
|
||||
The fitness function is the most vital part of the algorithm. It basically
|
||||
calculates the [Mean Squared Error](https://en.wikipedia.org/wiki/Mean_squared_error)
|
||||
of the entire set. Neataptic saves the programming of this fitness calculation.
|
||||
At the same time the default `growth` parameter is used, so the networks will
|
||||
get penalized for being too large.
|
||||
|
||||
And putting together all this code will create a color classifier.
|
10
node_modules/neataptic/mkdocs/templates/articles/index.md
generated
vendored
Normal file
10
node_modules/neataptic/mkdocs/templates/articles/index.md
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
description: Articles featuring projects that were created with Neataptic
|
||||
authors: Thomas Wagenaar
|
||||
keywords: Neataptic, JavaScript, library
|
||||
|
||||
Welcome to the articles page! Every now and then, articles will be posted here
|
||||
showing for what kind of projects Neataptic _could_ be used. Neataptic is
|
||||
excellent for the development of AI for browser games for example.
|
||||
|
||||
If you want to post your own article here, feel free to create a pull request
|
||||
or an isse on the [repo page](https://github.com/wagenaartje/neataptic)!
|
70
node_modules/neataptic/mkdocs/templates/articles/neuroevolution.md
generated
vendored
Normal file
70
node_modules/neataptic/mkdocs/templates/articles/neuroevolution.md
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
description: A list of neuro-evolution algorithms set up with Neataptic
|
||||
authors: Thomas Wagenaar
|
||||
keywords: genetic-algorithm, Neat, JavaScript, Neataptic, neuro-evolution
|
||||
|
||||
This page shows some neuro-evolution examples. Please note that not every example
|
||||
may always be successful. More may be added in the future!
|
||||
|
||||
<div class="panel panel-warning autocollapse">
|
||||
<div class="panel-heading clickable">
|
||||
1: Uphill and downhill
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p class="small">This neural network gets taught to increase the input by 0.2 until 1.0 is reached, then it must decrease the input by 2.0.</p>
|
||||
<button type="button" class="btn btn-default" onclick="showModal(1, 0)">Training set</button>
|
||||
<button type="button" class="btn btn-default" onclick="showModal(1, 1)">Evolve settings</button>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" onclick="run(1)">Start</button>
|
||||
<button type="button" class="btn btn-default status1" style="display: none" onclick="showModal(1, 2)">Status</button>
|
||||
<button type="button" class="btn btn-danger error1" style="display: none">Error</button>
|
||||
</div>
|
||||
<svg class="example1" style="display: none"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-warning autocollapse">
|
||||
<div class="panel-heading clickable">
|
||||
2: Count to ten
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p class="small">This neural network gets taught to wait 9 inputs of 0, to output 1 at input number 10.</p>
|
||||
<button type="button" class="btn btn-default" onclick="showModal(2, 0)">Training set</button>
|
||||
<button type="button" class="btn btn-default" onclick="showModal(2, 1)">Evolve settings</button>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" onclick="run(2)">Start</button>
|
||||
<button type="button" class="btn btn-default status2" style="display: none" onclick="showModal(2, 2)">Status</button>
|
||||
<button type="button" class="btn btn-danger error2" style="display: none">Error</button>
|
||||
</div>
|
||||
<svg class="example2" style="display: none"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-warning autocollapse">
|
||||
<div class="panel-heading clickable">
|
||||
3: Vowel vs. consonants classification
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p class="small">This neural network gets taught to classify if a letter of the alphabet is a vowel or not. The data is one-hot-encoded.</p>
|
||||
<button type="button" class="btn btn-default" onclick="showModal(3, 0)">Training set</button>
|
||||
<button type="button" class="btn btn-default" onclick="showModal(3, 1)">Evolve settings</button>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" onclick="run(3)">Start</button>
|
||||
<button type="button" class="btn btn-default status3" style="display: none" onclick="showModal(3, 2)">Status</button>
|
||||
<button type="button" class="btn btn-danger error3" style="display: none">Error</button>
|
||||
</div>
|
||||
<svg class="example3" style="display: none"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="modal" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title"></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre class="modalcontent"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
82
node_modules/neataptic/mkdocs/templates/articles/playground.md
generated
vendored
Normal file
82
node_modules/neataptic/mkdocs/templates/articles/playground.md
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
description: Play around with neural-networks built with Neataptic
|
||||
authors: Thomas Wagenaar
|
||||
keywords: mutate, neural-network, machine-learning, playground, Neataptic
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="btn-group btn-group-justified">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.SUB_NODE)">‌<span class="glyphicon glyphicon-minus"></button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">Node</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.ADD_NODE)">‌<span class="glyphicon glyphicon-plus"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.SUB_CONN)">‌<span class="glyphicon glyphicon-minus"></button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">Conn</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.ADD_CONN)">‌<span class="glyphicon glyphicon-plus"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.SUB_GATE)">‌<span class="glyphicon glyphicon-minus"></button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">Gate</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.ADD_GATE)">‌<span class="glyphicon glyphicon-plus"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.SUB_SELF_CONN)">‌<span class="glyphicon glyphicon-minus"></button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">Self-conn</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.ADD_SELF_CONN)">‌<span class="glyphicon glyphicon-plus"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.SUB_BACK_CONN)">‌<span class="glyphicon glyphicon-minus"></button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">Back-conn</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default" onclick="mutate(methods.mutation.ADD_BACK_CONN)">‌<span class="glyphicon glyphicon-plus"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group" style="margin-bottom: 15px;">
|
||||
<span class="input-group-addon">input1</span>
|
||||
<input type="number" class="form-control input1" value=0>
|
||||
</div>
|
||||
<div class="input-group" style="margin-bottom: 15px;">
|
||||
<span class="input-group-addon">input2</span>
|
||||
<input type="number" class="form-control input2" value=1>
|
||||
</div>
|
||||
<div class="btn-group btn-group-justified">
|
||||
<div class="btn-group" role="group">
|
||||
<button class="btn btn-warning" onclick="activate()">Activate</button>
|
||||
</div>
|
||||
</div>
|
||||
<pre>Output: <span class="output"></span></pre>
|
||||
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="panel panel-default">
|
||||
<svg class="draw" width="100%" height="60%"/>
|
||||
</div>
|
||||
|
||||
</div>
|
135
node_modules/neataptic/mkdocs/templates/articles/targetseeking.md
generated
vendored
Normal file
135
node_modules/neataptic/mkdocs/templates/articles/targetseeking.md
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
description: Neural agents learn to seek targets through neuro-evolution
|
||||
authors: Thomas Wagenaar
|
||||
keywords: target seeking, AI, genetic-algorithm, NEAT, Neataptic
|
||||
|
||||
In the simulation below, neural networks that have been evolved through roughly
|
||||
100 generations try to seek a target. Their goal is to stay as close to the target
|
||||
as possible at all times. If you want to see how one of these networks looks like,
|
||||
check out the [complete simulation](https://wagenaartje.github.io/target-seeking-ai/).
|
||||
|
||||
<div id="field" height="500px">
|
||||
</div>
|
||||
|
||||
_Click on the field to relocate the target! Source code [here](https://wagenaartje.github.io/target-seeking-ai/)._
|
||||
|
||||
The neural agents are actually performing really well. At least one agent will have
|
||||
'solved the problem' after roughly 20 generations. That is because the base of the solution
|
||||
is quite easy: one of the inputs of the neural networks is the angle to the target, so all it
|
||||
has to do is output some value that is similar to this input value. This can easily be done
|
||||
through the identity activation function, but surprisingly, most agents in the simulation above
|
||||
tend to avoid this function.
|
||||
|
||||
You can check out the topology of the networks [here](https://wagenaartje.github.io/target-seeking-ai/).
|
||||
If you manage to evolve the genomes quicker or better than this simulation with different settings, please
|
||||
perform a pull request on [this](https://wagenaartje.github.io/target-seeking-ai/) repo.
|
||||
|
||||
### The making of
|
||||
|
||||
In the previous article I have gone more into depth on the environment of the algorithm, but in this article
|
||||
I will focus more on the settings and inputs/outputs of the algorithm itself.
|
||||
|
||||
|
||||
If you have any questions about the code in the linked repo, please create an issue on [this](https://github.com/wagenaartje/neataptic) repo.
|
||||
|
||||
|
||||
### The agents
|
||||
The agents' task is very simple. They have to get in the vicinity of the target which is set to about
|
||||
100 pixels, once they are in that vicinity, each agents' score will be increased proportionally `(100 - dist)``
|
||||
to the distance. There is one extra though: for every node in the agents' network, the score of the agent will
|
||||
be decreased. This has two reasons; 1. networks shouldn't overfit the solution and 2. having smaller networks
|
||||
reduces computation power.
|
||||
|
||||
Agents have some kind of momentum. They don't have mass, but they do have acceleration, so it takes a small
|
||||
amount of time for a agent to reach the top speed in a certain direction.
|
||||
|
||||
|
||||
**Each agent has the following inputs**:
|
||||
|
||||
* Its own speed in the x-axis
|
||||
* Its own speed in the y-axis
|
||||
* The targets' speed in the x-axis
|
||||
* The targets' speed in the y-axis
|
||||
* The angle towards the target
|
||||
* The distance to the target
|
||||
|
||||
|
||||
The output of each agent is just the desired movement direction.
|
||||
|
||||
There is no kind of collision, except for the walls of the fields. In the future, it might be interesting to
|
||||
add collisions between multiple agents and/or the target to reveal some new tactics. This would require the
|
||||
agent to know the location of surrounding agents.
|
||||
|
||||
### The target
|
||||
The target is fairly easy. It's programmed to switch direction every now and then by a random amount. There
|
||||
is one important thing however: _the target moves with half the speed of the agents_, this makes sure
|
||||
that agents always have the ability to catch up with the target. Apart from that, the physics for the target
|
||||
are similar to the agents' physics.
|
||||
|
||||
### The genetic algorithm
|
||||
|
||||
The genetic algorithm is the core of the AI. In the first frame, a certain
|
||||
amount of players are initialized with a neural network as brain. The brains
|
||||
represent the population of a generation. These brains are then evolved by
|
||||
putting the entire population in óne playing field and letting them compete
|
||||
against each other. The fittest brains are moved on the next generation,
|
||||
the less fit brains have a high chance of being removed.
|
||||
|
||||
```javascript
|
||||
// Networks shouldn't get too big
|
||||
for(var genome in neat.population){
|
||||
genome = neat.population[genome];
|
||||
genome.score -= genome.nodes.length * SCORE_RADIUS / 10;
|
||||
}
|
||||
|
||||
// Sort the population by score
|
||||
neat.sort();
|
||||
|
||||
// Draw the best genome
|
||||
drawGraph(neat.population[0].graph($('.best').width(), $('.best').height()), '.best', false);
|
||||
|
||||
// Init new pop
|
||||
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();
|
||||
```
|
||||
|
||||
The above code shows the code run when the evaluation is finished. It is very similar
|
||||
to the built-in `evolve()` function of Neataptic, however adapted to avoid a fitness
|
||||
function as all genomes must be evaluated at the same time.
|
||||
|
||||
The scoring of the genomes is quite easy: when a certain amount of iterations has been reached,
|
||||
each genome is ranked by their final score. Genomes with a higher score have a small amount of nodes
|
||||
and have been close to the target throughout the iteration.
|
||||
|
||||
**Some (configurable) settings**:
|
||||
|
||||
* An evaluation runs for 250 frames
|
||||
* The mutation rate is 0.3
|
||||
* The elitism is 10%
|
||||
* Each genome starts with 0 hidden nodes
|
||||
* All mutation methods are allowed
|
||||
|
||||
### Issues/future improvements
|
||||
* ... none yet! [Tell me your ideas!](https://github.com/wagenaartje/neataptic)
|
||||
|
||||
**Forks**
|
||||
|
||||
* [corpr8's fork](https://corpr8.github.io/neataptic-targetseeking-tron/)
|
||||
gives each neural agent its own acceleration, as well as letting each arrow
|
||||
remain in the same place after each generation. This creates a much more
|
||||
'fluid' process.
|
Reference in New Issue
Block a user