From a70b7670e70d14da075a5f75bcc4369b0972cfd4 Mon Sep 17 00:00:00 2001 From: Matthias Guillitte Date: Sat, 21 Mar 2026 09:46:35 +0100 Subject: [PATCH] Use correct naming for iteration and epoch --- app/Events/PerceptronTrainingIteration.php | 3 +-- .../GradientDescentPerceptronTraining.php | 21 ++++++++++--------- app/Models/NetworkTraining.php | 14 ++++++------- app/Models/SimpleBinaryPerceptronTraining.php | 16 +++++++------- .../PerceptronIterationsErrorsGraph.vue | 12 +++++------ resources/js/components/PerceptronSetup.vue | 2 +- resources/js/types/graphs.ts | 2 +- resources/js/types/perceptron.ts | 5 +++-- 8 files changed, 38 insertions(+), 37 deletions(-) diff --git a/app/Events/PerceptronTrainingIteration.php b/app/Events/PerceptronTrainingIteration.php index 0c1004b..63eae74 100644 --- a/app/Events/PerceptronTrainingIteration.php +++ b/app/Events/PerceptronTrainingIteration.php @@ -7,7 +7,6 @@ use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Log; class PerceptronTrainingIteration implements ShouldBroadcast { @@ -17,7 +16,7 @@ class PerceptronTrainingIteration implements ShouldBroadcast * Create a new event instance. */ public function __construct( - public array $iterations, // ["iteration" => int, "exampleIndex" => int, "error" => float, "synaptic_weights" => array] + public array $iterations, // ["epoch" => int, "exampleIndex" => int, "error" => float, "synaptic_weights" => array] public string $sessionId, public string $trainingId, ) diff --git a/app/Models/GradientDescentPerceptronTraining.php b/app/Models/GradientDescentPerceptronTraining.php index c8e10c8..952df78 100644 --- a/app/Models/GradientDescentPerceptronTraining.php +++ b/app/Models/GradientDescentPerceptronTraining.php @@ -4,6 +4,7 @@ namespace App\Models; use App\Events\PerceptronTrainingEnded; use App\Services\DataSetReader; +use App\Services\IPerceptronIterationEventBuffer; use App\Services\ISynapticWeightsProvider; use App\Services\PerceptronIterationEventBuffer; @@ -18,36 +19,36 @@ class GradientDescentPerceptronTraining extends NetworkTraining public function __construct( DataSetReader $datasetReader, protected float $learningRate, - int $maxIterations, + int $maxEpochs, protected ISynapticWeightsProvider $synapticWeightsProvider, - PerceptronIterationEventBuffer $iterationEventBuffer, + IPerceptronIterationEventBuffer $iterationEventBuffer, string $sessionId, string $trainingId, private float $minError, ) { - parent::__construct($datasetReader, $maxIterations, $iterationEventBuffer, $sessionId, $trainingId); + parent::__construct($datasetReader, $maxEpochs, $iterationEventBuffer, $sessionId, $trainingId); $this->perceptron = new GradientDescentPerceptron($synapticWeightsProvider->generate($datasetReader->getInputSize())); } public function start(): void { - $this->iteration = 0; + $this->epoch = 0; do { $this->epochError = 0; - $iterationErrorPerWeight = []; - $this->iteration++; + $epochCorrectorPerWeight = []; + $this->epoch++; while ($nextRow = $this->datasetReader->getRandomLine()) { $inputs = array_slice($nextRow, 0, -1); $correctOutput = (float) end($nextRow); $iterationError = $this->iterationFunction($inputs, $correctOutput); - $this->epochError += (1 / 2) * (abs($iterationError) ** 2); // TDDO REMOVEME abs() + $this->epochError += ($iterationError ** 2) / 2; // Store the iteration error for each weight $inputs_with_bias = array_merge([1], $inputs); // Add bias input foreach ($inputs_with_bias as $index => $input) { - $iterationErrorPerWeight[$index][] = $iterationError * $input; + $epochCorrectorPerWeight[$index][] = $iterationError * $input; } // Broadcast the training iteration event @@ -57,14 +58,14 @@ class GradientDescentPerceptronTraining extends NetworkTraining // Synaptic weights correction after each epoch $synaptic_weights = $this->perceptron->getSynapticWeights(); $new_weights = array_map( - fn($weight, $weightIndex) => $weight + $this->learningRate * array_sum($iterationErrorPerWeight[$weightIndex]), + fn($weight, $weightIndex) => $weight + $this->learningRate * array_sum($epochCorrectorPerWeight[$weightIndex]), $synaptic_weights, array_keys($synaptic_weights) ); $this->perceptron->setSynapticWeights($new_weights); $this->datasetReader->reset(); // Reset the dataset for the next iteration - } while ($this->iteration < $this->maxIterations && !$this->stopCondition()); + } while ($this->epoch < $this->maxEpochs && !$this->stopCondition()); $this->iterationEventBuffer->flush(); // Ensure all iterations are sent to the frontend diff --git a/app/Models/NetworkTraining.php b/app/Models/NetworkTraining.php index 1b8a572..3f873a0 100644 --- a/app/Models/NetworkTraining.php +++ b/app/Models/NetworkTraining.php @@ -4,11 +4,11 @@ namespace App\Models; use App\Events\PerceptronTrainingEnded; use App\Services\DataSetReader; -use App\Services\PerceptronIterationEventBuffer; +use App\Services\IPerceptronIterationEventBuffer; abstract class NetworkTraining { - protected int $iteration = 0; + protected int $epoch = 0; /** * @abstract @@ -18,8 +18,8 @@ abstract class NetworkTraining public function __construct( protected DataSetReader $datasetReader, - protected int $maxIterations, - protected PerceptronIterationEventBuffer $iterationEventBuffer, + protected int $maxEpochs, + protected IPerceptronIterationEventBuffer $iterationEventBuffer, protected string $sessionId, protected string $trainingId, ) { @@ -29,8 +29,8 @@ abstract class NetworkTraining abstract protected function stopCondition(): bool; protected function checkPassedMaxIterations(?float $finalError) { - if ($this->iteration >= $this->maxIterations) { - $message = 'Le nombre maximal d\'itérations a été atteint'; + if ($this->epoch >= $this->maxEpochs) { + $message = 'Le nombre maximal d\'epoch a été atteint'; if ($finalError) { $message .= " avec une erreur finale de $finalError"; } @@ -40,6 +40,6 @@ abstract class NetworkTraining } protected function addIterationToBuffer(float $error, array $synapticWeights) { - $this->iterationEventBuffer->addIteration($this->iteration, $this->datasetReader->getLastReadLineIndex(), $error, $synapticWeights); + $this->iterationEventBuffer->addIteration($this->epoch, $this->datasetReader->getLastReadLineIndex(), $error, $synapticWeights); } } diff --git a/app/Models/SimpleBinaryPerceptronTraining.php b/app/Models/SimpleBinaryPerceptronTraining.php index 95961d7..1570edb 100644 --- a/app/Models/SimpleBinaryPerceptronTraining.php +++ b/app/Models/SimpleBinaryPerceptronTraining.php @@ -4,8 +4,8 @@ namespace App\Models; use App\Events\PerceptronTrainingEnded; use App\Services\DataSetReader; +use App\Services\IPerceptronIterationEventBuffer; use App\Services\ISynapticWeightsProvider; -use App\Services\PerceptronIterationEventBuffer; class SimpleBinaryPerceptronTraining extends NetworkTraining { @@ -19,25 +19,25 @@ class SimpleBinaryPerceptronTraining extends NetworkTraining public function __construct( DataSetReader $datasetReader, protected float $learningRate, - int $maxIterations, + int $maxEpochs, protected ISynapticWeightsProvider $synapticWeightsProvider, - PerceptronIterationEventBuffer $iterationEventBuffer, + IPerceptronIterationEventBuffer $iterationEventBuffer, string $sessionId, string $trainingId, ) { - parent::__construct($datasetReader, $maxIterations, $iterationEventBuffer, $sessionId, $trainingId); + parent::__construct($datasetReader, $maxEpochs, $iterationEventBuffer, $sessionId, $trainingId); $this->perceptron = new SimpleBinaryPerceptron($synapticWeightsProvider->generate($datasetReader->getInputSize())); } public function start(): void { - $this->iteration = 0; + $this->epoch = 0; $error = 0; do { $this->iterationErrorCounter = 0; - $this->iteration++; + $this->epoch++; - while ($nextRow = $this->datasetReader->getRandomLine()) { + while ($nextRow = $this->datasetReader->getNextLine()) { $inputs = array_slice($nextRow, 0, -1); $correctOutput = (float) end($nextRow); $correctOutput = $correctOutput > 0 ? 1 : 0; // Modify labels for non binary datasets @@ -48,7 +48,7 @@ class SimpleBinaryPerceptronTraining extends NetworkTraining $this->addIterationToBuffer($error, [[$this->perceptron->getSynapticWeights()]]); } $this->datasetReader->reset(); // Reset the dataset for the next iteration - } while ($this->iteration < $this->maxIterations && !$this->stopCondition()); + } while ($this->epoch < $this->maxEpochs && !$this->stopCondition()); $this->iterationEventBuffer->flush(); // Ensure all iterations are sent to the frontend diff --git a/resources/js/components/PerceptronIterationsErrorsGraph.vue b/resources/js/components/PerceptronIterationsErrorsGraph.vue index 57068c5..09c597b 100644 --- a/resources/js/components/PerceptronIterationsErrorsGraph.vue +++ b/resources/js/components/PerceptronIterationsErrorsGraph.vue @@ -39,8 +39,8 @@ function getPerceptronErrorsPerIteration(): ChartData< dataset.data.push(iteration.error); // Epoch error - epochAverageError[iteration.iteration - 1] = - (epochAverageError[iteration.iteration - 1] || 0) + + epochAverageError[iteration.epoch - 1] = + (epochAverageError[iteration.epoch - 1] || 0) + iteration.error ** 2 / 2; }); @@ -81,7 +81,7 @@ function getPerceptronErrorsPerIteration(): ChartData< plugins: { title: { display: true, - text: 'Nombre d\'erreurs par itération', + text: 'Nombre d\'erreurs par epoch', }, }, scales: { @@ -96,7 +96,7 @@ function getPerceptronErrorsPerIteration(): ChartData< color: function (context) { if (context.tick.value == 0) { return gridColorBold; - } + } return gridColor; }, @@ -106,8 +106,8 @@ function getPerceptronErrorsPerIteration(): ChartData< }" :data="{ labels: props.iterations.reduce((labels, iteration) => { - if (!labels.includes(`Itération ${iteration.iteration}`)) { - labels.push(`Itération ${iteration.iteration}`); + if (!labels.includes(`Époch ${iteration.epoch}`)) { + labels.push(`Époch ${iteration.epoch}`); } return labels; }, [] as string[]), diff --git a/resources/js/components/PerceptronSetup.vue b/resources/js/components/PerceptronSetup.vue index 1e82b24..b887ec3 100644 --- a/resources/js/components/PerceptronSetup.vue +++ b/resources/js/components/PerceptronSetup.vue @@ -202,7 +202,7 @@ watch(selectedDatasetCopy, (newValue) => { - Nombre maximum d'epoch + Nombre maximum d'itérations