系統學習機器學習之增強學習(五)--馬爾可夫決策過程策略TD求解(SARSA)

轉自:https://www.cnblogs.com/pinard/p/9529828.html

1.時間差分法(temporal difference)

蒙特卡洛方法,需要所有的採樣序列都是經歷完整的狀態序列。如果我們沒有完整的狀態序列,那麼就無法使用蒙特卡羅法求解了。本文我們就來討論可以不使用完整狀態序列求解強化學習問題的方法:時序差分(Temporal-Difference, TD)。

1. 時序差分TD簡介

    時序差分法和蒙特卡羅法類似,都是不基於模型的強化學習問題求解方法。所以在上一篇定義的不基於模型的強化學習控制問題和預測問題的定義,在這裏仍然適用。

    預測問題:即給定強化學習的5個要素:狀態集S, 動作集A, 即時獎勵R,衰減因子γ,  給定策略π, 求解該策略的狀態價值函數v(π)

    控制問題:也就是求解最優的價值函數和策略。給定強化學習的5個要素:狀態集S, 動作集A, 即時獎勵R,衰減因子γ, 探索率ϵ, 求解最優的動作價值函數q∗和最優策略π∗

    回顧蒙特卡羅法中計算狀態收穫的方法是:

G_t =R_{t+1} + \gamma R_{t+2} + \gamma^2R_{t+3}+... \gamma^{T-t-1}R_{T}

    而對於時序差分法來說,我們沒有完整的狀態序列,只有部分的狀態序列,那麼如何可以近似求出某個狀態的收穫呢?回顧貝爾曼方程:

v_{\pi}(s) = \mathbb{E}_{\pi}(R_{t+1} + \gamma v_{\pi}(S_{t+1}) | S_t=s)

    這啓發我們可以用Rt+1+γv(St+1)來近似的代替收穫Gt, 一般我們把Rt+1+γV(St+1)稱爲TD目標值。Rt+1+γV(St+1)−V(St)Rt+1+γV(St+1)−V(St)稱爲TD誤差,將用TD目標值近似代替收穫G(t)的過程稱爲引導(bootstrapping)。這樣我們只需要兩個連續的狀態與對應的獎勵,就可以嘗試求解強化學習問題了。

    現在我們有了自己的近似收穫Gt的表達式,那麼就可以去求解時序差分的預測問題和控制問題了。

2. 時序差分TD的預測問題求解

    時序差分的預測問題求解和蒙特卡羅法類似,但是主要有兩個不同點。一是收穫Gt的表達式不同,時序差分G(t)的表達式爲:

G(t) = R_{t+1} + \gamma V(S_{t+1})

    二是迭代的式子係數稍有不同,回顧蒙特卡羅法的迭代式子是:

V(S_t) = V(S_t) + \frac{1}{N(S_t)}(G_t - V(S_t) )

    由於在時序差分我們沒有完整的序列,也就沒有對應的次數N(St),一般就用一個[0,1]的係數α代替。這樣時序差分的價值函數迭代式子是:

V(S_t) = V(S_t) + \alpha(G_t - V(S_t) )

Q(S_t, A_t) = Q(S_t, A_t) +\alpha(G_t - Q(S_t, A_t) )

    這裏我們用一個簡單的例子來看看蒙特卡羅法和時序差分法求解預測問題的不同。

    假設我們的強化學習問題有A,B兩個狀態,模型未知,不涉及策略和行爲。只涉及狀態轉化和即時獎勵。一共有8個完整的狀態序列如下:

    ① A,0,B,0 ②B,1 ③B,1 ④ B,1 ⑤ B,1 ⑥B,1 ⑦B,1 ⑧B,0

    只有第一個狀態序列是有狀態轉移的,其餘7個只有一個狀態。設置衰減因子γ=1。

    首先我們按蒙特卡羅法來求解預測問題。由於只有第一個序列中包含狀態A,因此A的價值僅能通過第一個序列來計算,也就等同於計算該序列中狀態A的收穫:

V(A)=G(A)=RA+γRB=0

    對於B,則需要對其在8個序列中的收穫值來平均,其結果是6/8。

    再來看看時序差分法求解的過程。其收穫是在計算狀態序列中某狀態價值時是應用其後續狀態的預估價值來計算的,對於B來說,它總是終止狀態,沒有後續狀態,因此它的價值直接用其在8個序列中的收穫值來平均,其結果是6/8。

    對於A,只在第一個序列出現,它的價值爲:

V(A)=RA+γV(B)=6/8

    從上面的例子我們也可以看到蒙特卡羅法和時序差分法求解預測問題的區別。

    一是時序差分法在知道結果之前就可以學習,也可以在沒有結果時學習,還可以在持續進行的環境中學習,而蒙特卡羅法則要等到最後結果才能學習,時序差分法可以更快速靈活的更新狀態的價值估計,這在某些情況下有着非常重要的實際意義。

    二是時序差分法在更新狀態價值時使用的是TD 目標值,即基於即時獎勵和下一狀態的預估價值來替代當前狀態在狀態序列結束時可能得到的收穫,是當前狀態價值的有偏估計,而蒙特卡羅法則使用實際的收穫來更新狀態價值,是某一策略下狀態價值的無偏估計,這一點蒙特卡羅法佔優。

    三是雖然時序差分法得到的價值是有偏估計,但是其方差卻比蒙特卡羅法得到的方差要低,且對初始值敏感,通常比蒙特卡羅法更加高效。

    從上面的描述可以看出時序差分法的優勢比較大,因此現在主流的強化學習求解方法都是基於時序差分的。後面的文章也會主要基於時序差分法來擴展討論。

3. n步時序差分

    在第二節的時序差分法中,我們使用了用Rt+1+γv(St+1)來近似的代替收穫Gt。即向前一步來近似我們的收穫Gt,那麼能不能向前兩步呢?當然可以,這時我們的收穫Gt的近似表達式爲:

G_t^{(2)} = R_{t+1} + \gamma R_{t+2} + \gamma^2V(S_{t+2})

    從兩步,到三步,再到n步,我們可以歸納出n步時序差分收穫G(n)t表達式爲:

G_t^{(n)} = R_{t+1} + \gamma R_{t+2} + ... + \gamma^{n-1} R_{t+n} + \gamma^nV(S_{t+n})

    當n越來越大,趨於無窮,或者說趨於使用完整的狀態序列時,n步時序差分就等價於蒙特卡羅法了。

    對於n步時序差分來說,和普通的時序差分的區別就在於收穫的計算方式的差異。那麼既然有這個n步的說法,那麼n到底是多少步好呢?如何衡量n的好壞呢?我們在下一節討論。

4. TD(λ)

    n步時序差分選擇多少步數作爲一個較優的計算參數是需要嘗試的超參數調優問題。爲了能在不增加計算複雜度的情況下綜合考慮所有步數的預測,我們引入了一個新[0,1]的參數λ,定義λ−收穫是n從1到∞所有步的收穫乘以權重的和。每一步的權重是(1−λ)λ^(n−1),這樣λ−收穫的計算公式表示爲:

G_t^{\lambda} = (1-\lambda)\sum\limits_{n=1}^{\infty}\lambda^{n-1}G_t^{(n)}

    進而我們可以得到TD(λ)的價值函數的迭代公式:

V(S_t) = V(S_t) + \alpha(G_t^{\lambda} - V(S_t) )

