強化學習(一)模型基礎

劉建平Pinard發表於2018-07-29

    從今天開始整理強化學習領域的知識,主要參考的資料是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)

相關文章