Простой пример использования нейронной сети в PHP

Добавлено: 08/01/2018 16:16 |  Обновлено: 17/03/2018 19:54 |  Добавил: nick |  Просмотры: 2712 Комментарии: 2
Вводная часть
На новогодних выходных решил немного разобраться как работают нейронные сети. Посмотрел пример на php.net касательно Fast Artificial Neural Network или FANN. И придумал свой вариант использования FANN в PHP.
Суть задачи
С помощью нейронных сетей я постарался определить безопасно ли плавать в море, с учетом следующих параметров: время суток (день/ночь), туман (задается дробным числом), волны (есть/нет), акулы (есть/нет).

Для обучения нейронной сети я использовал следующие данные:
День (-1) / Ночь (1) Туман: Волны: есть (1), нет (-1) Акулы: есть (1), нет (-1) Опасно (1), нет (-1)
-1 0,50 -1 -1 -1
-1 0,10 -1 -1 -1
-1 0,00 1 -1 -1
1 0,00 -1 -1 -1
1 0,00 1 1 1
1 0,30 1 -1 1
1 0,00 1 -1 1
1 0,50 -1 -1 1
-1 0,50 -1 1 1
-1 0,00 -1 1 1
Реализация
Для начала создадим файл данных, я его назвал sea.data. В этот файл внесем параметры из таблицы.
10 4 1
-1 0.50 -1 -1
-1
-1 0.10 -1 -1
-1
-1 0.00 1 -1
-1
1 0.00 -1 -1
-1
1 0.00 1 1
1
1 0.30 1 -1
1
1 0.00 1 -1
1
1 0.50 -1 -1
1
-1 0.50 -1 1
1
-1 0.00 -1 1
1
В первой строке 10 – это количество строк входных данных. Можете посчитать количество строк в таблице и удостовериться, что у нас их 10. Далее, 4 – это число входных данных (время суток, туман, волны, акулы); 1 – это число выходных данных, нейронная сеть должна выдавать -1 или 1. Хотя как оказалось, чаще всего получается приближенное число.

В следующих строчках входные и выходные данные чередуются (сначала входные, а затем выходные).

Создадим php-файл, в котором обучим нейронную сеть решать нашу задачу. Код в этом файле должен быть следующим:
$num_input = 4;
$num_output = 1;
$num_layers = 3;
$num_neurons_hidden = 130;
$desired_error = 0.0001;
$max_epochs = 100000;
$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);
    fann_set_training_algorithm($ann, FANN_TRAIN_QUICKPROP);

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

    fann_destroy($ann);
}
Параметры $num_neurons_hidden и $max_epochs подбираются экспериментальным путем.

Теперь осталось создать еще один php-файл для проверки того, как обученная нейронная сеть решает нашу задачу. Код в этом файле должен быть следующим:
$sea_file = (dirname(__FILE__) . "/sea_float.net");
if (!is_file($sea_file))
    die("Файл sea_float.net не был создан! Перезапустите главный файл, чтобы его создать");

$ann = fann_create_from_file($sea_file);
if (!$ann)
    die("ANN не была создана");

$input = array(-1, 0.10, -1, 1); // вносим тестовые данные
$calc_out = fann_run($ann, $input);
echo "С параметрами моря:<br>";
echo ($input[0] != 1) ? 'день<br>' : 'ночь<br>';
echo ($input[1] == 0.00) ? 'нет тумана<br>' : "есть туман ($input[1])<br>";
echo ($input[2] != 1) ? 'нет волн<br>' : 'есть волны<br>';
echo ($input[3] != 1) ? 'нет акул<br>' : 'есть акулы<br>';
if (round($calc_out[0]) == 1)
    printf("плавать опасно (%.2f).", $calc_out[0]);
else
    printf("плавать не опасно (%.2f).", $calc_out[0]);

fann_destroy($ann);
Результаты работы нейронной сети вы можете видеть в таблице:
День (-1) / Ночь (1) Туман: Волны: есть (1), нет (-1) Акулы: есть (1), нет (-1) Опасно (1), нет (-1)
1 0,00 -1 -1 -0.97
1 0,60 -1 -1 1.00
1 0,10 -1 -1 -0.86
1 0,45 -1 -1 0.95
1 0,10 1 -1 0.99
-1 0,10 1 -1 -0.98
-1 0,10 -1 1 1.00
Наглядный пример работы нейронной сети с одним из наборов входных данных: Для удобства выкладываю исходники.

Дополнение. О том как установить FANN в Линуксе
Я работал с FANN в Linux Mint, соответственно все нижеизложенное подойдет и для другой Debian-системы.

В первую очередь нужно установить библиотеку libfann, если она не установлена.
sudo apt install libfann-dev
Затем нужно установить php-pear и php-dev той же командой (apt install).

А также само расширение FANN для PHP:
sudo pecl install fann

Комментарии

  • 19/03/2018 22:38 Vova пишет:

    Был windows, запустил на линукс минт- заработала

    Сейчас пытаюсь понять значения этих переменных, получается чем больше скрытых нейронов и эпох, и чем меньше значение ошибки($max_epochs) и $epochs_between_reports тем лучше?

    nick пишет:
    Все зависит от ситуации, много нейронов может быть плохо потому что могут быть запомнены все возможные ситуации в решаемой задаче, мало нейронов - тоже плохо, потому что просто грубо говоря мозгов не хватит решить задачу. Так что тут надо подобрать золотую середину.

  • 17/03/2018 12:54 Vova пишет:

    Здравствуйте, Вы не могли бы мне помочь, делаю все точь в точь, браузер не загружает(ERR_CONNECTION_RESET). Методом тыка узнал что проблема в файле с начальными данными, удаляю последнюю строку(результат входных данных) или добавляю в количестве входных +1 то код работает но результат выдает неправильный. Использовал разные версии PHP(7.1 и 5.6) без разницы, все тоже.

    nick пишет:
    Здравствуйте. Никаких ошибок в файле нет. В какой ОС запускаете? От версии PHP, я думаю, не должно зависеть, потому как там все, что больше версии 5.2.0 подходит.

Оставьте свой комментарий