cia1099 / learning_reiforceLearning

junier learning

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

《實戰人工智慧之深度強化學習》ISBN:9789865021900 http://books.gotop.com.tw/download/ACD017700

Sarsa & Q-Learning

Sarsa的動作價值函數Q的更新公式為

Q-Learnig的更新公式為
  • Sarsa演算法會在更新時計算下一個動作formula,然後用來更新函數,但Q-learning則是以狀態formula的動作價值函數的最大值更新函數。
  • Sarsa是使用下個動作formula更新動作價值函數Q,所以特徵是Q的更新方式取決於計算formula的策略。這種特徵又稱為On-Policy型。
  • Q-learning的動作價值函數Q不需要透過動作的策略決定如何更新,所以這種特性又稱為Off-Policy型。由於更新公式未完全符合formula法產生的隨機性,所以動作價值函數的收斂也比Sarsa來得更快。[p.57]
  • formula是時間折扣率、formula是學習率。[p.82]
  • 為了避免在不知正確的Q table之前,學習可能因收斂至錯誤的解,因此在智能體學習Q table的亂數條件時,還要補以一個 機率的隨機移動,在以 的機率作 最大值的移動;這種手法稱為formula法。[p.51]其中 機率可以隨著epoch的訓練次數來調低機率: [p.133]
  • 指的是進入狀態 之後的即時報酬。[p.49]

Jupyter的動畫繪圖參考

References: [1] Sutton, Richard S., et al. "Policy gradient methods for reinforcement learning with function approximation." Advances in neural information processing systems. 2000.

[2] Tanaka, Saori C., et al. "Neural mechanisms of gain–loss asymmetry in temporal discounting." Journal of Neuroscience 34.16 (2014): 5595-5602.

安裝強化學習所需的套件

pip install gym
pip install matplotlib
pip install JSAnimation //failure
# pip uninstall pyglet -y
# pip install pyglet==1.4.5
# git clone https://github.com/jakevdp/JSAnimation
# cd JSAnimation
# python setup.py install

conda install -c conda-forge ffmpeg
#[p.70]
pip install tqdm #確認for陳述式進度的套件
pip install atari-py
#安裝OpenAI的gym執行程式所需套件[p.210]
mkdir breakout
cd breakout
git clone http://github.com/openai/baselines.git
cd baselines
#pip install -e . #會安裝opencv一般版,使得opencv-contrib失效,要砍掉重新安裝才能恢復

matplotlib最新版本與JSAnimation的版本會有不兼容,要修改JSAnimation的名稱或將matplotlib降版本至3.1.3;需修正的地方有:

''' 
yourPythonSystemPath/JSAnimation/html_writer.py at line 324
which solved connot find self._temp_names 
'''
with open(self.outfile, 'w') as of:
            of.write(JS_INCLUDE)
            of.write(DISPLAY_TEMPLATE.format(id=self.new_id(),
                                            #  Nframes=len(self._temp_names),
                                             Nframes=len(self._temp_paths),
                                             fill_frames=fill_frames,
                                             interval=interval,
                                             icons=_Icons(),
                                             **mode_dict))
#新版的(>=3.2.0)matplotlib.FileMovieWriter成員叫做"self._temp_path"
#舊版本的(<3.2.0)matplotlib.FileMovieWriter成員叫"self._temp_names"

''' 
yourPythonSystemPath/matplotlib/animation.py at line 399
which solve the TypeError
ref https://stackoverflow.com/questions/57911170/typeerror-a-bytes-like-object-is-required-not-str-with-funcanimation-how-ca
'''
try:
    out = TextIOWrapper(BytesIO(out)).read()
    err = TextIOWrapper(BytesIO(err)).read()
except:
    out = TextIOWrapper(BytesIO(out.encode('utf-8'))).read()
    err = TextIOWrapper(BytesIO(err.encode('utf-8'))).read()

OpenAI:cartPole game

Reference: [1] 讀這份參考文獻立刻能採用與實踐強化學習_日文fuck

