Глубокое обучение с подкреплением для совместной работы и конкуренции между несколькими агентами

26 декабря 2018 г., Thomas Tracey, изначально размещено на Github

В этом посте рассматривается моя работа над финальным проектом Udacity Глубокое обучение с подкреплением Nanodegree. Моя цель - помочь другим студентам и специалистам в области машинного обучения (ML), которые находятся на ранних этапах развития своей интуиции в обучении с подкреплением (RL).

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

Мое репозиторий Github для этого проекта можно найти здесь. Исходный репозиторий Udacity для этого проекта находится здесь.

Общая картина: почему RL имеет значение

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

Один из шагов на этом пути - обучить агентов ИИ взаимодействовать с другими агентами как в кооперативной, так и в конкурентной среде. Обучение с подкреплением (RL) - это многообещающее подполе ИИ. RL отличается от других типов подходов к машинному обучению тем, что агенты RL ориентированы на достижение цели. То есть алгоритмы RL используют функцию вознаграждения (также известную как целевая функция) для усиления определенного поведения. Например, агент Pac-Man может получить награду в размере +1 балл за каждую съеденную гранулу и -100 баллов за столкновение с призраком. Пытаясь максимизировать совокупное вознаграждение, агент Pac-Man в конечном итоге учится - путем многократных проб и ошибок - как отличать хорошие действия от плохих.

OpenAI сделал большой набор виртуальных сред общедоступным для обучения и тестирования агентов RL. Это стимулировало множество исследований и инноваций в RL. Однако большая часть первоначального прогресса была в областях с одним агентом, где нет необходимости в построении моделей, предсказывающих поведение других участников. В результате традиционные подходы RL (такие как Q-Learning) плохо подходят для сложности, которая сопровождает среды, в которых несколько агентов постоянно взаимодействуют и развивают свои политики.

К сожалению, традиционные подходы к обучению с подкреплением, такие как Q-Learning или градиент политики, плохо подходят для многоагентных сред. Одна из проблем заключается в том, что политика каждого агента меняется по мере продвижения обучения, и среда становится нестационарной с точки зрения любого отдельного агента, что не может быть объяснено изменениями в собственной политике агента. Это создает проблемы для стабильности обучения и предотвращает прямое использование воспроизведения прошлого опыта, что имеет решающее значение для стабилизации глубокого Q-обучения. С другой стороны, методы градиента политики обычно демонстрируют очень большую вариативность, когда требуется координация нескольких агентов. В качестве альтернативы можно использовать оптимизацию политики на основе модели, которая может изучить оптимальные политики с помощью обратного распространения, но для этого требуется дифференцируемая модель мировой динамики и предположения о взаимодействиях между агентами. Применение этих методов в конкурентной среде также является сложной задачей с точки зрения оптимизации, о чем свидетельствует печально известная нестабильность состязательных методов обучения.

- Лоу и Ву и др., Мультиагентный субъект-критик для смешанных кооперативно-конкурентных сред

Вау, это полный рот. По сути, то, что необходимо (и что исследуется в этом проекте), - это общая структура, которая позволяет нескольким агентам извлекать уроки из своих собственных наблюдений как в совместной, так и в конкурентной среде. Это без какой-либо связи между агентами или моделирования поведения других агентов. Однако каждый агент в этом проекте учится, наблюдая за своими действиями и действиями другого агента. Каждое наблюдение включает в себя: предыдущее игровое состояние, действие агента, награду и последующее игровое состояние (s, a, r, sʹ).

Новые подходы к совместной и конкурентной среде быстро развиваются. Я не буду подробно исследовать их в этом посте, но рекомендую проверить OpenAI Five и DeepMind AlphaStar.

Цель этого проекта

Цель этого проекта - обучить двух агентов RL играть в теннис. Как и в реальном теннисе, цель каждого игрока - сохранить мяч в игре. А когда у вас есть два равных соперника, вы, как правило, наблюдаете довольно продолжительные обмены, когда игроки отбивают мяч вперед и назад через сетку.

Окружение

Мы будем работать со средой, похожей, но не идентичной Теннисной среде на странице Unity ML-Agents на GitHub.

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

Пространство наблюдения состоит из 8 переменных, соответствующих положению и скорости мяча и ракетки. Каждый агент получает собственное, локальное наблюдение. Доступны два непрерывных действия: движение к сетке (или от нее) и прыжок.

