Various fixess and xor
This commit is contained in:
@@ -6,6 +6,7 @@ use Illuminate\Broadcasting\Channel;
|
|||||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||||
use Illuminate\Foundation\Events\Dispatchable;
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
class PerceptronTrainingIteration implements ShouldBroadcast
|
class PerceptronTrainingIteration implements ShouldBroadcast
|
||||||
@@ -38,9 +39,15 @@ class PerceptronTrainingIteration implements ShouldBroadcast
|
|||||||
|
|
||||||
public function broadcastWith(): array
|
public function broadcastWith(): array
|
||||||
{
|
{
|
||||||
|
$weights = collect($this->iterations)
|
||||||
|
->pluck('weights')
|
||||||
|
->first(fn (array $weights): bool => $weights !== []);
|
||||||
|
$shouldBroadcastAllWeights = $weights !== null
|
||||||
|
&& count(Arr::flatten($weights)) <= config('perceptron.max_displayed_weights');
|
||||||
|
|
||||||
$lastIterationIndex = count($this->iterations) - 1;
|
$lastIterationIndex = count($this->iterations) - 1;
|
||||||
$iterations = array_map(
|
$iterations = array_map(
|
||||||
fn (array $iteration, int $index): array => $index === $lastIterationIndex
|
fn (array $iteration, int $index): array => $shouldBroadcastAllWeights || $index === $lastIterationIndex
|
||||||
? $iteration
|
? $iteration
|
||||||
: [...$iteration, 'weights' => []],
|
: [...$iteration, 'weights' => []],
|
||||||
$this->iterations,
|
$this->iterations,
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class PerceptronController extends Controller
|
|||||||
break;
|
break;
|
||||||
case 'multilayer':
|
case 'multilayer':
|
||||||
$learningRate = 0.8;
|
$learningRate = 0.8;
|
||||||
|
$maxIterations = 2000;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,6 +110,17 @@ class PerceptronController extends Controller
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'logic_xor':
|
||||||
|
switch ($perceptronType) {
|
||||||
|
case 'multilayer':
|
||||||
|
$dataset['defaultLearningRate'] = 0.3;
|
||||||
|
$dataset['defaultMinError'] = 0.001;
|
||||||
|
$dataset['defaultMaxIterations'] = 500;
|
||||||
|
$dataset['defaultHiddenLayers'] = 1;
|
||||||
|
$dataset['defaultHiddenLayersNeurons'] = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'table_2_9':
|
case 'table_2_9':
|
||||||
switch ($perceptronType) {
|
switch ($perceptronType) {
|
||||||
case 'simple':
|
case 'simple':
|
||||||
@@ -132,6 +144,15 @@ class PerceptronController extends Controller
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'table_4_17':
|
||||||
|
switch ($perceptronType) {
|
||||||
|
case 'multilayer':
|
||||||
|
$dataset['defaultLearningRate'] = 0.5;
|
||||||
|
$dataset['defaultMinError'] = 0.08;
|
||||||
|
$dataset['defaultMaxIterations'] = 400;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
$datasets[] = $dataset;
|
$datasets[] = $dataset;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,10 @@ return [
|
|||||||
'broadcast_iteration_size' => 75,
|
'broadcast_iteration_size' => 75,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide the weight columns in the iteration table above this count.
|
* Maximum number of weights for which all iteration weights are broadcast
|
||||||
|
* and displayed in the iteration table.
|
||||||
*/
|
*/
|
||||||
'max_displayed_weights' => 25,
|
'max_displayed_weights' => 5,
|
||||||
|
|
||||||
'run_inputs_validation' => [
|
'run_inputs_validation' => [
|
||||||
'hidden_layers' => 'required|integer|min:1|max:5',
|
'hidden_layers' => 'required|integer|min:1|max:5',
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ watch(selectedDatasetCopy, (newvalue) => {
|
|||||||
if (selectedDatasetCopy && selectedDatasetCopy.defaultMaxIterations !== undefined) {
|
if (selectedDatasetCopy && selectedDatasetCopy.defaultMaxIterations !== undefined) {
|
||||||
maxIterations.value = selectedDatasetCopy.defaultMaxIterations;
|
maxIterations.value = selectedDatasetCopy.defaultMaxIterations;
|
||||||
}
|
}
|
||||||
|
// HiddenLayers
|
||||||
|
hiddenLayers.value = props.hiddenLayers;
|
||||||
|
if (selectedDatasetCopy && selectedDatasetCopy.defaultHiddenLayers !== undefined) {
|
||||||
|
hiddenLayers.value = selectedDatasetCopy.defaultHiddenLayers;
|
||||||
|
}
|
||||||
|
hiddenLayersNeurons.value = props.hiddenLayersNeurons;
|
||||||
|
if (selectedDatasetCopy && selectedDatasetCopy.defaultHiddenLayersNeurons !== undefined) {
|
||||||
|
hiddenLayersNeurons.value = selectedDatasetCopy.defaultHiddenLayersNeurons;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const trainingId = ref<string>('');
|
const trainingId = ref<string>('');
|
||||||
|
|||||||
@@ -140,6 +140,10 @@ function perceptronTrainingEnded(data: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const activationFunction = ref<string>('');
|
const activationFunction = ref<string>('');
|
||||||
|
const isRegression = computed(
|
||||||
|
() => props.type === 'multilayer' && activationFunction.value === 'linear',
|
||||||
|
);
|
||||||
|
|
||||||
function perceptroninitialization(data: any) {
|
function perceptroninitialization(data: any) {
|
||||||
console.log('Perceptron training initialized:', data);
|
console.log('Perceptron training initialized:', data);
|
||||||
if (data.trainingId !== trainingId.value) {
|
if (data.trainingId !== trainingId.value) {
|
||||||
@@ -216,7 +220,7 @@ function resetTraining() {
|
|||||||
<PerceptronDecisionGraph
|
<PerceptronDecisionGraph
|
||||||
:cleanedDataset="cleanedDataset"
|
:cleanedDataset="cleanedDataset"
|
||||||
:iterations="iterations"
|
:iterations="iterations"
|
||||||
:is-regression="activationFunction === 'linear'"
|
:is-regression="isRegression"
|
||||||
:activation-function="
|
:activation-function="
|
||||||
getActivationFunction(activationFunction)
|
getActivationFunction(activationFunction)
|
||||||
"
|
"
|
||||||
@@ -225,7 +229,7 @@ function resetTraining() {
|
|||||||
<div>
|
<div>
|
||||||
<PerceptronIterationsErrorsGraph
|
<PerceptronIterationsErrorsGraph
|
||||||
:iterations="iterations"
|
:iterations="iterations"
|
||||||
:is-regression="activationFunction === 'linear'"
|
:is-regression="isRegression"
|
||||||
v-if="iterations.length > 0"
|
v-if="iterations.length > 0"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ export type Dataset = {
|
|||||||
defaultLearningRate?: number;
|
defaultLearningRate?: number;
|
||||||
defaultMinError?: number;
|
defaultMinError?: number;
|
||||||
defaultMaxIterations?: number;
|
defaultMaxIterations?: number;
|
||||||
|
defaultHiddenLayers?: number;
|
||||||
|
defaultHiddenLayersNeurons?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DatasetPoint = {
|
export type DatasetPoint = {
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit\Events;
|
||||||
|
|
||||||
|
use App\Events\PerceptronTrainingIteration;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class PerceptronTrainingIterationTest extends TestCase
|
||||||
|
{
|
||||||
|
public function test_small_networks_keep_weights_for_every_iteration(): void
|
||||||
|
{
|
||||||
|
$event = new PerceptronTrainingIteration(
|
||||||
|
iterations: [
|
||||||
|
['epoch' => 1, 'exampleIndex' => 0, 'error' => 1, 'weights' => [[[1, 2]]]],
|
||||||
|
['epoch' => 1, 'exampleIndex' => 1, 'error' => 0, 'weights' => [[[3, 4]]]],
|
||||||
|
],
|
||||||
|
sessionId: 'session',
|
||||||
|
trainingId: 'training',
|
||||||
|
);
|
||||||
|
|
||||||
|
$iterations = $event->broadcastWith()['iterations'];
|
||||||
|
|
||||||
|
$this->assertSame([[[1, 2]]], $iterations[0]['weights']);
|
||||||
|
$this->assertSame([[[3, 4]]], $iterations[1]['weights']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_large_networks_only_keep_the_last_iteration_weights(): void
|
||||||
|
{
|
||||||
|
$largeWeights = [[array_fill(0, config('perceptron.max_displayed_weights') + 1, 0)]];
|
||||||
|
$event = new PerceptronTrainingIteration(
|
||||||
|
iterations: [
|
||||||
|
['epoch' => 1, 'exampleIndex' => 0, 'error' => 1, 'weights' => $largeWeights],
|
||||||
|
['epoch' => 1, 'exampleIndex' => 1, 'error' => 0, 'weights' => $largeWeights],
|
||||||
|
],
|
||||||
|
sessionId: 'session',
|
||||||
|
trainingId: 'training',
|
||||||
|
);
|
||||||
|
|
||||||
|
$iterations = $event->broadcastWith()['iterations'];
|
||||||
|
|
||||||
|
$this->assertSame([], $iterations[0]['weights']);
|
||||||
|
$this->assertSame($largeWeights, $iterations[1]['weights']);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user