強化學習(十三) 策略梯度(Policy Gradient)

    在前面講到的DQN系列強化學習算法中,咱們主要對價值函數進行了近似表示,基於價值來學習。這種Value Based強化學習方法在不少領域都獲得比較好的應用,可是Value Based強化學習方法也有不少侷限性,所以在另外一些場景下咱們須要其餘的方法,好比本篇討論的策略梯度(Policy Gradient),它是Policy Based強化學習方法,基於策略來學習。html

    本文參考了Sutton的強化學習書第13章和策略梯度的論文git

1. Value Based強化學習方法的不足

    DQN系列強化學習算法主要的問題主要有三點。github

    第一點是對連續動做的處理能力不足。DQN之類的方法通常都是隻處理離散動做,沒法處理連續動做。雖然有NAF DQN之類的變通方法,可是並不優雅。好比咱們以前提到的經典的冰球世界(PuckWorld) 強化學習問題,具體的動態demo見這裏。環境由一個正方形區域構成表明着冰球場地,場地內大的圓表明着運動員個體,小圓表明着目標冰球。在這個正方形環境中,小圓會每隔必定的時間隨機改變在場地的位置,而表明個體的大圓的任務就是儘量快的接近冰球目標。大圓能夠操做的行爲是在水平和豎直共四個方向上施加一個時間乘時長的力,藉此來改變大圓的速度。假如此時這個力的大小和方向是能夠靈活選擇的,那麼使用普通的DQN之類的算法就很差作了。由於此時策略是一個有具體值有方向的力,咱們能夠把這個力在水平和垂直方向分解。那麼這個力就是兩個連續的向量組成,這個策略使用離散的方式是很差表達的,可是用Policy Based強化學習方法卻很容易建模。算法

    第二點是對受限狀態下的問題處理能力不足。在使用特徵來描述狀態空間中的某一個狀態時,有可能由於個體觀測的限制或者建模的侷限,致使真實環境下原本不一樣的兩個狀態卻再咱們建模後擁有相同的特徵描述,進而頗有可能致使咱們的value Based方法沒法獲得最優解。此時使用Policy Based強化學習方法也頗有效。網絡

    第三點是沒法解決隨機策略問題。Value Based強化學習方法對應的最優策略一般是肯定性策略,由於其是從衆多行爲價值中選擇一個最大價值的行爲,而有些問題的最優策略倒是隨機策略,這種狀況下一樣是沒法經過基於價值的學習來求解的。這時也能夠考慮使用Policy Based強化學習方法。app

    因爲上面這些緣由,Value Based強化學習方法不能通吃全部的場景,咱們須要新的解決上述類別問題的方法,好比Policy Based強化學習方法。ide

2. Policy Based強化學習方法引入

    回想咱們在alue Based強化學習方法裏,咱們對價值函數進行了近似表示,引入了一個動做價值函數$\hat{q}$,這個函數由參數$w$描述,並接受狀態$s$與動做$a$做爲輸入,計算後獲得近似的動做價值,即:$$\hat{q}(s,a,w) \approx q_{\pi}(s,a)$$函數

    在Policy Based強化學習方法下,咱們採樣相似的思路,只不過這時咱們對策略進行近似表示。此時策略$\pi$能夠被被描述爲一個包含參數$\theta$的函數,即:$$\pi_{\theta}(s,a) = P(a|s,\theta)\approx  \pi(a|s)$$學習

    將策略表示成一個連續的函數後,咱們就能夠用連續函數的優化方法來尋找最優的策略了。而最經常使用的方法就是梯度上升法了,那麼這個梯度對應的優化目標如何定義呢?優化

