Создайте настраиваемую среду RL с использованием современного программного обеспечения для разработки игр и глубокого обучения с подкреплением (A2C, PPO, TD3, ACER, DQN)

Https://www.youtube.com/watch?v=kNmNKnDQvgo

Хотя возможности обучения с подкреплением (RL), скорее всего, вскоре выйдут далеко за рамки компьютерного моделирования, сегодня основное место обучения агентов RL находится в цифровой среде. В мире искусственного интеллекта симуляторы часто являются средой, в которой функционирует алгоритм.

Что касается людей, мы рождаемся непосредственно в нашем симуляторе, и с нашей стороны не требуется никаких усилий, чтобы продолжать функционировать. Мы называем этот симулятор вселенной, и он существует независимо от того, верим мы в это или нет. Точно так же действуют законы физики, признаёте вы их или нет. Они не требуют никаких усилий или согласия с нашей стороны. Однако синтетический агент, обладающий способностью к обучению с подкреплением, такой как робот или персонаж видеоигры, не имеет прямого доступа к какому-либо миру, кроме того, который мы обеспечиваем ему через искусственные органы чувств. Сам по себе он существует как не более чем сложный набор инструкций для создания обучающего агента, мало чем отличающийся от генетического кода. У него нет тела или чувств, нет среды, в которой можно действовать. По крайней мере, на начальном этапе таким агентам намного проще взаимодействовать в виртуальных мирах внутри компьютера, чем в нашем собственном физическом мире, поскольку их инструкции состоят из программного обеспечения, а не из органических соединений, таких как ДНК.

В виртуальном мире агент может легко получить доступ ко всем видам информации о своем симуляторе, которую трудно обнаружить в нашем собственном физическом мире. Если он хочет узнать о физике своего виртуального мира, он может просто запросить переменные, в которых программист сохранил эту информацию. В физическом мире не существует справочной таблицы, в которой хранится эта информация. Напротив, такие свойства должны быть установлены на собственном опыте, путем обучения. Также гораздо безопаснее, чтобы эти обучающиеся с подкреплением были ограничены виртуальными мирами во время периода их исследования, поскольку, когда они совершают «ошибку», это имеет ограниченные последствия, в худшем случае вызывая сбой компьютера, на котором они работают (исключение составляют алгоритмы с доступом в Интернет, как некоторые компьютерные вирусы или боты для торговли акциями, которые обладают гораздо большей способностью наносить реальный ущерб). Искусственные агенты также могут учиться намного быстрее в виртуальных мирах, поскольку они не ограничены многими переменными окружающей среды нашего физического мира. Это очень важно, когда процесс обучения с подкреплением требует тысяч или миллионов тренировочных итераций, чтобы получить представление о желаемых ассоциациях для достижения своей стратегической цели.

Таким образом, симулятор является ключевым дополнительным элементом уравнения обучения с подкреплением. В этой статье мы рассмотрим, как преодолеть разрыв между алгоритмом и симулятором, создав в процессе индивидуальную среду обучения с подкреплением. До недавнего времени OpenAI Gym был одним из лучших кандидатов для экспериментов с RL-агентами; однако у этого были свои ограничения. Можно только наблюдать, как агент столько раз учится играть в Atari Pong, прежде чем грубость пиксельной среды начинает действовать на нервы.

Сегодня есть лучшие варианты - с помощью бесплатного плагина под названием MindMaker можно развернуть те же самые передовые алгоритмы RL, которые работают в OpenAI Gym, в наиболее графически реалистичной среде моделирования, известной человечеству. Да, я говорю о Unreal Engine 4 от создателей Fortnight. Благодаря интеграции чертежей вы можете настроить свой алгоритм DRL с помощью простого в использовании графического интерфейса, вместо того, чтобы погружаться в код. Итак, без дальнейших предварительных действий, давайте приступим к созданию пользовательской среды RL в Unreal Engine 4.

