Actor-Critic网络实战指南:参数更新与损失函数的原理与实现

1次阅读
没有评论

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

image.webp

为什么需要 Actor-Critic?

强化学习中有两种主要方法:基于价值的方法(如 Q -Learning)和基于策略的方法(如 Policy Gradient)。前者在离散动作空间表现良好但难以处理连续动作,后者虽然通用但训练方差大。Actor-Critic 结合二者优势:

Actor-Critic 网络实战指南:参数更新与损失函数的原理与实现

  • Actor(策略网络)负责生成动作,解决 ” 做什么 ” 的问题
  • Critic(价值网络)评估动作好坏,提供 ” 做得怎么样 ” 的反馈

这种分工合作方式大幅提升了训练稳定性,使其成为当今最流行的强化学习架构之一,从游戏 AI 到机器人控制都有广泛应用。

核心参数更新机制

1. 策略梯度(Actor 更新)

Actor 的参数更新遵循策略梯度定理:

# 策略梯度计算公式
def compute_actor_loss(states, actions, advantages):
    # 获取当前策略下动作的概率对数
    log_probs = actor_network(states).log_prob(actions)
    # 带优势函数的策略梯度
    return -(log_probs * advantages).mean()

关键点:

  • 使用 优势函数(Advantage)代替简单回报,减少方差
  • 梯度更新方向是 提高优势动作的概率
  • 实践中常加入熵正则项防止策略过早收敛

2. 价值函数(Critic 更新)

Critic 通过最小化 TD 误差(Temporal Difference Error)来学习:

def compute_critic_loss(states, returns):
    # 预测状态价值
    predicted_values = critic_network(states)
    # 均方误差损失
    return F.mse_loss(predicted_values, returns)

注意事项:

  • 可采用 n -step TD 或 GAE(Generalized Advantage Estimation)
  • 价值函数更新通常比策略更新更快(学习率更大)

主流变体对比

算法 关键改进 适用场景
A2C 同步多环境采样 单机训练
A3C 异步多进程更新 分布式系统
PPO 带裁剪的策略更新 高维连续控制
SAC 最大熵强化学习 需要高探索性的任务

完整 PyTorch 实现

网络结构定义

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.distributions import Categorical

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 = F.relu(self.fc1(state))
        return F.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 = F.relu(self.fc1(state))
        return self.fc2(x)

训练循环核心

# 初始化
actor = Actor(state_dim, action_dim)
critic = Critic(state_dim)
actor_optim = optim.Adam(actor.parameters(), lr=1e-3)
critic_optim = optim.Adam(critic.parameters(), lr=3e-3)

for episode in range(1000):
    state = env.reset()
    done = False

    while not done:
        # 采样动作
        prob = actor(torch.FloatTensor(state))
        m = Categorical(prob)
        action = m.sample()

        # 环境交互
        next_state, reward, done, _ = env.step(action.item())

        # 计算优势
        value = critic(torch.FloatTensor(state))
        next_value = critic(torch.FloatTensor(next_state))
        advantage = reward + (1-done)*gamma*next_value - value

        # 更新 Critic
        critic_loss = F.mse_loss(value, reward + (1-done)*gamma*next_value)
        critic_optim.zero_grad()
        critic_loss.backward()
        critic_optim.step()

        # 更新 Actor
        actor_loss = -m.log_prob(action) * advantage.detach()
        actor_optim.zero_grad()
        actor_loss.backward()
        actor_optim.step()

        state = next_state

调优实战技巧

学习率设置

  • 典型比例:Critic 学习率是 Actor 的 3 -10 倍
  • 使用学习率衰减:
    scheduler = optim.lr_scheduler.StepLR(actor_optim, step_size=100, gamma=0.9)

折扣因子 γ

  • 取值范围通常为 0.9-0.99
  • 长期任务取较高值(0.99)
  • 即时奖励重要的任务取较低值(0.9)

经验回放技巧

from collections import deque
import random

class ReplayBuffer:
    def __init__(self, capacity):
        self.buffer = deque(maxlen=capacity)

    def push(self, state, action, reward, next_state, done):
        self.buffer.append((state, action, reward, next_state, done))

    def sample(self, batch_size):
        return random.sample(self.buffer, batch_size)

常见问题解决

梯度异常

  • 梯度爆炸:添加梯度裁剪
    nn.utils.clip_grad_norm_(actor.parameters(), 0.5)
  • 梯度消失:使用 ReLU 激活函数 + 合适的初始化

探索不足

  • 添加策略熵正则项:
    entropy = -torch.sum(prob * torch.log(prob))
    actor_loss -= 0.01 * entropy  # 系数可调

训练波动

  • 使用目标网络(Target Network)
  • 增大批次大小(Batch Size)
  • 尝试 PPO 的 Clipped Surrogate Objective

拓展思考

如何适应连续动作空间?关键修改:

  1. Actor 输出高斯分布的均值和方差
  2. 使用重参数化技巧(Reparameterization Trick)采样
  3. 调整 Critic 输出维度

推荐延伸阅读:
–《Proximal Policy Optimization Algorithms》(PPO 原论文)
– OpenAI Spinning Up 教程
– Stable Baselines3 开源实现

通过本文的实践指导,你应该已经掌握了 Actor-Critic 的核心实现要点。建议从 CartPole 等简单环境开始实验,逐步挑战更复杂任务。记住调参过程需要耐心,好的强化学习模型往往需要数百次的迭代优化。

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