понедельник, 6 июля 2020 г.

NeyroGamer 2

Всем привет, с вами Платон из команды "Карандаш и Самоделкин". Лето идёт полным ходом и наша команда не сидит без дела. Сегодня я готов представить вам продолжение проекта NeyroGamer, в котором я создам нейронную сеть, которая будет учиться  играть в видео игры.

Я всё глубже изучаю нейронные сети, и зачастую пишу код без использования библиотек с готовыми методами и инструментами для создания алгоритмов машинного обучения. Это связанно с желанием узнать, что находится «под капотом» у таких библиотек как Keras и TensorFlow. Однако алгоритм обратного распространения ошибки кажется мне несколько сложным, поэтому в NeyroGamer нейросети выступают в качестве особей генетического алгоритма. В сегодняшнем проекте я написал нейронную сеть с краткосрочной памятью с нуля, используя лишь стандартные библиотеки и NumPy.

В качестве игры, в которую будет учится играть мой алгоритм, снова выступит Nigel Mansell's World Championship Racing с платформы Sega Genesis. Так как я использую генетический алгоритм, использование эмулятора консоли и ретро игра дает мне следующие преимущества:

  •     Загрузка состояния с контрольной точки. Каждая особь начинает гонку со старта. 
  •     Простая графика для разбора OpenCV

В первой части проекта, я опирался на несколько моментов дороги, взятых OpenCV на разной высоте кадра. Такой подход казался мне более верным, в нем нейронной сети подавались предобработанные моментами данные. После многих поколений эволюции такой подход позволял обучать нейронную сеть, но процесс был очень долгий и после достижения N-ого уровня мастерства алгоритм переставал учится, «упираясь в потолок», так как не учитывал многие нюансы трассы - столбы, мосты, положение соперников друг относительно друга.

Во второй части проекта я пошел другим путем. На вход нейронным сетям особей теперь подается изображение нижний части экрана (машина и дорога без показаний приборов, спидометра, коробки передач и миникарты) в виде уменьшенного полноцветного битмапа. После нескольких экспериментов было выбрано разрешение 64х16. При увеличении количества точек сильно растёт количество нейронов, что приводит к медленной работе алгоритма. На картинке с меньшим количеством точек не хватает данных.

 
32х8

64х16

Такой метод оказался намного лучше и обучение пошло значительно быстрее. Правда из-за того, что нейронная сеть очень сильно выросла (3000+ входов), пришлось заняться оптимизацией. Весь алгоритм обучения я переписал на NumPy. Самое «медленное» место в старом алгоритме оказалось в методе «предсказания»(использования) нейронной сети из-за «бега» циклом по 2м матрицам. После оптимизации этого места FPS вырос в 100 раз, с 6 до 600. Вместе с переработкой всего кода и его оптимизацией, была дополнена модель нейронной сети. Была добавлена краткосрочная память, то есть теперь я использую LSTM-сеть . 

С помощью моментов  на кадре выделяется данные о скорости (вырезается полоса с показаниями передачи и по ней берётся красный момент). Эти данные показывают текущую скорость — показатель по которому сортировались нейронные сети.

  

Каждая из особей «загружается» с контрольной точки (на старте гонки) и тестируется в периоде N-ого времени. В каждый «тик» особи прибавляется количество очков в зависимости от её скорости. Таким образом переходить в следующее поколение будут самые быстрые особи. После тестирование всех особей происходит сортировка и скрещивание, после чего новое поколение особей заново тестируется. После каждых 5 поколений все особи сохраняются в файл, что бы обучение можно было продолжить позже.


Вначале своего обучения, алгоритм ведёт себя крайне случайно. Однако после первых 2-3х поколений особи случайно нажавшие на газ начинают вести за собой остальных. Тут начинается 2й этап обучения - «Зажимай, авось получится!». Нейронные сети научившись давить на газ начинают зажимать случайные кнопки. Кто-то едет прямо, а кто-то постоянно улетает в правое ограждение. Получается довольно смешно. Далее алгоритм находит «середину» и обучается уже более сложным вещам - держатся по центру дороги, правильно входить в поворот, обгонять своих противников.

Автор - Платон, 14 лет ("Карандаш и Самоделкин")

вторник, 12 мая 2020 г.

Нейронная сеть учится играть в Lunar Lander

Lunar Lander — аркадная игра, выпущенная Atari, Inc. в 1979 году. Цель игры — управлять посадочным лунным модулем, чтобы произвести мягкую посадку на поверхность Луны. На посадочный модуль действует гравитация и инерция, кроме того количество топлива в нем ограничено. Управление производится 4 кнопками: наклоны посадочного модуля влево/вправо, управление тягой двигателя +/-.


Задача, решаемая в рамках данного проекта - разработать самообучающуюся нейронную сеть, способную посадить на поверхность Луны посадочный модуль, выбрав при этом для этого пригодную для посадки площадку. Для управления посадочным модулем нейронная сеть должна "нажимать" кнопки на виртуальной клавиатуре, так как это делал бы реальный игрок.



Для ускорения обучения нейронной сети используется генетический алгоритм, в каждом поколении запускается 10 ее копий. Нейронная сеть имеет 2 скрытых слоя. Проект разрабатывается на Python, никакие дополнительные нейросетевые фреймворки/модули не используются. Автор - Тихон, 13 лет ("Карандаш и Самоделкин")
Исходный код



воскресенье, 10 мая 2020 г.

Звездолеты 3D

Продолжение игры про звездолеты, теперь в 3D. Управление с помощью наэкранных кнопок. В демо 1 уровень, есть звуковые эффекты и музыка.



Язык C#, среда разработки - Unity.
Автор - Тихон, 13 лет ("Карандаш и Самоделкин")
Исходный код здесь

суббота, 9 мая 2020 г.

Звездолеты

Игра про звездолеты. Несколько уровней, разные типы врагов и оружия. Подбираемые боеприпасы и "аптечки". Управление движением - на гироскопе/акселерометре телефона, выстрелы разным типом оружия - тапы в разных зонах экрана. Есть звуковые эффекты и миникарта. Написана без использования готовых библиотек и конструкторов.


Язык Java, среда разработки - Android Studio.
Автор - Тихон, 13 лет ("Карандаш и Самоделкин")
Исходный код здесь



Tetris 2x

Классический тетрис представляет собой головоломку, построенную на использовании геометрических фигур «тетрамино» — разновидности полимино, состоящих из четырёх квадратов. В нашей версии стакан имеет глубину в 2 квадрата (слоя), заполнять необходимо оба горизонтальных ряда из 10 клеток, расположенных на одной высоте. Управление на стрелках клавиатуры, переворот игрового поля на другой слой - Ctrl.


Язык C#, среда разработки - Unity.
Автор - Тихон, 13 лет ("Карандаш и Самоделкин")
Скачать можно c Яндекс.Диск, исходный код здесь
Прототип игры сначала написал на Python, исходники по ссылке

NeyroGamer 1

На самоизоляции сейчас непросто всем, но сидеть и унывать скучнее, чем заниматься любимым делом. Мы не сидим сложа руки и придумали довольно фановую штуку, назвав ее NeyroGamer.

NeyroGamer это своего рода бот, играющий в видео игры. Так как нам нравятся старые консоли, первая игра, в которую мы хотим научить играть нашего бота - гоночная аркада на Sega Genesis под названием Nigel Mansell's World Championship Racing. Игры запускаются на эмуляторе консоли (мы используем Fusion 3). Проект немного похож на один из наших прошлых проектов "Длинный хвост питона", так как использует машинное зрение с OpenCV.


Исходный код проекта

