Pull to refresh

Быстрая нейронная сеть для каждого

Reading time 3 min
Views 223K
Данная статья продемонстрирует возможность легко написать свою нейронную сеть на языке Javа. Дабы не изобретать велосипед, возьмем уже хорошо проработанную библиотеку Fast Artificial Neural Network. Использование нейронных сетей в своих Java-проектах — реально. Часто можно услышать упреки в адрес Java касательно скорости выполнения. Хотя разница не так велика — подробно об этом можно узнать в публикации «Производительность C++ vs. Java vs. PHP vs. Python. Тест «в лоб»». Мы будем использовать обертку вокруг библиотеки FANN.

Задача


Необходимо написать систему, которая сможет принимать решения за персонажа, который может встретить одного или несколько врагов. Системе может быть известно:
  • здоровье персонажа в процентах;
  • наличие пистолета;
  • количество врагов.

Ответ должен быть в виде одного из действий:
  • атаковать;
  • бежать;
  • прятаться (для внезапной атаки);
  • ничего не делать.

Для обучения составим таблицу «уроков»:
Здоровье пистолет Враги Действие
50% 1 1 Атаковать
90% 1 2 Атаковать
80% 0 1 Атаковать
30% 1 1 Прятаться
60% 1 2 Прятаться
40% 0 1 Прятаться
90% 1 7 Бежать
60% 1 4 Бежать
10% 0 1 Бежать
60% 1 0 Ничего
100% 0 0 Ничего

Подготовка


Первое, что нужно сделать — собрать и установить libfann.
Затем скачать fannj и jna.

Сделаем файл, который будет содержать набор «уроков»:

11 3 4
0.5 1 1
1 0 0 0
0.9 1 2
1 0 0 0
0.8 0 1
1 0 0 0
0.3 1 1
0 1 0 0
0.6 1 2
0 1 0 0
0.4 0 1
0 1 0 0
0.9 1 7
0 0 1 0
0.5 1 4
0 0 1 0
0.1 0 1
0 0 1 0
0.6 1 0
0 0 0 1
1.0 0 0
0 0 0 1

Теперь обучим нашу ИНС и сохраним ее в файл:

   public static void main(String[] args) {
        //Для сборки новой ИНС необходимо создасть список слоев
        List<Layer> layerList = new ArrayList<Layer>();
        layerList.add(Layer.create(3, ActivationFunction.FANN_SIGMOID_SYMMETRIC, 0.01f));
        layerList.add(Layer.create(16, ActivationFunction.FANN_SIGMOID_SYMMETRIC, 0.01f));
        layerList.add(Layer.create(4, ActivationFunction.FANN_SIGMOID_SYMMETRIC, 0.01f));
        Fann fann = new Fann(layerList);
        //Создаем тренера и определяем алгоритм обучения
        Trainer trainer = new Trainer(fann);
        trainer.setTrainingAlgorithm(TrainingAlgorithm.FANN_TRAIN_RPROP);
        /* Проведем обучение взяв уроки из файла, с максимальным колличеством
           циклов 100000, показывая отчет каждую 100ю итерацию и добиваемся
        ошибки меньше 0.0001 */
        trainer.train(new File("train.data").getAbsolutePath(), 100000, 100, 0.0001f);
        fann.save("ann");
    }

Пояснение


Layer


ИНС состоит из слоев нейронов. Первый слой — это нейроны «рецепторы» или нейроны входных данных. Последний слой нейронов выходных данных. Все остальные — это скрытые слои. В нашем случае первый слой имеет 3 нейрона:

уровень здоровья (0.1-1.0);
наличие оружия (1-есть, 0-нету);
количество врагов.

Fann


Объект класса Fann это и есть нейронная сеть, которая создается на основе созданных ранее слоев.

Trainer


Объект класса тренер инкапсулирует алгоритмы обучения нейронной сети переданной при создании тренера. После обучения не забываем сохранить ее в файл.

Проверка результатов


Для проверки нашего обучения воспользуемся следующим кодом:

   public static void main(String[] args) {
        Fann fann = new Fann("ann");
        float[][] tests = {
                {1.0f, 0, 1},
                {0.9f, 1, 3},
                {0.3f, 0, 8},
                {1, 1, 8},
                {0.1f, 0, 0},
        };
        for (float[] test:tests){
            System.out.println(getAction(fann.run(test)));
        }
    }
    
    private static String getAction(float[] out){
        int i = 0;
        for (int j = 1; j < 4; j++) {
            if(out[i]<out[j]){
                i = j;
            }
        }
        switch (i){
            case 0:return "атаковать";
            case 1:return "прятаться";
            case 2:return "бежать";
            case 3:return "ничего не делать";
        }
        return "";
    }

У меня получились такие результаты:
Здоровье пистолет Враги Действие
100% Нет 1 Атаковать
90% Есть 3 Прятаться
30% нет 8 Бежать
100% Есть 8 Бежать
10% Нет 0 Ничего не делать

Буду рад услышать конструктивную критику.
Tags:
Hubs:
+19
Comments 12
Comments Comments 12

Articles