跳轉到

5.1 策略梯度定理、REINFORCE 與 Baseline(1999-2017)#

前言:換一條完全不同的路——直接對策略求導#

到第 4 章為止,我們都在學「價值」再從價值推出行為( \(\arg\max Q\) )。這條路有三個結構性困難:(1) \(\arg\max\) 需要可枚舉動作,連續控制(機器人關節角度)與超大動作空間(LLM 詞表)都會卡死;(2)價值函數的微小變動可能讓 argmax 跳到完全不同的動作——目標函數對參數不連續,梯度法水土不服;(3)它學的是「確定性最優策略」,但很多問題的最佳解本來就是隨機的(石頭剪刀布)。策略梯度(policy gradient)換了一個根本立場:把策略本身參數化成 \(\pi_\theta(a|s)\) ,直接對期望回報 \(J(\theta)\) 求梯度做上升。1992 年 Williams 的 REINFORCE 給出第一個可實作的形式,1999-2000 年 Sutton、Marbach 與 Glynn 等人把 策略梯度定理 嚴格化,2017 年之後 PPO 成為 LLM 時代的訓練主力。本節把這條數學線完整走一遍——它是第 5.2 節 A2C/PPO、第 6 章 AlphaGo 的策略網路、第 8 章 RLHF 的共同數學祖先。

歷史背景:從「估計價值」到「估計梯度」#

策略直接學習的想法比價值迭代更早就有影子(Barto 1983 的 Actor-Critic 中,Actor 就是一個隨機策略),但缺少兩樣東西:對 \(J(\theta)\) 的無偏梯度估計與收斂理論。1986-1989 年間,Glynn、L'Ecuyer 等在模擬優化領域發展出 likelihood ratio 法(對離散取樣的機率求導的技巧);1988 年 Williams 把它應用到神經網路,發表《Simple statistical gradient-following algorithms for connectionist reinforcement learning》——REINFORCE。名字是學術幽默:「Reward Increment = Nonnegative Factor × Offset Reinforcement × Characteristic Eligibility」。但 REINFORCE 方差太大,1990 年代被 TD 路線壓制。轉機在 1999-2002:Sutton et al. 《Policy Gradient Methods for Reinforcement Learning with Function Approximation》與 Marbach & Tsitsiklis 給出策略梯度定理及其函數近似收斂性;Baxter & Bartlett 進一步處理無限時域。2000 年代 actor-critic 成為連續控制主流;2015-2017 年 DDPG、TRPO、A2C、PPO 把它推向深度時代;2017 年起 OpenAI 把 PPO 用於機器人與遊戲,2022 年 InstructGPT 把 PPO 用於對齊 LLM(第 8 章)。REINFORCE 到 PPO 的三十年,本質上是一部「降低梯度估計方差」的工程史。

核心數學:策略梯度定理#

目標函數與困難點#

設軌跡 \(\tau = (s_0,a_0,r_1,\ldots,s_T)\) ,其發生機率為:

\[ p_\theta(\tau) = \rho_0(s_0) \prod_{t} \pi_\theta(a_t|s_t) P(s_{t+1}|s_t,a_t) \]

目標: \(J(\theta) = \mathbb{E}_{\tau \sim p_\theta}\left[ R(\tau) \right]\) ,其中 \(R(\tau) = \sum_t \gamma^t r_t\) 。困難: \(J\) 的期望對「環境分布 \(P\) 」取值,而 \(P\) 未知且對 \(\theta\) 的導數根本不存在(離散環境不可微)。直接微分是死路。

關鍵一步:likelihood ratio 技巧#

雖然 \(P\) 不可微,但 \(p_\theta(\tau)\) 中含 \(\theta\) 的只有 \(\pi_\theta\) 部分!利用 \(\nabla \log f = \nabla f / f\) :

\[ \nabla_\theta p_\theta(\tau) = p_\theta(\tau)\, \nabla_\theta \log p_\theta(\tau) = p_\theta(\tau) \sum_t \nabla_\theta \log \pi_\theta(a_t|s_t) \]

( \(\rho_0\) 與 \(P\) 的項在取對數後消失——環境的不可微性被完整繞過。)代入 \(J\) 的梯度:

\[ \nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim p_\theta}\left[ R(\tau) \sum_t \nabla_\theta \log \pi_\theta(a_t|s_t) \right] \]

這就是策略梯度定理(有限時域形式)。讀懂它的直覺至關重要:

  • \(\nabla_\theta \log \pi_\theta(a_t|s_t)\) 是「提高這個動作在這個狀態的機率」的方向。
  • \(R(\tau)\) 是權重:回報高的軌跡,它做過的所有動作機率都被推高;回報低的被推低。
  • 這正是第 1 章效果律的精確數學化!Thorndike 的「伴隨滿足的反應更可能重複」→「 \(R>0\) 時推高 \(\log \pi\) 」。
  • 注意它不需要知道 \(P\) 與 \(R\) 的形式,只要能採樣軌跡——天然無模型。

漸近無偏折扣版#

折扣版有一個微妙處:把 \(R(\tau)\) 直接換成 \(\sum_t \gamma^t r_t\) 在有限時域下嚴格說是有偏的(因為折扣改變了軌跡分布的解讀)。嚴格形式(Sutton et al. 1999)對平均獎勵或無折扣情形最乾淨;對折扣情形,常用 \(\sum_{t'} \gamma^{t'-t} r_{t'}\) (從 \(t\) 起算的折扣回報 \(G_t\) )配合 \(\nabla \log \pi_\theta(a_t|s_t)\) ,這在無限時域下漸近無偏:

\[ \nabla_\theta J(\theta) = \sum_s d^\pi(s) \sum_a \frac{\partial \pi_\theta(a|s)}{\partial \theta} q^\pi(s,a) = \mathbb{E}_{\pi_\theta}\left[ \sum_t \nabla_\theta \log \pi_\theta(a_t|s_t)\, G_t \right] \]

其中 \(d^\pi\) 是策略的折扣狀態分布。第二個等式就是 likelihood ratio 形式與「每步用 \(G_t\) 加權」的等效表述。

三劑降方差藥方#

REINFORCE 之所以需要三劑藥,根源是一個事實: \(G_t\) 的變異數隨時域線性或超線性增長,而梯度估計要乘上它。

藥方一:Baseline——減去一個與動作無關的量#

定理:對任意函數 \(b(s)\) (只要不依賴 \(a\) ):

\[ \mathbb{E}_{\pi_\theta}\left[ \nabla_\theta \log \pi_\theta(a|s)\, b(s) \right] = 0 \]

證明: \(\mathbb{E}_a[\nabla \log \pi(a|s)\, b(s)] = b(s) \sum_a \pi(a|s) \frac{\nabla \pi(a|s)}{\pi(a|s)} = b(s) \nabla \sum_a \pi(a|s) = b(s) \nabla 1 = 0\) 。 \(\blacksquare\)

所以可以無偏地使用 \(G_t - b(s_t)\) 。最優 baseline 的方差最小化解(對每個 \(s\) 最小化 \(\mathrm{Var}[G_t - b(s)]\) )是加權平方誤差最小值:

\[ b^*(s) = \frac{\mathbb{E}[G_t^2 \|\nabla \log \pi\|^2 \mid s]}{\mathbb{E}[\|\nabla \log \pi\|^2 \mid s]} \]

實務上不精確解它,而是讓 \(b(s)\) 就是價值函數 \(V_\phi(s)\) ——用另一個網路學它(第 5.2 節 Critic 的登場)。減去 \(V\) 之後的加權量就是優勢函數 \(A(s,a) = Q(s,a) - V(s)\) (第 4.2 節 Dueling 的同一個量):「這個動作比平均好多少」。這是方差的數量級改善:原始 REINFORCE 的梯度方差隨回合長度劇增,baseline 可將方差縮小一到兩個數量級。

藥方二:TD 誤差代替回報#

\(A(s,a)\) 仍需整條未來。若已有 Critic \(V_\phi\) ,則單步 TD 誤差 \(\delta_t = r_{t+1} + \gamma V_\phi(s_{t+1}) - V_\phi(s_t)\) 是 \(A(s_t,a_t)\) 的(有偏但低方差)估計。on-policy 且 \(\phi\) 收斂時 \(\delta_t \to A\) 。這就是 Actor-Critic:Actor 用 \(\delta_t\) 更新策略,Critic 用 \(\delta_t\) 更新價值(第 3.1 節的 TD 在幕後服務)。完整版是 GAE(Generalized Advantage Estimation, Schulman 2015):用指數加權的 k 步優勢估計, \(\hat{A}_t^{GAE(\gamma,\lambda)} = \sum_{l\ge 0} (\gamma\lambda)^l \delta_{t+l}\) ——又一次,第 3.1 節的 λ 光譜出現,這次是在優勢估計上。

藥方三:小批次與信任域(預告 PPO)#

REINFORCE 每回合更新一次,梯度噪聲巨大;現代做法是收集一批次軌跡算平均梯度。但批次更新引出新問題:同一批資料用太多次(off-policy 化)會讓估計失效、策略崩壞——這就是第 5.2 節 PPO 的 clip 機制要解決的「更新量控制」問題。歷史的因果鏈在此清晰:REINFORCE(方差太大)→ baseline(方差減半)→ actor-critic(TD 誤差進一步降方差)→ GAE(λ 調優勢偏差-方差)→ PPO(控制更新步長防崩壞)。每一步都是在修上一步的缺陷。

程式碼:REINFORCE + Baseline 解 CartPole#

# pip install gymnasium torch
import gymnasium as gym
import numpy as np, torch, torch.nn as nn

env = gym.make("CartPole-v1")
GAMMA = 0.99
torch.manual_seed(0)

pi = nn.Sequential(nn.Linear(4,128), nn.ReLU(), nn.Linear(128,2))   # Actor
vf = nn.Sequential(nn.Linear(4,128), nn.ReLU(), nn.Linear(128,1))   # Critic(baseline)
opt_pi = torch.optim.Adam(pi.parameters(), lr=1e-3)
opt_vf = torch.optim.Adam(vf.parameters(), lr=1e-3)

def act(s):
    p = torch.softmax(pi(torch.tensor(s, dtype=torch.float32)), dim=-1)
    return np.random.choice(2, p=p.numpy()), p

for ep in range(1200):
    s, _ = env.reset(seed=ep)
    logps, rews, vs, done = [], [], [], False
    # --- 採樣一條軌跡 ---
    while not done:
        a, p = act(s)
        ns, r, term, trunc, _ = env.step(a)
        logps.append(torch.log(p[a] + 1e-8))
        vs.append(vf(torch.tensor(s, dtype=torch.float32)).squeeze())
        rews.append(r)
        s, done = ns, term or trunc
    # --- 回報與(優勢 = G - V) ---
    T = len(rews)
    G = np.zeros(T); g = 0.0
    for t in reversed(range(T)):
        g = rews[t] + GAMMA * g
        G[t] = g
    G = torch.tensor(G, dtype=torch.float32)
    V = torch.stack(vs)
    adv = G - V.detach()                    # 藥方一: baseline
    adv = (adv - adv.mean()) / (adv.std() + 1e-8)   # 標準化: 再降一截方差
    # --- Actor 更新: 藥方一的梯度形式 ---
    loss_pi = -(torch.stack(logps) * adv).mean()
    opt_pi.zero_grad(); loss_pi.backward(); opt_pi.step()
    # --- Critic 更新: 學 V ≈ G ---
    loss_vf = nn.functional.mse_loss(V, G)
    opt_vf.zero_grad(); loss_vf.backward(); opt_vf.step()

    if (ep + 1) % 100 == 0:
        sc = []
        for ev in range(10):
            s, _ = env.reset(seed=9000+ev); dn = False; tot = 0
            while not dn:
                a, _ = act(s); s, r, t, tr, _ = env.step(a); dn = t or tr; tot += r
            sc.append(tot)
        print(f"ep {ep+1:4d}  平均步數={np.mean(sc):.0f} (滿分500)")

對照實驗建議:(1)刪掉 adv = G - V.detach() 改用 G 純 REINFORCE——收斂明顯變慢、曲線抖動加大;(2)刪掉標準化——方差又升;(3)把 lr 調大 10 倍——策略崩壞(性能斷崖),預示第 5.2 節 PPO 信任域的必要性。

本節重點#

  1. 策略梯度定理: \(\nabla J = \mathbb{E}[\sum_t \nabla\log\pi(a_t|s_t)\, G_t]\) ——環境不可微被 likelihood ratio 技巧繞過;直覺就是 Thorndike 效果律的精確化(好軌跡推高其動作機率)。
  2. Baseline 定理:與動作無關的量對梯度期望零貢獻;取 baseline \(= V_\phi(s)\) 後加權量變成優勢 \(A = Q - V\) ——「比平均好多少」。
  3. Actor-Critic:用 TD 誤差 \(\delta_t\) 當低方差優勢估計;GAE 用 λ 加權多步 TD 誤差,是第 3.1 節光譜在優勢估計上的重現。
  4. 策略路線的核心代價是高方差;REINFORCE → baseline → AC → GAE → PPO 的演進史就是一部降方差史。
  5. 策略直接參數化天然支援連續動作與隨機策略——這是價值路線做不到、而 LLM 時代(第 8 章)必需的能力。

思考問題#

  1. 證明 baseline 定理。並推理:若 baseline \(b(s,a)\) 依賴動作,證明為何不再成立、引入什麼偏差。
  2. 「策略梯度不需要環境可微」——請指出式子中環境的哪些成分被消掉了,又保留了什麼。這與第 7 章「學一個可微分的環境模型」的動機有何互補?
  3. 在程式中把 baseline 換成「整批回報的均值」(常數)而非 \(V_\phi(s)\) 。這仍是合法的 baseline 嗎?方差效果為何較差?
  4. 策略梯度是隨機上升:同一批資料重用(epoch > 1)時,估計就不再無偏。請由此推演 PPO 為何必須引入「重要性採樣比率 + 裁剪」(第 5.2 節的伏筆)。
  5. 石頭剪刀布的最優策略是隨機的 (1/3,1/3,1/3)。請說明為何 \(\arg\max Q\) 型確定性策略在此問題上永遠學不到最優,而策略梯度可以逼近它。