Berkeley CS294-112 深度增強學習 筆記 (4) 策略梯度法

前言:我個人向大家推薦伯克利大學的這門深度增強學習課程。這門課程的內容非常精彩,乾貨滿滿。事實上這門課程的完整版已經開設兩個學期,廣受關注,知乎內外已不乏點評,也有不錯的學習筆記。本筆記試圖較詳細地談談我自己的學習過程和理解,形成補充。課程內容的版權由伯克利大學所有,中文解釋說明的版權由我保留。由於該課程比較傾向於機器人學的應用,本人非工科專業,水平有限,有疏漏錯誤之處還請各路高手不吝賜教。如果能對大家有點滴用途,自當欣喜不已。

上一篇:謝天:Berkeley CS294-112 深度增強學習 筆記 (3) 增強學習簡介


策略梯度法

在上一篇中,我們已經熟悉了智能體通過增強學習與環境打交道的運作機理:當前智能體處於某個狀態mathbf{s},會根據某種諸如由參數為	heta的神經網路所表示的策略pi_	heta(mathbf{a}|mathbf{s}),得到行動mathbf{a},作用於環境中,由環境內在的某種動態決定的狀態轉移概率p(mathbf{s}|mathbf{s},mathbf{a})得到新的狀態,接著循環往複。我們也知道了根據這樣的決策過程,由Markov性,一個軌跡的出現概率是p_	heta(	au)=p(mathbf{s}_1)prod_{t=1}^Tpi_	heta(mathbf{a}_t|mathbf{s}_t)p(mathbf{s}_{t+1}|mathbf{s}_t,mathbf{a}_t)。我們的目標是選出一組最優的神經網路參數	heta^*最大化總收益函數的關於軌跡分布的期望max_	hetamathbf{E}_{	ausim p_	heta(	au)}left[sum_tr(mathbf{s}_t,mathbf{a}_t)
ight]

首先我們要研究怎麼去評估這個目標,然後再考慮如何去改進當前的策略。我們把目標函數記作J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}left[sum_tr(mathbf{s}_t,mathbf{a}_t)
ight]。除非我們的分布性質非常乾淨譬如說高斯分布,通常我們不能精確地對這個期望進行評估,但我們可以去用蒙特卡洛方法抽樣近似。如果我們根據軌跡分布來抽樣的話,目標函數的一個無偏估計是frac{1}{N}sum_isum_tr(mathbf{s}_{i,t},mathbf{a}_{i,t}),其中樣本量為N,第i個樣本在t時刻的狀態為mathbf{s}_{i,t},行動為mathbf{a}_{i,t}。因為分布是關於我們當前策略的,因此我們抽樣的方式是在實際環境或者模擬器中運行我們的策略,來生成這些軌跡。如對於機器人,只是讓它去嘗試完成任務,看它做得怎麼樣。同樣策略下,不同軌跡可能有些做得好有些做得不好,對每個軌跡得到一個評分sum_tr(mathbf{s}_{i,t},mathbf{a}_{i,t}),然後把這些評分平均起來來近似我們的目標函數。這是一個最簡單的利用蒙特卡洛方法來評估一個策略是否好的方式。

現在考慮怎麼去改進策略,在連續優化中最常見的方法是計算其梯度,然後讓參數走一個梯度步。現在看怎麼在這個目標中實現這個步驟。令軌跡的收益r(	au)=sum_tr(mathbf{s}_t,mathbf{a}_t),則J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}[r(	au)]。根據期望的定義,J(	heta)=int p_	heta(	au)r(	au)mathrm{d}	au。它的梯度為
abla_	heta J(	heta)=int 
abla_	heta p_	heta(	au)r(	au)mathrm{d}	au,因此其實我們關心的主要是
abla_	heta p_	heta(	au)這個部分。以下有一個非常重要的恆等式:

p_	heta(	au)
abla_	heta log p_	heta(	au)=p_	heta(	au)frac{
abla_	heta p_	heta(	au)}{p_	heta(	au)}=
abla_	heta p_	heta(	au)

