从马尔可夫决策到 DQN 算法族(下)

175 阅读2分钟

0 全文目录

3.DQN 算法

  在之前的 Q-learning 算法中,我们以矩阵的方式建立了一张存储每个状态下所有动作 QQ 值的表格。表格中的每一个动作价值 Q(s,a)Q(s,a) 表示在状态 ss 下选择动作 aa 然后继续遵循某一策略预期能够得到的期望回报。然而,这种用表格存储动作价值的做法只在环境的状态和动作都是离散的,并且空间都比较小的情况下适用,我们之前进行代码实战的几个环境都是如此 (如悬崖漫步)。当状态或者动作数量非常大的时候,这种做法就不适用了。例如,当输入是高维向量时 (比如一张RGB 图像时,假设图像大小是 224×224×3224\times224\times3,此时一共有 256(224×224×3)256^{(224\times224\times3)} 种状态)。另外一种例子则是,当状态或者动作连续的时候,会存在无限个状态动作对,这都是先前的方法很难解决的。

  对于这种情况,我们需要用函数拟合的方法来估计 QQ 值,即将这个复杂的值表格视作数据,使用一个参数化的函数来拟合这些数据。很显然,这种函数拟合的方法存在一定的精度损失,因此被称为近似方法。

3.1 在 CartPole 环境中的 DQN 方法初探

  Cartpole 强化学习环境是一个简单的物理仿真环境,由竖直放置的杆和水平移动的小车组成。目标是通过控制小车的左右移动,使杆保持竖直不倒。环境的状态由 4 个连续值表示 (见下表),智能体可以选择向左或向右施加力,(使用 0 表示向左移动小车,用 1 表示向右移动小车)。实验中,常用的评估指标包括杆的持续时间和奖励累积。

维度意义最小值最大值
0小车位置2.4-2.42.42.4
1小车速度-\infty\infty
2杆子角度41.8\sim-41.8^{\circ}41.8\sim41.8^{\circ}
3杆尖端的速度-\infty\infty

表 1. CartPole 环境的状态空间

  考虑到需要用函数拟合 (function approximation) 的方法来估计 QQ 值,一个很自然的想法就是借助于神经网络来进行拟合。因此我们可以用一个神经网络来表示函数 QQ

  • 若动作是连续 (无限) 的,神经网络的输入是状态 ss 和动作 aa,然后输出一个标量,表示在状态 ss 下采取动作 aa 能获得的价值。
  • 若动作是离散 (有限) 的,除了可以采取动作连续情况下的做法,我们还可以只将状态 ss 输入到神经网络中,使其同时输出每一个动作的 QQ 值。

通常 DQN (以及 Q-learning) 只能处理动作离散的情况,因为在函数 QQ 的更新过程中有 maxa\max_a 这一操作。设神经网络用来拟合函数的参数是 ww,即每一个状态 ss 下所有可能动作 aaQQ 值我们都能表示为 Qw(s,a)Q_w(s,a)。我们将用于拟合 QQ函数的神经网络称为 Q 网络,如下图所示。

  回顾之前的 Q-learning 的更新规则 :

Q(s,a)Q(s,a)+α[r+γmaxaAQ(s,a)Q(s,a)]Q(s, a) \leftarrow Q(s, a)+\alpha\left[r+\gamma \max _{a^{\prime} \in \mathcal{A}} Q\left(s^{\prime}, a^{\prime}\right)-Q(s, a)\right]

  上述公式用时序差分 (temporal difference,TD) 学习目标 r+γmaxaAQ(s,a)r+\gamma \max _{a^{\prime} \in \mathcal{A}} Q\left(s^{\prime}, a^{\prime}\right) 来增量式更新 Q(s,a)Q(s, a) ,也就是说要使 Q(s,a)Q(s, a) 和时序差分目标 r+γmaxaAQ(s,a)r+\gamma \max _{a^{\prime} \in \mathcal{A}} Q\left(s^{\prime}, a^{\prime}\right) 靠 近。于是,对于一组数据 {(si,ai,ri,si)}\left\{\left(s_i, a_i, r_i, s_i^{\prime}\right)\right\} ,我们可以很自然地将 Q\mathrm{Q} 网络的损失函数构造为均方误差的形式 :

