本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:在强化学习领域,ADP(近似动态规划)结合Actor-Critic架构为复杂决策问题提供了高效解决方案。本项目围绕“ADP冲冲冲”展开,深入实现ADP神经网络模型中的Actor策略网络与Critic评估网络协同机制,涵盖Criticactor融合思想、值函数逼近、策略优化等核心技术。压缩包包含可扩展代码框架,需用户自行配置输入数据与奖励信号,适用于游戏AI、机器人控制和资源调度等场景,是深入理解强化学习算法设计与工程落地的重要实践平台。

近似动态规划与Actor-Critic协同学习机制深度解析

在强化学习的演进历程中,我们曾一度被“维度灾难”困于高维状态空间之外。传统动态规划依赖精确模型和完整状态枚举,在面对真实世界的复杂系统时显得力不从心——无论是自动驾驶中的多模态感知融合,还是机器人控制中的连续动作优化,亦或是金融交易里瞬息万变的市场信号,都让表格型方法望尘莫及。

而今天, 近似动态规划(ADP) 正是打破这一桎梏的关键钥匙。它不再执着于对每一个状态进行显式建模,而是引入函数逼近器——尤其是深度神经网络——来估计价值函数或策略本身。这不仅解决了可扩展性问题,更开启了一种全新的智能体设计范式:从“记住最优路径”转向“学会评估与决策”。

🎯 核心思想跃迁
传统DP → “我知道每一步的价值”
ADP → “我能快速判断这个局面好不好”

这种转变的背后,是马尔可夫决策过程(MDP)框架下对贝尔曼方程的创造性重构。虽然我们依然保留了状态转移、即时奖励以及最优性原理这些基石概念,但求解方式已彻底革新。值函数近似(Value Function Approximation)成为主角,而策略搜索技术则赋予算法更强的探索能力。

正是在这种背景下, Actor-Critic架构 应运而生,并迅速成长为现代强化学习系统的骨干结构。它的精妙之处在于将“行动”与“评价”分离,模拟人类认知中的“做-思”循环:一个模块负责执行动作并探索环境(Actor),另一个模块则冷静观察、打分反馈(Critic)。两者相互驱动,形成闭环,共同逼近最优策略。

但这不仅仅是两个网络的简单拼接。当我们深入剖析其内部工作机制时会发现,这是一场关于 梯度流动、误差传播、稳定性博弈 的精密工程。从REINFORCE的高方差困境到Critic如何作为“指导教师”降低噪声;从随机策略与确定性策略的设计权衡,到双Q网络防止过高估计的技术细节……每一环都在讲述同一个故事: 如何在一个不确定的世界里,构建一个既高效又稳健的学习系统?

让我们一起揭开这场智能革命背后的数学之美与工程智慧。✨


Actor-Critic 架构的本质:不只是两个网络那么简单

你有没有想过,为什么叫“Actor-Critic”而不是“Policy-Value”?这个名字本身就藏着玄机。

想象一下演员在舞台上即兴发挥(Actor),而导演坐在台下记录笔记、给出建议(Critic)。前者负责表现,后者专注评判。他们共享同一部剧本(环境交互数据),却扮演截然不同的角色。最终目标一致——呈现一场完美的演出,但在过程中必须保持独立思考。

这就是Actor-Critic的核心哲学: 解耦决策与评估

🔧 解耦的力量:为何要拆开策略与价值?

早期的策略梯度方法如 REINFORCE 虽然理论上优雅,但实际训练起来就像盲人摸象——每次只能等到整条轨迹结束才知道“刚才那波操作到底行不行”。结果就是:

  • ✅ 理论无偏
  • ❌ 方差极高
  • ⏳ 更新延迟严重
  • 📉 样本效率极低

比如在 CartPole 任务中,即使你的平衡技巧已经炉火纯青,某次因为初始摆角稍大导致提前倒下,整个episode的所有动作都会被惩罚。这种“一棒子打死”的逻辑显然不合理。

于是研究者开始思考:能不能有个“实时裁判”,边看边打分?这就催生了Critic的角色。

