【强化学习】深度确定性策略梯度算法(DDPG)详解(附代码)

【强化学习】深度确定性策略梯度算法(DDPG)详解(附代码)
        📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:

       【强化学习】- 【单智能体强化学习】(10)---《深度确定性策略梯度算法(DDPG)详解》

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

目录

DDPG算法详细介绍

算法特点

核心改进点

算法公式推导

1. Q值函数更新

2. 策略更新(Actor网络)

3. 目标网络更新

算法流程

[Python] DDPG算法实现

1. 导入必要库

2. 定义 Actor 网络

3. 定义 Critic 网络

4. 定义经验回放池

5. 定义 DDPG 智能体

6. 动作选择方法

7. 训练方法

8. 训练智能体

 9.可视化学习曲线

完整代码

[Results] 运行结果

[Notice] 代码说明

优势

通俗类比

应用场景


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. 更新Actor网络:使用Critic网络的梯度来调整Actor网络的参数。
  3. 目标网络更新:按照软更新公式更新目标网络的参数。
  4. 重复以上步骤,直到达到学习目标。

更新Critic网络:使用采样数据和目标Critic网络计算目标值

y_i

,最小化Critic的损失函数。

采样训练:从经验池中随机采样小批量数据

(s_i, a_i, r_i, s'_i)

存储经验:将

(s_t, a_t, r_t, s_{t+1})

存储到经验回放池。

交互环境:在状态

s_t

下,通过Actor网络生成动作

a_t


执行动作

a_t

,获取奖励

r_t

和下一状态

s_{t+1}


[Python] DDPG算法实现

        下面给出了DDPG(深度确定性策略梯度)算法的完整Python实现。该实现包括Actor-Critic架构、缓冲区和目标网络等。

 项目代码我已经放入GitCode里面,可以通过下面链接跳转:🔥

【强化学习】--- DDPG算法 

后续相关单智能体强化学习算法也会不断在【强化学习】项目里更新,如果该项目对你有所帮助,请帮我点一个星星✨✨✨✨✨,鼓励分享,十分感谢!!!

若是下面代码复现困难或者有问题,也欢迎评论区留言

1. 导入必要库

import gym # 导入 Gym 库,用于创建和管理强化学习环境 import numpy as np # 导入 NumPy,用于处理数组和数学运算 import torch # 导入 PyTorch,用于构建和训练神经网络 import torch.nn as nn # 导入 PyTorch 的神经网络模块 import torch.optim as optim # 导入 PyTorch 的优化器模块 from collections import deque # 导入双端队列,用于实现经验回放池 import random # 导入随机模块,用于从经验池中采样
  • gym:用于创建和管理强化学习环境(例如Pendulum-v1)。
  • numpy:处理数组和数值计算。
  • torch:用于深度学习模型的构建和训练。
  • deque:一个双端队列,适用于存储经验回放池。
  • random:用于从经验池中随机抽样。

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) # 输入层到隐藏层1,大小为 256 self.layer2 = nn.Linear(256, 256) # 隐藏层1到隐藏层2,大小为 256 self.layer3 = nn.Linear(256, action_dim) # 隐藏层2到输出层,输出动作维度 self.max_action = max_action # 动作的最大值,用于限制输出范围 def forward(self, state): x = torch.relu(self.layer1(state)) # 使用 ReLU 激活函数处理隐藏层1 x = torch.relu(self.layer2(x)) # 使用 ReLU 激活函数处理隐藏层2 x = torch.tanh(self.layer3(x)) * self.max_action # 使用 Tanh 激活函数,并放大到动作范围 return x # 返回输出动作 
解析
  • Actor 网络的作用是生成给定状态下的最优动作。
  • 输入
    • state_dim:环境状态的维度。
    • action_dim:动作空间的维度。
    • max_action:动作的最大值,用于约束输出动作的范围。
  • 网络结构
    • 两层隐藏层(256个神经元,每层使用ReLU激活函数)。
    • 输出层使用tanh激活函数(将动作限制在 ([-1, 1])),再乘以 max_action 缩放到实际动作范围。

3. 定义 Critic 网络