深度強化學習 Deep Q-Network(DQN)

表格表示法(Q table)的Q學習是以表格的row編號對應智能體的狀態,column編號則對應智能體的動作,而表格的值則為動作價值 的值。

動作價值 則是在時間 t 的狀態 之下,採取動作 所得的折扣報酬總和。

為了解決「狀態變數過多、各變數過於離散化、表格列數會激增的缺點」的問題才使用深度學習。[p.120]

要使用Q-learning的更新公式,以下公式成立的關係就必須成立:

這公式的源頭來自於貝爾曼方程式。意思是,新狀態的狀態價值乘上1step的時間折扣率,再加上即時報酬的最大總和就是目前的狀代價值。貝爾曼公式成立的前提是學習的對象必須是馬可夫決策過程(Markov Decision Process),馬可夫決策過程就是以目前的狀態 與採取動作 確定下一步的狀態 的系統。[p.49]

輸出層元素的輸出值將為 ,而且也會繼續學習,直到輸出值趨近 。可以用L2或L1誤差來定義損失函數:[p.122]

當然最佳的損失函數是綜合了L1與L2損失的Huber(smooth-L1)函數為最佳,該函數的特性為:[p.124]

smooth-L1避免當誤差較大(大於1)時,輸出值或梯度會變得過大,導致學習過程不穩定。

用於計算指令訊號 的detach()可用來取得神經網路的輸出值。在Pytorch使用detach()會讓該變數之前的計算歷程消失,無法在反向傳播演算法的時候計算微分?在學習連結參數時,指令訊號必須先固定,所以執行detach(),避免對指令訊號微分,但神經網路在預測輸出的 則不執行detach()才能進行微分,讓 趨近指令訊號,更新神經網路的連結參數。[p.136, code_5.3]

要讓DQN穩定地學習,必須在建置之際重視四項重點[1]。[p.123]

DQN有兩種,分別是2013年版本[2]與2015年Nature版本[1]。利用小批次(batch)學習建置DQN,相當於2013年版本,而2015年版本則是建立Target Q-Network學習Main Q-Network;總共有兩個Q-Network,Q值最大行動a是由Tearget Q-Network定出。[p.147]

Reference:

(ref5_1): [1] Mnih, Volodymyr, et al. "Human-level control through deep reinforcement learning." Nature 518.7540 (2015): 529-533.

[2] Mnih, Volodymyr, et al. "Playing atari with deep reinforcement learning." arXiv preprint arXiv:1312.5602 (2013).

深度強化學習演算法地圖

Q-learning與DQN都會學習動作價值函數 ,但是更新動作價值函數Q時,都得用到動作價值函數Q,這也是導致無法穩定學習的原因之一。[p.145]

DDQN(Double DQN)

改善DQN學習不穩定的方法;使用兩個Q-Network改良Q值的更新公式:[1]

這裡的 是Main Q-Network, 是Target Q-Network;每次更新Main Q都是藉由前幾次的暫存Target Q,在每執行幾個步驟後就更新Target Q-Network一次,讓 。[p.147, code6_2]

Dueling Network

中心**是將Q函數分成只由狀態s決定的部份V(s)和由動作決定的部份Advantage,也就是A(s,a)在進行學習,然後在最後的輸出層加總V(s)與A(s,a),算出Q(s,a)。[2]

Advantage函數關係為:

