Gradient descent training + Added all dataset + graphs improvements
linter / quality (push) Failing after 18s
tests / ci (8.4) (push) Failing after 10s
tests / ci (8.5) (push) Failing after 11s

This commit is contained in:
2026-03-13 22:06:08 +01:00
parent f8d9fbc5b1
commit f0e7be4476
29 changed files with 872 additions and 68 deletions
+52 -21
View File
@@ -2,14 +2,14 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\SimplePerceptron; use App\Events\PerceptronInitialization;
use App\Models\SimplePerceptronTraining; use App\Models\GradientDescentPerceptronTraining;
use App\Models\SimpleBinaryPerceptronTraining;
use App\Services\DataSetReader; use App\Services\DataSetReader;
use App\Services\ISynapticWeightsProvider; use App\Services\ISynapticWeightsProvider;
use App\Services\PerceptronIterationEventBuffer; use App\Services\PerceptronIterationEventBuffer;
use App\Services\ZeroSynapticWeights; use App\Services\ZeroSynapticWeights;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class PerceptronController extends Controller class PerceptronController extends Controller
{ {
@@ -18,29 +18,32 @@ class PerceptronController extends Controller
*/ */
public function index(Request $request) public function index(Request $request)
{ {
$perceptronType = $request->query('type', 'simple'); $perceptronType = $request->query('type');
$learningRate = 0.1; $learningRate = 0.01;
$maxIterations = 100; $maxIterations = 200;
$minError = 0.6;
switch ($perceptronType) { switch ($perceptronType) {
case 'simple': case 'simple':
$learningRate = 0.015; $learningRate = 0.015;
$maxIterations = 100; $maxIterations = 150;
break; break;
case 'gradientdescent':
$learningRate = 0.00003;
} }
return inertia('PerceptronViewer', [ return inertia('PerceptronViewer', [
'type' => $perceptronType, 'type' => $perceptronType,
'sessionId' => session()->getId(), 'sessionId' => session()->getId(),
'datasets' => $this->getDatasets(), 'datasets' => $this->getDatasets($perceptronType),
'minError' => 0.01, 'minError' => $minError,
'learningRate' => $learningRate, 'learningRate' => $learningRate,
'maxIterations' => $maxIterations, 'maxIterations' => $maxIterations,
]); ]);
} }
private function getDatasets(): array private function getDatasets(string $perceptronType): array
{ {
$dataSetsDirectory = public_path('data_sets'); $dataSetsDirectory = public_path('data_sets');
$files = scandir($dataSetsDirectory); $files = scandir($dataSetsDirectory);
@@ -51,17 +54,44 @@ class PerceptronController extends Controller
$dataset['label'] = str_replace('.csv', '', $file); $dataset['label'] = str_replace('.csv', '', $file);
$dataSetReader = new DataSetReader($dataSetsDirectory . '/' . $file); $dataSetReader = new DataSetReader($dataSetsDirectory . '/' . $file);
$dataset['data'] = []; $dataset['data'] = [];
foreach ($dataSetReader->lines as $line) { switch (count($dataSetReader->lines[0])) {
$dataset['data'][] = [ case 3:
'x' => $line[0], foreach ($dataSetReader->lines as $line) {
'y' => $line[1], $dataset['data'][] = [
'label' => $line[2], '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']) { switch ($dataset['label']) {
case '2.9': case 'logic_and_gradient':
$dataset['defaultLearningRate'] = 0.015; switch ($perceptronType) {
case 'gradientdescent':
$dataset['defaultLearningRate'] = 0.3;
break;
}
break;
case 'table_2_9':
switch ($perceptronType) {
case 'simple':
$dataset['defaultLearningRate'] = 0.015;
break;
}
break; break;
} }
$datasets[] = $dataset; $datasets[] = $dataset;
@@ -78,7 +108,7 @@ class PerceptronController extends Controller
public function run(Request $request, ISynapticWeightsProvider $synapticWeightsProvider) public function run(Request $request, ISynapticWeightsProvider $synapticWeightsProvider)
{ {
$perceptronType = $request->input('type', 'simple'); $perceptronType = $request->input('type');
$minError = $request->input('min_error', 0.01); $minError = $request->input('min_error', 0.01);
$weightInitMethod = $request->input('weight_init_method', 'random'); $weightInitMethod = $request->input('weight_init_method', 'random');
$dataSet = $request->input('dataset'); $dataSet = $request->input('dataset');
@@ -96,11 +126,12 @@ class PerceptronController extends Controller
$iterationEventBuffer = new PerceptronIterationEventBuffer($sessionId, $trainingId); $iterationEventBuffer = new PerceptronIterationEventBuffer($sessionId, $trainingId);
$networkTraining = match ($perceptronType) { $networkTraining = match ($perceptronType) {
'simple' => new SimplePerceptronTraining($dataSetReader, $learningRate, $maxIterations, $synapticWeightsProvider, $iterationEventBuffer, $sessionId, $trainingId), 'simple' => new SimpleBinaryPerceptronTraining($dataSetReader, $learningRate, $maxIterations, $synapticWeightsProvider, $iterationEventBuffer, $sessionId, $trainingId),
'gradientdescent' => new GradientDescentPerceptronTraining($dataSetReader, $learningRate, $maxIterations, $synapticWeightsProvider, $iterationEventBuffer, $sessionId, $trainingId, $minError),
default => null, default => null,
}; };
event(new \App\Events\PerceptronInitialization($dataSetReader->lines, $networkTraining->activationFunction, $sessionId, $trainingId)); event(new PerceptronInitialization($dataSetReader->lines, $networkTraining->activationFunction, $sessionId, $trainingId));
$networkTraining->start(); $networkTraining->start();
+1
View File
@@ -5,6 +5,7 @@ namespace App\Models;
enum ActivationsFunctions: string enum ActivationsFunctions: string
{ {
case STEP = 'step'; case STEP = 'step';
case LINEAR = 'linear';
case SIGMOID = 'sigmoid'; case SIGMOID = 'sigmoid';
case RELU = 'relu'; case RELU = 'relu';
} }
@@ -2,7 +2,7 @@
namespace App\Models; namespace App\Models;
class SimplePerceptron extends Perceptron { class GradientDescentPerceptron extends Perceptron {
public function __construct( public function __construct(
array $synaptic_weights, array $synaptic_weights,
@@ -10,9 +10,9 @@ class SimplePerceptron extends Perceptron {
parent::__construct($synaptic_weights); parent::__construct($synaptic_weights);
} }
public function activationFunction(float $weighted_sum): int public function activationFunction(float $weighted_sum): float
{ {
return $weighted_sum >= 0 ? 1 : 0; return $weighted_sum;
} }
} }
@@ -0,0 +1,91 @@
<?php
namespace App\Models;
use App\Events\PerceptronTrainingEnded;
use App\Services\DataSetReader;
use App\Services\ISynapticWeightsProvider;
use App\Services\PerceptronIterationEventBuffer;
class GradientDescentPerceptronTraining extends NetworkTraining
{
private Perceptron $perceptron;
public ActivationsFunctions $activationFunction = ActivationsFunctions::LINEAR;
private float $epochError;
public function __construct(
DataSetReader $datasetReader,
protected float $learningRate,
int $maxIterations,
protected ISynapticWeightsProvider $synapticWeightsProvider,
PerceptronIterationEventBuffer $iterationEventBuffer,
string $sessionId,
string $trainingId,
private float $minError,
) {
parent::__construct($datasetReader, $maxIterations, $iterationEventBuffer, $sessionId, $trainingId);
$this->perceptron = new GradientDescentPerceptron($synapticWeightsProvider->generate($datasetReader->getInputSize()));
}
public function start(): void
{
$this->iteration = 0;
do {
$this->epochError = 0;
$iterationErrorPerWeight = [];
$this->iteration++;
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()
// 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;
}
// Broadcast the training iteration event
$this->addIterationToBuffer($iterationError, [[$this->perceptron->getSynapticWeights()]]);
}
// 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]),
$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());
$this->iterationEventBuffer->flush(); // Ensure all iterations are sent to the frontend
$this->checkPassedMaxIterations($this->epochError);
}
protected function stopCondition(): bool
{
$condition = $this->epochError <= $this->minError && $this->perceptron->getSynapticWeights() !== [[0.0, 0.0, 0.0]];
if ($condition === true) {
event(new PerceptronTrainingEnded('Le perceptron à atteint l\'erreur minimale', $this->sessionId, $this->trainingId));
}
return $condition;
}
private function iterationFunction(array $inputs, int $correctOutput)
{
$output = $this->perceptron->test($inputs);
$error = $correctOutput - $output;
return $error;
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace App\Models;
abstract class Network
{
}
+7 -2
View File
@@ -28,9 +28,14 @@ abstract class NetworkTraining
abstract public function start() : void; abstract public function start() : void;
abstract protected function stopCondition(): bool; abstract protected function stopCondition(): bool;
protected function checkPassedMaxIterations() { protected function checkPassedMaxIterations(?float $finalError) {
if ($this->iteration >= $this->maxIterations) { if ($this->iteration >= $this->maxIterations) {
event(new PerceptronTrainingEnded('Le nombre maximal d\'itérations a été atteint', $this->sessionId, $this->trainingId)); $message = 'Le nombre maximal d\'itérations a été atteint';
if ($finalError) {
$message .= " avec une erreur finale de $finalError";
}
event(new PerceptronTrainingEnded($message, $this->sessionId, $this->trainingId));
} }
} }
+2 -2
View File
@@ -12,7 +12,7 @@ abstract class Perceptron extends Model
$this->synaptic_weights = $synaptic_weights; $this->synaptic_weights = $synaptic_weights;
} }
public function test(array $inputs): int public function test(array $inputs): float
{ {
$inputs = array_merge([1], $inputs); // Add bias input $inputs = array_merge([1], $inputs); // Add bias input
@@ -24,7 +24,7 @@ abstract class Perceptron extends Model
return $this->activationFunction($weighted_sum); return $this->activationFunction($weighted_sum);
} }
abstract public function activationFunction(float $weighted_sum): int; abstract public function activationFunction(float $weighted_sum): float;
public function getSynapticWeights(): array public function getSynapticWeights(): array
{ {
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Models;
class SimpleBinaryPerceptron extends Perceptron {
public function __construct(
array $synaptic_weights,
) {
parent::__construct($synaptic_weights);
}
public function activationFunction(float $weighted_sum): float
{
return $weighted_sum >= 0.0 ? 1.0 : 0.0;
}
}
@@ -6,9 +6,8 @@ use App\Events\PerceptronTrainingEnded;
use App\Services\DataSetReader; use App\Services\DataSetReader;
use App\Services\ISynapticWeightsProvider; use App\Services\ISynapticWeightsProvider;
use App\Services\PerceptronIterationEventBuffer; use App\Services\PerceptronIterationEventBuffer;
use Illuminate\Support\Facades\Log;
class SimplePerceptronTraining extends NetworkTraining class SimpleBinaryPerceptronTraining extends NetworkTraining
{ {
private Perceptron $perceptron; private Perceptron $perceptron;
private int $iterationErrorCounter = 0; private int $iterationErrorCounter = 0;
@@ -27,7 +26,7 @@ class SimplePerceptronTraining extends NetworkTraining
string $trainingId, string $trainingId,
) { ) {
parent::__construct($datasetReader, $maxIterations, $iterationEventBuffer, $sessionId, $trainingId); parent::__construct($datasetReader, $maxIterations, $iterationEventBuffer, $sessionId, $trainingId);
$this->perceptron = new SimplePerceptron($synapticWeightsProvider->generate(2)); $this->perceptron = new SimpleBinaryPerceptron($synapticWeightsProvider->generate($datasetReader->getInputSize()));
} }
public function start(): void public function start(): void
@@ -40,13 +39,11 @@ class SimplePerceptronTraining extends NetworkTraining
while ($nextRow = $this->datasetReader->getRandomLine()) { while ($nextRow = $this->datasetReader->getRandomLine()) {
$inputs = array_slice($nextRow, 0, -1); $inputs = array_slice($nextRow, 0, -1);
$correctOutput = end($nextRow); $correctOutput = (float) end($nextRow);
$correctOutput = $correctOutput > 0 ? 1 : 0; // Modify labels for non binary datasets $correctOutput = $correctOutput > 0 ? 1 : 0; // Modify labels for non binary datasets
$error = $this->iterationFunction($inputs, $correctOutput); $error = $this->iterationFunction($inputs, $correctOutput);
$error = abs($error); // Use absolute error
// Broadcast the training iteration event // Broadcast the training iteration event
$this->addIterationToBuffer($error, [[$this->perceptron->getSynapticWeights()]]); $this->addIterationToBuffer($error, [[$this->perceptron->getSynapticWeights()]]);
} }
@@ -55,7 +52,7 @@ class SimplePerceptronTraining extends NetworkTraining
$this->iterationEventBuffer->flush(); // Ensure all iterations are sent to the frontend $this->iterationEventBuffer->flush(); // Ensure all iterations are sent to the frontend
$this->checkPassedMaxIterations(); $this->checkPassedMaxIterations(null);
} }
protected function stopCondition(): bool protected function stopCondition(): bool
+2 -2
View File
@@ -4,7 +4,7 @@ namespace App\Services;
class CsvReader { class CsvReader {
private $file; private $file;
private array $headers; // private array $headers;
public array $lines = []; public array $lines = [];
@@ -17,7 +17,7 @@ class CsvReader {
throw new \RuntimeException("Failed to open file: " . $filename); throw new \RuntimeException("Failed to open file: " . $filename);
} }
$this->headers = $this->readNextLine(); // $this->headers = $this->readNextLine();
} }
public function readNextLine(): ?array public function readNextLine(): ?array
+20 -1
View File
@@ -20,7 +20,17 @@ class DataSetReader {
private function readEntireFile(CsvReader $reader): void private function readEntireFile(CsvReader $reader): void
{ {
while ($line = $reader->readNextLine()) { while ($line = $reader->readNextLine()) {
$this->lines[] = $line; $newLine = [];
foreach ($line as $value) { // Transform to float
$newLine[] = (float) $value;
}
// if the dataset is for regression, we add a fake label of 0
if (count($newLine) === 2) {
$newLine[] = 0.0;
}
$this->lines[] = $newLine;
} }
} }
@@ -31,12 +41,21 @@ class DataSetReader {
} }
$randomNumber = array_rand($this->currentLines); $randomNumber = array_rand($this->currentLines);
$randomLine = $this->currentLines[$randomNumber]; $randomLine = $this->currentLines[$randomNumber];
// Remove the line from the current lines to avoid repetition // Remove the line from the current lines to avoid repetition
unset($this->currentLines[$randomNumber]); unset($this->currentLines[$randomNumber]);
// Remember the index of the last read line in the full list
$this->lastReadLineIndex = array_search($randomLine, $this->lines, true); $this->lastReadLineIndex = array_search($randomLine, $this->lines, true);
return $randomLine; return $randomLine;
} }
public function getInputSize(): int
{
return count($this->lines[0]) - 1; // Don't count the label
}
public function reset(): void public function reset(): void
{ {
$this->currentLines = $this->lines; $this->currentLines = $this->lines;
-22
View File
@@ -1,22 +0,0 @@
x_1, x_2, d
1, 6, 1
7, 9, -1
1, 9, 1
7, 10, -1
2, 5, -1
2, 7, 1
2, 8, 1
6, 8, -1
6, 9, -1
3, 5, -1
3, 6, -1
3, 8, 1
3, 9, 1
5, 7, -1
5, 8, -1
5, 10, 1
5, 11, 1
4, 6, -1
4, 7, -1
4, 9, 1
4, 10, 1
1 x_1 x_2 d
2 1 6 1
3 7 9 -1
4 1 9 1
5 7 10 -1
6 2 5 -1
7 2 7 1
8 2 8 1
9 6 8 -1
10 6 9 -1
11 3 5 -1
12 3 6 -1
13 3 8 1
14 3 9 1
15 5 7 -1
16 5 8 -1
17 5 10 1
18 5 11 1
19 4 6 -1
20 4 7 -1
21 4 9 1
22 4 10 1
-1
View File
@@ -1,4 +1,3 @@
x_1, x_2, d
0, 0, 0 0, 0, 0
0, 1, 0 0, 1, 0
1, 0, 0 1, 0, 0
1 x_1 0 x_2 0 d 0
x_1 x_2 d
1 0 0 0 0 0 0
2 0 0 1 1 0 0
3 1 1 0 0 0 0
+4
View File
@@ -0,0 +1,4 @@
0, 0, -1
0, 1, -1
1, 0, -1
1, 1, 1
1 0 0 -1
2 0 1 -1
3 1 0 -1
4 1 1 1
-1
View File
@@ -1,4 +1,3 @@
x_1, x_2, d
0, 0, 1 0, 0, 1
0, 1, 0 0, 1, 0
1, 0, 0 1, 0, 0
1 x_1 0 x_2 0 d 1
x_1 x_2 d
1 0 0 0 0 1 1
2 0 0 1 1 0 0
3 1 1 0 0 0 0
+23
View File
@@ -0,0 +1,23 @@
1,2,1
1,4,-1
1,5,1
7,5,-1
7,6,-1
2,1,-1
2,3,1
2,4,1
6,2,1
6,4,-1
6,5,-1
3,1,-1
3,2,-1
3,4,1
3,5,1
5,3,-1
5,4,-1
5,6,1
5,7,1
4,2,-1
4,3,1
4,5,1
4,6,1
1 1 2 1
2 1 4 -1
3 1 5 1
4 7 5 -1
5 7 6 -1
6 2 1 -1
7 2 3 1
8 2 4 1
9 6 2 1
10 6 4 -1
11 6 5 -1
12 3 1 -1
13 3 2 -1
14 3 4 1
15 3 5 1
16 5 3 -1
17 5 4 -1
18 5 6 1
19 5 7 1
20 4 2 -1
21 4 3 1
22 4 5 1
23 4 6 1
+30
View File
@@ -0,0 +1,30 @@
10,4.4
14,5.6
12,4.6
18,6.1
16,6.0
14,7.0
22,6.8
28,10.6
26,11.0
16,7.6
23,10.8
25,10.0
20,6.5
20,8.2
24,8.8
12,5.5
15,5.0
18,8.0
14,7.8
26,9.0
25,9.4
17,8.5
12,6.4
20,7.5
23,9.0
22,8.1
26,8.2
22,10.0
18,9.1
21,9.0
1 10 4.4
2 14 5.6
3 12 4.6
4 18 6.1
5 16 6.0
6 14 7.0
7 22 6.8
8 28 10.6
9 26 11.0
10 16 7.6
11 23 10.8
12 25 10.0
13 20 6.5
14 20 8.2
15 24 8.8
16 12 5.5
17 15 5.0
18 18 8.0
19 14 7.8
20 26 9.0
21 25 9.4
22 17 8.5
23 12 6.4
24 20 7.5
25 23 9.0
26 22 8.1
27 26 8.2
28 22 10.0
29 18 9.1
30 21 9.0
+21
View File
@@ -0,0 +1,21 @@
1,6,1
7,9,-1
1,9,1
7,10,-1
2,5,-1
2,7,1
2,8,1
6,8,-1
6,9,-1
3,5,-1
3,6,-1
3,8,1
3,9,1
5,7,-1
5,8,-1
5,10,1
5,11,1
4,6,-1
4,7,-1
4,9,1
4,10,1
1 1 6 1
2 7 9 -1
3 1 9 1
4 7 10 -1
5 2 5 -1
6 2 7 1
7 2 8 1
8 6 8 -1
9 6 9 -1
10 3 5 -1
11 3 6 -1
12 3 8 1
13 3 9 1
14 5 7 -1
15 5 8 -1
16 5 10 1
17 5 11 1
18 4 6 -1
19 4 7 -1
20 4 9 1
21 4 10 1
+150
View File
@@ -0,0 +1,150 @@
2.8,1.9,-1,-1,1
2.9,1.8,-1,-1,1
2.2,1.5,-1,-1,1
1.3,5.6,-1,1,-1
-1.2,1.6,1,-1,-1
2.5,1.7,-1,-1,1
3.1,2.3,-1,-1,1
2.8,2.4,-1,-1,1
-1.2,1.5,1,-1,-1
1.4,6.1,-1,1,-1
-1.2,1.3,1,-1,-1
3.1,1.8,-1,-1,1
3.3,2.5,-1,-1,1
3.4,2.3,-1,-1,1
1.5,5.9,-1,1,-1
1.3,5.6,-1,1,-1
-1.2,1,1,-1,-1
3,2.1,-1,-1,1
1.4,5.2,-1,1,-1
1.2,5.5,-1,1,-1
1.4,6.7,-1,1,-1
-1.3,1.7,1,-1,-1
1,5.7,-1,1,-1
2.6,1.4,-1,-1,1
1.6,6,-1,1,-1
1.2,5.8,-1,1,-1
1.4,6.1,-1,1,-1
1.3,5.7,-1,1,-1
-1.2,1.4,1,-1,-1
1,5.5,-1,1,-1
3.1,2.1,-1,-1,1
-1.4,1.7,1,-1,-1
1.6,6.3,-1,1,-1
-1.2,1.4,1,-1,-1
2.7,1.9,-1,-1,1
1.1,5.5,-1,1,-1
3,1.8,-1,-1,1
3.8,2,-1,-1,1
2.8,2.1,-1,-1,1
1,5,-1,1,-1
2.8,2,-1,-1,1
-1.2,1.6,1,-1,-1
1.3,6.6,-1,1,-1
1.6,6,-1,1,-1
3,1.6,-1,-1,1
-1.1,1.1,1,-1,-1
2.9,1.8,-1,-1,1
3,1.8,-1,-1,1
-1.2,1.4,1,-1,-1
1,5.8,-1,1,-1
1.2,5.7,-1,1,-1
2.8,1.5,-1,-1,1
-1.4,1.6,1,-1,-1
-1.2,1.4,1,-1,-1
2.8,2.2,-1,-1,1
-1.5,1.7,1,-1,-1
1,4.9,-1,1,-1
1.3,5.7,-1,1,-1
3.2,2.3,-1,-1,1
-1.3,1.5,1,-1,-1
-1.2,1.2,1,-1,-1
-1.2,1.6,1,-1,-1
3,2.1,-1,-1,1
-1.4,1.5,1,-1,-1
1.3,5.5,-1,1,-1
3.3,2.5,-1,-1,1
3.1,2.4,-1,-1,1
1.8,5.9,-1,1,-1
2.7,1.9,-1,-1,1
1.5,6.3,-1,1,-1
-1.3,1.4,1,-1,-1
1,5,-1,1,-1
3.2,2.3,-1,-1,1
-1.3,1.4,1,-1,-1
3,2.1,-1,-1,1
3.2,2,-1,-1,1
1.3,6.3,-1,1,-1
1.4,7,-1,1,-1
-1.2,1.7,1,-1,-1
1.4,6.6,-1,1,-1
1.2,5.8,-1,1,-1
3,2,-1,-1,1
-1.2,1.6,1,-1,-1
1.5,6.2,-1,1,-1
1.5,6.4,-1,1,-1
-1.2,1.9,1,-1,-1
3.2,2.3,-1,-1,1
-1.2,1.5,1,-1,-1
1.5,5.4,-1,1,-1
1.5,6,-1,1,-1
1.5,6.9,-1,1,-1
-1.4,1.5,1,-1,-1
1.3,6.4,-1,1,-1
2.8,2,-1,-1,1
-1.2,1.5,1,-1,-1
-1.1,1.5,1,-1,-1
3.6,2.5,-1,-1,1
1.1,5.1,-1,1,-1
-1.1,1.5,1,-1,-1
-1.2,1.5,1,-1,-1
3.4,2.4,-1,-1,1
-1.3,1.3,1,-1,-1
3,2.3,-1,-1,1
-1.1,1.5,1,-1,-1
1.1,5.6,-1,1,-1
1.3,5.6,-1,1,-1
-1.2,1.5,1,-1,-1
-1.2,1.3,1,-1,-1
1.7,6.7,-1,1,-1
-1.2,1.3,1,-1,-1
-1.4,1.3,1,-1,-1
2.5,1.8,-1,-1,1
-1.4,1.5,1,-1,-1
1.5,6.5,-1,1,-1
2.6,2.3,-1,-1,1
-1.2,1.4,1,-1,-1
1.5,5.6,-1,1,-1
1.3,5.7,-1,1,-1
1.2,6.1,-1,1,-1
3,2.2,-1,-1,1
3,1.8,-1,-1,1
-1.1,1.4,1,-1,-1
1.4,6.8,-1,1,-1
-1.6,1.6,1,-1,-1
-1.2,1.4,1,-1,-1
3.2,1.8,-1,-1,1
-1.2,1.5,1,-1,-1
2.7,1.8,-1,-1,1
-1.3,1.4,1,-1,-1
1.3,6.2,-1,1,-1
-1.3,1.3,1,-1,-1
3,1.8,-1,-1,1
2.7,1.9,-1,-1,1
-1.2,1.4,1,-1,-1
-1.2,1.2,1,-1,-1
1.5,6.7,-1,1,-1
2.5,1.9,-1,-1,1
3.3,2.1,-1,-1,1
2.8,1.8,-1,-1,1
-1.2,1.3,1,-1,-1
3.8,2.2,-1,-1,1
2.5,2,-1,-1,1
1.3,6.1,-1,1,-1
-1.2,1.4,1,-1,-1
-1.1,1.5,1,-1,-1
3,2.3,-1,-1,1
-1.4,1.9,1,-1,-1
-1.2,1.6,1,-1,-1
1,6,-1,1,-1
1.3,5.5,-1,1,-1
1 2.8 1.9 -1 -1 1
2 2.9 1.8 -1 -1 1
3 2.2 1.5 -1 -1 1
4 1.3 5.6 -1 1 -1
5 -1.2 1.6 1 -1 -1
6 2.5 1.7 -1 -1 1
7 3.1 2.3 -1 -1 1
8 2.8 2.4 -1 -1 1
9 -1.2 1.5 1 -1 -1
10 1.4 6.1 -1 1 -1
11 -1.2 1.3 1 -1 -1
12 3.1 1.8 -1 -1 1
13 3.3 2.5 -1 -1 1
14 3.4 2.3 -1 -1 1
15 1.5 5.9 -1 1 -1
16 1.3 5.6 -1 1 -1
17 -1.2 1 1 -1 -1
18 3 2.1 -1 -1 1
19 1.4 5.2 -1 1 -1
20 1.2 5.5 -1 1 -1
21 1.4 6.7 -1 1 -1
22 -1.3 1.7 1 -1 -1
23 1 5.7 -1 1 -1
24 2.6 1.4 -1 -1 1
25 1.6 6 -1 1 -1
26 1.2 5.8 -1 1 -1
27 1.4 6.1 -1 1 -1
28 1.3 5.7 -1 1 -1
29 -1.2 1.4 1 -1 -1
30 1 5.5 -1 1 -1
31 3.1 2.1 -1 -1 1
32 -1.4 1.7 1 -1 -1
33 1.6 6.3 -1 1 -1
34 -1.2 1.4 1 -1 -1
35 2.7 1.9 -1 -1 1
36 1.1 5.5 -1 1 -1
37 3 1.8 -1 -1 1
38 3.8 2 -1 -1 1
39 2.8 2.1 -1 -1 1
40 1 5 -1 1 -1
41 2.8 2 -1 -1 1
42 -1.2 1.6 1 -1 -1
43 1.3 6.6 -1 1 -1
44 1.6 6 -1 1 -1
45 3 1.6 -1 -1 1
46 -1.1 1.1 1 -1 -1
47 2.9 1.8 -1 -1 1
48 3 1.8 -1 -1 1
49 -1.2 1.4 1 -1 -1
50 1 5.8 -1 1 -1
51 1.2 5.7 -1 1 -1
52 2.8 1.5 -1 -1 1
53 -1.4 1.6 1 -1 -1
54 -1.2 1.4 1 -1 -1
55 2.8 2.2 -1 -1 1
56 -1.5 1.7 1 -1 -1
57 1 4.9 -1 1 -1
58 1.3 5.7 -1 1 -1
59 3.2 2.3 -1 -1 1
60 -1.3 1.5 1 -1 -1
61 -1.2 1.2 1 -1 -1
62 -1.2 1.6 1 -1 -1
63 3 2.1 -1 -1 1
64 -1.4 1.5 1 -1 -1
65 1.3 5.5 -1 1 -1
66 3.3 2.5 -1 -1 1
67 3.1 2.4 -1 -1 1
68 1.8 5.9 -1 1 -1
69 2.7 1.9 -1 -1 1
70 1.5 6.3 -1 1 -1
71 -1.3 1.4 1 -1 -1
72 1 5 -1 1 -1
73 3.2 2.3 -1 -1 1
74 -1.3 1.4 1 -1 -1
75 3 2.1 -1 -1 1
76 3.2 2 -1 -1 1
77 1.3 6.3 -1 1 -1
78 1.4 7 -1 1 -1
79 -1.2 1.7 1 -1 -1
80 1.4 6.6 -1 1 -1
81 1.2 5.8 -1 1 -1
82 3 2 -1 -1 1
83 -1.2 1.6 1 -1 -1
84 1.5 6.2 -1 1 -1
85 1.5 6.4 -1 1 -1
86 -1.2 1.9 1 -1 -1
87 3.2 2.3 -1 -1 1
88 -1.2 1.5 1 -1 -1
89 1.5 5.4 -1 1 -1
90 1.5 6 -1 1 -1
91 1.5 6.9 -1 1 -1
92 -1.4 1.5 1 -1 -1
93 1.3 6.4 -1 1 -1
94 2.8 2 -1 -1 1
95 -1.2 1.5 1 -1 -1
96 -1.1 1.5 1 -1 -1
97 3.6 2.5 -1 -1 1
98 1.1 5.1 -1 1 -1
99 -1.1 1.5 1 -1 -1
100 -1.2 1.5 1 -1 -1
101 3.4 2.4 -1 -1 1
102 -1.3 1.3 1 -1 -1
103 3 2.3 -1 -1 1
104 -1.1 1.5 1 -1 -1
105 1.1 5.6 -1 1 -1
106 1.3 5.6 -1 1 -1
107 -1.2 1.5 1 -1 -1
108 -1.2 1.3 1 -1 -1
109 1.7 6.7 -1 1 -1
110 -1.2 1.3 1 -1 -1
111 -1.4 1.3 1 -1 -1
112 2.5 1.8 -1 -1 1
113 -1.4 1.5 1 -1 -1
114 1.5 6.5 -1 1 -1
115 2.6 2.3 -1 -1 1
116 -1.2 1.4 1 -1 -1
117 1.5 5.6 -1 1 -1
118 1.3 5.7 -1 1 -1
119 1.2 6.1 -1 1 -1
120 3 2.2 -1 -1 1
121 3 1.8 -1 -1 1
122 -1.1 1.4 1 -1 -1
123 1.4 6.8 -1 1 -1
124 -1.6 1.6 1 -1 -1
125 -1.2 1.4 1 -1 -1
126 3.2 1.8 -1 -1 1
127 -1.2 1.5 1 -1 -1
128 2.7 1.8 -1 -1 1
129 -1.3 1.4 1 -1 -1
130 1.3 6.2 -1 1 -1
131 -1.3 1.3 1 -1 -1
132 3 1.8 -1 -1 1
133 2.7 1.9 -1 -1 1
134 -1.2 1.4 1 -1 -1
135 -1.2 1.2 1 -1 -1
136 1.5 6.7 -1 1 -1
137 2.5 1.9 -1 -1 1
138 3.3 2.1 -1 -1 1
139 2.8 1.8 -1 -1 1
140 -1.2 1.3 1 -1 -1
141 3.8 2.2 -1 -1 1
142 2.5 2 -1 -1 1
143 1.3 6.1 -1 1 -1
144 -1.2 1.4 1 -1 -1
145 -1.1 1.5 1 -1 -1
146 3 2.3 -1 -1 1
147 -1.4 1.9 1 -1 -1
148 -1.2 1.6 1 -1 -1
149 1 6 -1 1 -1
150 1.3 5.5 -1 1 -1
+4
View File
@@ -0,0 +1,4 @@
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-1,-1
0,0,1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,-1,1,-1,-1
1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,-1,-1,1,-1
0,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,1,1,1,0,0,0,0,0,0,-1,-1,-1,1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 -1 -1
2 0 0 1 0 0 0 0 1 0 0 1 1 1 1 1 0 0 1 0 0 0 0 1 0 0 -1 1 -1 -1
3 1 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 1 -1 -1 1 -1
4 0 0 0 0 0 0 1 1 1 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 0 -1 -1 -1 1
+100
View File
@@ -0,0 +1,100 @@
-1.56,0.93,0.0
1.43,-1.29,0.0
1.03,0.59,1.0
0.21,-0.04,1.0
-0.62,1.25,0.0
1.21,0.35,1.0
-0.1,-0.26,1.0
-1.59,1.75,0.0
-1.45,1.71,0.0
0.79,-1.93,0.0
0.32,0.28,1.0
0.57,0.4,1.0
0.75,-0.07,1.0
-0.09,0.15,1.0
1.79,1.15,0.0
0.2,-0.18,1.0
1.85,0.34,0.0
-0.53,-1.25,0.0
-0.4,0.54,1.0
0.45,0,1.0
0.04,0.59,1.0
0.07,-0.81,0.0
-0.28,0.78,1.0
0.21,1.53,0.0
1.14,0.14,1.0
-0.51,0.06,1.0
-1.21,0.76,0.0
0.35,0.64,1.0
-0.65,0.56,1.0
1.48,1.31,0.0
1.6,1.73,0.0
0.82,0.68,1.0
-1.09,-1.18,0.0
1.75,-0.75,0.0
-0.14,0.32,1.0
-1.39,-1.93,0.0
0.84,-0.1,1.0
-0.35,0.43,1.0
-0.57,0.31,1.0
0.51,-1.26,0.0
-0.31,-1.71,0.0
-1.48,1.25,0.0
-1.71,0.18,0.0
-0.31,0.7,1.0
0.07,0.98,1.0
0.92,0.42,1.0
0.71,1.73,0.0
-1.45,-0.92,0.0
1.43,1.01,0.0
0.6,0.1,1.0
0.07,-1.31,0.0
0.76,0.37,1.0
-0.9,0.93,0.0
0.07,0.09,1.0
0.95,0.48,1.0
1.31,1.57,0.0
-0.73,-0.68,0.0
0.17,0.37,1.0
-0.12,0.76,1.0
1.14,1.31,0.0
-0.45,-0.07,1.0
0.21,0.43,1.0
-0.01,0.25,1.0
0.04,1.82,0.0
-0.87,-1.56,0.0
0.57,-0.21,1.0
0.37,0.51,1.0
0.43,0.29,1.0
0.31,-1.68,0.0
1.25,-1.75,0.0
0.54,0.67,1.0
1.29,-0.73,0.0
1.75,-0.25,0.0
0.42,-1.06,0.0
-0.26,-0.98,0.0
1.01,-1.34,0.0
-0.28,1.32,0.0
0.62,-1.32,0.0
0.4,0.9,1.0
0.28,-0.09,1.0
-1.07,1.32,0.0
1.56,-0.26,0.0
1,0.23,1.0
-0.06,0.48,1.0
-0.18,-0.1,1.0
-0.53,0.2,1.0
0.9,0.15,1.0
-0.51,1.68,0.0
-0.76,0.28,1.0
0.25,0.78,1.0
1.68,0.67,0.0
-1.48,-0.43,0.0
-1.64,-1.39,0.0
0.76,-0.92,0.0
1.09,0.51,1.0
0.65,0.67,1.0
-0.37,0.17,1.0
-1.06,-0.23,0.0
0.59,1.42,0.0
-1.32,0.23,0.0
1 -1.56 0.93 0.0
2 1.43 -1.29 0.0
3 1.03 0.59 1.0
4 0.21 -0.04 1.0
5 -0.62 1.25 0.0
6 1.21 0.35 1.0
7 -0.1 -0.26 1.0
8 -1.59 1.75 0.0
9 -1.45 1.71 0.0
10 0.79 -1.93 0.0
11 0.32 0.28 1.0
12 0.57 0.4 1.0
13 0.75 -0.07 1.0
14 -0.09 0.15 1.0
15 1.79 1.15 0.0
16 0.2 -0.18 1.0
17 1.85 0.34 0.0
18 -0.53 -1.25 0.0
19 -0.4 0.54 1.0
20 0.45 0 1.0
21 0.04 0.59 1.0
22 0.07 -0.81 0.0
23 -0.28 0.78 1.0
24 0.21 1.53 0.0
25 1.14 0.14 1.0
26 -0.51 0.06 1.0
27 -1.21 0.76 0.0
28 0.35 0.64 1.0
29 -0.65 0.56 1.0
30 1.48 1.31 0.0
31 1.6 1.73 0.0
32 0.82 0.68 1.0
33 -1.09 -1.18 0.0
34 1.75 -0.75 0.0
35 -0.14 0.32 1.0
36 -1.39 -1.93 0.0
37 0.84 -0.1 1.0
38 -0.35 0.43 1.0
39 -0.57 0.31 1.0
40 0.51 -1.26 0.0
41 -0.31 -1.71 0.0
42 -1.48 1.25 0.0
43 -1.71 0.18 0.0
44 -0.31 0.7 1.0
45 0.07 0.98 1.0
46 0.92 0.42 1.0
47 0.71 1.73 0.0
48 -1.45 -0.92 0.0
49 1.43 1.01 0.0
50 0.6 0.1 1.0
51 0.07 -1.31 0.0
52 0.76 0.37 1.0
53 -0.9 0.93 0.0
54 0.07 0.09 1.0
55 0.95 0.48 1.0
56 1.31 1.57 0.0
57 -0.73 -0.68 0.0
58 0.17 0.37 1.0
59 -0.12 0.76 1.0
60 1.14 1.31 0.0
61 -0.45 -0.07 1.0
62 0.21 0.43 1.0
63 -0.01 0.25 1.0
64 0.04 1.82 0.0
65 -0.87 -1.56 0.0
66 0.57 -0.21 1.0
67 0.37 0.51 1.0
68 0.43 0.29 1.0
69 0.31 -1.68 0.0
70 1.25 -1.75 0.0
71 0.54 0.67 1.0
72 1.29 -0.73 0.0
73 1.75 -0.25 0.0
74 0.42 -1.06 0.0
75 -0.26 -0.98 0.0
76 1.01 -1.34 0.0
77 -0.28 1.32 0.0
78 0.62 -1.32 0.0
79 0.4 0.9 1.0
80 0.28 -0.09 1.0
81 -1.07 1.32 0.0
82 1.56 -0.26 0.0
83 1 0.23 1.0
84 -0.06 0.48 1.0
85 -0.18 -0.1 1.0
86 -0.53 0.2 1.0
87 0.9 0.15 1.0
88 -0.51 1.68 0.0
89 -0.76 0.28 1.0
90 0.25 0.78 1.0
91 1.68 0.67 0.0
92 -1.48 -0.43 0.0
93 -1.64 -1.39 0.0
94 0.76 -0.92 0.0
95 1.09 0.51 1.0
96 0.65 0.67 1.0
97 -0.37 0.17 1.0
98 -1.06 -0.23 0.0
99 0.59 1.42 0.0
100 -1.32 0.23 0.0
+150
View File
@@ -0,0 +1,150 @@
-0.87,0.7,0.0,0.0,1.0
-0.62,-0.78,1.0,0.0,0.0
0.73,1.09,0.0,0.0,1.0
0.32,-0.2,1.0,0.0,0.0
0.18,-1.07,1.0,0.0,0.0
-0.45,-0.51,1.0,0.0,0.0
0.28,0.89,0.0,0.0,1.0
1.67,0.75,0.0,1.0,0.0
-0.21,0.95,0.0,0.0,1.0
1.48,0.01,0.0,1.0,0.0
1.75,1.07,0.0,1.0,0.0
1.64,1.78,0.0,1.0,0.0
0.76,-1.28,1.0,0.0,0.0
-0.56,1.17,0.0,0.0,1.0
1.73,1.59,0.0,1.0,0.0
1.1,-0.7,1.0,0.0,0.0
1.67,0.62,0.0,1.0,0.0
0.17,-0.62,1.0,0.0,0.0
0.64,1.71,0.0,0.0,1.0
-1.73,-0.71,0.0,0.0,1.0
0.17,-0.48,1.0,0.0,0.0
1.82,0.92,0.0,1.0,0.0
-1.21,0.5,0.0,0.0,1.0
1.29,0.1,0.0,1.0,0.0
-1.78,-0.2,0.0,0.0,1.0
1.42,0.64,0.0,1.0,0.0
-0.21,1.21,0.0,0.0,1.0
-0.06,1.39,0.0,0.0,1.0
0.03,-1.92,1.0,0.0,0.0
1.15,0.6,0.0,1.0,0.0
-0.75,0.95,0.0,0.0,1.0
1.51,0.85,0.0,1.0,0.0
1.5,0.43,0.0,1.0,0.0
1.28,-0.5,1.0,0.0,0.0
1.1,0.29,0.0,1.0,0.0
-1.48,-0.65,0.0,0.0,1.0
1.18,-0.98,1.0,0.0,0.0
-1.53,0.62,0.0,0.0,1.0
-0.67,-0.32,1.0,0.0,0.0
0.89,-0.37,1.0,0.0,0.0
1.54,0.2,0.0,1.0,0.0
0.4,1.53,0.0,0.0,1.0
-0.62,0.5,0.0,0.0,1.0
1.84,1.73,0.0,1.0,0.0
-0.04,-0.35,1.0,0.0,0.0
-0.5,0.79,0.0,0.0,1.0
-0.31,1.51,0.0,0.0,1.0
1.7,0.82,0.0,1.0,0.0
1.29,0.34,0.0,1.0,0.0
0.5,-1.04,1.0,0.0,0.0
1.62,0.81,0.0,1.0,0.0
1.76,1.67,0.0,1.0,0.0
-0.35,-1,1.0,0.0,0.0
1.03,-0.53,1.0,0.0,0.0
-0.35,-0.64,1.0,0.0,0.0
1.31,0.35,0.0,1.0,0.0
0.68,-1.68,1.0,0.0,0.0
-0.98,0.28,0.0,0.0,1.0
-0.15,-0.17,1.0,0.0,0.0
-0.01,0.92,0.0,0.0,1.0
0.46,-1.68,1.0,0.0,0.0
1,0.59,0.0,1.0,0.0
0.51,-0.46,1.0,0.0,0.0
-0.15,-0.68,1.0,0.0,0.0
1.73,0.17,0.0,1.0,0.0
1.62,0.35,0.0,1.0,0.0
0.96,-1.06,1.0,0.0,0.0
0.06,-1.68,1.0,0.0,0.0
-1.48,-1.75,0.0,0.0,1.0
0.18,-1.39,1.0,0.0,0.0
1.12,0.2,0.0,1.0,0.0
-1.23,-1.32,0.0,0.0,1.0
-0.26,-0.39,1.0,0.0,0.0
1.82,1.48,0.0,1.0,0.0
-0.64,-0.56,1.0,0.0,0.0
-1.37,-1.46,0.0,0.0,1.0
1.43,0.21,0.0,1.0,0.0
-0.14,-1.6,1.0,0.0,0.0
0.9,1.46,0.0,0.0,1.0
0.87,0.18,0.0,1.0,0.0
-1.1,-1.62,0.0,0.0,1.0
-0.43,-0.29,1.0,0.0,0.0
-0.53,-0.12,1.0,0.0,0.0
0.12,1.14,0.0,0.0,1.0
0.18,-0.29,1.0,0.0,0.0
1.42,0.56,0.0,1.0,0.0
-0.82,-0.1,1.0,0.0,0.0
0.89,-0.71,1.0,0.0,0.0
1.12,1.62,0.0,0.0,1.0
-1.51,-0.06,0.0,0.0,1.0
-1.37,-0.93,0.0,0.0,1.0
0.87,0.4,0.0,1.0,0.0
-1.54,0.29,0.0,0.0,1.0
0.57,-1.9,1.0,0.0,0.0
-0.04,-0.71,1.0,0.0,0.0
0.5,-1.46,1.0,0.0,0.0
0.32,-0.39,1.0,0.0,0.0
-0.96,1.01,0.0,0.0,1.0
1.14,1.32,0.0,0.0,1.0
0.6,0.48,0.0,1.0,0.0
-1.5,-1.31,0.0,0.0,1.0
0.03,-0.85,1.0,0.0,0.0
1.67,1.26,0.0,1.0,0.0
0.34,-0.68,1.0,0.0,0.0
1.85,1.17,0.0,1.0,0.0
0.93,1.78,0.0,0.0,1.0
1.32,0.37,0.0,1.0,0.0
0.43,0.32,0.0,1.0,0.0
-1.18,0.57,0.0,0.0,1.0
-1.75,-1.67,0.0,0.0,1.0
1.71,1.89,0.0,1.0,0.0
0.2,-1.25,1.0,0.0,0.0
-1.21,0.92,0.0,0.0,1.0
1.76,1.75,0.0,1.0,0.0
-1.75,-1.03,0.0,0.0,1.0
-0.26,-1.23,1.0,0.0,0.0
0.95,-1.57,1.0,0.0,0.0
-0.18,-1.1,1.0,0.0,0.0
-0.17,-0.5,1.0,0.0,0.0
-0.89,0.56,0.0,0.0,1.0
-0.43,0.78,0.0,0.0,1.0
1.79,1.4,0.0,1.0,0.0
0.4,1.26,0.0,0.0,1.0
0.76,0.32,0.0,1.0,0.0
1.7,-0.03,0.0,1.0,0.0
0.68,-0.34,1.0,0.0,0.0
1.31,0.89,0.0,1.0,0.0
-0.32,-0.29,1.0,0.0,0.0
0.76,-0.9,1.0,0.0,0.0
1.9,1.82,0.0,1.0,0.0
1.54,1.03,0.0,1.0,0.0
-0.07,0.64,0.0,0.0,1.0
1.85,0.56,0.0,1.0,0.0
0.76,0.53,0.0,1.0,0.0
-1.65,0.06,0.0,0.0,1.0
1.04,-1.29,1.0,0.0,0.0
-0.39,0.64,0.0,0.0,1.0
1.14,0.42,0.0,1.0,0.0
-1.35,0.1,0.0,0.0,1.0
0.06,1.62,0.0,0.0,1.0
-1.26,-1.78,0.0,0.0,1.0
-1.39,-0.43,0.0,0.0,1.0
-0.87,-1.84,0.0,0.0,1.0
0.65,-0.65,1.0,0.0,0.0
1,0.43,0.0,1.0,0.0
0.64,0.32,0.0,1.0,0.0
0.75,1.85,0.0,0.0,1.0
0.57,0.21,0.0,1.0,0.0
0.14,0.29,0.0,1.0,0.0
1.09,0.68,0.0,1.0,0.0
1 -0.87 0.7 0.0 0.0 1.0
2 -0.62 -0.78 1.0 0.0 0.0
3 0.73 1.09 0.0 0.0 1.0
4 0.32 -0.2 1.0 0.0 0.0
5 0.18 -1.07 1.0 0.0 0.0
6 -0.45 -0.51 1.0 0.0 0.0
7 0.28 0.89 0.0 0.0 1.0
8 1.67 0.75 0.0 1.0 0.0
9 -0.21 0.95 0.0 0.0 1.0
10 1.48 0.01 0.0 1.0 0.0
11 1.75 1.07 0.0 1.0 0.0
12 1.64 1.78 0.0 1.0 0.0
13 0.76 -1.28 1.0 0.0 0.0
14 -0.56 1.17 0.0 0.0 1.0
15 1.73 1.59 0.0 1.0 0.0
16 1.1 -0.7 1.0 0.0 0.0
17 1.67 0.62 0.0 1.0 0.0
18 0.17 -0.62 1.0 0.0 0.0
19 0.64 1.71 0.0 0.0 1.0
20 -1.73 -0.71 0.0 0.0 1.0
21 0.17 -0.48 1.0 0.0 0.0
22 1.82 0.92 0.0 1.0 0.0
23 -1.21 0.5 0.0 0.0 1.0
24 1.29 0.1 0.0 1.0 0.0
25 -1.78 -0.2 0.0 0.0 1.0
26 1.42 0.64 0.0 1.0 0.0
27 -0.21 1.21 0.0 0.0 1.0
28 -0.06 1.39 0.0 0.0 1.0
29 0.03 -1.92 1.0 0.0 0.0
30 1.15 0.6 0.0 1.0 0.0
31 -0.75 0.95 0.0 0.0 1.0
32 1.51 0.85 0.0 1.0 0.0
33 1.5 0.43 0.0 1.0 0.0
34 1.28 -0.5 1.0 0.0 0.0
35 1.1 0.29 0.0 1.0 0.0
36 -1.48 -0.65 0.0 0.0 1.0
37 1.18 -0.98 1.0 0.0 0.0
38 -1.53 0.62 0.0 0.0 1.0
39 -0.67 -0.32 1.0 0.0 0.0
40 0.89 -0.37 1.0 0.0 0.0
41 1.54 0.2 0.0 1.0 0.0
42 0.4 1.53 0.0 0.0 1.0
43 -0.62 0.5 0.0 0.0 1.0
44 1.84 1.73 0.0 1.0 0.0
45 -0.04 -0.35 1.0 0.0 0.0
46 -0.5 0.79 0.0 0.0 1.0
47 -0.31 1.51 0.0 0.0 1.0
48 1.7 0.82 0.0 1.0 0.0
49 1.29 0.34 0.0 1.0 0.0
50 0.5 -1.04 1.0 0.0 0.0
51 1.62 0.81 0.0 1.0 0.0
52 1.76 1.67 0.0 1.0 0.0
53 -0.35 -1 1.0 0.0 0.0
54 1.03 -0.53 1.0 0.0 0.0
55 -0.35 -0.64 1.0 0.0 0.0
56 1.31 0.35 0.0 1.0 0.0
57 0.68 -1.68 1.0 0.0 0.0
58 -0.98 0.28 0.0 0.0 1.0
59 -0.15 -0.17 1.0 0.0 0.0
60 -0.01 0.92 0.0 0.0 1.0
61 0.46 -1.68 1.0 0.0 0.0
62 1 0.59 0.0 1.0 0.0
63 0.51 -0.46 1.0 0.0 0.0
64 -0.15 -0.68 1.0 0.0 0.0
65 1.73 0.17 0.0 1.0 0.0
66 1.62 0.35 0.0 1.0 0.0
67 0.96 -1.06 1.0 0.0 0.0
68 0.06 -1.68 1.0 0.0 0.0
69 -1.48 -1.75 0.0 0.0 1.0
70 0.18 -1.39 1.0 0.0 0.0
71 1.12 0.2 0.0 1.0 0.0
72 -1.23 -1.32 0.0 0.0 1.0
73 -0.26 -0.39 1.0 0.0 0.0
74 1.82 1.48 0.0 1.0 0.0
75 -0.64 -0.56 1.0 0.0 0.0
76 -1.37 -1.46 0.0 0.0 1.0
77 1.43 0.21 0.0 1.0 0.0
78 -0.14 -1.6 1.0 0.0 0.0
79 0.9 1.46 0.0 0.0 1.0
80 0.87 0.18 0.0 1.0 0.0
81 -1.1 -1.62 0.0 0.0 1.0
82 -0.43 -0.29 1.0 0.0 0.0
83 -0.53 -0.12 1.0 0.0 0.0
84 0.12 1.14 0.0 0.0 1.0
85 0.18 -0.29 1.0 0.0 0.0
86 1.42 0.56 0.0 1.0 0.0
87 -0.82 -0.1 1.0 0.0 0.0
88 0.89 -0.71 1.0 0.0 0.0
89 1.12 1.62 0.0 0.0 1.0
90 -1.51 -0.06 0.0 0.0 1.0
91 -1.37 -0.93 0.0 0.0 1.0
92 0.87 0.4 0.0 1.0 0.0
93 -1.54 0.29 0.0 0.0 1.0
94 0.57 -1.9 1.0 0.0 0.0
95 -0.04 -0.71 1.0 0.0 0.0
96 0.5 -1.46 1.0 0.0 0.0
97 0.32 -0.39 1.0 0.0 0.0
98 -0.96 1.01 0.0 0.0 1.0
99 1.14 1.32 0.0 0.0 1.0
100 0.6 0.48 0.0 1.0 0.0
101 -1.5 -1.31 0.0 0.0 1.0
102 0.03 -0.85 1.0 0.0 0.0
103 1.67 1.26 0.0 1.0 0.0
104 0.34 -0.68 1.0 0.0 0.0
105 1.85 1.17 0.0 1.0 0.0
106 0.93 1.78 0.0 0.0 1.0
107 1.32 0.37 0.0 1.0 0.0
108 0.43 0.32 0.0 1.0 0.0
109 -1.18 0.57 0.0 0.0 1.0
110 -1.75 -1.67 0.0 0.0 1.0
111 1.71 1.89 0.0 1.0 0.0
112 0.2 -1.25 1.0 0.0 0.0
113 -1.21 0.92 0.0 0.0 1.0
114 1.76 1.75 0.0 1.0 0.0
115 -1.75 -1.03 0.0 0.0 1.0
116 -0.26 -1.23 1.0 0.0 0.0
117 0.95 -1.57 1.0 0.0 0.0
118 -0.18 -1.1 1.0 0.0 0.0
119 -0.17 -0.5 1.0 0.0 0.0
120 -0.89 0.56 0.0 0.0 1.0
121 -0.43 0.78 0.0 0.0 1.0
122 1.79 1.4 0.0 1.0 0.0
123 0.4 1.26 0.0 0.0 1.0
124 0.76 0.32 0.0 1.0 0.0
125 1.7 -0.03 0.0 1.0 0.0
126 0.68 -0.34 1.0 0.0 0.0
127 1.31 0.89 0.0 1.0 0.0
128 -0.32 -0.29 1.0 0.0 0.0
129 0.76 -0.9 1.0 0.0 0.0
130 1.9 1.82 0.0 1.0 0.0
131 1.54 1.03 0.0 1.0 0.0
132 -0.07 0.64 0.0 0.0 1.0
133 1.85 0.56 0.0 1.0 0.0
134 0.76 0.53 0.0 1.0 0.0
135 -1.65 0.06 0.0 0.0 1.0
136 1.04 -1.29 1.0 0.0 0.0
137 -0.39 0.64 0.0 0.0 1.0
138 1.14 0.42 0.0 1.0 0.0
139 -1.35 0.1 0.0 0.0 1.0
140 0.06 1.62 0.0 0.0 1.0
141 -1.26 -1.78 0.0 0.0 1.0
142 -1.39 -0.43 0.0 0.0 1.0
143 -0.87 -1.84 0.0 0.0 1.0
144 0.65 -0.65 1.0 0.0 0.0
145 1 0.43 0.0 1.0 0.0
146 0.64 0.32 0.0 1.0 0.0
147 0.75 1.85 0.0 0.0 1.0
148 0.57 0.21 0.0 1.0 0.0
149 0.14 0.29 0.0 1.0 0.0
150 1.09 0.68 0.0 1.0 0.0
+120
View File
@@ -0,0 +1,120 @@
-0.4,-1.32
1.7,-0.04
0.53,-0.07
-1.9,1.09
0.53,0.12
1.85,0.17
-1.35,-0.46
0.4,-0.15
1.73,0.32
-0.67,-0.71
0.21,-0.03
0.26,-0.59
-1.45,-0.04
0.09,-1.06
-1.17,0.46
-0.25,-1.42
-1.71,0.7
0.42,0.25
-1.23,-0.21
1.34,0.07
-0.98,-1.17
-1.9,0.84
0.39,-0.71
-0.71,-1.32
1.82,-0.1
0.79,0.18
1.65,0.39
-1.65,1
1.01,0.03
0.56,0.39
-1.64,0.98
0.89,0.29
-1.23,0.2
-1.32,0.46
-0.1,-0.85
-0.68,-1.04
1.12,0.25
-1.79,1.09
-1.39,1.17
-1.79,1.71
1.37,0.15
-0.76,-0.64
0.75,0.34
-1.67,0.39
-0.07,-0.65
0.4,-0.17
1.06,0.56
-0.96,-0.35
0.98,0.42
-0.39,-1.15
-0.51,-1.4
1.5,0.32
-0.84,-0.85
1.76,0.34
-0.28,-1.09
-1.59,1.14
-0.07,-0.75
-0.81,-0.43
-0.5,-1.1
-1.84,1.54
-0.84,-0.84
1.37,0.35
-1.59,1.56
-1.12,-0.79
-0.46,-0.87
-0.87,-1.07
-1.46,0.81
-1.59,0.1
0.29,-0.4
-0.01,-1.1
0.85,0.51
-1.45,0.34
-1.26,0.34
1.37,0.26
0,-0.79
-1.07,0.1
1.35,0.51
0.82,0.35
-1.67,1.35
0.82,0.09
0.51,-0.03
0.07,-0.75
-0.07,-1.01
0.35,-0.07
-0.73,-0.15
-1.64,1.39
-0.67,-0.82
-0.29,-1.03
0.75,0.51
-0.84,-0.64
-1.4,0.1
-1.07,0.07
-0.21,-1.21
-1.45,0.98
1.2,0.45
-0.28,-1.1
0.09,-0.26
-1.32,0.5
1.12,0.34
-1.53,0.54
-1.65,1.64
1.75,0.04
0.7,0
0.89,0.09
-1.29,0
-1.73,0.9
1,0.51
-1.14,-0.14
1.7,0.21
-0.98,-0.64
-0.92,-0.23
-0.23,-0.89
-0.37,-1.34
1.48,0.03
0.51,-0.28
-1.04,0.32
-1.56,0.85
1.57,0.42
-1.26,0.76
-1.81,1.25
1 -0.4 -1.32
2 1.7 -0.04
3 0.53 -0.07
4 -1.9 1.09
5 0.53 0.12
6 1.85 0.17
7 -1.35 -0.46
8 0.4 -0.15
9 1.73 0.32
10 -0.67 -0.71
11 0.21 -0.03
12 0.26 -0.59
13 -1.45 -0.04
14 0.09 -1.06
15 -1.17 0.46
16 -0.25 -1.42
17 -1.71 0.7
18 0.42 0.25
19 -1.23 -0.21
20 1.34 0.07
21 -0.98 -1.17
22 -1.9 0.84
23 0.39 -0.71
24 -0.71 -1.32
25 1.82 -0.1
26 0.79 0.18
27 1.65 0.39
28 -1.65 1
29 1.01 0.03
30 0.56 0.39
31 -1.64 0.98
32 0.89 0.29
33 -1.23 0.2
34 -1.32 0.46
35 -0.1 -0.85
36 -0.68 -1.04
37 1.12 0.25
38 -1.79 1.09
39 -1.39 1.17
40 -1.79 1.71
41 1.37 0.15
42 -0.76 -0.64
43 0.75 0.34
44 -1.67 0.39
45 -0.07 -0.65
46 0.4 -0.17
47 1.06 0.56
48 -0.96 -0.35
49 0.98 0.42
50 -0.39 -1.15
51 -0.51 -1.4
52 1.5 0.32
53 -0.84 -0.85
54 1.76 0.34
55 -0.28 -1.09
56 -1.59 1.14
57 -0.07 -0.75
58 -0.81 -0.43
59 -0.5 -1.1
60 -1.84 1.54
61 -0.84 -0.84
62 1.37 0.35
63 -1.59 1.56
64 -1.12 -0.79
65 -0.46 -0.87
66 -0.87 -1.07
67 -1.46 0.81
68 -1.59 0.1
69 0.29 -0.4
70 -0.01 -1.1
71 0.85 0.51
72 -1.45 0.34
73 -1.26 0.34
74 1.37 0.26
75 0 -0.79
76 -1.07 0.1
77 1.35 0.51
78 0.82 0.35
79 -1.67 1.35
80 0.82 0.09
81 0.51 -0.03
82 0.07 -0.75
83 -0.07 -1.01
84 0.35 -0.07
85 -0.73 -0.15
86 -1.64 1.39
87 -0.67 -0.82
88 -0.29 -1.03
89 0.75 0.51
90 -0.84 -0.64
91 -1.4 0.1
92 -1.07 0.07
93 -0.21 -1.21
94 -1.45 0.98
95 1.2 0.45
96 -0.28 -1.1
97 0.09 -0.26
98 -1.32 0.5
99 1.12 0.34
100 -1.53 0.54
101 -1.65 1.64
102 1.75 0.04
103 0.7 0
104 0.89 0.09
105 -1.29 0
106 -1.73 0.9
107 1 0.51
108 -1.14 -0.14
109 1.7 0.21
110 -0.98 -0.64
111 -0.92 -0.23
112 -0.23 -0.89
113 -0.37 -1.34
114 1.48 0.03
115 0.51 -0.28
116 -1.04 0.32
117 -1.56 0.85
118 1.57 0.42
119 -1.26 0.76
120 -1.81 1.25
+2 -2
View File
@@ -11,9 +11,9 @@ const links = [
data: { type: 'simple' }, data: { type: 'simple' },
}, },
{ {
name: 'Perceptron Complex', name: 'Descente du gradient',
href: '/perceptron', href: '/perceptron',
data: { type: 'complex' }, data: { type: 'gradientdescent' },
}, },
]; ];
@@ -7,7 +7,7 @@ import type {
} from 'chart.js'; } from 'chart.js';
import { computed } from 'vue'; import { computed } from 'vue';
import { Chart } from 'vue-chartjs'; import { Chart } from 'vue-chartjs';
import { colors } from '@/types/graphs'; import { colors, gridColor, gridColorBold } from '@/types/graphs';
import type { Iteration } from '@/types/perceptron'; import type { Iteration } from '@/types/perceptron';
const props = defineProps<{ const props = defineProps<{
@@ -157,10 +157,28 @@ function getPerceptronDecisionBoundaryDataset(
x: { x: {
type: 'linear', type: 'linear',
position: 'bottom', position: 'bottom',
grid: {
color: function (context) {
if (context.tick.value == 0) {
return gridColorBold;
}
return gridColor;
},
},
}, },
y: { y: {
type: 'linear', type: 'linear',
position: 'left', position: 'left',
grid: {
color: function (context) {
if (context.tick.value == 0) {
return gridColorBold;
}
return gridColor;
},
},
}, },
}, },
}" }"
@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ChartData } from 'chart.js'; import type { ChartData } from 'chart.js';
import { Bar } from 'vue-chartjs'; import { Bar } from 'vue-chartjs';
import { colors } from '@/types/graphs'; import { colors, gridColor, gridColorBold } from '@/types/graphs';
import type { Iteration } from '@/types/perceptron'; import type { Iteration } from '@/types/perceptron';
const props = defineProps<{ const props = defineProps<{
@@ -17,6 +17,7 @@ function getPerceptronErrorsPerIteration(): ChartData<
>[] { >[] {
const datasets: ChartData<'bar', (number | [number, number] | null)[]>[] = const datasets: ChartData<'bar', (number | [number, number] | null)[]>[] =
[]; [];
const epochAverageError: number[] = [];
const backgroundColors = colors; const backgroundColors = colors;
@@ -27,6 +28,7 @@ function getPerceptronErrorsPerIteration(): ChartData<
dataset = { dataset = {
label: exampleLabel, label: exampleLabel,
data: [], data: [],
order: 1,
backgroundColor: backgroundColor:
backgroundColors[ backgroundColors[
iteration.exampleIndex % backgroundColors.length iteration.exampleIndex % backgroundColors.length
@@ -35,6 +37,11 @@ function getPerceptronErrorsPerIteration(): ChartData<
datasets.push(dataset); datasets.push(dataset);
} }
dataset.data.push(iteration.error); dataset.data.push(iteration.error);
// Epoch error
epochAverageError[iteration.iteration - 1] =
(epochAverageError[iteration.iteration - 1] || 0) +
iteration.error ** 2 / 2;
}); });
// Sort dataset by label (Exemple 0, Exemple 1, ...) // Sort dataset by label (Exemple 0, Exemple 1, ...)
@@ -44,6 +51,23 @@ function getPerceptronErrorsPerIteration(): ChartData<
return aIndex - bIndex; return aIndex - bIndex;
}); });
// Epoch error
const epochErrorDataset = {
type: 'line',
label: "Erreur de l'époque",
data: [],
backgroundColor: '#fff',
borderColor: '#fff',
order: 0,
tension: 0.3,
};
epochAverageError.forEach((error) => {
epochErrorDataset.data.push(error);
});
datasets.push(epochErrorDataset);
return datasets; return datasets;
} }
</script> </script>
@@ -68,6 +92,15 @@ function getPerceptronErrorsPerIteration(): ChartData<
y: { y: {
stacked: true, stacked: true,
beginAtZero: true, beginAtZero: true,
grid: {
color: function (context) {
if (context.tick.value == 0) {
return gridColorBold;
}
return gridColor;
},
},
}, },
}, },
}" }"
+2 -2
View File
@@ -73,10 +73,10 @@ function startTraining() {
}, },
credentials: 'same-origin', credentials: 'same-origin',
body: JSON.stringify({ body: JSON.stringify({
type: 'simple', type: props.type,
dataset: selectedDatasetCopy.value, dataset: selectedDatasetCopy.value,
weight_init_method: selectedMethod.value, weight_init_method: selectedMethod.value,
min_error: 0.01, min_error: minError.value,
learning_rate: learningRate.value, learning_rate: learningRate.value,
session_id: props.sessionId, session_id: props.sessionId,
training_id: trainingId.value, training_id: trainingId.value,
+2
View File
@@ -155,6 +155,8 @@ function getActivationFunction(type: string): (x: number) => number {
return (x) => 1 / (1 + Math.exp(-x)); return (x) => 1 / (1 + Math.exp(-x));
case 'tanh': case 'tanh':
return (x) => Math.tanh(x); return (x) => Math.tanh(x);
case 'linear':
return (x) => x;
default: default:
return (x) => x; // Identity function as fallback return (x) => x; // Identity function as fallback
} }
+3
View File
@@ -32,3 +32,6 @@ export const colors = [
'#DC143C', '#DC143C',
'#00FF00', '#00FF00',
] as const; ] as const;
export const gridColor = '#444';
export const gridColorBold = '#999';