Задача носит эпизодический характер, и для решения задачи агенты должны получить средний балл +0,5 (более 100 последовательных эпизодов после взятия максимума над обоими агентами).

Конкретно,

  • После каждого эпизода мы складываем награды, полученные каждым агентом (без учета скидки), чтобы получить балл для каждого агента. Это дает 2 потенциально разных балла. Затем мы берем максимум из этих двух оценок.
  • Это дает единый балл для каждого эпизода.
  • Среда считается решенной, если среднее значение (более 100 эпизодов) этих оценок составляет не менее +0,5.

Вот пример двух полуобученных агентов, взаимодействующих в этой среде.

Подход

Вот общие шаги, которые были предприняты при создании агента, решающего эту среду.

  1. Установите базовый уровень производительности, используя политику случайных действий.
  2. Выберите подходящий алгоритм и приступайте к его реализации.
  3. Проводите эксперименты, вносите изменения и переобучайте агент, пока не будет достигнут порог производительности.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: я в конечном итоге нашел хорошее решение; однако результаты не были последовательными. Мои лучшие результаты можно было воспроизвести, только если я перепроверил модель несколько раз (›10). Если вы просто запустите модель один раз (или даже 3-5 раз), она может не сойтись. И во время первоначальной реализации я запускал модель не менее 30 раз в поисках надежного набора гиперпараметров. Если вы хотите поэкспериментировать с разными подходами, я настоятельно рекомендую реализовать более систематический подход к настройке гиперпараметров (чего я не делал, но хотел бы иметь).

Установление базовой линии

Прежде чем создавать обучающиеся агенты, я начал с тестирования агентов, которые выбирают действия (равномерно) случайным образом на каждом временном шаге.

Выполнение случайных агентов несколько раз привело к получению баллов от 0 до 0,02. Очевидно, что если этим агентам необходимо набрать в среднем 0,5 балла за 100 последовательных эпизодов, случайный выбор действий не сработает. Однако, если вы посмотрите, как агенты действуют случайным образом, становится ясно, что эти типы спорадических действий могут быть полезны на ранних этапах тренировочного процесса. То есть они могут помочь агентам исследовать пространство действий, чтобы найти какой-то сигнал о хороших и плохих действиях. Это понимание пригодится позже, когда мы реализуем процесс Орнштейна-Уленбека и затухание эпсилон-шума.

Реализация алгоритма обучения

Для начала нам необходимо принять несколько архитектурных решений высокого уровня. Во-первых, нам нужно определить, какие типы алгоритмов наиболее подходят для среды тенниса.

Методы, основанные на политике, и методы, основанные на ценности

В среде Tennis есть два ключевых отличия от среды Navigation из первого проекта программы Udacity Deep RL:

  1. Несколько агентов. В среде Tennis есть два разных агента, тогда как в проекте Navigation был только один агент.
  2. Пространство непрерывного действия. Пространство действий теперь непрерывное (вместо дискретного), что позволяет каждому агенту выполнять более сложные и точные движения. Несмотря на то, что каждый теннисный агент может двигаться только вперед, назад или прыгать, существует неограниченный диапазон возможных значений действия, которые управляют этими движениями. Тогда как агент в Навигационном проекте был ограничен четырьмя дискретными действиями: влево, вправо, вперед, назад.

Учитывая дополнительную сложность этой среды, метод на основе значений, который мы использовали для проекта навигации, не подходит, то есть алгоритм Deep Q-Network (DQN). Самое главное, нам нужен алгоритм, который позволяет теннисному агенту использовать весь свой диапазон и силу движений. Для этого нам потребуется изучить другой класс алгоритмов, называемый методами на основе политик.

Вот некоторые преимущества методов на основе политик:

  • Пространства непрерывного действия. Методы, основанные на политике, хорошо подходят для непрерывных пространств действий.
  • Стохастические политики. Как методы, основанные на ценностях, так и методы, основанные на политике, могут изучать детерминированные политики. Однако методы, основанные на политиках, также могут изучить истинные стохастические политики.
  • Простота. Методы, основанные на политике, непосредственно изучают оптимальную политику, без необходимости поддерживать отдельную оценку функции ценности. При использовании методов, основанных на значениях, агент использует свой опыт работы со средой для поддержания оценки оптимальной функции значение-действие, из которой выводится оптимальная политика. Этот промежуточный шаг требует хранения большого количества дополнительных данных, поскольку вам необходимо учитывать все возможные значения действий. Даже если вы дискретизируете пространство действий, количество возможных действий может стать довольно большим. А использование DQN для определения действия, которое максимизирует функцию значения действия в непрерывном или многомерном пространстве, требует сложного процесса оптимизации на каждом временном шаге.