ω=argminω12Ni=1N[Qω(si,ai)(ri+γmaxaQω(si,a))]2\omega^*=\arg \min _\omega \frac{1}{2 N} \sum_{i=1}^N\left[Q_\omega\left(s_i, a_i\right)-\left(r_i+\gamma \max _{a^{\prime}} Q_\omega\left(s_i^{\prime}, a^{\prime}\right)\right)\right]^2

  至此,我们就可以将 Q-learning 扩展到神经网络形式——深度 Q 网络(deep Q network,DQN)算法。由于 DQN 是离线策略算法,因此我们在收集数据的时候可以使用一个 ϵ\epsilon-贪婪策略来平衡探索与利用,将收集到的数据存储起来,在后续的训练中使用。DQN 中还有两个非常重要的模块——经验回放目标网络,它们能够帮助 DQN 取得稳定、出色的性能。

3.2 经验回放

  在有监督学习中,我们通常假设训练数据独立同分布。然而,在原始的 Q-learning 算法中,每个数据仅用于一次更新 QQ 值。为了更好地结合 Q-learning 和深度神经网络,DQN 算法引入了经验回放。它维护一个回放缓冲区,将采样的四元组数据 (状态、动作、奖励、下一状态) 存储在其中。在训练 Q 网络时,从回放缓冲区中随机采样数据进行训练。这样做有两个作用。

  1. 使样本满足独立假设 : 在 MDP 中交互采样得到的数据本身不满足独立假设,因为这一时刻的状态和上一时刻的状态有关。非独立同分布的数据对训练神经网络有很大的影响,会使神经网络拟合到最近训练的数据上。采用经验回放可以打破样本之间的相关性,让其满足独立假设。
  2. 提高样本效率 : 每一个样本可以被使用多次,十分适合深度神经网络的梯度学习。

3.3 目标网络

  DQN 算法最终更新的目标是让 Qω(s,a)Q_\omega(s, a) 逼近 r+γmaxaQω(s,a)r+\gamma \max _{a^{\prime}} Q_\omega\left(s^{\prime}, a^{\prime}\right) ,由于时序差分的误差 目标本身就包含神经网络的输出,因此在更新网络参数的同时目标也在不断地改变,这非常容易造成神经网络训练的不稳定性。为了解决这一问题,DQN 便使用了目标网络 (target network) 的思想 : 既然训练过程中 QQ 网络的不断更新会导致目标不断发生改变,不如暂时先将时序差分目标中的 QQ 网络固定住。为了实现这一思想,我们需要利用两套 QQ 网络 :

  1. 原来的训练网络 Qω(s,a)Q_\omega(s, a),用于计算原来的损失函数 12[Qω(s,a)(r+γmaxaQω(s,a))]2\frac{1}{2}\left[Q_\omega(s, a)-\left(r+\gamma \max _{a^{\prime}} Q_{\omega^{-}}\left(s^{\prime}, a^{\prime}\right)\right)\right]^2 中的 Qω(s,a)Q_\omega(s, a) 项,并且使用正常梯度下降方法来进行更新。

  2. 目标网络 Qω(s,a)Q_{\omega^{-}}(s, a),用于计算原先损失函数 12[Qω(s,a)(r+γmaxaQω(s,a))]2\frac{1}{2}\left[Q_\omega(s, a)-\left(r+\gamma \max _{a^{\prime}} Q_{\omega^{-}}\left(s^{\prime}, a^{\prime}\right)\right)\right]^2 中的 (r+γmaxaQω(s,a))\left(r+\gamma \max _{a^{\prime}} Q_{\omega^{-}}\left(s^{\prime}, a^{\prime}\right)\right) 项,其中 ω\omega^{-} 表示目标网络中的参数。如果两套网络的参数随时保持一致,则仍为原先不够稳定的算法。为了让更新目标更稳定,目标网络并不会每一步都更新。具体而言,目标网络使用训练网络的一套较旧的参数,训练网络 Qω(s,a)Q_\omega(s, a) 在训练中的每一步都会更新,而目标网络的参数每隔 CC 步才会与训练网络同步一次,即 ωω\omega^{-} \leftarrow \omega 。这样做使得目标网络相对于训练网络更加稳定。

  可以大致理解为目标网络保持较低的更新频率来进行更新 (因为这样对于理论上的精度的影响应该不会很大,同时也能规避同时更新导致的问题)。