💡 关键洞察
我们不需要等游戏结束才评分,完全可以根据当前局势预判未来潜力!

于是,Critic登场了。它不参与决策,只做一件事:估算当前状态(或状态-动作对)的长期回报。这个估计值随后被用于计算 优势函数(Advantage)

$$
A(s,a) = Q(s,a) - V(s)
$$

意思是:“在这个状态下采取这个动作,比平均水平好多少?” 如果 $ A > 0 $,说明干得不错,该鼓励;反之则应抑制。

这样一来,Actor的更新就不再是基于全轨迹回报 $ G_t $,而是基于局部优势信号 $ A_t $。这带来了三大好处:

  1. 低方差 :优势信号比完整回报更稳定;
  2. 在线学习 :无需等待episode结束即可更新;
  3. 高频反馈 :每步都能获得指导,收敛更快。
维度 Actor(策略网络) Critic(价值网络)
功能目标 学习最优策略 $ \pi_\theta(a|s) $ 评估当前策略的价值 $ V_\phi(s) $ 或 $ Q_\phi(s,a) $
输出类型 动作概率分布(离散)或动作参数(连续) 标量值(状态值或动作值)
损失函数 策略梯度损失(依赖优势函数) 均方误差(TD误差)
参数更新方式 策略梯度上升(最大化期望回报) 函数逼近下降(最小化预测误差)
是否需要环境模型 否(完全在线学习)

这种分工体现了经典的“控制-观测”分离原则,类似于工程控制系统中的控制器与状态观测器。Actor主动干预环境以改变轨迹,Critic被动观察并提供反馈,二者构成一个自适应闭环系统。

import torch
import torch.nn as nn
import torch.optim as optim

# 定义简单的Actor网络(连续动作空间)
class Actor(nn.Module):
    def __init__(self, state_dim, action_dim, hidden_size=64):
        super(Actor, self).__init__()
        self.net = nn.Sequential(
            nn.Linear(state_dim, hidden_size),
            nn.ReLU(),
            nn.Linear(hidden_size, hidden_size),
            nn.ReLU(),
            nn.Linear(hidden_size, action_dim),
            nn.Tanh()  # 动作归一化到[-1,1]
        )
    def forward(self, state):
        return self.net(state)

# 定义Critic网络(状态价值函数)
class Critic(nn.Module):
    def __init__(self, state_dim, hidden_size=64):
        super(Critic, self).__init__()
        self.net = nn.Sequential(
            nn.Linear(state_dim, hidden_size),
            nn.ReLU(),
            nn.Linear(hidden_size, hidden_size),
            nn.ReLU(),
            nn.Linear(hidden_size, 1)
        )
    def forward(self, state):
        return self.net(state)

# 初始化网络与优化器
state_dim, action_dim = 4, 1
actor = Actor(state_dim, action_dim)
critic = Critic(state_dim)
optim_actor = optim.Adam(actor.parameters(), lr=1e-4)
optim_critic = optim.Adam(critic.parameters(), lr=1e-3)

🔍 代码逻辑逐行解读:

  1. class Actor(nn.Module): —— 定义策略网络类,继承自 PyTorch 的模块基类。
  2. nn.Sequential(...) —— 构建三层全连接网络,包含两个隐藏层,最后一层使用 Tanh 将输出限制在 [-1,1] 区间,适用于标准化动作空间。
  3. forward(self, state): —— 前向传播函数,接收状态张量并返回建议动作。
  4. class Critic(nn.Module): —— 定义价值网络,结构类似,但输出仅为单个标量(状态值)。
  5. optim.Adam(...) —— 分别为 Actor 和 Critic 设置独立优化器,实践中常使用不同学习率(Critic 更新更快)。

此实现展示了最简化的同步 Actor-Critic 结构,适用于 CartPole 或 Pendulum 等基准任务。实际应用中需结合经验回放、目标网络等机制提升稳定性。


从REINFORCE到Actor-Critic:一场降方差的进化史

如果说强化学习的发展是一部“对抗噪声”的史诗,那么Actor-Critic就是其中最关键的转折点之一。

