1 前置知識點
基本概念
https://www.yuque.com/docs/share/04b60c4c-90ec-49c7-8a47-0dae7d3c78c7?#(部分符合的定義在這裡)
要了解PPO,就必須先了解Actor-Critic.
Actor負責輸出policy,也就是在某個狀态下執行各種action的機率分布
Critic負責輸出Vaue of state。
Actor和Critic的默契:Actor相信Critic給的狀态的value就是真的; Critic也相信Actor選送過來的(s,a)中的a就是最優的action。通過不斷的疊代,強化這個信任關系的正确性。
(這展現了我們的價值觀 [因為信任,是以簡單],哈哈哈~)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI3kjM9gGdkl2dmUmbv5WPlxWe0NnJl52bk1zc1RXY0NnJ3cTOxITPlpXazZyM1MTPoRHZpdlbpdWay9mJwUzM9QHanlWZI5WanlmcvZyZuBnLldWYtlWPl1WYuZCN5ITP0h2ZpVGamUmbpxmbp1TehxGczlGZmIXZ05WZj1jbnlGbhNyZuBnL4YDN2QmYwEjNlBDMtATMhFWLiVWO00SYiJTOtYGZzUzYmJjZtMTO4UTM0gTNwEDO1EzLcN3Ztl0Lc12bj5ycj5Wd5lGbh5yZulmapVmYt42YtM3cv5yYpxmY1BXL0NWYyVGdulWLuFWb1h2Lc9CX6MHc0RHaiojIsJye.png)
是以這樣就不難了解Critic的Loss是怎麼來的了,Critic的輸出就是state的Value,那就讓Critic模型的輸出使得以下公式成立:
$$V_s=r_{s,a}+\gamma V_{s'}$$
其中,$r_{s,a}, s,a,s'$是訓練Critic需要的資料,$s'$是在狀态$s$下執行動作$a$得到新狀态, $r_{s,a}$是reward, $\gamma$ 是discount factor。
跟基礎概念的差別是,這裡的系統假定是執行動作$a$隻能到$s'$, 沒有展現執行$a$可以得到不同的狀态; (但是其實這種機率可以展現在訓練資料中,因為$(s,a,r_{s,a})
$$和$$s'$ 不一定是一一對應,其機率可以通過sampling得到的資料分布展現)
是以Critic的Loss就是$|r_{s,a}+\gamma V_{s'}-Vs|$,也就是所謂的TD(Time Difference)-Error的L1,或者L2也可以.
那麼Actor的Loss怎麼計算呢?
這裡就先來明白Advantage的概念,其實也就是TD-Error
$$Adv=r_{s,a}+\gamma V_{s'}-Vs$$
之是以稱之為Advantage,是因為假如Advantage>0, 就是說實際執行$a$之後,發現目前的狀态Value實際上比目前Critic估計出來的要大,是以這是個好的Action,它能夠讓$V_s$ 變大,Actor應該增大這個action的機率;反之,Advantage<0,這個action就是不好的,應該減小執行它機率。
是以Actor的Loss就是$$-log(\pi(a|s))*Adv$$, 因為要最小化Loss,是以前面加個負号;Adv的符号代表了應該增大這個action的輸出機率,還是減小這個action的輸出機率;Adv的大小代表了增加或減小的幅度應該有多大。
2 Proximal Policy Optimization(PPO)
2.1 PPO主要是來解決什麼問題?
它是為了讓我們在訓練Agent的時候能夠take the biggest possible improvement step on a policy using the data we currently have, without stepping so far that we accidentally cause performance collapse。就是更新policy的時候盡可能步子邁大點,但也要防止扯着蛋,即模型參數崩了。
2.2 PPO怎麼解決這個問題的?
簡單來說,相同的網絡結構,維護兩組模型參數Old和New,在每次疊代的時候去更新New的參數,但是要控制New的模型輸出Policy和Old的Policy不要差距太大,本輪疊代結束後,把New的參數覆寫掉Old的參數。
怎麼去控制差距不要太大呢?作者給了兩種方式: PPO-Penalty, PPO-Clip
2.2.1 PPO-Clip
先說PPO-Clip, 它通過下面的公式來更新政策:
$$\theta_{k+1}=arg max_{\theta}E_{s,a \sim \pi_{\theta_k}}[L(s,a,\theta_k,\theta)]$$
就是最大化$L(s,a,\theta_k,\theta)$,
$$L(s,a,\theta_k,\theta)=min \left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}A^{\pi_{\theta_k}}(s,a) , clip \left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}, 1-\epsilon, 1+\epsilon \right)A^{\pi_{\theta_k}}(s,a) \right)$$
這個形式主要是為了讓我們了解為啥叫PPO-Clip(我感覺直接用後面那個Clip項其實就夠了,這個表達有點備援),$\theta_k$ 就是目前Old的參數,$\theta$ 是New的參數。$\pi_{\theta}(a|s)$ 是New Actor輸出的Policy上狀态$s$時執行$a$的機率,$\pi_{\theta_k}(a|s)$ 表示的Old Actor輸出的Policy上狀态$s$時執行$a$的機率。$A^{\pi_{\theta_k}}(s,a)$是基于Old Critic得到的Advantage.
對這個公式進行改寫,更容易看出它的真實目的,
$$L(s,a,\theta_k,\theta)=min \left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}A^{\pi_{\theta_k}}(s,a) , g \left( \epsilon, A^{\pi_{\theta_k}}(s,a) \ \right) \right)$$
其中,
$$g \left( \epsilon, A \right)=\left\{
\begin{aligned}
&(1+\epsilon)A & A\ge 0 \\
&(1-\epsilon)A & A< 0
\end{aligned}
\right.$$
當Advantage>=0的時候,
$$L(s,a,\theta_k,\theta)=min \left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}, (1+\epsilon) \right)A^{\pi_{\theta_k}}(s,a) $$
這就清楚的說明,這時候應該增大$\pi_{\theta}(a|s)$,也就是認為這個action是好的,增加選擇$a$的機率。但是通過$1+\epsilon$ 限制增大的幅度。
同理,當Advantage<0的時候
$$L(s,a,\theta_k,\theta)=min \left( \frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}, (1-\epsilon) \right)A^{\pi_{\theta_k}}(s,a) $$
縮小$\pi_{\theta}(a|s)$,但是幅度不能小于$1-\epsilon$
另外,根據我的了解,$\pi_{\theta_k}(a|s)$應該截斷梯度,也就是反向傳到的時候用不着去更新Old Actor的參數。在OpenAI Spinningup的代碼([https://github.com/openai/spinningup/blob/master/spinup/algos/pytorch/ppo/ppo.py](https://github.com/openai/spinningup/blob/master/spinup/algos/pytorch/ppo/ppo.py))确實是這樣處理的,但是在Tianshou的代碼裡([https://github.com/thu-ml/tianshou/blob/master/tianshou/policy/ppo.py](https://github.com/thu-ml/tianshou/blob/master/tianshou/policy/ppo.py))沒有做截斷,結果也OK,想來對于$\pi_{\theta}(a|s)$來說,$\pi_{\theta_k}(a|s)$就是一個scalar factor, 這個factor是變量還是靜态值,也許影響不那麼大,而且本輪疊代結束後$\theta_k$也會被覆寫掉,反向傳導更新了也白搭。
到這裡,其實說的都是如何更新Actor。
怎麼更新Critic的參數呢?
$$L_c(s,a,r_{s,a},s')=|r_{s,a}+V^{\pi_{\theta_k}}_{s'}-V^{\pi_{\theta}}|$$
唯一的不同是target value是用Old Critic計算的,這也是DRL領域的正常操作了.
小結一下,PPO-Clip就是通過Clip操作來防止步子邁太大的。作者實驗證明Clip的效果比Penalty好。
### 2.2.2 PPO-Penalty
$$L^{KLPEN}(\theta)=\frac{\pi_{\theta}(a|s)}{\pi_{\theta_k}(a|s)}A^{\pi_{\theta_k}}(s,a) -\beta KLD\left( \pi_{\theta}(*|s), \pi_{\theta_k}(*|s) \right)$$
了解上上面的,這個了解起來也就容易了,就是增加一個新舊Policy差異的懲罰項,差異通過KL divergence來衡量
(PS: 如了解有誤支援,歡迎批評指正~)