在这里插入图片描述

😊你好,我是小航,一个正在变秃、变强的文艺倾年。
🔔本文讲解【强化学习】Actor-Critic 演员、评论家,20W字总结(五),期待与你一同探索、学习、进步,一起卷起来叭!

🎯 把我的博客装进你的 Claude Code,它就是你的 AI 学习搭子

想随时搜我的文章、让 AI 帮你深度讲解甚至出面试题?复制下面这段提示词丢进你的 Claude Code——它会自动生成一个本地 SKILL,之后你直接说「搜一下强化学习的文章」就行。RSS 自动同步最新内容,不用手动存任何文件。

请为这个 CSDN 博客创建一个本地 SKILL(存到 .claude/skills/csdn-blog/SKILL.md):
RSS 源:https://rss.csdn.net/m0_51517236/rss/map
支持三件事:① 列出最新文章(标题+链接+摘要);② 按关键词搜索;
③ 抓取指定文章全文,作为 AI 学习助手 / 面试官深度讲解并出题考核我。
SKILL.md 里写清楚 RSS URL、调用方式和示例。生成完就能用自然语言搜文章了。

一键订阅,长期可用。🚀


上一篇我们用 REINFORCE + 基线把策略梯度的方差压了下来,训练曲线平滑多了。但留了个硬伤:它俩都是蒙特卡洛方法——必须等一整局跑完,才能回头算回报、更新策略

杆子都倒了,你才告诉它"刚才那步走错了",反馈滞后得离谱。

这篇就来治这个病。主角叫 Actor-Critic(演员-评论家),它让智能体走一步、学一步,不用再苦等一整局。

在这里插入图片描述

蒙特卡洛的硬伤:得等一整局

先复习一下带基线 REINFORCE 的梯度公式:

∇ θ J ( θ ) = E [ ∑ t ( G t − V ( S t ) ) ⋅ ∇ θ log ⁡ π θ ( A t ∣ S t ) ] \nabla_{\theta}J(\theta) = \mathbb{E}\left[\sum_t (G_t - V(S_t)) \cdot \nabla_{\theta}\log\pi_\theta(A_t|S_t)\right] θJ(θ)=E[t(GtV(St))θlogπθ(AtSt)]

权重是 G t − V ( S t ) G_t - V(S_t) GtV(St)。问题出在 G t G_t Gt 上——它是"从时刻 t t t 到回合结束"的所有奖励之和。换句话说,不跑到回合结束,你根本不知道 G t G_t Gt 是多少

这就是蒙特卡洛方法的通病:要凑齐一整条轨迹才能学习。样本效率低,反馈又慢。

TD 方法:走一步就能学

破解的法子叫时序差分(Temporal Difference,TD)。思路很巧:与其等一整局算 G t G_t Gt,不如用"下一步的价值"来估计

回顾一下价值函数的贝尔曼方程:

V ( S t ) ≈ R t + γ V ( S t + 1 ) V(S_t) \approx R_t + \gamma V(S_{t+1}) V(St)Rt+γV(St+1)

当前状态的价值 ≈ 这一步的奖励 + 打折后的"下一个状态的价值"。那 G t G_t Gt(真实的未来回报)就可以用这个估计顶上去——把 G t G_t Gt 换成 R t + γ V ( S t + 1 ) R_t + \gamma V(S_{t+1}) Rt+γV(St+1)

直观理解:评估一家公司对你的价值,不能只看这个月发的工资(即时奖励 R t R_t Rt),还得看以后公司对你的价值( γ V ( S t + 1 ) \gamma V(S_{t+1}) γV(St+1))打个折扣。眼下的钱更重要,但未来的前景也重要,只是没那么重要。

这个 R t + γ V ( S t + 1 ) R_t + \gamma V(S_{t+1}) Rt+γV(St+1)TD 目标。它和当前估计 V ( S t ) V(S_t) V(St) 的差,就是 TD 误差

δ = R t + γ V ( S t + 1 ) − V ( S t ) \delta = R_t + \gamma V(S_{t+1}) - V(S_t) δ=Rt+γV(St+1)V(St)

关键来了:算 TD 目标只需要走一步——拿到 R t R_t Rt 和下一个状态 S t + 1 S_{t+1} St+1 就够了,不用等回合结束。反馈从"等一整局"压缩到"等一步"。

在这里插入图片描述

Actor-Critic:演员 + 评论家

把 TD 误差塞进策略梯度,就得到了 Actor-Critic:

∇ θ J ( θ ) = E [ ∑ t ( R t + γ V ω ( S t + 1 ) − V ω ( S t ) ) ⏟ TD 误差  δ ⋅ ∇ θ log ⁡ π θ ( A t ∣ S t ) ] \nabla_{\theta}J(\theta) = \mathbb{E}\left[\sum_t \underbrace{(R_t + \gamma V_\omega(S_{t+1}) - V_\omega(S_t))}_{\text{TD 误差 } \delta} \cdot \nabla_{\theta}\log\pi_\theta(A_t|S_t)\right] θJ(θ)=E tTD 误差 δ (Rt+γVω(St+1)Vω(St))θlogπθ(AtSt)

这里有两个神经网络同台演出:

  • Actor(演员, π θ \pi_\theta πθ:负责选动作——输入状态,输出动作概率。就是前面的策略网络。
  • Critic(评论家, V ω V_\omega Vω:负责打分——输入状态,输出"这个状态值多少分"。就是价值网络。

演员负责演,评论家负责评。演员演完一个动作,评论家立刻给出 TD 误差当反馈:这个动作比预期好( δ > 0 \delta > 0 δ>0),增强;比预期差( δ < 0 \delta < 0 δ<0),压制。两个网络边演边学,一起更新。

这里用的是 1 步 TD 误差来估计优势。也可以用 n n n 步 TD(多看几步再评),那叫广义优势估计(GAE),放在番外篇的数学推导里讲。

代码实现

两个网络结构几乎一样,区别在输出层:

class PolicyNet(nn.Module):
    def __init__(self, action_size):
        super().__init__()
        self.l1 = nn.Linear(4, 128)
        self.l2 = nn.Linear(128, action_size)

    def forward(self, x):
        x = F.relu(self.l1(x))
        return F.softmax(self.l2(x), dim=1)   # 输出动作概率

class ValueNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.l1 = nn.Linear(4, 128)
        self.l2 = nn.Linear(128, 1)

    def forward(self, x):
        x = F.relu(self.l1(x))
        return self.l2(x)                      # 输出状态价值(标量,不激活)

💡 代码解析:PolicyNet 输出走 Softmax(概率),ValueNet 输出不过激活(价值可正可负)。结构对称,像一对双胞胎。

Agent 同时管着这俩网络,update 是核心——每走一步就调用一次:

class Agent:
    def __init__(self):
        self.gamma = 0.98
        self.lr_pi = 0.0002
        self.lr_v = 0.0005
        self.pi = PolicyNet(action_size=2)
        self.v = ValueNet()
        self.optimizer_pi = optim.Adam(self.pi.parameters(), lr=self.lr_pi)
        self.optimizer_v = optim.Adam(self.v.parameters(), lr=self.lr_v)

    def get_action(self, state):
        state = torch.tensor(state[np.newaxis, :])
        probs = self.pi(state)[0]
        m = Categorical(probs)
        action = m.sample().item()
        return action, probs[action]

    def update(self, state, action_prob, reward, next_state, done):
        state = torch.tensor(state[np.newaxis, :])
        next_state = torch.tensor(next_state[np.newaxis, :])

        # ① 训练 Critic:让 V(S_t) 逼近 TD 目标
        target = reward + self.gamma * self.v(next_state) * (1 - done)
        v = self.v(state)
        loss_v = nn.MSELoss()(v, target)

        # ② 训练 Actor:用 TD 误差当权重更新策略
        delta = target - v              # TD 误差
        loss_pi = -torch.log(action_prob) * delta.item()

        self.optimizer_v.zero_grad()
        self.optimizer_pi.zero_grad()
        loss_v.backward()
        loss_pi.backward()
        self.optimizer_v.step()
        self.optimizer_pi.step()

💡 代码解析:update 干两件事——① 算 TD 目标 target,用 MSE 把 Critic 的 V ( S t ) V(S_t) V(St) 往它上拉;② 算 TD 误差 delta,当权重更新 Actor。注意 done 那一项:回合结束时 ( 1 − d o n e ) = 0 (1 - done) = 0 (1done)=0,TD 目标就只剩即时奖励 R t R_t Rt,不再幻想"还有下一步"。

和前几篇最大的区别在训练循环——update 在每一步都调用,不用等回合结束

for episode in range(2000):
    state = env.reset()
    done = False
    total_reward = 0

    while not done:
        action, prob = agent.get_action(state)
        next_state, reward, done, _ = env.step(action)
        agent.update(state, prob, reward, next_state, done)   # 每走一步就学
        state = next_state
        total_reward += reward

    reward_history.append(total_reward)

🚩 运行结果:每步都在学,收敛比 REINFORCE 快不少。

在这里插入图片描述

小结:策略梯度法家族集齐

到这里,第 2 章的四种策略梯度法就集齐了。它们其实共享一个统一的数学骨架,区别只在权重 Φ t \Phi_t Φt

∇ θ J ( θ ) = E [ ∑ t Φ t ⋅ ∇ θ log ⁡ π θ ( A t ∣ S t ) ] \nabla_\theta J(\theta) = \mathbb{E}\left[\sum_t \Phi_t \cdot \nabla_\theta\log\pi_\theta(A_t|S_t)\right] θJ(θ)=E[tΦtθlogπθ(AtSt)]

算法 权重 Φ t \Phi_t Φt
原始策略梯度 G ( τ ) G(\tau) G(τ)(整条轨迹回报)
REINFORCE G t G_t Gt(只看动作之后的)
带基线 REINFORCE G t − V ( S t ) G_t - V(S_t) GtV(St)(减去预期)
Actor-Critic R t + γ V ( S t + 1 ) − V ( S t ) R_t + \gamma V(S_{t+1}) - V(S_t) Rt+γV(St+1)V(St)(TD 误差)

从上到下:噪声越来越少、方差越来越小、反馈越来越即时。Actor-Critic 已经能"走一步学一步",听起来很完美。

但别高兴太早——它还有个新毛病:步子太大容易训崩。一次更新走太远,策略直接翻车。下一篇的 PPO 就来给更新"装刹车",让训练既快又稳。它是 RLHF 的核心组件,也是 ChatGPT 背后的关键算法之一。


📌 [ 笔者 ] 文艺倾年
📃 [ 更新 ] 2026.06.14
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,
本人也很想知道这些错误,恳望读者批评指正!

在这里插入图片描述

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