首页 / 资讯中心 / 文章详情

Actor-Critic算法原理与实战:从基础到进阶优化

Actor-Critic算法原理与实战:从基础到进阶优化 ★ FEATURED ARTICLE
1. Actor-Critic算法概述Actor-Critic算法是强化学习领域中最具代表性的算法架构之一它巧妙地将策略梯度Policy Gradient和价值函数Value Function两种方法结合起来。我第一次接触这个算法是在解决一个工业机器人控制问题时——传统方法要么收敛速度慢要么稳定性差直到尝试了Actor-Critic架构才真正突破了性能瓶颈。这个算法的核心思想就像导演Critic指导演员Actor拍戏Actor负责根据当前状态做出动作决策Critic则实时评估这些动作的价值并提供改进建议。这种分工协作的模式使得算法既能像策略梯度方法那样直接优化策略又能利用价值函数的低方差特性来加速学习过程。在实际项目中我发现这种架构特别适合处理连续动作空间和高维状态空间的问题比如自动驾驶的转向控制或者机械臂的轨迹规划。2. 算法核心原理拆解2.1 双网络架构设计Actor-Critic的核心在于其独特的双网络结构Actor网络输入状态s输出动作概率分布π(a|s)Critic网络输入状态s或状态-动作对(s,a)输出价值估计V(s)或Q(s,a)我在TensorFlow中实现的典型网络结构如下# Actor网络示例 class Actor(tf.keras.Model): def __init__(self, action_dim): super().__init__() self.dense1 layers.Dense(64, activationrelu) self.dense2 layers.Dense(64, activationrelu) self.output_layer layers.Dense(action_dim, activationsoftmax) def call(self, state): x self.dense1(state) x self.dense2(x) return self.output_layer(x) # Critic网络示例 class Critic(tf.keras.Model): def __init__(self): super().__init__() self.dense1 layers.Dense(64, activationrelu) self.dense2 layers.Dense(64, activationrelu) self.output_layer layers.Dense(1) def call(self, state): x self.dense1(state) x self.dense2(x) return self.output_layer(x)关键经验Actor的最后一层激活函数选择取决于动作空间类型——离散动作用softmax连续动作用tanh或sigmoid。Critic的输出层不要加激活函数因为价值估计的范围不受限。2.2 优势函数计算算法性能的关键在于优势函数A(s,a)的计算它表示当前动作相对于平均水平的优势。最常用的计算方法是A(s,a) Q(s,a) - V(s) ≈ r γV(s) - V(s)其中γ是折扣因子。在实际编码时我通常会使用广义优势估计(GAE)来平衡偏差和方差def compute_gae(rewards, values, gamma0.99, lam0.95): deltas rewards[:-1] gamma * values[1:] - values[:-1] gae np.zeros_like(deltas) running_add 0 for t in reversed(range(len(deltas))): running_add deltas[t] gamma * lam * running_add gae[t] running_add return gae3. 经典算法实现与优化3.1 A2C算法实现Advantage Actor-Critic (A2C)是最基础的同步版本实现。以下是核心训练循环的关键步骤数据收集运行当前策略πθ与环境交互N步优势计算使用Critic网络计算每个状态的价值估计策略更新计算策略梯度 ∇θ logπθ(a|s)A(s,a)价值更新最小化Critic的TD误差 (rγV(s)-V(s))²# 伪代码示例 for episode in range(EPISODES): states, actions, rewards run_episode(env, actor) values critic(states) advantages compute_gae(rewards, values) # 更新Actor with tf.GradientTape() as tape: probs actor(states) selected_probs tf.gather(probs, actions, batch_dims1) actor_loss -tf.reduce_mean(tf.math.log(selected_probs) * advantages) actor_grads tape.gradient(actor_loss, actor.trainable_variables) actor_optimizer.apply_gradients(zip(actor_grads, actor.trainable_variables)) # 更新Critic with tf.GradientTape() as tape: current_values critic(states) critic_loss tf.reduce_mean((rewards GAMMA * critic(states_next) - current_values)**2) critic_grads tape.gradient(critic_loss, critic.trainable_variables) critic_optimizer.apply_gradients(zip(critic_grads, critic.trainable_variables))3.2 A3C算法优化Asynchronous Advantage Actor-Critic (A3C)通过多个worker并行收集经验来提升效率。我在实际部署中发现这些优化点特别重要网络同步策略全局网络每K步同步到各个worker熵正则化在策略损失中加入熵项避免过早收敛entropy tf.reduce_sum(probs * tf.math.log(probs), axis1) actor_loss -tf.reduce_mean(log_probs * advantages) - 0.01 * entropy梯度裁剪防止梯度爆炸grads, _ tf.clip_by_global_norm(grads, 0.5)4. 实战技巧与调参经验4.1 超参数设置黄金法则经过数十个项目的调参实践我总结出这些经验值参数推荐值作用说明学习率(Actor)3e-4 ~ 1e-3策略更新步长学习率(Critic)1e-3 ~ 3e-3价值函数收敛速度折扣因子γ0.9 ~ 0.99未来奖励的重要性GAE参数λ0.9 ~ 0.95优势估计的偏差-方差权衡批量大小64 ~ 512每次更新的样本数熵系数0.01 ~ 0.1策略探索强度血泪教训Critic的学习率通常应该比Actor大2-3倍因为价值函数通常比策略更容易学习。我曾在一个机械臂控制项目中发现当Critic学习不足时Actor会基于错误的价值估计做出决策导致完全无法收敛。4.2 网络架构设计技巧共享底层特征对于视觉输入等复杂状态可以让Actor和Critic共享前面的卷积层class SharedNetwork(tf.keras.Model): def __init__(self): super().__init__() self.conv1 layers.Conv2D(32, 3, activationrelu) self.flatten layers.Flatten() self.common_fc layers.Dense(256, activationrelu) def call(self, inputs): x self.conv1(inputs) x self.flatten(x) return self.common_fc(x)输出层初始化Actor的最后一层bias初始化为0.5sigmoid或0tanhCritic最后一层初始化为0归一化技巧对优势函数进行批量归一化可以显著提升稳定性advantages (advantages - advantages.mean()) / (advantages.std() 1e-8)5. 常见问题与解决方案5.1 训练不稳定问题症状回报曲线剧烈波动或突然崩溃检查清单确认Critic的损失是否在持续下降检查优势值是否出现NaN通常意味着梯度爆炸观察策略熵值是否过早趋近于0解决方案降低Actor学习率增加熵系数使用梯度裁剪特别是对于RNN版本改用PPO等带约束的算法变种5.2 探索不足问题典型案例智能体卡在局部最优策略诊断方法# 计算策略熵 probs actor(states) entropy -tf.reduce_sum(probs * tf.math.log(probs), axis1).numpy().mean() print(fAverage policy entropy: {entropy:.3f})健康值通常在动作空间大小的1/2左右如5个动作则熵≈1.5改进措施动态调整熵系数开始时较大随着训练逐渐减小使用噪声探索在动作输出中加入OU噪声采用课程学习从简化环境开始逐步增加难度6. 进阶变种与扩展应用6.1 分布式Actor-Critic现代实现通常采用IMPALA架构其核心改进包括使用V-trace修正off-policy偏差分离推理worker和训练worker优先经验回放(PER)机制# V-trace计算示例 def vtrace(target_values, behaviour_values, rewards, discounts, rho1.0): v_target np.zeros_like(target_values) delta rewards discounts * target_values[1:] - target_values[:-1] v_target[-1] target_values[-1] for t in reversed(range(len(delta))): v_target[t] target_values[t] delta[t] * min(rho, 1.0) return v_target6.2 混合动作空间处理对于同时包含离散和连续动作的场景如RTS游戏可以采用分层架构顶层Actor选择离散动作类型子Actor处理对应类型的连续参数Critic评估整体决策价值class HybridActor(tf.keras.Model): def __init__(self, discrete_dim, continuous_dims): super().__init__() self.common layers.Dense(64, activationrelu) self.discrete_head layers.Dense(discrete_dim, activationsoftmax) self.continuous_heads [layers.Dense(dim, activationtanh) for dim in continuous_dims] def call(self, state): x self.common(state) discrete_probs self.discrete_head(x) continuous_actions [head(x) for head in self.continuous_heads] return discrete_probs, continuous_actions在实际机器人控制项目中这种架构成功地将离散操作如抓手开合和连续控制如关节角度统一到了一个策略网络中。
阅读完成 · 觉得有帮助?
咨询建站