В этом примере мы воссоздадим классическую тренировочную среду RL, легендарную задачу с тележкой. Цель проекта - научить тележку балансировать на шесте, двигаясь из стороны в сторону соответствующим образом. Это похоже на балансирующие игры, в которые играют дети, в которых они учатся держать метлу на кончике пальца. В этом примере есть несколько интересных следствий для таких вещей, как обучение использованию рулевого колеса в случае беспилотного автомобиля или обучение робота балансированию в вертикальном положении. Мы будем создавать эту среду обучения с нуля, демонстрируя, насколько легко создать пользовательскую задачу обучения RL в UE4.

Для начала загрузите пакет MindMaker Deep Reinforcement Learning с UE Marketplace. Он содержит начальный контент, который мы будем использовать для создания среды полюса тележки (законченная версия примера полюса тележки также включена в бесплатный Плагин MindMaker AI). Откройте папку с картами и найдите карту под названием MindMakerStarterContent. После открытия перейдите в папку с именем MindMakerStarterContent. Это будет похоже на исходный контент от третьего лица по умолчанию, предоставляемый UE4, с той разницей, что включены несколько нестандартных схем.

Прежде чем продолжить, нам нужно внести одно изменение в настройки проекта, установив частоту кадров равной 30. Это необходимо для того, чтобы мы получили плавный отклик от физического движка, и тележка не зависла в воздухе при падении. . Перейдите в раскрывающееся меню «Правка» и нажмите «Параметры проекта». Найдите частоту кадров в разделе «Общие настройки движка» и установите для флажка «Использовать фиксированную частоту кадров» значение «Истина». Затем установите частоту кадров 30.

Теперь переименуйте чертеж BlankMindMakerActorBP в «Cart_BP». Перед продолжением убедитесь, что вы удалили другие активы Mindmaker, которые не будут использоваться, в частности MindMakerCharacterControler и MindMakerCharacterBP, которые относятся к персонажу от третьего лица, если вы создавали агента RL на основе чертежей от третьего лица. Затем откройте Cart_BP в редакторе чертежей и перейдите на вкладку области просмотра. С левой стороны зеленой кнопки «добавить меню компонента» найдите объект 1M_Cube и поместите его в окно просмотра. Измените масштаб по оси Z на .2 и убедитесь, что для флажка включения гравитации в его свойствах установлено значение true. Снова щелкните меню добавления компонентов и добавьте сферу над кубом, чтобы он выступал за верх. Измените масштаб z на 0,3. а положение z равно 10. Ура, теперь у нас есть основная форма тележки. Вернитесь к карте и перетащите свой план Cart_BP на карту, чтобы вы увидели появившиеся комбинированные формы. Теперь измените масштаб x на уровне карты вашей тележки .3, это повлияет на обе формы, составляющие тележку.

Теперь нам нужен цилиндр для балансировки на тележке. Создайте новый чертеж актера класса и назовите его Cyl_BP. Откройте его и с левой стороны зеленую кнопку «добавить меню компонента» щелкните цилиндр и перетащите его в область просмотра. Измените масштаб цилиндра так, чтобы размеры X и Y составляли 0,2, а не 1. Перейдя на уровень карты, выберите цилиндр и убедитесь, что для параметра моделирования физики в свойствах установлено значение True, а также для параметра включения гравитации. Измените линейное демпфирование и угловое демпфирование на 11. Оба параметра находятся в разделе свойств. Теперь перейдите к графу событий и создайте две новые переменные с плавающей запятой в чертеже цилиндра, которые называются cylroll, cylpitch. Затем создайте переменную типа Cart_BP, которая будет служить ссылкой на корзину, поскольку нам нужно будет взаимодействовать с переменными, содержащимися в Cart_BP. Вернитесь к карте, выберите свой цилиндр и в меню по умолчанию вы должны увидеть только что созданную переменную Cart_BP. Щелкните его и выберите ссылку Cart_BP под названием вашей карты. Это значит, что переменная Cart_BP в чертеже цилиндра указывает на чертеж Cart_BP. Вернитесь к чертежу цилиндра и создайте переменную типа bool с именем start, которая будет работать как идентификатор, когда цилиндр опрокинулся и его необходимо сбросить. Установите для параметра Start значение по умолчанию true.

