Optimization with @fitness, only keep fitnesses greater than @this->maxFit (if anti-regression-option enabled) + no_file anymore

This commit is contained in:
xdrm-brackets 2016-10-29 16:35:49 +02:00
parent 6826434e07
commit dee73f521a
4 changed files with 38 additions and 42 deletions

View File

@ -227,7 +227,7 @@
*/ */
public function mutation($threshold=1){ public function mutation($threshold=1){
/* (1) Checks @threshold argument */ /* (1) Checks @threshold argument */
if( floatval($threshold) !== $threshold || $threshold < 0 || $threshold > 1 ) if( !is_numeric($threshold) || $threshold < 0 || $threshold > 1 )
throw new \Exception('Invalid threshold for Genome mutation.'); throw new \Exception('Invalid threshold for Genome mutation.');
/* (2) Calculates how many neurons/synapses to mutate */ /* (2) Calculates how many neurons/synapses to mutate */

View File

@ -25,8 +25,8 @@
/************************************************ /************************************************
**** LOCAL ATTRIBUTES **** **** LOCAL ATTRIBUTES ****
************************************************/ ************************************************/
public $maxFit; // Maximum fitness of the previous generation private $maxFit; // Maximum fitness of the previous generation
public $minFit; // Minimum fitness of the current generation private $fitnesses; // The fitnesses of the current generation's genomes
public $gnr; // Current generation index public $gnr; // Current generation index
public $gnm; // Current genome index public $gnm; // Current genome index
private $genome; // Current genome instance private $genome; // Current genome instance
@ -83,9 +83,6 @@
], 'gn' => [ ], 'gn' => [
'filename' => $absolute_path.'.gn', // will contain genomes of the generation 'filename' => $absolute_path.'.gn', // will contain genomes of the generation
'exists' => is_file($absolute_path.'.gn') 'exists' => is_file($absolute_path.'.gn')
], 'ft' => [
'filename' => $absolute_path.'.ft', // will contain genomes' fitness
'exists' => is_file($absolute_path.'.ft')
], 'ln' => [ ], 'ln' => [
'filename' => $absolute_path.'.ln', // will contain learnt best genomes 'filename' => $absolute_path.'.ln', // will contain learnt best genomes
'exists' => is_file($absolute_path.'.ln') 'exists' => is_file($absolute_path.'.ln')
@ -370,10 +367,10 @@
/* (1) Initializes data & storage */ /* (1) Initializes data & storage */
$this->gnr = 0; $this->gnr = 0;
$this->gnm = 0; $this->gnm = 0;
$this->minFit = null;
$this->maxFit = null; $this->maxFit = null;
FileManager::write($this->storage['gn']['filename'], ''); FileManager::write($this->storage['gn']['filename'], '');
FileManager::write($this->storage['ft']['filename'], ''); // FileManager::write($this->storage['ft']['filename'], '');
$this->fitnesses = [];
/* (2) Stores random genomes to storage */ /* (2) Stores random genomes to storage */
for( $g = 0 ; $g < $this->maxGnm ; $g++ ){ for( $g = 0 ; $g < $this->maxGnm ; $g++ ){
@ -399,10 +396,10 @@
/* (1) Initializes data & storage */ /* (1) Initializes data & storage */
$this->gnr = 0; $this->gnr = 0;
$this->gnm = 0; $this->gnm = 0;
$this->minFit = null;
$this->maxFit = null; $this->maxFit = null;
FileManager::write($this->storage['gn']['filename'], ''); FileManager::write($this->storage['gn']['filename'], '');
FileManager::write($this->storage['ft']['filename'], ''); // FileManager::write($this->storage['ft']['filename'], '');
$this->fitnesses = [];
/* (2.1) Fetch learnt best genomes */ /* (2.1) Fetch learnt best genomes */
$loadedGenomes = [ $loadedGenomes = [
@ -481,7 +478,11 @@
throw new \Exception('The learning routine is closed.'); throw new \Exception('The learning routine is closed.');
/* (1) Stores fitness */ /* (1) Stores fitness */
FileManager::append($this->storage['ft']['filename'], strval($this->genome->getFitness()) ); $fit = $this->genome->getFitness();
if( !$this->antReg || is_null($this->maxFit) || $fit > $this->maxFit )
$this->fitnesses[$this->gnm] = $fit;
// FileManager::append($this->storage['ft']['filename'], strval($this->genome->getFitness()) );
/* (1) Iterates if possible /* (1) Iterates if possible
@ -499,12 +500,12 @@
$this->gnm = 0; $this->gnm = 0;
/* (2) Fetch the whole generation fitness values */ /* (2) Fetch the whole generation fitness values */
$ftRead = FileManager::read($this->storage['ft']['filename']); // $ftRead = FileManager::read($this->storage['ft']['filename']);
$fitnesses = explode("\n", trim($ftRead) ); // $this->fitnesses = explode("\n", trim($ftRead) );
/* (3) Checks if fitnessEnd is reached */ /* (3) Checks if fitnessEnd is reached */
if( min($fitnesses) == $this->fitEnd ){ if( count($this->fitnesses) > 0 && max($this->fitnesses) == $this->fitEnd ){
/* (1) Get the 2 best genomes */ /* (1) Get the 2 best genomes */
$best = FileManager::readline($this->storage['gn']['filename'], 0); $best = FileManager::readline($this->storage['gn']['filename'], 0);
@ -522,13 +523,11 @@
/* (4) Checks if theres a fitness maximum evolution */ /* (4) Checks if theres a fitness maximum evolution */
$fitnessEvolution = !$this->antReg || is_null($this->maxFit) && is_null($this->minFit) || max($fitnesses) > $this->maxFit; // Extract @mother & @father indexes //
$iBest = $this->bestFitnesses($this->fitnesses);
/* (4.1) If evolution -> choose best + cross-over ... */ /* (4.1) If evolution -> choose best + cross-over ... */
if( $fitnessEvolution ){ if( !is_null($iBest[0]) ){
// {1} Extract @mother & @father indexes //
$iBest = $this->bestFitnesses($fitnesses);
// {2} Extract best 2 genomes // // {2} Extract best 2 genomes //
$sFather = FileManager::readline($this->storage['gn']['filename'], $iBest[0]); $sFather = FileManager::readline($this->storage['gn']['filename'], $iBest[0]);
@ -541,8 +540,7 @@
$mother = new Genome(2, 2, 2, 2); $mother = new Genome(2, 2, 2, 2);
$mother->unserialize($sMother); $mother->unserialize($sMother);
$this->maxFit = max($fitnesses); $this->maxFit = max($this->fitnesses);
$this->minFit = min($fitnesses);
$this->storeLearntBest(); $this->storeLearntBest();
@ -566,7 +564,7 @@
/* (7) Create new generation */ /* (7) Create new generation */
FileManager::write($this->storage['gn']['filename'], ''); FileManager::write($this->storage['gn']['filename'], '');
FileManager::write($this->storage['ft']['filename'], ''); // FileManager::write($this->storage['ft']['filename'], '');
for( $g = 0 ; $g < $this->maxGnm ; $g++ ){ for( $g = 0 ; $g < $this->maxGnm ; $g++ ){
@ -587,6 +585,8 @@
} }
$this->fitnesses = [];
/* (3) If end of process /* (3) If end of process
---------------------------------------------------------*/ ---------------------------------------------------------*/
}else{ }else{
@ -611,7 +611,6 @@
/* (2) Stores data to learnt data */ /* (2) Stores data to learnt data */
FileManager::write($this->storage['ln']['filename'], $best); FileManager::write($this->storage['ln']['filename'], $best);
} }
// TODO: Manage @mutThr decreasing to be more precise
/************************************************ /************************************************
**** Utility **** **** Utility ****
@ -646,8 +645,8 @@
$c++; $c++;
} }
/* (3) Anti-regression, if @mother < @father only use @father*/ /* (3) If mother not found copy father */
if( $fitnesses[$iMother] < $fitnesses[$iFather] ) if( is_null($iMother) )
$iMother = $iFather; $iMother = $iFather;
return [ $iFather, $iMother ]; return [ $iFather, $iMother ];

View File

@ -2,7 +2,7 @@
"storage_parent": "/build/neuralnetwork/storage", "storage_parent": "/build/neuralnetwork/storage",
"default": { "default": {
"mutation_threshold": 0.5, "mutation_threshold": 1,
"fitness_end": 1, "fitness_end": 1,
"storage": "_buffer", "storage": "_buffer",
"hidden_layers": 2, "hidden_layers": 2,

View File

@ -12,7 +12,7 @@
$train = true; $train = $argc > 1 && $argv[1] == 'train';
$guess = !$train; $guess = !$train;
if( $train && 'learning_process' ){ if( $train && 'learning_process' ){
@ -34,13 +34,13 @@
=========================================================*/ =========================================================*/
}catch(\Exception $e){ }catch(\Exception $e){
$nn = NeuralNetwork::create(50, 500); $nn = NeuralNetwork::create(50, 100);
$nn->setHiddenLayersCount(3); // 3 Hidden layers $nn->setHiddenLayersCount(5); // 3 Hidden layers
$nn->setHiddenLayerNeuronsCount(4); // Composed with 3 neurons each $nn->setHiddenLayerNeuronsCount(3); // Composed with 3 neurons each
$nn->setInputLayerCount(3); // 3 inputs $nn->setInputLayerCount(3); // 3 inputs
$nn->setOutputLayerCount(1); // 1 output $nn->setOutputLayerCount(1); // 1 output
$nn->setMutationThreshold(0.3); // mutation 30% each generation $nn->setMutationThreshold(0.5); // mutation 30% each generation
$nn->setFitnessEnd(-1.5); // Algorithm is done when fitness reaches 0 $nn->setFitnessEnd(-1.5); // Algorithm is done when fitness reaches 0
$nn->setAntiRegression(true); // That repeats a generation while its fitness is lower than the previous one $nn->setAntiRegression(true); // That repeats a generation while its fitness is lower than the previous one
@ -71,12 +71,11 @@
/* [2] Initializing learning routine /* [2] Initializing learning routine
=========================================================*/ =========================================================*/
$defaultMT = 0.3;
$fitness = 0; $fitness = 0;
$max_fit = 0; $max_fit = 0;
$nn->loadLearningRoutine(function($input, $output){ $nn->loadLearningRoutine(function($input, $output){
global $fitness; global $fitness;
$fitness -= abs($output[0] - behaviourtest2($input)[0]); $fitness -= abs(round($output[0]) - behaviourtest2($input)[0]);
}); });
echo "$part. Learning routine initialized.\n"; $part++; echo "$part. Learning routine initialized.\n"; $part++;
@ -94,7 +93,6 @@
$last_gnr = $nn->gnr; $last_gnr = $nn->gnr;
$max_fit = -1e9; $max_fit = -1e9;
$min_fit = 100;
/* (2) For each genome */ /* (2) For each genome */
while( true ){ while( true ){
@ -102,19 +100,18 @@
/* (2.1) Get current genome */ /* (2.1) Get current genome */
$g = $nn->getGenome(); $g = $nn->getGenome();
echo "\r[x] gnm ".($nn->gnm+1)."/500 on gnr ".($nn->gnr+1)."/50 - x".($gen_repeat+1)." - fit[$min_fit;$max_fit] "; echo "\r[x] gnm ".($nn->gnm+1)."/100 on gnr ".($nn->gnr+1)."/50 - x".($gen_repeat+1)." - fit[$max_fit] ";
/* (2.2) Train genome with random samples */ /* (2.2) Train genome with random samples */
for( $r = 0 ; $r < 100 ; $r++ ) for( $r = 0 ; $r < 500 ; $r++ )
$g->train([rand(0,10), rand(0,10), rand(0,10)]); $g->train([rand(0,100), rand(0,100), rand(0,100)]);
/* (2.3) Set fitness & go to next genome */ /* (2.3) Set fitness & go to next genome */
if( $fitness > $max_fit ) $max_fit = $fitness; if( $fitness > $max_fit ) $max_fit = $fitness;
if( $fitness < $min_fit ) $min_fit = $fitness;
$g->setFitness($fitness); $g->setFitness($fitness);
if( $nn->gnm >= 500-1 ) if( $nn->gnm >= 100-1 )
break; break;
$nn->nextGenome(); $nn->nextGenome();