JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

REINFORCE:蒙地卡羅策略梯度

把定理變成一個真正會學習的迴圈,再用兩個便宜的點子——只看未來報酬與基準線——讓它的雜訊大幅下降。

從定理到演算法

REINFORCE 是使用策略梯度定理最直接的方式。它是一種蒙地卡羅(Monte-Carlo)方法:用當前策略跑到回合結束,再把你實際觀察到的報酬當作梯度裡的權重。沒有模型、不做自助(bootstrapping),就只是抽樣得到的軌跡。

  1. 用當前策略跑出一整段回合:s0, a0, r1, s1, a1, r2, …
  2. 對每個時刻 t,計算報酬 Gt(從 t 起往後的折扣報酬總和)。
  3. 對數微分技巧累加梯度 Σt Gt · ∇θ log π(at | st; θ)。
  4. 做一步上升:θ ← θ + α · (那個梯度)。再用新的回合重複。

未來報酬:別怪罪過去

天真的版本會把每個動作的對數機率,都乘上整段回合的報酬。但一個在時刻 t 採取的動作,不可能影響到 t 之前就已到達的報酬。把那些過去的報酬留在權重裡,只會增加雜訊。修正方式是未來報酬(reward-to-go):每個動作只用它之後才出現的報酬來加權,即從 t 起的總和。估計仍然無偏,而且明顯安靜許多。

\nabla_\theta J(\theta)=\mathbb{E}_{\tau\sim\pi_\theta}\!\left[\sum_{t=0}^{T}\Big(\sum_{t'=t}^{T} r_{t'}\Big)\,\nabla_\theta \log \pi_\theta(a_t\mid s_t)\right]

未来回报:每个动作只用 t 时刻及之后获得的奖励来加权,绝不使用它之前的奖励。

基準線:減去你原本就預期的

基準線(baseline)會在用報酬加權梯度之前,先減去一個與狀態相依的參考值 b(st):(Gt − b(st)) · ∇θ log π。其中的奧妙——也就是基準線相減直覺——在於:任何不依賴動作的基準線都讓梯度保持無偏(它的期望貢獻恰好是零),但選得好的基準線卻能大幅砍掉變異數。

\nabla_\theta J(\theta)=\mathbb{E}\!\left[\sum_{t}\big(G_t-b(s_t)\big)\,\nabla_\theta \log \pi_\theta(a_t\mid s_t)\right]

在用回报加权梯度之前先减去基线 b(s_t),在不引入偏差的情况下降低方差。

為什麼有用?如果在某個狀態下每個動作都得到 +100 的報酬,原始訊號會把它們全部等量往上推——智能體學不到哪個比較好,只學到數字很大。減去這個狀態的平均報酬,剩下的就是相對優劣:哪些動作超出了預期。b(st) 最常見的選擇是對該狀態價值的估計值,而這正好把我們帶向演員-評論家。

為什麼光靠 REINFORCE 還不夠

即使有了未來報酬與基準線,原味的 REINFORCE 仍受困於很高的策略梯度變異數(policy gradient variance)。因為它要等一整段回合,單一次幸運或倒楣的運行就可能主宰一次更新,而且樣本效率差——每條軌跡只用一次就丟掉。實務上你會看到它確實在學,但在任何超出玩具問題的情境上都又慢又抖。

原始 REINFORCE 处于高方差的一端:整回合的回报让它的梯度估计在不同回合之间剧烈波动。

偏差—方差权衡曲线,显示总误差是偏差与方差之和。

# REINFORCE with reward-to-go and a baseline (one episode)
for t in range(T):
    G[t] = sum(gamma**(k-t) * r[k] for k in range(t, T))   # reward-to-go
advantage = G - baseline(states)                            # subtract reference
loss = -(advantage.detach() * logprob(actions, states)).sum()
loss.backward(); optimizer.step()
整個演算法只需幾行;本單元接下來都在談如何讓「優勢值」更不嘈雜。