我們把這個式子代回去,得到
abla_	heta J(	heta)=int p_	heta(	au)
abla_	heta log p_	heta(	au)r(	au)mathrm{d}	au,因為式子中又再度出現了p_	heta(	au)這個概率,它本質上又變回了一個期望:
abla_	heta J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}[
abla_	heta log p_	heta(	au)r(	au)]。回想我們的概率表達形式p_	heta(	au)=p(mathbf{s}_1)prod_{t=1}^Tpi_	heta(mathbf{a}_t|mathbf{s}_t)p(mathbf{s}_{t+1}|mathbf{s}_t,mathbf{a}_t),將兩邊取對數,得到log p_	heta(	au)=log p(mathbf{s}_1)+sum_{t=1}^T[log pi_	heta(mathbf{a}_t|mathbf{s}_t)+log p(mathbf{s}_{t+1}|mathbf{s}_t,mathbf{a}_t)]。在原式子中,我們需要的是這個東西關於	heta的梯度,而事實上初始分布和轉移概率本身都與參數	heta並不相關。因此形式上只有
abla_	hetalog p_	heta(	au)=sum_{t=1}^T
abla_	hetalog pi_	heta(mathbf{a}_t|mathbf{s}_t)。再將r(	au)展開,我們得到的最終形式如
abla_	heta J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}left[left(sum_{t=1}^T
abla_	hetalog pi_	heta(mathbf{a}_t|mathbf{s}_t)
ight)left(sum_{t=1}^Tr(mathbf{s}_t,mathbf{a}_t)
ight)
ight]。這個形式的最大優點是,它不需要我們知道狀態的初始分布,也不需要我們知道轉移概率:而這兩者通常正是非常困難的!這一點是非常重要的,我們只需要從環境中抽一些樣本來估計一個期望,然後我們唯一需要知道的事情是關於我們策略的梯度,不需要知道這個環境本身是什麼樣的。

關於蒙特卡洛估計方法,與之前類似,我們也可以從實際系統中抽樣,用
abla_	heta J(	heta)approxfrac{1}{N}sum_{i=1}^Nleft[left(sum_{t=1}^T
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t})
ight)left(sum_{t=1}^Tr(mathbf{s}_{i,t},mathbf{a}_{i,t})
ight)
ight]來作為一個無偏估計。得到梯度後,使用梯度上升法走一個的梯度步	hetaleftarrow	heta+alpha
abla_	heta J(	heta)。我們在上一篇提到過一般的增強學習演算法都可以由三大塊構成,第一步橙色方塊是我們生成很多樣本,用於估計目標函數和梯度;第二步綠色方塊用來估計收益sum_{t=1}^Tr(mathbf{s}_{i,t},mathbf{a}_{i,t}),用於判斷我們的策略有多好,非常簡單,只需要一個加總;第三步藍色方塊需要我們搞清楚
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t}),求出梯度然後走一個梯度步。這樣,我們就得到了一個最簡單的策略梯度法REINFORCE (Williams, 1992):

  1. 運行策略pi_	heta(mathbf{a}|mathbf{s}),抽取樣本{	au^i}
  2. 估計梯度
abla_	heta J(	heta)approxfrac{1}{N}sum_{i=1}^Nleft[left(sum_{t=1}^T
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t})
ight)left(sum_{t=1}^Tr(mathbf{s}_{i,t},mathbf{a}_{i,t})
ight)
ight]
  3. 走一個梯度上升步	hetaleftarrow	heta+alpha
abla_	heta J(	heta)

不幸的是,通常直接這麼做效果不會很好,因此我們需要做很多工作讓它能真正運行起來。但在優化這個演算法之前,我們首先要解決之前的遺留問題,搞清楚
abla_	hetalog pi_	heta(mathbf{a}_t|mathbf{s}_t)到底是什麼。這個是根據策略分布不同而有差異的,譬如說之前我們所講述的模仿學習之中,模仿學習也想學習一個策略pi_	heta(mathbf{a}_t|mathbf{s}_t),從一個狀態輸出一個行動之類:假設我們只有兩種操作,向左轉或者向右轉,那麼策略就變成了一個向左或者向右的概率。

考慮一個人形機器人的控制問題。此時小人需要得到連續的控制變數,而不是離散的。假設我們的策略函數輸出的是一個高斯分布,形如pi_	heta(mathbf{a}_t|mathbf{s}_t)=mathcal{N}(f_{神經網路}(mathbf{s}_t);Sigma),我們的神經網路根據當前狀態輸出均值,而一個簡單的情形,協方差矩陣可能是固定的。根據分布函數,我們有logpi_	heta(mathbf{a}_t|mathbf{s}_t)=-frac{1}{2}Vert f(mathbf{s}_t)-mathbf{a}_tVert_Sigma^2+	ext{const},形式非常簡單;將它取梯度,得到
abla_	hetalogpi_	heta(mathbf{a}_t|mathbf{s}_t)=-frac{1}{2}Sigma^{-1}( f(mathbf{s}_t)-mathbf{a}_t)frac{mathrm{d}f}{mathrm{d}	heta}。在實踐中,frac{mathrm{d}f}{mathrm{d}	heta}是對神經網路取梯度,需要一次反向傳播。而訓練神經網路我們也是走一個梯度步,因此我們只需要在走梯度步的時候乘上權重-frac{1}{2}Sigma^{-1}( f(mathbf{s}_t)-mathbf{a}_t)left(sum_tr(mathbf{s}_t,mathbf{a}_t)
ight)就行。

我們回顧一下之前我們都做了些什麼。我們用軌跡樣本近似了目標函數的梯度
abla_	heta J(	heta)approxfrac{1}{N}sum_{i=1}^N
abla_	heta log p_	heta(	au_i)r(	au_i)。在普通的監督學習之中,我們可能會嘗試使用極大似然估計,梯度是
abla_	heta J_mathrm{ML}(	heta)approxfrac{1}{N}sum_{i=1}^N
abla_	heta log p_	heta(	au_i)。可以發現策略梯度在做非常相似的事情,除了策略梯度法嘗試對不同的樣本進行加權,權重是收益函數之和。每個樣本的收益可正可負,因此在行為上,極大似然估計梯度總是嘗試去增加所有樣本的出現概率,而策略梯度法則嘗試去減少一些不好的樣本的出現概率,增加其他樣本的出現概率,屬於一個趨利避害的試錯過程的梯度上升法版本。在計算機程序上,這兩者也是非常相似的:如果我們能有代碼計算極大似然估計,那麼它也可以稍作修改以執行策略梯度法。

如果我們的觀測不完全,即只有部分觀測信息,怎麼辦?在策略梯度法中,這不是個問題。我們可以得到基於觀測的梯度
abla_	heta J(	heta)approxfrac{1}{N}sum_{i=1}^Nleft[left(sum_{t=1}^T
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{o}_{i,t})
ight)left(sum_{t=1}^Tr(mathbf{o}_{i,t},mathbf{a}_{i,t})
ight)
ight],可以發現這個式子中完全沒有用到Markov性。也就是說,我們可以直接在POMDP中使用策略梯度法,不需要任何的修改;但是在之後的諸如演員-評論家演算法、Q學習演算法之類的,這個性質往往是不成立的。這是策略梯度法的一大優勢。但即便如此,它不能保證你能得到一個運行得很好的策略,因為非Markov性可能導致真正運行得好的策略和之前的歷史有關,但是它能在你的策略簇中找到一個不錯的策略。如果你覺得歷史還是非常重要的,那麼可能使用一個RNN會好一些。

策略梯度法通常會有一些問題。第一個問題下一節會講,第二個問題我們會在將來討論怎麼去緩解。

第一個問題:在兩個圖中,x軸代表軌跡,而y軸代表軌跡對應的收益。藍色實線是我們選取策略的分布密度。我們從分布之中抽取了三個樣本,在(a)圖中,可以發現最左邊的樣本的收益是一個很大的負數,而右邊兩個都是很小的正數。我們想做的就是把我們的策略右移到右邊的虛線,使得在壞的位置密度更低,好的位置密度更高。實際上,正負的數值對這個演算法影響很大:兩個小正數和一個大負數可能把步伐拉得比較大。而我們(b)圖中,只是把收益都加上了一個很大的常數,收益之間的相對差不變。如果我們把所有情況的收益都增減同一個常數,我們可以把這個常數從這個期望中提出來,作為一個與參數無關的部分,因此整個期望關於參數求梯度的結果是不發生變化的。此時,策略梯度法就會想增加第一個樣本的概率(行為發生了根本性變化),但更想增加後兩個的概率。這個情況下,移動的步伐就小了很多,取而代之的是可能方差就增大了,變得更平緩了。這一點被稱為「高方差」問題。一個更極端的情形是,有很好的樣本,但是它的收益函數是0(其他的樣本收益為負數),那麼如何動完全依賴於我現在的策略在什麼位置。我們只需要把獎勵函數整體上下移動,就可以完全改變策略梯度法的行為。這個問題主要是因為如果我們選取無數個樣本的話,那麼這些差異互相會被抵消掉;但是對有限個樣本的選擇會很有偏差,就會導致這樣的問題:對於這樣的高方差問題,當然增加樣本總是能緩解的,但是增加樣本也使得學習效率降低。

第二個問題:讓我們考慮一個一維的連續狀態和行動的增強學習問題。參數是	heta=(k,sigma)。對數策略函數是一個高斯分布,由這兩個參數確定,整個簇的形式是logpi_	heta(mathbf{a}_t|mathbf{s}_t)=-frac{1}{2sigma^2}(kmathbf{s}_t-mathbf{a}_t)^2+	ext{const},依賴於行動和均值之差的平方,其中均值是當前狀態的k倍。收益函數r(mathbf{s}_t,mathbf{a}_t)=-mathbf{s}_t^2-mathbf{a}_t^2,前一部分表明最終狀態希望是0,後一部分說明我們希望行動大小盡量小:這在機械中是很合理的,如果我們的行動是電動機指令的話,通常不希望讓電動機運轉過強。在最優控制領域,這是一個LQR問題,可以用解析方法求出最優解,也很容易分析。但是在策略梯度法中,有趣的是,因為收益函數希望行動盡量小,梯度法總會傾向於減小sigma(見上圖,藍色箭頭為梯度,總在降低sigma的方向),用於減少很大的mathbf{a}_t的概率:因為概率來源於高斯分布,而高斯分布的支撐集非常大。事實上,更小的sigma,更傾向於讓我們進一步減少sigma。即便我們的梯度總是指向正確的方向,它在sigma上的分量更長些:在sigma很小時候,k分量的大小可以忽略不計了。因此一個結果是,我們會快速下降sigma,然而逐漸地k就不動了,所以最終得到一個正確結果的速度奇慢無比。這也導致了策略梯度法的收斂速度很慢,而且選擇學習率也是一個很難的問題:如果因為收斂速度慢而使用了較大的步長,反而更快地進入了一個讓k難以動彈的狀況。

方差削減

第一種方法是使用因果關係 (casuality)。回顧我們的梯度為
abla_	heta J(	heta)approxfrac{1}{N}sum_{i=1}^Nleft[left(sum_{t=1}^T
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t})
ight)left(sum_{t=1}^Tr(mathbf{s}_{i,t},mathbf{a}_{i,t})
ight)
ight]。因果關係指的是,在時間點t的策略不能影響時間點t<t的收益。這個關係看起來很蠢,就像今天做的事情不會影響昨天已經發生的事情。而事實上我們可以用這個關係得到更好的估計量。我們把後者這個括弧做進前面去,
abla_	heta J(	heta)approxfrac{1}{N}sum_{i=1}^Nsum_{t=1}^Tleft[
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t})left(sum_{t=1}^Tr(mathbf{s}_{i,t},mathbf{a}_{i,t})
ight)
ight]。從另一個角度看,我們根據概率的可加性有
abla_	heta J(	heta)=sum_{t=1}^T
abla_	heta mathbf{E}[r(mathbf{s}_t,mathbf{a}_t)] ,其中
abla_	heta mathbf{E}[r(mathbf{s}_t,mathbf{a}_t)]=mathbf{E}left[left(sum_{t=1}^t
abla_	hetalog pi_	heta(mathbf{a}_{t}|mathbf{s}_{t})
ight)r(mathbf{s}_t,mathbf{a}_t)
ight],相當於是一個在當前時點截斷的軌跡,因為t時刻的收益的概率分布之和之前有關而與之後無關。我們將雙重求和號調整順序,得到
abla_	heta J(	heta)approxfrac{1}{N}sum_{i=1}^Nsum_{t=1}^Tleft[
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t})left(sum_{t=t}^Tr(mathbf{s}_{i,t},mathbf{a}_{i,t})
ight)
ight]:正好是我們之前論述的,一個策略隻影響從它之後的部分。我們把hat{Q}_{i,t}=sum_{t=t}^Tr(mathbf{s}_{i,t},mathbf{a}_{i,t})記作今後收益 (reward-to-go),也就是從這個時刻起的收益。這樣做的一大好處就是,我們這樣採樣做,數值求和上減少了,方差也傾向於隨之減少;更重要的是我們幾乎沒有理由不這麼做,這麼做基本上總是好的,即便是計算上實現起來稍微複雜了一點,但也只是一個從後往前加的後綴和的事情。

第二種有效的方法是基準線 (baseline)。回到
abla_	heta J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}[
abla_	heta log p_	heta(	au)r(	au)],我們希望好的軌跡的收益函數是正的,而差的軌跡是負的。然而之前也提到了它對值非常敏感,如果收益函數增加或者減少一個常數,結果就會很不同。所以我們想做的,可能是不依賴於軌跡自身有多好,而是一條軌跡比平均好多少:這裡的平均指的是我們平時通常情況的普遍收益。舉個例子,平均可以是b=frac{1}{N}sum_{i=1}^Nr(	au_i),然後我們使用
abla_	heta J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}[
abla_	heta log p_	heta(	au)(r(	au)-b)]。看起來是非常合理的,而且更重要的是在這裡b是某個常數的話,這樣做總是對的。數學上,mathbf{E}_{	ausim p_	heta(	au)}[
abla_	heta log p_	heta(	au)b]=int p_	heta(	au)
abla_	heta log p_	heta(	au)bmathrm{d}	au=int 
abla_	heta p_	heta(	au)bmathrm{d}	au=b
abla_	hetaint p_	heta(	au)mathrm{d}	au=b
abla_	heta1=0 。其中第一個等號是把期望寫成積分形式,第二個等號直接利用了我們之前的恆等關係p_	heta(	au)
abla_	heta log p_	heta(	au)=
abla_	heta p_	heta(	au),第三個利用了b是常數和積分微分可交換的性質,第四個利用了對一個概率密度積分恆等於1的性質。因此我們減去一個常數的基準線,這樣得到的估計總是在期望意義下無偏的。

當然,我們這麼取平均得到一個基線常數不見得是最好的,但是實際效果卻通常較好。為了降低方差,我們可以求出一個理論上最優的b。回憶方差的表達式為	ext{Var}[X]=mathbf{E}[X^2]-mathbf{E}[X]^2。而
abla_	heta J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}[
abla_	heta log p_	heta(	au)(r(	au)-b)],其方差為: 	ext{Var}=mathbf{E}_{	ausim p_	heta(	au)}[(
abla_	heta log p_	heta(	au)(r(	au)-b))^2]-mathbf{E}_{	ausim p_	heta(	au)}[
abla_	heta log p_	heta(	au)(r(	au)-b)]^2 ,而我們在前面已經證明了後面一塊等價於mathbf{E}_{	ausim p_	heta(	au)}[
abla_	heta log p_	heta(	au)r(	au)]^2,與b是不相關的。我們將方差取微商取一階最優性條件,令g(	au):=
abla_	heta log p_	heta(	au),得到 frac{mathrm{d}	ext{Var}}{mathrm{d}b}=frac{mathrm{d}}{mathrm{d}b}mathbf{E}[g(	au)^2(r(	au)-b)^2]=frac{mathrm{d}}{mathrm{d}b}left(mathbf{E}[g(	au)^2 r(	au)^2]-2bmathbf{E}[g(	au)^2 r(	au)]+b^2mathbf{E}[g(	au)^2]
ight) ,其中第一項微分後為0。要使該微商等於0,則需要-2mathbf{E}[g(	au)^2 r(	au)]+2b^*mathbf{E}[g(	au)^2]=0,因此最優解b^*=frac{mathbf{E}[g(	au)^2 r(	au)]}{mathbf{E}[g(	au)^2]}。本質上來說,它是一個關於概率梯度的加權平均,不同樣本的權重不同是因為概率的梯度不同。而我們前面說的簡單平均只是它的一個粗糙簡化版本而已,也是有一些理論根據的。在實踐中也沒有發現很大的效果差異。

離線的策略梯度法

我們不難發現策略梯度法是一個在線 (on-policy) 演算法,這是因為策略梯度
abla_	heta J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}[
abla_	heta log p_	heta(	au)r(	au)],求期望的時候必須是從當前的分布上採樣才能有無偏性,而這就要求每次梯度更新之後就根據新分布全部重新採樣:如果策略是一個非常複雜的神經網路,每次迭代可能只更新一點點,但也要求把之前的樣本全都扔了然後重新採樣,對數據的利用率是非常低的。在前面也提到了,使用策略梯度法選擇學習率可能是很難的,收斂速度也可以非常低。

如果我們沒有從最新的p_	heta(	au)中得到的樣本呢?雖然我們還是要求去估計期望,但是我們可以考慮用其他分布去估計它。假設我們有一堆從分布hat{p}(	au)中抽取出來的數據,並知道對應的軌跡和收益,那我們就可以使用重要性抽樣 (importance sampling) 的方法。

重要性抽樣的原理是mathbf{E}_{xsim p(x)}[f(x)]=int p(x)f(x)mathrm{d}x=int q(x)frac{p(x)}{q(x)}f(x)mathrm{d}x=mathbf{E}_{xsim q(x)}left[frac{p(x)}{q(x)}f(x)
ight] ,給了我們用其他分布的數據進行無偏估計的方法,但前面需要乘上一塊東西,算是重新加個權重。

換到我們的目標函數上,則J(	heta)=mathbf{E}_{	ausim ar{p}(	au)}left[frac{p_	heta(	au)}{ar{p}(	au)}r(	au)
ight]。這裡我們需要具體分析這個權重是什麼。由於p_	heta(	au)=p(mathbf{s}_1)prod_{t=1}^Tpi_	heta(mathbf{a}_t|mathbf{s}_t)p(mathbf{s}_{t+1}|mathbf{s}_t,mathbf{a}_t)frac{p_	heta(	au)}{ar{p}(	au)}=frac{p(mathbf{s}_1)prod_{t=1}^Tpi_	heta(mathbf{a}_t|mathbf{s}_t)p(mathbf{s}_{t+1}|mathbf{s}_t,mathbf{a}_t)}{p(mathbf{s}_1)prod_{t=1}^Tar{pi}(mathbf{a}_t|mathbf{s}_t)p(mathbf{s}_{t+1}|mathbf{s}_t,mathbf{a}_t)}=frac{prod_{t=1}^Tpi_	heta(mathbf{a}_t|mathbf{s}_t)}{prod_{t=1}^Tar{pi}(mathbf{a}_t|mathbf{s}_t)},同樣最難處理的初始分布和轉移概率也被消掉了:我們依然保持了無需知道這些繁瑣內容的性質。在實踐上可能會有一些問題,但是至少在理論上還是無偏的:只要給定足夠多的樣本就行。

現在我們要求出目標函數的梯度了。使用重要性抽樣的技術,J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}left[frac{p_{	heta}(	au)}{p_{	heta}(	au)}r(	au)
ight],可以發現與	heta有關的部分僅僅是p_{	heta}(	au),因此將目標函數求梯度得
abla_{	heta}J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}left[frac{
abla_{	heta}p_{	heta}(	au)}{p_{	heta}(	au)}r(	au)
ight]。繼續利用恆等式p_	heta(	au)
abla_	heta log p_	heta(	au)=
abla_	heta p_	heta(	au),得到
abla_{	heta}J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}left[frac{p_{	heta}(	au)}{p_{	heta}(	au)}
abla_{	heta}log p_{	heta}(	au)r(	au)
ight]。我們將其展開,
abla_{	heta}J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}left[left(prod_{t=1}^Tfrac{pi_{	heta}(mathbf{a}_t|mathbf{s}_t)}{pi_{	heta}(mathbf{a}_t|mathbf{s}_t)}
ight)left(sum_{t=1}^T
abla_{	heta}log pi_{	heta}(mathbf{a}_t|mathbf{s}_t)
ight)left(sum_{t=1}^Tr(mathbf{s}_t,mathbf{a}_t)
ight)
ight] 這個和之前還是比較相似的,只是前面加了一塊權重。同樣,之前所說的因果關係可以加到這裡來,類似的推導過程可以得到
abla_{	heta}J(	heta)=mathbf{E}_{	ausim p_	heta(	au)}left[sum_{t=1}^T
abla_{	heta}log pi_{	heta}(mathbf{a}_t|mathbf{s}_t)left(prod_{t=1}^tfrac{pi_{	heta}(mathbf{a}_{t}|mathbf{s}_{t})}{pi_{	heta}(mathbf{a}_{t}|mathbf{s}_{t})}
ight)left(sum_{t=t}^Tr(mathbf{s}_{t},mathbf{a}_{t})
ight)
ight] ,可以理解為概率這塊到此時為止,而收益從此時開始看起。

那麼這麼做的問題主要在哪裡呢?我們不難看出中間這塊連乘部分的數值,是關於T指數增長的,如果每個數都略小於1,而時間軸非常長,這個乘積最終將非常接近於0,這樣梯度效果就會很差了。

在課程的後面會具體介紹怎麼解決,而這裡給一個預覽。我們把目標函數重寫為J(	heta)=sum_{t=1}^Tmathbf{E}_{(mathbf{s}_t,mathbf{a}_t)sim p_	heta(mathbf{s}_t,mathbf{a}_t)}[r(mathbf{s}_t,mathbf{a}_t)],寫成一個邊際分布下的期望求和的形式。根據我們的決策過程,把期望進一步展開成J(	heta)=sum_{t=1}^Tmathbf{E}_{mathbf{s}_tsim p_	heta(mathbf{s}_t)}left[mathbf{E}_{mathbf{a}_tsimpi_	heta(mathbf{a}_t|mathbf{s}_t)}[r(mathbf{s}_t,mathbf{a}_t)]
ight]。 這樣,我們就可以在兩個層面上做重要性抽樣了:J(	heta)=sum_{t=1}^Tmathbf{E}_{mathbf{s}_tsim p_	heta(mathbf{s}_t)}left[frac{p_{	heta}(mathbf{s}_t)}{p_{	heta}(mathbf{s}_t)}mathbf{E}_{mathbf{a}_tsimpi_	heta(mathbf{a}_t|mathbf{s}_t)}left[frac{pi_{	heta}(mathbf{a}_t|mathbf{s}_t)}{pi_{	heta}(mathbf{a}_t|mathbf{s}_t)}r(mathbf{s}_t,mathbf{a}_t)
ight]
ight]。這樣就不再有指數乘積問題,但是同時又帶來了一個新的需要知道p_{	heta}(mathbf{s}_t)這樣給定策略下某個時刻在某個狀態的概率這樣的大難題。一個近似的處理方式是我們可以把frac{p_{	heta}(mathbf{s}_t)}{p_{	heta}(mathbf{s}_t)}這塊弄掉,當然這樣做的話理論上就不再無偏了,但是事實上當兩個策略足夠接近的話,可以說明這個比值是不重要的:在很多問題的實踐上是好的,而且有一定的理論保證。

用自動差分器做策略梯度法