# 定义 Critic 网络(价值网络) class Critic(nn.Module): def __init__(self, state_dim, action_dim): super(Critic, self).__init__() self.layer1 = nn.Linear(state_dim + action_dim, 256) # 将状态和动作拼接后输入到隐藏层1 self.layer2 = nn.Linear(256, 256) # 隐藏层1到隐藏层2,大小为 256 self.layer3 = nn.Linear(256, 1) # 隐藏层2到输出层,输出 Q 值 def forward(self, state, action): x = torch.cat([state, action], dim=1) # 将状态和动作拼接为单个输入 x = torch.relu(self.layer1(x)) # 使用 ReLU 激活函数处理隐藏层1 x = torch.relu(self.layer2(x)) # 使用 ReLU 激活函数处理隐藏层2 x = self.layer3(x) # 输出 Q 值 return x # 返回 Q 值
解析
  • Critic 网络评估给定状态和动作的质量(即 Q 值)。
  • 输入
    • state:环境的当前状态。
    • action:给定状态下的动作。
  • 网络结构
    • 将状态和动作拼接作为输入。
    • 两层隐藏层,使用ReLU激活。
    • 输出层是一个标量 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)) # 返回 NumPy 数组格式的数据 def size(self): return len(self.buffer) # 返回经验池中当前存储的样本数量
解析
  • 作用:存储智能体与环境交互的经验数据,打破样本间的时间相关性。
  • 方法
    • add:将 ((state, action, reward, next_state, done)) 存入经验池。
    • sample:从经验池中随机采样,返回小批量的训练数据。
    • size:返回经验池中的样本数量。

5. 定义 DDPG 智能体

# 定义 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) # 初始化 Actor 网络 self.actor_target = Actor(state_dim, action_dim, max_action) # 初始化目标 Actor 网络 self.actor_target.load_state_dict(self.actor.state_dict()) # 将 Actor 网络的权重复制到目标网络 self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=1e-4) # 定义 Actor 网络的优化器 self.critic = Critic(state_dim, action_dim) # 初始化 Critic 网络 self.critic_target = Critic(state_dim, action_dim) # 初始化目标 Critic 网络 self.critic_target.load_state_dict(self.critic.state_dict()) # 将 Critic 网络的权重复制到目标网络 self.critic_optimizer = optim.Adam(self.critic.parameters(), lr=1e-3) # 定义 Critic 网络的优化器 self.max_action = max_action # 动作的最大值 self.gamma = gamma # 折扣因子 self.tau = tau # 目标网络软更新参数 self.replay_buffer = ReplayBuffer(buffer_size) # 初始化经验回放池 self.batch_size = batch_size # 批量大小
解析
  • 初始化网络
    • Actor 和 Critic 网络分别有目标网络(actor_target 和 critic_target),用于稳定训练。
  • 优化器
    • Adam 优化器分别优化 Actor 和 Critic 网络。
  • 超参数
    • gamma:折扣因子。
    • tau:目标网络更新的系数。
    • buffer_size:经验池的容量。
    • batch_size:每次训练使用的样本数量。

6. 动作选择方法

# 根据状态选择动作 def select_action(self, state): state = torch.FloatTensor(state.reshape(1, -1)) # 将状态转换为 PyTorch 张量 action = self.actor(state).detach().cpu().numpy().flatten() # 使用 Actor 网络生成动作,并转为 NumPy 数组 return action # 返回动作
  • 作用:根据当前状态 (s),生成一个连续动作 (a)。
  • 流程
    • 将输入状态转换为 Torch 张量。
    • 用 Actor 网络预测动作。
    • 动作转换为 NumPy 数组返回。