В коде реализовано 2 класса, каждый из которых отвечает за свою область.
   Класс ScreenReader содержит функциональность, позволяющую получать информацию о данных с экрана. Для этого делается скриншот. Мы пробовали множество вариантов — но самым быстрым был метод ImageGrab из модуля PIL. Он показал FPS в 25 кадров в секунду. Этого вполне достаточно для реагирования на повороты. После взятия изображения оно обрабатывается с помощью библиотеки OpenCV. Я накладываю маску, что бы выделить дорогу из кадра. Маска берётся не на всём кадре, а на 2 полосах экрана, первая из которых находится в самом низу кадра, а вторая почти под линией горизонта. Таким образом можно понять в какую сторону изгибается дорога. С помощью двух моментов можно притормаживать на поворотах и газовать максимально на прямых участках.
  Второй класс, Сontrol — отвечает за управление машинкой путем передачи в игру нажатия кнопок на виртуальном геймпаде.

Настройка эмулятора и виртуального геймпада. 
Для управления игрой в эмуляторе была установлена программа Vjoy, с помощью которой к компьютеру был подключен виртуальный геймпад. На геймпаде 11 кнопок и 1 стик. Для управления этим геймпадом из программы я использую модуль PyVjoy. Для корректной работы модуля внутрь папки требуется положить специальный DLL-файл, который генерируется в папке, куда вы установили Vjoy.  После этого вы сможете управлять виртуальным геймпадом из программы на Python. Необходимо установить в настройках эмулятора вход 1. На него следует поставить 3х кнопочный джойстик Genesis и выбрать в качестве него ваш виртуальный геймпад.
После этого надо запустить программу AssignKeys.py. Она будет нажимать кнопки виртуального геймпада в том порядке, какого требует эмулятор Fusion 3. Во время назначения клавиш фокус должен быть всё время на программе-эмуляторе. Когда эмулятор будет ждать клавиши старт, нажмите любую удобную кнопку на клавиатуре. Это нужно для возможности войти в гонку и поставить паузу. Всё готово! Вы можете запускать гонку в полноэкранном режиме предварительно запустив run.py.


  У вас наверно возник вопрос - почему проект носит порядковый номер 1? Всё просто. В репозитории пока открыт только демо-код, алгоритм которого не идеальный. Гонку мы пока проходим на 8-9 месте, поэтому будем дорабатывать NeyroGamer. Первая часть проекта - научиться взаимодействовать с игрой, получать игровые события, передавать команды управления. Сейчас мы работаем над нейронной сетью, которая улучшит игровые результаты.

Язык Python.
Автор - Платон, 14 лет ("Карандаш и Самоделкин")

четверг, 23 апреля 2020 г.

Lode Runner


Чем заняться на самоизоляции? Как вариант - написать игру, в которую можно играть всей семьей.


Ремейк игры Lode Runner (Apple II) с оригинальным набором уровней. Главная фишка - режим hot seat до 4 человек, где остальные игроки играют за противников главного героя. Однако от уровня к уровню могут играть разное количество игроков, так как количество противников разное на разных уровнях.


Игрок управляет маленьким человечком и должен собрать всё золото, лежащее на данном уровне, избегая встречи с противниками. Весь уровень целиком виден на экране и состоит из кирпичных платформ, лестниц, а также натянутых верёвок, по которым можно двигаться, держась за них руками. Персонаж игры не может убивать роботов, но может создавать для них ямы в кирпичном полу — попавший в яму робот задерживается там на некоторое время. Герой может падать с любой высоты, не разбиваясь, но не может подпрыгивать. После того, как все ящики с золотом собраны, где-либо появляется лестница (или несколько), по которой нужно добраться до верха экрана — это приведёт к переходу на следующий уровень.


Всего в игре 150 уровней. На каждом новом уровне требуется более сложная стратегия в отношении того, в каком порядке обходить уровень и где прорыть ямы с тем, чтобы собрать все ящики с золотом и не попасться. Стратегия также может включать способы создания одной большой ямы из множества обычных, прорытых друг за другом.


С переходом на более высокие уровни игра становится более «головоломной» чем игрой на скорость реакции, хотя и то и другое остаётся важным.

Язык C#, среда разработки - Unity.
Автор - Платон, 14 лет ("Карандаш и Самоделкин")
Скачать можно c rutracker.org или c Яндекс.Диск

Самое популярное