[PHP | FANN] Czy wyniki są prawidłowe?

0

Witam,
Zainteresowałem się biblioteką FANN i korzystając z przykładu stworzyłem prostą sieć do wykrywania czy dana figura jest kwadratem korzystając z trzech warunków, tz jest kwadratem jeśli

  • Ma cztery boki
  • Ma wszystkie kąty proste
  • Wszystkie boki są równe

Zbiór uczący

4 3 1
1 1 1
1
0 1 1
0
1 0 1
0
1 1 0
0

train.php

<?php
$num_input = 3;
$num_output = 1;
$num_layers = 3;
$num_neurons_hidden = 3;
$desired_error = 0.001;
$max_epochs = 500000;
$epochs_between_reports = 1000;

$ann = fann_create_standard($num_layers, $num_input, $num_neurons_hidden, $num_output);

if ($ann) {
    fann_set_activation_function_hidden($ann, FANN_SIGMOID_SYMMETRIC);
    fann_set_activation_function_output($ann, FANN_SIGMOID_SYMMETRIC);

    $filename = dirname(__FILE__) . "/kwadrat.data";
    if (fann_train_on_file($ann, $filename, $max_epochs, $epochs_between_reports, $desired_error))
        fann_save($ann, dirname(__FILE__) . "/kwadrat_float.net");

    fann_destroy($ann);
}
?>

test.php

Wyniki testów:<br />
<?php
$train_file = (dirname(__FILE__) . "/kwadrat_float.net");
if (!is_file($train_file))
    die("The file xor_float.net has not been created! Please run simple_train.php to generate it");

$ann = fann_create_from_file($train_file);
if (!$ann)
    die("ANN could not be created");

$input = array(1,1,1);
$input2 = array(1,0,1);
$input3 = array(0,0,0);
$input4 = array(0,1,1);
$calc_out = fann_run($ann, $input);
$calc_out2 = fann_run($ann,$input2);
$calc_out3 = fann_run($ann,$input3);
$calc_out4 = fann_run($ann,$input4);
printf("#1 (%f,%f,%f) -> %f<br>", $input[0], $input[1],$input[2], $calc_out[0]);
printf("#2 (%f,%f,%f) -> %f<br>", $input2[0], $input2[1],$input2[2], $calc_out2[0]);
printf("#3 (%f,%f,%f) -> %f<br>", $input3[0], $input3[1],$input3[2], $calc_out3[0]);
printf("#4 (%f,%f,%f) -> %f<br>", $input4[0], $input4[1],$input4[2], $calc_out4[0]);
fann_destroy($ann);
?>

Wyniki testów

Wyniki testów:
#1 (1.000000,1.000000,1.000000) -> 0.972579
#2 (1.000000,0.000000,1.000000) -> -0.015160
#3 (0.000000,0.000000,0.000000) -> -0.999144
#4 (0.000000,1.000000,1.000000) -> 0.076887

Zastanawia mnie czy wyniki dla podanych wartości są prawidłowe, jak nie co zrobiłem źle? Proszę nie hejtować, bardzo mnie zainteresował ten temat i chcę się jakoś w tym kierunku rozwinąć ;)

0

Nie. Wynik dla #3 jest nieprawidłowy, powinno być około zera. Zestaw treningowy powinien być w zasadzie taki:

8 3 1
0 0 0
0
0 0 1
0
0 1 0
0
0 1 1
0
1 0 0
0
1 0 1
0
1 1 0
0
1 1 1
1

I dla tego ostatniego patternu powinieneś mieć wyjście bliskie +1.0, w pozostałych przypadkach około zera, oczywiście +/- ze względu na funkcję sigmoidalną bipolarną, albo dodatnie i bliskie zeru jeśli masz funkcję aktywacji sigmoidalną unipolarną. FANN pod PHP wypluwało mi inne wyniki (zupełnie nieprawidłowe), testowałem to jednak na sieci MLP którą sobie sam napisałem w PHP i wyniki miałem takie jak się spodziewałem czyli 0.89 w ostatnim przypadku i około zera w pozostałych. Parametry treningu mniej więcej takie jak w Twoim założeniu.

