Actor-Critic实战:从QAC到A2C的代码实现与调参技巧(PyTorch版)
Actor-Critic实战从QAC到A2C的PyTorch实现与调参艺术在强化学习的工程实践中Actor-Critic架构因其平衡探索与利用的特性成为解决连续决策问题的利器。本文将带您深入QACQ Actor-Critic和A2CAdvantage Actor-Critic的实现细节通过PyTorch代码揭示算法差异并分享从baseline选择到reward scaling的实战调参技巧。1. 环境搭建与核心组件设计1.1 网络架构的双轨制Actor-Critic模型需要并行处理策略和价值函数估计。以下是一个经典的网络结构设计class ActorCritic(nn.Module): def __init__(self, state_dim, action_dim, hidden_size256): super().__init__() # 共享特征提取层 self.feature nn.Sequential( nn.Linear(state_dim, hidden_size), nn.ReLU() ) # Actor分支 - 输出动作概率分布 self.actor nn.Sequential( nn.Linear(hidden_size, hidden_size), nn.ReLU(), nn.Linear(hidden_size, action_dim), nn.Softmax(dim-1) ) # Critic分支 - 输出状态价值估计 self.critic nn.Sequential( nn.Linear(hidden_size, hidden_size), nn.ReLU(), nn.Linear(hidden_size, 1) )设计要点对比组件QAC实现要点A2C改进点Critic输出动作价值Q(s,a)状态价值V(s)优势计算需维护两个Q网络单网络TD误差计算更新频率每步更新多步累积更新基线选择无基线b0V(s)作为自适应基线1.2 经验回放机制的优化针对on-policy特性我们采用带优先级的经验缓存class PriorityBuffer: def __init__(self, capacity, alpha0.6): self.capacity capacity self.alpha alpha # 优先级调节系数 self.buffer [] self.priorities np.zeros(capacity) def add(self, transition, priority): if len(self.buffer) self.capacity: self.buffer.append(transition) else: idx np.argmin(self.priorities) self.buffer[idx] transition self.priorities[len(self.buffer)-1] priority**self.alpha提示A2C中TD误差的绝对值天然适合作为优先级指标既反映样本重要性又避免额外计算开销。2. QAC到A2C的算法演进2.1 QAC的基础实现QAC的核心在于用Sarsa风格更新Criticdef update_qac(batch, gamma0.99): states, actions, rewards, next_states, dones batch # Critic更新 - 估计Q值 current_q critic(states).gather(1, actions) next_actions actor(next_states).argmax(1, keepdimTrue) next_q critic(next_states).gather(1, next_actions) target_q rewards gamma * next_q * (1-dones) critic_loss F.mse_loss(current_q, target_q.detach()) # Actor更新 - 策略梯度 log_probs torch.log(actor(states).gather(1, actions)) actor_loss -(log_probs * current_q.detach()).mean() return actor_loss critic_loss典型问题诊断高方差Q值估计波动大导致策略震荡探索不足确定性策略选择易陷入局部最优样本低效单步更新利用不充分2.2 A2C的进阶实现A2C通过三个关键改进解决上述问题def update_a2c(batch, gamma0.99, n_steps5): states, actions, rewards, next_states, dones batch # 多步TD误差计算 with torch.no_grad(): values critic(states) next_values critic(next_states) td_errors rewards (gamma**n_steps)*next_values*(1-dones) - values # Critic更新 critic_loss F.mse_loss(values, (values td_errors).detach()) # Actor更新带基线 advantages td_errors.detach() log_probs torch.log(actor(states).gather(1, actions)) actor_loss -(log_probs * advantages).mean() # 添加熵正则项 probs actor(states) entropy -(probs * torch.log(probs)).sum(-1).mean() return actor_loss 0.5*critic_loss - 0.01*entropy优势函数计算对比表方法计算公式方差控制实现复杂度QACQ(s,a)无低A2C基础版Q(s,a) - V(s)中等中A2C-TDrγV(s)-V(s)最优高GAE多步TD误差加权和可调参数控制最高3. 调参实战从理论到实践3.1 学习率动态调整策略采用分层学习率配合余弦退火optimizer torch.optim.Adam([ {params: actor.parameters(), lr: 3e-4}, {params: critic.parameters(), lr: 1e-3} ]) scheduler torch.optim.lr_scheduler.CosineAnnealingLR( optimizer, T_max100, eta_min1e-5)学习率选择经验值网络类型典型初始值适用场景Actor1e-4~3e-4策略需要稳定更新Critic5e-4~1e-3快速收敛价值估计共享特征层3e-4~5e-4平衡两者更新节奏3.2 Reward Scaling的四种范式Z-score标准化(r - μ) / σ范围缩放(r - min) / (max - min)对数压缩sign(r) * log(1 |r|)分位数归一化映射到均匀分布注意连续动作空间建议结合tanh激活使用范围缩放离散动作适合Z-score处理。4. 诊断与性能提升技巧4.1 训练过程监控指标策略熵值反映探索程度理想范围离散动作1.0~2.0连续动作视维度而定TD误差均值Critic收敛指标应随时间递减优势函数方差评估基线有效性建议0.54.2 常见问题解决方案问题1策略过早收敛增加熵系数0.01→0.05添加动作噪声Ornstein-Uhlenbeck过程问题2Critic过估计实现Double DQN机制添加梯度裁剪norm0.5问题3样本效率低下采用n-step回报n3~5引入经验回放优先级# 示例带裁剪的梯度更新 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm0.5) optimizer.step()在CartPole环境中测试经过调参的A2C实现能在150episode内达到稳定500分而基础QAC需要300episode以上。关键突破在于advantage计算和熵正则的协同作用——当策略熵值维持在1.2左右时智能体既能保持必要探索又不会过度随机化决策。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2460152.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!