⚠️ REINFORCE 的致命弱点

REINFORCE 算法公式如下:

$$
\nabla_\theta J(\theta) = \mathbb{E} \left[ \sum_{t=0}^{T} \nabla_\theta \log \pi_\theta(a_t | s_t) \cdot G_t \right]
$$

其中 $ G_t = \sum_{k=t}^{T} \gamma^{k-t} r_k $ 是从时刻 $ t $ 开始的累积折扣回报。

听起来很完美,对吧?但它有三个致命缺陷:

  1. 高方差 :$ G_t $ 是随机变量之和,波动极大;
  2. 延迟更新 :必须等 episode 结束才能计算;
  3. 样本浪费 :每个 transition 只用一次。

这些问题使得训练过程极其不稳定。哪怕策略已经接近最优,偶尔的失败轨迹仍可能引发剧烈震荡。

🛠️ 解法一:引入基线(Baseline)

聪明的研究者想到:既然我们要比较“哪个动作更好”,为什么不减去一个“平均表现”呢?

于是提出带基线的梯度公式:

$$
\nabla_\theta J(\theta) = \mathbb{E} \left[ \sum_{t} \nabla_\theta \log \pi_\theta(a_t | s_t) \cdot (G_t - b(s_t)) \right]
$$

只要 $ b(s) $ 不依赖动作 $ a $,数学期望不变,但方差显著下降!

最优基线形式为 $ b^*(s) = \frac{\mathbb{E}[Q^2]}{\mathbb{E}[Q]} $,但现实中难以获取。于是人们想到:何不让一个神经网络去学这个 $ b(s) $?

这个 $ b(s) $,正是 Critic 的本质

🔄 自举(Bootstrapping)的艺术与陷阱

Critic 使用 TD 误差作为优势估计:

$$
A_t^{\text{TD}} = r_t + \gamma V_\phi(s_{t+1}) - V_\phi(s_t) = \delta_t
$$

相比完整的 $ G_t $,这是一个局部信号,响应快、方差低,还能实现实时更新!

但是!bootstrapping 带来了新的问题: 偏差

如果 $ V_\phi $ 初始不准,$ \delta_t $ 就会误导更新。例如,在稀疏奖励任务中,若某个状态偶然触发正奖励,Critic可能错误泛化,认为所有通向该状态的动作都很棒,从而引导Actor走上歧途。

这就是所谓的“ 幻想价值扩散 ”现象。

为了缓解这个问题,现代算法普遍采用以下策略:

  • n-step TD :折中单步与蒙特卡洛;
  • λ-return :加权无限多步估计,灵活调节偏差-方差;
  • 目标网络 :冻结部分参数,减缓目标漂移;
  • 双重Critic :防止过高估计。
graph TD
    A[Environment Interaction] --> B{State s_t}
    B --> C[Actor: Select Action a_t ~ π_θ(s_t)]
    C --> D[Apply a_t to Environment]
    D --> E[Observe Reward r_t and Next State s_{t+1}]
    E --> F[Critic: Compute Value V_φ(s_t), V_φ(s_{t+1})]
    F --> G[Calculate TD Error δ_t = r_t + γV_φ(s_{t+1}) - V_φ(s_t)]
    G --> H[Update Critic: Minimize δ_t² via Backprop]
    G --> I[Compute Advantage A_t ≈ δ_t (or λ-return)]
    I --> J[Update Actor: ∇_θ logπ_θ(a_t|s_t) · A_t]
    J --> K[Parameters Updated: θ ← θ + α∇_θ, φ ← φ - β∇_φ L_critic]
    K --> A

该流程图清晰描绘了信息流动路径:从环境交互开始,Actor 决策动作,Critic 评估结果,TD 误差同时驱动两个网络更新,形成闭环反馈机制。

此外,为了提高学习稳定性,常采用 广义优势估计(Generalized Advantage Estimation, GAE)

$$
\hat{A} t^{\text{GAE}} = \sum {l=0}^{T-t-1} (\gamma \lambda)^l \delta_{t+l}
$$

其中 $ \lambda \in [0,1] $ 控制偏差-方差权衡,$ \lambda=0 $ 对应单步 TD,$ \lambda=1 $ 接近蒙特卡洛估计。GAE 已成为现代 Actor-Critic 方法(如 PPO)的标准组件。


随机 vs 确定性策略:你选哪一种?

在强化学习中,策略可分为两大类: 随机策略 (Stochastic Policy)与 确定性策略 (Deterministic Policy)。两者各有千秋,选择取决于任务特性。

特性 随机策略 确定性策略
输出形式 概率分布 $ \pi_\theta(a|s) $ 动作值 $ a = \mu_\theta(s) $
探索方式 内生(通过分布方差) 外源(需加噪声)
训练稳定性 较高(平滑梯度) 易震荡(对噪声敏感)
典型应用 PPO, A2C DDPG, TD3
实现复杂度 中等(需重参数化) 简单(直接前向传播)

🎲 随机策略:天生具备探索能力

随机策略定义为:

$$
\pi_\theta(a|s) = P(a|s; \theta)
$$

在连续控制任务中,常用高斯分布建模:

$$
a \sim \mathcal{N}(\mu_\theta(s), \sigma_\theta^2(s))
$$

均值 $ \mu $ 和标准差 $ \sigma $ 由神经网络输出。这种参数化方式允许策略通过调整分布参数来优化期望回报。

更重要的是,它 天然具备探索能力 ——同一状态下可以采样出不同动作,无需额外机制。

graph TD
    A[当前状态 s] --> B{策略类型}
    B -->|随机策略| C[神经网络输出 μ, σ]
    C --> D[采样 a ~ N(μ, σ²)]
    D --> E[执行动作 a]

    B -->|确定性策略| F[神经网络输出 a = μ(s)]
    F --> G[添加噪声 ε (如 OU)]
    G --> H[执行动作 a + ε]

🔁 重参数化技巧:让采样变得可导

但有一个问题:采样操作不可导,梯度无法回传。

解决办法是 重参数化技巧 (Reparameterization Trick):

$$
a = \mu_\theta(s) + \sigma_\theta(s) \cdot \varepsilon, \quad \varepsilon \sim \mathcal{N}(0, I)
$$

这样,动作 $ a $ 成为确定性函数关于 $ \theta $ 的输出,梯度可以顺利反向传播。

class GaussianActor(nn.Module):
    def __init__(self, state_dim, action_dim, hidden_size=256):
        super(GaussianActor, self).__init__()
        self.fc1 = nn.Linear(state_dim, hidden_size)
        self.fc2 = nn.Linear(hidden_size, hidden_size)
        self.mu_head = nn.Linear(hidden_size, action_dim)
        self.log_std_head = nn.Linear(hidden_size, action_dim)

        self.LOG_STD_MIN = -20
        self.LOG_STD_MAX = 2

    def forward(self, state):
        x = torch.relu(self.fc1(state))
        x = torch.relu(self.fc2(x))
        mu = self.mu_head(x)
        log_std = self.log_std_head(x)
        log_std = torch.clamp(log_std, self.LOG_STD_MIN, self.LOG_STD_MAX)
        std = torch.exp(log_std)

        normal = dist.Normal(mu, std)
        z = normal.rsample()  # 支持梯度传播

        action = torch.tanh(z)
        log_prob = normal.log_prob(z) - torch.log(1 - action.pow(2) + 1e-6)
        log_prob = log_prob.sum(dim=-1, keepdim=True)

        return action, log_prob, mu, std

注意最后的概率修正项 $ -\log(1-a^2+\epsilon) $,这是由于 tanh 变换导致的概率密度变化,忽略会导致严重偏差。


Critic网络的深层挑战:不只是拟合那么简单

你以为Critic只是个回归器?错!它是一个动态、非平稳、自我参照的复杂系统。

🌀 自举带来的四大难题

  1. 引导性偏差 (Bootstrapping Bias):错误估计会通过TD目标传播放大;
  2. 目标漂移 (Target Drift):参数频繁更新导致目标剧烈波动;
  3. 过高估计 (Overestimation Bias):max操作倾向于选择噪声大的Q值;
  4. 分布迁移 (Distribution Shift):Actor更新后数据分布改变。

为此,现代算法引入一系列保障机制:

✅ 目标网络(Target Network)

冻结旧版本参数用于生成目标值:

def soft_update(target_net, source_net, tau=0.005):
    for target_param, param in zip(target_net.parameters(), source_net.parameters()):
        target_param.data.copy_(tau * param.data + (1 - tau) * target_param.data)
✅ 双重Critic(Double Q-learning)

分离动作选择与价值评估:

q_next_1, q_next_2 = critic1_target(next_states, noisy_actions), critic2_target(next_states, noisy_actions)
target_q = rewards + gamma * torch.min(q_next_1, q_next_2)
✅ 批量归一化 + 残差连接

提升深层网络训练稳定性:

class ResidualBlock(nn.Module):
    def __init__(self, dim):
        super().__init__()
        self.linear = nn.Linear(dim, dim)
        self.norm = nn.LayerNorm(dim)
        self.act = nn.ReLU()

    def forward(self, x):
        return x + self.norm(self.act(self.linear(x)))

协同学习的终极挑战:它们真的能好好合作吗?

Actor 和 Critic 表面上是合作伙伴,实则暗藏竞争。

⚖️ 速度匹配问题

  • Critic 快 → 提供准确反馈 → Actor 学得好
  • Critic 慢 → 滞后于策略 → 引导失效

解决方案: 两时间尺度分离

组件 学习率 相对速度
Critic $1e^{-3}$ 快(内环)
Actor $1e^{-4}$ 慢(外环)

或者设定更新频率比,如每训5次Critic才更新1次Actor。

🧩 失配场景与应对策略

问题 现象 解法
过度乐观 Critic高估 → Actor追逐幻象 Double Q, Clipped DDQN
更新过大 策略跳跃 → Critic失效 KL约束, PPO裁剪
峰值敏感 微小扰动 → 动作剧变 目标平滑, 加噪声
flowchart TB
    S[Start: Collect Trajectory] --> C{Update Critic?}
    C -->|Yes| CT[Train Critic with Target Networks]
    CT --> AT{Should Update Actor?}
    AT -->|Yes| AU[Compute Advantage & Update Actor]
    AU --> END((Next Iteration))
    AT -->|No| WAIT[Wait for Delay Steps]
    WAIT --> END
    CT --> CHECK[Check for Overestimation?]
    CHECK -->|Yes| DDQ[Double Q-Learning Correction]
    DDQ --> AU

写在最后:我们正在建造什么样的智能?

Actor-Critic 不只是一个算法架构,它是一种思维方式: 评价先于行动,反思驱动进步

就像人类不会靠试错学会骑车,也不会盲目相信每一次直觉判断,真正的智能体必须懂得:

  • 如何建立稳定的自我认知(Critic)
  • 如何在反馈中迭代行为模式(Actor)
  • 如何在探索与利用之间找到平衡
  • 如何在噪声中识别真正有用的信号

而这一切,都建立在一个看似简单却无比深刻的洞见之上:

🌟 最好的老师,是你自己。

当你看到那个小小的智能体在屏幕上反复跌倒又爬起,终于学会行走时,请记得——它不是靠蛮力取胜,而是学会了“停下来想一想”。

而这,或许才是人工智能最迷人的地方。🚀

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:在强化学习领域,ADP(近似动态规划)结合Actor-Critic架构为复杂决策问题提供了高效解决方案。本项目围绕“ADP冲冲冲”展开,深入实现ADP神经网络模型中的Actor策略网络与Critic评估网络协同机制,涵盖Criticactor融合思想、值函数逼近、策略优化等核心技术。压缩包包含可扩展代码框架,需用户自行配置输入数据与奖励信号,适用于游戏AI、机器人控制和资源调度等场景,是深入理解强化学习算法设计与工程落地的重要实践平台。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