3. 策略梯度的優化目標

    咱們要用梯度上升來尋找最優的梯度,首先就要找到一個能夠優化的函數目標。

    最簡單的優化目標就是初始狀態收穫的指望,即優化目標爲:$$J_1(\theta) = V_{\pi_{\theta}}(s_1) = \mathbb{E}_{\pi_{\theta}}(G_1) $$

    可是有的問題是沒有明確的初始狀態的,那麼咱們的優化目標能夠定義平均價值,即:$$J_{avV}(\theta) =\sum\limits_sd_{\pi_{\theta}}(s)V_{\pi_{\theta}}(s)$$

    其中,$d_{\pi_{\theta}}(s)$是基於策略$\pi_{\theta}$生成的馬爾科夫鏈關於狀態的靜態分佈。

    或者定義爲每一時間步的平均獎勵,即:$$J_{avR}(\theta) = =\sum\limits_sd_{\pi_{\theta}}(s) \sum\limits_a \pi_{\theta}(s,a) R_s^a$$

    不管咱們是採用$J_1,J_{avV}$仍是$J_{avR}$來表示優化目標,最終對$\theta$求導的梯度均可以表示爲:$$\nabla_{\theta} J(\theta) = \mathbb{E}_{\pi_{\theta}}[\nabla_{\theta}log \pi_{\theta}(s,a) Q_{\pi}(s,a)]$$

    具體的證實過程這裏就再也不列了,若是你們感興趣,能夠去看策略梯度的論文的附錄1,裏面有詳細的證實。

    固然咱們還能夠採用不少其餘可能的優化目標來作梯度上升,此時咱們的梯度式子裏面的$\nabla_{\theta}log \pi_{\theta}(s,a)$部分並不改變,變化的只是後面的$ Q_{\pi}(s,a)]$部分。對於$\nabla_{\theta}log \pi_{\theta}(s,a)$,咱們通常稱爲分值函數(score function)。

    如今梯度的式子已經有了,後面剩下的就是策略函數$\pi_{\theta}(s,a)$的設計了。

4. 策略函數的設計

    如今咱們回頭看一下策略函數$ \pi_{\theta}(s,a) $的設計,在前面它一直是一個數學符號。

    最經常使用的策略函數就是softmax策略函數了,它主要應用於離散空間中,softmax策略使用描述狀態和行爲的特徵$\phi(s,a)$ 與參數$\theta$的線性組合來權衡一個行爲發生的概率,即:$$\pi_{\theta}(s,a) = \frac{e^{\phi(s,a)^T\theta}}{\sum\limits_be^{\phi(s,b)^T\theta}}$$

    則經過求導很容易求出對應的分值函數爲:$$\nabla_{\theta}log \pi_{\theta}(s,a) = \phi(s,a) - \mathbb{E}_{\pi_{\theta}}[\phi(s,.)]$$

    另外一種高斯策略則是應用於連續行爲空間的一種經常使用策略。該策略對應的行爲從高斯分佈$ \mathbb{N(\phi(s)^T\theta, \sigma^2)}$中產生。高斯策略對應的分值函數求導能夠獲得爲:$$\nabla_{\theta}log \pi_{\theta}(s,a) =  = \frac{(a-\phi(s)^T\theta)\phi(s)}{\sigma^2}$$

    有策略梯度的公式和策略函數,咱們能夠獲得初版的策略梯度算法了。

