跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

深度确定性策略梯度算法 (DDPG) 详解与实现

深度确定性策略梯度(DDPG)是一种适用于连续动作空间的强化学习算法。它结合了确定性策略梯度与深度神经网络,采用 Actor-Critic 架构。核心机制包括经验回放池打破数据相关性、目标网络稳定训练以及软更新参数。详细推导了 Q 值函数与策略更新的数学原理,并基于 PyTorch 提供了完整的 Python 实现,涵盖网络定义、智能体逻辑及训练流程,适合用于机器人控制等连续控制任务的学习与参考。

BigDataPan发布于 2026/3/15更新于 2026/10/1588 浏览
深度确定性策略梯度算法 (DDPG) 详解与实现

深度确定性策略梯度算法 (DDPG) 详解

深度确定性策略梯度(Deep Deterministic Policy Gradient,简称 DDPG)是一种基于深度强化学习的算法,专门用于解决连续动作空间的问题,例如机器人控制中的连续运动。它结合了确定性策略和深度神经网络,属于模型无关的强化学习算法,采用 Actor-Critic 框架,同时利用了 DQN 和 PG(Policy Gradient)的优点。

算法特点

  • 适用于连续动作空间: DDPG 直接输出连续值动作,无需对动作进行离散化。
  • 利用确定性策略: 与随机策略不同,DDPG 输出的是每个状态下一个确定的最优动作。
  • 结合目标网络: 使用延迟更新的目标网络,稳定了训练过程,避免了过大的参数波动。
  • 经验回放机制: 通过经验回放缓解数据相关性,提升样本利用率。
  • 高效学习: 使用 Critic 网络评估动作的质量,使得策略优化过程更加高效。

核心改进点

  1. 从 DQN 继承的目标网络: 避免 Q 值的估计震荡问题,提高算法的训练稳定性。
  2. 从 PG 继承的策略梯度优化: 通过 Actor 网络直接优化策略,适应连续动作问题。
  3. 经验回放(Replay Buffer): 将交互环境中的经验(状态、动作、奖励、下一状态)存储起来,训练时从中随机采样,减少数据相关性和样本浪费。
  4. 双网络架构: Actor 网络负责生成动作;Critic 网络评估动作的质量。

算法公式推导

1. Q 值函数更新

DDPG 使用 Bellman 方程更新 Critic 网络的目标 Q 值:

y = r + \gamma Q'(s', \mu'(s'; \theta^{\mu'}); \theta^{Q'})

其中 $s'$ 是下一状态,$\mu'(s')$ 是目标动作,$\gamma$ 是折扣因子,$\mu'$ 是目标 Actor 网络,$Q'$ 是目标 Critic 网络。

Critic 网络的优化目标是最小化以下损失函数:

L(\theta^Q) = \frac{1}{N} \sum_{i} \left( Q(s_i, a_i; \theta^Q) - y_i \right)^2

其中 $y_i$ 是目标值,$\theta^Q$ 是 Critic 网络的参数。

2. 策略更新(Actor 网络)

Actor 网络通过最大化 Critic 网络的 Q 值来优化策略,其目标函数为:

J(\theta^\mu) = \frac{1}{N} \sum_{i} Q(s_i, \mu(s_i; \theta^\mu); \theta^Q)

使用梯度上升法更新 Actor 网络:

\nabla_{\theta^\mu} J \approx \frac{1}{N} \sum_{i} \nabla_a Q(s, a; \theta^Q) \big|{a=\mu(s)} \nabla{\theta^\mu} \mu(s; \theta^\mu)

3. 目标网络更新

目标网络采用软更新方式,缓慢地向当前网络靠近:

![\theta^{Q'} \leftarrow \tau \theta^Q + (1 - \tau) \theta^{Q'}] ![\theta^{\mu'} \leftarrow \tau \theta^\mu + (1 - \tau) \theta^{\mu'}]

其中 $\tau \in (0, 1)$ 是软更新系数。

算法流程

  1. 初始化: 初始化 Actor、Critic 网络和它们对应的目标网络,初始化经验回放池。
  2. 交互环境: 在状态 $s_t$ 下,通过 Actor 网络生成动作 $a_t$,执行动作获取奖励 $r_t$ 和下一状态 $s_{t+1}$。
  3. 存储经验: 将 $(s_t, a_t, r_t, s_{t+1})$ 存储到经验回放池。
  4. 采样训练: 从经验池中随机采样小批量数据 $(s_i, a_i, r_i, s'_i)$。
  5. 更新 Critic 网络: 计算目标 Q 值,最小化 Critic 的损失函数。
  6. 更新 Actor 网络: 使用 Critic 网络的梯度来调整 Actor 网络的参数。
  7. 目标网络更新: 按照软更新公式更新目标网络的参数。
  8. 重复以上步骤, 直到达到学习目标。

Python 实现

下面给出 DDPG 算法的完整 Python 实现。该实现包括 Actor-Critic 架构、缓冲区和目标网络等。代码基于 PyTorch 编写,适合理解算法原理及复现。

1. 导入必要库
import gym
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from collections import deque
import random

这里主要用到 gym 创建环境,numpy 处理数组,torch 构建神经网络,deque 实现经验回放池。

2. 定义 Actor 网络

Actor 网络的作用是生成给定状态下的最优动作。

class Actor(nn.Module):
    def __init__(self, state_dim, action_dim, max_action):
        super(Actor, self).__init__()
        self.layer1 = nn.Linear(state_dim, 256)
        self.layer2 = nn.Linear(256, 256)
        self.layer3 = nn.Linear(256, action_dim)
        self.max_action = max_action

    def forward(self, state):
        x = torch.relu(self.layer1(state))
        x = torch.relu(self.layer2(x))
        x = torch.tanh(self.layer3(x)) * self.max_action
        return x

输入包含状态维度、动作维度和最大动作值。网络结构包含两层隐藏层(256 个神经元),输出层使用 tanh 激活函数将动作限制在 [-1, 1],再乘以 max_action 缩放到实际范围。

3. 定义 Critic 网络

Critic 网络评估给定状态和动作的质量(即 Q 值)。

class Critic(nn.Module):
    def __init__(self, state_dim, action_dim):
        super(Critic, self).__init__()
        self.layer1 = nn.Linear(state_dim + action_dim, 256)
        self.layer2 = nn.Linear(256, 256)
        self.layer3 = nn.Linear(256, 1)

    def forward(self, state, action):
        x = torch.cat([state, action], dim=1)
        x = torch.relu(self.layer1(x))
        x = torch.relu(self.layer2(x))
        x = self.layer3(x)
        return x

状态和动作拼接后作为输入,经过两层隐藏层,输出标量 Q 值。

4. 定义经验回放池

作用:存储智能体与环境交互的经验数据,打破样本间的时间相关性。

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

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

    def sample(self, batch_size):
        batch = random.sample(self.buffer, batch_size)
        states, actions, rewards, next_states, dones = zip(*batch)
        return (np.array(states), np.array(actions), np.array(rewards), 
                np.array(next_states), np.array(dones))

    def size(self):
        return len(self.buffer)
5. 定义 DDPG 智能体
class DDPGAgent:
    def __init__(self, state_dim, action_dim, max_action, gamma=0.99, tau=0.005, buffer_size=100000, batch_size=64):
        self.actor = Actor(state_dim, action_dim, max_action)
        self.actor_target = Actor(state_dim, action_dim, max_action)
        self.actor_target.load_state_dict(self.actor.state_dict())
        self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=1e-4)

        self.critic = Critic(state_dim, action_dim)
        self.critic_target = Critic(state_dim, action_dim)
        self.critic_target.load_state_dict(self.critic.state_dict())
        self.critic_optimizer = optim.Adam(self.critic.parameters(), lr=1e-3)

        self.max_action = max_action
        self.gamma = gamma
        self.tau = tau
        self.replay_buffer = ReplayBuffer(buffer_size)
        self.batch_size = batch_size

    def select_action(self, state):
        state = torch.FloatTensor(state.reshape(1, -1))
        action = self.actor(state).detach().cpu().numpy().flatten()
        return action

    def train(self):
        if self.replay_buffer.size() < self.batch_size:
            return

        states, actions, rewards, next_states, dones = self.replay_buffer.sample(self.batch_size)
        states = torch.FloatTensor(states)
        actions = torch.FloatTensor(actions)
        rewards = torch.FloatTensor(rewards).unsqueeze(1)
        next_states = torch.FloatTensor(next_states)
        dones = torch.FloatTensor(dones).unsqueeze(1)

        with torch.no_grad():
            next_actions = self.actor_target(next_states)
            target_q = self.critic_target(next_states, next_actions)
            target_q = rewards + (1 - dones) * self.gamma * target_q

        current_q = self.critic(states, actions)
        critic_loss = nn.MSELoss()(current_q, target_q)

        self.critic_optimizer.zero_grad()
        critic_loss.backward()
        self.critic_optimizer.step()

        actor_loss = -self.critic(states, self.actor(states)).mean()
        self.actor_optimizer.zero_grad()
        actor_loss.backward()
        self.actor_optimizer.step()

        for target_param, param in zip(self.critic_target.parameters(), self.critic.parameters()):
            target_param.data.copy_(self.tau * param.data + (1 - self.tau) * target_param.data)
        for target_param, param in zip(self.actor_target.parameters(), self.actor.parameters()):
            target_param.data.copy_(self.tau * param.data + (1 - self.tau) * target_param.data)

    def add_to_replay_buffer(self, state, action, reward, next_state, done):
        self.replay_buffer.add(state, action, reward, next_state, done)

这里初始化了 Actor 和 Critic 及其目标网络,并定义了训练循环。注意 Actor 的损失取负号是因为我们要最大化 Q 值,而优化器默认最小化损失。

6. 训练智能体
def train_ddpg(env_name, episodes=1000, max_steps=200):
    env = gym.make(env_name)
    state_dim = env.observation_space.shape[0]
    action_dim = env.action_space.shape[0]
    max_action = float(env.action_space.high[0])

    agent = DDPGAgent(state_dim, action_dim, max_action)
    rewards = []

    for episode in range(episodes):
        state, _ = env.reset()
        episode_reward = 0
        for step in range(max_steps):
            action = agent.select_action(state)
            next_state, reward, done, _, _ = env.step(action)
            agent.add_to_replay_buffer(state, action, reward, next_state, done)
            agent.train()
            state = next_state
            episode_reward += reward
            if done:
                break
        rewards.append(episode_reward)
        print(f"Episode: {episode + 1}, Reward: {episode_reward}")

    plt.plot(rewards)
    plt.title("Learning Curve")
    plt.xlabel("Episodes")
    plt.ylabel("Cumulative Reward")
    plt.show()
    env.close()

if __name__ == "__main__":
    env_name = "Pendulum-v1"
    episodes = 500
    train_ddpg(env_name, episodes=episodes)

主函数中创建了 Pendulum 环境,设置状态和动作维度,初始化智能体并开始训练。训练结束后会绘制学习曲线。

运行结果

训练完成后,可以看到累计奖励随回合数变化的曲线,通常随着训练进行,奖励会逐渐上升并趋于稳定。

文章配图

注意事项

  • 演员和评论家网络: 演员网络预测给定当前状态的动作,批评家网络评估状态 - 行为对的 q 值。
  • Replay Buffer: 存储过去的经验,使有效的采样训练成为可能。
  • 训练: Critic 使用 Bellman 方程更新,Actor 被更新以最大化期望 q 值。
  • 目标网络: 平滑更新以稳定训练。
  • 环境: 代理在 Pendulum-v1 环境中进行训练作为演示。

优势与应用

  • 解决连续动作问题: 直接输出连续值动作,无需离散化。
  • 样本效率高: 使用经验回放和目标网络,减少样本相关性,提高学习效率。

应用场景:机器人运动控制(机械臂、无人机)、自动驾驶中的连续控制任务、游戏中的复杂策略设计。

通俗类比

可以把 DDPG 算法想象成一个赛车手(Actor)和他的教练(Critic):

  • 赛车手(Actor): 决定转弯的角度、加速的力度,直接控制赛车。
  • 教练(Critic): 观察赛车手的表现,告诉他哪些动作是好的,哪些需要改进。
  • 经验回放池: 赛车手回看之前的比赛录像,找到改进的地方。
  • 目标网络: 类似于赛车手的长期目标,比如平稳驾驶,而不是今天开得快、明天开得慢。

目录

  1. 深度确定性策略梯度算法 (DDPG) 详解
  2. 算法特点
  3. 核心改进点
  4. 算法公式推导
  5. 1. Q 值函数更新
  6. 2. 策略更新(Actor 网络)
  7. 3. 目标网络更新
  8. 算法流程
  9. Python 实现
  10. 1. 导入必要库
  11. 2. 定义 Actor 网络
  12. 3. 定义 Critic 网络
  13. 4. 定义经验回放池
  14. 5. 定义 DDPG 智能体
  15. 6. 训练智能体
  16. 运行结果
  17. 注意事项
  18. 优势与应用
  19. 通俗类比

更多推荐文章

查看全部
  • 大规模文本去重加速:Fast Sketch 算法与 C++ 落地实践
  • C++ 实现 JSON 与 HTTP 协议,从零构建 Web 计算器服务器
  • AI 大模型开发经典书籍推荐与学习路径
  • Windows 11 配置 CUDA 版 llama.cpp 实现系统全局调用
  • 基于 Vue3 与.NET Core 的企业级大文件断点续传及信创适配方案
  • CentOS 安装 Python 3.12 实战记录
  • 手机端 Stable Diffusion 开源工具使用指南
  • Qwen3-VL-WEBUI 架构与 Instruct/Thinking 双模式实战
  • Spring Boot 3.x PostgreSQL JSONB 类型映射到 Java 对象详解与解决方案
  • 国内大模型公司面试经历与技术复盘
  • C++高性能推理优化全解析:AIGC 场景下吞吐量提升策略
  • Next-AI-Draw.io:AI 驱动开源绘图工具部署指南
  • Comfy-Photoshop-SD:革命性AI绘画集成解决方案深度解析
  • 使用 Frontend Design Skill 提升大模型前端设计质量
  • WebCodecs 设备能力检测与硬解/软解降级方案
  • Kestrel:.NET 跨平台高性能 Web 服务器详解
  • Docker 部署 Web-Check 站点检测工具及内网穿透远程访问
  • 无人机电力巡检缺陷检测数据集及 YOLOv8 训练指南
  • RAG 实战:利用 Langchain 和 Milvus 构建本地知识库
  • 动态网站爬虫实战:SpiderFlow 可视化编排与自定义函数

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online