告别DQN的离散动作限制:用PyTorch从零实现DDPG算法玩转Pendulum-v0倒立摆 告别DQN的离散动作限制用PyTorch从零实现DDPG算法玩转Pendulum-v0倒立摆当智能体需要在连续动作空间中做出决策时传统的DQN算法就显得力不从心。想象一下你正在训练一个机械臂抓取物体——动作空间不再是简单的左/右离散选择而是需要精确控制每个关节的角度和力度。这正是深度确定性策略梯度DDPG算法大显身手的场景。1. 连续控制的核心挑战与DDPG解决方案在机器人控制和自动驾驶等领域连续动作空间的建模至关重要。与DQN只能处理离散动作不同DDPG通过独特的行动者-评论家架构直接输出连续的动作值。关键对比特性DQNDDPG动作空间离散连续策略类型隐式通过Q值选择显式直接输出动作网络结构单一Q网络Actor-Critic双网络探索方式ε-greedy动作噪声注入DDPG的创新之处在于将确定性策略梯度DPG与深度Q网络DQN的成功经验相结合。Actor网络直接输出确定性动作而Critic网络则评估该动作的价值两者协同工作class Actor(nn.Module): def __init__(self, state_dim, action_dim, max_action): super().__init__() self.net nn.Sequential( nn.Linear(state_dim, 256), nn.ReLU(), nn.Linear(256, 256), nn.ReLU(), nn.Linear(256, action_dim), nn.Tanh() ) self.max_action max_action def forward(self, state): return self.max_action * self.net(state)2. DDPG四大核心组件实现2.1 经验回放机制强化学习的样本具有强时序相关性直接使用会导致训练不稳定。DDPG借鉴DQN的经验回放Experience Replay技术class ReplayBuffer: def __init__(self, capacity): self.buffer deque(maxlencapacity) def add(self, state, action, reward, next_state, done): self.buffer.append((state, action, reward, next_state, done)) def sample(self, batch_size): transitions random.sample(self.buffer, batch_size) return zip(*transitions)提示经验池大小一般设置为1e51e6batch_size通常取64-2562.2 目标网络与软更新直接使用主网络更新目标会导致训练震荡。DDPG采用软更新soft update策略def soft_update(target, source, tau): for t, s in zip(target.parameters(), source.parameters()): t.data.copy_(t.data * (1.0 - tau) s.data * tau)更新过程分三步Critic通过最小化TD误差更新Actor通过最大化Q值更新目标网络缓慢跟踪主网络2.3 探索策略设计确定性策略本身缺乏探索能力。我们在动作输出上添加噪声def take_action(self, state, noise_scale0.1): action self.actor(state) noise noise_scale * torch.randn_like(action) return torch.clamp(action noise, -self.max_action, self.max_action)2.4 网络结构与超参数配置典型的网络结构和超参数设置网络架构Actor状态→256→256→动作tanh激活Critic状态动作→256→256→Q值无激活超参数范围参数推荐值作用学习率(Actor)1e-41e-3策略更新步长学习率(Critic)1e-31e-2值函数更新步长折扣因子γ0.950.99未来奖励重要性软更新系数τ0.0010.01目标网络更新速度噪声标准差σ0.10.3探索强度3. Pendulum-v0环境实战让我们在经典的倒立摆控制问题上测试DDPG算法。这个环境需要控制力矩使摆杆保持直立env gym.make(Pendulum-v0) state_dim env.observation_space.shape[0] action_dim env.action_space.shape[0] max_action float(env.action_space.high[0]) agent DDPG(state_dim, action_dim, max_action)训练过程中常见的挑战和解决方案训练初期不收敛检查Critic的损失是否在下降适当增大经验回放池初始数据量调整探索噪声大小策略陷入局部最优尝试周期性重置探索噪声结合OU噪声代替高斯噪声增加网络隐藏层维度训练后期波动大动态衰减探索噪声减小学习率检查目标网络更新频率4. 进阶技巧与性能优化要让DDPG在实际应用中表现更好可以考虑以下优化4.1 分层经验回放优先回放重要的transitionclass PrioritizedReplayBuffer: def __init__(self, capacity, alpha0.6): self.alpha alpha self.priorities np.zeros(capacity) self.buffer [] def add(self, *args): max_prio self.priorities.max() if self.buffer else 1.0 self.buffer.append(args) self.priorities[len(self.buffer)-1] max_prio4.2 自适应噪声调整根据策略性能动态调整探索噪声if episode_reward threshold: self.noise_scale * 0.99 else: self.noise_scale min(1.0, self.noise_scale * 1.01)4.3 多步TD目标使用n-step bootstrap提高学习效率def compute_n_step_target(rewards, next_qs, dones, gamma0.99, n_step3): targets torch.zeros_like(rewards) cumulative 0 for i in reversed(range(len(rewards))): cumulative rewards[i] gamma * cumulative * (1 - dones[i]) targets[i] cumulative if i n_step len(rewards): break return targets在实际机器人控制项目中DDPG的表现往往优于传统PID控制器特别是在系统动力学模型未知的情况下。我曾在一个机械臂抓取任务中通过DDPG实现了比人工调参控制器高30%的成功率。