7. 训练方法

 # 训练方法 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) # 添加一个维度以匹配Q值维度 next_states = torch.FloatTensor(next_states) dones = torch.FloatTensor(dones).unsqueeze(1) # 添加一个维度以匹配Q值维度 # 计算critic的损失 with torch.no_grad(): # 关闭梯度计算 next_actions = self.actor_target(next_states) # 使用目标actor网络预测下一步动作 target_q = self.critic_target(next_states, next_actions) # 目标Q值 # 使用贝尔曼方程更新目标Q值 target_q = rewards + (1 - dones) * self.gamma * target_q # 当前Q值 current_q = self.critic(states, actions) # 均方误差损失 critic_loss = nn.MSELoss()(current_q, target_q) # 优化critic网络 self.critic_optimizer.zero_grad() critic_loss.backward() self.critic_optimizer.step() # 计算actor的损失 actor_loss = -self.critic(states, self.actor(states)).mean() # 策略梯度目标为最大化Q值 # 优化actor网络 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)
解析
  1. Actor 网络更新:优化目标:最大化 Critic 网络的 Q 值。
  2. 目标网络更新:使用软更新方式(通过 (\tau))平滑更新目标网络参数。

Critic 网络更新:计算目标 Q 值

y = r + \gamma Q'(s', \mu'(s'))


使用均方误差 (MSE) 更新 Critic 网络。


8. 训练智能体

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]) # 动作最大值 # 初始化DDPG智能体 agent = DDPGAgent(state_dim, action_dim, max_action) rewards = [] # 用于存储每个episode的奖励 for episode in range(episodes): state, _ = env.reset() # 重置环境,获取初始状态 episode_reward = 0 # 初始化每轮奖励为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}") 
解析
  • 训练流程
    1. 初始化环境和智能体。
    2. 在每个 episode 中:
      • 使用 Actor 网络生成动作与环境交互。
      • 将经验存储到经验池。
      • 更新 Actor 和 Critic 网络。
      • 打印 episode 的累计奖励。

 9.可视化学习曲线

    # 绘制学习曲线的方法 import matplotlib.pyplot as plt # 绘制学习曲线     plt.plot(rewards)     plt.title("Learning Curve")     plt.xlabel("Episodes")     plt.ylabel("Cumulative Reward")     plt.show()

完整代码

"""《DDPG算法的代码》 时间:2024.12 环境:gym 作者:不去幼儿园 """ import gym # 导入 Gym 库,用于创建和管理强化学习环境 import numpy as np # 导入 NumPy,用于处理数组和数学运算 import torch # 导入 PyTorch,用于构建和训练神经网络 import torch.nn as nn # 导入 PyTorch 的神经网络模块 import torch.optim as optim # 导入 PyTorch 的优化器模块 from collections import deque # 导入双端队列,用于实现经验回放池 import random # 导入随机模块,用于从经验池中采样 # 定义 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) # 输入层到隐藏层1,大小为 256 self.layer2 = nn.Linear(256, 256) # 隐藏层1到隐藏层2,大小为 256 self.layer3 = nn.Linear(256, action_dim) # 隐藏层2到输出层,输出动作维度 self.max_action = max_action # 动作的最大值,用于限制输出范围 def forward(self, state): x = torch.relu(self.layer1(state)) # 使用 ReLU 激活函数处理隐藏层1 x = torch.relu(self.layer2(x)) # 使用 ReLU 激活函数处理隐藏层2 x = torch.tanh(self.layer3(x)) * self.max_action # 使用 Tanh 激活函数,并放大到动作范围 return x # 返回输出动作 # 定义 Critic 网络(价值网络) class Critic(nn.Module): def __init__(self, state_dim, action_dim): super(Critic, self).__init__() self.layer1 = nn.Linear(state_dim + action_dim, 256) # 将状态和动作拼接后输入到隐藏层1 self.layer2 = nn.Linear(256, 256) # 隐藏层1到隐藏层2,大小为 256 self.layer3 = nn.Linear(256, 1) # 隐藏层2到输出层,输出 Q 值 def forward(self, state, action): x = torch.cat([state, action], dim=1) # 将状态和动作拼接为单个输入 x = torch.relu(self.layer1(x)) # 使用 ReLU 激活函数处理隐藏层1 x = torch.relu(self.layer2(x)) # 使用 ReLU 激活函数处理隐藏层2 x = self.layer3(x) # 输出 Q 值 return x # 返回 Q 值 # 定义经验回放池 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)) # 返回 NumPy 数组格式的数据 def size(self): return len(self.buffer) # 返回经验池中当前存储的样本数量 # DDPG智能体类定义 class DDPGAgent: # 初始化方法,设置智能体的参数和模型 def __init__(self, state_dim, action_dim, max_action, gamma=0.99, tau=0.005, buffer_size=100000, batch_size=64): # 定义actor网络(策略网络)及其目标网络 self.actor = Actor(state_dim, action_dim, max_action) self.actor_target = Actor(state_dim, action_dim, max_action) # 将目标actor网络的参数初始化为与actor网络一致 self.actor_target.load_state_dict(self.actor.state_dict()) # 定义actor网络的优化器 self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=1e-4) # 定义critic网络(值网络)及其目标网络 self.critic = Critic(state_dim, action_dim) self.critic_target = Critic(state_dim, action_dim) # 将目标critic网络的参数初始化为与critic网络一致 self.critic_target.load_state_dict(self.critic.state_dict()) # 定义critic网络的优化器 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)) # 使用actor网络预测动作,并将结果转换为NumPy数组 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) # 添加一个维度以匹配Q值维度 next_states = torch.FloatTensor(next_states) dones = torch.FloatTensor(dones).unsqueeze(1) # 添加一个维度以匹配Q值维度 # 计算critic的损失 with torch.no_grad(): # 关闭梯度计算 next_actions = self.actor_target(next_states) # 使用目标actor网络预测下一步动作 target_q = self.critic_target(next_states, next_actions) # 目标Q值 # 使用贝尔曼方程更新目标Q值 target_q = rewards + (1 - dones) * self.gamma * target_q # 当前Q值 current_q = self.critic(states, actions) # 均方误差损失 critic_loss = nn.MSELoss()(current_q, target_q) # 优化critic网络 self.critic_optimizer.zero_grad() critic_loss.backward() self.critic_optimizer.step() # 计算actor的损失 actor_loss = -self.critic(states, self.actor(states)).mean() # 策略梯度目标为最大化Q值 # 优化actor网络 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) # 绘制学习曲线的方法 import matplotlib.pyplot as plt 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]) # 动作最大值 # 初始化DDPG智能体 agent = DDPGAgent(state_dim, action_dim, max_action) rewards = [] # 用于存储每个episode的奖励 for episode in range(episodes): state, _ = env.reset() # 重置环境,获取初始状态 episode_reward = 0 # 初始化每轮奖励为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) 

[Results] 运行结果


[Notice] 代码说明

演员和评论家网络:

        演员网络预测给定当前状态的动作。

        批评家网络评估状态-行为对的q值。

Replay Buffer:

        存储过去的经验,并使有效的采样训练。

训练:

        Critic使用Bellman方程更新评论家。

        Actor被更新以最大化期望q值。

目标网络:

        平滑更新以稳定训练。

环境:

        代理在Pendulum-v1环境中进行训练作为演示。

​# 环境配置 Python 3.11.5 torch 2.1.0 torchvision 0.16.0 gym 0.26.2
        由于博文主要为了介绍相关算法的原理和应用的方法,缺乏对于实际效果的关注,算法可能在上述环境中的效果不佳或者无法运行,一是算法不适配上述环境,二是算法未调参和优化,三是没有呈现完整的代码,四是等等。上述代码用于了解和学习算法足够了,但若是想直接将上面代码应用于实际项目中,还需要进行修改。

优势

  • 解决连续动作问题: 它可以直接输出一个连续值动作,而不像传统的离散强化学习算法需要动作离散化。
  • 样本效率高: 使用了经验回放和目标网络,这减少了样本相关性问题,提高了学习效率和稳定性。

通俗类比

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

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

应用场景

  1. 机器人运动控制(机械臂、无人机)
  2. 自动驾驶中的连续控制任务
  3. 游戏中的复杂策略设计
 更多强化学习文章,请前往:【强化学习(RL)】专栏

        博客都是给自己看的笔记,如有误导深表抱歉。文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者添加VX:Rainbook_2,联系作者。✨

Read more

【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

目录 一、为什么需要 Disruptor?—— 背景与问题 二、核心设计思想 三、核心组件与原理 1. 环形缓冲区(Ring Buffer) 2. 序列(Sequence) 3. 序列屏障(Sequence Barrier) 4. 等待策略(Wait Strategy) 5. 事件处理器(EventProcessor) 6. 生产者(Producer) 四、工作流程示例(单生产者 -> 单消费者) 五、多消费者与依赖关系 六、总结:Disruptor 高性能的秘诀 一、为什么需要 Disruptor?—— 背景与问题 在高并发编程中,传统的队列(如 java.

By Ne0inhk
Java-Spring入门指南(十四)利用IDEA教你构建第一个SpringMVC系统

Java-Spring入门指南(十四)利用IDEA教你构建第一个SpringMVC系统

Java-Spring入门指南(十四)SpringMVC项目实战搭建 * 前言 * 一、首先导入我们的Maven * 二、接着导入SpringMVC相关的包 * 三、创建Servlet_web环境 * (1)配置springmvc.xml * (2)配置web.xml里面的中央处理器 * (3)为什么需要配置前端控制器? * 五、配置最新的tomcat 11 * 六、运行项目 前言 * 在上一篇博客中,我们系统学习了SpringMVC的核心流程与组件分工,明确了DispatcherServlet(前端控制器)、HandlerMapping(处理器映射器)等组件的协作逻辑。 * 理论之后更需实践,如何从0到1搭建一个可运行的SpringMVC项目,如何将核心组件配置落地,是本次实战的核心目标。 * 本文将基于Maven+IDEA+Tomcat 11环境,一步步完成SpringMVC项目的搭建、配置与运行,让你直观感受“理论”到“实战”的转化过程。 我的个人主页,欢迎来阅读我的其他文章 https:

By Ne0inhk
javaSE————网络原理

javaSE————网络原理

今天巨无聊,全是概念,重点记一下五元组,TCP/IP五层模型和OSI七层调用模型,大家这期就当看故事啦; 1,网络发展史 1)独立模式 我们刚开始使用计算机呢,客户端的数据不是共享的,如果有一个人想要办理业务,而这个业务所需的资源是在三台电脑上,那么这个人就需要在这三个电脑上不断的办理任务,而其他人想要办理业务,还需要等到前一个人办理完,效率非常低,那怎么办,我们就改进; 2)网络互联 接下来我们就使用网络进行计算机资源的共享,让多个计算机可以一起办理业务,达成数据共享,即网络通信,我们可以根据网络互联的规模分为局域网和广域网; 3)局域网LAN 局域网是本地,局部构建的一种私有网络,又被称为内网,局域网内的主机能够实现网络通信,局域网和局域网在没有连接的情况是不能进行通信的; 组件局域网等待方式也有很多种,可以通过网线直连,也可以通过交换机相连,还可以通过集线器相连,还可以通过路由器连接交换机在与多个主机相连; 4)广域网WAN 广域网就是多个局域网完成了连接,很多很多的局域网都能进行网络通信,我们其实可以把咱们中国的网络看成一个巨大的广域网,我们管内部

By Ne0inhk
Java 大视界 -- Java 大数据在智能教育学习成果评估体系完善与教育质量提升中的深度应用(434)

Java 大视界 -- Java 大数据在智能教育学习成果评估体系完善与教育质量提升中的深度应用(434)

Java 大视界 -- Java 大数据在智能教育学习成果评估体系完善与教育质量提升中的深度应用(434) * 引言: * 正文: * 一、Java 大数据赋能智能教育评估的核心逻辑 * 1.1 教育评估数据特性与 Java 技术栈的精准适配 * 1.1.1 核心价值:从 “经验驱动” 到 “数据驱动” 的范式跃迁 * 1.2 数据流转与评估建模的底层逻辑 * 二、核心技术架构与落地路径(可直接复用) * 2.1 分层解耦的高可用架构设计 * 2.1.1 采集层:高并发多端数据接入(Java + Kafka) * 2.1.2 处理层:Spark + Hive 实现海量数据清洗与建模 * 2.1.

By Ne0inhk