Actor Critic—一個融合基於策略梯度和基於值優點的演算法
注:RL系列皆是莫煩教程的學習筆記,筆者僅做記錄。
目錄
1。前言
2。演算法
2。1 演算法剖析
2。2 程式碼
1.前言
我們有了像
Q-learning
這麼偉大的演算法,為什麼還要瞎折騰出一個Actor-Critic?原來Actor-Critic的Actor的前生是
Policy Gradients
,這能讓它毫不費力地在連續動作中選擇合適的動作,而Q-learning做這件事會癱瘓。那為什麼不直接用Policy Gradients呢?原來Actor Critic中的Critic的前生是Q-Learning或其他的以值為基礎的學習法,能進行單步更新,而傳統的Policy Gradients則是回合更新,這降低了學習效率。
2.演算法
2.1 演算法剖析
我們把演算法分成兩部分,Actor和Critic,他們都能用不同的神經網路來代替。在Policy Gradient中提到過,現實中的reward會左右Actor的更新情況。Policy Gradients也是靠這個來獲取適宜的更新。那麼何時會有reward這種資訊,而這些資訊又能不能被學習呢?這看起來不就是以值為基礎的強化學習方法做過的事嗎。那我們就拿一個Critic去學習這些獎懲機制,學習完以後,由Actor來指手畫腳,由Critic來告訴Actor你的那些指手畫腳哪些指的好,哪些指的差,Critic透過學習環境和獎勵之間的關係,能看到現在所處狀態的潛在獎勵,所以用它來指點Actor便能使Actor每一步都在更新,如果使用單純的Policy Gradients,,Actor只能等到回合結束才能開始更新。
但事物總有他壞的一面,Actor-Critic涉及到了兩個神經網路,而且每次都是在連續狀態中更新引數,每次引數更新前後都存在相關性,導致神經網路只能片面地看待問題,甚至導致神經網路學不到東西。Google DeepMind為了解決這個問題,修改了Actor Critic的演算法,將之前在Atari上獲得成功的DQN網路加入進Actor Critic系統中,這種新演算法叫做 Deep Deterministic Policy Gradient,成功地解決了在連續動作預測上學不到東西的問題,這個演算法我們會在下一篇文章介紹。
一句話概括
Actor Critic
方法:
結合了Policy Gradient(Actor)和Function Approximation(Critic)的方法。
Actor
基於機率選行為,
Critic
基於
Actor
的行為評判行為評判行為的得分,
Actor
根據
Critic
的評分修改選行為的機率。
優勢
:可以進行單步更新,比傳統的Policy Gradient要快。
劣勢
:取決於Critic價值判斷,但是Critic難收斂,再加上Actor的更新,就更難收斂。為了解決收斂問題,DeepMind團隊融合了DQN的優勢,解決了收斂難的問題。
下面是基於Actor Critic的Gym Cartpole實驗:
這套演算法是在普通的Policy Gradient的基礎上修改的,如果對Policy Gradient演算法那不瞭解的可以看一下我之前的文章。
Actor
修改行為時就像蒙著眼睛一直向前開車
,
Critic
就是那個扶方向盤改變
Actor
開車方向的。
或者說詳細點,就是
Actor
在運用Policy Gradient的方法進行Gradient asent的時候,由
Actor
來告訴他,這次的Gradient ascent是不是一次正確的ascent,如果這次的得分不好,那麼就不要ascent那麼多。
2.2 程式碼
上圖是
Actor
的神經網路結果,程式碼結構在下面:
1class Actor(object):
2 def __init__(self, sess, n_features, n_actions, lr=0。001):
3 # 用 tensorflow 建立 Actor 神經網路,
4 # 搭建好訓練的 Graph。
5
6 def learn(self, s, a, td):
7 # s, a 用於產生 Gradient ascent 的方向,
8 # td 來自 Critic, 用於告訴 Actor 這方向對不對。
9
10 def choose_action(self, s):
11 # 根據 s 選 行為 a
上圖是
Critic
的神經網路結果,程式碼結果在下面:
1class Critic(object):
2 def __init__(self, sess, n_features, lr=0。01):
3 # 用 tensorflow 建立 Critic 神經網路,
4 # 搭建好訓練的 Graph。
5
6 def learn(self, s, r, s_):
7 # 學習 狀態的價值 (state value), 不是行為的價值 (action value),
8 # 計算 TD_error = (r + v_) - v,
9 # 用 TD_error 評判這一步的行為有沒有帶來比平時更好的結果,
10 # 可以把它看做 Advantage
11 return # 學習時產生的 TD_error
Actor
想要最大化期望的
reward
,在
Actor Ctitic
演算法中,我們用“比平時好多少”(
TD error
)來當做
reward
,所以就是:
1with tf。variable_scope(‘exp_v’):
2 log_prob = tf。log(self。acts_prob[0, self。a]) # log 動作機率
3 self。exp_v = tf。reduce_mean(log_prob * self。td_error) # log 機率 * TD 方向
4with tf。variable_scope(‘train’):
5 # 因為我們想不斷增加這個 exp_v (動作帶來的額外價值),
6 # 所以我們用過 minimize(-exp_v) 的方式達到
7 # maximize(exp_v) 的目的
8 self。train_op = tf。train。AdamOptimizer(lr)。minimize(-self。exp_v)
Critic
的更新很簡單,就是像Q-Learning那樣更新現實和估計的誤差(TD_error)就好
1with tf。variable_scope(‘squared_TD_error’):
2 self。td_error = self。r + GAMMA * self。v_ - self。v
3 self。loss = tf。square(self。td_error) # TD_error = (r+gamma*V_next) - V_eval
4with tf。variable_scope(‘train’):
5 self。train_op = tf。train。AdamOptimizer(lr)。minimize(self。loss)
每回合更新:
1for i_episode in range(MAX_EPISODE):
2 s = env。reset()
3 t = 0
4 track_r = [] # 每回合的所有獎勵
5 while True:
6 if RENDER: env。render()
7
8 a = actor。choose_action(s)
9
10 s_, r, done, info = env。step(a)
11
12 if done: r = -20 # 回合結束的懲罰
13
14 track_r。append(r)
15
16 td_error = critic。learn(s, r, s_) # Critic 學習
17 actor。learn(s, a, td_error) # Actor 學習
18
19 s = s_
20 t += 1
21
22 if done or t >= MAX_EP_STEPS:
23 # 回合結束, 列印回合累積獎勵
24 ep_rs_sum = sum(track_r)
25 if ‘running_reward’ not in globals():
26 running_reward = ep_rs_sum
27 else:
28 running_reward = running_reward * 0。95 + ep_rs_sum * 0。05
29 if running_reward > DISPLAY_REWARD_THRESHOLD: RENDER = True # rendering
30 print(“episode:”, i_episode, “ reward:”, int(running_reward))
31 break
完整程式碼:
https://
github。com/cristianoc20
/RL_learning/tree/master/Actor_Critic_Advantage
參考:莫煩教程
https://
github。com/MorvanZhou