我們現在想找到一個比較簡單的方法去實現策略梯度法,以利用上TensorFlow或者PyTorch等自動差分器。回顧梯度
abla_	heta J(	heta)approxfrac{1}{N}sum_{i=1}^Nsum_{t=1}^Tleft[
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t})hat{Q}_{i,t}
ight],我們不想顯式地去計算這些
abla_	hetalog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t}),然後再做乘法丟回去。我們需要一個圖結構,可以用監督學習,它的極大似然的梯度正好是我們的策略梯度,那樣就完美解決了。考慮到極大似然估計的目標函數為J_mathrm{ML}(	heta)approxfrac{1}{N}sum_{i=1}^Nsum_{t=1}^Tlog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t}),梯度為
abla_	heta J_mathrm{ML}(	heta)approxfrac{1}{N}sum_{i=1}^Nsum_{t=1}^T
abla_	heta log pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t})。我們要把hat{Q}_{i,t}給放進去。一個特性是,hat{Q}_{i,t}本身是不依賴於參數的,我們所需要做的一切就是做一個虛擬的損失函數,加權損失函數	ilde{J}(	heta)approxfrac{1}{N}sum_{i=1}^Nsum_{t=1}^Tlog pi_	heta(mathbf{a}_{i,t}|mathbf{s}_{i,t})hat{Q}_{i,t},其中權重就是hat{Q}_{i,t},然後就用自動差分器求梯度就行了。當然,在線方法要求我們每一個梯度步重新採樣,所以我們不能使用SGD。

Levine教授給出了TensorFlow樣式的代碼例子,給出了兩者的區別(狀態和行動認為是離散的,所以是one-hot編碼,因此輸入是二維張量):

最大似然估計:

# Given:# actions -(N*T) x Da tensor of actions# states -(N*T) x Ds tensor of states# Build the graph:logits = policy.predictions(states) # This should return (N*T) x Da tensor of action logitsnegative_likelihoods = tf.nn.softmax_cross_entropy_with_logits(labels=actions, logits=logits)loss = tf.reduce_mean(negative_likelihoods)gradients = loss.gradients(loss, variables)

策略梯度法:

# Given:# actions -(N*T) x Da tensor of actions# states -(N*T) x Ds tensor of states# q_values – (N*T) x 1 tensor of estimated state-action values# Build the graph:logits = policy.predictions(states) # This should return (N*T) x Da tensor of action logitsnegative_likelihoods = tf.nn.softmax_cross_entropy_with_logits(labels=actions, logits=logits)weighted_negative_likelihoods = tf.multiply(negative_likelihoods, q_values)loss = tf.reduce_mean(weighted_negative_likelihoods)gradients = loss.gradients(loss, variables)

可以發現差別還是很小的,只是加了一個加權的過程。

在實踐中,我們需要記住梯度的方差是非常大的,處理監督學習的方法不見得在這裡適用,而且噪音非常大。一個比較實際的解決方法是使用很大的批量數據來降低方差。調整學習率是很有挑戰性的,而且可能會需要很多時間來做這件事情。使用自適應的步長如ADAM等方法通常還可以。在之後的課程中會講一些針對策略梯度法的步長調整方法。

Levine and Koltun (2013) 訓練模擬機器人,使用重要性抽樣的方法用演示例子去訓練神經網路代表的策略。一點啟發是抽樣的分布不見得一定要是一個神經網路分布,也可以是其他給定數據的分布:這樣如果那個分布好的話,可以減少訓練所需要的時間,可以說是一個熱啟動。Schulman et al. (2015) 使用信賴域策略優化演算法 (TRPO) 訓練模擬機器人,使用自然梯度,並使用了自動調節步長的方法,可以做出離散和連續的行動,也可以玩Atari遊戲。可以找到相關代碼 (Duan et al., 2016, arxiv.org/abs/1604.0677, rll/rllab)。這個方法適用範圍比較廣,如果不關注樣本效率的話,通常較容易用於新的問題。


推薦閱讀:

剛剛,吳恩達講了乾貨滿滿的一節全新AI課,全程手寫板書
用APP來預防失明?16歲的少女為此還研發了一套AI
國內首次!Pony.ai無人車進入常態化試運營
人工智慧的思考: 人被機器取代後這些難題怎麼解決?
OTT大屏勢能的新一站,人工智慧光環下的價值鏈

TAG:强化学习ReinforcementLearning | TensorFlow | 人工智能 |