Я пробую модуль FANN PHP, и я смог успешно запустить пример здесь http://php.net/manual/en/fann.examples-1.php
Я изменил его, чтобы иметь возможность обрабатывать 5 входов с произвольной функцией для вывода. Я сгенерировал 1000 обучающих данных и провел обучение для нейронной сети. Тем не менее, при тестировании выходные данные имеют дублированные результаты для разных входных данных.
Это фрагмент обучающих данных. Функция $x = round($a + $b * $c / $d - $e, 2)
, так 35 + 33 * 31 / 25 - 48 = 27.92
1000 5 1
35 33 31 25 48
27.92
74 3 1 26 94
-19.88
7 62 86 48 71
47.08
31 73 68 94 95
-11.19
100 87 44 75 43
108.04
72 25 62 39 57
54.74
...
Вот мой тренировочный код. Я использовал FANN_LINEAR, потому что другие функции активации имеют выходы 0, 1 или -1. Я читал, что FANN_LINEAR не ограничен. Так что это должно быть применимо, верно?
<?php
$num_input = 5;
$num_output = 1;
$num_layers = 6;
$num_neurons_hidden = 4;
$desired_error = 0.0001;
$max_epochs = 500000;
$epochs_between_reports = 1000;
$ann = fann_create_standard($num_layers, 5, 5, 5, 5, 5, 1);
if ($ann) {
fann_set_activation_function_hidden($ann, FANN_LINEAR);
fann_set_activation_function_output($ann, FANN_LINEAR);
$filename = dirname(__FILE__) . "/xor.data";
if (fann_train_on_file($ann, $filename, $max_epochs, $epochs_between_reports, $desired_error))
fann_save($ann, dirname(__FILE__) . "/xor_float.net");
fann_destroy($ann);
}
Вот мой тестовый код
<?php
$train_file = (dirname(__FILE__) . "/xor_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");
$a = mt_rand(1, 100);
$b = mt_rand(1, 100);
$c = mt_rand(1, 100);
$d = mt_rand(1, 100);
$e = mt_rand(1, 100);
echo "Expecting $a $b $c $d $e => ".round($a + $b * $c / $d - $e, 2)."\n\n";
$input = array($a, $b, $c, $d, $e);
$calc_out = fann_run($ann, $input);
echo "Result: ".print_r($calc_out, true);
fann_destroy($ann);
Вот где это становится странным. Я пытался запустить этот код несколько раз, но результат тот же
fann$ php test2.php
Expecting 94 67 95 40 85 => 168.13
Result: Array
(
[0] => 89.329223632812
)
fann$ php test2.php
Expecting 53 43 56 64 64 => 26.63
Result: Array
(
[0] => 89.329223632812
)
fann$ php test2.php
Expecting 18 85 57 94 30 => 39.54
Result: Array
(
[0] => 89.329223632812
)
Можете ли вы дать мне несколько советов для достижения моей цели, то есть для аппроксимации произвольной функции с помощью FANN. Должен ли я увеличить свои тренировочные данные? Увеличение слоев или узлов на слой? Я использую другую функцию активации.
На первый взгляд кажется, что ваша сеть застряла с определенной конфигурацией веса. Это означает, что веса, которые обычно инициализируется до небольших значений около 0, начните изменять их значения, чтобы лучше соответствовать желаемым результатам. Поскольку эти изменения невелики, возможно, что после ряда тренировочных эпох они либо «не двигаются достаточно», чтобы найти хорошую комбинацию значений, либо остаются на локальном минимуме. Для этого есть ряд возможных причин (или просто соображений):
Вход & выходные значения, которые должны обрабатывать сеть и алгоритм обучения, относительно велики (~ диапазон [-20,100]) по сравнению с начальными значениями весов (~ диапазон [-1,1]). Самым простым решением здесь является нормализовать входы & выходы должны быть A) маленькими, B) сосредоточенными вокруг 0.
Функция активацииFANN_LINEAR
не имеет верхнего и нижнего пределов. Это может быть хорошо, но это также может привести к расхождению. Одним из вариантов является использование FANN_SIGMOID_SYMMETRIC
, который имеет пределы, но также и переходную зону, где он почти линейный. Работает с нормализованными входами и выходами.
Иногда значения импульса и скорости обучения могут привести к плохому обучению. Чтобы сделать некоторую диагностику, вы можете построить кривая ошибки обучения ошибки против тренировочной эпохи. Конечно, это немного трудоемко, так как каждую эпоху нужно тренировать отдельно (fann_train_epoch
вместо fann_train_on_file
).
И, наконец. У меня нет опыта работы с большими сетями, но я мог предположить, что один скрытый слой может изучить такую проблему. Почему бы не попробовать? Уже достаточно сложно зафиксировать число в 1 скрытом слое, чтобы просто добавить все больше параметров в уравнение;)
Ну, я надеюсь, что это помогает 🙂
Веселитесь со своими сетями!
Других решений пока нет …