1. 程式人生 > >機器學習工程師 - Udacity 強化學習 Part Seven

機器學習工程師 - Udacity 強化學習 Part Seven

text Coding 平臺 底層 標量 公式 以及 規劃 依然

七、連續空間中的強化學習

1.復習強化學習
強化學習問題通常都會轉化為馬爾可夫決策流程,簡稱 MDP。一個 MDP 由一組狀態 S 動作 A 概率 P 獎勵 R 和折扣因子 γ 組成。P 表示不同轉換和獎勵的發生頻率,通常建模為單個聯合概率。任何時間步 t+1 的狀態和獎勵僅依賴於在上個時間步 t 的狀態和采取的動作。特定環境的這一特性稱之為馬爾可夫性。
我們通常對兩個量感興趣:我們嘗試估算或預測的狀態值 V(S),以及在特定狀態下采取的動作的值 Q(S,A)。後者可以幫助我們判斷應采取什麽樣的動作。這兩個映射或方法關系非常緊密,可以幫助我們找到問題的最優策略 π*,從而最大化接收的總獎勵。


註意,因為 MDP 本質上具有概率性,因此我們無法完全確定地預測未來將獲得什麽樣的獎勵以及持續多久,因此我們通常計算的是總預期獎勵。這時候就要提到折扣因子 γ 了。在計算狀態和動作值時,我們用它來為未來的獎勵分配更低的權重。
強化學習算法通常分為兩大類別:基於模型的方法,例如策略叠代以及需要已知轉換和獎勵模型的值叠代。它們本質上通過動態規劃並使用該模型以叠代方式計算期望的值函數和最優策略;另一方面,蒙特卡洛方法和時間差分學習等不基於模型的方法不需要明確的模型。它們通過執行探索性動作對環境抽樣並使用獲得的經驗直接估計值函數。

2.資源

編程:OpenAI Gym

在整個課程中,我們將使用 OpenAI Gym 作為編程練習。它是一個開發和分享強化學習算法的開源庫和平臺。如果你之前沒有使用過該平臺,建議你現在就熟悉一下該平臺。

閱讀 OpenAI Gym 文檔中的說明,以了解基本語法。

還建議你花時間查看 leaderboard,其中包含了每個任務的最佳解決方案。

請參閱此博客以詳細了解如何使用 OpenAI Gym 加快強化學習 (RL) 研究。

教科書:Sutton & Barto,第二版。

建議你閱讀這本經典強化學習教科書中的章節。我們在深度強化學習課程中介紹的知識可以在這本書的第 II 部分:逼近解決方案中找到。

請參閱此 GitHub 代碼庫 以查看教科書中的大部分圖表的 Python 實現。

3.Tile Coding
這是一種較通用的離散化方案:

技術分享圖片

這裏的底層狀態空間是連續的二維空間。我們在該空間上方疊加多個網格或拼貼,每層都稍微不對齊。狀態空間裏的任何位置 S 都可以粗略地通過它所激活的拼貼識別。如果我們為每個拼貼分配一個位,則可以將新離散化狀態表示為位向量:激活的位置為 1 其他位置為 0。


這種方法本身是一個非常高效的表示法,但是精彩之處在於如何使用該方案計算狀態值函數。

技術分享圖片

它由該狀態的位向量和每個拼貼的權重定義,而不是為每個狀態 V(s) 存儲單獨的值。Tile Coding 算法叠代地更新這些權重。這樣可以確保共享拼貼的臨近位置也共享狀態值的一些部分,從而有效地使所學的值函數更加平緩。

5.Adaptive Tile Coding
Tile Coding 也具有一些缺點。和簡單的網格方法一樣,我們需要提前手動選擇拼貼大小、偏移量、拼貼數量等等。一個更加靈活的方式是 Adaptive Tile Coding。

技術分享圖片

先從非常大的拼貼開始,然後在合適時將每個拼貼一分為二。如何判斷何時該拆分呢?我們可以采用試探法。也就是說,當我們意識到通過當前的表示法不再學到很多規律,即值函數不再改變時,我們就需要拆分狀態空間。當我們達到拼貼數量上限或叠代上限時可以停止拆分。
為了判斷應該拆分哪個拼貼,我們需要確定哪個拼貼最有可能對值函數的影響最大。為此,我們需要跟蹤子拼貼以及它們的預測權重,然後我們可以選擇子拼貼之間權重差別最大的拼貼,你還可以使用很多其他試探法。
Adaptive Tile Coding 的主要優勢是它不需要我們手動提前指定離散化方式,最終得到一個基於空間復雜程度的狀態空間的劃分。

6.Coarse Coding
Coarse Coding 和 Tile Coding 很像,但是使用一組更稀疏的特征來表示狀態空間。

技術分享圖片

想象一下在二維連續狀態空間上放下一堆圓圈,選擇任何一個狀態 S 即在該空間中的位置,並標記它所屬的所有圓圈構建一個位向量,這些圓圈用 1 表示,剩余圓圈用 0 表示。這就是狀態的稀疏編碼表示法。它也可以擴展到更高維度的空間,圓圈變成球面和超球面。
Coarse Coding 具有一些特性。圓圈越小,空間的泛化程度越低,學習算法需要持續更長時間,但是可以獲得更有效的分辨率;圓圈越大,泛化程度越高,通常會形成更平緩的值函數,你可以使用更少的大圓圈來涵蓋空間從而縮小表示法,但是可能會失去一定的分辨率。
我們不僅可以更改這些圓圈的大小,還可以從其他方面更改它們,例如更高或更寬,以便在一個維度裏獲得更高的分辨率。實際上,這種技巧可以泛化到幾乎任何形狀。
和在 Tile Coding 中一樣,Coarse Coding 形成的狀態表示法是二元向量。將每個拼貼或圓圈看做一個特征,如果是活躍狀態,則用 1 表示,否則用 0 表示。一個比較自然的擴展方法是,根據到每個圓圈中心的距離衡量該特征的活躍程度:

技術分享圖片

可以使用高斯或鐘形曲線使這種衡量方法或響應更加平緩。曲線在圓圈上居中,稱之為徑向基函數(RBF)。當然,形成的特征值不再離散化,因此又是另一個連續狀態向量,但是比較酷的是可以顯著降低特征數量。

7.函數逼近
到目前為止,我們已經討論了離散化連續狀態空間的各種方式,這些方式使我們能夠幾乎不做修改就能使用現有的強化學習算法。但是也存在一些限制。當底層空間很復雜時,所需的離散狀態數量可能會很大,因此就失去了離散化的優勢。此外,對於狀態空間裏臨近的位置,它們的值應該相似或者平滑地變化,但是離散化並非始終會利用這一特性,無法跨空間地有效泛化。我們要獲得的是真實的狀態值函數 vπ,或動作值函數 qπ,通常在整個空間內都比較平滑連續,可以想象,除了一些非常簡單的問題之外,我們的最佳希望是函數逼近。依然是逼近結果,因為我們不知道真正的底層函數是什麽。

技術分享圖片

定義此類函數逼近的一般方法是引入一個表示函數形狀的參數向量 W,我們的任務變成調整這個參數向量,直到找到理想的逼近結果。

技術分享圖片

註意逼近函數可以將狀態映射到其值,或將狀態動作對映射到相應的 q 值。另一種形式是從一個狀態映射到一堆不同的 q 值,同時映射到每個動作,這對 Q 學習來說尤其實用。

技術分享圖片

先來看看第一種情況:逼近狀態值函數,將狀態 S 和參數 W 轉換為標量值。但是如何轉換呢?首先我們需要確保有一個表示狀態的向量。你的狀態可能已經是一個向量,這樣的話你不需要進行任何處理。通常我們將定義一個轉換算法,將任何給定狀態 S 轉換為特征向量 X(s)。這樣也給我們帶來了更多的靈活性,因為我們不需要對原始狀態值進行運算。我們可以改為使用任何計算或推導的特征。

技術分享圖片

現在我們已經有了特征向量 X(s) 和參數向量 W,我們想要獲得一個標量值。如果我們有兩個向量並想要生成標量該怎麽辦?進行點積運算。沒錯,這是最簡單的方式。實際上,這和計算特征的線性組合一樣,將每個特征與相應的權重相乘,然後求和,稱之為線性函數逼近,即我們嘗試使用線性函數逼近底層值函數。

8.線性函數逼近
我們來仔細研究下線性函數逼近以及如何估算參數向量。你已經知道,線性函數是所有特征乘以相應的權重並求和的結果。假設你已經隨機初始化這些權重,並計算了狀態值 v^(s,w),如何調整 W 以使逼近函數越來越接近真函數?聽起來像一個數值優化問題。我們使用梯度下降來找到最優參數向量。註意,因為 v^ 是一個線性函數,相對於 W 的導數就是特征向量 x(s),這也是線性函數的優勢之一,以及為何如此受歡迎的原因。

技術分享圖片