3.4 整体算法流程

  • 用随机的网络参数 ω\omega 初始化网络 Qω(s,a)Q_\omega(s, a)
  • 复制相同的参数 ωω\omega^{-} \leftarrow \omega 来初始化目标网络 QωQ_{\omega^{\prime}}
  • 初始化经验回放池 RR
  • for 序列 e=1Ee=1 \rightarrow E do
    • 获取环境初始状态 s1s_1
    • for 时间步 t=1Tt=1 \rightarrow T do
      • 根据当前网络 Qω(s,a)Q_\omega(s, a)ϵ\epsilon-贪婪策略选择动作 ata_t
      • 执行动作 ata_t ,获得回报 rtr_t ,环境状态变为 st+1s_{t+1}
      • (st,at,rt,st+1)\left(s_t, a_t, r_t, s_{t+1}\right) 存储进回放池 RR
      • RR 中数据足够,从 RR 中采样 NN 个数据 {(si,ai,ri,si+1)}i=1,,N\left\{\left(s_i, a_i, r_i, s_{i+1}\right)\right\}_{i=1, \ldots, N}
      • 对每个数据,用目标网络计算 yi=ri+γmaxaQω(si+1,a)y_i=r_i+\gamma \max _a Q_{\omega^{-}}\left(s_{i+1}, a\right)
      • 最小化目标损失 L=1Ni(yiQω(si,ai))2L=\frac{1}{N} \sum_i\left(y_i-Q_\omega\left(s_i, a_i\right)\right)^2 ,以此更新当前网络 QωQ_\omega
      • 更新目标网络
    • end for
  • end for

4.DQN 算法族

4.1 Double DQN 算法

  普通的 DQN 算法通常会导致对值的过高估计 (overestimation)。传统 DQN 优化的时序差分误差目标为 :

r+γmaxaQω(s,a)r+\gamma \max _{a^{\prime}} Q_{\omega^{-}}\left(s^{\prime}, a^{\prime}\right)

  其中 maxaQω(s,a)\max _{a^{\prime}} Q_{\omega^{-}}\left(s^{\prime}, a^{\prime}\right) 由目标网络 (参数为 ω\omega^{-}) 计算得出,我们还可以将其写成如下形式 :

Qω(s,argmaxaQω(s,a))Q_{\omega^{-}}\left(s^{\prime}, \arg \max _{a^{\prime}} Q_{\omega^{-}}\left(s^{\prime}, a^{\prime}\right)\right)

  由此,max 操作实际可以被拆解为两部分 : 首先选取状态 ss^{\prime} 下的最优动作 a=argmaxaQω(s,a)a^*=\arg \max _{a^{\prime}} Q_{\omega^{-}}\left(s^{\prime}, a^{\prime}\right) ,然后计算该动作对应的价值 Qω(s,a)Q_{\omega^{-}}\left(s^{\prime}, a^*\right) 。当这两部分采用同一套 QQ 网络进行计算时,每次得到的都是神经网络当前估算的所有动作价值中的最大值。考虑到通过神经网络估算的 QQ 值本身在某些时候会产生正向或负向的误差,在 DQN 的更新方式下神经网络会将正向误差累积。

  考虑一个特殊情形 : 在状态 ss^{\prime} 下所有动作的 QQ 值均为 0 ,即 Q(s,ai)=0,iQ\left(s^{\prime}, a_i\right)=0, \forall i,此时正确的更新目标应 为 r=r+0r=r+0,但是由于神经网络拟合的误差通常会出现某些动作的估算有正误差的情况,即存在某个动作 aa^{\prime}Q(s,a)>0Q\left(s^{\prime}, a^{\prime}\right)>0 ,此时我们的更新目标出现了过高估计, r+γmaxQ>r+0r+\gamma \max Q>r+0。因此,当我们用 DQN 的更新公式进行更新时, Q(s,a)Q(s, a) 也就会被过高估计了。同理,我们拿这个 Q(s,a)Q(s, a) 来作为更新目标来更新上一步的 QQ 值时,同样会过高估计,这样的误差将会逐步累积。对于动作空间较大的任务,DQN 中的过高估计问题会非常严重,造成 DQN 无法有效工作的后果。

  为了解决这个问题,借助于上面的等效形式,Double DQN 算法提出利用两个独立训练的神经网络估算 maxaQ(s,a)\max _{a^{\prime}} Q_*\left(s^{\prime}, a^{\prime}\right)。即 :

