強化學習(一)模型基礎


    從今天開始整理強化學習領域的知識,主要參考的資料是Sutton的強化學習書和UCL強化學習的課程。這個系列大概准備寫10到20篇,希望寫完后自己的強化學習碎片化知識可以得到融會貫通,也希望可以幫到更多的人,畢竟目前系統的講解強化學習的中文資料不太多。

    第一篇會從強化學習的基本概念講起,對應Sutton書的第一章和UCL課程的第一講。

1.  強化學習在機器學習中的位置

    強化學習的學習思路和人比較類似,是在實踐中學習,比如學習走路,如果摔倒了,那么我們大腦后面會給一個負面的獎勵值,說明走的姿勢不好。然后我們從摔倒狀態中爬起來,如果后面正常走了一步,那么大腦會給一個正面的獎勵值,我們會知道這是一個好的走路姿勢。那么這個過程和之前講的機器學習方法有什么區別呢?

    強化學習是和監督學習,非監督學習並列的第三種機器學習方法,從下圖我們可以看出來。

    強化學習來和監督學習最大的區別是它是沒有監督學習已經准備好的訓練數據輸出值的。強化學習只有獎勵值,但是這個獎勵值和監督學習的輸出值不一樣,它不是事先給出的,而是延后給出的,比如上面的例子里走路摔倒了才得到大腦的獎勵值。同時,強化學習的每一步與時間順序前后關系緊密。而監督學習的訓練數據之間一般都是獨立的,沒有這種前后的依賴關系。

    再來看看強化學習和非監督學習的區別。也還是在獎勵值這個地方。非監督學習是沒有輸出值也沒有獎勵值的,它只有數據特征。同時和監督學習一樣,數據之間也都是獨立的,沒有強化學習這樣的前后依賴關系。

2. 強化學習的建模

    我們現在來看看強化學習這樣的問題我們怎么來建模,簡單的來說,是下圖這樣的:

    上面的大腦代表我們的算法執行個體,我們可以操作個體來做決策,即選擇一個合適的動作(Action)$A_t$。下面的地球代表我們要研究的環境,它有自己的狀態模型,我們選擇了動作$A_t$后,環境的狀態(State)會變,我們會發現環境狀態已經變為$S_{t+1}$,同時我們得到了我們采取動作$A_t$的延時獎勵(Reward)$R_{t+1}$。然后個體可以繼續選擇下一個合適的動作,然后環境的狀態又會變,又有新的獎勵值。。。這就是強化學習的思路。

    那么我們可以整理下這個思路里面出現的強化學習要素。

    第一個是環境的狀態$S$, t時刻環境的狀態$S_t$是它的環境狀態集中某一個狀態。

    第二個是個體的動作$A$, t時刻個體采取的動作$A_t$是它的動作集中某一個動作。

    第三個是環境的獎勵$R$,t時刻個體在狀態$S_t$采取的動作$A_t$對應的獎勵$R_{t+1}$會在t+1時刻得到。

    下面是稍復雜一些的模型要素。

    第四個是個體的策略(policy)$\pi$,它代表個體采取動作的依據,即個體會依據策略$\pi$來選擇動作。最常見的策略表達方式是一個條件概率分布$\pi(a|s)$, 即在狀態$s$時采取動作$a$的概率。即$\pi(a|s) = P(A_t=a | S_t=s)$.此時概率大的動作被個體選擇的概率較高。

    第五個是個體在策略$\pi$和狀態$s$時,采取行動后的價值(value),一般用$v_{\pi}(s)$表示。這個價值一般是一個期望函數。雖然當前動作會給一個延時獎勵$R_{t+1}$,但是光看這個延時獎勵是不行的,因為當前的延時獎勵高,不代表到了t+1,t+2,...時刻的后續獎勵也高。比如下象棋,我們可以某個動作可以吃掉對方的車,這個延時獎勵是很高,但是接着后面我們輸棋了。此時吃車的動作獎勵值高但是價值並不高。因此我們的價值要綜合考慮當前的延時獎勵和后續的延時獎勵。價值函數$v_{\pi}(s)$一般可以表示為下式,不同的算法會有對應的一些價值函數變種,但思路相同。:$$v_{\pi}(s) = \mathbb{E}_{\pi}(R_{t+1} + \gamma R_{t+2} + \gamma^2R_{t+3}+...|S_t=s)$$

    其中$\gamma$是第六個模型要素,即獎勵衰減因子,在[0,1]之間。如果為0,則是貪婪法,即價值只由當前延時獎勵決定,如果是1,則所有的后續狀態獎勵和當前獎勵一視同仁。大多數時候,我們會取一個0到1之間的數字,即當前延時獎勵的權重比后續獎勵的權重大。

    第七個是環境的狀態轉化模型,可以理解為一個概率狀態機,它可以表示為一個概率模型,即在狀態$s$下采取動作$a$,轉到下一個狀態$s'$的概率,表示為$P_{ss'}^a$。

    第八個是探索率$\epsilon$,這個比率主要用在強化學習訓練迭代過程中,由於我們一般會選擇使當前輪迭代價值最大的動作,但是這會導致一些較好的但我們沒有執行過的動作被錯過。因此我們在訓練選擇最優動作時,會有一定的概率$\epsilon$不選擇使當前輪迭代價值最大的動作,而選擇其他的動作。

    以上8個就是強化學習模型的基本要素了。當然,在不同的強化學習模型中,會考慮一些其他的模型要素,或者不考慮上述要素的某幾個,但是這8個是大多數強化學習模型的基本要素。

3. 強化學習的簡單實例

    這里給出一個簡單的強化學習例子Tic-Tac-Toe。這是一個簡單的游戲,在一個3x3的九宮格里,兩個人輪流下,直到有個人的棋子滿足三個一橫一豎或者一斜,贏得比賽游戲結束,或者九宮格填滿也沒有人贏,則和棋。

    這個例子的完整代碼在我的github例子只有一個文件,很簡單,代碼首先會用兩個電腦選手訓練模型,然后可以讓人和機器對戰。當然,由於這個模型很簡單,所以只要你不亂走,最后的結果都是和棋,當然想贏電腦也是不可能的。

    我們重點看看這個例子的模型,理解上面第二節的部分。如何訓練強化學習模型可以先不管。代碼部分大家可以自己去看,只有300多行。

    首先看第一個要素環境的狀態$S$。這是一個九宮格,每個格子有三種狀態,即沒有棋子(取值0),有第一個選手的棋子(取值1),有第二個選手的棋子(取值-1)。那么這個模型的狀態一共有$3^9=19683$個。

    接着我們看個體的動作$A$,這里只有9個格子,每次也只能下一步,所以最多只有9個動作選項。實際上由於已經有棋子的格子是不能再下的,所以動作選項會更少。實際可以選擇動作的就是那些取值為0的格子。

    第三個是環境的獎勵$R$,這個一般是我們自己設計。由於我們的目的是贏棋,所以如果某個動作導致的改變到的狀態可以使我們贏棋,結束游戲,那么獎勵最高,反之則獎勵最低。其余的雙方下棋動作都有獎勵,但獎勵較少。特別的,對於先下的棋手,不會導致結束的動作獎勵要比后下的棋手少。

    # give reward to two players
    def giveReward(self):
        if self.currentState.winner == self.p1Symbol:
            self.p1.feedReward(1)
            self.p2.feedReward(0)
        elif self.currentState.winner == self.p2Symbol:
            self.p1.feedReward(0)
            self.p2.feedReward(1)
        else:
            self.p1.feedReward(0.1)
            self.p2.feedReward(0.5)

    第四個是個體的策略(policy)$\pi$,這個一般是學習得到的,我們會在每輪以較大的概率選擇當前價值最高的動作,同時以較小的概率去探索新動作,在這里AI的策略如下面代碼所示。

    里面的exploreRate就是我們的第八個要素探索率$\epsilon$。即策略是以$1-\epsilon$的概率選擇當前最大價值的動作,以$\epsilon$的概率隨機選擇新動作。

   # determine next action
    def takeAction(self):
        state = self.states[-1]
        nextStates = []
        nextPositions = []
        for i in range(BOARD_ROWS):
            for j in range(BOARD_COLS):
                if state.data[i, j] == 0:
                    nextPositions.append([i, j])
                    nextStates.append(state.nextState(i, j, self.symbol).getHash())
        if np.random.binomial(1, self.exploreRate):
            np.random.shuffle(nextPositions)
            # Not sure if truncating is the best way to deal with exploratory step
            # Maybe it's better to only skip this step rather than forget all the history
            self.states = []
            action = nextPositions[0]
            action.append(self.symbol)
            return action

        values = []
        for hash, pos in zip(nextStates, nextPositions):
            values.append((self.estimations[hash], pos))
        np.random.shuffle(values)
        values.sort(key=lambda x: x[0], reverse=True)
        action = values[0][1]
        action.append(self.symbol)
        return action

    第五個是價值函數,代碼里用value表示。價值函數的更新代碼里只考慮了當前動作的現有價值和得到的獎勵兩部分,可以認為我們的第六個模型要素衰減因子$\gamma$為0。具體的代碼部分如下,價值更新部分的代碼加粗。具體為什么會這樣更新價值函數我們以后會講。

    # update estimation according to reward
    def feedReward(self, reward):
        if len(self.states) == 0:
            return
        self.states = [state.getHash() for state in self.states]
        target = reward
        for latestState in reversed(self.states):
 value = self.estimations[latestState] + self.stepSize * (target - self.estimations[latestState])             self.estimations[latestState] = value
            target = value
        self.states = []

    第七個是環境的狀態轉化模型, 這里由於每一個動作后,環境的下一個模型狀態是確定的,也就是九宮格的每個格子是否有某個選手的棋子是確定的,因此轉化的概率都是1,不存在某個動作后會以一定的概率到某幾個新狀態,比較簡單。

    從這個例子,相信大家對於強化學習的建模會有一個初步的認識了。        

    以上就是強化學習的模型基礎,下一篇會討論馬爾科夫決策過程。

 

(歡迎轉載,轉載請注明出處。歡迎溝通交流: liujianping-ok@163.com)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM