diff --git a/app/Events/PerceptronInitialization.php b/app/Events/PerceptronInitialization.php index a7efc73..4a957ec 100644 --- a/app/Events/PerceptronInitialization.php +++ b/app/Events/PerceptronInitialization.php @@ -21,8 +21,7 @@ class PerceptronInitialization implements ShouldBroadcast public ActivationsFunctions $activationFunction, public string $sessionId, public string $trainingId, - ) - { + ) { // } @@ -34,7 +33,7 @@ class PerceptronInitialization implements ShouldBroadcast public function broadcastOn(): array { return [ - new Channel($this->sessionId . '-perceptron-training'), + new Channel($this->sessionId.'-perceptron-training'), ]; } diff --git a/app/Events/PerceptronTrainingEnded.php b/app/Events/PerceptronTrainingEnded.php index 8561d10..36ee705 100644 --- a/app/Events/PerceptronTrainingEnded.php +++ b/app/Events/PerceptronTrainingEnded.php @@ -4,8 +4,6 @@ namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Broadcasting\PresenceChannel; -use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; @@ -21,8 +19,7 @@ class PerceptronTrainingEnded implements ShouldBroadcast public string $reason, public string $sessionId, public string $trainingId, - ) - { + ) { // } @@ -34,7 +31,7 @@ class PerceptronTrainingEnded implements ShouldBroadcast public function broadcastOn(): array { return [ - new Channel($this->sessionId . '-perceptron-training'), + new Channel($this->sessionId.'-perceptron-training'), ]; } diff --git a/app/Events/PerceptronTrainingIteration.php b/app/Events/PerceptronTrainingIteration.php index 63eae74..f003ded 100644 --- a/app/Events/PerceptronTrainingIteration.php +++ b/app/Events/PerceptronTrainingIteration.php @@ -19,8 +19,7 @@ class PerceptronTrainingIteration implements ShouldBroadcast public array $iterations, // ["epoch" => int, "exampleIndex" => int, "error" => float, "synaptic_weights" => array] public string $sessionId, public string $trainingId, - ) - { + ) { // } @@ -33,7 +32,7 @@ class PerceptronTrainingIteration implements ShouldBroadcast { // Log::debug("Broadcasting on channel: " . $this->sessionId . '-perceptron-training'); return [ - new Channel($this->sessionId . '-perceptron-training'), + new Channel($this->sessionId.'-perceptron-training'), ]; } diff --git a/app/Http/Controllers/PerceptronController.php b/app/Http/Controllers/PerceptronController.php index 5eeedfd..dc38716 100644 --- a/app/Http/Controllers/PerceptronController.php +++ b/app/Http/Controllers/PerceptronController.php @@ -57,7 +57,7 @@ class PerceptronController extends Controller if (pathinfo($file, PATHINFO_EXTENSION) === 'csv') { $dataset = []; $dataset['label'] = str_replace('.csv', '', $file); - $dataSetReader = new LinearOrderDataSetReader($dataSetsDirectory . '/' . $file); + $dataSetReader = new LinearOrderDataSetReader($dataSetsDirectory.'/'.$file); $dataset['data'] = []; switch (count($dataSetReader->lines[0])) { case 3: @@ -113,12 +113,14 @@ class PerceptronController extends Controller $datasets[] = $dataset; } } + return $datasets; } private function getDataSetReader(string $dataSet): IDataSetReader { $dataSetFileName = "data_sets/{$dataSet}.csv"; + return new RandomOrderDataSetReader($dataSetFileName); } @@ -134,18 +136,17 @@ class PerceptronController extends Controller $trainingId = $request->input('training_id'); if ($weightInitMethod === 'zeros') { - $synapticWeightsProvider = new ZeroSynapticWeights(); + $synapticWeightsProvider = new ZeroSynapticWeights; } $iterationEventBuffer = new PerceptronIterationEventBuffer($sessionId, $trainingId); if ($maxEpochs > config('perceptron.limited_broadcast_iterations')) { - $iterationsInterval = (int)($maxEpochs / config('perceptron.limited_broadcast_iterations')); + $iterationsInterval = (int) ($maxEpochs / config('perceptron.limited_broadcast_iterations')); $iterationEventBuffer = new PerceptronLimitedEpochEventBuffer($sessionId, $trainingId, $iterationsInterval); } $datasetReader = $this->getDataSetReader($dataSet); - $networkTraining = match ($perceptronType) { 'simple' => new SimpleBinaryPerceptronTraining($datasetReader, $learningRate, $maxEpochs, $synapticWeightsProvider, $iterationEventBuffer, $sessionId, $trainingId), 'gradientdescent' => new GradientDescentPerceptronTraining($datasetReader, $learningRate, $maxEpochs, $synapticWeightsProvider, $iterationEventBuffer, $sessionId, $trainingId, $minError), diff --git a/app/Models/NetworksTraining/ADALINEPerceptronTraining.php b/app/Models/NetworksTraining/ADALINEPerceptronTraining.php index b4982f5..f8ae11b 100644 --- a/app/Models/NetworksTraining/ADALINEPerceptronTraining.php +++ b/app/Models/NetworksTraining/ADALINEPerceptronTraining.php @@ -52,7 +52,7 @@ class ADALINEPerceptronTraining extends NetworkTraining $synaptic_weights = $this->perceptron->getSynapticWeights(); $inputs_with_bias = array_merge([1], $inputs); // Add bias input $new_weights = array_map( - fn($weight, $weightIndex) => $weight + ($this->learningRate * $iterationError * $inputs_with_bias[$weightIndex]), + fn ($weight, $weightIndex) => $weight + ($this->learningRate * $iterationError * $inputs_with_bias[$weightIndex]), $synaptic_weights, array_keys($synaptic_weights) ); @@ -73,7 +73,7 @@ class ADALINEPerceptronTraining extends NetworkTraining $this->epochError /= $this->datasetReader->getEpochExamplesCount(); // Average error for the epoch $this->datasetReader->reset(); // Reset the dataset for the next iteration - } while ($this->epoch < $this->maxEpochs && !$this->stopCondition()); + } while ($this->epoch < $this->maxEpochs && ! $this->stopCondition()); $this->iterationEventBuffer->flush(); // Ensure all iterations are sent to the frontend @@ -86,6 +86,7 @@ class ADALINEPerceptronTraining extends NetworkTraining if ($condition === true) { event(new PerceptronTrainingEnded('Le perceptron à atteint l\'erreur minimale', $this->sessionId, $this->trainingId)); } + return $condition; } diff --git a/app/Models/NetworksTraining/GradientDescentPerceptronTraining.php b/app/Models/NetworksTraining/GradientDescentPerceptronTraining.php index a6e3293..925a890 100644 --- a/app/Models/NetworksTraining/GradientDescentPerceptronTraining.php +++ b/app/Models/NetworksTraining/GradientDescentPerceptronTraining.php @@ -62,14 +62,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($epochCorrectorPerWeight[$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->epoch < $this->maxEpochs && !$this->stopCondition()); + } while ($this->epoch < $this->maxEpochs && ! $this->stopCondition()); $this->iterationEventBuffer->flush(); // Ensure all iterations are sent to the frontend @@ -82,6 +82,7 @@ class GradientDescentPerceptronTraining extends NetworkTraining if ($condition === true) { event(new PerceptronTrainingEnded('Le perceptron à atteint l\'erreur minimale', $this->sessionId, $this->trainingId)); } + return $condition; } diff --git a/app/Models/NetworksTraining/NetworkTraining.php b/app/Models/NetworksTraining/NetworkTraining.php index bdbbb88..859e7fa 100644 --- a/app/Models/NetworksTraining/NetworkTraining.php +++ b/app/Models/NetworksTraining/NetworkTraining.php @@ -3,9 +3,9 @@ namespace App\Models\NetworksTraining; use App\Events\PerceptronTrainingEnded; +use App\Models\ActivationsFunctions; use App\Services\DatasetReader\IDataSetReader; use App\Services\IterationEventBuffer\IPerceptronIterationEventBuffer; -use App\Models\ActivationsFunctions; abstract class NetworkTraining { @@ -13,7 +13,6 @@ abstract class NetworkTraining /** * @abstract - * @var ActivationsFunctions */ public ActivationsFunctions $activationFunction; @@ -23,13 +22,14 @@ abstract class NetworkTraining protected IPerceptronIterationEventBuffer $iterationEventBuffer, protected string $sessionId, protected string $trainingId, - ) { - } + ) {} + + abstract public function start(): void; - abstract public function start() : void; abstract protected function stopCondition(): bool; - protected function checkPassedMaxIterations(?float $finalError) { + protected function checkPassedMaxIterations(?float $finalError) + { if ($this->epoch >= $this->maxEpochs) { $message = 'Le nombre maximal d\'epoch a été atteint'; if ($finalError) { @@ -40,7 +40,8 @@ abstract class NetworkTraining } } - protected function addIterationToBuffer(float $error, array $synapticWeights) { + protected function addIterationToBuffer(float $error, array $synapticWeights) + { $this->iterationEventBuffer->addIteration($this->epoch, $this->datasetReader->getLastReadLineIndex(), $error, $synapticWeights); } diff --git a/app/Models/NetworksTraining/SimpleBinaryPerceptronTraining.php b/app/Models/NetworksTraining/SimpleBinaryPerceptronTraining.php index bf01d6d..72e2dd8 100644 --- a/app/Models/NetworksTraining/SimpleBinaryPerceptronTraining.php +++ b/app/Models/NetworksTraining/SimpleBinaryPerceptronTraining.php @@ -13,6 +13,7 @@ use App\Services\SynapticWeightsProvider\ISynapticWeightsProvider; class SimpleBinaryPerceptronTraining extends NetworkTraining { private Perceptron $perceptron; + private int $iterationErrorCounter = 0; public ActivationsFunctions $activationFunction = ActivationsFunctions::STEP; @@ -51,7 +52,7 @@ class SimpleBinaryPerceptronTraining extends NetworkTraining $this->addIterationToBuffer($error, [[$this->perceptron->getSynapticWeights()]]); } $this->datasetReader->reset(); // Reset the dataset for the next iteration - } while ($this->epoch < $this->maxEpochs && !$this->stopCondition()); + } while ($this->epoch < $this->maxEpochs && ! $this->stopCondition()); $this->iterationEventBuffer->flush(); // Ensure all iterations are sent to the frontend @@ -64,6 +65,7 @@ class SimpleBinaryPerceptronTraining extends NetworkTraining if ($condition === true) { event(new PerceptronTrainingEnded('Le perceptron ne commet plus d\'erreurs sur aucune des données', $this->sessionId, $this->trainingId)); } + return $this->iterationErrorCounter == 0; } @@ -79,9 +81,10 @@ class SimpleBinaryPerceptronTraining extends NetworkTraining if ($error !== 0) { // Update synaptic weights if needed $synaptic_weights = $this->perceptron->getSynapticWeights(); $inputs_with_bias = array_merge([1], $inputs); // Add bias input - $new_weights = array_map(fn($weight, $input) => $weight + $this->learningRate * $error * $input, $synaptic_weights, $inputs_with_bias); + $new_weights = array_map(fn ($weight, $input) => $weight + $this->learningRate * $error * $input, $synaptic_weights, $inputs_with_bias); $this->perceptron->setSynapticWeights($new_weights); } + return $error; } diff --git a/app/Models/Perceptrons/GradientDescentPerceptron.php b/app/Models/Perceptrons/GradientDescentPerceptron.php index 22d0f2e..6397baa 100644 --- a/app/Models/Perceptrons/GradientDescentPerceptron.php +++ b/app/Models/Perceptrons/GradientDescentPerceptron.php @@ -2,8 +2,8 @@ namespace App\Models\Perceptrons; -class GradientDescentPerceptron extends Perceptron { - +class GradientDescentPerceptron extends Perceptron +{ public function __construct( array $synaptic_weights, ) { @@ -14,5 +14,4 @@ class GradientDescentPerceptron extends Perceptron { { return $weighted_sum; } - } diff --git a/app/Models/Perceptrons/Perceptron.php b/app/Models/Perceptrons/Perceptron.php index 099403a..f6a5ef8 100644 --- a/app/Models/Perceptrons/Perceptron.php +++ b/app/Models/Perceptrons/Perceptron.php @@ -17,10 +17,11 @@ abstract class Perceptron extends Model $inputs = array_merge([1], $inputs); // Add bias input if (count($inputs) !== count($this->synaptic_weights)) { // Check - throw new \InvalidArgumentException("Number of inputs must match number of synaptic weights."); + throw new \InvalidArgumentException('Number of inputs must match number of synaptic weights.'); } - $weighted_sum = array_sum(array_map(fn($input, $weight) => $input * $weight, $inputs, $this->synaptic_weights)); + $weighted_sum = array_sum(array_map(fn ($input, $weight) => $input * $weight, $inputs, $this->synaptic_weights)); + return $this->activationFunction($weighted_sum); } diff --git a/app/Models/Perceptrons/SimpleBinaryPerceptron.php b/app/Models/Perceptrons/SimpleBinaryPerceptron.php index 2309527..42f0ba1 100644 --- a/app/Models/Perceptrons/SimpleBinaryPerceptron.php +++ b/app/Models/Perceptrons/SimpleBinaryPerceptron.php @@ -2,8 +2,8 @@ namespace App\Models\Perceptrons; -class SimpleBinaryPerceptron extends Perceptron { - +class SimpleBinaryPerceptron extends Perceptron +{ public function __construct( array $synaptic_weights, ) { @@ -14,5 +14,4 @@ class SimpleBinaryPerceptron extends Perceptron { { return $weighted_sum >= 0.0 ? 1.0 : 0.0; } - } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 22db204..c171880 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -6,7 +6,6 @@ use Carbon\CarbonImmutable; use Illuminate\Support\Facades\Date; use Illuminate\Support\Facades\DB; use Illuminate\Support\ServiceProvider; -use Illuminate\Validation\Rules\Password; class AppServiceProvider extends ServiceProvider { diff --git a/app/Providers/InitialSynapticWeightsProvider.php b/app/Providers/InitialSynapticWeightsProvider.php index 29b32cc..ba5397a 100644 --- a/app/Providers/InitialSynapticWeightsProvider.php +++ b/app/Providers/InitialSynapticWeightsProvider.php @@ -14,7 +14,7 @@ class InitialSynapticWeightsProvider extends ServiceProvider public function register(): void { $this->app->singleton(ISynapticWeightsProvider::class, function ($app) { - return new RandomSynapticWeights(); + return new RandomSynapticWeights; }); } diff --git a/app/Services/CsvReader.php b/app/Services/CsvReader.php index d28cb75..dc03f1c 100644 --- a/app/Services/CsvReader.php +++ b/app/Services/CsvReader.php @@ -2,7 +2,8 @@ namespace App\Services; -class CsvReader { +class CsvReader +{ private $file; // private array $headers; @@ -10,11 +11,10 @@ class CsvReader { public function __construct( public string $filename, - ) - { - $this->file = fopen($filename, "r"); - if (!$this->file) { - throw new \RuntimeException("Failed to open file: " . $filename); + ) { + $this->file = fopen($filename, 'r'); + if (! $this->file) { + throw new \RuntimeException('Failed to open file: '.$filename); } // $this->headers = $this->readNextLine(); @@ -22,9 +22,10 @@ class CsvReader { public function readNextLine(): ?array { - if (($data = fgetcsv($this->file, 1000, ",")) !== FALSE) { + if (($data = fgetcsv($this->file, 1000, ',')) !== false) { return $data; } + return null; // End of file or error } } diff --git a/app/Services/DatasetReader/IDataSetReader.php b/app/Services/DatasetReader/IDataSetReader.php index bd5316e..52bc0cd 100644 --- a/app/Services/DatasetReader/IDataSetReader.php +++ b/app/Services/DatasetReader/IDataSetReader.php @@ -2,10 +2,15 @@ namespace App\Services\DatasetReader; -interface IDataSetReader { - public function getNextLine(): array | null; +interface IDataSetReader +{ + public function getNextLine(): ?array; + public function getInputSize(): int; + public function reset(): void; + public function getLastReadLineIndex(): int; + public function getEpochExamplesCount(): int; } diff --git a/app/Services/DatasetReader/LinearOrderDataSetReader.php b/app/Services/DatasetReader/LinearOrderDataSetReader.php index 85d8154..cd99e5f 100644 --- a/app/Services/DatasetReader/LinearOrderDataSetReader.php +++ b/app/Services/DatasetReader/LinearOrderDataSetReader.php @@ -4,8 +4,10 @@ namespace App\Services\DatasetReader; use App\Services\CsvReader; -class LinearOrderDataSetReader implements IDataSetReader { +class LinearOrderDataSetReader implements IDataSetReader +{ public array $lines = []; + private array $currentLines = []; private int $lastReadLineIndex = -1; @@ -36,8 +38,9 @@ class LinearOrderDataSetReader implements IDataSetReader { } } - public function getNextLine(): array | null { - if (!isset($this->currentLines[0])) { + public function getNextLine(): ?array + { + if (! isset($this->currentLines[0])) { return null; // No more lines to read } diff --git a/app/Services/DatasetReader/RandomOrderDataSetReader.php b/app/Services/DatasetReader/RandomOrderDataSetReader.php index 6a745bf..61c33c7 100644 --- a/app/Services/DatasetReader/RandomOrderDataSetReader.php +++ b/app/Services/DatasetReader/RandomOrderDataSetReader.php @@ -4,8 +4,10 @@ namespace App\Services\DatasetReader; use App\Services\CsvReader; -class RandomOrderDataSetReader implements IDataSetReader { +class RandomOrderDataSetReader implements IDataSetReader +{ public array $lines = []; + private array $currentLines = []; private int $lastReadLineIndex = -1; @@ -36,7 +38,7 @@ class RandomOrderDataSetReader implements IDataSetReader { } } - public function getNextLine(): array | null + public function getNextLine(): ?array { if (empty($this->currentLines)) { return null; // No more lines to read diff --git a/app/Services/IterationEventBuffer/IPerceptronIterationEventBuffer.php b/app/Services/IterationEventBuffer/IPerceptronIterationEventBuffer.php index ea6c80d..1049aab 100644 --- a/app/Services/IterationEventBuffer/IPerceptronIterationEventBuffer.php +++ b/app/Services/IterationEventBuffer/IPerceptronIterationEventBuffer.php @@ -2,9 +2,9 @@ namespace App\Services\IterationEventBuffer; -interface IPerceptronIterationEventBuffer { +interface IPerceptronIterationEventBuffer +{ + public function flush(): void; - public function flush(): void ; - - public function addIteration(int $iteration, int $exampleIndex, float $error, array $synaptic_weights): void ; + public function addIteration(int $iteration, int $exampleIndex, float $error, array $synaptic_weights): void; } diff --git a/app/Services/IterationEventBuffer/PerceptronIterationEventBuffer.php b/app/Services/IterationEventBuffer/PerceptronIterationEventBuffer.php index 87832cd..7678be3 100644 --- a/app/Services/IterationEventBuffer/PerceptronIterationEventBuffer.php +++ b/app/Services/IterationEventBuffer/PerceptronIterationEventBuffer.php @@ -2,9 +2,12 @@ namespace App\Services\IterationEventBuffer; -class PerceptronIterationEventBuffer implements IPerceptronIterationEventBuffer { +class PerceptronIterationEventBuffer implements IPerceptronIterationEventBuffer +{ private $data; + private int $nextSizeIncreaseThreshold; + private int $underSizeIncreaseCount = 0; public function __construct( @@ -17,24 +20,25 @@ class PerceptronIterationEventBuffer implements IPerceptronIterationEventBuffer $this->nextSizeIncreaseThreshold = $sizeIncreaseStart; } - public function flush(): void { + public function flush(): void + { event(new \App\Events\PerceptronTrainingIteration($this->data, $this->sessionId, $this->trainingId)); $this->data = []; } - public function addIteration(int $epoch, int $exampleIndex, float $error, array $synaptic_weights): void { + public function addIteration(int $epoch, int $exampleIndex, float $error, array $synaptic_weights): void + { $this->data[] = [ - "epoch" => $epoch, - "exampleIndex" => $exampleIndex, - "error" => $error, - "weights" => $synaptic_weights, + 'epoch' => $epoch, + 'exampleIndex' => $exampleIndex, + 'error' => $error, + 'weights' => $synaptic_weights, ]; if ($this->underSizeIncreaseCount <= $this->sizeIncreaseStart) { // We can still send a single date because we are under the increase start threshold $this->underSizeIncreaseCount++; $this->flush(); - } - else if (count($this->data) >= $this->nextSizeIncreaseThreshold) { + } elseif (count($this->data) >= $this->nextSizeIncreaseThreshold) { $this->flush(); $this->nextSizeIncreaseThreshold *= $this->sizeIncreaseFactor; diff --git a/app/Services/IterationEventBuffer/PerceptronLimitedEpochEventBuffer.php b/app/Services/IterationEventBuffer/PerceptronLimitedEpochEventBuffer.php index 1efbe34..c52b06d 100644 --- a/app/Services/IterationEventBuffer/PerceptronLimitedEpochEventBuffer.php +++ b/app/Services/IterationEventBuffer/PerceptronLimitedEpochEventBuffer.php @@ -2,8 +2,10 @@ namespace App\Services\IterationEventBuffer; -class PerceptronLimitedEpochEventBuffer implements IPerceptronIterationEventBuffer { +class PerceptronLimitedEpochEventBuffer implements IPerceptronIterationEventBuffer +{ private array $data; + private int $underSizeIncreaseCount = 0; public function __construct( @@ -15,23 +17,26 @@ class PerceptronLimitedEpochEventBuffer implements IPerceptronIterationEventBuff $this->data = []; } - public function flush(): void { + public function flush(): void + { event(new \App\Events\PerceptronTrainingIteration($this->data, $this->sessionId, $this->trainingId)); $this->data = []; } - public function addIteration(int $epoch, int $exampleIndex, float $error, array $synaptic_weights): void { + public function addIteration(int $epoch, int $exampleIndex, float $error, array $synaptic_weights): void + { $newData = [ - "epoch" => $epoch, - "exampleIndex" => $exampleIndex, - "error" => $error, - "weights" => $synaptic_weights, + 'epoch' => $epoch, + 'exampleIndex' => $exampleIndex, + 'error' => $error, + 'weights' => $synaptic_weights, ]; if ($this->underSizeIncreaseCount <= $this->sizeIncreaseStart) { // Special case where we need to send each iteration separately $this->underSizeIncreaseCount++; $this->data[] = $newData; $this->flush(); + return; } @@ -39,8 +44,7 @@ class PerceptronLimitedEpochEventBuffer implements IPerceptronIterationEventBuff if ($this->data && $lastEpoch !== $epoch) { // Current Epoch has changed from the last one if ($lastEpoch % $this->epochInterval === 0) { // The last epoch need to be sent $this->flush(); // Flush all data from the previous epoch - } - else { + } else { $this->data = []; } diff --git a/app/Services/SynapticWeightsProvider/ISynapticWeightsProvider.php b/app/Services/SynapticWeightsProvider/ISynapticWeightsProvider.php index 6dab718..884e29b 100644 --- a/app/Services/SynapticWeightsProvider/ISynapticWeightsProvider.php +++ b/app/Services/SynapticWeightsProvider/ISynapticWeightsProvider.php @@ -2,6 +2,7 @@ namespace App\Services\SynapticWeightsProvider; -interface ISynapticWeightsProvider { +interface ISynapticWeightsProvider +{ public function generate(int $input_size): array; } diff --git a/app/Services/SynapticWeightsProvider/RandomSynapticWeights.php b/app/Services/SynapticWeightsProvider/RandomSynapticWeights.php index 549aad8..81821ff 100644 --- a/app/Services/SynapticWeightsProvider/RandomSynapticWeights.php +++ b/app/Services/SynapticWeightsProvider/RandomSynapticWeights.php @@ -2,13 +2,15 @@ namespace App\Services\SynapticWeightsProvider; -class RandomSynapticWeights implements ISynapticWeightsProvider { +class RandomSynapticWeights implements ISynapticWeightsProvider +{ public function generate(int $input_size): array { $weights = []; for ($i = 0; $i < $input_size + 1; $i++) { // +1 for bias weight $weights[] = rand(-100, 100) / 100; // Random weights between -1 and 1 } + return $weights; } } diff --git a/app/Services/SynapticWeightsProvider/ZeroSynapticWeights.php b/app/Services/SynapticWeightsProvider/ZeroSynapticWeights.php index dc56865..8ce77d3 100644 --- a/app/Services/SynapticWeightsProvider/ZeroSynapticWeights.php +++ b/app/Services/SynapticWeightsProvider/ZeroSynapticWeights.php @@ -2,13 +2,15 @@ namespace App\Services\SynapticWeightsProvider; -class ZeroSynapticWeights implements ISynapticWeightsProvider { +class ZeroSynapticWeights implements ISynapticWeightsProvider +{ public function generate(int $input_size): array { $weights = []; for ($i = 0; $i < $input_size + 1; $i++) { // +1 for bias weight $weights[] = 0; // Zero weights } + return $weights; } } diff --git a/config/perceptron.php b/config/perceptron.php index 5fe2fe9..08841a5 100644 --- a/config/perceptron.php +++ b/config/perceptron.php @@ -7,13 +7,13 @@ return [ * Beyond this number of iterations, the broadcast will be splitted every x iterations, * x is limited_broadcast_number */ - 'limited_broadcast_iterations' => 200, + 'limited_broadcast_iterations' => 200, - /** - * How much broadcasts is sent when in limmited broadcast mode - */ - 'limited_broadcast_number' => 200, + /** + * How much broadcasts is sent when in limmited broadcast mode + */ + 'limited_broadcast_number' => 200, - 'broadcast_iteration_size' => 75, + 'broadcast_iteration_size' => 75, ]; diff --git a/resources/js/components/PerceptronIterationsErrorsGraph.vue b/resources/js/components/PerceptronIterationsErrorsGraph.vue index f7178bc..e7b7a5a 100644 --- a/resources/js/components/PerceptronIterationsErrorsGraph.vue +++ b/resources/js/components/PerceptronIterationsErrorsGraph.vue @@ -11,8 +11,6 @@ const props = defineProps<{ iterations: Iteration[]; }>(); -const page = usePage(); - const epochErrorOnly = ref(false); /** diff --git a/routes/api.php b/routes/api.php index 8443620..bd12649 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,7 +1,6 @@ name('perceptron.run'); diff --git a/routes/channels.php b/routes/channels.php index dd2538c..2ba94b1 100644 --- a/routes/channels.php +++ b/routes/channels.php @@ -2,6 +2,6 @@ use Illuminate\Support\Facades\Broadcast; -Broadcast::channel(session()->getId() . '-perceptron-training', function ($user) { +Broadcast::channel(session()->getId().'-perceptron-training', function ($user) { return $user; }); diff --git a/tests/Services/IterationEventBuffer/DullIterationEventBuffer.php b/tests/Services/IterationEventBuffer/DullIterationEventBuffer.php index da6fd26..01a6bfe 100644 --- a/tests/Services/IterationEventBuffer/DullIterationEventBuffer.php +++ b/tests/Services/IterationEventBuffer/DullIterationEventBuffer.php @@ -4,19 +4,13 @@ namespace Tests\Services\IterationEventBuffer; use App\Services\IterationEventBuffer\IPerceptronIterationEventBuffer; -class DullIterationEventBuffer implements IPerceptronIterationEventBuffer { - +class DullIterationEventBuffer implements IPerceptronIterationEventBuffer +{ public function __construct( - ) { + ) {} - } + public function flush(): void {} - public function flush(): void { - return; - } - - public function addIteration(int $epoch, int $exampleIndex, float $error, array $synaptic_weights): void { - return; - } + public function addIteration(int $epoch, int $exampleIndex, float $error, array $synaptic_weights): void {} } diff --git a/tests/Unit/Training/ADALINEPerceptronTest.php b/tests/Unit/Training/ADALINEPerceptronTest.php index d50ad48..647b2b6 100644 --- a/tests/Unit/Training/ADALINEPerceptronTest.php +++ b/tests/Unit/Training/ADALINEPerceptronTest.php @@ -9,15 +9,14 @@ use Tests\Services\IterationEventBuffer\DullIterationEventBuffer; class ADALINEPerceptronTest extends TrainingTestCase { - public function test_adaline_perceptron_training_logic_and() { $training = new ADALINEPerceptronTraining( datasetReader: new LinearOrderDataSetReader(public_path('data_sets/logic_and_gradient.csv')), learningRate: 0.03, maxEpochs: 10000, - synapticWeightsProvider: new ZeroSynapticWeights(), - iterationEventBuffer: new DullIterationEventBuffer(), + synapticWeightsProvider: new ZeroSynapticWeights, + iterationEventBuffer: new DullIterationEventBuffer, sessionId: 'test-session', trainingId: 'test-training', minError: 0.1251, @@ -57,8 +56,8 @@ class ADALINEPerceptronTest extends TrainingTestCase datasetReader: new LinearOrderDataSetReader(public_path('data_sets/table_2_10.csv')), learningRate: 0.0015, maxEpochs: 1000, - synapticWeightsProvider: new ZeroSynapticWeights(), - iterationEventBuffer: new DullIterationEventBuffer(), + synapticWeightsProvider: new ZeroSynapticWeights, + iterationEventBuffer: new DullIterationEventBuffer, sessionId: 'test-session', trainingId: 'test-training', // minError: 16.597077, // Impossible pour un dataset avec des labels -1 et 1 d'avoir une erreur moyenne supérieure à 2 diff --git a/tests/Unit/Training/GradientDescentPerceptronTest.php b/tests/Unit/Training/GradientDescentPerceptronTest.php index 6c9b57b..9398e42 100644 --- a/tests/Unit/Training/GradientDescentPerceptronTest.php +++ b/tests/Unit/Training/GradientDescentPerceptronTest.php @@ -9,15 +9,14 @@ use Tests\Services\IterationEventBuffer\DullIterationEventBuffer; class GradientDescentPerceptronTest extends TrainingTestCase { - public function test_gradient_descent_perceptron_training_logic_and() { $training = new GradientDescentPerceptronTraining( datasetReader: new LinearOrderDataSetReader(public_path('data_sets/logic_and_gradient.csv')), learningRate: 0.2, maxEpochs: 100, - synapticWeightsProvider: new ZeroSynapticWeights(), - iterationEventBuffer: new DullIterationEventBuffer(), + synapticWeightsProvider: new ZeroSynapticWeights, + iterationEventBuffer: new DullIterationEventBuffer, sessionId: 'test-session', trainingId: 'test-training', minError: 0.125001, @@ -56,8 +55,8 @@ class GradientDescentPerceptronTest extends TrainingTestCase datasetReader: new LinearOrderDataSetReader(public_path('data_sets/table_2_10.csv')), learningRate: 0.0015, maxEpochs: 1000, - synapticWeightsProvider: new ZeroSynapticWeights(), - iterationEventBuffer: new DullIterationEventBuffer(), + synapticWeightsProvider: new ZeroSynapticWeights, + iterationEventBuffer: new DullIterationEventBuffer, sessionId: 'test-session', trainingId: 'test-training', // minError: 16.388103, // Impossible pour un dataset avec des labels -1 et 1 d'avoir une erreur moyenne supérieure à 2 diff --git a/tests/Unit/Training/SimplePerceptronTest.php b/tests/Unit/Training/SimplePerceptronTest.php index 307be65..fb7aff9 100644 --- a/tests/Unit/Training/SimplePerceptronTest.php +++ b/tests/Unit/Training/SimplePerceptronTest.php @@ -9,15 +9,14 @@ use Tests\Services\IterationEventBuffer\DullIterationEventBuffer; class SimplePerceptronTest extends TrainingTestCase { - public function test_simple_perceptron_training_logic_and() { $training = new SimpleBinaryPerceptronTraining( datasetReader: new LinearOrderDataSetReader(public_path('data_sets/logic_and.csv')), learningRate: 1.0, maxEpochs: 100, - synapticWeightsProvider: new ZeroSynapticWeights(), - iterationEventBuffer: new DullIterationEventBuffer(), + synapticWeightsProvider: new ZeroSynapticWeights, + iterationEventBuffer: new DullIterationEventBuffer, sessionId: 'test-session', trainingId: 'test-training', ); diff --git a/tests/Unit/Training/TrainingTestCase.php b/tests/Unit/Training/TrainingTestCase.php index c11e35b..8d418ce 100644 --- a/tests/Unit/Training/TrainingTestCase.php +++ b/tests/Unit/Training/TrainingTestCase.php @@ -13,7 +13,6 @@ class TrainingTestCase extends TestCase { $training->start(); - // Assert that the final synaptic weights are as expected withing the margin of error // $finalWeights = $training->getSynapticWeights(); // $this->assertEqualsWithDelta($expectedWeights, $finalWeights, $marginOfError, "Final synaptic weights do not match expected values."); @@ -21,5 +20,4 @@ class TrainingTestCase extends TestCase // Assert that the number of epochs taken is as expected $this->assertEquals($expectedEpochs, $training->getEpoch(), "Expected training to take $expectedEpochs epochs, but it took {$training->getEpoch()} epochs."); } - }