maxaQω(s,a)Qω(s,argmaxaQω(s,a))\max _{a^{\prime}} Q_{\omega^{-}}\left(s^{\prime}, a^{\prime}\right)\Rightarrow Q_{\omega^{-}}\left(s^{\prime}, \arg \max _{a^{\prime}} Q_\omega\left(s^{\prime}, a^{\prime}\right)\right)

利用一套神经网络 QωQ_\omega 的输出选取价值最大的动作,但在使用该动作的价值时,用另一套神经网络 QωQ_\omega^{-} 计算该动作的价值。这样,即使其中一套神经网络的某个动作存在比较严重的过高估计问题,由于另一套神经网络的存在,这个动作最终使用的 QQ 值不会存在很大的过高估计问题。

  与上面类似的,我们给出 double DQN 对应的伪代码。


  • 用随机的网络参数 ω\omega 初始化网络 Qω(s,a)Q_\omega(s, a) 和目标网络 Qω(s,a)Q_{\omega^{-}}(s, a)
  • 初始化经验回放池 RR
  • for 序列 e=1Ee=1 \rightarrow E do
    • 获取环境初始状态 s1s_1
    • for 时间步 t=1Tt=1 \rightarrow T do
      • 根据当前网络 Qω(s,a)Q_\omega(s, a)ϵ\epsilon-贪婪策略选择动作 ata_t
      • 执行动作 ata_t,获得回报 rtr_t,环境状态变为 st+1s_{t+1}
      • (st,at,rt,st+1)\left(s_t, a_t, r_t, s_{t+1}\right) 存储进回放池 RR
      • RR 中数据足够,从 RR 中采样 NN 个数据 {(si,ai,ri,si+1)}i=1,,N\left\{\left(s_i, a_i, r_i, s_{i+1}\right)\right\}_{i=1, \ldots, N}
      • 对每个数据,用当前网络计算下一状态的最优动作 a=argmaxaQω(si+1,a)a^*=\arg \max_{a'} Q_{\omega}\left(s_{i+1}, a'\right)
      • 使用目标网络计算目标值 yi=ri+γQω(si+1,a)y_i=r_i+\gamma Q_{\omega^{-}}\left(s_{i+1}, a^*\right) 最小化目标损失 L=1Ni(yiQω(si,ai))2L=\frac{1}{N} \sum_i\left(y_i-Q_\omega\left(s_i, a_i\right)\right)^2,以此更新当前网络 QωQ_\omega
      • if 当前时间步是更新目标网络的时间步 then
        • 更新目标网络参数 ωω\omega^{-} \leftarrow \omega
      • end if
    • end for
  • end for

4.2 Dueling DQN 算法

  Dueling DQN 是 DQN 另一种的改进算法 : 将状态动作价值函数 QQ 减去状态价值函数 VV 的结果定义为优势函数 AA ,即 A(s,a)=Q(s,a)V(s)A(s, a)=Q(s, a)-V(s) 。在同一状态下,所有动作的优势值之和为 0,因为所有动作的动作价值的期望就是这个状态的状态价值。因此,在 Dueling DQN 中,Q 网络被建模为 :

