Actor-Critic强化学习实战:从算法原理到工程实现

1次阅读
没有评论

共计 2738 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

背景介绍:为什么需要 Actor-Critic?

强化学习在连续控制问题(如机器人控制、自动驾驶)中面临两大核心挑战:

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()

调优与避坑指南

关键超参数设置

  1. 学习率
  2. Actor 网络通常需要比 Critic 更小的学习率(建议比例 1:2)
  3. 使用 Adam 优化器时 3e- 4 是较好的起点

  4. 折扣因子 γ

  5. 短期任务取 0.9-0.99
  6. 长期任务建议 0.99-0.999

  7. 熵系数

  8. 初始设为 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  # 接近理论最大值

开放思考题

  1. 如何设计适用于高维图像输入的 Actor-Critic 网络结构?
  2. 在多智能体场景下,Critic 网络应该如何评估联合行动的价值?
  3. 当遇到稀疏奖励问题时,可以如何改进优势函数的计算方式?

希望这篇实战指南能帮助你快速掌握 Actor-Critic 的核心实现技巧。在实际项目中,建议先从简单环境验证算法正确性,再逐步增加环境复杂度。记住:强化学习的调参过程往往需要耐心,良好的监控系统(如 TensorBoard)会极大提升调试效率。

正文完
 0
评论(没有评论)