see: https://hrl.boyuai.com/chapter/2/actor-critic%E7%AE%97%E6%B3%95
普通 Policy Gradient 通常使用蒙特卡洛求一整条轨迹的 G_t,方差大且要求完整轨迹.
引入 critic 可以用 TD 估计优势,边采样边更新而且方差更低,但会因为 critic 的网络参数引入一点 bias.
On-policy Actor-Critic
训练 critic 来估计后续收益.
1states, actions, rewards, next_states, dones = rollout(pi_theta)2td_target = rewards + gamma * V_phi(next_states) * (1 - dones)3td_delta = td_target - V_phi(states) # 这里减去 V_phi 只是为了降低方差(不改变期望)。这就是优势函数 A.4log_probs = log(pi_theta(states)[actions]) # 这里 action 必须是离散的.5actor_loss = mean(-log_probs * detach(td_delta))6# critic 数学上含义是 V(s) = E_(pi_theta) (G_t | S_t = s),7# 但这里 critic 其实拟合的 td_target 来自更新前的 pi_theta,怎么回事?285 表示问题不大.8critic_loss = mse(V_phi(states), detach(td_target))9actor_optim.zero_grad()10critic_optim.zero_grad()11actor_loss.backward(); critic_loss.backward()12actor_optim.step(); critic_optim.step()如果是连续动作 on-policy,则可使用 mean_net 和 logstd 参数,比如 285 Hw2 就是这么做的.
Off-policy Actor-Critic
考虑在 replay buffer 中采样 (s, a)。然而,采样后不可再沿用上面 on-policy 的 advantage-based.
- critic 的 loss 是错误的. 比如,采样得到的 (s, a) 都特别笨,导致奖励 r(s, a) 都很糟糕,而 critic 却拟合了这些.
- actor 的梯度也是错误的,具体原因要看 actor 的梯度公式推导. 从而必须使用 importance sampling(如 PPO),当然我们也可以使用 critic 绕开这个步骤. actor 的优化目标直接改为使得 Q(s, actor(s)) 最大化,如下:
- 以下方法拆分 target network 和 online network 就是 DDPG 了.
- 以下方法的 actor 直接输出最优解而不是概率,因而适用于连续动作.
1replay_buffer.add(s, a, r, s2, done)2states, actions, rewards, next_states, dones = replay.sample() # 数据可能来自旧 policy3next_actions = pi_theta(next_states) # 当前 actor 给下一动作4td_target = rewards + gamma * Q_phi(next_states, next_actions) * (1-dones)5
6critic_loss = mse(Q_phi(states, actions), detach(td_target))7freeze(Q_phi)8actor_loss = -mean(Q_phi(states, pi_theta(states)))9actor_optim.zero_grad()10critic_optim.zero_grad()11actor_loss.backward(); critic_loss.backward()12actor_optim.step(); critic_optim.step()