演员-评论家(Actor-Critic)算法详解与实现
演员-评论家(Actor-Critic)算法详解与实现
- 0. 前言
- 1. 演员-评论家算法
- 2. 算法流程
- 3. 使用 Keras 实现 Actor-Critic
0. 前言
在带基线的 REINFORCE 方法中,价值函数仅作为基准使用,并未直接参与价值函数的训练。本节介绍一种带基线 REINFORCE 的变体——演员-评论家 (Actor-Critic) 方法。策略网络与价值网络分别扮演演员和评论家的角色:策略网络作为演员,根据状态决定采取何种动作;而价值网络则作为评论家,评估演员(即策略网络)所做决策的优劣。
1. 演员-评论家算法
在演员-评论家算法中,价值网络通过比较当前状态价值 V(s,θv)V(s,\theta_v)V(s,θv) 与实际获得的奖励 rrr 加上观察到的下一状态折扣价值 γV(s′,θv)\gamma V(s',\theta_v)γV(s′,θv) 之间的差异来量化演员所选动作的好坏程度。该差异值 δ\deltaδ 的计算公式为:
δ=rt+1+γV(st+1,θv)−V(st,θv)=r+γV(s′,θv)−V(s,θv)\delta= r_{t+1} + \gamma V(s_{t+1},\theta_v) −V(s_t,\theta_v)= r + \gamma V(s',\theta_v) − V(s,\theta_v) δ=rt+1+γV(st+1,θv)−V(st,θv)=r+γV(s′,θv)−V(s,θv)
为简化表达,我们省略了 rrr 和 sss 的下标。此公式与Q学习中的时序差分法相似。下一状态价值通过 γ∈[0.0,1.0]\gamma∈[0.0,1.0]γ∈[0.0,1.0] 进行折扣,由于预估远期奖励较为困难,因此我们的估计仅基于近期未来 (r+γV(s′,θv)r + \gamma V(s',\theta_v)r+γV(s′,θv)),这种技术称为自举法。
上式中采用的自举技术及其对状态表示的依赖性,通常能加速学习过程并降低方差。从该公式可观察到,价值网络评估的当前状态 s=sts=s_ts=st 是由策略网络前一动作 at−1a_{t−1}at−1 所导致,而策略梯度则基于当前动作 ata_tat。从这个意义上说,价值评估存在一步延迟。
2. 算法流程
以下算法流程总结了演员-评论家方法。除了用于训练策略网络和价值网络的状态价值评估外,该方法采用同策略训练模式——每一步都会同步训练两个网络。这与需要完成整个回合才能进行训练的 REINFORCE 及其基线变体形成鲜明对比。价值网络在训练过程中被调用两次:首次用于评估当前状态价值,第二次用于计算下一状态价值,这两个价值均参与梯度计算。
定义可微参数化目标策略网络 π(a∣s,θ)\pi(a|s,\theta)π(a∣s,θ) 与可微参数化价值网络 V(s,θv)V(s,\theta_v)V(s,θv);定义折扣因子 γ∈[0,1]\gamma∈[0,1]γ∈[0,1],性能梯度学习率 α\alphaα,价值梯度学习率 αv\alpha_vαv;初始策略网络参数 θ0\theta_0θ0 与价值网络参数 θv0\theta_{v_0}θv0
重复执行
对每个时间步 t=0,…,T−1t=0,…,T−1t=0,…,T−1 执行循环
从策略 π(a∣s,θ))\pi(a|s,\theta))π(a∣s,θ)) 中采样动作 aaa
执行动作并观察奖励 rrr 和下一状态 s′s's′
计算状态价值估计 δ=r+γV(s′,θv)−V(s,θv)\delta= r + \gamma V(s',\theta_v) − V(s,\theta_v)δ=r+γV(s′,θv)−V(s,θv)
计算折扣价值梯度 ∇V(θv)=γtδ∇θvV(s,θv)\nabla V(\theta_v)=\gamma^t \delta\nabla_{\theta_v}V(s,\theta_v)∇V(θv)=γtδ∇θvV(s,θv)
执行梯度上升:θv=θv+αv∇V(θv)\theta_v = \theta_v + \alpha v\nabla V(\theta_v)θv=θv+αv∇V(θv)
计算折扣性能梯度 ∇J(θ)=γtδ∇θvlnπ(a∣s,θ)\nabla \mathcal J(\theta) = \gamma^t\delta\nabla_{\theta_v}ln\pi(a|s,\theta)∇J(θ)=γtδ∇θvlnπ(a∣s,θ)
执行梯度上升:θ=θ)+α∇J(θ)\theta = \theta) + \alpha\nabla \mathcal J(\theta)θ=θ)+α∇J(θ)
状态更新:s=s′s = s's=s′
3. 使用 Keras 实现 Actor-Critic
接下来,使用 Keras 实现 ActorCriticAgent 类。与两种 REINFORCE 方法不同,演员-评论员算法无需等待整个回合结束即可进行训练,因此该类没有实现 train_by_episode() 方法。在每个经验单元处理时,系统会通过调用各自模型的 fit() 方法,同步优化目标函数网络 logp_model 和价值函数网络 value_model。
class ActorCriticAgent(PolicyAgent):def __init__(self,env):super().__init__(env)def train(self,item,gamma=1.0):[step,state,next_state,reward,done] = item#must save state for entropy computationself.state = statediscount_factor = gamma ** step#actor-critic: delta = reward - value + discounted_next_valuedelta = reward - self.value(state)[0]#since this fuction is called by Actor-Critic#directly, evaluate the value function hereif not done:next_value = self.value(next_state)[0]#add the discounted next valuedelta += gamma * next_value#apply the discount factor as shown in algortihmsdiscounted_delta = delta * discount_factordiscounted_delta = np.reshape(discounted_delta,[-1,1])verbose = verbose#train the lopg model (implies training of actor model# as well) since they share exactly the same set of parametersself.logp_model.fit(np.array(state),discounted_delta,batch_size=1,epochs=1,verbose=verbose)
