NeatBundle
Â
 , (*1)
The NeatBundle is an implementation of an genetic algorithm, based on the neuro evolution by augmenting topologies., (*2)
learn more about Evolving Neural Networks through Augmenting Topologies, (*3)
Installation
$ composer install gheb/neat-bundle
In such a system, values of inputs are computed to tend toward one or more outputs.
To do so, and keep it isolated, gheb/neat-bundle
comes with gheb/io-bundle
., (*4)
First define your inputs:, (*5)
<?php
namespace Acme\DemoBundle\IO\Inputs;
use Gheb\IOBundle\Inputs\AbstractInput;
class MyInput extends AbstractInput
{
public function getName()
{
// the name is here to allow you calling it from the console
// php bin/console gheb:io:input MyInput
return 'MyInput';
}
public function getValue()
{
// return the input value
}
}
And register it as a service with the tag gheb.io.input
:, (*6)
parameters:
acme.io.input.myinput.class : Acme\DemoBundle\IO\Inputs\MyInput
services:
acme.io.input.myinput:
class : '%acme.io.input.myinput.class%'
tags:
- { name: gheb.io.input }
Same way for the outputs:, (*7)
First define your inputs:, (*8)
<?php
namespace Acme\DemoBundle\IO\Outputs;
use Gheb\IOBundle\Outputs\AbstractOutput;
class MyOutput extends AbstractInput
{
public function getName()
{
// the name is here to allow you calling it from the console
// php bin/console gheb:io:output MyOutput
return 'MyOutput';
}
public function apply()
{
// does something for your app
}
}
And register it as a service with the tag gheb.io.output
:, (*9)
parameters:
acme.io.input.myoutput.class : Acme\DemoBundle\IO\Inputs\MyOutput
services:
acme.io.input.myoutput:
class : '%acme.io.input.myoutput.class%'
tags:
- { name: gheb.io.output}
Hooks
Maybe hooks is not the right term here, because in my minds, you don't always need to use hooks.
In our case, hooks may be essential., (*10)
when you run the neat command (php bin/console gheb:neat:run) to evaluate over and over the network created, there is a two things you MUST define :, (*11)
the criteria to define when the evaluation of the current genome must stop and go to the next. It's done with the nextGenomeCriteria
hook., (*12)
the fitness is something really depending on what you are trying to achieve, so you have to send it to the NeatBundle. It's done with the getFitness
hook., (*13)
That's it., (*14)
Create a hook
<?php
namespace Acme\DemoBundle\Neat;
use Gheb\NeatBundle\Hook;
class myHook implements Hook
{
public function __invoke()
{
// logic part
}
}
and plug it to the corresponding tag :, (*15)
services:
acme.neat.hook.nextgenomecriteria:
class: '%tamagotchi.neat.hook.nextgenomecriteria.class%'
arguments: [ "@doctrine.orm.entity_manager" ]
tags:
- { name: gheb.neat.hook.nextGenomeCriteria }
The different tags / hooks are :, (*16)
-
gheb.neat.hook.onBeforeInit
multiple hooks can be defined, they are executed once when you run the command.
-
gheb.neat.hook.onBeforeNewRun
multiple hooks can be defined, they are executed just before a new run. That mean after the GA did switch to the next genome/specie/generation.
-
gheb.neat.hook.onAfterEvaluation
multiple hooks can be defined, they are executed just after the current genome network is evaluated for given inputs.
-
gheb.neat.hook.stopEvaluation
only one hook can be defined, if multiple, they just overwrite the previous ones, it must return a boolean. In some cases, you want just to execute your evaluation for N times, sometimes based on a result to get. If you don't set any, it will run almost forever.
-
gheb.neat.hook.getFitness
only one hook can and must be defined, if multiple, they just overwrite the previous ones, it must return an integer. The GA will keep and mutate the genomes having the higher fitness.
-
gheb.neat.hook.nextGenomeCriteria
only one hook can and must be defined, if multiple, they just overwrite the previous ones, it must return a boolean. This criteria is the condition that indicate the end of the current genome evaluation, and then just switch to the next genome/specie/generation.
Just to get a more precise idea of what's going on, when you run the command gheb:neat:run
, here is a pseudo-code:, (*17)
hook.onBeforeInit()
getOrCreatePoolofSpecies()
while hook.stopEvaluation()
if hook.nextGenomeCriteria
fitness = hook.getFitness()
genome.setFitness(fitness)
if fitness > pool.getMaxFitness()
pool.setMaxFitness(fitness);
endif
nextGenome()
hook.onBeforeNewRun()
newRun()
else
evaluateCurrentInputs() and applyOutputs()
endif
hook.onAfterEvaluation()
endwhile
I clearly see other places to put new hooks like just after the while loop with a onBeforeEnding hook.
But I do not have the use at the moment. I will add them later, or please feel free open a pull request., (*18)
TODO
- Add UnitTests
- prioritize outputs applications ??