Actor Critic (Tensorflow)
学习资料:
- 全部代码
- 什么是 Actor Critic 短视频
- 什么是 Policy Gradient 短视频
- 强化学习实战
- 学习书籍 Reinforcement learning: An introduction
要点 ¶
一句话概括 Actor Critic 方法:
结合了 Policy Gradient (Actor) 和 Function Approximation (Critic) 的方法.
Actor
基于概率选行为, Critic
基于 Actor
的行为评判行为的得分,
Actor
根据 Critic
的评分修改选行为的概率.
Actor Critic 方法的优势: 可以进行单步更新, 比传统的 Policy Gradient 要快.
Actor Critic 方法的劣势:
取决于 Critic 的价值判断, 但是 Critic 难收敛, 再加上 Actor 的更新, 就更难收敛.
为了解决收敛问题, Google Deepmind 提出了 Actor Critic
升级版 Deep Deterministic Policy Gradient
.
后者融合了 DQN 的优势, 解决了收敛难的问题. 我们之后也会要讲到 Deep Deterministic Policy Gradient.
不过那个是要以 Actor Critic
为基础, 懂了 Actor Critic
, 后面那个就好懂了.
下面是基于 Actor Critic 的 Gym Cartpole 实验:
算法 ¶
这套算法是在普通的 Policy gradient 算法上面修改的, 如果对 Policy Gradient 算法还不是很了解, 欢迎戳这里. 对这套算法打个比方如下:
Actor
修改行为时就像蒙着眼睛一直向前开车, Critic
就是那个扶方向盘改变 Actor
开车方向的.
或者说详细点, 就是 Actor
在运用 Policy Gradient 的方法进行 Gradient ascent 的时候, 由
Critic
来告诉他, 这次的 Gradient ascent 是不是一次正确的 ascent, 如果这次的得分不好,
那么就不要 ascent 那么多.
代码主结构 ¶
有了点理解, 我们来代码 (如果想一次性看所有代码, 请来我的 Github):
上图是 Actor
的神经网络结果, 代码结构在下面:
class Actor(object):
def __init__(self, sess, n_features, n_actions, lr=0.001):
# 用 tensorflow 建立 Actor 神经网络,
# 搭建好训练的 Graph.
def learn(self, s, a, td):
# s, a 用于产生 Gradient ascent 的方向,
# td 来自 Critic, 用于告诉 Actor 这方向对不对.
def choose_action(self, s):
# 根据 s 选 行为 a
上图是 Critic
的神经网络结果, 代码结构在下面:
class Critic(object):
def __init__(self, sess, n_features, lr=0.01):
# 用 tensorflow 建立 Critic 神经网络,
# 搭建好训练的 Graph.
def learn(self, s, r, s_):
# 学习 状态的价值 (state value), 不是行为的价值 (action value),
# 计算 TD_error = (r + v_) - v,
# 用 TD_error 评判这一步的行为有没有带来比平时更好的结果,
# 可以把它看做 Advantage
return # 学习时产生的 TD_error
两者学习方式 ¶
Actor
想要最大化期望的 reward
, 在 Actor Critic
算法中, 我们用 “比平时好多少”
(TD error
) 来当做 reward
, 所以就是:
with tf.variable_scope('exp_v'):
log_prob = tf.log(self.acts_prob[0, self.a]) # log 动作概率
self.exp_v = tf.reduce_mean(log_prob * self.td_error) # log 概率 * TD 方向
with tf.variable_scope('train'):
# 因为我们想不断增加这个 exp_v (动作带来的额外价值),
# 所以我们用过 minimize(-exp_v) 的方式达到
# maximize(exp_v) 的目的
self.train_op = tf.train.AdamOptimizer(lr).minimize(-self.exp_v)
Critic
的更新很简单, 就是像 Q learning 那样更新现实和估计的误差 (TD error) 就好了.
with tf.variable_scope('squared_TD_error'):
self.td_error = self.r + GAMMA * self.v_ - self.v
self.loss = tf.square(self.td_error) # TD_error = (r+gamma*V_next) - V_eval
with tf.variable_scope('train'):
self.train_op = tf.train.AdamOptimizer(lr).minimize(self.loss)
每回合算法 ¶
for i_episode in range(MAX_EPISODE):
s = env.reset()
t = 0
track_r = [] # 每回合的所有奖励
while True:
if RENDER: env.render()
a = actor.choose_action(s)
s_, r, done, info = env.step(a)
if done: r = -20 # 回合结束的惩罚
track_r.append(r)
td_error = critic.learn(s, r, s_) # Critic 学习
actor.learn(s, a, td_error) # Actor 学习
s = s_
t += 1
if done or t >= MAX_EP_STEPS:
# 回合结束, 打印回合累积奖励
ep_rs_sum = sum(track_r)
if 'running_reward' not in globals():
running_reward = ep_rs_sum
else:
running_reward = running_reward * 0.95 + ep_rs_sum * 0.05
if running_reward > DISPLAY_REWARD_THRESHOLD: RENDER = True # rendering
print("episode:", i_episode, " reward:", int(running_reward))
break
建立神经网络的详细流程请直接看代码更直观, 其他方面的代码也不是重点, 所以直接看代码很好懂. 一次性看到全部代码, 请去我的 Github
由于更新时的 网络相关性, state 相关性, Actor Critic 很难收敛. 如果同学们对这份代码做过修改, 并且达到了好的收敛性, 欢迎在下面分享~
分享到:
如果你觉得这篇文章或视频对你的学习很有帮助, 请你也分享它, 让它能再次帮助到更多的需要学习的人.
UnityTutorial没有正式的经济来源, 如果你也想支持 UnityTutorial 并看到更好的教学内容, 赞助他一点点, 作为鼓励他继续开源的动力.