はじめに
ポリシー勾配 メソッドは、値関数を学習してポリシーを導出する代わりに、ポリシー π(a|s;θ) を直接最適化します。利点: 継続的なアクション、確率的ポリシー、および収束保証を処理します。
1. ポリシー勾配定理
$$\nabla_\theta J(\theta) = \mathbb{E}{\pi\theta}[\nabla_\theta \log \pi_\theta(a|s) \cdot G_t]$$
直感: アクションの確率を高めると高いリターンが得られ、アクションの確率を下げると低いリターンが得られます。
2. REINFORCE アルゴリズム
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 | 両方 | 下 | いくつか | ✅ |