跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

强化学习:演员评论家 Actor-Critic 算法详解与实现

Actor-Critic 算法通过结合策略梯度与值函数估计,有效降低了策略更新的高方差问题。Actor 负责动作选择,Critic 利用时序差分误差评估价值并指导优化。文章详细推导了数学原理,并提供基于 PyTorch 的完整实现及 CartPole 环境训练示例。

氛围发布于 2026/3/23更新于 2026/6/2320 浏览
强化学习:演员评论家 Actor-Critic 算法详解与实现

演员评论家 Actor-Critic 算法

Actor-Critic 算法是强化学习中一种结合了策略梯度(Policy Gradient)和值函数估计(Value Function Estimation)的方法。它通过引入 Critic 来评估状态价值,从而降低策略更新过程中的方差,加速收敛。

核心概念理解

角色设定

在 Actor-Critic 框架中,两个网络分工明确:

  • Actor(演员):负责决策。根据当前状态 $s$ 输出动作 $a$ 的概率分布,即策略 $\ heta(a|s)$。
  • Critic(评论家):负责评估。估算当前状态的价值 $V(s)$ 或状态 - 动作对的价值 $Q(s, a)$,用于判断 Actor 的动作好坏。

协作机制

  1. Actor 观察环境并执行动作。
  2. Critic 接收反馈,计算时序差分误差(TD Error),评价该动作的优劣。
  3. Actor 利用 Critic 的评价信号更新策略参数,向更优方向移动。
  4. Critic 同时根据实际奖励更新价值估计,提高评估准确性。

这种机制类似于教练指导运动员:运动员(Actor)尝试动作,教练(Critic)实时反馈效果,双方共同提升表现。

背景与动机

强化学习的演进

强化学习方法主要分为三类:

  1. 值函数方法(如 Q-Learning):估算价值表,适合离散空间,但面临维度灾难。
  2. 策略方法(如 REINFORCE):直接优化策略,适合连续空间,但梯度方差大,收敛慢。
  3. 结合方法(Actor-Critic):取长补短,既保留策略方法的灵活性,又利用值函数降低方差。

策略梯度的局限性

纯策略梯度方法的目标函数梯度为: $$ \nabla_\theta J(\theta) = \mathbb{E}{\pi\theta} \left[ \nabla_\theta \log \pi_\theta(a|s) \cdot A^\pi(s, a) \right] $$ 其中优势函数 $A^\pi(s, a)$ 衡量动作相对于平均水平的优劣。直接使用环境奖励作为基线会导致高方差问题,需要大量采样才能稳定更新。引入 Critic 后,用 TD 误差替代优势函数,显著降低了方差。

数学推导

优化目标

最大化累积折扣奖励的期望: $$ J(\theta) = \mathbb{E}{\pi\theta} \left[ \sum_{t=0}^\infty \gamma^t r_t \right] $$

Critic 更新(值函数估计)

Critic 通过最小化均方误差来学习状态值函数 $V(s)$: $$ L(w) = \frac{1}{2} \mathbb{E} \left[ \left( r + \gamma V^\pi(s') - V^\pi(s) \right)^2 \right] $$ 参数 $w$ 的更新方向由 TD 误差 $\delta$ 决定: $$ \delta = r + \gamma V^\pi(s') - V^\pi(s) $$ $$ w \leftarrow w + \beta \cdot \delta \cdot \nabla_w V^\pi(s) $$

Actor 更新(策略优化)

Actor 利用 Critic 计算的 TD 误差作为优势函数的近似,更新策略参数 $\theta$: $$ \theta \leftarrow \theta + \alpha \cdot \nabla_\theta \log \pi_\theta(a|s) \cdot \delta $$ 这里 $\delta > 0$ 表示动作优于预期,应增加概率;反之则减少。

PyTorch 实现

下面是一个基于 PyTorch 的完整实现示例。代码结构清晰,分为策略网络、价值网络和主训练循环。

网络定义

import torch
import torch.nn as nn
from torch.nn import functional as F

class PolicyNet(nn.Module):
    """Actor: 策略网络"""
    def __init__(self, n_states, n_hiddens, n_actions):
        super(PolicyNet, self).__init__()
        self.fc1 = nn.Linear(n_states, n_hiddens)
        self.fc2 = nn.Linear(n_hiddens, n_actions)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        return F.softmax(self.fc2(x), dim=1)

class ValueNet(nn.Module):
    """Critic: 价值网络"""
    def __init__(self, n_states, n_hiddens):
        super(ValueNet, self).__init__()
        self.fc1 = nn.Linear(n_states, n_hiddens)
        self.fc2 = nn.Linear(n_hiddens, 1)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        return self.fc2(x)

算法逻辑

class ActorCritic:
    def __init__(self, n_states, n_hiddens, n_actions, actor_lr, critic_lr, gamma):
        self.gamma = gamma
        self.actor = PolicyNet(n_states, n_hiddens, n_actions)
        self.critic = ValueNet(n_states, n_hiddens)
        self.actor_optimizer = torch.optim.Adam(self.actor.parameters(), lr=actor_lr)
        self.critic_optimizer = torch.optim.Adam(self.critic.parameters(), lr=critic_lr)

    def take_action(self, state):
        # 将 numpy 状态转换为 tensor
        state = torch.tensor(state[np.newaxis, :], dtype=torch.float)
        probs = self.actor(state)
        action_dist = torch.distributions.Categorical(probs)
        action = action_dist.sample().item()
        return action

    def update(self, transition_dict):
        states = torch.tensor(transition_dict['states'], dtype=torch.float)
        actions = torch.tensor(transition_dict['actions']).view(-1, 1)
        rewards = torch.tensor(transition_dict['rewards'], dtype=torch.float).view(-1, 1)
        next_states = torch.tensor(transition_dict['next_states'], dtype=torch.float)
        dones = torch.tensor(transition_dict['dones'], dtype=torch.float).view(-1, 1)

        # Critic 更新:最小化 TD 误差
        td_value = self.critic(states)
        td_target = rewards + self.gamma * self.critic(next_states) * (1 - dones)
        td_delta = td_target - td_value
        critic_loss = F.mse_loss(td_value, td_target.detach())

        # Actor 更新:最大化期望回报
        log_probs = torch.log(self.actor(states).gather(1, actions))
        actor_loss = -torch.mean(log_probs * td_delta.detach())

        # 反向传播与参数更新
        self.actor_optimizer.zero_grad()
        self.critic_optimizer.zero_grad()
        actor_loss.backward()
        critic_loss.backward()
        self.actor_optimizer.step()
        self.critic_optimizer.step()

训练脚本

使用 CartPole-v1 环境进行验证。

import gym
import matplotlib.pyplot as plt

env_name = 'CartPole-v1'
num_episodes = 100
gamma = 0.9
actor_lr = 1e-3
critic_lr = 1e-2
n_hiddens = 16

env = gym.make(env_name)
n_states = env.observation_space.shape[0]
n_actions = env.action_space.n

agent = ActorCritic(n_states, n_hiddens, n_actions, actor_lr, critic_lr, gamma)
return_list = []

for i in range(num_episodes):
    state = env.reset()[0]
    done = False
    episode_return = 0
    transition_dict = {'states': [], 'actions': [], 'next_states': [], 'rewards': [], 'dones': []}

    while not done:
        action = agent.take_action(state)
        next_state, reward, done, _, _ = env.step(action)
        
        transition_dict['states'].append(state)
        transition_dict['actions'].append(action)
        transition_dict['next_states'].append(next_state)
        transition_dict['rewards'].append(reward)
        transition_dict['dones'].append(done)
        
        state = next_state
        episode_return += reward

    return_list.append(episode_return)
    agent.update(transition_dict)
    print(f'Iter {i}, Avg Return: {np.mean(return_list[-10:])}')

plt.plot(return_list)
plt.title('Training Returns')
plt.show()

关键点总结

  1. TD 误差是关键:Critic 的评估质量直接影响 Actor 的更新方向。如果 Critic 不准,Actor 可能学偏。
  2. 熵正则化:在实际应用中,建议在 Actor 损失中加入熵项,鼓励探索,避免过早陷入局部最优。
  3. 超参数敏感:Actor 和 Critic 的学习率通常不同,Critic 往往需要更快的收敛速度。
  4. 扩展算法:A3C 引入了多线程并行,PPO 限制了策略更新幅度,都是基于 Actor-Critic 思想的改进。

总结

Actor-Critic 算法通过结合策略梯度与值函数估计,有效解决了纯策略方法方差大的问题。文章详细推导了数学原理,并提供了基于 PyTorch 的完整实现及 CartPole 环境训练示例。掌握这一基础架构,有助于进一步理解 PPO、SAC 等现代强化学习算法。

目录

  1. 演员评论家 Actor-Critic 算法
  2. 核心概念理解
  3. 角色设定
  4. 协作机制
  5. 背景与动机
  6. 强化学习的演进
  7. 策略梯度的局限性
  8. 数学推导
  9. 优化目标
  10. Critic 更新(值函数估计)
  11. Actor 更新(策略优化)
  12. PyTorch 实现
  13. 网络定义
  14. 算法逻辑
  15. 训练脚本
  16. 关键点总结
  17. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • sd-webui-animatediff 扩展使用指南
  • Virt-A-Mate 虚拟实境交互平台技术解析
  • Android 开发工程师 70 道核心技术面试题整理与解析
  • 大模型应用开发极简入门:基于 GPT-4 和 ChatGPT 实战指南
  • 前缀和算法详解与应用
  • 前端请求后端 404/405/500 状态码:核心排查与解决方案
  • 前端兼容策略深度解析:优雅降级与渐进增强
  • GPT-OSS-20B 模型本地部署及 WebUI 交互指南
  • Python 调用高德地图 MCP 服务查询天气示例
  • OpenClaw 安装与飞书机器人全流程配置指南
  • OpenClaw 生态 16 款 AI Agent 选型指南
  • 企业级大模型构建:知识库核心与落地实践
  • Milvus 向量数据库实战:Attu 可视化安装与 Python 整合指南
  • 大模型应用:如何增强模型记忆力与上下文管理
  • UniApp 小程序自定义底部 TabBar 闪烁白屏优化方案
  • C++ 核心基础:从语法特性到入门体系构建
  • 利用 Anonymous GitHub 创建双盲评审匿名代码链接
  • LMArena.ai 全球 AI 模型盲测对战与排行榜使用指南
  • 低空经济下无人机光伏巡检技术与应用
  • Spring 国际化核心原理详解:4 大组件实现企业级多语言开发

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online