Внедрение A2C с несколькими воркерами или без них с помощью TensorFlow 2.x

Эта статья является второй частью серии Актер-критик с TensorFlow 2.x. В предыдущей статье мы реализовали метод Naive Actor-Critic с помощью TensorFlow 2.x, а в этой статье мы будем реализовывать метод Advantage Actor-Critic (A2C) с / без нескольких рабочих. Вы можете сослаться на мою предыдущую статью из этой серии здесь.

Преимущество актер-критик (A2C):

Давайте сначала сделаем обзор алгоритма A2C, чем попытаемся понять код. Шаги для алгоритма следующие.

Без нескольких рабочих:

  1. Агент играет для n временных шагов и сохраняет состояния, действия и награды для n временных шагов.
  2. Рассчитайте ожидаемую прибыль от состояния, используя уравнение дисконтирования вознаграждений, то есть (R = r + Gamma * R) для каждого состояния.
  3. Вычислить потерю актера и потерю критики (мы рассмотрим это в разделе кода)
  4. Обновляйте сеть через каждые n шагов. Пожалуйста, обратите внимание, что в этой статье мы будем обновлять после каждого выпуска для простоты, и это зависит от среды, которую вы используете.
  5. Повторяйте описанный выше процесс до схождения.

С несколькими работниками:

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

Код (без нескольких рабочих):

Нейронные сети:

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

Инициализация агента и выбор действия:

  1. Эти две функции также одинаковы, но на этот раз скорость обучения другая.
  2. Короче говоря, мы использовали библиотеку вероятностей TensorFlow, чтобы превратить вероятности в распределение для выборки действий.

Теперь давайте сначала посмотрим на взаимодействие с окружающей средой для лучшего понимания.

Основной цикл обучения:

  1. Агент взаимодействует с окружающей средой и сохраняет состояние, действие и награду в своих списках.
  2. Когда эпизод завершен, вызывается функция preprocess1, которая принимает приведенные выше списки в качестве входных и выходных массивов NumPy для состояний, действий и ожидаемого возврата из каждого состояния (аналогично Монте-Карло для расчета ожидаемого возврата из каждого состояния).
  3. Затем сети агента обновляются с использованием этих массивов NumPy.

Узнай функцию и потерю:

Итак, это несколько иначе. давайте разбираться в этом шаг за шагом.

  1. Функция Learn принимает в качестве входных данных массивы состояний, действий и ожидаемого возврата из состояний NumPy (здесь записанные как discnt_rewards).
  2. Актер предсказывает вероятности для каждого действия в каждом состоянии. И критик предсказывает ценность для каждого состояния.
  3. Временная разница рассчитывается как разница ч / б ожидаемых доходов от состояний и значений, предсказанных критиком.
  4. Критические потери рассчитываются как MSE с ожидаемой доходностью в качестве целевого значения и прогнозируемыми значениями в качестве прогноза.
  5. Поначалу Actor Loss довольно сложно реализовать, поскольку во многих онлайн-уроках используется встроенный SparseCategoricalCrossentropy TensorFlow, который я считаю абстрактным. Итак, вот простая реализация.
  6. Потеря актора - это комбинация двух потерь, а именно: потери полиса и потери энтропии. Потеря политики, которая является отрицательной из логарифмической вероятности действий, предпринятых в этом состоянии, умноженной на временную разность для этого состояния. А потеря энтропии является отрицательной величиной вероятности предпринятого действия, умноженной на логарифмическую вероятность действия, предпринятого в этом состоянии.
  7. Реализация потери может сначала выглядеть пугающей, но цель такой реализации состоит в том, что тензоры, предсказанные сетями, не могут быть преобразованы в массив NumPy, если вы конвертируете значения в массив NumPy, вы получите сообщение об отсутствии градиента. .
  8. Таким образом, функция потерь актора принимает в качестве входных данных тензоры вероятностей действий, предсказываемых актором, действиями и временными различиями.
  9. Первый цикл for превращает каждое предсказание в распределение, поэтому мы можем получить вероятность и логарифмическую вероятность действий, предпринятых в каждом состоянии. Потребность в «цикле for» заключается в том, чтобы мы могли получить вероятность предпринятого действия, не превращая вероятности в массив NumPy.
  10. Затем рассчитываем убыток.

Учебный участок:

Ниже приведен график средней награды ч / б за последние 100 эпизодов по сравнению с эпизодами.

Код (с несколькими рабочими):

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

Для реализации нескольких рабочих A2C требуется только модификация в основном цикле обучения.

  1. Мы создаем 3 общие очереди для состояний, действий и ожидаемых наград соответственно. И создал экземпляр Barrier и экземпляр блокировки, используя многопроцессорную библиотеку python.
  2. Затем мы запускаем процесс 10, который выполняет функцию бегуна. А с помощью join () мы гарантируем завершение каждого процесса.

Основной цикл обучения:

  1. Функция Runer взаимодействует с окружающей средой и сохраняет переходы в списках, как мы видели раньше.
  2. Когда эпизод выполняется для рабочего, он вызывает функцию preprocess1, которая выполняет ту же задачу, что и раньше, но на этот раз она помещает состояния, действия и ожидаемые награды в их уважаемые очереди (сначала получая блокировку, чтобы ни один другой работник не помещал ее опыт между опытом других рабочих и снятием блокировки после помещения их опыта в очередь).
  3. Мы позволяем только одному работнику извлекать опыт и обучать сети с помощью экземпляра Barrier.
  4. Функция preprocess2 извлекает эти события из очередей и объединяет их в один массив NumPy для состояний, один для действий и один для ожидаемых вознаграждений.
  5. Потом сети обновляются. Последняя строка Barrier.wait () гарантирует, что все остальные рабочие будут ждать, пока все рабочие не достигнут этой точки.

Итак, это все о кодировании. Теперь давайте рассмотрим причины, по которым ваш агент не учится, и несколько советов.

О чем нужно позаботиться при выполнении:

При кодировании RL следует иметь в виду следующее.

  1. Количество нейронов, скрытые слои, скорость обучения имеют огромное влияние на обучение.
  2. Форма тензоров и массива NumPy должна быть правильной. Часто реализация правильная и коды работают, но агент ничего не узнает только потому, что форма тензоров неправильная, и когда операции применяются к этим тензорам, дают неправильные результаты.

Вы можете найти полный код этой статьи здесь и здесь. Следите за обновлениями в следующих статьях, в которых мы будем реализовывать PPO в TensorFlow 2.

На этом статья завершается. Спасибо за чтение, надеюсь, вам понравилось, и вы смогли понять то, что я хотел объяснить. Надеюсь, вы прочитаете мои предстоящие статьи. Хари Ом… 🙏

Использованная литература: