Files
Reseaux-de-neurones-artific…/app/Http/Controllers/PerceptronController.php
Matthias Guillitte 6abb417430 Added Limited Epoch Event Buffer
for better frontend performance when using big  max epoch number
2026-03-21 09:42:05 +01:00

156 lines
5.9 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Events\PerceptronInitialization;
use App\Models\GradientDescentPerceptronTraining;
use App\Models\SimpleBinaryPerceptronTraining;
use App\Services\DataSetReader;
use App\Services\ISynapticWeightsProvider;
use App\Services\PerceptronIterationEventBuffer;
use App\Services\PerceptronLimitedEpochEventBuffer;
use App\Services\ZeroSynapticWeights;
use Illuminate\Http\Request;
class PerceptronController extends Controller
{
/**
* Display the specified resource.
*/
public function index(Request $request)
{
$perceptronType = $request->query('type');
$learningRate = 0.01;
$maxIterations = 200;
$minError = 0.6;
switch ($perceptronType) {
case 'simple':
$learningRate = 0.015;
$maxIterations = 150;
break;
case 'gradientdescent':
$learningRate = 0.00003;
}
return inertia('PerceptronViewer', [
'type' => $perceptronType,
'sessionId' => session()->getId(),
'datasets' => $this->getDatasets($perceptronType),
'minError' => $minError,
'learningRate' => $learningRate,
'maxIterations' => $maxIterations,
]);
}
private function getDatasets(string $perceptronType): array
{
$dataSetsDirectory = public_path('data_sets');
$files = scandir($dataSetsDirectory);
$datasets = [];
foreach ($files as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'csv') {
$dataset = [];
$dataset['label'] = str_replace('.csv', '', $file);
$dataSetReader = new DataSetReader($dataSetsDirectory . '/' . $file);
$dataset['data'] = [];
switch (count($dataSetReader->lines[0])) {
case 3:
foreach ($dataSetReader->lines as $line) {
$dataset['data'][] = [
'x' => $line[0],
'y' => $line[1],
'label' => $line[2],
];
}
break;
case 2:
foreach ($dataSetReader->lines as $line) {
$dataset['data'][] = [
'x' => $line[0],
'y' => $line[1],
'label' => 1,
];
}
break;
default:
$dataset['data'] = null; // Not supported for viewing
break;
}
switch ($dataset['label']) {
case 'logic_and_gradient':
switch ($perceptronType) {
case 'gradientdescent':
$dataset['defaultLearningRate'] = 0.3;
break;
}
break;
case 'table_2_9':
switch ($perceptronType) {
case 'simple':
$dataset['defaultLearningRate'] = 0.015;
break;
case 'gradientdescent':
$dataset['defaultLearningRate'] = 0.001;
$dataset['defaultMinError'] = 2.0;
break;
}
break;
case 'table_2_11':
$dataset['defaultMinError'] = 1.0;
break;
}
$datasets[] = $dataset;
}
}
return $datasets;
}
private function getDataSetReader(string $dataSet): DataSetReader
{
$dataSetFileName = "data_sets/{$dataSet}.csv";
return new DataSetReader($dataSetFileName);
}
public function run(Request $request, ISynapticWeightsProvider $synapticWeightsProvider)
{
$perceptronType = $request->input('type');
$minError = $request->input('min_error', 0.01);
$weightInitMethod = $request->input('weight_init_method', 'random');
$dataSet = $request->input('dataset');
$learningRate = $request->input('learning_rate', 0.015);
$maxIterations = $request->input('max_iterations', 100);
$sessionId = $request->input('session_id', session()->getId());
$trainingId = $request->input('training_id');
if ($weightInitMethod === 'zeros') {
$synapticWeightsProvider = new ZeroSynapticWeights();
}
$iterationEventBuffer = new PerceptronIterationEventBuffer($sessionId, $trainingId);
if ($maxIterations > config('perceptron.limited_broadcast_iterations')) {
$iterationsInterval = (int)($maxIterations / config('perceptron.limited_broadcast_iterations'));
$iterationEventBuffer = new PerceptronLimitedEpochEventBuffer($sessionId, $trainingId, $iterationsInterval);
}
$dataSetReader = $this->getDataSetReader($dataSet);
$networkTraining = match ($perceptronType) {
'simple' => new SimpleBinaryPerceptronTraining($dataSetReader, $learningRate, $maxIterations, $synapticWeightsProvider, $iterationEventBuffer, $sessionId, $trainingId),
'gradientdescent' => new GradientDescentPerceptronTraining($dataSetReader, $learningRate, $maxIterations, $synapticWeightsProvider, $iterationEventBuffer, $sessionId, $trainingId, $minError),
default => null,
};
event(new PerceptronInitialization($dataSetReader->lines, $networkTraining->activationFunction, $sessionId, $trainingId));
$networkTraining->start();
return response()->json([
'message' => 'Training completed',
]);
}
}