Перейти к содержимому
ПереводыOpenAI и DeepLearning.AI

Spinning Up: алгоритмы TRPO, DDPG, TD3 и SAC

Перевод описаний четырёх алгоритмов из документации Spinning Up: TRPO с ограничением на KL и сопряжёнными градиентами, DDPG и TD3 для непрерывных действий, SAC с регуляризацией энтропией — формулы, псевдокод, гиперпараметры.

(Раньше: основы VPG)

TRPOTRPO (оптимизация политики в доверительной области)EN trust region policy optimization (TRPO)Schulman и др., 2015 — шаг политики с ограничением на KL к старой политике; предшественник PPO. обновляет политику, делая самый большой возможный шаг улучшения качества и при этом соблюдая особое ограничение на то, насколько близкими должны быть новая и старая политики. Ограничение выражено через KL-дивергенцию — меру (чем-то похожую на расстояние, но не совсем им являющуюся) различия между распределениями вероятностей.

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

  • TRPO — алгоритм с обучением по текущей политике (on-policy).
  • TRPO можно применять в средах как с дискретным, так и с непрерывным пространством действий.
  • Реализация TRPO в Spinning Up поддерживает распараллеливание через MPI.

Пусть πθ\pi_{\theta} — политика с параметрами θ\theta. Теоретическое обновление TRPO таково:

θk+1=arg⁡max⁡θ  L(θk,θ)s.t.  DˉKL(θ∣∣θk)≤δ\begin{aligned} \theta_{k+1} = \arg \max_{\theta} \; & {\mathcal L}(\theta_k, \theta) \\ \text{s.t.} \; & \bar{D}_{KL}(\theta || \theta_k) \leq \delta \end{aligned}

где L(θk,θ){\mathcal L}(\theta_k, \theta) — суррогатное преимущество, мера того, насколько политика πθ\pi_{\theta} лучше старой политики πθk\pi_{\theta_k}, посчитанная по данным старой политики:

L(θk,θ)=Es,a∼πθk[πθ(a∣s)πθk(a∣s)Aπθk(s,a)],{\mathcal L}(\theta_k, \theta) = \underset{s,a \sim \pi_{\theta_k}}{\mathrm{E}}\left[ \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)} A^{\pi_{\theta_k}}(s,a) \right],

а DˉKL(θ∣∣θk)\bar{D}_{KL}(\theta || \theta_k) — средняя KL-дивергенция между политиками по состояниям, которые посещала старая политика:

DˉKL(θ∣∣θk)=Es∼πθk[DKL(πθ(⋅∣s)∣∣πθk(⋅∣s))].\bar{D}_{KL}(\theta || \theta_k) = \underset{s \sim \pi_{\theta_k}}{\mathrm{E}}\left[ D_{KL}\left(\pi_{\theta}(\cdot|s) || \pi_{\theta_k} (\cdot|s) \right) \right].

Словами: «s.t.» (subject to) — «при условии». Ищем параметры, при которых суррогатное преимущество максимально, но средняя KL-дивергенция между новой и старой политикой не больше δ\delta (например, 0,01). Отношение πθ/πθk\pi_{\theta}/\pi_{\theta_k} — поправка по значимости (importance samplingвыборка по значимости (importance sampling)EN importance samplingПеревзвешивание сэмплов старой политики отношением π_new / π_old — основа PPO.): данные собраны старой политикой, а оцениваем новую.

С теоретическим обновлением TRPO работать не очень удобно, поэтому TRPO делает несколько приближений, чтобы быстро получить ответ. Разложим цель и ограничение в ряд Тейлора до главных членов вокруг θk\theta_k:

L(θk,θ)≈gT(θ−θk)DˉKL(θ∣∣θk)≈12(θ−θk)TH(θ−θk)\begin{aligned} {\mathcal L}(\theta_k, \theta) &\approx g^T (\theta - \theta_k) \\ \bar{D}_{KL}(\theta || \theta_k) & \approx \frac{1}{2} (\theta - \theta_k)^T H (\theta - \theta_k) \end{aligned}

и получим приближённую задачу оптимизации

θk+1=arg⁡max⁡θ  gT(θ−θk)s.t.  12(θ−θk)TH(θ−θk)≤δ.\begin{aligned} \theta_{k+1} = \arg \max_{\theta} \; & g^T (\theta - \theta_k) \\ \text{s.t.} \; & \frac{1}{2} (\theta - \theta_k)^T H (\theta - \theta_k) \leq \delta. \end{aligned}

Словами: цель приближаем линейной функцией (наклон gg), а KL — квадратичной (матрица HH — гессиан KL, она же информационная матрица Фишера). Линейная цель на «эллипсоиде» допустимых шагов — задача, которая решается формулой.

Эту приближённую задачу можно решить аналитически методами двойственности Лагранжа 1, и решение будет таким:

θk+1=θk+2δgTH−1gH−1g.\theta_{k+1} = \theta_k + \sqrt{\frac{2 \delta}{g^T H^{-1} g}} H^{-1} g.

Если бы мы на этом остановились и просто использовали этот результат, алгоритм в точности вычислял бы натуральный градиент политики (Natural Policy Gradient). Проблема в том, что из-за ошибок приближения рядом Тейлора такой шаг может не удовлетворять ограничению на KL или на самом деле не улучшать суррогатное преимущество. TRPO добавляет к этому правилу обновления поправку — линейный поиск с возвратом (backtracking line search):

θk+1=θk+αj2δgTH−1gH−1g,\theta_{k+1} = \theta_k + \alpha^j \sqrt{\frac{2 \delta}{g^T H^{-1} g}} H^{-1} g,

где α∈(0,1)\alpha \in (0,1) — коэффициент возврата, а jj — наименьшее неотрицательное целое число, при котором πθk+1\pi_{\theta_{k+1}} удовлетворяет ограничению на KL и даёт положительное суррогатное преимущество.

Словами: сначала пробуем полный шаг (j=0j = 0). Если он нарушает ограничение или ухудшает цель — укорачиваем шаг в α\alpha раз (например, до 80 %), потом ещё раз, пока не получится.

Наконец: вычислять и хранить обратную матрицу H−1H^{-1} мучительно дорого, когда у нейросетевой политики тысячи или миллионы параметров. TRPO обходит эту проблему с помощью алгоритма сопряжённых градиентов: он решает систему Hx=gHx = g относительно x=H−1gx = H^{-1} g, и для этого нужна только функция, вычисляющая произведение матрицы на вектор HxHx, а не вся матрица HH целиком. Сделать это не так уж трудно: заводим символьную операцию, вычисляющую

Hx=∇θ((∇θDˉKL(θ∣∣θk))Tx),Hx = \nabla_{\theta} \left( \left(\nabla_{\theta} \bar{D}_{KL}(\theta || \theta_k)\right)^T x \right),

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

Словами: сначала берём градиент KL (вектор), скалярно умножаем его на xx (получаем число) и ещё раз берём градиент — это произведение гессиана на вектор за два прохода автодифференцирования. Для сети с миллионом параметров матрица HH заняла бы 101210^{12} чисел, а такой приём требует памяти порядка одного вектора.

TRPO обучает стохастическую политику on-policy. Это значит, что он исследует среду, выбирая действия по самой свежей версии своей стохастической политики. Насколько случаен выбор действий, зависит и от начальных условий, и от процедуры обучения. По ходу обучения политика обычно становится всё менее случайной, потому что правило обновления подталкивает её использовать награды, которые она уже нашла. Из-за этого политика может застрять в локальном оптимуме.

Алгоритм 1. Trust Region Policy Optimization

  1. Вход: начальные параметры политики θ0\theta_0, начальные параметры функции ценности ϕ0\phi_0.
  2. Гиперпараметры: предел KL-дивергенции δ\delta, коэффициент возврата α\alpha, максимальное число шагов возврата KK.
  3. Для k=0,1,2,…k = 0, 1, 2, \dots:
    1. Собрать набор траекторий Dk={τi}\mathcal{D}_k = \{\tau_i\}, запуская в среде политику πk=π(θk)\pi_k = \pi(\theta_k).
    2. Посчитать reward-to-go R^t\hat{R}_t.
    3. Посчитать оценки преимущества A^t\hat{A}_t (любым методом оценки преимущества) на основе текущей функции ценности VϕkV_{\phi_k}.
    4. Оценить градиент политики: g^k=1∣Dk∣∑τ∈Dk∑t=0T∇θlog⁡πθ(at∣st)∣θkA^t.\hat{g}_k = \frac{1}{|\mathcal{D}_k|} \sum_{\tau \in \mathcal{D}_k} \sum_{t=0}^T \left. \nabla_{\theta} \log\pi_{\theta}(a_t|s_t)\right|_{\theta_k} \hat{A}_t.
    5. Алгоритмом сопряжённых градиентов вычислить x^k≈H^k−1g^k,\hat{x}_k \approx \hat{H}_k^{-1} \hat{g}_k, где H^k\hat{H}_k — гессиан выборочной средней KL-дивергенции.
    6. Обновить политику линейным поиском с возвратом: θk+1=θk+αj2δx^kTH^kx^kx^k,\theta_{k+1} = \theta_k + \alpha^j \sqrt{ \frac{2\delta}{\hat{x}_k^T \hat{H}_k \hat{x}_k}} \hat{x}_k, где j∈{0,1,2,…K}j \in \{0, 1, 2, \dots K\} — наименьшее значение, которое улучшает выборочную функцию потерь и удовлетворяет выборочному ограничению на KL-дивергенцию.
    7. Подогнать функцию ценности регрессией по среднеквадратичной ошибке: ϕk+1=arg⁡min⁡ϕ1∣Dk∣T∑τ∈Dk∑t=0T(Vϕ(st)−R^t)2,\phi_{k+1} = \arg \min_{\phi} \frac{1}{|\mathcal{D}_k| T} \sum_{\tau \in \mathcal{D}_k} \sum_{t=0}^T\left( V_{\phi} (s_t) - \hat{R}_t \right)^2, обычно каким-нибудь алгоритмом градиентного спуска.
spinup.trpo_tf1(env_fn, actor_critic=<mlp_actor_critic>, ac_kwargs={}, seed=0,
steps_per_epoch=4000, epochs=50, gamma=0.99, delta=0.01, vf_lr=0.001,
train_v_iters=80, damping_coeff=0.1, cg_iters=10, backtrack_iters=10,
backtrack_coeff=0.8, lam=0.97, max_ep_len=1000, logger_kwargs={},
save_freq=10, algo='trpo')

Trust Region Policy Optimization (с поддержкой натурального градиента политики). Параметры env_fn, ac_kwargs, seed, steps_per_epoch, epochs, gamma, vf_lr, train_v_iters, lam, max_ep_len, logger_kwargs, save_freq значат то же, что у VPG. Особые параметры TRPO:

ПараметрПо умолчаниюСмысл
delta0.01Предел KL-дивергенции для обновления TRPO / NPG. (Для устойчивости должен быть маленьким: значения вроде 0,01, 0,05.)
damping_coeff0.1Костыль для численной устойчивости, должен быть небольшим. Меняет вычисление произведения гессиана на вектор: Hv→(αI+H)vHv \rightarrow (\alpha I + H)v, где α\alpha — коэффициент затухания. Этот гиперпараметр, скорее всего, лучше не трогать
cg_iters10Число итераций метода сопряжённых градиентов. Если увеличить, приближение к H−1gH^{-1} g станет точнее и качество, возможно, немного вырастет, но ценой замедления. Тоже, скорее всего, лучше не трогать
backtrack_iters10Максимальное число шагов в линейном поиске с возвратом. Поиск обычно не возвращается, а если и возвращается, то обычно на один шаг, поэтому этот гиперпараметр редко важен
backtrack_coeff0.8Насколько далеко шагать назад при линейном поиске. (Всегда между 0 и 1, обычно больше 0,5.)
algo'trpo'Либо 'trpo', либо 'npg': код поддерживает оба, потому что они почти одинаковы

Граф вычислений, который сохраняет логгер, содержит: x — placeholder TensorFlow для входного состояния; pi — сэмплирует действие агента при состояниях из x; v — оценка ценности для состояний из x. К модели можно обратиться через инструмент test_policy.py или загрузить граф функцией restore_tf_graph.

Schulman 2015 включена, потому что это исходная статья с описанием TRPO. Schulman 2016 включена, потому что наша реализация TRPO использует Generalized Advantage Estimation для вычисления градиента политики. Kakade and Langford 2002 включена, потому что в ней есть теоретические результаты, которые мотивируют теоретические основы TRPO и глубоко с ними связаны.


(Раньше: Введение в RL, часть 1: оптимальная Q-функция и оптимальное действие)

Deep Deterministic Policy Gradient (DDPG) — алгоритм, который одновременно учит Q-функцию и политику. Q-функцию он учит по off-policy данным с помощью уравнения Беллмана, а политику — с помощью Q-функции.

Этот подход тесно связан с Q-обучениемQ-learningEN Q-learningQ(s,a) ← Q(s,a) + α[r + γ max_a′ Q(s′,a′) − Q(s,a)]. Off-policy: учит Q* при любом поведении. и мотивирован так же: если известна оптимальная функция ценности действия Q∗(s,a)Q^*(s,a), то в любом состоянии оптимальное действие a∗(s)a^*(s) можно найти, решив

a∗(s)=arg⁡max⁡aQ∗(s,a).a^*(s) = \arg \max_a Q^*(s,a).

DDPG чередует обучение аппроксиматора Q∗(s,a)Q^*(s,a) с обучением аппроксиматора a∗(s)a^*(s) и делает это способом, специально приспособленным для сред с непрерывным пространством действий. Но что значит, что DDPG приспособлен именно для непрерывных действий? Это связано с тем, как мы вычисляем максимум по действиям в max⁡aQ∗(s,a)\max_a Q^*(s,a).

Когда дискретных действий конечное число, максимум не проблема: можно просто посчитать Q-значения для каждого действия отдельно и напрямую их сравнить. (Это заодно сразу даёт действие, на котором Q-значение максимально.) Но когда пространство действий непрерывно, перебрать его целиком нельзя, а решать задачу оптимизации совсем не просто. Обычный алгоритм оптимизации сделал бы вычисление max⁡aQ∗(s,a)\max_a Q^*(s,a) мучительно дорогой подпрограммой. А поскольку её пришлось бы запускать каждый раз, когда агент хочет сделать шаг в среде, это неприемлемо.

