---
# System prepended metadata

title: '[RL 算法筆記] Proximal Policy Optimization(PPO)-回顧'

---

## [Reinforence_Learning 算法] Proximal Policy Optimization(PPO)

## 前言
#### **強化學習演算法可以策略函數分為兩大類：基於值函數的強化學習和基於策略的強化學習。**
#### **也可以以資料搜集方法分為on-policy和off-policy**

基於值函數的強化學習透過遞歸地求解貝爾曼方程來維護 Q 值函數（可以是離散的列表，也可以是神經網路），每次選擇動作時會選擇該狀態下對應 Q 值最大的動作，使得未來累積的期望獎勵值最大。經典的基於值函數的強化學習演算法有 Q‐Learning、SARSA、DQN 演算法等。這些演算法在學習後的 Q 值函數可能並不會發生變化，但此時的策略是固定的，可以理解為確定性策略。
基於策略的強化學習不再透過價值函數來確定選擇動作的策略，而是直接學習策略本身，透過一組參數$\theta$ 對策略進行參數化，並透過神經網路等方法優化$\theta$。
傳統策略梯度演化流程如下圖所示：
![image](https://hackmd.io/_uploads/ryDqHTa5eg.png)


在進入算法說明之前，我們要先理解重要性採樣(important sampling)的概念
假設有函數$f(x)$，x從分布p採樣，帶回到$f(x)$中求取期望值
$E_{x~p}[f(x)]$假設分佈p是未知的，我們希望用更容易求取的分佈q(無論什麼分佈)進行採樣，但在q中採樣的內容不能直接等於p的數值，我們需要進行一些修正才能等價於以分佈p求取的期望值。
首先我們要知道期望值公式可以表示為：
$$E_{x \sim p} (f(x))= \int f(x)p(x)dx$$
若想將分佈由p轉到q
可以透過以下步驟：
$$\text{右邊展開$q(x)$}\quad E_{x \sim p}(f(x)) = \int f(x)p(x)\cdot \frac{q(x)}{q(x)}dx$$
$$\text{呈現為$q(x)$}\quad E_{x \sim p}(f(x)) = \int [f(x)\frac {p(x)}{q(x)}]q(x)dx=E_{x\sim q}(f(x)\frac{p(x)}{q(x)})$$

因此我們可以知道當分布p(x)轉換到分佈q(x)時會需要有一個權重進行調整也就是$\frac{p(x)}{q(x)}$，因此若$p(x),q(x)差距太大$數值就會有很大的變動
![image](https://hackmd.io/_uploads/rkaxDEWoee.png)
證明 &darr;
![image](https://hackmd.io/_uploads/H1XRySZsge.png)

可以用以下的範例說明![image](https://hackmd.io/_uploads/S1Lru4Zjlg.png)
可以看出若p(x)和q(x)差很多的話估計值在樣本有限情況下會亂跳
- 這就是為何選擇p(x)和q(x)需要選擇較為相近，即使理論表示可以隨便的分佈q

在我們了解了important sampling(IS)後就可以開始理解PPO為何會和這個扯上關係

最原始的策略踢度算法Policy-Gradient公式：

$$\nabla_\theta J(\theta)=E_{\pi\theta}[\nabla_\theta log \pi_\theta(a \mid s)R]$$
缺點是每次更新都需要重新搜集資料 &rarr; 樣本效率低下

因此我們希望可以使用舊資料進行更新，但舊資料是來自$\pi_{old}$可是更新對象是$\pi_{new}$，若直接使用會背離on-Policy的定義，因此引入IS觀念：
$$\nabla_\theta J(\theta)=E_{\pi old}[\frac{\pi_\theta(a \mid s)}{\pi_{old}(a \mid s)}\nabla_\theta log \pi_\theta(a \mid s)A(s,a)]$$
$r_t(\theta)=\frac{\pi_\theta(a \mid s)}{\pi_{old}(a \mid s)}$就是用來調整新舊策略差異的權重，而$A(s,a)$就是優勢函。



## 正文

[PPO](https://arxiv.org/pdf/1707.06347)，或稱為Proximal Policy Optimization，是Open-AI提出的強化學習算法，是梯度策略算法的一種，基於A-C架構，由**TRPO**延伸而來,Chat-gpt的RLHF調整的核心方法也是PPO。
主要的特色是:
- 剪枝機制能夠限制每次更新不會過度偏離舊的策略，提升訓練穩定性
- [On-policy](https://hackmd.io/@Su-Guan/OnOffPolicy)、無經驗回放（no replay buffer）
目前有兩種主要的PPO變體需討論（均在17年的論文中介绍）：PPO Penalty和PPO Clip。

本文主要說明PPO Clip(PPO2)，因目前主流默認提到PPO時變體為Clip。
因此以下內文皆以PPO代稱PPO Clip。



### 一、直觀理解PPO：

想像你在玩一款分數競賽遊戲，而你的教練（PPO）做了以下三件事：
只根據你最近一次的遊戲紀錄來指導，不會拿舊紀錄或別人經驗當教材（on-policy）。
每次只微調建議幅度，不會產出過大的分歧策略。
不忘偶爾讓你試試新招，以免你老是用同一招錯過更高分的機會。


### 二、**PPO**的核心算法
#### psudo code 示意:
::::info
Algorithm 5 PPO with Clipped Objective

Input: initial policy parameters θ₀, clipping threshold ε 
for k = 0, 1, 2, … do 
  Collect set of partial trajectories 𝒟ₖ on policy πₖ = π(θₖ) 
  Estimate advantages $Âₜ^{πₖ}$ using any advantage estimation algorithm 
  Compute policy update 
    $$θₖ₊₁ = arg max_θ L^{CLIP}_{θₖ}(θ)$$ 
    by taking K steps of minibatch SGD (via Adam), where 

$$L^{CLIP}_{θₖ}(θ)  
= E_{t∼πₖ}\Biggl[∑_{t=0}^T min\bigl(rₜ(θ) Âₜ^{πₖ}, clip(rₜ(θ), 1−ε, 1+ε) Âₜ^{πₖ}\bigr)\Biggr]$$

end for
::::

---

### 三、PPO的目標函式
完整的**PPO**的目標函數$L^{CLIP+VF+S}(\theta)$結合了$L^{CLIP}_{\theta_k}$與熵正則以及新舊策略之間的差異表示：
$$
L^{CLIP+VF+S}(\theta)=
-\hat{\mathbb{E}}\!\Big[
    \min\!\bigl(
        r_t(\theta)\,\hat{A}_t,\;
        \operatorname{clip}\bigl(r_t(\theta),\,1-\epsilon,\,1+\epsilon\bigr)\,\hat{A}_t
    \bigr)
\Big]
\;+\;c_1\,
  \hat{\mathbb{E}}\!\Big[
      \bigl(V_\theta(s_t)-\hat{R}_t\bigr)^2
  \Big]
\;-\;c_2\,
  \hat{\mathbb{E}}\!\Big[
      \mathcal{H}\bigl[\pi_\theta(\cdot\mid s_t)\bigr]
  \Big] .
$$

- 第一項（Actor-net）：Policy_Loss
- 第二項（Critic-net）：Value_Loss
- 第三項(Entrophy) : 熵，控制Agent探索慾望

#### **policy loss**為:
$$L_p(\theta) = \hat{\mathbb{E}} \left[ \min\left( r(\theta) \hat{A}_t, \text{clip}(r(\theta), 1-\epsilon, 1+\epsilon) \hat{A}_t \right) \right]$$


- $\mathbb{E}$ 表示對樣本的期望值
- $r(\theta) = \frac{\pi_\theta(a_t \mid s_t)}{\pi_{\theta_{\rm old}}(a_t \mid s_t)}$，表示了在新策略下選擇動作與舊策略下選擇動作機率的比例
- $\hat{A}_t$ 是優勢函數（advantage function），用來估計在狀態 $s_t$ 下採取動作$a_t$ 比平均更好多少；原式如下：
$$\hat{A} = -V(S_t)+r_t+\gamma r_{t+1}+\dots+\gamma^{T-t+1}r_{T-1}+\gamma^{T-t}V_{(s_T)}$$
在PPO實作中使用GAE進行估計
$$\hat{A}_t = \delta_t+(\gamma\lambda)\delta_{t+1}+(\gamma\lambda)^2\delta_{t+2}+\dots+\dots+(\gamma\lambda)^{T-t+1}\delta_{T-1}$$
$$\text{where}\quad \delta_t=r_t+\gamma V_{(s_{t+1})}-V_{(s_t)}\quad(TD)$$
- $clip$ 函數將 $r(\theta)$ 的值限制在 $(1 - \epsilon, 1 + \epsilon)$ 的範圍內，這樣就避免了過大的策略更新，如下圖顯示：

![image](https://hackmd.io/_uploads/SJGk6vC5xl.png)


#### pseudo code 示意 :

- **$L^{CLIP}$**

:::info

```python

import numpy as np

def ppo_loss(old_probs, new_probs, advantage, epsilon=0.2):
    """
    Compute the PPO loss.

    old_probs: Probability of taking actions in each state as per the old policy.
    new_probs: Probability of taking actions in each state as per the new policy.
    advantage: Estimated advantage for each action at each state.
    epsilon: Hyperparameter that dictates how much the policy can change (usually small, like 0.1 or 0.2).

    Returns the PPO loss.
    """
    r_theta = new_probs / old_probs
    clipped_r_theta = np.clip(r_theta, 1 - epsilon, 1 + epsilon)
    loss = -np.mean(np.minimum(r_theta * advantage, clipped_r_theta * advantage))
    return loss

```
:::
---


#### value_loss則是:
$$L_v(\theta) = \hat{\mathbb{E}}\!\Big[
      \bigl(V_\theta(s_t)-\hat{R}_t\bigr)^2
  \Big]$$

其中:

$$V_\theta(s_t)=\mathbb{E}_{\tau\sim\pi_\theta}\!\Bigl[\textstyle\sum_{k=0}^{\infty}\gamma^{k}r_{t+k}\Bigm|s_t\Bigr] $$ $V_\theta(s_t)$為Critic 的輸出。透過最小化 MSE，讓網路學會「看到狀態就預估剩餘分數」。 $\hat R_t$  **Bootstrapped Return / Target** ，常見形式： $$ \hat R_t = r_t + \gamma r_{t+1} + \dots + \gamma^{T-t-1} r_{T-1} + \gamma^{T-t} V_\theta(s_T)$$

$$\hat R_t \;\stackrel{\text{def}}{=}\; \sum_{k=0}^{\infty}\gamma^{k}\, r_{t+k}$$
 
| 記號              | 全稱                               | 數學意義                                                 
| --------------- | -------------------------------- | ---------------------------------------------------- 
| $V_\theta(s_t)$ | **Value Function Approximation** | 網路估計在狀態 $s_t$ 時，依照當前策略 $\pi_\theta$ 後續所能取得的**期望折扣回報**： |            |
|                  |                                 |                     
| ------------------ | --------------------------------- | ---------------------------------   
| $\hat R_t$ | **(Discounted) Return**<br>（折扣回報） | 在狀態 $s_t$之後、依照 **當前策略** 收集到的累積獎勵： |        |



### 四、KL‐penalty PPO
原論文中PPO算法還會再引入一個變體，帶 KL 懲罰（KL‐penalty）的目標函數：
$$J^{\theta^K}_{PPO} (\theta) = J^{\theta^K} (\theta) - \beta D_\text{KL}(\theta, \theta^{K})$$
$J^{\theta^K}_{PPO} (\theta)$為最原始的 policy-gradient surrogate objective($L^{CLIP}$) :  $$J^{\theta^k}(θ)=E_{(s_t,a_t)∼\pi_{θ^k}}[\frac{\pi_\theta(a_t \mid s_t)}{π_{θ^k}(a_t \mid s_t)}A^{θ^k}(s_t,a_t)].$$

而$\beta D_\text{KL}(\theta, \theta^{K})$對新舊策略之間的 KL 散度加以懲罰，$\beta$ 則可根據:
$$\text{若}\; D_{KL}>KL_{max}\;則增大\;\beta\;,\;若\;D_{KL}<KL_{min}\;,則減小\;\beta$$

### 五、優勢函數$\hat{A}$說明
在強化學習中，優勢函數是用來衡量在某個狀態下採取某個決策優良程度的指標，他表示為在狀態$S_t$下採取$A_t$動作的價值與該狀態下平均動作價值的差異，定義如下：
$$A(s_t,a_t)=Q(s_t,a_t)-V(s_t)$$
其中$Q(s_t,a_t)$表示在狀態$s_t$下採取$a_t$後未來累積獎勵的期望值，而$V(s_t,a_t)$則是狀態$s_t$下未來累積獎勵的期望值。
因此若$A(s_t,a_t)>0$代表該動作$a_t$比平均動作好，反之亦然。


### 六、總結PPO訓練算法流程：
:::warning


Rollout 用 $π_{old}$ 蒐集一批資料 (T steps × N envs)
       $\quad$$\downarrow$
[Epoch 1] $\rightarrow$ 把這批資料打亂 (shuffle)
   ├─ [Mini-batch 1] → Forward πθ → 算 ratio $r_t$ → Clip loss → Backprop → 梯度下降 1 次
   ├─ [Mini-batch 2] → Forward πθ → 算 ratio $r_t$→ Clip loss → Backprop → 梯度下降 1 次
   ├─ ...
   └─ [Mini-batch M] → ... → 梯度下降 1 次
       $\downarrow$
[Epoch 2] $\rightarrow$ 資料再打亂，重複 mini-batch 訓練
       │
...
       $\downarrow$
[Epoch K] $\rightarrow$ 在這批 rollout 上最後一次訓練
       $\downarrow$
丟掉舊資料 → πθ 更新後變成新的 π_old → 下一輪 Rollout
:::
1.以當前策略網路與當前環境交互一段rollout(T個時間步)並獲取數據，假設一次rollout的T為128步，且你有16個envs則你會得到2048個transition。
2.對所有資料基於採樣時間步t計算估計優勢函數$\hat{A}$、$\hat{R}$$\;\dots$，如剛剛的2048個transitions中的所有資料
3.使用梯度優化優化目標函數，如把剛剛的2048筆數據打亂，分成你決定的批次(batch)，然後決定epoch數，每個epoch把剛剛的批次跑一輪。
4.更新策略函數與神經網路。

:::danger
PS:由於PPO屬於策略梯度，因此是直接學習一個機率分布$\pi_\theta(a \mid s)$。
通常這個機率分布為高斯分布或柏松分布，訓練時通常從分布中隨機抽取動作，而非採用argmax作法，原因為:
$\cdot\quad$要保證探索。
$\cdot\quad$由於策略梯度的期望定義為$\nabla_\theta J(\theta)=E_{a\sim\pi(,\mid s)}[\nabla_\theta log \pi_\theta(a\mid s)A_t]$，若非使用sampling而是用argmax，這個期望值就無法計算了。
:::


### 七、IPPO:

- [IPPO](https://arxiv.org/pdf/2210.00803)引入針對性調整去優化機械手臂避開障礙物同時到達目標位置的成功率
- 是專門針對機器手臂設計的PPO變體

#### IPPO特點說明:
本質上數學邏輯還是基於PPO，但有特殊改良 reward 專們針對六dof機械手臂設計
$$
R(s,a)\;=\;
-\Bigl[
      \omega_1 e^{2}
      + \ln\!\bigl(e^{2} + \tau_e\bigr)
      + \,\omega_2 \sum_{i=1}^{n} \psi_i
\Bigr]
$$

1. **距離誤差懲罰**：
   $$
    \omega_1 \cdot e^2
   $$
   強化對目標位置的趨近。
2. **對數誤差項（靠近強化）**：
   $$
   \log(e^2 + \tau_e)
   $$
   提升末端在靠近目標區域時的精度控制能力。

3. **障礙物靠近懲罰項**：
   $$
    \omega_2 \cdot \sum_{i=1}^{C} \max\left(0, 1 - \frac{d_i}{d_{\text{max}}} \right)
   $$
   當障礙物靠近機械臂時給予懲罰，用於維持安全距離。
   $d_i$為障礙物距離最近的軸之垂直距離。
---
#### IPPO的Agent架構為

![image](https://hackmd.io/_uploads/Hyj0e26qgg.png)

---

### 八、易混淆：
on-policy定義是用的資料必須是當前策略和環境互動時搜集的，而非任意舊資料。
PPO其實算是on-policy算法，雖然他是用$\pi_{old}$搜集一整個批次在打亂做學習，但由於每次梯度下降更新網路時會透過clip機制使$\theta$只會進行小幅度更新，因此$\pi_{old}\approx\pi_{new}$，仍歸類於on-policy

:::info
## 因此PPO歸類在on-policy且為梯度策略

:::
### 九、參考文獻
[1][梯度視角]( https://zhuanlan.zhihu.com/p/19949917958)
[2][Policy視角]( https://blog.csdn.net/weixin_42392454/article/details/140641453 )
[3][論文導讀](https://zhuanlan.zhihu.com/p/19949917958)