共计 2530 个字符,预计需要花费 7 分钟才能阅读完成。
引言
强化学习作为机器学习的重要分支,近年来在游戏 AI、机器人控制等领域取得了显著成果。Actor-Critic 框架结合了策略梯度方法和价值函数的优势,成为许多复杂任务的首选算法。但对于初学者来说,理解其内部结构和实现细节往往存在困难。本文将从结构图解析入手,逐步拆解这一框架的奥秘。

1. 背景与痛点
强化学习的核心思想是通过与环境的交互来学习最优策略。常见的算法包括:
- 基于价值的方法(如 Q -learning)
- 基于策略的方法(如 REINFORCE)
- Actor-Critic 结合两者优势
Actor-Critic 框架的优势在于:
- 相比纯策略梯度方法(如 REINFORCE),减少了方差
- 相比纯价值函数方法(如 Q -learning),能处理连续动作空间
- 通过 Critic 提供的信号,Actor 能获得更稳定的梯度
新手常见问题:
- 训练不稳定,策略容易崩溃
- 收敛速度慢
- 超参数敏感
2. 结构图解析
典型的 Actor-Critic 框架包含以下核心组件:
+----------------+ +----------------+
| Actor | | Critic |
| (策略网络) | | (价值网络) |
+-------+--------+ +-------+--------+
| |
v v
+-------------------------------+
| 环境交互 |
+-------------------------------+
2.1 Actor 网络
- 输入:环境状态
- 输出:动作概率分布(离散)或动作值(连续)
- 核心功能:根据当前策略选择动作
2.2 Critic 网络
- 输入:状态(或状态 - 动作对)
- 输出:状态价值 V(s)或动作价值 Q(s,a)
- 核心功能:评估当前策略的质量
2.3 交互流程
- Actor 根据当前状态选择动作
- 环境执行动作并返回新状态和奖励
- Critic 评估状态价值
- 使用 TD 误差更新 Actor 和 Critic
3. 实现细节
以下是 PyTorch 实现的简化版本:
import torch
import torch.nn as nn
import torch.optim as optim
class Actor(nn.Module):
"""策略网络"""
def __init__(self, state_dim, action_dim):
super().__init__()
self.fc1 = nn.Linear(state_dim, 64)
self.fc2 = nn.Linear(64, action_dim)
def forward(self, state):
x = torch.relu(self.fc1(state))
return torch.softmax(self.fc2(x), dim=-1)
class Critic(nn.Module):
"""价值网络"""
def __init__(self, state_dim):
super().__init__()
self.fc1 = nn.Linear(state_dim, 64)
self.fc2 = nn.Linear(64, 1)
def forward(self, state):
x = torch.relu(self.fc1(state))
return self.fc2(x)
# 初始化网络
actor = Actor(state_dim=4, action_dim=2)
critic = Critic(state_dim=4)
# 定义优化器
actor_optim = optim.Adam(actor.parameters(), lr=1e-3)
critic_optim = optim.Adam(critic.parameters(), lr=1e-3)
# 训练循环示例
for episode in range(1000):
state = env.reset()
done = False
while not done:
# 选择动作
action_probs = actor(torch.FloatTensor(state))
action = torch.multinomial(action_probs, 1).item()
# 与环境交互
next_state, reward, done, _ = env.step(action)
# 计算 TD 误差
value = critic(torch.FloatTensor(state))
next_value = critic(torch.FloatTensor(next_state))
td_error = reward + (1-done)*gamma*next_value - value
# 更新 Critic
critic_loss = td_error.pow(2)
critic_optim.zero_grad()
critic_loss.backward()
critic_optim.step()
# 更新 Actor
actor_loss = -torch.log(action_probs[action]) * td_error.detach()
actor_optim.zero_grad()
actor_loss.backward()
actor_optim.step()
state = next_state
4. 优化技巧
4.1 经验回放
- 存储经验 (s,a,r,s’) 到缓冲区
- 随机采样小批量进行训练
- 打破数据相关性,提高稳定性
4.2 目标网络
- 使用独立的网络计算目标值
- 定期更新目标网络参数
- 公式:θ’ ← τθ + (1-τ)θ’
4.3 熵正则化
- 鼓励探索
- 在损失函数中加入策略熵:L = L_actor + βH(π)
- β 控制探索强度
5. 避坑指南
常见错误及解决方案:
- 问题:训练初期策略崩溃
-
方案:适当降低学习率,增加探索
-
问题:Critic 过拟合
-
方案:使用更大的网络,增加 dropout
-
问题:梯度爆炸
- 方案:梯度裁剪,normalize 输入
6. 性能考量
关键权衡:
- 探索 vs 利用:ε-greedy 或熵正则化
- 偏差 vs 方差:n-step TD 或 GAE
- 采样效率:优先经验回放
7. 总结与思考
Actor-Critic 框架的强大之处在于其灵活性。我们可以:
- 更换网络结构(如使用 CNN 处理图像)
- 结合其他技术(如 PPO、SAC)
- 应用于各类连续控制任务
建议从简单的环境(如 CartPole)开始实践,逐步增加复杂度。记住,调试强化学习算法需要耐心,合理的日志记录和可视化工具至关重要。
正文完
发表至: 机器学习
近一天内
