Last active
July 23, 2017 18:27
-
-
Save D-Nice/9f332010ad9a22279c6f2a026be64a33 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Architect, Config, Methods, Network, Neat } from 'neataptic' | |
import Parallel from 'paralleljs' | |
Config.warnings = false | |
const trainingSet = [ | |
{ input: [0, 0], output: [0] }, | |
{ input: [0, 1], output: [1] }, | |
{ input: [1, 0], output: [1] }, | |
{ input: [1, 1], output: [0] }, | |
] | |
function evolveNet() { | |
const neat = new Neat( | |
2, | |
1, | |
undefined, | |
{ | |
popsize: 50, | |
mutationRate: 0.5, | |
mutationAmount: 5, | |
equal: true, | |
network: new Architect.Random( | |
2, | |
0, | |
1 | |
) | |
} | |
); | |
neat.mutate() | |
startEval() | |
function startEval() { | |
const env = { | |
trainingSet | |
} | |
// Deep cloning neat population here, could help with speed | |
// so that genomes don't have to be reconverted from JSON | |
const p = new Parallel(neat.population, { | |
maxWorkers: 4, // change this depending on context/threads available | |
env | |
}) | |
p.map(fitnessFunctionP).then(data => { | |
neat.population = data.map((d, i) => | |
Object.assign(Network.fromJSON(d.genome), { score: d.score }) | |
) | |
endEval() | |
}) | |
} | |
function endEval() { | |
neat.sort() | |
const fittest = neat.population[0] | |
console.log('Generation ' + neat.generation + ' Best score ' + fittest.score) | |
if(fittest.score < -0.03 && neat.generation < 500) { | |
const newPopulation = []; | |
// Elitism | |
for(let i = 0; i < neat.elitism; i++){ | |
newPopulation.push(neat.population[i]); | |
} | |
// Breed the next individuals | |
for(let i = 0; i < neat.popsize - neat.elitism; i++){ | |
newPopulation.push(neat.getOffspring()); | |
} | |
neat.population = newPopulation | |
neat.mutate() | |
neat.generation++ | |
setTimeout(startEval, 100) | |
} else { | |
console.log('Done, outputs:' + | |
' [0,0] ' + fittest.activate([0,0]) + | |
' [0,1] ' + fittest.activate([0,1]) + | |
' [1,0] ' + fittest.activate([1,0]) + | |
' [1,1] ' + fittest.activate([1,1]) | |
) | |
} | |
} | |
} | |
function fitnessFunctionP(genome){ | |
const Network = require('neataptic').Network | |
const Methods = require('neataptic').Methods | |
genome = Network.fromJSON(genome) | |
const score = -genome.test(global.env.trainingSet, Methods.Cost.MSE).error | |
return { genome, score } | |
} | |
evolveNet() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment