4 分钟阅读

#笔记 #AI-assisted

动手学习强化学习

强化学习和有监督学习的区别:有监督学习的训练数据来自于从给定的数据分布中采样得到的训练数据集上,通过优化在训练数据集中设定的目标函数(如最小化预测误差)来找到模型的最优参数。这里,训练数据集背后的数据分布是完全不变的

在强化学习中,数据是在智能体与环境交互的过程中得到的。如果智能体不采取某个决策动作,那么该动作对应的数据就永远无法被观测到,所以当前智能体的训练数据来自之前智能体的决策结果。因此,智能体获得的训练数据分布是随着其策略的改变而改变的

进而,强化学习和监督学习的优化目标不同:

监督学习: \(\theta^* = \arg\min_\theta \mathbb{E}_{(x,y)\sim D} [L(f_\theta(x), y)]\)

强化学习: \(\theta^* = \arg\max_\theta \mathbb{E}_{(s,a)\sim \mathcal{E}} [R(s,a)]\)

两者都是优化在某一个数据分布上的某一函数的期望,但监督学习中的数据分布是固定的,要优化的是损失函数 $f_{\theta}$;而强化学习中的数据分布是随着智能体的策略改变而改变的,要优化的是策略(进而影响数据分布 $\mathcal{E}$)

[[Multi-armed-Bandit]]

[[Markov-Decision-Process]]

SAC

SAC在reward中加入entropy正则化项,形成explore-exploit trade-off,保持策略的随机性,来避免策略过早地收敛到局部的次优解。

SAC是一种off-policy algorithm.

熵衡量的是一个分布的不确定性,分布越集中,采样确定性越高,熵越小: \(H(P) = \underset{x \sim P}E[-\log P(x)]\)

一般RL的目标策略是: \(\pi^* = \arg \max_{\pi} \underset{\tau \sim \pi}E{ \sum_{t=0}^{\infty} \gamma^t R(s_t, a_t, s_{t+1})}\) SAC在每一步的reward中加入了熵正则化项,衡量策略输出的不确定性: \(\begin{align} \pi^* &= \arg \max_{\pi} \underset{\tau \sim \pi}E{ \sum_{t=0}^{\infty} \gamma^t \bigg( R(s_t, a_t, s_{t+1}) + \alpha H\left(\pi(\cdot|s_t)\right) \bigg)}\\ &=\arg \max_{\pi} \underset{a \sim \pi}E\big[ R(s, a, s') - \alpha \log\pi(a|s)+\gamma Q(a,s')\big] \end{align}\)

$\alpha > 0$ 调节探索-利用的权重。 这种机制保证SAC的策略总是具有一定随机性,从而【不会在估计Q的时候过多受到尖峰的影响产生过度乐观的估计】。 相应地,价值函数变成:

\(V^{\pi}(s) = \underset{\tau \sim \pi}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) \bigg| s_0 = s\right]}\) 动作价值函数:

\[Q^{\pi}(s,a) = \underset{\tau \sim \pi}E{ \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)\bigg| s_0 = s, a_0 = a \right]}\]

注意熵是从$t=1$开始算的,因为$t=0$的 $a_0$已经确定了。 $V^{\pi}$和$Q^{\pi}$的关系:

\[V^{\pi}(s) = \underset{a \sim \pi}E[Q^{\pi}(s,a)] + \alpha H\left(\pi(\cdot|s)\right)\]

Bellman方程: \(\begin{align} Q^{\pi}(s,a) &= \underset{s' \sim P ,\; a' \sim \pi}E\bigg[R(s,a,s') + \gamma\left(Q^{\pi}(s',a') + \alpha H\left(\pi(\cdot|s')\right) \right)\bigg] \\ &= \underset{s' \sim P}E\bigg[R(s,a,s') + \gamma V^{\pi}(s')\bigg]. \end{align}\)

Critic的优化目标为Bellman均方误差 \(J(\theta)=\underset{s\sim \rho^\pi}E[Q_\theta^{\pi_\Phi}(s,a)-y(r,s',a)]\) 其中: \(y(r,s',a)=r(s,a)+\gamma \min_{i=1,2}[Q_{trag,i}^\pi(s',a)-\alpha\log\pi(\cdot|s')]\) 参考价值使用两个critic之中较为悲观的那个。

在更新的时候,用经验均值替代期望: \(J(\theta)=\frac{1}{N}\sum_{j=0}^N[Q_\theta^\pi(s_j,a_j)-y(r,s_j',a_j)]\) 这里 $s’$是从buffer里采样的,而 $a$ 是从online policy中采样 $a\sim \pi(s)$ \(\pi(a|s)=\tanh\big(\mu(s)+\sigma(s)\odot\xi\big),\quad\xi\sim\mathcal{N}(0,I)\) $\tanh$ 确保动作在一个有限区间内,而非像原始的高斯分布一样在无限区间上。 从而Actor的优化目标为:

\[\begin{align} \phi &= \max_{\phi} \underset{\tau \sim \pi}E{ \sum_{t=0}^{\infty} \gamma^t \bigg( R(s_t, a_t, s_{t+1}) + \alpha H\left(\pi(\cdot|s_t)\right) \bigg)}\\ &=\max_{\phi} \underset{a \sim \pi_\phi}E\big[ R(s, a, s') - \alpha \log\pi_\phi(a|s)+\gamma Q(a,s')\big]\\ &=\max_{\phi} \underset{\xi\sim\mathcal{N}(0,I)}E\big[ R(s, a, s') - \alpha \log\pi_\phi(a|s)+\gamma Q(a,s')\big]\\ \end{align}\]

Actor和Critic都使用polyak lazy update \(Q_{trag,i}\leftarrow \rho Q_{trag,i}+ (1-\rho )Q_{\theta,i},\quad i=1,2\) \(\pi_{trag}\leftarrow \rho \pi_{trag}+ (1-\rho )\pi_{\Phi}\)

RLPD

RLPD的核心目标是:在在线 RL 训练过程中,高效利用已有的离线数据(无论是专家演示还是次优轨迹),同时不依赖预训练或显式的约束项(如行为克隆)

它的核心设计包括:

  1. 对称采样(Symmetric Sampling)
  2. LayerNorm 缓解值函数过估计
  3. 大集成(Ensemble)与高更新-数据比(UTD)
  4. 环境敏感的超参数选择(如是否使用 CDQ、熵项、网络深度)

1. 对称采样(Symmetric Sampling)

做法:每次从 在线回放池( $\mathcal{R}$) 和 离线数据集( $\mathcal{D}$)中各采样一半(各 $N/2$)组成一个 batch。

\[b = b_{\mathcal{R}} \cup b_{\mathcal{D}}, \quad |b| = N\]

作用

  • 保证离线数据持续参与训练,避免被在线数据淹没;
  • 不增加额外计算开销;
  • 在稀疏奖励任务中显著提升探索效率。

    2. 目标值计算(带 LayerNorm 的 Critic)

RLPD 使用 集成 Q 函数(默认 10 个),目标值计算如下:

\(y = r + \gamma \left( \min_{i \in \mathcal{Z}} Q_{\theta_i'}(s', \tilde{a}') \right), \quad \tilde{a}' \sim \pi_\phi(\cdot | s')\) 动作是从当前策略中采样的,从而在线数据部分Q的估计是on-policy的。

其中:

  • $\mathcal{Z}$ 是从集成中采样的子集(大小 $Z$,可为 1 或 2);
  • 若使用最大熵目标,则加上熵项: \(y = y + \gamma \alpha \log \pi_\phi(\tilde{a}' | s')\)

关键点

  • 默认使用 LayerNorm 在 Q 网络中间层,保证输出有界: \(\| Q_{\theta,w}(s,a) \| \leq \| w \| \cdot \| \text{relu}(\psi_\theta(s,a)) \| \leq \| w \|\) 这有效防止了 OOD 动作的过度估计(见论文 Eq. 1)。

3. Critic 更新(最小化 TD 误差)

对每个 Q 网络 $i$(共 $E$ 个):

\[L = \frac{1}{N} \sum_{i} \left( y - Q_{\theta_i}(s,a) \right)^2\]

这里使用 均方误差(MSE),与 SAC 一致。

4. Actor 更新(最大化 Q 值 + 熵)

Actor 更新目标(使用所有集成 Q 的平均):

\[\max_{\phi} \frac{1}{E} \sum_{i=1}^{E} Q_{\theta_i}(s, \tilde{a}) - \alpha \log \pi_\phi(\tilde{a} | s), \quad \tilde{a} \sim \pi_\phi(\cdot | s)\]

这与 SAC 的更新目标一致,只是 Q 值来自多个集成网络的平均。

5. 高更新-数据比(UTD)

RLPD 在每个环境步骤中执行 G 次梯度更新(默认 $G = 20$),大大加速离线数据的利用。

  • 在像素任务中,还使用了 随机平移增强(Random Shift Augmentation) 来防止过拟合。
  1. 采样: $b \sim 0.5 \mathcal{R} + 0.5 \mathcal{D}$
  2. 计算目标: \(y = r + \gamma \left( \min_{i \in \mathcal{Z}} Q_{\theta_i'}(s', \tilde{a}') \right) + \gamma \alpha \log \pi_\phi(\tilde{a}'|s') \text{(可选)}\)
  3. 更新 Q: \(\theta_i \leftarrow \theta_i - \eta \nabla_{\theta_i} \frac{1}{N} \sum (y - Q_{\theta_i}(s,a))^2\)
  4. 更新 Actor: \(\phi \leftarrow \phi + \eta \nabla_\phi \frac{1}{E} \sum_i Q_{\theta_i}(s, \tilde{a}) - \alpha \log \pi_\phi(\tilde{a}|s)\)
  5. 重复 $G$ 次 / 环境步

梯度推导

Critic的损失函数是均方贝尔曼误差(MSBE),对于第 $i$ 个Q网络:

\[L(\theta_i) = \mathbb{E}_{(s,a,r,s') \sim \mathcal{B}} \left[ \left( y - Q_{\theta_i}(s,a) \right)^2 \right]\]

其中目标值 $y$ 为:

\[y = r + \gamma \left( \min_{j \in \mathcal{Z}} Q_{\theta'_j}(s', \tilde{a}') \right), \quad \tilde{a}' \sim \pi_\phi(\cdot | s')\]

注意:$y$ 中的 Target Q 网络参数为 $\theta’$(通过EMA软更新),与当前更新的 $\theta_i$ 不是同一个网络。因此,在计算梯度时,$y$ 被视为常数(detached),不参与梯度反传。

对 $\theta_i$ 求梯度:

\(\nabla_{\theta_i} L(\theta_i) = \mathbb{E}_{(s,a,r,s') \sim \mathcal{B}} \left[ -2 \left( y - Q_{\theta_i}(s,a) \right) \cdot \nabla_{\theta_i} Q_{\theta_i}(s,a) \right]\) \(\boxed{\nabla_{\theta_i} L(\theta_i) = -2\mathbb{E}_{\mathcal{B}} \left[ \delta_i \cdot \nabla_{\theta_i} Q_{\theta_i}(s,a) \right]}\)

其中 TD误差(TD-error)

\(\boxed{\delta_i = y - Q_{\theta_i}(s,a)}\) 通过最小化TD误差,让预测Q值逐步逼近由Bellman方程给出的目标值。

# 假设已有 batch (s, a, r, s', done)
with torch.no_grad():
    # 1. 采样下一动作(来自当前策略)
    next_action, next_log_prob = actor(s_next)
    
    # 2. 计算目标值(使用 Target Q 网络)
    # 从集成中随机取 Z=2 个Q网络的最小值
    target_q = torch.min(target_q1(s_next, next_action), 
                         target_q2(s_next, next_action))
    target_q = r + gamma * (1 - done) * (target_q - alpha * next_log_prob)  # 如果启用熵项
    
# 3. 计算当前Q值
current_q = q_net(s, a)

# 4. TD误差
td_error = (target_q - current_q).detach()  # target_q已detach,这里只是展示

# 5. 损失(MSE)
loss = torch.nn.functional.mse_loss(current_q, target_q)

# 6. 反向传播
loss.backward()  # 梯度自动计算

Actor的目标是最大化期望Q值(同时保持熵奖励):

\[J(\phi) = \mathbb{E}_{s \sim \mathcal{B}} \left[ \frac{1}{E} \sum_{i=1}^{E} Q_{\theta_i}(s, \tilde{a}_\phi(s)) - \alpha \log \pi_\phi(\tilde{a}_\phi(s) | s) \right]\]

其中:

  • $\tilde{a}_\phi(s)$ 是通过重参数化技巧(Reparameterization Trick)采样得到的动作:
\[\tilde{a}_\phi(s) = f_\phi(\epsilon; s), \quad \epsilon \sim \mathcal{N}(0, I)\]
  • 这是SAC的核心技巧,使得期望对 $\phi$ 的梯度可以直接通过 $\tilde{a}_\phi$ 传递。

2.2 梯度公式(重参数化)

对 $\phi$ 求梯度:

\[\boxed{ \nabla_\phi J(\phi) = \mathbb{E}_{s \sim \mathcal{B}, \epsilon \sim \mathcal{N}} \left[ \nabla_a \left( \frac{1}{E} \sum_{i=1}^{E} Q_{\theta_i}(s, a) - \alpha \log \pi_\phi(a|s) \right) \Bigg|_{a = \tilde{a}_\phi(s)} \cdot \nabla_\phi \tilde{a}_\phi(s) \right] }\]

2.3 拆解为两项

来源 作用  
Q值梯度 $\nabla_a \frac{1}{E} \sum_{i=1}^{E} Q_{\theta_i}(s, a)$ 引导策略选择高价值的动作  
熵正则梯度 $- \alpha \nabla_a \log \pi_\phi(a s)$ 鼓励策略增加熵(探索)

合在一起:

\[\boxed{ \nabla_\phi J(\phi) = \mathbb{E}_{s, \epsilon} \left[ \underbrace{\nabla_a \bar{Q}(s,a)}_{\text{Exploit}} - \underbrace{\alpha \nabla_a \log \pi_\phi(a|s)}_{\text{Explore}} \Bigg|_{a=\tilde{a}_\phi(s)} \cdot \nabla_\phi \tilde{a}_\phi(s) \right] }\]

其中 $\bar{Q}(s,a) = \frac{1}{E} \sum_{i=1}^{E} Q_{\theta_i}(s,a)$ 是所有Q网络的均值


2.4 物理意义

  • 如果只看Q值梯度:策略会贪婪地选择当前认为最好的动作 → 容易陷入局部最优。
  • 加上熵梯度:策略会保留一定的随机性 → 继续探索可能更优的动作。
  • 使用均值而非最小值:给予策略更“乐观”的引导,避免被单个保守Q网络带偏。

2.5 工程实现(PyTorch伪代码)

# 1. 从当前策略采样动作(重参数化)
action, log_prob = actor.sample(s)  # 内部实现了 reparameterization

# 2. 计算所有Q网络的均值
q_mean = torch.mean(torch.stack([q_net(s, action) for q_net in q_nets]), dim=0)

# 3. Actor目标(最大化 Q - alpha * log_prob)
actor_loss = -torch.mean(q_mean - alpha * log_prob)

# 4. 反向传播
actor_loss.backward()  # 梯度自动通过 action 传递到 actor 参数

三、一个容易被忽视的梯度细节:梯度截断(Gradient Clipping)

在实际实现中(尤其是高UTD=20时),为了避免梯度爆炸,RLPD通常会:

  • 对Critic的梯度进行裁剪(如 grad_norm_clip = 0.5),防止单个batch的异常TD误差导致网络参数剧烈变化。
  • 对Actor的梯度进行裁剪,因为Q值对动作的梯度 $\nabla_a \bar{Q}$ 可能很大(尤其是刚加上LayerNorm时)。

论文中虽未重点强调,但开源代码中包含了这一工程技巧。


四、总结:Actor和Critic梯度的对比

维度 Critic 梯度 Actor 梯度
优化目标 最小化 MSBE 最大化 Q值 + 熵
梯度来源 直接对参数 $\theta_i$ 求导 通过重参数化的 $a$ 传递
需要 Target Network ✅ 是(计算 $y$ 时用) ❌ 否
使用哪个Q值 Min(悲观,防过估计) Mean(乐观,促探索)
梯度方向 缩小 $\delta = y - Q$ 增大 $Q - \alpha \log \pi$
影响分布 拟合 Bellman 目标 移动策略分布向高Q区域

五、直观类比

  • Critic梯度:像一个学徒,老师(Target Network)告诉它正确答案($y$),它计算误差并修正自己($\delta$),逐步逼近真实价值。
  • Actor梯度:像一个探险家,询问一群专家(Q集成)哪条路好走(均值),然后朝着建议的方向迈一步($\nabla_\phi \tilde{a}$),同时保持一点随机性(熵项)以防迷路。

SAPG

On policy RL for higher performance with larger batch size

更新时间: