Создайте один из самых простых алгоритмов обучения с подкреплением с помощью PyTorch

Вы когда-нибудь задумывались, как работает обучение с подкреплением (RL)?

В этой статье мы создадим с нуля одну из самых простых форм RL — алгоритм ванильного политик-градиента (VPG). Затем мы обучим его выполнять знаменитую задачу CartPole — научиться перемещать тележку слева направо, чтобы сбалансировать шест. При этом мы также выполним первую задачу учебного ресурса OpenAI Spinning Up.

Код для этой статьи можно найти по адресу https://github.com/alan-cooney/cartpole-algorithms/blob/main/src/vanilla_policy_gradient.py.

Наш подход

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

Затем все, что нам нужно сделать, это накопить опыт, действуя в среде, используя эту политику.

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

И это действительно все, что нужно — так что давайте начнем кодировать!

Создание модели

Мы начнем с создания довольно простой модели с одним скрытым слоем. Первый линейный слой берет входные объекты из пространства наблюдения CartPole, а последний слой возвращает значения для возможных результатов.

Получение полиса

Нам также потребуется получить политику для модели один раз на каждый временной шаг (чтобы мы знали, как действовать). Для этого мы создадим функцию get_policy, которая использует модель для вывода вероятностей каждого действия в соответствии с политикой. Затем из этого мы можем получить категориальное (полиномиальное) распределение, которое можно использовать для выбора конкретных действий, случайно распределенных в соответствии с этими вероятностями.

Выборка действий из политики

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

Расчет убытка

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

Чтобы рассчитать это с помощью PyTorch, мы можем рассчитать псевдо-убыток ниже, а затем использовать .backward(), чтобы получить градиент выше (обратите внимание, что мы только что удалили член градиента):

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

Обучение эпохи

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

Запуск алгоритма

И с этим вы готовы запустить алгоритм. Вы можете запустить полный код с https://github.com/alan-cooney/cartpole-algorithms/blob/main/src/vanilla_policy_gradient.py, и вы должны увидеть, что модель хорошо изучила среду (оценка 180). +/200) примерно через 40 эпох.

Надеюсь, вам понравилось читать это, и если у вас есть какие-либо вопросы, просто дайте мне знать в комментариях!

Алан