5. 蒙特卡羅策略梯度reinforce算法

    這裏咱們討論最簡單的策略梯度算法,蒙特卡羅策略梯度reinforce算法, 使用價值函數$v(s)$來近似代替策略梯度公式裏面的$Q_{\pi}(s,a)$。算法的流程很簡單,以下所示:

    輸入:N個蒙特卡羅完整序列,訓練步長$\alpha$

    輸出:策略函數的參數$\theta$

    1. for 每一個蒙特卡羅序列:

    a. 用蒙特卡羅法計算序列每一個時間位置t的狀態價值$v_t$

    b. 對序列每一個時間位置t,使用梯度上升法,更新策略函數的參數$\theta$:$$\theta = \theta + \alpha \nabla_{\theta}log \pi_{\theta}(s_t,a_t)  v_t$$

       2. 返回策略函數的參數$\theta$

  這裏的策略函數能夠是softmax策略,高斯策略或者其餘策略。

 6. 策略梯度實例

    這裏給出第5節的蒙特卡羅策略梯度reinforce算法的一個實例。仍然使用了OpenAI Gym中的CartPole-v0遊戲來做爲咱們算法應用。CartPole-v0遊戲的介紹參見這裏。它比較簡單,基本要求就是控制下面的cart移動使鏈接在上面的pole保持垂直不倒。這個任務只有兩個離散動做,要麼向左用力,要麼向右用力。而state狀態就是這個cart的位置和速度, pole的角度和角速度,4維的特徵。堅持到200分的獎勵則爲過關。

     完整的代碼參見個人github:https://github.com/ljpzzz/machinelearning/blob/master/reinforcement-learning/policy_gradient.py

    這裏咱們採用softmax策略做爲咱們的策略函數,同時,softmax的前置部分,也就是咱們的策略模型用一個三層的softmax神經網絡來表示。這樣好處就是梯度的更新能夠交給神經網絡來作。

    咱們的softmax神經網絡的結構以下,注意這個網絡不是價值Q網絡,而是策略網絡:

    def create_softmax_network(self):
        # network weights
        W1 = self.weight_variable([self.state_dim, 20])
        b1 = self.bias_variable([20])
        W2 = self.weight_variable([20, self.action_dim])
        b2 = self.bias_variable([self.action_dim])
        # input layer
        self.state_input = tf.placeholder("float", [None, self.state_dim])
        self.tf_acts = tf.placeholder(tf.int32, [None, ], name="actions_num")
        self.tf_vt = tf.placeholder(tf.float32, [None, ], name="actions_value")
        # hidden layers
        h_layer = tf.nn.relu(tf.matmul(self.state_input, W1) + b1)
        # softmax layer
        self.softmax_input = tf.matmul(h_layer, W2) + b2
        #softmax output
        self.all_act_prob = tf.nn.softmax(self.softmax_input, name='act_prob')
        self.neg_log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=self.softmax_input,
                                                                      labels=self.tf_acts)
        self.loss = tf.reduce_mean(self.neg_log_prob * self.tf_vt)  # reward guided loss

        self.train_op = tf.train.AdamOptimizer(LEARNING_RATE).minimize(self.loss)

    注意咱們的損失函數是softmax交叉熵損失函數和狀態價值函數的乘積,這樣TensorFlow後面能夠自動幫咱們作梯度的迭代優化。

    另外一個要注意的點就是蒙特卡羅法裏面價值函數的計算,通常是從後向前算,這樣前面的價值的計算能夠利用後面的價值做爲中間結果,簡化計算,對應代碼以下:

    def learn(self):

        discounted_ep_rs = np.zeros_like(self.ep_rs)
        running_add = 0
        for t in reversed(range(0, len(self.ep_rs))):
            running_add = running_add * GAMMA + self.ep_rs[t]
            discounted_ep_rs[t] = running_add

        discounted_ep_rs -= np.mean(discounted_ep_rs)
        discounted_ep_rs /= np.std(discounted_ep_rs)

    其他部分和以前的DQN的代碼相似。

7. 策略梯度小結

    策略梯度提供了和DQN之類的方法不一樣的新思路,可是咱們上面的蒙特卡羅策略梯度reinforce算法卻並不完美。因爲是蒙特卡羅法,咱們須要徹底的序列樣本才能作算法迭代,同時蒙特卡羅法使用收穫的指望來計算狀態價值,會致使行爲有較多的變異性,咱們的參數更新的方向極可能不是策略梯度的最優方向。

    所以,Policy Based的強化學習方法還須要改進,注意到咱們以前有Value Based強化學習方法,那麼二者能不能結合起來一塊兒使用呢?下一篇咱們討論Policy Based+Value Based結合的策略梯度方法Actor-Critic。

    

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

相關文章
相關標籤/搜索