Shortcuts

SQN

概述

软Q学习是许多先前工作的扩展,包括: 利用平均值:强化学习中KL正则化的分析,软演员-评论家算法及其应用,策略梯度和软Q学习之间的等价性等。它是一种离策略Q学习算法,但采用了最大熵框架,建立了策略梯度和Q学习之间的联系。

快速事实

  1. SQN 是为具有离散动作空间的环境实现的。(例如,Atari,围棋)

  2. SQN 是一种离策略无模型的算法,并使用 Boltzmann 策略进行探索。

  3. SQN 基于 Q-learning 算法,该算法优化了 Q 函数并从 Q 函数构建策略

  4. SQN 也适用于 多离散 动作空间

关键方程或关键图表

一个熵正则化的RL目标版本可能会导致更好的探索和稳定性。定义熵增强回报的最一般方式是

\[\sum_{t=0}^{\infty} \gamma^{t}\left(r_{t}-\tau H_{t}\right),\]

\(\bar{\pi}\) 是某个“参考”策略, \(\tau\) 是一个“温度”参数,而 \(H\) 是Kullback-Leibler散度。注意,温度 \(\tau\) 可以通过重新缩放奖励来消除。因此,Q函数的定义变为:

\[Q^{\pi}(s, a)=\mathbb{E}\left[r_{0}+\sum_{t=1}^{\infty} \gamma^{t}\left(r_{t}-\tau \mathrm{KL}_{t}\right) \mid s_{0}=s, a_{0}=a\right]\]

此外,通过将动作概率作为估计值的分级函数变化,可以推导出一种称为Boltzmann-Policy的最优策略:

\[\begin{split}\begin{aligned} \pi^Q(\cdot \mid s) % &=\underset{\pi}{\arg \max }\left\{\mathbb{E}_{a \sim \pi}[Q(s, a)]-\tau D_{\mathrm{KL}}[\pi \| \bar{\pi}](s)\right\} \\ &=\frac{\bar{\pi}(a \mid s) \exp (Q(s, a) / \tau)}{\underbrace{\mathbb{E}_{a^{\prime} \sim \bar{\pi}}\left[\exp \left(Q\left(s, a^{\prime}\right) / \tau\right)\right]}_{\text {normalizing constant }}} \end{aligned}\end{split}\]

一般来说,我们可以使用一个均匀的 $bar{pi} \sim U$,所以 $r_t - \tau \mathrm{KL}_t = r_t + \mathcal{H} - \log{mathcal{N}}$。因此,最优策略还旨在在每个访问的状态下最大化其熵,TD目标变为:

\[y_t = r + \gamma\left[Q_{\bar{\theta}}\left(\mathbf{s}', \mathbf{a}'\right)-\tau \log \pi_{\phi}\left(\mathbf{a}' \mid \mathbf{s}')\right]\right.\]

伪代码

../_images/sqn.png
\begin{algorithm}[tp]
\setstretch{1.35}
\DontPrintSemicolon
\SetAlgoLined
\SetKwInOut{Input}{Input}\SetKwInOut{Output}{Output}
\Input{Initial Q functions parameters $\Theta$ \\
        Temperature $\tau$ \\
        Empty replay buffer $\mathcal{D}$ \\
}

\textbf{Initialize: }
        $\overline{\theta^i}_1 \leftarrow {\theta^i}_1$, $\overline{\theta^i}_2 \leftarrow {\theta^i}_2$

\While(Train){not converge}{


        % \tcc{comments on code}
        \For(Collect){each environment step}{
                $a_t \sim \pi^{Q}(a_t|s_t)$ \\
                $s_{t+1} \sim p(s_{t+1}|s_t, a_t)$ \\
                $\mathcal{D} \cup \{(s_t, a_t, r_t, s_{t+1}, d\}$
                }

        \For(Update){each gradient step}{
        $\{(s, a, r, s^\prime, d)\}^B_{i=1} \sim \mathcal{D}$

        Compute Q-loss $\mathcal{L}_Q(\theta)$


        $\theta \leftarrow \theta - \lambda_{\theta} \bigtriangledown_{\theta} \mathcal{L}_Q(\theta)$

        Compute temperature loss $\mathcal{L}(\tau)$

        $\tau \leftarrow \tau - \lambda_{\tau} \bigtriangledown_{\tau} \mathcal{L}(\tau)$

        % Update target network\\
        Update Target: \\
        $\overline{\theta}_j \leftarrow \rho {\overline{\theta}}_j + (1-\rho) {\theta}_j, \ \ \text{for} \ j \in \{1,2\}$
        }
}
\caption{SQN Algorithm}
\end{algorithm}

扩展

SQN 可以与以下内容结合使用:

  • SQN 可以使用一个单独的策略网络,称为 SAC-Discrete

  • SQN 与一般的正则化强化学习密切相关,后者可能有许多形式,但我们的实现利用了自动调整温度并移除了许多不明确的部分 Leverage the Average

  • SQN 使用 Boltzmann 策略从 Q 函数构建策略,尽管它被称为 softmax 策略。

  • 一些分析师将软Q学习与策略梯度算法(如策略梯度与软Q学习的等价性)联系起来。

  • 最近的一些研究将强化学习(RL)视为概率推断问题,例如MPOVMPO,它们与SQN、SAC和最大熵框架有密切关系,这是一个活跃的研究领域。

实现

软Q损失

# Target
with torch.no_grad():
      q0_targ = target_q_value[0]
      q1_targ = target_q_value[1]
      q_targ = torch.min(q0_targ, q1_targ)
      # discrete policy
      alpha = torch.exp(self._log_alpha.clone())
      # TODO use q_targ or q0 for pi
      log_pi = F.log_softmax(q_targ / alpha, dim=-1)
      pi = torch.exp(log_pi)
      # v = \sum_a \pi(a | s) (Q(s, a) - \alpha \log(\pi(a|s)))
      target_v_value = (pi * (q_targ - alpha * log_pi)).sum(axis=-1)
      # q = r + \gamma v
      q_backup = reward + (1 - done) * self._gamma * target_v_value
      # alpha_loss
      entropy = (-pi * log_pi).sum(axis=-1)
      expect_entropy = (pi * self._target_entropy).sum(axis=-1)

# Q loss
q0_loss = F.mse_loss(q0_a, q_backup)
q1_loss = F.mse_loss(q1_a, q_backup)
total_q_loss = q0_loss + q1_loss

从策略中采样

logits = output['logit'] / math.exp(self._log_alpha.item())
prob = torch.softmax(logits - logits.max(axis=-1, keepdim=True).values, dim=-1)
pi_action = torch.multinomial(prob, 1)

阿尔法损失

alpha_loss = self._log_alpha * (entropy - expect_entropy).mean()

其他公共实现

DRL