← 博客

Reinforcement Learning

AI 整理笔记: 本文由 AI 根据学习过程中的问题辅助整理,并非作者逐字手写。

Optimal Policy 与 Optimal Q-function

Let $\pi^*$ denote an optimal policy, i.e. any policy $\pi^*$ s.t.

$$ Q^{\pi^*}(s,a) \ge Q^\pi(s,a) $$

for every $s \in S$, $a \in A$, and any policy $\pi$.

All optimal policies have the same Q-function, which is called the optimal Q-function and denoted $Q^*$.

对于任意固定的 $(s,a)$,第一步已经确定,后面无论交给哪个最优策略,都能取得相同的最优后续回报。

如果环境有随机性,即使两个策略都最优,单次运行得到的累计折扣奖励也可能不同;相同的是对所有可能结果按概率加权后的平均值。

Bellman Equation(贝尔曼方程)

它表达的是: 从现在开始的累计回报,可以拆成“现在这一步的奖励”+“从下一步开始的累计回报”。

对于一个固定策略 $\pi$:

$$ Q^\pi(s,a)= \mathbb E_{s'} \left[ \underbrace{r(s,a)}_{\text{现在的奖励}} +\gamma\underbrace{Q^\pi(s',\pi(s'))}_{\text{下一步继续按 }\pi\text{ 行动的价值}} \right] $$

在训练中的用处是:即使一开始不知道完整的长期回报,也可以用“实际观察到的一步奖励+目前估计的下一状态价值”,逐渐修正当前 Q 值。

Off-policy

采集数据的策略和更新所针对的策略可以不同

DQN 与 $\epsilon$-greedy

DQN 使用 $Q_\theta(s,a)$ 表示每个动作的预期长期回报,通常用 $\epsilon$-greedy 选择动作。

设 $\epsilon=0.1$:

  • 有 10% 的概率进入探索分支,忽略 Q 值,从四个动作中均匀随机选择,每个动作被选中的概率都是 $1/4$。
  • 有 90% 的概率进入贪心分支,直接选 Q 值最高的“左”。

在线网络 $Q_\theta$:正在训练、不断修改的版本。

目标网络 $Q_{\theta^-}$:暂时冻结的旧版本,用来提供稳定的训练目标。

Step 1. 收集经验

先区分三个容易混淆的下标:

记号含义
$t$环境中的时间步
$k$第几次梯度更新
$i$从 Replay Buffer 抽出的第几条样本

在状态 $s_t$,在线 Q 网络估计各个动作的价值,再用 $\epsilon$-greedy 选出 $a_t$。执行一次 env.step(a_t) 后,环境返回即时奖励 $r_t$、下一状态 $s_{t+1}$ 和终止标记 $d_t$,得到一条 transition:

$$ (s_t,a_t,r_t,s_{t+1},d_t) $$

这条 transition 会立即存入 Replay Buffer,不需要等整条轨迹结束。

一次 training loop 到底采集多少 rollout? DQN 没有统一规定,而且通常不按完整 rollout 组织训练。最简单的实现中,外层循环每执行一个环境 step,就向 buffer 加 1 条 transition;如果一局有 $T$ 步,那么这一局最终会加入 $T$ 条 transition,而不是把整局当成一个不可拆分的训练样本。

实际采集与训练节奏通常由以下参数控制:

参数作用
learning_starts先只收集多少条 transition,再开始训练
train_freq每收集多少个环境 step,触发一次训练
gradient_steps每次触发训练后,执行多少次梯度更新
batch_size每次梯度更新从整个 buffer 随机抽多少条旧、新 transition

例如,buffer 已经过了预热阶段,单环境设置 train_freq=4、gradient_steps=1、batch_size=32:

  1. 连续与环境交互 4 步,向 buffer 新增 4 条 transition。
  2. 从整个 buffer 随机抽取 32 条 transition,不要求是刚加入的 4 条。
  3. 用这 32 条数据做 1 次梯度更新。
  4. 再收集 4 条,然后重复。

如果同时运行 $N$ 个并行环境,那么一次并行环境 step 会新增 $N$ 条 transition。也可以把 train_freq 配置成一整个 episode,但这只是实现选择,不是 DQN 算法要求。

Step 2. 使用目标网络构造训练目标

当 buffer 中已有足够数据并到达训练时机时,随机抽取一个 mini-batch:

$$ \mathcal B= \{(s_i,a_i,r_i,s'_i,d_i)\}_{i=1}^{B} $$

这里的 $i$ 是 batch 样本编号。不同样本可能来自不同 episode、不同时间步,并不要求按 $t$ 的先后顺序排列。

对于 batch 中每一条 transition,我们要修正在线网络对 $Q_\theta(s_i,a_i)$ 的估计。目标值来自 Bellman 方程:

$$ \boxed{ y_i=r_i+\gamma(1-d_i)\max_{a'}Q_{\theta^-}(s'_i,a') } $$

其中 $s'_i$ 就是这条经验里的下一状态。目标网络对 batch 中所有 $s'_i$ 做一次前向传播,为每个状态输出所有候选动作的 Q 值:

$$ Q_{\theta^-}(s'_i,a'), \qquad a'\in\mathcal A $$

然后对每条样本取最大的动作价值:

$$ \max_{a'}Q_{\theta^-}(s'_i,a') $$

这里的 $a'$ 是遍历所有候选动作的变量,不是 Replay Buffer 中实际执行的动作 $a_i$,因此不通过 $\epsilon$-greedy 选择。若 $d_i=1$,说明这条 transition 到达终止状态,目标就是 $y_i=r_i$,不再估计后续价值。

也就是:当前状态下实际动作 $a_i$ 的价值,应接近“实际即时奖励+下一状态的最佳后续价值估计”。

部分来源
$r_i$这条 buffer 样本中实际观察到的奖励
$\max_{a'}Q_{\theta^-}(s'_i,a')$目标网络对这条样本的未来回报估计

示例:

从同一个 mini-batch 中取一条样本:

$$ (s_i,a_i=\text{左},r_i=2,s'_i,d_i=0) $$

把其中的下一状态 $s'_i$ 输入目标网络。假设它估计:

下一步动作目标网络预测的 Q 值
上5
下10
左3
右4

最高值是 $10$。取 $r_i=2$、$\gamma=0.9$,构造参考值:

$$ y_i= \underbrace{2}_{\text{实际即时奖励}} +0.9\times\underbrace{10}_{\text{目标网络估计的后续价值}} =11 $$

这个 $11$ 是训练目标,仍然是估计,不是真实答案。

Step 3. 更新在线网络

Step 3 使用的就是 Step 2 从 buffer 抽出的同一个 mini-batch,不会重新采样。

对于上面的同一条样本,在线网络输入当前状态 $s_i$,输出所有动作的 Q 值。由于 buffer 记录的实际动作是 $a_i=\text{左}$,所以从输出中取出“左”的预测。假设:

$$ Q_\theta(s_i,a_i)=Q_\theta(s_i,\text{左})=3 $$

对 batch 中的每条样本都做同样的选择,然后计算平均损失:

$$ L(\theta) =\frac{1}{B}\sum_{i=1}^{B} \left(Q_\theta(s_i,a_i)-y_i\right)^2 $$

在这条示例中,对应的误差项是 $(3-11)^2$。反向传播只修改在线网络,让 $Q_\theta(s_i,\text{左})$ 向 $11$ 靠近;目标网络此时不动,$y_i$ 也不参与梯度计算。

同一个 batch 的数据流可以概括为:

1
2
3
4
5
s'_i ──> 目标网络 Q_{θ⁻} ──> y_i

s_i  ──> 在线网络 Q_θ ──> 取实际动作 a_i 的 Q 值

                         prediction 与 y_i 计算 loss

Step 4. 更新目标网络

训练一段时间后,把已经改进的在线网络复制给目标网络:

$$ \theta^- \leftarrow \theta $$

然后继续上述过程。

完整训练时序可以概括为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
先收集 learning_starts 条 transition

循环:
    收集 train_freq 个环境 step,并逐条写入 Replay Buffer

    重复 gradient_steps 次:
        从整个 Replay Buffer 随机抽取同一个 mini-batch
        用 s'_i 和目标网络计算 y_i
        用 s_i、a_i 和在线网络计算 prediction
        用 prediction 与 y_i 的差更新在线网络

    每隔一段时间,把在线网络参数复制给目标网络

为什么 DQN 是 Off-policy

Off-policy 体现在:“实际怎么走”和“更新时假定后面怎么走”可以不同。

假设到了 $s_{t+1}$,网络估计:

动作Q 值
左10
右2

收集数据时使用 $\epsilon$-greedy,可能因为探索而实际选择“右”。

但 DQN 构造 $y_t$ 时,仍然使用:

$$ \max_{a'}Q(s_{t+1},a')=10 $$

也就是**“左”的价值**,而不是实际探索选择的“右”的价值。

设 $r_t=1$、$\gamma=0.9$,DQN 的目标是:

$$ y_t=1+0.9\times10=10 $$

DDPG

DDPG 有两类网络:Actor(Action 网络)和 Critic(Q 网络)。训练时,两者各有一个在线网络和目标网络。

网络结构

网络用途更新方式
在线 Actor $\pi_\theta$输出动作,交互时加噪声进行探索梯度更新
在线 Critic $Q_\phi$评价动作,并指导在线 Actor 学习梯度更新
目标 Actor $\pi_{\theta^-}$提供计算训练目标时的下一步动作缓慢跟随在线 Actor
目标 Critic $Q_{\phi^-}$评价上述动作,帮助计算训练目标缓慢跟随在线 Critic

探索

采集数据时,给 Actor 输出的动作加一点随机噪声。目的和 DQN 的 $\epsilon$-greedy 类似:增加探索。

$$ \pi_b(s)=\pi_\theta(s)+\mathcal N(0,1) $$

训练目标

$$ \boxed{ y_t=r_t+\gamma Q_{\phi^-}\!\left(s_{t+1},\pi_{\theta^-}(s_{t+1})\right) } $$

也就是:目标 Actor 选下一步动作 → 目标 Critic 评价它 → 得到训练目标 $y_t$。

更新在线 Critic

对 Replay Buffer 中抽取的 mini-batch,最小化 Critic Loss:

$$ L_{\text{critic}} =\mathbb E\left[(Q_\phi(s_t,a_t)-y_t)^2\right] $$

通过梯度更新在线 Critic,使其评价更接近训练目标:

$$ \phi_{\text{old}}\longrightarrow\phi_{\text{new}} $$

更新在线 Actor

Critic 更新完成后,在线 Actor 使用同一个 mini-batch 中的状态重新生成训练动作:

$$ \hat a_i=\pi_\theta(s_i) $$

这个 $\hat a_i$ 不是 Replay Buffer 中实际执行过的动作 $a_i$。它只用于这次 Actor 训练,不会在环境中执行,也不会写回 Replay Buffer。

然后,使用更新后的在线 Critic $Q_{\phi_{\text{new}}}$ 评价这些动作,并指导在线 Actor:

$$ L_{\text{actor}} =-\mathbb E_{s\sim\mathcal D} \left[Q_{\phi_{\text{new}}}(s,\pi_\theta(s))\right] $$

这里的期望不是一个被学习或更新的参数,而是用 mini-batch 中的状态平均值来近似:

$$ L_{\text{actor}} \approx-\frac{1}{N}\sum_{i=1}^{N} Q_{\phi_{\text{new}}}\!\left(s_i,\pi_\theta(s_i)\right) $$

计算 Actor Loss 时固定 Critic 的参数 $\phi_{\text{new}}$,只更新 Actor 的参数 $\theta$。

软更新目标网络

两个目标网络不直接做梯度更新,而是通常采用软更新,例如:

$$ \phi^-\leftarrow(1-\tau)\phi^-+\tau\phi $$

Universal Value Function Approximators (UVFA)

UVFA 是 DQN、DDPG 等算法在多目标任务上的扩展。它引入目标空间 $\mathcal G$,每个目标 $g\in\mathcal G$ 对应一个奖励函数:

$$ r_g:\mathcal S\times\mathcal A\rightarrow\mathbb R $$

普通 DQN 学习 $Q_\theta(s,a)$;UVFA 把目标也作为网络输入,学习共享的 goal-conditioned Q-function:

$$ Q_\theta(s,a,g) $$

它表示:在状态 $s$ 执行动作 $a$,并且当前目标是 $g$ 时,预期能够获得多少长期回报。对应的策略也依赖目标:

$$ \pi:\mathcal S\times\mathcal G\rightarrow\mathcal A $$

多目标数据如何收集

每个 episode 开始时,从分布 $p(s_0,g)$ 中采样初始状态和本局目标。目标在这个 episode 中保持不变。

例如,本局目标是“到达红色位置”。在状态 $s_t$,使用当前状态和红色目标选择动作:

$$ a_t\sim\epsilon\text{-greedy}\left(Q_\theta(s_t,\cdot,g)\right) $$

执行动作后,根据本局目标对应的奖励函数计算奖励:

$$ r_t=r_g(s_t,a_t) $$

然后向 Replay Buffer 保存一条带有目标的 transition:

$$ (s_t,a_t,r_t,s_{t+1},g,d_t) $$

如果这一局有 $T$ 个环境 step,就会向 buffer 加入 $T$ 条带有相同目标 $g$ 的 transition。transition 可以在每个环境 step 后立即写入,不需要等整个 episode 结束才统一保存。

这一局结束后,下一局会重新采样目标,例如从“红色”换成“蓝色”。经过许多 episode 后,同一个 Replay Buffer 中就会同时包含:

1
2
3
红色目标的 transition
蓝色目标的 transition
绿色目标的 transition

因此,“同时学习多个目标”不是指一个 episode 内不断更换目标,而是不同 episode 采集不同目标的数据,再使用同一个网络统一训练。如果使用多个并行环境,也可以让不同环境同时采集不同目标。

从 Buffer 抽取混合 Batch

训练时,从整个 Replay Buffer 随机抽取一个 mini-batch:

$$ \mathcal B= \{(s_i,a_i,r_i,s'_i,g_i,d_i)\}_{i=1}^{B} $$

同一个 batch 中可以混合不同目标。例如:

样本当前状态实际动作目标
1$s_3$左红色
2$s_{17}$右蓝色
3$s_8$上绿色
4$s_{25}$下红色

对于每条样本,使用这条 transition 自己携带的目标 $g_i$ 构造 TD target:

$$ y_i= r_i+ \gamma(1-d_i) \max_{a'}Q_{\theta^-}(s'_i,a',g_i) $$

在线网络使用同一个 batch 计算:

$$ Q_\theta(s_i,a_i,g_i) $$

整个 batch 的损失为:

$$ L(\theta)= \frac{1}{B} \sum_{i=1}^{B} \left(Q_\theta(s_i,a_i,g_i)-y_i\right)^2 $$

一次梯度更新可以同时包含红色、蓝色和绿色目标的训练信号。虽然不同目标共享同一组网络参数 $\theta$,但目标 $g$ 是输入的一部分,因此同一个状态和动作在不同目标下可以有不同价值:

$$ Q_\theta(s,a,\text{红色}) \ne Q_\theta(s,a,\text{蓝色}) $$

共享参数还允许网络学习目标之间的共同结构。例如,当目标表示为目标位置时,网络可能学会根据当前位置与目标位置的相对方向选择动作,从而泛化到训练时没有见过的 state-goal 组合。

为什么一局内固定目标

$Q(s,a,g)$ 表示目标 $g$ 保持不变时的预期累计回报:

$$ Q(s,a,g)= \mathbb E\left[R_t\mid s_t=s,a_t=a,g\right] $$

如果在 episode 中途随意更换目标,前面动作所对应的长期回报定义也会改变,Bellman target 就不再描述同一个任务。因此标准 UVFA 的训练结构是:

1
2
3
4
5
一个 episode 内:目标固定
不同 episode 间:重新采样目标
Replay Buffer:混合保存不同目标的 transition
训练 mini-batch:可以同时包含多个目标
共享网络:通过输入 g 区分不同任务

On-policy

用近期策略收集一批数据 → 在这批数据上做有限次更新 → 再用新策略收集数据。

PPO (Proximal Policy Optimization)

两个模型

Actor (Policy Model)

  • 学习做出更好的 Action。
  • 通过 Policy Loss 更新参数。

Critic (Value Model)

  • 学习预测当前 State 的 Expected Return。
  • 通过 Value Loss 更新参数。
  • 它不负责产生 Reward,而是估计未来能获得多少 Reward。

Step 1. Rollout

假设 Memory Manager 当前输入为 State $s$,Actor 采样到 Action UPDATE,记录:

$$ \pi_{\mathrm{old}}(\text{UPDATE}\mid s)=0.6, \qquad R=1, \qquad V_\phi(s)=0.2 $$

其中,$R$ 是下游 QA 回答正确后得到的实际 Reward;$V_\phi(s)$ 是 Critic 对 Expected Return 的预测,不是人工标注。

Step 2. Calculate Advantage

Advantage 衡量这次 Action 的结果比预期好多少。在单步任务的简化情况下:

$$ A=R-V_\phi(s)=1-0.2=\boxed{0.8} $$
  • $A > 0$:实际结果好于预期,应提高这个 Action 的概率。
  • $A < 0$:实际结果差于预期,应降低这个 Action 的概率。

真实多步 PPO 通常使用 GAE 等方法计算 Advantage。

Step 3. Calculate PPO Objective

定义 Probability Ratio:

$$ r(\theta)=\frac{\pi_\theta(a\mid s)}{\pi_{\mathrm{old}}(a\mid s)} $$

分母是 Rollout 时旧 Policy 对 Action 的概率,分子是当前 Policy 对同一个 Action重新计算的概率。训练刚开始时,新旧 Policy 参数相同,因此 $r=0.6/0.6=1$。

PPO 引入 Clipping:

$$ \operatorname{clip}(r,\,0.8,\,1.2)= \begin{cases} 0.8, & r < 0.8, \\[4pt] r, & 0.8 \le r \le 1.2, \\[4pt] 1.2, & r > 1.2. \end{cases} $$

最终 PPO 希望最大化:

$$ L^{\mathrm{CLIP}}(\theta) =\min\!\left( rA,\; \operatorname{clip}(r,\,0.8,\,1.2)A \right) $$

代入初始值,$L^{\mathrm{CLIP}}=\min(1\times0.8,1\times0.8)=0.8$。

Clipping 的作用:

  • Advantage 为正且 Ratio 超过 1.2 时,概率继续增大不会带来额外优化收益。
  • Advantage 为负且 Ratio 低于 0.8 时,概率继续减小不会带来额外优化收益。

它的目的是防止 Policy 一次更新得过于激进;限制的是优化收益,并不硬性限制概率变化。

Step 4. Backpropagation — Update Actor

当前 Ratio = 1,尚未触发 Clipping。此时 Objective 仍依赖模型参数 $\theta$:

$$ \begin{aligned} L(\theta) &=0.8\,\frac{\pi_\theta(\text{UPDATE}\mid s)}{0.6}, \\[4pt] \nabla_\theta L(\theta) &=\frac{0.8}{0.6}\,\nabla_\theta\pi_\theta(\text{UPDATE}\mid s). \end{aligned} $$

Optimizer 利用梯度更新 Actor。由于 Advantage 为正,这次更新倾向于提高 UPDATE 的概率。例如:

$$ \pi_\theta(\text{UPDATE}\mid s): 0.60\longrightarrow0.65, \qquad r=\frac{0.65}{0.60}\approx1.083 $$

$0.65$ 只是举例,实际变化由梯度和 Learning Rate 决定。继续使用同一批 Rollout 数据训练时,不需要重新 Rollout,只需要重新计算 Action 的概率。

因为优化器通常使用 Gradient Descent,实际代码一般最小化:

$$ L_{\mathrm{policy}}(\theta)=-L^{\mathrm{CLIP}}(\theta) $$

Step 5. Update Critic

Actor 更新 Policy 的同时,Critic 通过最小化 Value Loss 学习预测 Expected Return。在单步任务中:

$$ L_{\mathrm{value}}(\phi) =\bigl(V_\phi(s)-R\bigr)^2 =(0.2-1)^2 =\boxed{0.64} $$

Critic 预测的是期望回报,不要求每次预测都与单次随机 Rollout 的结果一致。

GRPO

假设这一轮选择了 4 个任务,每个任务执行 8 次:

名称这个例子中包含什么用来干什么
Group同一条任务指令下的 8 条轨迹比较奖励,计算各条轨迹的 Advantage
Rollout Batch4 个 Group,共 32 条轨迹这一轮收集的全部交互数据
Mini-batch从这批数据中取出的一个小部分做一次梯度更新

通常会把 Mini-batch 中各条轨迹的所有有效动作位置都计入 Loss,再汇总起来做一次参数更新。Mini-batch 也可以混合不同 Group 的轨迹,不要求每个 Group 都完整地放在一起。

这一个 Rollout Batch 收集完,并完成了对它的训练更新后,再用更新后的模型收集下一批轨迹;新一轮的分母也随之更新。

Group-relative Advantage

$$ A_i= \frac{R_i-\operatorname{mean}(R_1,\ldots,R_G)} {\operatorname{std}(R_1,\ldots,R_G)+\epsilon} $$

Policy Ratio

$$ \tilde r_{i,t}(\theta)= \frac{\pi_\theta(a_{i,t}\mid o_{i,t},g')} {\pi_{\theta_{\mathrm{old}}}(a_{i,t}\mid o_{i,t},g)} $$

GRPO 目标项

$$ \ell_{i,t}= \min\left( r_{i,t}A_i,\; \operatorname{clip}(r_{i,t},1-\varepsilon,1+\varepsilon)A_i \right) $$

Mini-batch Loss

将上述目标项汇总:

$$ L_{\text{mini-batch}}= -\frac{1}{B} \sum_{i\in\text{mini-batch}} \frac{1}{T_i} \sum_{t=1}^{T_i}\ell_{i,t} $$

DPO

同一个问题,比较两个回答。

例如同一个问题 \(x\),好回答 \(y^+\),差回答 \(y^-\):

$$ s_{\mathrm{DPO}}= \underbrace{\log\frac{\pi_\theta(y^+\mid x)} {\pi_{\mathrm{ref}}(y^+\mid x)}}_{\text{好回答的概率变化}} -\underbrace{\log\frac{\pi_\theta(y^-\mid x)} {\pi_{\mathrm{ref}}(y^-\mid x)}}_{\text{差回答的概率变化}} $$