- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
本文为强化学习笔记第四篇,第一篇讲的是Q-learning和DQN,第二篇DDPG,第三篇TD3 。
TD3比DDPG少了一个target_actor网络,其它地方有点小改动 。
CSDN主页:https://blog.csdn.net/rvdgdsva 。
博客园主页:https://www.cnblogs.com/hassle 。
首先,我们需要明确,Q-learning算法发展成DQN算法,DQN算法发展成为DDPG算法,而DDPG算法发展成TD3算法,TD3算法发展成SAC算法 。
Soft Actor-Critic (SAC) 是一种基于策略梯度的深度强化学习算法,它具有最大化奖励与最大化熵(探索性)的双重目标。SAC 通过引入熵正则项,使策略在决策时具有更大的随机性,从而提高探索能力.
OK,先用伪代码让你们感受一下SAC算法 。
# 定义 SAC 超参数
alpha = 0.2 # 熵正则项系数
gamma = 0.99 # 折扣因子
tau = 0.005 # 目标网络软更新参数
lr = 3e-4 # 学习率
# 初始化 Actor、Critic、Target Critic 网络和优化器
actor = ActorNetwork() # 策略网络 π(s)
critic1 = CriticNetwork() # 第一个 Q 网络 Q1(s, a)
critic2 = CriticNetwork() # 第二个 Q 网络 Q2(s, a)
target_critic1 = CriticNetwork() # 目标 Q 网络 1
target_critic2 = CriticNetwork() # 目标 Q 网络 2
# 将目标 Q 网络的参数设置为与 Critic 网络相同
target_critic1.load_state_dict(critic1.state_dict())
target_critic2.load_state_dict(critic2.state_dict())
# 初始化优化器
actor_optimizer = torch.optim.Adam(actor.parameters(), lr=lr)
critic1_optimizer = torch.optim.Adam(critic1.parameters(), lr=lr)
critic2_optimizer = torch.optim.Adam(critic2.parameters(), lr=lr)
# 经验回放池(Replay Buffer)
replay_buffer = ReplayBuffer()
# SAC 训练循环
for each iteration:
# Step 1: 从 Replay Buffer 中采样一个批次 (state, action, reward, next_state)
batch = replay_buffer.sample()
state, action, reward, next_state, done = batch
# Step 2: 计算目标 Q 值 (y)
with torch.no_grad():
# 从 Actor 网络中获取 next_state 的下一个动作
next_action, next_log_prob = actor.sample(next_state)
# 目标 Q 值的计算:使用目标 Q 网络的最小值 + 熵项
target_q1_value = target_critic1(next_state, next_action)
target_q2_value = target_critic2(next_state, next_action)
min_target_q_value = torch.min(target_q1_value, target_q2_value)
# 目标 Q 值 y = r + γ * (最小目标 Q 值 - α * next_log_prob)
target_q_value = reward + gamma * (1 - done) * (min_target_q_value - alpha * next_log_prob)
# Step 3: 更新 Critic 网络
# Critic 1 损失
current_q1_value = critic1(state, action)
critic1_loss = F.mse_loss(current_q1_value, target_q_value)
# Critic 2 损失
current_q2_value = critic2(state, action)
critic2_loss = F.mse_loss(current_q2_value, target_q_value)
# 反向传播并更新 Critic 网络参数
critic1_optimizer.zero_grad()
critic1_loss.backward()
critic1_optimizer.step()
critic2_optimizer.zero_grad()
critic2_loss.backward()
critic2_optimizer.step()
# Step 4: 更新 Actor 网络
# 通过 Actor 网络生成新的动作及其 log 概率
new_action, log_prob = actor.sample(state)
# 计算 Actor 的目标损失:L = α * log_prob - Q1(s, π(s))
q1_value = critic1(state, new_action)
actor_loss = (alpha * log_prob - q1_value).mean()
# 反向传播并更新 Actor 网络参数
actor_optimizer.zero_grad()
actor_loss.backward()
actor_optimizer.step()
# Step 5: 软更新目标 Q 网络参数
with torch.no_grad():
for param, target_param in zip(critic1.parameters(), target_critic1.parameters()):
target_param.data.copy_(tau * param.data + (1 - tau) * target_param.data)
for param, target_param in zip(critic2.parameters(), target_critic2.parameters()):
target_param.data.copy_(tau * param.data + (1 - tau) * target_param.data)
1、初始化 Actor、Critic1、Critic2、TargetCritic1 、TargetCritic2 网络 2、Buffer中采样 (state, action, reward, next_state) 。
3、Actor 输入 next_state 对应输出 next_action 和 next_log_prob 4、Actor 输入 state 对应输出 new_action 和 log_prob 5、Critic1 和 Critic2 分别输入next_state 和 next_action 取其中较小输出经熵正则计算得 target_q_value 。
6、使用 MSE_loss(Critic1(state, action), target_q_value) 更新 Critic1 7、使用 MSE_loss(Critic2(state, action), target_q_value) 更新 Critic2 8、使用 (alpha * log_prob - critic1(state, new_action)).mean() 更新 Actor 。
在 SAC 算法 中,Actor、Critic1、Critic2、Target Critic1 和 Target Critic2 网络是核心模块,它们分别用于输出动作、评估状态-动作对的价值,并通过目标网络进行稳定的更新.
Actor 网络用于在给定状态下输出一个高斯分布的均值和标准差(即策略)。它是通过神经网络近似的随机策略。用于选择动作.
import torch
import torch.nn as nn
class ActorNetwork(nn.Module):
def __init__(self, state_dim, action_dim):
super(ActorNetwork, self).__init__()
self.fc1 = nn.Linear(state_dim, 256)
self.fc2 = nn.Linear(256, 256)
self.mean_layer = nn.Linear(256, action_dim) # 输出动作的均值
self.log_std_layer = nn.Linear(256, action_dim) # 输出动作的log标准差
def forward(self, state):
x = torch.relu(self.fc1(state))
x = torch.relu(self.fc2(x))
mean = self.mean_layer(x) # 输出动作均值
log_std = self.log_std_layer(x) # 输出 log 标准差
log_std = torch.clamp(log_std, min=-20, max=2) # 限制标准差范围
return mean, log_std
def sample(self, state):
mean, log_std = self.forward(state)
std = torch.exp(log_std) # 将 log 标准差转为标准差
normal = torch.distributions.Normal(mean, std)
action = normal.rsample() # 通过重参数化技巧进行采样
log_prob = normal.log_prob(action).sum(-1) # 计算 log 概率
return action, log_prob
Critic 网络用于计算状态-动作对的 Q 值,SAC 使用两个 Critic 网络(Critic1 和 Critic2)来缓解 Q 值的过估计问题.
class CriticNetwork(nn.Module):
def __init__(self, state_dim, action_dim):
super(CriticNetwork, self).__init__()
self.fc1 = nn.Linear(state_dim + action_dim, 256)
self.fc2 = nn.Linear(256, 256)
self.q_value_layer = nn.Linear(256, 1) # 输出 Q 值
def forward(self, state, action):
x = torch.cat([state, action], dim=-1) # 将 state 和 action 作为输入
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
q_value = self.q_value_layer(x) # 输出 Q 值
return q_value
Target Critic 网络的结构与 Critic 网络相同,用于稳定 Q 值更新。它们通过软更新(即在每次训练后慢慢接近 Critic 网络的参数)来保持训练的稳定性.
class TargetCriticNetwork(nn.Module):
def __init__(self, state_dim, action_dim):
super(TargetCriticNetwork, self).__init__()
self.fc1 = nn.Linear(state_dim + action_dim, 256)
self.fc2 = nn.Linear(256, 256)
self.q_value_layer = nn.Linear(256, 1) # 输出 Q 值
def forward(self, state, action):
x = torch.cat([state, action], dim=-1) # 将 state 和 action 作为输入
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
q_value = self.q_value_layer(x) # 输出 Q 值
return q_value
在 SAC 中,目标网络会通过软更新逐渐逼近 Critic 网络的参数。每次更新后,目标网络参数会按照 ττ 的比例向 Critic 网络的参数靠拢.
def soft_update(critic, target_critic, tau=0.005):
for param, target_param in zip(critic.parameters(), target_critic.parameters()):
target_param.data.copy_(tau * param.data + (1 - tau) * target_param.data)
最后此篇关于强化学习笔记之【SAC算法】的文章就讲到这里了,如果你想了解更多关于强化学习笔记之【SAC算法】的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要使用 .sac 文件中的信息并将其绘制在网格上。我知道使用各种 ObsPy 函数可以使用 st.plot() 绘制地震图,但我似乎无法根据网格来绘制地震图。我还尝试按照此处给出的示例“How d
在此 ParserFactory.java String className = System.getProperty("org.w3c.css.sac.parser"); if (className
我正在使用示例代码学习 AzureML RL。 我可以运行用于训练的 cartpole 示例 (cartpole_ci.ipynb) 计算实例上的 PPO 模型。 我通过将 training_algo
尝试在 HtmlUnit 上做教程示例,以便我可以通过 Java 连接到网页。当我尝试运行它时出现以下错误: java.lang.NoClassDefFoundError: org/w3c/css/s
我是一名优秀的程序员,十分优秀!