Глубокое Q-обучение
Введение
В прошлой статье про обучение с подкреплением мы разобрали алгоритм Q-обучения для решения табличных задач. Хотя это было полезно для понимания самого алгоритма и построения интуиции, многие реальные задачи практически невозможно свести к табличной форме. Часто размерность пространства состояний или действий оказывается очень большой. Поэтому использование таблиц для хранения и обновления Q-значений становится невозможным.
В качестве примера рассмотрим задачу обучения агента играть в игры Atari. Здесь пространство действий невелико — до 10 действий, однако пространство состояний очень большое. Другой пример — обучение четвероногого робота ходить, где пространство действий, как и пространство состояний, непрерывное.
Как же мы можем модифицировать Q-обучение из прошлой статьи, чтобы решить более сложные задачи? Спойлер: заменить таблицу на нейронную сеть 🙂
Коротко об основах
Обучение с подкреплением (reinforcement learning) — это метод решения задач обучения и управления путем взаимодействия со средой. В отличие от обучения с учителем, где предсказание модели не влияет на исходные данные, в RL действие агента меняет состояние среды, в которой он находится. Взаимодействие агента со средой в RL происходит следующим образом: сначала агент получает состояние среды
Задачу RL можно сформулировать как нахождение оптимальной стратегии (политики), которая максимизирует суммарное дисконтированное (то есть взвешенное) вознаграждение в ожидании:
где \( \gamma \) — значение дисконта, а \( G_t \) — суммарное вознаграждение (англ. return).
Задачу RL можно решить либо напрямую, изменяя саму стратегию, либо косвенно, обучая функцию ценности и выбирая действие, которое максимизирует ее. Прямой метод мы разберем в следующей статье, а сегодня разберемся с косвенными методами.
Функция ценности — это ожидаемое дисконтированное вознаграждение, которое получит агент, если он будет следовать стратегии \( \pi \), начиная состоянием \( s \):
\( \begin{align} V_\pi(s) &= \mathbb{E}_\pi\big[R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + \dots\ |\ S_t = s\big] \nonumber \\ &= \mathbb{E}_\pi\big[G_{t}\ |\ S_t = s\big] \nonumber \end{align} \)
Есть два способа подсчета \( V_\pi(s) \): метод Монте-Карло и обучение на временных разностях.
В методе Монте-Карло после того, как мы оказались в состоянии \( s_t \), мы сохраняем значения наград \( R_{t+1}, R_{t+2},\dots,R_{t+N} \) и на их основе обновляем \( V_\pi(s) \). Недостаток этого метода заключается в высокой дисперсии оценки функции ценности и необходимости дожидаться окончания эпизода для ее обновления.
В обучении на временных разностях используется уравнение Беллмана: \( G_{t} = R_t + \gamma V(s_{t+1}) \). Хотя этот метод страдает от сдвига, он хорошо работает на практике и, в частности, лежит в основе Q-обучения.
Помимо функции ценности еще одно полезное понятие — функция ценности действий, или Q-функция. Она показывает ожидаемое дисконтированное вознаграждение, которое получит агент, если примет действие \( a_t \), а затем будет следовать стратегии \( \pi \), начиная состоянием \( s_{t+1} \):
\( \begin{align} Q_\pi(s,a) = \mathbb E_\pi\big[ G_t\ |\ S_t=s, A_t=a] . \nonumber \end{align} \)
Эту функцию мы использовали в Q-обучении — методе обучения на временны х разностях (temporal-difference learning). А саму Q-таблицу изменяли следующим образом:
\( \begin{align} Q(S_t, A_t) \leftarrow Q(S_t, A_t) + \alpha \big [R_{t+1} + \gamma\cdot \underset{a}{\max}\ Q(S_{t+1}, a)- Q(S_t, A_t)\big] = Q(S_t, A_t) + \alpha \big [\mathrm{TD\ target} — Q(S_t, A_t)\big]. \end{align} \)
От таблиц к нейросети
Давайте представим: мы хотим обучить агента играть в игры Atari с дискретными действиями (например, двигаться влево, вправо и стрелять). В этих играх, как и в шахматах, количество состояний крайне велико: во-первых, для хранения Q-таблицы понадобится огромное количество памяти, а во-вторых, для посещения всех состояний и обновления Q-таблицы потребуются годы. Чтобы решить эту проблему, мы можем использовать нейронные сети и аппроксимировать значения Q-таблицы. Мы назовем эту сеть Q-network, и она будет возвращать Q-значения для каждого действия в заданном состоянии \( s \).
Для обучения Q-network нам нужно переписать (1) как минимизацию целевой функции. В результате получим:
\( \begin{align} \underset{\theta}{\min}\ \frac{1}{2}\sum \left(y_i — Q(s_i, a_i;\theta)\right)^2, \end{align} \)
где \( y_i \) — целевое значение Q-функции, которое определяется уравнением Беллмана:
\( \begin{align} y_i = R_i + \gamma\cdot \underset{a’}{\max} \ Q(s_{i+1}, a’; \theta). \end{align} \)
При использовании нейронных сетей, обучения на временных разностях (бутстрэппинга) и off-policy алгоритмов, таких как Q-обучение (часто называемых «смертоносной тройкой»), все гарантии сходимости (итерация стратегии и итерация функции ценности) — получения оптимальной стратегии — исчезают. Но есть три трюка для стабилизации Q-обучения:
- Воспроизведение опыта (Experience Replay) для более эффективного использования собранного опыта: данных в виде кортежей (состояние, действие, вознаграждение, следующее состояние) или \( (s_t, a_t, r_t, s_{t+1}) \);
- Фиксированная Q-цель (Fixed Q-target) для стабилизации обучения;
- Двойное глубокое Q-обучение (Double Q-learning) для борьбы с ошибочно завышенными Q-значениями.
Воспроизведение опыта
Зачем нам глобальная память, где хранятся кортежи (состояние, действие, вознаграждение, следующее состояние)? Прежде чем ответить на этот вопрос, давайте вспомним, как работает онлайн-обучение. В этом режиме агент взаимодействует со средой, собирает данные, учится на их основе — обновляет параметры нейросети, которая определяет стратегию. Затем он отбрасывает собранный опыт (собранные данные) и заново собирает данные и обновляет веса. Такой подход оказывается неэффективным и требует значительного времени для поиска хорошей стратегии.
Кроме того, при использовании нейросетей и отбрасывании предыдущего опыта возникает риск столкнуться с катастрофическим забыванием (catastrophic forgetting). Наконец, данные, собранные в процессе онлайн-обучения, часто коррелируют между собой, а многие оптимизационные алгоритмы предполагают, что данные независимы.
На практике опыт сохраняется в буфере данных, а во время обучения берутся случайные мини-батчи для обновления параметров нейросети.
Подытожим и отметим, что воспроизведение опыта выполняет три важные задачи:
- эффективное использование прошлого опыта: сохраняет информацию из предыдущих взаимодействий, обеспечивая обучение на более разнообразном наборе данных.
- предотвращение катастрофического забывания: помогает избежать стирания старого опыта, который может быть полезным для обобщения.
- снижение корреляции данных: делает данные более независимыми за счет случайного выбора мини-батчей (mini-batch).
Fixed Q-target
Для расчета потерь в уравнении (2) нам необходимо сначала определить целевое значение \( y \). На самом деле точное значение \( y \) нам неизвестно — мы можем лишь оценить его с помощью уравнения Беллмана. Применение простой формулы (3) вызовет колебания в процессе обучения, поскольку мы используем одни и те же или очень схожие веса для расчета как целевого значения, так и функции, которую мы стремимся оптимизировать. Это приводит к тому, что оптимизатор старается сблизить значение Q-network с целевым значением. Оно, в свою очередь, постоянно изменяется, как бы «убегает» от оптимизатора (см. Рис. 2).
Для решения проблемы в статье глубокого Q-обучения предложили использовать отдельную нейросеть с целью расчета целевого значения \( y \) — target network. Веса такой нейросети не обновляются на каждом шаге. Вместо этого они копируются из основной Q-network в target network каждые \( C \) шагов.
Двойное глубокое Q-обучение
Для расчета целевого значения в уравнении (3) используется операция \( \max \), которая позволяет выбрать действие с максимальным значением Q. Однако точность Q-значений напрямую зависит от предыдущих действий и исследованных состояний. В начале обучения Q-значения далеки от реальности, что может привести к принятию неэффективных решений и усложнить обучение. Этот эффект известен как переоценка Q-значений (Q-value overestimation).
Для решения проблемы в глубоком Q-обучении применяют двойное Q-обучение: Q-network используют для выбора действий, а target network — для оценки Q-значений. Алгоритм выглядит следующим образом:
- Определение оптимального действия с помощью Q-network:
\( a’ = \arg\underset{a}{\max}\ Q(s_{t+1}, a; \theta) \)
- Расчет целевого значения с использованием target network:
\( y = R_{t+1} + \gamma \cdot \hat Q(s_{t+1}, a’; \theta^{-}) \)
где \( \theta^{-} \) — это фиксированные веса Q-target; минус указывает на то, что это старые веса Q-network с шага \( t-C \) шага.
Обратите внимание: для расчета целевых значений мы используем фиксированные веса Q-функции. Если говорить более практичным языком — \( y_i \) считается внутри декоратора with torch.no_grad()
, чтобы не считать градиенты через \( y_i \).
Алгоритм глубокого Q-обучения
Наконец, давайте рассмотрим сам алгоритм глубокого Q-обучения:
За исключением \( \phi \), весь алгоритм должен быть понятен, если вы познакомились с трюками для стабилизации DQN. Чтобы разобраться в \( \phi \), вспомним, что DQN был разработан для игр Atari, где наблюдения — это последовательность кадров, а состояние \( s \) представлено четырьмя кадрами. Почему четырьмя? Взгляните на рисунок ниже и попробуйте определить, в каком направлении движется черный квадрат.
Вероятно, по одному кадру сделать это трудно, но с двумя, а еще лучше — с четырьмя направление становится очевидным. А \( \phi \) — это предобработчик, который масштабирует и обрезает изображения, создавая на выходе тензор размером 84x84x4. Архитектура Q-сети включает сверточные слои, которые обрабатывают такие изображения напрямую.
Заключение
Поздравляем, теперь вы знаете, как работает глубокое Q-обучение! 😊
Чтобы закрепить полученные знания, предлагаем самостоятельно реализовать алгоритм и применить его к одной из игр отсюда. Не забывайте делиться своими успехами и трудностями в комментариях.
А если вы захотите просто поиграться — вы сможете воспользоваться одной из готовых реализаций: Stable Baselines 3 или ClearnRL.