Q(S_t, A_t) = Q(S_t, A_t) +\alpha(G_t^{\lambda}- Q(S_t, A_t) )

    每一步收穫的權重定義爲(1−λ)λ^(n−1)的原因是什麼呢?其圖像如下圖所示,可以看到隨着n的增大,其第n步收穫的權重呈幾何級數的衰減。當在T時刻到達終止狀態時,未分配的權重全部給予終止狀態的實際收穫值。這樣可以使一個完整的狀態序列中所有的n步收穫的權重加起來爲1,離當前狀態越遠的收穫其權重越小。

    從前向來看TD(λ), 一個狀態的價值V(St)由Gt得到,而Gt又間接由所有後續狀態價值計算得到,因此可以認爲更新一個狀態的價值需要知道所有後續狀態的價值。也就是說,必須要經歷完整的狀態序列獲得包括終止狀態的每一個狀態的即時獎勵才能更新當前狀態的價值。這和蒙特卡羅法的要求一樣,因此TD(λ)有着和蒙特卡羅法一樣的劣勢。當λ=0時,就是第二節講到的普通的時序差分法,當λ=1時,就是蒙特卡羅法。

    從反向來看TD(λ),它可以分析我們狀態對後續狀態的影響。比如老鼠在依次連續接受了3 次響鈴和1 次亮燈信號後遭到了電擊,那麼在分析遭電擊的原因時,到底是響鈴的因素較重要還是亮燈的因素更重要呢?如果把老鼠遭到電擊的原因認爲是之前接受了較多次數的響鈴,則稱這種歸因爲頻率啓發(frequency heuristic) 式;而把電擊歸因於最近少數幾次狀態的影響,則稱爲就近啓發(recency heuristic) 式。

    如果給每一個狀態引入一個數值:效用(eligibility, E) 來表示該狀態對後續狀態的影響,就可以同時利用到上述兩個啓發。而所有狀態的效用值總稱爲效用跡(eligibility traces,ES)。定義爲:

E0(s)=0

E_t(s) = \gamma\lambda E_{t-1}(s) +1(S_t=s) = \begin{cases} 0& {t<k}\\ (\gamma\lambda)^{t-k}& {t\geq k} \end{cases}, \;\;s.t.\; \lambda,\gamma \in [0,1], s\; is\; visited \;once\;at\; time\; k

    此時我們TD(λ)的價值函數更新式子可以表示爲:

\delta_t = R_{t+1} + \gamma v(S_{t+1}) -V(S_t)

V(S_t) = V(S_t) + \alpha\delta_tE_t(s)

     也許有人會問,這前向的式子和反向的式子看起來不同啊,是不是不同的邏輯呢?其實兩者是等價的。現在我們從前向推導一下反向的更新式子。

\begin{align} G_t^{\lambda} - V(S_t) &= - V(S_t) + (1-\lambda)\lambda^{0}(R_{t+1} + \gamma V(S_{t+1})) \\ &+ (1-\lambda)\lambda^{1}(R_{t+1} + \gamma R_{t+2} + \gamma^2V(S_{t+2})) \\ &+ (1-\lambda)\lambda^{2}(R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + \gamma^3V(S_{t+3})) \\ &+... \\& = - V(S_t) + (\gamma\lambda)^0(R_{t+1} + \gamma V(S_{t+1}) - \gamma\lambda V(S_{t+1}) ) \\ & + (\gamma\lambda)^1(R_{t+2} + \gamma V(S_{t+2}) - \gamma\lambda V(S_{t+2}) ) \\ & + (\gamma\lambda)^2(R_{t+3} + \gamma V(S_{t+3}) - \gamma\lambda V(S_{t+3}) ) \\ &+... \\ & = (\gamma\lambda)^0(R_{t+1} + \gamma V(S_{t+1}) - V(S_t)) \\ & + (\gamma\lambda)^1(R_{t+2} + \gamma V(S_{t+2}) - V(S_{t+1})) \\ & + (\gamma\lambda)^2(R_{t+3} + \gamma V(S_{t+3}) - V(S_{t+2})) \\ & + ... \\ & = \delta_t + \gamma\lambda \delta_{t+1} + (\gamma\lambda)^2 \delta_{t+2} + ... \end{align}

    可以看出前向TD誤差和反向的TD誤差實際上一致的。

5.  時序差分的控制問題求解

    現在我們回到普通的時序差分,來看看它控制問題的求解方法。回想上一篇蒙特卡羅法在線控制的方法,我們使用的是ϵ−貪婪法來做價值迭代。對於時序差分,我們也可以用ϵ−貪婪法來價值迭代,和蒙特卡羅法在線控制的區別主要只是在於收穫的計算方式不同。時序差分的在線控制(on-policy)算法最常見的是SARSA算法。

    而除了在線控制,我們還可以做離線控制(off-policy),離線控制和在線控制的區別主要在於在線控制一般只有一個策略(最常見的是ϵ−貪婪法)。而離線控制一般有兩個策略,其中一個策略(最常見的是ϵ−貪婪法)用於選擇新的動作,另一個策略(最常見的是貪婪法)用於更新價值函數。時序差分的離線控制算法最常見的是Q-Learning算法,我們在下篇單獨講解。

5.1. SARSA算法的引入

    SARSA算法是一種使用時序差分求解強化學習控制問題的方法,回顧下此時我們的控制問題可以表示爲:給定強化學習的5個要素:狀態集S, 動作集A, 即時獎勵R,衰減因子γ, 探索率ϵ, 求解最優的動作價值函數q∗和最優策略π∗。

    這一類強化學習的問題求解不需要環境的狀態轉化模型,是不基於模型的強化學習問題求解方法。對於它的控制問題求解,和蒙特卡羅法類似,都是價值迭代,即通過價值函數的更新,來更新當前的策略,再通過新的策略,來產生新的狀態和即時獎勵,進而更新價值函數。一直進行下去,直到價值函數和策略都收斂。

    我們的SARSA算法,屬於在線控制這一類,即一直使用一個策略來更新價值函數和選擇新的動作,而這個策略是ϵ−貪婪法,在系統學習機器學習之增強學習(四)--馬爾可夫決策過程策略MC求解中,我們對於ϵ−貪婪法有詳細講解,即通過設置一個較小的ϵ值,使用1−ϵ的概率貪婪地選擇目前認爲是最大行爲價值的行爲,而用ϵ的概率隨機的從所有m個可選行爲中選擇行爲。用公式可以表示爲:

\pi(a|s)= \begin{cases} \epsilon/m + 1- \epsilon & {if\; a^{*} = \arg\max_{a \in A}Q(s,a)}\\ \epsilon/m & {else} \end{cases}

2. SARSA算法概述

    作爲SARSA算法的名字本身來說,它實際上是由S,A,R,S,A幾個字母組成的。而S,A,R分別代表狀態(State),動作(Action),獎勵(Reward),這也是我們前面一直在使用的符號。這個流程體現在下圖:

    在迭代的時候,我們首先基於ϵ−貪婪法在當前狀態S選擇一個動作A,這樣系統會轉到一個新的狀態S′, 同時給我們一個即時獎勵R, 在新的狀態S′,我們會基於ϵ−貪婪法在狀態S‘′選擇一個動作A′,但是注意這時候我們並不執行這個動作A′,只是用來更新的我們的價值函數,價值函數的更新公式是:

Q(S,A) = Q(S,A) + \alpha(R+\gamma Q(S',A') - Q(S,A))

    其中,γ是衰減因子,α是迭代步長。這裏和蒙特卡羅法求解在線控制問題的迭代公式的區別主要是,收穫Gt的表達式不同,對於時序差分,收穫Gt的表達式是R+γQ(S′,A′)。

    除了收穫Gt的表達式不同,SARSA算法和蒙特卡羅在線控制算法基本類似。

3. SARSA算法流程

    下面我們總結下SARSA算法的流程。

    算法輸入:迭代輪數T,狀態集S, 動作集A, 步長α,衰減因子γ, 探索率ϵ,

    輸出:所有的狀態和動作對應的價值Q

    1. 隨機初始化所有的狀態和動作對應的價值Q. 對於終止狀態其Q值初始化爲0.

    2. for i from 1 to T,進行迭代。

      a) 初始化S爲當前狀態序列的第一個狀態。設置A爲ϵ−貪婪法在當前狀態S選擇的動作。

      b) 在狀態S執行當前動作A,得到新狀態S′和獎勵R

      c) 用ϵ−貪婪法在狀態S′選擇新的動作A′

      d) 更新價值函數Q(S,A):

Q(S,A) = Q(S,A) + \alpha(R+\gamma Q(S',A') - Q(S,A))

      e) S=S′,A=A′

      f) 如果S′是終止狀態,當前輪迭代完畢,否則轉到步驟b)

    這裏有一個要注意的是,步長α一般需要隨着迭代的進行逐漸變小,這樣才能保證動作價值函數Q可以收斂。當Q收斂時,我們的策略ϵ−貪婪法也就收斂了。

4. SARSA算法實例:Windy GridWorld

    下面我們用一個著名的實例Windy GridWorld來研究SARSA算法。

    如下圖一個10×7的長方形格子世界,標記有一個起始位置 S 和一個終止目標位置 G,格子下方的數字表示對應的列中一定強度的風。當個體進入該列的某個格子時,會按圖中箭頭所示的方向自動移動數字表示的格數,藉此來模擬世界中風的作用。同樣格子世界是有邊界的,個體任意時刻只能處在世界內部的一個格子中。個體並不清楚這個世界的構造以及有風,也就是說它不知道格子是長方形的,也不知道邊界在哪裏,也不知道自己在裏面移動移步後下一個格子與之前格子的相對位置關係,當然它也不清楚起始位置、終止目標的具體位置。但是個體會記住曾經經過的格子,下次在進入這個格子時,它能準確的辨認出這個格子曾經什麼時候來過。格子可以執行的行爲是朝上、下、左、右移動一步,每移動一步只要不是進入目標位置都給予一個 -1 的懲罰,直至進入目標位置後獲得獎勵 0 同時永久停留在該位置。現在要求解的問題是個體應該遵循怎樣的策略才能儘快的從起始位置到達目標位置。

    邏輯並不複雜,完整的代碼在我的github。這裏我主要看一下關鍵部分的代碼。

    算法中第2步步驟a,初始化SS,使用ϵ−ϵ−貪婪法在當前狀態SS選擇的動作的過程:

複製代碼

    # initialize state
    state = START

    # choose an action based on epsilon-greedy algorithm
    if np.random.binomial(1, EPSILON) == 1:
        action = np.random.choice(ACTIONS)
    else:
        values_ = q_value[state[0], state[1], :]
        action = np.random.choice([action_ for action_, value_ in enumerate(values_) if value_ == np.max(values_)])

複製代碼

    算法中第2步步驟b,在狀態SS執行當前動作AA,得到新狀態S′S′的過程,由於獎勵不是終止就是-1,不需要單獨計算:

複製代碼

def step(state, action):
    i, j = state
    if action == ACTION_UP:
        return [max(i - 1 - WIND[j], 0), j]
    elif action == ACTION_DOWN:
        return [max(min(i + 1 - WIND[j], WORLD_HEIGHT - 1), 0), j]
    elif action == ACTION_LEFT:
        return [max(i - WIND[j], 0), max(j - 1, 0)]
    elif action == ACTION_RIGHT:
        return [max(i - WIND[j], 0), min(j + 1, WORLD_WIDTH - 1)]
    else:
        assert False

複製代碼

    算法中第2步步驟c,用ϵ−ϵ−貪婪法在狀態S‘S‘選擇新的動作A′A′的過程:

複製代碼

        next_state = step(state, action)
        if np.random.binomial(1, EPSILON) == 1:
            next_action = np.random.choice(ACTIONS)
        else:
            values_ = q_value[next_state[0], next_state[1], :]
            next_action = np.random.choice([action_ for action_, value_ in enumerate(values_) if value_ == np.max(values_)])

複製代碼

    算法中第2步步驟d,e, 更新價值函數Q(S,A)Q(S,A)以及更新當前狀態動作的過程:

複製代碼

        # Sarsa update
        q_value[state[0], state[1], action] += \
            ALPHA * (REWARD + q_value[next_state[0], next_state[1], next_action] -
                     q_value[state[0], state[1], action])
        state = next_state
        action = next_action