Qη,α,β(s,a)=Vη,α(s)+Aη,β(s,a)Q_{\eta, \alpha, \beta}(s, a)=V_{\eta, \alpha}(s)+A_{\eta, \beta}(s, a)

  其中,Vη,α(s)V_{\eta, \alpha}(s) 为状态价值函数,而 Aη,β(s,a)A_{\eta, \beta}(s, a) 则为该状态下采取不同动作的优势函数,表示采取不同动作的差异性; η\eta 是状态价值函数和优势函数共享的网络参数,一 般用在神经网络中,用来提取特征的前几层; 而 α\alphaβ\beta 分别为状态价值函数和优势函数的参数。在这样的模型下,我们不再让神经网络直接输出 QQ 值,而是训练神经网络的最后几层的两个分支,分别输出状态价值函数和优势函数,再求和得到 QQ 值。Dueling DQN 的网络结构如下图所示。

  将状态价值函数和优势函数分别建模的好处在于 : 某些情境下智能体只会关注状态的价值,而并不关心不同动作导致的差异,此时将二者分开建模能够使智能体更好地处理与动作关联较小的状态。在下图所示的驾驶车辆游戏中,智能体注意力集中的部位被显示为橙色,当智能体前面没有车时,车辆自身动作并没有太大差异,此时智能体更关注状态价值,而当智能体前面有车时 (智能体需要超车),智能体开始关注不同动作优势值的差异。

  对于 Dueling DQN 中的公式 Qη,α,β(s,a)=Vη,α(s)+Aη,β(s,a)Q_{\eta, \alpha, \beta}(s, a)=V_{\eta, \alpha}(s)+A_{\eta, \beta}(s, a),它存在对于 VV 值和 AA 值建模不唯一性的问题。例如,对于同样的 QQ 值,如果将 VV 值加上任意大小的常数 CC ,再将所有 AA 值减去 CC ,则得到的 QQ 值依然不变,这就导致了训练的不稳定性。为了解决这一问题,Dueling DQN 强制最优动作的优势函数的实际输出为 0 ,即 :

Qη,α,β(s,a)=Vη,α(s)+Aη,β(s,a)maxaAη,β(s,a)Q_{\eta, \alpha, \beta}(s, a)=V_{\eta, \alpha}(s)+A_{\eta, \beta}(s, a)-\max _{a^{\prime}} A_{\eta, \beta}\left(s, a^{\prime}\right)

  此时 V(s)=maxaQ(s,a)V(s)=\max _a Q(s, a),可以确保 VV 值建模的唯一性。在实现过程中,我们还可 以用平均代替最大化操作,即 :

