浅尝辄止

理论是灰色的,而生命之树常青。这里是@Dilettante258 的个人博客,用于记载和分享学习。

强化学习进阶-Actor-Critic算法

Dilettante258's avatar
| 0 views

主要参考:动手学强化学习

原理

策略梯度算法是一种基于策略的替代方法,以替代基于价值的系列方法。Actor-Critic算法是是普通策略梯度方法的另一种扩展,它大幅提高了该方法的稳定性和收敛速度。1

在 REINFORCE 算法中,每次需要根据一个策略采集一条完整的轨迹,并计算这条轨迹上的回报。这种采样方式的方差比较大,学习效率也比较低。

Actor-Critic算法既学习价值函数,又学习策略函数。但是Actor-Critic 算法本质上是基于策略的算法,因为这一系列算法的目标都是优化一个带参数的策略,只是会额外学习价值函数,从而帮助策略函数更好地学习。

提升策略梯度方法稳定性的一种方法是减小梯度的方差。减小梯度的方差。在统计学中,方差是随机变量与该变量的期望值之间的偏差的平方的期望。方差表示某值与平均值之间的距离。1

在强化学习中,尤其是策略梯度方法中,我们经常使用奖励信号来更新策略。用数学符号表示策略梯度,可以写为JE[Q(s,a)logπ(as)]\nabla J\approx\mathbb{E}[Q(s,a)\nabla\log\pi(a\mid s)]。策略梯度的思想是增加良好动作的执行概率,并减少不良动作的执行概率。

但这些奖励信号可能会有很大的方差,导致学习过程不稳定。为了解决这个问题,我们可以引入一个基线(baseline)来减少奖励信号的方差,而不改变期望值。

t=tTγttrtb(st)\sum_{t^{\prime}=t}^T\gamma^{t^{\prime}-t}r_t-b(s_t)是一个最基础的示例,引入基线函数(baseline function)来减小方差。

而基线的一个常见选择是状态值函数 V(s),同时估计一个动作价值函数Q。当我们选择使用 V(s) 作为基线时,我们实际上是考虑了相对于平均的奖励,这称为优势函数(advantage function):A(s,a)=Q(s,a)V(s)A(s,a)=Q(s,a)-V(s),其中Q(s,a) 是动作值函数。2

为什么引入基线可以减小方差呢?

  1. 中心化奖励:基线的引入相当于对奖励信号进行中心化。中心化的数据通常具有较低的方差。这是因为,相对于基线的奖励(或优势)会更加集中,而不是分散在一个很大的范围内。
  2. 无偏估计:尽管我们从奖励中减去了基线,但策略梯度的期望仍然保持不变。这意味着我们没有引入任何偏差,只是减少了方差。
  3. 更好的信号:通过减去基线,我们实际上得到了一个更好的学习信号。如果一个动作的预期奖励高于基线,那么这个动作是好的,应该被增强;反之,如果一个动作的预期奖励低于基线,那么这个动作是差的,应该被抑制。
  4. 适应性:在实际应用中,基线可以是任何函数,只要它不依赖于动作。这意味着我们可以使用适应性方法来估计和更新基线,使其更接近真实的状态值函数,从而进一步减少方差。2

但是如果这么实现的话,就要估计 2 个网络:Q-network 和 V-network,估测不准的风险就变成两倍。

事实上在这个 Actor-Critic 方法里面。可以只估测状态值函数V(s),然后用 V(s) 的值来表示 **动作值函数Q(s,a)**的值。3

Q=r+γVQ=r+\gamma V可得到时序差分残差

ψt=rt+γVπ(st+1)Vπ(st)\psi_t=r_t+\gamma V^\pi(s_{t+1})-V^\pi(s_t)

Actor-Critic 有两个部分:Actor(策略网络)和 Critic(价值网络)。

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

借助于值函数,演员-评论家算法可以进行单步更新参数,不需要等到回合结束才进行更新。

具体方法

基础的 Actor-Critic 算法比较简单,可以看作是在 Policy Gradient 上的延伸,加入了一个 Critic 网络去输出 Q value,而这个 Q value 就可以直接用于计算 Actor 的损失函数。而 Critic 本身更新方式也比较简单,直接用 next state 的 Q 值 去估算 Q target,然后计算 TD error 作为损失函数。

Actor 的更新采用策略梯度的原则,那 Critic 如何更新呢?我们将 Critic 价值网络表示为VωV_ω,参数为ω。于是,我们可以采取时序差分残差的学习方式,对于单个数据定义如下价值函数的损失函数(即F.mse_loss):

L(ω)=12(r+γVω(st+1)Vω(st))2\mathcal{L}(\omega)=\frac12(r+\gamma V_\omega(s_{t+1})-V_\omega(s_t))^2

与 DQN 中一样,我们采取类似于目标网络的方法,将上式中r+γVω(st+1)r+\gamma V_{\omega}(s_{t+1}) 作为时序差分目标,不会产生梯度来更新价值函数。因此,价值函数的梯度为:

ωL(ω)=(r+γVω(st+1)Vω(st))ωVω(st)\nabla_{\omega}\mathcal{L}(\omega)=-(r+\gamma V_{\omega}(s_{t+1})-V_{\omega}(s_{t}))\nabla_{\omega}V_{\omega}(s_{t})

然后使用梯度下降方法来更新 Critic 价值网络参数即可。但是实际上并不需要关心这么多,只需要利用PyTorch的自动微分就好了。

image-20231022182436656

Footnotes

  1. Maxim Lapan 2

  2. https://chat.openai.com/ 2

  3. https://blog.csdn.net/weixin_42301220/article/details/123311478