Теперь мы добавим некоторую логику, которая определяет, когда цилиндр опрокидывается, и сбрасывает его. Это можно сделать, добавив тиковый узел события, который будет постоянно проверять, упал ли цилиндр. Подключите тик события к узлу ветвления, который будет срабатывать, когда любая из переменных cylroll, cylpitch, наклонена более чем на 30 градусов или менее чем на 30 градусов. Мы обновим эти переменные на основе физики цилиндра на чертеже уровня карты. Мы также хотим, чтобы узел ветвления срабатывал, когда период обучения тележки завершен, даже если цилиндр еще не упал, чтобы его можно было сбросить, когда количество тренировочных эпизодов будет завершено, и мы готовы оценить ИИ. . Итак, мы добавляем ссылку на переменную TrainingComplete, содержащуюся в Cart_BP. TrainingComplete - это одна из переменных MindMakerVariables по умолчанию, которая поставляется с пакетом. Когда любое из этих условий истинно, мы устанавливаем для параметра Start bool значение false, по сути останавливая обучение до тех пор, пока тележка и шест не будут сброшены.

Следующие два узла предназначены для логики сброса тележки и шеста в их исходное положение с использованием заданного узла местоположения в мире и узла компонента перемещения. Координаты x, y и z для них будут в некоторой степени зависеть от того, где именно вы изначально разместили тележку и шест на карте. Вы можете найти эту информацию, щелкнув по ним на карте и записав их координаты x y и z. Наконец, нам нужен узел, устанавливающий для Start bool значение true, чтобы механизм обучения MindMaker в Cart_BP знал, что тележка сброшена, и снова начал обучение. Затем мы устанавливаем для переменной TrainingComplete значение false, чтобы мы не перезагружали корзину постоянно во время демонстрационных эпизодов, следующих за обучением.

На этом план цилиндра завершен. Вернитесь к карте и перетащите CYL_BP так, чтобы цилиндр оказался примерно на вершине тележки.

Получение обновлений о физике нашего цилиндра может быть непростым делом и должно выполняться на уровне карты. Для этого СНАЧАЛА НАЖМИТЕ ЦИЛИНДР НА КАРТЕ, чтобы он был выбран и выделен желтым цветом. Затем откройте план уровня карты. Теперь щелкните правой кнопкой мыши график событий, и вы увидите опцию «Создать ссылку на Cyl_BP». Это только потому, что вы сначала выбрали цилиндр в окне карты, и иначе к нему нельзя получить доступ.

Создайте две таких ссылки. Из первого перетащите узел GetActorRotation. По его возвращаемому значению найдите узел «Break Actor Rotator». Теперь перейдите к другой ссылке Cyl_BP и перетащите узел «Set Cylroll». Это ссылка на переменную CylRoll, созданную вами в Cyl_BP. Сделайте то же самое и для CylPitch. Теперь подключите все это к соответствующим узлам ротатора актора прерывания. Теперь добавьте узел тика события и подключите к нему два узла переменной Set. После этого ваши переменные в Cyl_BP будут обновляться в реальном времени со значениями, касающимися крена и тангажа цилиндра.

Затем мы переходим к Cart_BP, которую создали впервые, так как именно здесь будет происходить машинное обучение. Он уже будет содержать множество переменных и функций по умолчанию, которые используются с MindMaker, поскольку он был скопирован из BlankMindMakerActorBP.