複製代碼

    代碼很簡單,相信大家對照算法,跑跑代碼,可以很容易得到這個問題的最優解,進而搞清楚SARSA算法的整個流程。

5. SARSA(λ)

    在系統學習機器學習之增強學習(五)--馬爾可夫決策過程策略TD求解中我們講到了多步時序差分TD(λ)的價值函數迭代方法,那麼同樣的,對應的多步時序差分在線控制算法,就是我們的SARSA(λ)。

    TD(λ)有前向和後向兩種價值函數迭代方式,當然它們是等價的。在控制問題的求解時,基於反向認識的 SARSA(λ)算法將可以有效地在線學習,數據學習完即可丟棄。因此 SARSA(λ)算法默認都是基於反向來進行價值函數迭代。

    在上一篇我們講到了TD(λ)狀態價值函數的反向迭代,即:

\delta_t = R_{t+1} + \gamma V(S_{t+1}) -V(S_t)

V(S_t) = V(S_t) + \alpha\delta_tE_t(S)

    對應的動作價值函數的迭代公式可以找樣寫出,即:

\delta_t = R_{t+1} + \gamma Q(S_{t+1},A_{t+1}) -Q(S_t, A_t)

Q(S_t, A_t) = Q(S_t, A_t) + \alpha\delta_tE_t(S,A)

    除了狀態價值函數Q(S,A)的更新方式,多步參數λ以及反向認識引入的效用跡E(S,A),其餘算法思想和SARSA類似。這裏我們總結下SARSA(λ)的算法流程。   

    算法輸入:迭代輪數T,狀態集S, 動作集A, 步長α,衰減因子γ, 探索率ϵ, 多步參數λ

    輸出:所有的狀態和動作對應的價值Q

    1. 隨機初始化所有的狀態和動作對應的價值Q. 對於終止狀態其Q值初始化爲0.

    2. for i from 1 to T,進行迭代。

      a) 初始化所有狀態動作的效用跡E爲0,初始化S爲當前狀態序列的第一個狀態。設置A爲ϵ−貪婪法在當前狀態S選擇的動作。

      b) 在狀態S執行當前動作A,得到新狀態S′和獎勵R

      c) 用ϵ−貪婪法在狀態S′選擇新的動作A′

      d) 更新效用跡函數E(S,A)和TD誤差δ:

E(S,A) = E(S,A)+1

\delta= R_{t+1} + \gamma Q(S_{t+1},A_{t+1}) -Q(S_t, A_t)

      e) 對當前序列所有出現的狀態s和對應動作a, 更新價值函數Q(s,a)和效用跡函數E(s,a):

Q(s,a) = Q(s,a) + \alpha\delta E(s,a)

E(s,a) = \gamma\lambda E(s,a)

      f) S=S′,A=A′

      g) 如果S′是終止狀態,當前輪迭代完畢,否則轉到步驟b)

      對於步長α,和SARSA一樣,一般也需要隨着迭代的進行逐漸變小才能保證動作價值函數Q收斂。

6. SARSA小結

    SARSA算法和動態規劃法比起來,不需要環境的狀態轉換模型,和蒙特卡羅法比起來,不需要完整的狀態序列,因此比較靈活。在傳統的強化學習方法中使用比較廣泛。

    但是SARSA算法也有一個傳統強化學習方法共有的問題,就是無法求解太複雜的問題。在 SARSA 算法中,Q(S,A)的值使用一張大表來存儲的,如果我們的狀態和動作都達到百萬乃至千萬級,需要在內存裏保存的這張大表會超級大,甚至溢出,因此不是很適合解決規模很大的問題。當然,對於不是特別複雜的問題,使用SARSA還是很不錯的一種強化學習問題求解方法。

    下一篇我們討論SARSA的姊妹算法,時序差分離線控制算法Q-Learning。

7. 時序差分小結

    時序差分和蒙特卡羅法比它更加靈活,學習能力更強,因此是目前主流的強化學習求解問題的方法,現在絕大部分強化學習乃至深度強化學習的求解都是以時序差分的思想爲基礎的。因此後面我們會重點討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章