Градиент глубоко детерминированной политики для нескольких агентов (MADDPG)

Исходный алгоритм DDPG, который я расширил до версии MADDPG, описан в этой статье, Непрерывное управление с глубоким обучением с подкреплением, исследователями из Google Deepmind. В этой статье авторы представляют свободный от моделей алгоритм критика субъектов вне политики, использующий глубокие аппроксиматоры функций, которые могут изучать политики в многомерных пространствах непрерывных действий. Они подчеркивают, что DDPG можно рассматривать как расширение Deep Q-Learning для непрерывных задач.

Для основы DDPG я использовал этот ванильный одноагентный DDPG в качестве шаблона. Затем, чтобы сделать этот алгоритм подходящим для множества конкурирующих агентов в теннисной среде, я реализовал компоненты, описанные в этой статье Мультиагентный фактор-критик для смешанных кооперативно-конкурентных сред Лоу и Ву вместе с другими исследователями из OpenAI, Калифорнийского университета в Беркли и Университета Макгилла. В частности, я реализовал их вариант метода актер-критик (см. Рис. 1), который я расскажу в следующем разделе.

Наконец, я поэкспериментировал с компонентами алгоритма DDPG на основе других концепций, рассмотренных в классе и на уроках Udacity. Моя реализация этого алгоритма (включая различные настройки) обсуждается ниже.

Актерско-критический метод

Методы актерской критики используют сильные стороны как методов, основанных на политике, так и методов, основанных на ценностях.

Используя подход, основанный на политике, агент (субъект) учится действовать, напрямую оценивая оптимальную политику и максимизируя вознаграждение за счет градиентного подъема. Между тем, используя ценностный подход, агент (критик) учится оценивать ценность (то есть будущую совокупную награду) различных пар состояние-действие. Методы «актер-критик» объединяют эти два подхода, чтобы ускорить процесс обучения. Агенты-субъекты-критики также более стабильны, чем агенты, основанные на ценностях, и при этом требуют меньшего количества обучающих выборок, чем агенты, основанные на политике.

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

Вы можете найти логику актер-критик, реализованную как часть Agent() класса здесь в maddpg_agent.py исходного кода. Модели актер-критик можно найти через соответствующие классы Actor() и Critic() здесь в models.py.

Примечание. Как и в случае с Double Q-Learning в последнем проекте Непрерывное управление: обучение роботов-манипуляторов, мы снова используем локальные и целевые сети для повышения стабильности. Здесь один набор параметров w используется для выбора наилучшего действия, а другой набор параметров используется для оценки этого действия. В этом проекте локальная и целевая сети реализованы отдельно как для актера, так и для критика.

Разведка против эксплуатации

Одна из проблем - выбрать, какое действие предпринять, пока агент все еще изучает оптимальную политику. Следует ли агенту выбирать действие на основе полученных до сих пор наград? Или агент должен попробовать новое действие в надежде получить более высокую награду? Это известно как дилемма разведки и эксплуатации.

В предыдущем Навигационном проекте я решил эту проблему, реализовав 𝛆-жадный алгоритм. Этот алгоритм позволяет агенту систематически управлять компромиссом между разведкой и эксплуатацией. Агент исследует, выбирая случайное действие с некоторой вероятностью эпсилон 𝛜. Тем временем агент продолжает эксплуатировать свои знания об окружающей среде, выбирая действия, основанные на детерминированной политике с вероятностью (1-).

Однако этот подход не работает для управления теннисными агентами. Причина в том, что действия больше не являются дискретным набором простых направлений (т.е. вверх, вниз, влево, вправо). Действия, управляющие движением руки, представляют собой силы с разной величиной и направлением. Если мы основываем наш механизм исследования на случайной однородной выборке, действия направления будут иметь нулевое среднее значение, в свою очередь взаимно компенсируя друг друга. Это может вызвать колебания системы без особого прогресса.