Раз пространство действий непрерывно, предполагается, что функция Q∗(s,a)Q^*(s,a) дифференцируема по аргументу-действию. Это позволяет построить эффективное правило обучения политики μ(s)\mu(s) на основе градиента, которое пользуется этим фактом. Тогда вместо дорогой подпрограммы оптимизации при каждом вычислении max⁡aQ(s,a)\max_a Q(s,a) можно приблизить его: max⁡aQ(s,a)≈Q(s,μ(s))\max_a Q(s,a) \approx Q(s,\mu(s)). Подробности — в разделе «Ключевые формулы».

  • DDPG — алгоритм с обучением вне текущей политикиoff-policy (обучение на данных другой политики)EN off-policyПолитика, которую учим, отличается от той, что собирала данные. Пример — Q-learning; в PPO и GRPO — поправка π/π_old. (off-policy).
  • DDPG можно применять только в средах с непрерывным пространством действий.
  • DDPG можно считать глубоким Q-обучением для непрерывных пространств действий.
  • Реализация DDPG в Spinning Up не поддерживает распараллеливание.

Здесь мы объясним математику двух частей DDPG: обучения Q-функции и обучения политики.

Сначала напомним уравнение Беллмана для оптимальной функции ценности действия Q∗(s,a)Q^*(s,a). Оно имеет вид

Q∗(s,a)=Es′∼P[r(s,a)+γmax⁡a′Q∗(s′,a′)]Q^*(s,a) = \underset{s' \sim P}{{\mathrm E}}\left[r(s,a) + \gamma \max_{a'} Q^*(s', a')\right]

где s′∼Ps' \sim P — краткая запись того, что следующее состояние s′s' среда выбирает из распределения P(⋅∣s,a)P(\cdot| s,a).

Это уравнение Беллмана — отправная точка для обучения аппроксиматора Q∗(s,a)Q^*(s,a). Пусть аппроксиматор — нейросеть Qϕ(s,a)Q_{\phi}(s,a) с параметрами ϕ\phi, и мы собрали набор D\mathcal{D} переходов (s,a,r,s′,d)(s,a,r,s',d) (где dd показывает, терминально ли состояние s′s'). Можно построить функцию среднеквадратичной ошибки Беллмана (mean-squared Bellman error, MSBE), которая грубо показывает, насколько QϕQ_{\phi} близка к тому, чтобы удовлетворять уравнению Беллмана:

L(ϕ,D)=E(s,a,r,s′,d)∼D[(Qϕ(s,a)−(r+γ(1−d)max⁡a′Qϕ(s′,a′)))2]L(\phi, {\mathcal D}) = \underset{(s,a,r,s',d) \sim {\mathcal D}}{{\mathrm E}}\left[ \Bigg( Q_{\phi}(s,a) - \left(r + \gamma (1 - d) \max_{a'} Q_{\phi}(s',a') \right) \Bigg)^2 \right]

Здесь, вычисляя (1−d)(1-d), мы пользуемся соглашением Python, по которому True равно 1, а False — 0. Поэтому когда d==True — то есть когда s′s' терминальное состояние, — Q-функция должна показывать, что после текущего состояния агент не получит дополнительных наград. (Такой выбор обозначений соответствует тому, что мы потом реализуем в коде.)

Алгоритмы Q-обучения с аппроксиматорами функций, такие как DQNDQN (глубокая Q-сеть)EN deep Q-network (DQN)Mnih и др., 2015 — Q-learning с нейросетью, буфером воспроизведения и целевой сетью; играл в Atari по пикселям. (и все его варианты) и DDPG, в основном построены на минимизации этой функции потерь MSBE. Все они используют два главных приёма, которые стоит описать, и ещё одну особую деталь DDPG.

Приём первый: буферы воспроизведения. Все стандартные алгоритмы обучения глубокой нейросети, приближающей Q∗(s,a)Q^*(s,a), используют буфер воспроизведения опытабуфер воспроизведения (replay buffer)EN experience replay bufferХранилище прошлых переходов (s, a, r, s′), из которого сэмплируют случайные мини-батчи. (experience replay buffer). Это и есть множество D\mathcal{D} прошлого опыта. Чтобы алгоритм вёл себя устойчиво, буфер должен быть достаточно большим, чтобы вмещать широкий спектр опыта, но не всегда хорошо хранить всё подряд. Если использовать только самые свежие данные, модель на них переобучится и всё сломается; если использовать слишком много опыта, обучение может замедлиться. Чтобы найти баланс, может понадобиться настройка.

Приём второй: целевые сети. Алгоритмы Q-обучения используют целевые сетицелевая сеть (target network)EN target networkЗамороженная копия Q-сети для вычисления цели r + γ max Q; её веса обновляют редко. (target networks). Выражение