Dueling Network優於DQN的部份在於連接V(s)的神經網路參數不受動作a影響,能在每個step學習,所以能以少於DQN的回合數完成學習,尤其當可選擇的動作增加,這個優勢也就更加明顯。[p.159] ```python import torch.nn as nn import torch.nn.functional as F

class Net(nn.Module): def init(self, n_in, n_mid, n_out): super(Net, self).init() self.fc1 = nn.Linear(n_in, n_mid) self.fc2 = nn.Linear(n_mid, n_mid) # Dueling Network self.fc3_adv = nn.Linear(n_mid, n_out) #Advantage的部份 self.fc3_v = nn.Linear(n_mid, 1) #價值V的部份

def forward(self, x):
    h1 = F.relu(self.fc1(x))
    h2 = F.relu(self.fc2(h1))

    adv = self.fc3_adv(h2)
    v = self.fc3_v(h2).expand(-1, adv.size(1))
    output = v + adv -adv.mean(1, keepdim=True).expand(-1, adv.size(1))
    #利用expand展開(broadcast)成[minibatchx動作數量]

    return output
減掉平均值的用意在於避免某個動作的偏好,或是說對所有動作的值 ![](https://render.githubusercontent.com/render/math?math=A(s,a_i)) 都歸零在V(s)的數值上:[p.161]
<div align=center>

<img src="http://latex.codecogs.com/gif.latex?Q(s,a_i)=V(s)+A(s,a_i)-\underset{a}{mean}A(s,a)" />
</div>
雖然Dueling Network與DDQN不同之處只有Net類別,但是學習性能卻因此提升。

#### Prioritized Experience Replay
這個手法可在Q-learning無法順利進行時,挑出需優先學習的狀態s的transition。[[3]](#ref6_3)

優先順序的基準就是價值函數貝爾曼方程式的絕對值誤差。嚴格來說,不能稱為TD誤差,但為了方便說明,姑且用TD誤差暫稱之:
<div align=center>

<img src="http://latex.codecogs.com/gif.latex?TD(t)=|R_{t+1}+\gamma \underset{a}{\max}Q(s_{t+1},a)-Q(s_t,a_t)|" />
</div>

將TD誤差明顯的transition優先學習,藉此縮小價值函數的神經網路的輸出誤差。Prioritized Experience Replay的建置方式有很多種,但目前認為以二元樹儲存TD誤差的方式最快速[[11]](#ref6_11),這次為了方便了解,改以最簡單的list形式。[p.162]
```python
#一個不屌的隨機取樣方法,依list中元素的大小來決定取樣機率,值越大的取樣機會越多
def get_prioritized_indexes(self, batch_size):
    '''以對應TD誤差的機率取得index,
        原文[p.165]版的取樣法不公平,有空再改良'''

    sum_absolute_td_error = np.sum(np.absolute(self.memory)) #self.memory is a list
    sum_absolute_td_error += TD_ERROR_EPSILON*len(self.memory)

    rand_list = np.random.uniform(0, sum_absolute_td_error, batch_size)
    rnad_list = np.sort(rand_list) #昇幕排序

    indexes = []
    idx = 0
    tmp_abs_td_error = 0
    for rand_num in rand_list:
        while tmp_abs_td_error < rand_num:
            tmp_abs_td_error += abs(self.memory[idx]) + TD_ERROR_EPSILON
            idx += 1 #會缺失取樣idx=0的機會
        
        #因為取樣至少取樣1,長度會超過list的長度,要修正
        if idx >= len(self.memory):
            idx len(self.memory)-1
        indexes.append(idx)

    return indexes

範例代碼中Agent的成員函數memorize_td_error()用來增加list長度?因為最後都還是呼叫Agent.update_td_error_memory()刷新一個新的TD list,所以memorized_td_error()形同虛設?[p.171, code6_4]

Prioritized experience replay像是在改善學習效率的方法。可以使訓練Q函數的經驗中batch取TD值較大的狀態做加速的訓練;或是說TD值偏高,代表該動作價值函數 之下,學習效率很低,所以在replay時優先取出,多加練習。這種優先學習效率不彰之處的replay演算法就是PER。[p.145]

A2C (Advantage Actor-Critic)[6]

這裡的Advantage學習指的是步進大小,例如以二步之後的更新Q函數:

但不代表以更多的步進更新就會比較好,因為要以多步之後的值更新,所以挑到不適當動作的機率會增加,無法正確學習的機率也就跟著增加;選擇適當步進的值進行Advantage學習才是一般辦法。[p.176]

傳統Q-learning是價值迭代法的手法,但Actor-Critic則同時使用策略迭代法與價值迭代法。Actor只具備動作數量的輸出量,在CartPole課題裡,Actor的輸出量就只有兩個,會針對狀態 的輸入值輸出各動作的優劣程度;當這個輸出值經過softmax函數轉換,就能得到在狀態 下,採用某種動作的機率 ,與策略迭代法[ch2.3]所要求得的目的相同。Critic得輸出值為狀態的價值 。狀態價值就是在狀態 底下所能得到的折扣報酬總和期望值。[p.177]

Actor這邊需要最大化的值就是在狀態 底下採用連結參數 的神經網路,使動作持續執行之後得到的折扣報酬總和

實際建置時,會計算小批次資料的平均E[]。注意動作價值 不是與動作a有關的變數,而是當常數使用,狀態價值 ,也是Critic的輸出值。因此我們要求的最大化就是找一個機率使(6.1)式最大,追加策略的熵項:

熵項是隨機挑選動作時(也就是學習初期)的最大值。假設是只能選擇一種動作時,熵項將為最小值?[p.178]

Critic部份會不斷學習,直到能正確輸出狀態價值 為止,所以會盡可能讓採取動作所得的動作價值與輸出一致:

A2C的建置可以參考OpenAI的A2C範例[12,13]

學習Breakout的四項作業
  1. No-Operation:這是在重設Breakout的執行環境之後,在0~30步之內什麼都不做,為的是讓遊戲能順利初始化,避免在特定的初始狀態進行學習。
  2. Episodic Life:Breakout有五個生命數,所以失敗五次,遊戲就結束。允許重複失敗的狀態其實很麻煩,但每次失敗就要全部重來,會無法在多種狀態下學習,因此這個打磚塊遊戲要直接開始下回合的學習,直到失敗五次再徹底重設遊戲。
  3. Max and Skip:Breakout是以60Hz進行遊戲,會於每4格影格判斷動作(輸入的堆疊為4,所以第一層的Convolution要是4通道),所以Breakout這個遊戲要在第3格影格與第4格影格預備計算最大值的影像。
  4. Wrap frame:Breakout的影像是210x160像素、RGB,我們將這影像轉換成DQN的Nature論文使用的1x84x84的灰階影像,影像縮放處理完後還會在用WrapPytorch供Pytorch模型的資料型態,讓影像由CxHxW→HxWxC。DQN將報酬介紹在-1~1之間,但Breakout則不需要設定報酬範圍。[p.214-p.219]

Reference:

[1] Van Hasselt, Hado, Arthur Guez, and David Silver. "Deep reinforcement learning with double q-learning." Thirtieth AAAI conference on artificial intelligence. 2016.

[2] Wang, Ziyu, et al. "Dueling network architectures for deep reinforcement learning." arXiv preprint arXiv:1511.06581 (2015).

[3] Schaul, Tom, et al. "Prioritized experience replay." arXiv preprint arXiv:1511.05952 (2015).

[4] Mnih, Volodymyr, et al. "Asynchronous methods for deep reinforcement learning." International conference on machine learning. 2016.

[5] Nair, Arun, et al. "Massively parallel methods for deep reinforcement learning." arXiv preprint arXiv:1507.04296 (2015).

[6] OpenAI Baselines:ACKTR & A2C

--未解說文獻-- [7] Jaderberg, Max, et al. "Reinforcement learning with unsupervised auxiliary tasks." arXiv preprint arXiv:1611.05397 (2016).

[8] Schulman, John, et al. "Trust region policy optimization." International conference on machine learning. 2015.

[9] Schulman, John, et al. "Proximal policy optimization algorithms." arXiv preprint arXiv:1707.06347 (2017).

[10] Wu, Yuhuai, et al. "Scalable trust-region method for deep reinforcement learning using kronecker-factored approximation." Advances in neural information processing systems. 2017.

[11] Let’s make a DQN: Double Learning and Prioritized Experience Replay

[12] A2C

[13] acktr

About

junier learning


Languages

Language:Jupyter Notebook 100.0%