Первым шагом в настройке Cart_BP будет его открытие и нажатие на функцию слева под названием «CheckReward». Вознаграждения являются строительными блоками обучения с подкреплением, и нам нужно будет сообщить агенту, что именно он пытается оптимизировать с помощью этой функции вознаграждения. В этом случае мы хотим, чтобы он был вознагражден за каждый «эпизод» игры, в котором он удерживает цилиндр в вертикальном положении. Для этого будет использоваться оператор ветвления, эквивалент «if than else». У нас есть несколько условий, которые нужно проверить, поэтому мы присоединим узел ветвления к узлу ИЛИ. Затем создайте переменную с именем цилиндр типа Cyl_BP, которая будет использоваться для доступа к нашим переменным цилиндра. Вернитесь к плану уровня карты, выберите вкладку по умолчанию, и вы должны увидеть свою переменную Cyl_BP, щелкните раскрывающийся список и выберите объект Cyl_BP, который должен быть указан под именем вашей карты. Опять же, это значит, что ваша переменная Cylinder отражает значения из Cyl_BP. Вернитесь к графу событий для Cart_BP и из узла ИЛИ вашей ветви перетащите условные выражения для тангажа и крена цилиндра, то есть Cylpitch и Cylroll, и установите их больше 30 и меньше -30. Теперь из Истинной части ветки перетащите узел, устанавливая переменную награду на себя плюс один. Это увеличит награду за каждый эпизод игры, в котором цилиндр остается в вертикальном положении. Если false, мы устанавливаем переменную вознаграждения в ноль, сбрасывая все, потому что цилиндр упал. Это все, что касается функции вознаграждения.

Затем откройте функцию MakeObservations в Cart_BP. Нам нужно получить ссылку на шаг цилиндра, чтобы алгоритм RL мог научиться его оптимизировать. Подобно функции вознаграждения, возьмите переменную цилиндра, перетащите ее внутрь и вытащите переменную get cylpitch. Подключите это к узлу добавления набора наблюдений.

Мы почти закончили! Наконец, нам нужно изменить код отображения, чтобы среда обновлялась действиями, предпринимаемыми агентом. Перейдите к основному графику событий и найдите раздел логики «Задержка для отображения». Перед вызовом функции MakeObersvations добавьте узел MoveComponentTo и из ссылки на компонент на нем перетащите ссылку, чтобы получить «MindMakerStaticMesh». По сути, это комбинированные объекты, составляющие тележку. Из того же узла «MindMakerStaticMesh» перетащите узел «получить относительное местоположение» из заголовка преобразования. Щелкните правой кнопкой мыши на золотой булавке этого узла и выберите «Разделить структурный контакт». Теперь мы можем изменить переменные x y и z, относящиеся к нашей тележке, чтобы она двигалась в зависимости от действия, выбранного для нее алгоритмом RL.

На этом этапе в схеме переменная действия уже будет автоматически обновлена ​​в функции «RecieveAction». MindMaker обрабатывает создание действий, и они принимаются в UE через функцию ReceiveAction, так что впоследствии мы перемещаем агента в соответствии с выбранным действием. Теперь нам просто нужно передать наблюдения и награды за эти действия обратно в алгоритм MindMaker RL до тех пор, пока он не сгенерирует более эффективные действия, в своего рода добродетельном цикле. Это магия обучения с подкреплением.

Вернувшись к узлу MoveComponentTo, найдите контакт TargetRelativeLocation и перетащите узел MakeVector. Соедините относительное местоположение Y и относительное местоположение Z с соответствующими контактами в MakeVectorNode. Единственное, что мы хотим изменить, - это значение X, поскольку это плоскость, в которой тележка будет двигаться, то есть из стороны в сторону. Поэтому перетащите дополнительный узел из местоположения Relative X и добавьте к нему переменную «actionselected». Теперь, когда все готово, нам нужно добавить задержку, чтобы, когда цилиндр падает и сбрасывается, все временно приостанавливается, и MindMaker не просто продолжает генерировать действия «бездумно». Для этого создайте узел ветви после элементов набора в узле MindMakerCustomStruct. Ветвь должна проверять состояние логической переменной Start, которую мы создали в нашем Cyl_BP. Перетащите узел с ложного вывода на вызов задержки, установив это значение 0,1 секунды, а затем повторно подключите его к узлу ветвления в цикле. От истинного вывода он должен просто подключиться к узлу Emit, который был там раньше.