r+γ(1−d)max⁡a′Qϕ(s′,a′)r + \gamma (1 - d) \max_{a'} Q_{\phi}(s',a')

называется целью (target), потому что, минимизируя потери MSBE, мы пытаемся сделать Q-функцию похожей на эту цель. Беда в том, что цель зависит от тех же параметров ϕ\phi, которые мы обучаем. Из-за этого минимизация MSBE неустойчива. Решение — использовать набор параметров, близкий к ϕ\phi, но с запаздыванием: вторую сеть, называемую целевой, которая отстаёт от первой. Параметры целевой сети обозначают ϕtarg\phi_{\text{targ}}.

В алгоритмах на основе DQN целевую сеть просто копируют из основной раз в фиксированное число шагов. В алгоритмах в стиле DDPG целевая сеть обновляется при каждом обновлении основной сети усреднением Поляка (polyak averaging):

ϕtarg←ρϕtarg+(1−ρ)ϕ,\phi_{\text{targ}} \leftarrow \rho \phi_{\text{targ}} + (1 - \rho) \phi,

где ρ\rho — гиперпараметр от 0 до 1 (обычно близкий к 1). (В нашем коде этот гиперпараметр называется polyak.)

Словами: при ρ=0,995\rho = 0{,}995 целевая сеть на каждом шаге сдвигается к основной всего на 0,5 % — это экспоненциальное скользящее среднееэкспоненциальное скользящее среднее (EMA)EN exponential moving average (EMA)m ← βm + (1 − β)x. Помнит примерно последние 1/(1 − β) значений; при β = 0.9 — около 10. весов, которое отстаёт примерно на 1/(1−ρ)=2001/(1-\rho) = 200 обновлений.

Деталь DDPG: вычисление максимума по действиям в цели. Как говорилось выше, вычислить максимум по действиям в цели трудно, когда пространство действий непрерывно. DDPG справляется с этим, используя целевую сеть политики (target policy network), которая вычисляет действие, приблизительно максимизирующее QϕtargQ_{\phi_{\text{targ}}}. Целевая сеть политики получается так же, как целевая Q-функция: усреднением Поляка параметров политики по ходу обучения.

Собирая всё вместе, Q-обучение в DDPG выполняется минимизацией следующей функции потерь MSBE стохастическим градиентным спуском:

L(ϕ,D)=E(s,a,r,s′,d)∼D[(Qϕ(s,a)−(r+γ(1−d)Qϕtarg(s′,μθtarg(s′))))2],L(\phi, {\mathcal D}) = \underset{(s,a,r,s',d) \sim {\mathcal D}}{{\mathrm E}}\left[ \Bigg( Q_{\phi}(s,a) - \left(r + \gamma (1 - d) Q_{\phi_{\text{targ}}}(s', \mu_{\theta_{\text{targ}}}(s')) \right) \Bigg)^2 \right],

где μθtarg\mu_{\theta_{\text{targ}}} — целевая политика.

Обучение политики в DDPG довольно простое. Мы хотим выучить детерминированную политику μθ(s)\mu_{\theta}(s), которая выдаёт действие, максимизирующее Qϕ(s,a)Q_{\phi}(s,a). Раз пространство действий непрерывно и мы предполагаем, что Q-функция дифференцируема по действию, можно просто делать градиентный подъём (только по параметрам политики), чтобы решить

max⁡θEs∼D[Qϕ(s,μθ(s))].\max_{\theta} \underset{s \sim {\mathcal D}}{{\mathrm E}}\left[ Q_{\phi}(s, \mu_{\theta}(s)) \right].

Обратите внимание: параметры Q-функции здесь считаются константами.

Словами: критик QϕQ_{\phi} подсказывает, в какую сторону сдвинуть действие, чтобы оценка выросла (∇aQ\nabla_a Q), а цепное правило переносит эту подсказку на параметры политики: ∇θQ(s,μθ(s))=∇aQ(s,a)∣a=μθ(s)∇θμθ(s)\nabla_{\theta} Q(s, \mu_{\theta}(s)) = \nabla_a Q(s,a)\big|_{a=\mu_{\theta}(s)} \nabla_{\theta} \mu_{\theta}(s).

DDPG обучает детерминированную политику off-policy. Поскольку политика детерминированная, при исследовании по текущей политике агент в начале, скорее всего, не попробовал бы достаточно разнообразных действий, чтобы найти полезные обучающие сигналы. Чтобы политики DDPG лучше исследовали среду, мы во время обучения добавляем к их действиям шум. Авторы исходной статьи о DDPG рекомендовали коррелированный во времени шум Орнштейна — Уленбека (OU noise), но более свежие результаты говорят, что некоррелированный гауссов шум с нулевым средним работает ничуть не хуже. Поскольку последний проще, он предпочтительнее. Чтобы получать более качественные обучающие данные, масштаб шума можно уменьшать по ходу обучения. (В нашей реализации мы этого не делаем и держим масштаб шума постоянным.)

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

Алгоритм 1. Deep Deterministic Policy Gradient

  1. Вход: начальные параметры политики θ\theta, параметры Q-функции ϕ\phi, пустой буфер воспроизведения D\mathcal{D}.
  2. Приравнять целевые параметры к основным: θtarg←θ\theta_{\text{targ}} \leftarrow \theta, ϕtarg←ϕ\phi_{\text{targ}} \leftarrow \phi.
  3. Повторять:
    1. Наблюдать состояние ss и выбрать действие a=clip(μθ(s)+ϵ,aLow,aHigh)a = \text{clip}(\mu_{\theta}(s) + \epsilon, a_{Low}, a_{High}), где ϵ∼N\epsilon \sim \mathcal{N}.
    2. Выполнить aa в среде.
    3. Наблюдать следующее состояние s′s', награду rr и сигнал завершения dd, показывающий, терминально ли s′s'.
    4. Сохранить (s,a,r,s′,d)(s,a,r,s',d) в буфер воспроизведения D\mathcal{D}.
    5. Если s′s' терминально, сбросить среду.
    6. Если пора обновляться, то столько раз, сколько нужно обновлений:
      1. Случайно выбрать из D\mathcal{D} батч переходов B={(s,a,r,s′,d)}B = \{ (s,a,r,s',d) \}.
      2. Вычислить цели y(r,s′,d)=r+γ(1−d)Qϕtarg(s′,μθtarg(s′))y(r,s',d) = r + \gamma (1-d) Q_{\phi_{\text{targ}}}(s', \mu_{\theta_{\text{targ}}}(s'))
      3. Обновить Q-функцию одним шагом градиентного спуска по ∇ϕ1∣B∣∑(s,a,r,s′,d)∈B(Qϕ(s,a)−y(r,s′,d))2\nabla_{\phi} \frac{1}{|B|}\sum_{(s,a,r,s',d) \in B} \left( Q_{\phi}(s,a) - y(r,s',d) \right)^2
      4. Обновить политику одним шагом градиентного подъёма по ∇θ1∣B∣∑s∈BQϕ(s,μθ(s))\nabla_{\theta} \frac{1}{|B|}\sum_{s \in B}Q_{\phi}(s, \mu_{\theta}(s))
      5. Обновить целевые сети: ϕtarg←ρϕtarg+(1−ρ)ϕθtarg←ρθtarg+(1−ρ)θ\begin{aligned} \phi_{\text{targ}} &\leftarrow \rho \phi_{\text{targ}} + (1-\rho) \phi \\ \theta_{\text{targ}} &\leftarrow \rho \theta_{\text{targ}} + (1-\rho) \theta \end{aligned}
  4. До сходимости.

У DDPG есть реализации на PyTorch (spinup.ddpg_pytorch) и TensorFlow (spinup.ddpg_tf1) с почти одинаковыми вызовами. Параметры общие для DDPG, TD3 и SAC собраны в таблицу после SAC; особый параметр DDPG:

ПараметрПо умолчаниюСмысл
act_noise0.1Стандартное отклонение гауссова шума для исследования, добавляемого к политике во время обучения. (Во время теста шум не добавляется.)

Сохранённую модель PyTorch можно загрузить командой ac = torch.load('path/to/model.pt') — получится объект актор-критика (ac) со свойствами, описанными в docstring функции ddpg_pytorch. Действия из неё: actions = ac.act(torch.as_tensor(obs, dtype=torch.float32)).

Граф TensorFlow, который сохраняет логгер, содержит: x — placeholder для входного состояния; a — placeholder для входного действия; pi — детерминированно вычисляет действие агента при состояниях из x; q — оценка ценности действия для состояний из x и действий из a.

Silver 2014 включена, потому что в ней заложена теория детерминированных градиентов политики (DPG). Lillicrap 2016 включена, потому что в ней теоретически обоснованный алгоритм DPG адаптирован к глубокому RL — так получился DDPG.


(Раньше: основы DDPG)

DDPG иногда показывает отличное качество, но часто капризен к гиперпараметрам и прочим настройкам. Типичный сбой DDPG: выученная Q-функция начинает резко завышать Q-значения, и тогда ломается политика, потому что она эксплуатирует ошибки Q-функции. Twin Delayed DDPG (TD3) — алгоритм, который решает эту проблему тремя ключевыми приёмами:

Приём первый: обрезанное двойное Q-обучение (clipped double-Q learning). TD3 учит две Q-функции вместо одной (отсюда «twin», «близнецы») и для целей в функциях потерь ошибки Беллмана берёт меньшее из двух Q-значений.

Приём второй: «отложенные» обновления политики. TD3 обновляет политику (и целевые сети) реже, чем Q-функцию. Статья рекомендует одно обновление политики на каждые два обновления Q-функции.

Приём третий: сглаживание целевой политики (target policy smoothing). TD3 добавляет шум к целевому действию, чтобы политике было труднее эксплуатировать ошибки Q-функции: шум сглаживает Q вдоль изменений действия.

Вместе эти три приёма дают заметно лучшее качество, чем базовый DDPG.

  • TD3 — алгоритм с обучением вне текущей политики (off-policy).
  • TD3 можно применять только в средах с непрерывным пространством действий.
  • Реализация TD3 в Spinning Up не поддерживает распараллеливание.

TD3 одновременно учит две Q-функции, Qϕ1Q_{\phi_1} и Qϕ2Q_{\phi_2}, минимизацией среднеквадратичной ошибки Беллмана — почти так же, как DDPG учит свою единственную Q-функцию. Чтобы показать, как именно TD3 это делает и чем он отличается от обычного DDPG, пойдём от самой внутренней части функции потерь наружу.

Первое: сглаживание целевой политики. Действия, по которым строится цель Q-обучения, берутся из целевой политики μθtarg\mu_{\theta_{\text{targ}}}, но к каждой координате действия добавляется обрезанный шум. После добавления обрезанного шума целевое действие обрезается так, чтобы лежать в допустимом диапазоне (все допустимые действия aa удовлетворяют aLow≤a≤aHigha_{Low} \leq a \leq a_{High}). Итак, целевые действия:

a′(s′)=clip(μθtarg(s′)+clip(ϵ,−c,c),aLow,aHigh),          ϵ∼N(0,σ)a'(s') = \text{clip}\left(\mu_{\theta_{\text{targ}}}(s') + \text{clip}(\epsilon,-c,c), a_{Low}, a_{High}\right), \;\;\;\;\; \epsilon \sim \mathcal{N}(0, \sigma)

Сглаживание целевой политики по сути служит регуляризатором алгоритма. Оно устраняет особый сбой, который случается в DDPG: если у аппроксиматора Q-функции появляется ложный острый пик на каких-то действиях, политика быстро начинает его эксплуатировать и ведёт себя хрупко или неправильно. Этого можно избежать, сгладив Q-функцию по похожим действиям, — для этого и придумано сглаживание целевой политики.

Далее: обрезанное двойное Q-обучение. Обе Q-функции используют одну общую цель, вычисленную по той из двух Q-функций, которая даёт меньшее значение цели:

y(r,s′,d)=r+γ(1−d)min⁡i=1,2Qϕi,targ(s′,a′(s′)),y(r,s',d) = r + \gamma (1 - d) \min_{i=1,2} Q_{\phi_{i, \text{targ}}}(s', a'(s')),

и обе учатся регрессией к этой цели:

L(ϕ1,D)=E(s,a,r,s′,d)∼D[(Qϕ1(s,a)−y(r,s′,d))2],L(\phi_1, {\mathcal D}) = \underset{(s,a,r,s',d) \sim {\mathcal D}}{\mathrm{E}}\left[ \Bigg( Q_{\phi_1}(s,a) - y(r,s',d) \Bigg)^2 \right], L(ϕ2,D)=E(s,a,r,s′,d)∼D[(Qϕ2(s,a)−y(r,s′,d))2].L(\phi_2, {\mathcal D}) = \underset{(s,a,r,s',d) \sim {\mathcal D}}{\mathrm{E}}\left[ \Bigg( Q_{\phi_2}(s,a) - y(r,s',d) \Bigg)^2 \right].

Если брать для цели меньшее Q-значение и регрессировать к нему, это помогает не допустить завышения Q-функции.

Словами: у каждой из двух сетей свои случайные ошибки. Если одна завысила оценку, а другая нет, минимум возьмёт более скромную — систематическое завышение «через максимум» сменяется лёгким занижением, которое для обучения безопаснее.

Наконец, политика учится просто максимизацией Qϕ1Q_{\phi_1}:

max⁡θEs∼D[Qϕ1(s,μθ(s))],\max_{\theta} \underset{s \sim {\mathcal D}}{{\mathrm E}}\left[ Q_{\phi_1}(s, \mu_{\theta}(s)) \right],

что почти не отличается от DDPG. Но в TD3 политика обновляется реже, чем Q-функции. Это помогает гасить нестабильность, которая обычно возникает в DDPG из-за того, что обновление политики меняет цель.

TD3 обучает детерминированную политику off-policy. Поскольку политика детерминированная, при исследовании по текущей политике агент в начале, скорее всего, не попробовал бы достаточно разнообразных действий, чтобы найти полезные обучающие сигналы. Чтобы политики TD3 лучше исследовали среду, мы во время обучения добавляем к их действиям шум, обычно некоррелированный гауссов шум с нулевым средним. Чтобы получать более качественные обучающие данные, масштаб шума можно уменьшать по ходу обучения. (В нашей реализации мы этого не делаем и держим масштаб шума постоянным.)

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

Алгоритм 1. Twin Delayed DDPG

  1. Вход: начальные параметры политики θ\theta, параметры Q-функций ϕ1\phi_1, ϕ2\phi_2, пустой буфер воспроизведения D\mathcal{D}.
  2. Приравнять целевые параметры к основным: θtarg←θ\theta_{\text{targ}} \leftarrow \theta, ϕtarg,1←ϕ1\phi_{\text{targ},1} \leftarrow \phi_1, ϕtarg,2←ϕ2\phi_{\text{targ},2} \leftarrow \phi_2.
  3. Повторять:
    1. Наблюдать состояние ss и выбрать действие a=clip(μθ(s)+ϵ,aLow,aHigh)a = \text{clip}(\mu_{\theta}(s) + \epsilon, a_{Low}, a_{High}), где ϵ∼N\epsilon \sim \mathcal{N}.
    2. Выполнить aa в среде.
    3. Наблюдать следующее состояние s′s', награду rr и сигнал завершения dd, показывающий, терминально ли s′s'.
    4. Сохранить (s,a,r,s′,d)(s,a,r,s',d) в буфер воспроизведения D\mathcal{D}.
    5. Если s′s' терминально, сбросить среду.
    6. Если пора обновляться, то для jj от 0 до нужного числа обновлений:
      1. Случайно выбрать из D\mathcal{D} батч переходов B={(s,a,r,s′,d)}B = \{ (s,a,r,s',d) \}.
      2. Вычислить целевые действия a′(s′)=clip(μθtarg(s′)+clip(ϵ,−c,c),aLow,aHigh),          ϵ∼N(0,σ)a'(s') = \text{clip}\left(\mu_{\theta_{\text{targ}}}(s') + \text{clip}(\epsilon,-c,c), a_{Low}, a_{High}\right), \;\;\;\;\; \epsilon \sim \mathcal{N}(0, \sigma)
      3. Вычислить цели y(r,s′,d)=r+γ(1−d)min⁡i=1,2Qϕtarg,i(s′,a′(s′))y(r,s',d) = r + \gamma (1-d) \min_{i=1,2} Q_{\phi_{\text{targ},i}}(s', a'(s'))
      4. Обновить Q-функции одним шагом градиентного спуска по ∇ϕi1∣B∣∑(s,a,r,s′,d)∈B(Qϕi(s,a)−y(r,s′,d))2для i=1,2\nabla_{\phi_i} \frac{1}{|B|}\sum_{(s,a,r,s',d) \in B} \left( Q_{\phi_i}(s,a) - y(r,s',d) \right)^2 \qquad \text{для } i=1,2
      5. Если j mod j \bmod policy_delay =0= 0:
        • обновить политику одним шагом градиентного подъёма по ∇θ1∣B∣∑s∈BQϕ1(s,μθ(s))\nabla_{\theta} \frac{1}{|B|}\sum_{s \in B}Q_{\phi_1}(s, \mu_{\theta}(s))
        • обновить целевые сети: ϕtarg,i←ρϕtarg,i+(1−ρ)ϕiдля i=1,2θtarg←ρθtarg+(1−ρ)θ\begin{aligned} \phi_{\text{targ},i} &\leftarrow \rho \phi_{\text{targ}, i} + (1-\rho) \phi_i \qquad \text{для } i=1,2\\ \theta_{\text{targ}} &\leftarrow \rho \theta_{\text{targ}} + (1-\rho) \theta \end{aligned}
  4. До сходимости.

У TD3 есть реализации на PyTorch (spinup.td3_pytorch) и TensorFlow (spinup.td3_tf1). Общие параметры — в таблице после SAC; особые параметры TD3:

ПараметрПо умолчаниюСмысл
act_noise0.1Стандартное отклонение гауссова шума для исследования, добавляемого к политике во время обучения. (Во время теста шум не добавляется.)
target_noise0.2Стандартное отклонение сглаживающего шума, добавляемого к целевой политике (σ\sigma в формулах)
noise_clip0.5Предел для модуля сглаживающего шума целевой политики (cc в формулах)
policy_delay2Политика обновляется только один раз на каждые policy_delay обновлений Q-сетей

Сохранённая модель PyTorch загружается так же, как у DDPG. Граф TensorFlow содержит: x и a — placeholder для состояния и действия; pi — детерминированно вычисляет действие при состояниях из x; q1 — одна оценка ценности действия для x и a; q2 — другая оценка ценности действия для x и a.


(Раньше: основы TD3)

Soft Actor Critic (SAC) — алгоритм, который оптимизирует стохастическую политику off-policy; он служит мостом между стохастической оптимизацией политики и подходами в стиле DDPG. Это не прямой наследник TD3 (они опубликованы примерно одновременно), но SAC использует приём обрезанного двойного Q, а благодаря стохастичности, присущей политике SAC, в итоге получает и что-то вроде сглаживания целевой политики.

Центральная особенность SAC — регуляризация энтропией. Политика обучается максимизировать компромисс между ожидаемой отдачей и энтропией — мерой случайности политики. Это тесно связано с компромиссом между исследованием и использованием: рост энтропии ведёт к большему исследованию, что может ускорить обучение в дальнейшем. Он также может помешать политике преждевременно сойтись к плохому локальному оптимуму.

  • SAC — алгоритм с обучением вне текущей политики (off-policy).
  • Реализованная здесь версия SAC применима только в средах с непрерывным пространством действий.
  • Альтернативную версию SAC, слегка меняющую правило обновления политики, можно реализовать для дискретных пространств действий.
  • Реализация SAC в Spinning Up не поддерживает распараллеливание.

Чтобы объяснить Soft Actor Critic, сначала нужно ввести постановку RL с регуляризацией энтропией. В ней формулы для функций ценности немного другие.

Энтропияэнтропия (информационная)EN (Shannon) entropyH(p) = −Σ p log p — среднее «удивление», мера неопределённости распределения. Максимальна у равномерного распределения. — величина, которая, грубо говоря, показывает, насколько случайна случайная величина. Если монета утяжелена так, что почти всегда выпадает орлом, у неё низкая энтропия; если она честная и оба исхода выпадают с вероятностью половина, у неё высокая энтропия.

Пусть xx — случайная величина с функцией вероятности или плотностью PP. Энтропия HH величины xx вычисляется по её распределению PP так:

H(P)=Ex∼P[−log⁡P(x)].H(P) = \underset{x \sim P}{\mathrm{E}}\left[-\log P(x)\right].

Словами и числами: честная монета: H=−(0,5ln⁡0,5+0,5ln⁡0,5)=ln⁡2≈0,69H = -(0{,}5 \ln 0{,}5 + 0{,}5 \ln 0{,}5) = \ln 2 \approx 0{,}69 нат; монета с орлом в 99 % случаев: H=−(0,99ln⁡0,99+0,01ln⁡0,01)≈0,056H = -(0{,}99 \ln 0{,}99 + 0{,}01 \ln 0{,}01) \approx 0{,}056 нат.

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

π∗=arg⁡max⁡πEτ∼π[∑t=0∞γt(R(st,at,st+1)+αH(π(⋅∣st)))],\pi^* = \arg \max_{\pi} \underset{\tau \sim \pi}{\mathrm{E}}\left[ \sum_{t=0}^{\infty} \gamma^t \bigg( R(s_t, a_t, s_{t+1}) + \alpha H\left(\pi(\cdot|s_t)\right) \bigg)\right],

где α>0\alpha > 0 — коэффициент компромисса. (Примечание: здесь и далее на этой странице мы предполагаем бесконечный горизонт с дисконтированием.) Теперь можно определить немного другие функции ценности в этой постановке. VπV^{\pi} меняется так, чтобы включать бонусы за энтропию на каждом шаге:

Vπ(s)=Eτ∼π[∑t=0∞γt(R(st,at,st+1)+αH(π(⋅∣st)))∣s0=s]V^{\pi}(s) = \underset{\tau \sim \pi}{\mathrm{E}}\left[ \left. \sum_{t=0}^{\infty} \gamma^t \bigg( R(s_t, a_t, s_{t+1}) + \alpha H\left(\pi(\cdot|s_t)\right) \bigg) \right| s_0 = s\right]

QπQ^{\pi} меняется так, чтобы включать бонусы за энтропию на каждом шаге, кроме первого:

Qπ(s,a)=Eτ∼π[∑t=0∞γtR(st,at,st+1)+α∑t=1∞γtH(π(⋅∣st))∣s0=s,a0=a]Q^{\pi}(s,a) = \underset{\tau \sim \pi}{\mathrm{E}}\left[ \left. \sum_{t=0}^{\infty} \gamma^t R(s_t, a_t, s_{t+1}) + \alpha \sum_{t=1}^{\infty} \gamma^t H\left(\pi(\cdot|s_t)\right)\right| s_0 = s, a_0 = a\right]

При таких определениях VπV^{\pi} и QπQ^{\pi} связаны соотношением

Vπ(s)=Ea∼π[Qπ(s,a)]+αH(π(⋅∣s))V^{\pi}(s) = \underset{a \sim \pi}{\mathrm{E}}\left[Q^{\pi}(s,a)\right] + \alpha H\left(\pi(\cdot|s)\right)

а уравнение Беллмана для QπQ^{\pi} имеет вид

Qπ(s,a)=Es′∼Pa′∼π[R(s,a,s′)+γ(Qπ(s′,a′)+αH(π(⋅∣s′)))]=Es′∼P[R(s,a,s′)+γVπ(s′)].\begin{aligned} Q^{\pi}(s,a) &= \underset{\substack{s' \sim P \\ a' \sim \pi}}{\mathrm{E}}\left[R(s,a,s') + \gamma\left(Q^{\pi}(s',a') + \alpha H\left(\pi(\cdot|s')\right) \right)\right] \\ &= \underset{s' \sim P}{\mathrm{E}}\left[R(s,a,s') + \gamma V^{\pi}(s')\right]. \end{aligned}

SAC одновременно учит политику πθ\pi_{\theta} и две Q-функции Qϕ1,Qϕ2Q_{\phi_1}, Q_{\phi_2}. Сейчас стандартны два варианта SAC: один использует фиксированный коэффициент регуляризации энтропией α\alpha, а другой обеспечивает ограничение на энтропию, меняя α\alpha по ходу обучения. Для простоты Spinning Up использует версию с фиксированным коэффициентом, но практики обычно предпочитают вариант с ограничением на энтропию.

Обучение Q. Q-функции учатся похоже на TD3, но с несколькими ключевыми отличиями.

Сначала — что похоже?

  1. Как и в TD3, обе Q-функции учатся минимизацией MSBE, регрессией к одной общей цели.
  2. Как и в TD3, общая цель вычисляется с помощью целевых Q-сетей, а целевые Q-сети получаются усреднением Поляка параметров Q-сетей по ходу обучения.
  3. Как и в TD3, общая цель использует приём обрезанного двойного Q.

Что отличается?

  1. В отличие от TD3, в цели есть ещё слагаемое, которое появляется из-за регуляризации энтропией в SAC.
  2. В отличие от TD3, действия в следующем состоянии, используемые в цели, берутся из текущей политики, а не из целевой политики.
  3. В отличие от TD3, явного сглаживания целевой политики нет. TD3 учит детерминированную политику и поэтому сглаживает, добавляя случайный шум к действиям в следующем состоянии. SAC учит стохастическую политику, и шума от этой стохастичности хватает для похожего эффекта.

Прежде чем дать окончательный вид функции потерь Q, разберёмся, как в неё входит вклад регуляризации энтропией. Начнём с рекурсивного уравнения Беллмана для QπQ^{\pi} с регуляризацией энтропией и немного перепишем его, используя определение энтропии:

Qπ(s,a)=Es′∼Pa′∼π[R(s,a,s′)+γ(Qπ(s′,a′)+αH(π(⋅∣s′)))]=Es′∼Pa′∼π[R(s,a,s′)+γ(Qπ(s′,a′)−αlog⁡π(a′∣s′))]\begin{aligned} Q^{\pi}(s,a) &= \underset{\substack{s' \sim P \\ a' \sim \pi}}{\mathrm{E}}\left[R(s,a,s') + \gamma\left(Q^{\pi}(s',a') + \alpha H\left(\pi(\cdot|s')\right) \right)\right] \\ &= \underset{\substack{s' \sim P \\ a' \sim \pi}}{\mathrm{E}}\left[R(s,a,s') + \gamma\left(Q^{\pi}(s',a') - \alpha \log \pi(a'|s') \right)\right] \end{aligned}

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

Qπ(s,a)≈r+γ(Qπ(s′,a~′)−αlog⁡π(a~′∣s′)),          a~′∼π(⋅∣s′).Q^{\pi}(s,a) \approx r + \gamma\left(Q^{\pi}(s',\tilde{a}') - \alpha \log \pi(\tilde{a}'|s') \right), \;\;\;\;\; \tilde{a}' \sim \pi(\cdot|s').

SAC строит функцию потерь MSBE для каждой Q-функции с помощью такого выборочного приближения цели. Не определено осталось только одно: какую Q-функцию использовать для выборочного подсчёта цели. Как и TD3, SAC использует приём обрезанного двойного Q и берёт минимальное Q-значение из двух аппроксиматоров.

Собирая всё вместе, функции потерь для Q-сетей в SAC таковы:

L(ϕi,D)=E(s,a,r,s′,d)∼D[(Qϕi(s,a)−y(r,s′,d))2],L(\phi_i, {\mathcal D}) = \underset{(s,a,r,s',d) \sim {\mathcal D}}{{\mathrm E}}\left[ \Bigg( Q_{\phi_i}(s,a) - y(r,s',d) \Bigg)^2 \right],

где цель задаётся так:

y(r,s′,d)=r+γ(1−d)(min⁡j=1,2Qϕtarg,j(s′,a~′)−αlog⁡πθ(a~′∣s′)),          a~′∼πθ(⋅∣s′).y(r, s', d) = r + \gamma (1 - d) \left( \min_{j=1,2} Q_{\phi_{\text{targ},j}}(s', \tilde{a}') - \alpha \log \pi_{\theta}(\tilde{a}'|s') \right), \;\;\;\;\; \tilde{a}' \sim \pi_{\theta}(\cdot|s').

Обучение политики. Политика в каждом состоянии должна действовать так, чтобы максимизировать ожидаемую будущую отдачу плюс ожидаемую будущую энтропию. То есть она должна максимизировать Vπ(s)V^{\pi}(s), которую мы раскрываем так:

Vπ(s)=Ea∼π[Qπ(s,a)]+αH(π(⋅∣s))=Ea∼π[Qπ(s,a)−αlog⁡π(a∣s)].\begin{aligned} V^{\pi}(s) &= \underset{a \sim \pi}{\mathrm{E}}\left[Q^{\pi}(s,a)\right] + \alpha H\left(\pi(\cdot|s)\right) \\ &= \underset{a \sim \pi}{\mathrm{E}}\left[Q^{\pi}(s,a) - \alpha \log \pi(a|s)\right]. \end{aligned}

Способ, которым мы оптимизируем политику, использует трюк с репараметризациейтрюк репараметризацииEN reparameterization trickz = μ + σ·ε, ε ~ N(0, 1): случайность выносится во вход, и градиент проходит к μ и σ: выборка из πθ(⋅∣s)\pi_{\theta}(\cdot|s) получается вычислением детерминированной функции от состояния, параметров политики и независимого шума. Для иллюстрации: вслед за авторами статьи о SAC мы используем «сплющенную» гауссову политику (squashed Gaussian policy), то есть выборки получаются так:

a~θ(s,ξ)=tanh⁡(μθ(s)+σθ(s)⊙ξ),          ξ∼N(0,I).\tilde{a}_{\theta}(s, \xi) = \tanh\left( \mu_{\theta}(s) + \sigma_{\theta}(s) \odot \xi \right), \;\;\;\;\; \xi \sim \mathcal{N}(0, I).

Трюк с репараметризацией позволяет переписать матожидание по действиям (в котором есть неприятность: распределение зависит от параметров политики) в матожидание по шуму (в котором неприятность исчезает: распределение больше не зависит от параметров):

Ea∼πθ[Qπθ(s,a)−αlog⁡πθ(a∣s)]=Eξ∼N[Qπθ(s,a~θ(s,ξ))−αlog⁡πθ(a~θ(s,ξ)∣s)]\underset{a \sim \pi_{\theta}}{\mathrm{E}}\left[Q^{\pi_{\theta}}(s,a) - \alpha \log \pi_{\theta}(a|s)\right] = \underset{\xi \sim \mathcal{N}}{\mathrm{E}}\left[Q^{\pi_{\theta}}(s,\tilde{a}_{\theta}(s,\xi)) - \alpha \log \pi_{\theta}(\tilde{a}_{\theta}(s,\xi)|s)\right]

Чтобы получить функцию потерь политики, остаётся последний шаг: заменить QπθQ^{\pi_{\theta}} одним из наших аппроксиматоров. В отличие от TD3, который использует Qϕ1Q_{\phi_1} (только первый аппроксиматор Q), SAC использует min⁡j=1,2Qϕj\min_{j=1,2} Q_{\phi_j} (минимум из двух аппроксиматоров Q). Таким образом, политика оптимизируется по

max⁡θEs∼Dξ∼N[min⁡j=1,2Qϕj(s,a~θ(s,ξ))−αlog⁡πθ(a~θ(s,ξ)∣s)],\max_{\theta} \underset{\substack{s \sim \mathcal{D} \\ \xi \sim \mathcal{N}}}{\mathrm{E}}\left[\min_{j=1,2} Q_{\phi_j}(s,\tilde{a}_{\theta}(s,\xi)) - \alpha \log \pi_{\theta}(\tilde{a}_{\theta}(s,\xi)|s)\right],

что почти совпадает с оптимизацией политики в DDPG и TD3, за исключением приёма с минимумом двух Q, стохастичности и слагаемого с энтропией.

SAC обучает стохастическую политику с регуляризацией энтропией и исследует среду по текущей политике. Коэффициент регуляризации энтропией α\alpha явно управляет компромиссом между исследованием и использованием: большее α\alpha соответствует большему исследованию, меньшее α\alpha — большему использованию. Правильный коэффициент (тот, что ведёт к самому устойчивому обучению или к самой высокой награде) может различаться от среды к среде и требовать тщательной настройки.

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

Алгоритм 1. Soft Actor-Critic

  1. Вход: начальные параметры политики θ\theta, параметры Q-функций ϕ1\phi_1, ϕ2\phi_2, пустой буфер воспроизведения D\mathcal{D}.
  2. Приравнять целевые параметры к основным: ϕtarg,1←ϕ1\phi_{\text{targ},1} \leftarrow \phi_1, ϕtarg,2←ϕ2\phi_{\text{targ},2} \leftarrow \phi_2.
  3. Повторять:
    1. Наблюдать состояние ss и выбрать действие a∼πθ(⋅∣s)a \sim \pi_{\theta}(\cdot|s).
    2. Выполнить aa в среде.
    3. Наблюдать следующее состояние s′s', награду rr и сигнал завершения dd, показывающий, терминально ли s′s'.
    4. Сохранить (s,a,r,s′,d)(s,a,r,s',d) в буфер воспроизведения D\mathcal{D}.
    5. Если s′s' терминально, сбросить среду.
    6. Если пора обновляться, то для jj от 0 до нужного числа обновлений:
      1. Случайно выбрать из D\mathcal{D} батч переходов B={(s,a,r,s′,d)}B = \{ (s,a,r,s',d) \}.
      2. Вычислить цели для Q-функций: y(r,s′,d)=r+γ(1−d)(min⁡i=1,2Qϕtarg,i(s′,a~′)−αlog⁡πθ(a~′∣s′)),a~′∼πθ(⋅∣s′)y (r,s',d) = r + \gamma (1-d) \left(\min_{i=1,2} Q_{\phi_{\text{targ}, i}} (s', \tilde{a}') - \alpha \log \pi_{\theta}(\tilde{a}'|s')\right), \qquad \tilde{a}' \sim \pi_{\theta}(\cdot|s')
      3. Обновить Q-функции одним шагом градиентного спуска по ∇ϕi1∣B∣∑(s,a,r,s′,d)∈B(Qϕi(s,a)−y(r,s′,d))2для i=1,2\nabla_{\phi_i} \frac{1}{|B|}\sum_{(s,a,r,s',d) \in B} \left( Q_{\phi_i}(s,a) - y(r,s',d) \right)^2 \qquad \text{для } i=1,2
      4. Обновить политику одним шагом градиентного подъёма по ∇θ1∣B∣∑s∈B(min⁡i=1,2Qϕi(s,a~θ(s))−αlog⁡πθ(a~θ(s)∣s)),\nabla_{\theta} \frac{1}{|B|}\sum_{s \in B} \Big(\min_{i=1,2} Q_{\phi_i}(s, \tilde{a}_{\theta}(s)) - \alpha \log \pi_{\theta} \left(\left. \tilde{a}_{\theta}(s) \right| s\right) \Big), где a~θ(s)\tilde{a}_{\theta}(s) — выборка из πθ(⋅∣s)\pi_{\theta}(\cdot|s), дифференцируемая по θ\theta благодаря трюку с репараметризацией.
      5. Обновить целевые сети: ϕtarg,i←ρϕtarg,i+(1−ρ)ϕiдля i=1,2\phi_{\text{targ},i} \leftarrow \rho \phi_{\text{targ}, i} + (1-\rho) \phi_i \qquad \text{для } i=1,2
  4. До сходимости.

У SAC есть реализации на PyTorch (spinup.sac_pytorch) и TensorFlow (spinup.sac_tf1). Общие параметры — в таблице ниже; особые параметры SAC:

ПараметрПо умолчаниюСмысл
lr0.001Скорость обучения (одна и та же для политики и для обучения ценности)
alpha0.2Коэффициент регуляризации энтропией. (Эквивалентен величине, обратной масштабу награды в исходной статье о SAC.)

Сохранённая модель PyTorch загружается так же, как у DDPG. Граф TensorFlow содержит: x и a — placeholder для состояния и действия; mu — детерминированно вычисляет среднее действие агента при состояниях из x; pi — сэмплирует действие агента при состояниях из x; q1 и q2 — две оценки ценности действия для x и a; v — оценка ценности для состояний из x.

Примечание: для SAC правильная политика для оценки качества — mu, а не pi. Политику pi можно считать политикой исследования, а mu — политикой использования.


Функции spinup.ddpg_pytorch, spinup.td3_pytorch и spinup.sac_pytorch (и их версии *_tf1) принимают одни и те же основные параметры. Значения по умолчанию одинаковые у всех трёх, кроме отмеченных.

ПараметрПо умолчаниюСмысл
env_fn—Функция, которая создаёт копию среды. Среда должна удовлетворять API OpenAI Gym
actor_criticMLPActorCriticКонструктор модуля PyTorch с методом act, модулем pi и модулем (или модулями) q. У DDPG один q, у TD3 и SAC — q1 и q2; у SAC pi возвращает действие и его лог-вероятность. Критично: выход q должен быть плоским, формы (batch,)
ac_kwargs{}Любые именованные аргументы для объекта ActorCritic, переданного в алгоритм
seed0Сид генераторов случайных чисел
steps_per_epoch4000Число шагов взаимодействия (пар «состояние — действие») агента со средой за эпоху
epochs100Число эпох, в течение которых агент работает и обучается
replay_size1 000 000Максимальная длина буфера воспроизведения
gamma0.99Коэффициент дисконтирования. (Всегда между 0 и 1.)
polyak0.995Коэффициент интерполяции при усреднении Поляка для целевых сетей: θtarg←ρθtarg+(1−ρ)θ\theta_{\text{targ}} \leftarrow \rho \theta_{\text{targ}} + (1-\rho) \theta, где ρ\rho — polyak. (Всегда между 0 и 1, обычно близок к 1.)
pi_lr, q_lr0.001, 0.001Скорости обучения политики и Q-сетей (у DDPG и TD3; у SAC вместо них один lr)
batch_size100Размер минибатча для SGD
start_steps10 000Число шагов, в течение которых действия выбираются равномерно случайно, прежде чем запустить настоящую политику. Помогает исследованию
update_after1000Сколько шагов взаимодействия со средой собрать, прежде чем начинать обновления градиентным спуском. Гарантирует, что в буфере достаточно данных для полезных обновлений
update_every50Сколько шагов взаимодействия со средой должно пройти между обновлениями градиентным спуском. Важно: как бы долго вы ни ждали между обновлениями, отношение шагов в среде к шагам градиента зафиксировано на 1
num_test_episodes10Сколько эпизодов в конце каждой эпохи тестировать детерминированную политику
max_ep_len1000Максимальная длина траектории / эпизода / роллаута
logger_kwargs{}Именованные аргументы для EpochLogger
save_freq1Как часто (через сколько эпох) сохранять текущие политику и функцию ценности
  • VPG и PPO — два других алгоритма оптимизации политики.
  • Упражнения: упражнение 1.3 — дописать математику TD3; упражнение 2.2 — найти «тихий» баг в DDPG.
  • В модуле курса 6.0 те же идеи в простых средах и с кодом: 6.0.2, 6.0.3.
  1. См. книгу Convex Optimization Бойда и Ванденберге, особенно главы 2–5. ↩