簡介
策略梯度方法直接最佳化策略 π(a|s;θ) — 而不是學習價值函數然後推導策略。優點:處理連續動作、隨機策略和收斂保證。
1. 策略梯度定理
$$\nabla_\theta J(\theta) = \mathbb{E}{\pi\theta}[\nabla_\theta \log \pi_\theta(a|s) \cdot G_t]$$
直覺:增加行動的機率導致高回報,減少行動的機率導致低迴報。
2. 強化演算法
import torch
import torch.nn as nn
from torch.distributions import Categorical
class PolicyNetwork(nn.Module):
def __init__(self, state_dim, action_dim):
super().__init__()
self.net = nn.Sequential(
nn.Linear(state_dim, 128),
nn.ReLU(),
nn.Linear(128, action_dim),
nn.Softmax(dim=-1),
)
def forward(self, x):
return self.net(x)
def reinforce(env, policy_net, optimizer, num_episodes, gamma=0.99):
for episode in range(num_episodes):
log_probs = []
rewards = []
state, _ = env.reset()
done = False
while not done:
probs = policy_net(torch.FloatTensor(state))
dist = Categorical(probs)
action = dist.sample()
log_probs.append(dist.log_prob(action))
state, reward, terminated, truncated, _ = env.step(action.item())
rewards.append(reward)
done = terminated or truncated
# Compute discounted returns
returns = []
G = 0
for r in reversed(rewards):
G = r + gamma * G
returns.insert(0, G)
returns = torch.FloatTensor(returns)
returns = (returns - returns.mean()) / (returns.std() + 1e-8)
# Policy gradient loss
loss = sum(-lp * G for lp, G in zip(log_probs, returns))
optimizer.zero_grad()
loss.backward()
optimizer.step()
3. 基線和變異數減少
使用基線 b(s) 來減少變異數而不改變預期梯度:
$$\nabla_\theta J(\theta) = \mathbb{E}[\nabla_\theta \log \pi_\theta(a|s) \cdot (G_t - b(s))]$$
4. 演員評論家
class ActorCritic(nn.Module):
def __init__(self, state_dim, action_dim):
super().__init__()
self.shared = nn.Sequential(nn.Linear(state_dim, 128), nn.ReLU())
self.actor = nn.Sequential(nn.Linear(128, action_dim), nn.Softmax(dim=-1))
self.critic = nn.Linear(128, 1)
def forward(self, x):
feat = self.shared(x)
return self.actor(feat), self.critic(feat)
def actor_critic_update(model, optimizer, state, action, reward, next_state, done, gamma):
probs, value = model(torch.FloatTensor(state))
_, next_value = model(torch.FloatTensor(next_state))
# Advantage = TD error
advantage = reward + gamma * next_value * (1 - done) - value
# Actor loss
dist = Categorical(probs)
actor_loss = -dist.log_prob(torch.tensor(action)) * advantage.detach()
# Critic loss
critic_loss = advantage.pow(2)
loss = actor_loss + 0.5 * critic_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
5. A2C — 優勢演員評論家
A2C = 同步、多位工作人員 → 減少變異數 + 更快的訓練。
總結
| 方法 | 類型 | 變異數 | 偏見 | 線上 |
|---|---|---|---|---|
| 加強 | 政策 | 高 | 無 | ❌ |
| 強化 + 基線 | 政策 | 中 | 無 | ❌ |
| 演員評論家 | 兩者 | 低 | 一些 | ✅ |
| A2C | 兩者 | 降低 | 一些 | ✅ |