Змеиная игра с нейронными сетями и генетическими алгоритмами не учится
Ссылка на представителя: https://github.com/MyisCARRY/Snake---Genetic-Algorthm
Поэтому я недавно построил игру со змеями, используя Neural Network и GA. Структура NN: входной слой -> скрытый слой -> выходной слой. Входными данными являются 10 узлов: 4 расстояния до стены (N, S, E, W), 4 расстояния до ближайшего тела (N, S, E, W) и X и Y разница между едой и головой. Скрытый слой имеет 8 узлов. Выход - это направление движения (N, S, E, W). Веса находятся между <-1, 1> и смещением между <-3, 3>. Самый активный выходной узел отправляется змее.
Теперь о генетическом алгоритме.
Размер популяции установлен на 2000 змей, коэффициент мутации на 0,01. Выбор следующий: 20% змей с наилучшими характеристиками размножаются. Например, в поп-музыке из 100 выбираются 20 лучших змей, и они переходят к следующему поколению. Остальные 80 змей сделаны из пересечения 20 лучших. Вероятность стать родителем эквивалентна его пригодности.
Crossover. Существует 4 массива: весовые коэффициенты между входом и скрытым, смещение между входным и скрытым, весовые коэффициенты между скрытым и выходным, смещенные между скрытым и выходным. Каждый родитель отдает половину каждого массива потомству.
Мутация. Для каждого веса и смещения я случайным образом выбираю число от 0 до 1, и, если число меньше или равно частоте мутации, этот вес или смещение изменяются на случайное значение, как в начале.
Как работает змея.
Когда он сталкивается со своим телом или стеной, он умирает. Время жизни змеи устанавливается в начале 200 шагов. Каждый раз, когда он ест пищу, длина увеличивается на 1 и получает 1 очко и получает 100 дополнительных шагов (макс. 500). Когда у него заканчиваются шаги, он умирает.
Фитнес-функция. Вы можете увидеть это в классе Snake в конце в функции с именем "Calculate_fitness". шаги - сколько ходов он сделал, оценка - сколько еды он съел.
К сожалению, нейронная сеть не учится. Часто сам змеиная петля. Я перепробовал много вариантов размера поп-музыки, частоты мутаций, скрытых узлов, функции фитнеса и т. Д. Мои идеи закончились, и я не знаю, что я делаю неправильно. Если бы кто-то мог показать мне, что не так, я был бы рад. Я думаю, что проблема может быть в функции фитнеса, но я попробовал много разных идей, и ни одна из них не работает.
void calculate_fitness() {
if (score < 10) {
fitness = steps;
fitness *= pow(2, score);
} else {
fitness = steps;
fitness *= pow(2,10);
fitness *= (score - 9);
}}