共计 2738 个字符,预计需要花费 7 分钟才能阅读完成。
背景介绍:为什么需要 Actor-Critic?
强化学习在连续控制问题(如机器人控制、自动驾驶)中面临两大核心挑战:

- 连续动作空间处理困难:传统 Q -Learning 需要离散化动作空间,导致维度爆炸问题
- 高维状态收敛缓慢:Policy Gradient 方法在复杂环境中方差过高,训练不稳定
Actor-Critic 架构通过分离策略(Actor)和评估(Critic)模块实现优势互补:
# 直观理解 Actor-Critic 工作流程
state → Actor → action → environment → reward
↑ Critic 评估优劣 ↓
←←←← 梯度更新 ←←←←←
算法横向对比
| 方法 | 优势 | 局限性 |
|---|---|---|
| Q-Learning | 理论收敛性好 | 需离散动作,不适合连续控制 |
| Policy Gradient | 直接优化策略 | 高方差,采样效率低 |
| Actor-Critic | 天然支持连续动作,方差较低 | 实现复杂度较高 |
PyTorch 实现详解
1. 网络结构定义
import torch
import torch.nn as nn
class Actor(nn.Module):
"""策略网络,输出动作概率分布"""
def __init__(self, state_dim, action_dim, hidden_size=256):
super().__init__()
self.net = nn.Sequential(nn.Linear(state_dim, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, action_dim),
nn.Tanh() # 假设动作空间在 [-1,1] 范围
)
def forward(self, state):
return self.net(state)
class Critic(nn.Module):
"""价值网络,评估状态价值"""
def __init__(self, state_dim, hidden_size=256):
super().__init__()
self.net = nn.Sequential(nn.Linear(state_dim, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, 1)
)
def forward(self, state):
return self.net(state)
2. 优势函数计算
采用 GAE(Generalized Advantage Estimation)降低方差:
$$ A_t = \sum_{k=0}^{∞} (γλ)^k δ_{t+k} $$
其中 TD-error $δ_t = r_t + γV(s_{t+1}) – V(s_t)$
def compute_advantage(rewards, values, gamma=0.99, lambda_=0.95):
"""GAE 优势计算"""
deltas = rewards[:-1] + gamma * values[1:] - values[:-1]
advantages = []
advantage = 0
for delta in reversed(deltas):
advantage = delta + gamma * lambda_ * advantage
advantages.insert(0, advantage)
return torch.tensor(advantages)
完整训练流程
class A2CAgent:
def __init__(self, state_dim, action_dim):
self.actor = Actor(state_dim, action_dim)
self.critic = Critic(state_dim)
self.optimizer = torch.optim.Adam(list(self.actor.parameters()) + list(self.critic.parameters()),
lr=3e-4
)
self.memory = [] # 简易经验回放
def update(self, batch):
states, actions, rewards, next_states, dones = batch
# Critic 更新
values = self.critic(states)
next_values = self.critic(next_states)
advantages = compute_advantage(rewards, values)
# Actor 更新(含策略熵正则)action_probs = self.actor(states)
entropy = -torch.mean(action_probs * torch.log(action_probs + 1e-5))
policy_loss = -(advantages * torch.log(action_probs)).mean() - 0.01*entropy
# 价值损失
value_loss = nn.MSELoss()(values, rewards + gamma*next_values*(1-dones))
# 联合优化
self.optimizer.zero_grad()
(policy_loss + 0.5*value_loss).backward()
nn.utils.clip_grad_norm_(self.actor.parameters(), 0.5) # 梯度裁剪
self.optimizer.step()
调优与避坑指南
关键超参数设置
- 学习率:
- Actor 网络通常需要比 Critic 更小的学习率(建议比例 1:2)
-
使用 Adam 优化器时 3e- 4 是较好的起点
-
折扣因子 γ :
- 短期任务取 0.9-0.99
-
长期任务建议 0.99-0.999
-
熵系数:
- 初始设为 0.01,观察策略探索程度调整
常见问题解决方案
- 策略坍塌:
- 增加熵正则项
-
设置最小探索率 ε
-
高方差:
- 采用 GAE 代替简单优势估计
-
增大 batch size(建议≥64)
-
分布式训练陷阱:
- 使用参数服务器同步频率不宜过高
- 建议采用异步更新策略
性能验证
在 Pendulum-v1 环境中的训练曲线:
Episode 100 | Avg Reward: -1200
Episode 200 | Avg Reward: -800
Episode 500 | Avg Reward: -200
Episode 1000 | Avg Reward: -50 # 接近理论最大值
开放思考题
- 如何设计适用于高维图像输入的 Actor-Critic 网络结构?
- 在多智能体场景下,Critic 网络应该如何评估联合行动的价值?
- 当遇到稀疏奖励问题时,可以如何改进优势函数的计算方式?
希望这篇实战指南能帮助你快速掌握 Actor-Critic 的核心实现技巧。在实际项目中,建议先从简单环境验证算法正确性,再逐步增加环境复杂度。记住:强化学习的调参过程往往需要耐心,良好的监控系统(如 TensorBoard)会极大提升调试效率。
正文完
发表至: 人工智能
近一天内