Qη,α,β(s,a)=Vη,α(s)+Aη,β(s,a)1AaAη,β(s,a)Q_{\eta, \alpha, \beta}(s, a)=V_{\eta, \alpha}(s)+A_{\eta, \beta}(s, a)-\frac{1}{|\mathcal{A}|} \sum_{a^{\prime}} A_{\eta, \beta}\left(s, a^{\prime}\right)

  此时 V(s)=1AaQ(s,a)V(s)=\frac{1}{|\mathcal{A}|} \sum_{a^{\prime}} Q\left(s, a^{\prime}\right)。虽然此时不再满足贝尔曼最优方程,但实际应用时更加稳定。

  相比较于 DQN, Dueling DQN 更好的部分原因在于其能更高效学习状态价值函数。每一次更新时,函数 VV 都会被更新,这也会影响到其他动作的 QQ 值。而传统的 DQN 只会更新某个动作的 QQ 值,其他动作的 QQ 值就不会更新。因此,Dueling DQN 能够更加频繁、准确地学习状态价值函数。


  • 用随机的网络参数 ω\omega 初始化网络 Qω(s,a)Q_\omega(s, a) 和目标网络 Qω(s,a)Q_{\omega^{-}}(s, a)
  • 复制相同的参数 ωω\omega^{-} \leftarrow \omega 来初始化目标网络 QωQ_{\omega^{-}}
  • 初始化经验回放池 RR
  • for 序列e =1E=1 \rightarrow E do
    • 获取环境初始状态 s1s_1
    • for 时间步 t=1Tt=1 \rightarrow T do
      • 根据当前网络 Qω(s,a)Q_\omega(s, a)ϵ\epsilon-贪婪策略选择动作 ata_t
      • 执行动作 ata_t,获得回报 rtr_t,环境状态变为 st+1s_{t+1}
      • (st,at,rt,st+1)\left(s_t, a_t, r_t, s_{t+1}\right) 存储进回放池 RR
      • RR 中数据足够,从 RR 中采样 NN 个数据 {(si,ai,ri,si+1)}i=1,,N\left\{\left(s_i, a_i, r_i, s_{i+1}\right)\right\}_{i=1, \ldots, N}
      • 对每个数据,用目标网络计算下一状态的动作值 Qω(si+1,a)Q_{\omega^{-}}(s_{i+1}, a)
      • 对每个数据,用当前网络计算状态值 Vω(si)V_{\omega}(s_i)
      • 使用状态值和动作值计算优势函数 Aω(si,ai)=Qω(si,ai)Vω(si)A_{\omega}(s_i, a_i) = Q_{\omega}(s_i, a_i) - V_{\omega}(s_i)
      • 使用优势函数和状态值计算Q值 Qduel(si,ai)=Vω(si)+Aω(si,ai)Q_{\text{duel}}(s_i, a_i) = V_{\omega}(s_i) + A_{\omega}(s_i, a_i)
      • 使用Q值计算目标值 yi=ri+γmaxaQduel(si+1,a)y_i = r_i + \gamma \max_a Q_{\text{duel}}(s_{i+1}, a)
      • 最小化目标损失 L=1Ni(yiQω(si,ai))2L=\frac{1}{N} \sum_i(y_i - Q_{\omega}(s_i, a_i))^2,以此更新当前网络 QωQ_{\omega}
      • if 当前时间步是更新目标网络的时间步 then
        • 更新目标网络参数 ωω\omega^{-} \leftarrow \omega
      • end if
    • end for
  • end for

4.3 Rainbow DQN 算法

4.3.1 Rainbow DQN 算法的组成

  Rainbow DQN 算法是 DQN 算法的一个集成算法,它将 DQN 算法中的多种改进方法进行了组合,包括了以下的几种方法 :

  • Double DQN
  • Prioritized experience replay
  • Dueling network architecture
  • Multi-step bootstrap
  • Distributional DQN
  • Noisy DQN

4.3.2 Prioritized experience replay

  当涉及到经验回放时,一种改进的方法是使用优先经验回放 (Prioritized Experience Replay)。这个方法的目标是增强对重要经验的学习,以提高强化学习算法的效率和性能。

  优先经验回放的关键思想是根据经验的重要性来进行采样。在之前的经验回放中,每个经验都以相同的概率被采样,但实际上,一些经验可能对算法的学习更加重要。优先经验回放通过引入优先级来量化经验的重要性,并根据优先级进行采样。 (又是重加权)

   假设有 N 个样本,每个样本的优先级为 pip_i,则每个样本被采样的概率为 :

P(i)=piαkpkαP(i)=\frac{p_i^{\alpha}}{\sum_k p_k^{\alpha}}

  其中,α\alpha 是一个超参数,控制优先级对采样概率的影响。较大的 α\alpha 值会增加优先级较高的经验被采样的概率。

5.Actor-Critic 算法

  Actor-Critic 分为两个部分 : Actor (策略网络) 和 Critic (价值网络),如下图所示。(这不就是对抗神经网络那一套吗)

  • Actor 要做的是与环境交互,并在 Critic 价值函数的指导下用策略梯度学习一个更好的策略。
  • Critic 要做的是通过 Actor 与环境交互收集的数据学习一个价值函数,这个价值函数会用于判断在当前状态什么动作是好的,什么动作不是好的,进而帮助 Actor 进行策略更新。

参考资料 (References)