Вместо этого мы воспользуемся процессом Орнштейна-Уленбека, как это предлагается в ранее упомянутой статье Google DeepMind (см. Нижнюю часть страницы 4). Процесс Орнштейна-Уленбека добавляет определенное количество шума к значениям действия на каждом временном шаге. Этот шум коррелирует с предыдущим шумом и, следовательно, имеет тенденцию оставаться в том же направлении в течение более длительных периодов времени, не прекращая себя. Это позволяет агенту поддерживать скорость и исследовать пространство действия с большей непрерывностью.

Вы можете найти процесс Орнштейна-Уленбека, реализованный здесь в классе OUNoise() в maddpg_agent.py исходного кода.

Всего с этим шумовым процессом связано пять гиперпараметров.

Сам процесс Орнштейна-Уленбека имеет три гиперпараметра, которые определяют характеристики и величину шума:

  • mu: долгосрочное среднее
  • theta: скорость возврата к среднему.
  • сигма: параметр волатильности.

Из них настроил только сигму. Проведя несколько экспериментов, я уменьшил сигму с 0,3 до 0,2. Уменьшение волатильности шума, казалось, помогло модели сойтись.

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

Вы можете найти процесс распада эпсилона, реализованный здесь в Agent.act() методе maddpg_agent.py исходного кода. В то время как распад эпсилона выполняется здесь как часть этапа обучения.

Окончательные параметры шума были установлены следующим образом:

OU_SIGMA = 0.2   # Ornstein-Uhlenbeck noise parameter, volatility
OU_THETA = 0.15  # OU noise parameter, speed of mean reversion
EPS_START = 5.0  # initial value for epsilon in noise decay process
EPS_EP_END = 300 # episode to end the noise decay process
EPS_FINAL = 0    # final value for epsilon after decay

ВАЖНОЕ ПРИМЕЧАНИЕ. Обратите внимание, что для параметра EPS_START установлено значение 5.0. В десятках экспериментов у меня был этот параметр равным 1.0, как и в предыдущих проектах. Но мне было трудно добиться сходимости модели, а если и получилось, то она сходилась очень медленно (›1500 эпизодов). После долгих проб и ошибок я понял, что агентам было трудно обнаружить сигнал на ранней стадии процесса (т.е. большинство эпизодов равнялись нулю). Повышая уровень шума от процесса Орнштейна-Уленбека (OU), он поощрял агрессивное исследование пространства действия и, следовательно, увеличивал шансы того, что сигнал будет обнаружен (то есть вступит в контакт с мячом). Этот дополнительный сигнал, казалось, улучшил обучение на более поздних этапах обучения, когда шум спал до нуля.

Интервал обучения

В первых нескольких версиях моей реализации агент выполнял только одну итерацию обучения для каждого эпизода. Хотя лучшая модель имела такую ​​настройку, это казалось удачей. В целом, я обнаружил, что выполнение нескольких обучающих проходов за эпизод дает более быструю конвергенцию и более высокие баллы. Это действительно замедляло тренировку, но это был стоящий компромисс. В итоге я реализовал интервал, в котором этап обучения выполняется в каждом эпизоде. В рамках каждого шага обучения алгоритм затем производит выборку опыта из буфера и запускает метод Agent.learn() 10 раз.

LEARN_EVERY = 1  # learning interval (no. of episodes)
LEARN_NUM = 5    # number of passes per learning step

Вы можете найти интервал обучения, реализованный здесь в Agent.step() методе maddpg_agent.py исходного кода.

Градиентная обрезка

В ранних версиях моей реализации у меня были проблемы с обучением моего агента. Или, скорее, он начал бы учиться, но затем стал бы очень нестабильным и либо вышел на плато, либо рухнул.

Подозреваю, что одной из причин были негабаритные градиенты. К сожалению, мне не удалось найти простой способ исследовать это, хотя я уверен, что в PyTorch есть способ сделать это. В отсутствие этого исследования я предполагаю, что многие веса из моей модели критика становились довольно большими после всего лишь 50–100 тренировок. А поскольку я запускал процесс обучения несколько раз за серию, это только усугубило проблему.

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

Чтобы бороться с этим, я реализовал отсечение градиента с помощью функции torch.nn.utils.clip_grad_norm. Я установил функцию обрезать норму градиентов на 1, поэтому установил верхний предел для размера обновлений параметров и предотвратил их экспоненциальный рост. После того, как это изменение было реализовано, моя модель стала намного более стабильной, и мой агент начал учиться намного быстрее.

Вы можете найти градиентное отсечение, реализованное здесь, в разделе критик обновления метода Agent.learn() в ddpg_agent.py исходного кода.

Обратите внимание, что эта функция применяется после обратного прохода, но до этапа оптимизации.

# Compute critic loss
Q_expected = self.critic_local(states, actions)
critic_loss = F.mse_loss(Q_expected, Q_targets)
# Minimize the loss
self.critic_optimizer.zero_grad()
critic_loss.backward()
torch.nn.utils.clip_grad_norm_(self.critic_local.parameters(), 1)
self.critic_optimizer.step()

Опыт Replay

Воспроизведение опыта позволяет агенту RL извлечь уроки из прошлого опыта.

Как и в предыдущем проекте, алгоритм использует буфер воспроизведения для сбора опыта. Опыт хранится в едином буфере воспроизведения, поскольку каждый агент взаимодействует с окружающей средой. Затем этот опыт используется центральным критиком, что позволяет агентам учиться на опыте друг друга.

Буфер воспроизведения содержит набор кортежей опыта с состоянием, действием, наградой и следующим состоянием (s, a, r, sʹ). Критик делает выборку из этого буфера на этапе обучения. Опыт отбирается случайным образом, чтобы данные не коррелировали. Это предотвращает катастрофическое колебание или расхождение значений действий, поскольку в противном случае наивный алгоритм мог бы стать смещенным из-за корреляций между последовательными экспериментальными кортежами.

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

Реализацию буфера воспроизведения можно найти здесь в maddpg_agent.py файле исходного кода.

Полученные результаты

После того, как все вышеперечисленные компоненты были на месте, агенты смогли решить проблему тенниса. Опять же, цель производительности - это среднее вознаграждение не менее +0,5 за 100 эпизодов, принимая лучший результат от любого агента за данный эпизод.

Вот видео, на котором обученные агенты разыгрывают несколько очков.

На графике ниже показаны окончательные результаты обучения. Самые эффективные агенты смогли решить среду в 607 эпизодах с наивысшим баллом 5,2 и максимальным скользящим средним 0,927. Полный набор результатов и шагов можно найти в блокноте Jupyter Tennis.ipynb.

Будущие улучшения

  • Устранение проблем со стабильностью для получения более стабильных результатов. Мои «лучшие» результаты можно воспроизвести, только если вы запустите модель несколько раз. Если вы просто запустите его один раз (или даже 3-5 раз), модель может не сойтись. Я прогнал модель как минимум 30 при поиске хорошего набора гиперпараметров, поэтому, возможно, поможет реализация более системного подхода, такого как поиск по сетке. В противном случае необходимы дополнительные исследования, чтобы найти более стабильный алгоритм или внести изменения в текущий алгоритм DDPG.
  • Добавьте приоритет воспроизведения опыта. Вместо случайного выбора кортежей опыта, приоритетное воспроизведение выбирает события на основе значения приоритета, которое коррелирует с величиной ошибки. Это может улучшить обучение за счет увеличения вероятности выборки редких или важных векторов опыта.
  • Пакетная нормализация. Я не использовал пакетную нормализацию в этом проекте, но, вероятно, мне следовало бы это сделать. В прошлом я много раз использовал пакетную нормализацию при построении сверточных нейронных сетей (CNN), чтобы уменьшить значения пикселей. Но мне и в голову не пришло, что именно к этому проекту. Пакетная нормализация использовалась в статье Google DeepMind и оказалась чрезвычайно полезной в моей реализации других проектов. Подобно упомянутой выше проблеме взрывного градиента, выполнение вычислений с большими входными значениями и параметрами модели может препятствовать обучению. Пакетная нормализация решает эту проблему, масштабируя функции, чтобы они находились в одном диапазоне по всей модели и в разных средах и единицах измерения. В дополнение к нормализации каждого измерения, чтобы иметь единичное среднее значение и дисперсию, диапазон значений часто намного меньше, обычно от 0 до 1. Вы можете найти пакетную нормализацию, реализованную здесь для актера и здесь для критика в пределах model.py исходного кода моего предыдущего проекта Тренировка рук-роботов с непрерывным управлением. Это значительно улучшило производительность и стабильность модели.

Контакт

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

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