我們想要縮小真值函數 vπ 和逼近值函數 v^ 之間的差異,我們寫成平方差,因為我們不關心誤差的符號,只想使差異降低到 0。更確切地來說,因為強化學習領域通常都是隨機的,這是預期平方差。
現在我們有了要優化的目標函數,為此我們將使用梯度下降,我們來計算該函數相對於 W 的梯度或導數。使用差分鏈式法則,結果是 -2 乘以值差異乘以 v^ 的導數,之前我們提到它就是特征向量 (x,s)。註意,我們去掉了這裏的期望運算符,側重於單個狀態 s 表示的誤差梯度。我們假設狀態是隨機選擇的,如果我們能夠抽樣足夠多的狀態,則可以非常接近預期值。我們將這個代入梯度下降更新規則的一般公式。α 是步長或學習速率參數。註意這裏的 -1/2是為了消去導數中的 -2。我們將使用這個基本公式叠代地降低每個樣本狀態的誤差,直到逼近函數和真函數幾乎相等。

技術分享圖片

直觀地解釋下梯度下降如何優化了參數向量。在每次叠代時,朝著誤差的相反方向小步地更改權重,因此這裏的特征向量可以指出哪個方向不合適,這樣我們就可以遠離該方向。

技術分享圖片

到目前為止,我們只討論了逼近狀態值函數,為了解決不基於模型的控制問題,即在未知環境中采取動作,我們需要逼近動作值函數。為此,我們可以定義一個利用狀態和動作的特征轉換,然後使用狀態值函數中用到的梯度下降方法。

技術分享圖片

最後,我們看看希望逼近函數同時計算所有動作值的情況。可以看做生成動作向量。為此,我們可以繼續使用之前的相同特征轉換,傳入狀態和動作。但是如何生成不同的動作值?

技術分享圖片

一種思考方式是,我們嘗試找到 n 個不同的動作值函數,每個動作維度對應一個函數。但是憑直覺,我們知道這些函數有關聯性,因此可以同時計算它們。為此,我們可以擴展權重向量並轉換為矩陣。矩陣的每列模擬一個單獨的線性函數,但是根據狀態和動作計算的共同特征使這些函數相互保持關聯性,如果我們的問題領域具有連續狀態空間和離散動作空間。這很常見。我們可以輕松地選擇值最大的動作。沒有這種平行處理的話,我們需要挨個解析每個動作,然後找到最大值。如果動作空間也是連續的,那麽這種形式使我們能夠同時輸出多個值。例如,如果我們在開車,則希望同時控制方向盤和油門。

線性函數逼近的主要限制條件是我們只能表示輸入和輸出之間的線性關系。對於一維輸入,則是一條線;對於二維輸入,變成平面,等等。如果底層的值函數是非線性形狀呢?線性逼近可能會產生非常糟糕的結果,這時候就需要開始研究非線性函數了。

9.對線性函數逼近進行簡單的擴展可以幫助我們捕獲非線性關系。

技術分享圖片

該方法的核心是特征轉換。還記得我們是如何以一般形式定義它的嗎?傳入狀態或狀態動作對並生成特征向量,該向量的每個元素都可以用單獨的函數生成,可以是非線性函數。例如,假設狀態 S 是一個實數,然後定義為 X1(S) = S,X2(S) = S2,X3(S) = S3 等等。這些叫做內核函數或基函數。它們將輸入狀態轉換為不同的空間。但是註意,因為值函數依然定義為這些特征的線性組合,我們依然可以使用線性函數逼近,這使得值函數能夠表示輸入狀態和輸出狀態之間的非線性關系。

技術分享圖片

徑向基函數是用於此目的很常見內核。本質上,將當前狀態 S 看做連續狀態空間內的位置,狀態空間表示為矩形平面,每個基函數都顯示為一個水泡,狀態越接近水泡的中心函數返回結果就越高,距離越遠返回結果沿著半徑逐漸減小,因此得名徑向基函數。從數學上來講,實現方式是將高斯內核與每個基函數相關聯,均值表示水泡的中心,標準偏差決定了返回結果降低的平緩程度。因此,對於任何給定狀態,我們可以將狀態表示法簡化為這些徑向基函數的返回結果向量,然後我們可以使用相同的函數逼近方法。

10.非線性函數逼近

技術分享圖片

在之前的討論中我們提到如何使用徑向基函數等隨機內核作為特征轉換捕獲輸入狀態和輸出值之間的非線性關系,在此模型中,輸出值相對於特征來說依然是線性的,如果底層的值函數相對於這些特征值的組合來說是非線性呢?為了捕獲這種復雜的關系,我們將通過點積獲得的線性返回結果傳入某個非線性函數 f 。看起來熟悉嗎?沒錯,它是人工神經網絡的基礎。此類非線性函數通常稱為激活函數,大大提高了逼近器的表示能力。

技術分享圖片

我們可以使用梯度下降叠代地更新任何此類函數的參數,學習速率 α 乘以值差異乘以函數相對於權重的導數。

機器學習工程師 - Udacity 強化學習 Part Seven