1. 程式人生 > >強化學習:函式逼近思想

強化學習:函式逼近思想

在開始這一篇內容之前,讓我們先回顧一下前8篇所提及的內容。概括地說,前八篇所講到的各種強化學習方法(DP、MC、TD等),有一個共同套路:即採用資料表儲存每一個狀態(state)的價值量(value),然後用不同的方式更新這些狀態的value,直至收斂;最後根據每個狀態下不同動作(action)對應的value,決定應該選擇哪個狀態,也就是確定了策略(policy)。儘管不同的方法之間有些小的差異,但是從本質上看是相似的。

但是從本篇開始提及的“函式近似”方法,卻在本質上有了幾個重大改變,也因此有了一些突出的特點。首先要說明的是:“函式近似”更像是一種思想,包含一類方法,從後面的章節就能看出來,基於這個思想,可以衍生出很多不同型別的方法。同時,該方法也正式把強化學習和機器學習聯絡起來,讓我們可以互相借鑑兩個領域的一些優勢。

那麼,函式近似這類方法,有什麼改變?第一、對狀態的價值量(value)的儲存使用函式來表徵,不再用資料表。第二、採用機器學習中流行的有監督訓練方式來更新函式的固有引數,直至函式收斂。一旦函式訓練完成,我們就自然得到了“狀態x”--“狀態價值量y”之間的對映關係,然後由狀態價值決定策略就是順理成章的事了。這兩個改變也相應帶來了顯著的特點:第一、函式近似方法不需要大量的儲存空間來存狀態,因為函式的引數個數通常遠遠少於環境狀態的數量(深度神經網路也許是個例外);第二、訓練出來的函式具備一定的泛化特性(這也是機器學習方法的常見特性),可以應對部分可觀測的環境,這對在實際問題中應用強化學習方法是個好事,因為很多時候我們是無法窮盡所有狀態的。

下面開始正式介紹這一類方法。

1. 函式近似思想

1.1 什麼是“函式近似”思想?

採用某種函式(線性函式或者非線性函式等等),基於小部分訓練樣本,來擬合價值函式的真值,比如 V_{\pi}(s)Q_{\pi}(s,a) ,使之在較大規模的測試樣本上同樣適用。這種思想的主要任務就是求該函式的最優引數。

1.2 為什麼引進“函式近似”思想?

(1)資料表形式的價值函式有缺陷。

到目前為止,我們對強化學習問題的討論,都侷限於tabular的形式,也就是採用一張表來儲存當前任務的價值函式。這張表,可以理解成python裡面的字典結構,任務中所有的“狀態/狀態-動作”作為keys,每個“狀態/狀態-動作”的價值作為values。為什麼這種資料表形式的強化學習會限制強化學習問題的規模呢?有如下兩個原因:1、記憶體空間。當問題規模超大時,儲存這麼一張表需要的記憶體空間是巨大的。2、計算時間和所需資料量。當問題規模變大後,再想準確地計算這張表中的每個值,需要的時間開銷是巨大的;同時,在很多實際任務中,有些狀態和動作是永遠不會出現的,這就導致價值函式很難準確計算。

上面這番文字提到的問題,簡單總結後,就是四個字:泛化問題,即在小規模資料上獲得的經驗,怎麼才能夠在大規模的資料上也適用?

(2)引數方程形式的價值函式可以解決上述泛化問題

使用函式近似的思想,我們只需找到一組最優的引數,也就確定了最優的擬合函式。這個擬合函式既不需要儲存大量的狀態價值資訊,也不要求看到整個狀態-動作空間。只要它的引數包含了整個狀態-動作空間背後的規律,那麼它就可以在任何情況下都表現良好,也就是泛化能力好。

1.3 需要注意的問題

函式近似思想來源於傳統的機器學習問題。將這種思想移植到強化學習問題中,自然會帶來一些問題。這是因為強化學習中存在很多傳統機器學習沒有的特點,比如:非穩定性(包括狀態分佈和獎勵分佈的不穩定性),自舉性(bootstrapping),目標的延後性。在將函式逼近思想融合到強化學習的過程中,這些問題都要考慮到並做出相應改進。

1.4 如何用函式近似思想解決on-policy prediction問題?

我們知道強化學習中存在on-policy和off-policy之分,也存在prediction和control問題之分。事實上,on-policy和off-policy的本質區別在於,更新某狀態的價值量時,所使用的方法是沿用既定的策略(on-policy)還是使用新策略(off-policy)。而prediction和control問題的本質區別在於所估計的是狀態價值函式V_{\pi}(s)還是動作價值函式 Q_{\pi}(s,a) 。其實這就是幾種相似但又有少許不同的問題,我們本篇就從on-policy的prediction問題入手,看看函式近似思想怎麼應用。

既然函式近似思想來源於傳統機器學習,那麼其主要步驟也跑不了機器學習那一套。在函式近似思想的定義中我們提到“這種思想的主要任務就是求該函式的引數”,如何求?分為以下三個步驟:

  • 確定價值函式的擬合模型
  • 確定待優化的目標函式
  • 確定引數的更新演算法

這三個環節層層遞進,初步給出我們解決on-policy prediction問題的框架,下面分別討論。

 

2. 確定價值函式的擬合模型

2.1 價值函式的引數方程表示

在前面幾章,價值函式都是採用資料表的形式儲存,一個蘿蔔一個坑。從這一章開始,我們開始採用引數方程的形式表示價值函式,寫法: \widehat{v}(s,\mathbf{w}) 。該寫法表示當權重向量為 \mathbf{w} 時,狀態s的價值近似值。比如: \widehat{v} 可以是關於狀態特徵的線性函式, \mathbf{w} 的每個元素表示每個特徵的權重; \widehat{v} 還可以是通過神經網路建模得到的非線性函式, \mathbf{w} 表示神經網路中神經元之間的連線權值。通過改變 \mathbf{w} ,我們可以得到各種各樣的擬合函式。一般來說, \mathbf{w} 的元素個數遠遠少於狀態的數量。每改變 \mathbf{w} 的任意一個元素,都會影響很多狀態價值的估計量。

2.2 確定訓練樣本

既然“函式近似”屬於監督學習的技巧,那麼必然需要構造訓練樣本,包括輸入和輸出。回憶一下我們之前在處理prediction問題時,總是會提到“反向更新”這個詞,也就是backups。比如在蒙特卡洛演算法中,backup過程是 S_t \rightarrow G_t ,也就是說,狀態 S_t 的value向著 G_t 的方向更新, G_t 叫做 backed-up \;value ,也叫做target;同理在TD(0)演算法中,反向更新過程是: S_t \rightarrow R_{t+1}+\gamma \widehat{v}(S_{t+1},\mathbf{w}_t)

於是我們自然就想到,可否把反向更新中的 s \rightarrow v 作為一條訓練樣本的input和output。這種形式的樣本表明狀態s的價值估計應該更傾向於v,而我們最終想要得到的擬合函式,其特點也應該是傾向於把狀態s的價值估計為v。因此我們確定將反向更新中的 s\rightarrow v 作為訓練樣本。

2.3 擬合模型的選擇

確定了訓練樣本之後,原則上我們可以選擇任何型別的監督學習模型來擬合訓練樣本。但是並非所有模型都合適,為什麼呢?這就需要我們研究一下強化學習任務的特點。

  1. 強化學習任務需要實時線上學習,一邊和環境互動一邊學習。因此需要一個效率很高的模型,可以不斷接收新增的訓練樣本進行快速學習。
  2. 強化學習任務需要處理"非穩態目標函式"問題。這個怎麼理解?在強化學習中,特別是按照GPI流程(見第四章動態規劃的4.6部分)進行value function和policy更新的情況下, q_{\pi} 經常隨著 \pi 變化,於是我們就要不斷地逼近這個變化的 q_{\pi} 。另外,就算 \pi 不變,那麼通過bootstrapping方法(比如DP中就用到)所產生的訓練樣本的目標價值也是非穩定的,同一個state,可能其目標價值是多個。

強化學習問題的上述兩個特點和傳統機器學習問題有所不同,因此我們選擇的函式擬合模型必須得能夠應付這兩個特點的任務。

我們在這裡先不提出具體的模型,只說明模型的必要特點,在下一篇第二部分中會討論具體的模型。

 

3. 確定待優化的目標函式

3.1 為什麼建立目標函式

我們知道,在機器學習中,為了得到一個準確的模型,需要時刻監控該模型的訓練演化過程,確保模型往好的方面進化。什麼是好的方面?怎麼確保呢?通常都是針對具體的任務,建立合適的目標函式(有時也叫損失函式),通過保證模型的更新始終朝著使損失函式不斷減小的方向,最終可以得到一組滿意的模型引數。

之所以之前我們從沒設立過明確的目標函式,是因為採用資料表儲存價值函式時,不需要這麼一個目標函式,因為價值函式經過不斷學習迭代,最終可以自動趨於收斂,得到真實值。此外,資料表儲存方式下,每個狀態的價值更新過程呈相互解耦關係:即A狀態的價值更新後,並不影響B、C狀態的價值,因為資料表的每個區域是相互隔離的。

但是,通過函式近似思想進行價值函式的估計時,這種解耦關係被打破了:A狀態的價值更新後,會導致模型引數 \mathbf{w} 發生變化,從而間接影響其他狀態的價值,因此不再有可能使所有狀態的價值都達到真實值。

所以,需要制定一個目標函式,這個目標函式,決定哪些狀態我們更在乎,哪些狀態我們不在乎。更在乎的狀態,適當提高它的價值估計精確度;不在乎的狀態,適當降低它的價值估計精確度。

3.2 確定目標函式

用數學語言做上面那件事,就是定義一個概率分佈 \mu(s) ,表示對每個狀態價值準確度的在乎程度。同時我們用價值近似值 \widehat{v}(s,\mathbf{w}) 和真值 v_{\pi}(s) 的均方差作為誤差的定義。結合這兩部分,我們定義目標函式如下:

MSVE(\mathbf{w}) \doteq \sum _{s \in S} \mu (s)[v_{\pi}(s)-\widehat{v}(s,\mathbf{w})]^2

MSVE全稱“Mean Squared Value Error”,均方價值誤差。

這裡再說一下 \mu(s) 的數學含義:通常 \mu(s) 表示在目標策略 \pi 下,花在狀態s上的時間佔總時間的比例。這時 \mu(s) 叫做“on-policy distribution”。在離散序列任務中, \mu(s) 略有不同,不能嚴格地叫做“概率分佈”,因為離散任務中初始狀態的選擇會對該分佈造成一些影響。因此我們也給出離散序列任務下的 \mu(s) 定義:

\mu (s) = h(s) + \sum _{\overline{s}}\mu (\overline{s})\sum \pi(a|\overline{s})p(s|\overline{s},a) \;\; \forall s \in S

其中h(s)表示狀態s被選中作為初始狀態的概率分佈。

需要提醒大家的是,MSVE並不一定是最好的評價指標,因為我們最終的目的是利用價值函式的估計值找到最優的policy,而滿足這個目的並非一定需要最小化MSVE。但是目前也並不清楚有啥更好的指標,因此還是繼續選用MSVE。

3.3 求解目標函式

既然目標函式是某種誤差,那麼求解該函式,就是使其值變得越小越好。為了最小化MSVE,其實我們要做的就是找到全域性最優解,也就是找到一個特定的 \mathbf{w*} ,使其滿足:

MSVE(\mathbf{w*}) \leq MSVE(\mathbf{w}) \;for \;all \;possible\; \mathbf{w}

值得注意的是,對於簡單的線性模型,這個 \mathbf{w*} 或許容易找到,但是對於複雜的非線性模型,比如神經網路或者決策樹,這個 \mathbf{w*} 很難得到。因此在複雜非線性模型中常用的替代方案是“尋找區域性最優解”,也就是找到一個 \mathbf{w*} ,使其滿足:

MSVE(\mathbf{w*}) \leq MSVE(\mathbf{w}) \;for \;all \; \mathbf{w}\; in \;some \;neighborhood \;of \;\mathbf{w*}

至此,我們介紹了基於函式近似思想擬合價值函式,進而解決強化學習問題的大框架。

從下一節開始,我們開始討論具體的引數更新演算法。這些方法主要是基於梯度下降理論。

 

4. 確定引數更新演算法

為了找到最優的引數 \mathbf{w*} ,需要從一開始的初始值向著最優值不斷迭代更新。有哪些迭代更新的演算法可以採用呢?

4.1 隨機梯度方法

接下來我們要討論的引數更新演算法主要基於隨機梯度下降理論(SGD)。SGD方法在引數更新中的運用極其廣泛,並且這類方法恰好也很適合實時線上的強化學習任務。

在梯度下降理論中, \mathbf{w}=(w_1,w_2,...,w_n)^T ,價值擬合函式 \widehat{v}(s,\mathbf{w}) 是定義在 s \in S 上,關於 \mathbf{w} 的光滑可微函式。我們會在整個訓練過程中的每個離散時間點上更新 \mathbf{w} ,因此我們需要一個新符號 \mathbf{w}_t 表明在每一個時間點t上的 \mathbf{w}

接下來,假定在我們的訓練樣本中的狀態分佈和上一節在MSVE那裡定義的分佈 \mu 相同。現在我們開始著手更新 \mathbf{w} ,很明顯的一個方法就是在觀測到的訓練樣本上儘可能地減小誤差。SGD方法會在每個隨機訓練樣本上按照MSVE誤差減小的方向更新 \mathbf{w} 。這裡我們會用到常見的梯度運算子,關於梯度的含義我在此就不贅述了,可以檢視大學數學課本。

總之, \mathbf{w} 的更新如下式:

\mathbf{w}_{t+1}=\mathbf{w}_{t} - 1/2 \alpha \triangledown_{\mathbf{w}_{t}}[v_{\pi}(S_t)-\widehat{v}(S_t,\mathbf{w}_t)]^2\\ = \mathbf{w}_{t}+\alpha[v_{\pi}(S_t)-\widehat{v}(S_t,\mathbf{w}_t)]\triangledown_{\mathbf{w}_{t}}\widehat{v}(S_t,\mathbf{w}_t)

從上式可以看出, \mathbf{w} 的更新量方向是沿著MSVE誤差的負梯度方向的,根據梯度的定義,這個方向也是誤差下降最快的方向。另外 \alpha 表示步長引數,控制著每次更新的幅度。

可能讀者會有疑問,為什麼要SGD每次沿誤差方向更新一小步,而不是直接徹底消除誤差呢?原因是:我們既不想要也不期待最終的價值函式能在所有狀態上的誤差全部為0。我們想要的是價值函式可以在不同狀態的誤差幅度之間獲得某種平衡。如果我們在每一個觀測到的狀態上都徹底消除誤差,那麼就會發現 \mathbf{w} 會不斷震盪,永遠也找不到區域性最優 \mathbf{w} 了。事實上,根據第二篇提到的“標準隨機近似條件”,步長引數 \alpha 需要隨著時間而不斷減小的,只有滿足了“標準隨機近似條件”(見第二章多臂賭博機下 2.5部分,梯度下降法才能保證收斂到區域性最優解。

現在我們要討論一個很重要的問題:訓練樣本的output部分,即 S_t\rightarrow U_t 中的 U_t ,如果不是真實值,怎麼辦?這在實際任務中很常見,因為 U_t 很可能是被噪聲影響的真實值 v_{\pi}(S_t) ,或者是其他狀態反向更新後的某個 \widehat{v} 。這時候,上述 \mathbf{w} 的更新公式就要改成如下所示,用 U_t 代替 v_{\pi}(S_t)

\mathbf{w}_{t}+\alpha[U_t-\widehat{v}(S_t,\mathbf{w}_t)]\triangledown_{\mathbf{w}_{t}}\widehat{v}(S_t,\mathbf{w}_t)

如果 U_tv_{\pi}(S_t) 的無偏估計值,即 E(U_t)=v_{\pi}(S_t) ,那麼根據“標準隨機近似條件”, \mathbf{w} 依然可以收斂(保證步長引數 \alpha 需要隨著時間而不斷減小)。如果 U_t 不是 v_{\pi}(S_t) 的無偏估計值,那麼 \mathbf{w} 就不能保證收斂。

U_t 作為 v_{\pi}(S_t) 的無偏估計值的一個典型案例是蒙特卡羅演算法的target value: G_t 。還記得 G_t 代表啥麼? G_t 表示狀態 S_t 對應的return,即獎勵值的總和(也可以是discounted sum)。因為 G_tv_{\pi}(S_t) 的無偏估計,因此梯度下降版本的蒙特卡洛價值函式估計演算法是可以確定找到區域性最優解的。

下面給出的是將傳統蒙特卡洛演算法改造成梯度下降版本蒙特卡洛演算法的虛擬碼:

 

4.2 半梯度方法

說完了收斂性質特別棒的蒙特卡洛演算法的target value,也就是訓練樣本的output,我們要來說幾個收斂性質不樂觀的target:就是採用自舉法(bootstrapping)估計得到價值估計值。

大家想一下有哪幾個演算法採用自舉法進行價值函式的估計?這裡有兩個:

  • TD(λ)前向視角的target value:TD(λ)的前向視角採用λ-return,所以其target value是 G_t^\lambda 。然而,當λ<1時, G_t^\lambda 不是 v_{\pi}(S_t) 的無偏估計,因此該方法的梯度下降版本無法找到區域性最優解。
  • DP的target value: E_{\pi}[R_{t+1}+\gamma \widehat{v}(S_{t+1},\mathbf{w})|S_t] 。同樣,DP中也採用了bootstrapping,它的target value也不是 v_{\pi}(S_t) 的無偏估計,因此該方法的梯度下降版本無法找到區域性最優解。

為什麼採用自舉法進行價值函式估計得到的target value收斂性質不好呢?因為從 \mathbf{w} 的梯度更新公式可以看出,target需要和 \mathbf{w}_t 相互獨立,互不影響。而這個條件一旦用了自舉法就無法被滿足(看下式標紅部分):

DP \;target:\;E_{\pi}[R_{t+1}+\gamma \widehat{v}(S_{t+1},{\color{Red} {\mathbf{w}}})|S_t]

這一類target代入梯度更新公式後,得到的只是部分梯度的下降,而不是真正的梯度下降,因此把這類梯度更新方法叫做:半梯度方法(semi-gradient methods)。

我們可以看到,半梯度下降演算法和梯度下降演算法的形式是一樣的,只是target的特點不一樣。區分這兩種引數更新演算法的唯一指標,就是看target,即訓練樣本的output,是否是input(狀態)真實價值的無偏估計。

半梯度方法雖然收斂性質不如真正的梯度下降方法,但是它有自己的優點:

  1. 半梯度方法線上性模型下可以保證收斂。
  2. 在可收斂的情形下,半梯度方法的收斂速度特別快。
  3. 半梯度方法可以用在連續性任務中,不必等到序列結束。

這裡給出一個半梯度方法的典型案例:semi-gradient TD(0)