0

Dzięki za pomoc ^^
Teraz mam takie wyniki

Wyniki testów:
#1 (1.000000,1.000000,1.000000) -> 0.863790
#2 (1.000000,0.000000,1.000000) -> -0.048524
#3 (0.000000,0.000000,0.000000) -> -0.051940
#4 (0.000000,1.000000,1.000000) -> 0.036361

Mógłbyś jeszcze powiedzieć co i jak? W sensie rozumiem chyba jak się buduje dane uczące oraz jak z tego ogólnie korzystać (tz co oznacza co w kodzie, jak dodawać neurony) ale się trochę gubię, nie wiem czy moje dane są poprawne, czy dodanie kolejnych neuronów może jakoś pogorszyć wyniki. Czytałem o tym parę artów w tym trochę z autora projektu na Sourceforge, dokumentacji PHP, ogólnej koncepcji oraz dokumentacji na oficjalnej stronie ale dalej to trochę dla mnie trochę zagadka ;)

0

Po zwiększeniu liczby warstw do 5 i neuronów w każdej warstwie też do 5 wyniki prezentują się tak, dobrze to?

Wyniki testów:
#1 (1.000000,1.000000,1.000000) -> 0.835280
#2 (1.000000,0.000000,1.000000) -> -0.019227
#3 (0.000000,0.000000,0.000000) -> -0.001492
#4 (0.000000,1.000000,1.000000) -> -0.052298

(przepraszam moda za dwa posty, prosiłbym o złączenie bo nie mogę edytować)

0

W warstwie wejściowej dajesz tyle neuronów ile masz wejść, tutaj 3, w wyjściowej tyle ile masz wyjść tutaj jedno. Jako że masz funkcję sigmoidalną bipolarną a chciałbyś np. dla 0 0 0 na wyjściu mieć 1, to musisz dać jeszcze w warstwie wejściowej +1 neuron dla biasu i na nim zawsze wartość 1, można to oczywiście zrobić łatwo na podstawie zestawu treningowego. Z tego co się doczytałem to problem dotyczy ilości warstw ukrytych i ilości neuronów, jedna wystarczy do większości postawionych problemów i w Twoim przypadku również, było gdzieś info, żeby ilość neuronów w warstwie ukrytej nie przekraczała 2x tego co masz w warstwie wejściowej i chyba nie mniej niż liczba (na wejściu + na wyjściu) / 3, czyli w Twoim przypadku min. 2 neurony w warstwie ukrytej. A więc zrób testy dla architektury 3 - 2 - 1 oraz 3 - 6 - 1 i zobacz jakie będą wyniki.

Tu masz do poczytania:
http://www.heatonresearch.com/2017/06/01/hidden-layers.html
https://stats.stackexchange.com/questions/181/how-to-choose-the-number-of-hidden-layers-and-nodes-in-a-feedforward-neural-netw/1097

0

@drorat1 Ok, dzięki jesteś wielki ^^

0

Podepne sie pod pytani, jestem studentem socjologii czy za pomoca tego mozna przeprowadzac symulacje np kto wygra wybory Trump czy Clinton albo czy dany produkt (na podstawie danych) ma szanse zawojowac rynek? Ciekawi mnie to. A jak tak, to mozna by co i jak dla nieinformatykow jak zaczac?

0

Przy założeniu że wynik zależy od X zmiennych i jest jakąś funkcją czemu nie? W końcu ładowanie kupy szmalu w reklamę produktu coś tam daje a to jest pewnie jakaś tam zależność. Zresztą udowodniono że sieci Feed Forward (a taką jest FANN) są uniwersalnymi aproksymatorami funkcji:

http://www.cs.cmu.edu/~bhiksha/courses/deeplearning/Fall.2016/notes/Sonia_Hornik.pdf

1 użytkowników online, w tym zalogowanych: 0, gości: 1