Наша последняя и последняя задача - настроить функцию LaunchMindMaker для работы с созданной нами средой. К счастью, это довольно просто. Первое, что нам нужно сделать, это выбрать алгоритм RL для обучения. Для этой задачи мы будем использовать Proximal Policy Optimization или PPO2 из раскрывающегося списка. Далее мы устанавливаем количество тренировочных серий, давайте попробуем для начала 1000. Для количества оценочных эпизодов установите это значение на 100. Чтобы сделать вещи более увлекательными, позвольте агенту использовать непрерывное пространство действий вместо дискретного набора действий. Таким образом, вместо того, чтобы просто перемещать тележку на одну клетку вправо или влево, она может перемещать ее дробно, делая пространство действия бесконечно большим и более сложным. В разделе пространства действий нам нужно указать диапазон, в котором агент может выполнять действия, давайте сделаем от 1 до -1. Это очень большое пространство, если учесть десятичные значения от 1 до -1. Он вводится в формате, используемом OPEN AI для определения пространств действий, и должен выглядеть следующим образом: «low = -1, high = 1, shape = (1,)».

Теперь нам нужно установить пространство наблюдения. Алгоритм RL в движке обучения MindMaker будет получать наблюдения о шаге цилиндров, и для нашей цели предположим, что они будут в диапазоне от -100 до 120, поэтому введите «low = np.array ([- 100]), high = np. array ([120]), dtype = np.float32 ”Это снова из формата OpenAI для пространств наблюдения. Далее, если мы хотим использовать какие-либо специальные параметры для нашего алгоритма RL, есть много всего, что можно изменить. Я прилагаю снимок экрана с одной установкой, которая, кажется, хорошо подходит для этой задачи.

Готово! Вернитесь в окно просмотра уровня карты и нажмите кнопку воспроизведения, чтобы начать обучение. Вы должны увидеть, как обучающий движок MindMaker начинает управлять тележкой. Размер совершаемых им движений, по сути, случайные действия, которые он выполняет, чтобы научиться балансировать тележку, будут передаваться по экрану. После тысячи повторений он должен был научиться балансировать тележку. Во многих случаях это можно сделать очень небольшими движениями, при которых тележка не упадет.

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

Например, недавно один из основателей компании DeepMind выразил заинтересованность в обнаружении сверхпроводника при комнатной температуре с помощью обучения с подкреплением. Для такой цели проблема создания правильного симулятора может быть невероятно сложной, поскольку симулятор должен улавливать все свойства физики и химии, которые взаимодействуют в сверхпроводниках. В то время как алгоритм обучения с подкреплением, необходимый для решения такой задачи, может быть представлен на нескольких страницах кода и требует для работы только портативного компьютера, симулятор, необходимый для моделирования среды, в которой работают сверхпроводники, может быть настолько сложным, что потребуются годы программирование и гигантские суперкомпьютеры для работы. Многие из самых неясных свойств физики взаимодействуют в сверхпроводниках, и нужно было бы уловить значительную их часть, чтобы быть уверенным, что решение, полученное обучающимся с подкреплением, применимо к нашей физической реальности, а не только к реальности симулятора. Поэтому крайне важно при работе с алгоритмами RL иметь доступ к лучшим симуляторам, таким как Unreal Engine.

Использование функций чертежей Unreal Engine также снижает барьеры для входа в сферу машинного обучения. Разработчики, практически не имеющие опыта программирования, могут погрузиться в работу и начать использовать те же алгоритмы, что и профессионалы в области машинного обучения, и все это без необходимости пачкать руки, возясь с кодом Python или Tensorflow.

Если у вас есть вопросы или запросы, не стесняйтесь оставлять их здесь или обращаться ко мне лично. В следующих статьях я буду исследовать связанные темы, такие как темное искусство инженерии вознаграждений - в частности, как вылепить подходящие функции вознаграждения для использования со своим настраиваемым агентом RL.