В прошлом месяце у OpenAI был интересный пост в блоге и бумага по обобщению в Reinforcement Learning (RL). OpenAI создал среду под названием CoinRun для проверки возможностей различных агентов по обобщению. CoinRun — это среда, похожая на видеоигру, в которой агент должен перемещать персонажа через различные препятствия, чтобы получить монету. В статье отмечалось, насколько производительность сверточной нейронной сети (CNN) IMPALA была выше, чем у Nature CNN (CNN по умолчанию в OpenAI Baselines). Код для CoinRun, бумаги и IMPALA CNN доступен на github. В этом посте я расскажу о настройке пользовательской модели с использованием IMPALA CNN с базовыми линиями и модели настройки, которую я использую для прохождения уровня 1 Contra 3 в сложном режиме.

Настройка пользовательской модели

В предыдущем посте о базовом использовании Baselines я писал о том, как использовать пользовательские модели. Шаги: определить модель в функции, зарегистрировать модель и вызвать это имя в параметрах алгоритма RL. Пример:

ИМПАЛА CNN

Я модифицировал реализация CoinRun CNN IMPALA для работы с базовыми линиями в этом файле. Сеть IMPALA на изображении выше — это сеть, которая использовалась в исходной статье IMPALA и включает в себя несколько остаточных блоков, выходной слой LSTM и компонент внедрения LSTM. Реализация CoinRun делает выходной слой LSTM необязательным, не имеет компонента внедрения LSTM и добавляет пакетную норму и отсев (поскольку CoinRun тестирует эти методы на их эффект обобщения). Моя реализация Baselines не имеет выходного слоя LSTM (хотя добавить его несложно) и не реализует отсев (поскольку я не тестирую на предмет обобщения). Я провел простой тест на Contra 3 (видеоигра Super Nintendo), чтобы убедиться, что IMPALA CNN работает. К сожалению, я указал неправильные действия для агента, поэтому я не смог провести честное сравнение с Nature CNN на уровне 1 Contra 3. Агент учится добираться до финального босса на уровне 1 в простом режиме, который является своего рода впечатляет, так как агент не может прыгать или стрелять в большинстве направлений. Смотрите функция def impala_cnn() в этом файле для более подробной информации.

Противоположная пользовательская модель

Настройки гиперпараметров, которые я использовал для очистки уровня 1 в простом режиме с Nature CNN по умолчанию, также работают в среднем и сложном режимах. Среднее немного сложнее, чем легкое, но все же справляется с примерно 1 эпизодом смерти менее чем за 30 миллионов временных шагов. В жестком режиме агент борется с CNN по умолчанию. Агенту удается очистить некоторые эпизоды из 6 или 7 смертей, но не так много. Я добавил больше функций и изменил CNN по умолчанию, чтобы значительно повысить производительность на уровне очистки 1 в сложном режиме.

Я добавил дополнительный слой для CNN, который содержит положение игрока, врагов, вражеские снаряды, неуязвимых врагов и врагов со здоровьем. К счастью, кто-то уже проделал работу по поиску где в ПЗУ адреса хранится вся эта информация. Я изменил оболочку WarpFrame по умолчанию на WarpFrameFeatures, чтобы включить этот дополнительный слой. Я в основном сканирую адрес ПЗУ для типов информации, получаю доступ к информации о позиции и записываю эти позиции в серию 2D-массивов. У меня есть массив для каждого типа информации, и в конце я складываю массивы вместе и добавляю их к изображению в градациях серого.

Я также добавил 15 скалярных функций, которые включают в себя такие вещи, как оружие, установленное в каждом слоте, и количество бомб. Однако, поскольку Baselines не позволяет нам использовать словарные пространства наблюдения, трудно передать 15 скалярных признаков в CNN. Вместо этого мне пришлось создать новый двумерный массив, поместить в него полезные скаляры и добавить их в массив наблюдений. Немного пустая трата, и, по-видимому, в Стабильных базовых показателях есть обходной путь, но я еще не тестировал его.

Новые слои передаются в модифицированный Nature CNN. Я написал плохой код TensorFlow, чтобы разделить скалярный слой объектов и объединить эти объекты с выходными данными сверточных слоев. Смотрите функция contra_mixed_net для уродливых подробностей. Я не уверен в идеальном способе сочетания сверточных и несверточных функций в модели RL. Это то, что я собираюсь исследовать в какой-то момент. Я также думаю, что скалярные функции можно было бы улучшить, если бы я использовал небольшую сеть встраивания для типов оружия, а не отдельно одно оружие горячего кодирования 1 и оружие 2.

Новые функции помогают в сложном режиме уровня 1. Я протестировал базовую модель и настраиваемую модель функций с одними и теми же гиперпараметрами. В то время как время стены для базовой модели (23,1 часа) и функциональной модели (22,6 часа) примерно одинаково, базовая модель смогла выполнить примерно на 50% больше временных шагов (от 30 до 20 миллионов) из-за меньшего количества сверточных слоев и параметры. Тем не менее, функциональная модель имела гораздо лучшую производительность с точки зрения вознаграждения (пиковое среднее вознаграждение за 1400 эпизодов по сравнению со средним вознаграждением за 800 эпизодов), медианное количество смертей (12 смертей против 16 смертей) и минимальное количество смертей (2 против 6).

Я также не уверен, какая разница в улучшении связана со скалярными функциями, а какая — с новым слоем CNN. Мне нужно проверить два отдельно. Я также должен провести тестирование с разными случайными начальными значениями и разными диапазонами гиперпараметров, попробовать IMPALA CNN и, возможно, попробовать еще несколько экспериментов LSTM… Я не уверен, что мне удастся провести все эти часы (2000?) экспериментов. но, надеюсь, в какой-то момент будет больше результатов.

Вот видео прохождения агентом уровня 1 в сложном режиме: