📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏: 【强化学习】(27)---《分层深度Q网络(Hierarchical-DQN)算法》
Hierarchical-DQN (Hierarchical Deep Q-Network) 是一种分层强化学习算法,专门设计用于解决复杂的任务,通过将任务分解为层次化的子任务来学习。它结合了深度 Q 网络(DQN)和分层强化学习的思想,将复杂任务分解为多个具有不同时间尺度的子任务。Hierarchical-DQN 的设计思路和 FeUdal Networks 类似,都是通过层次结构来解决长时间跨度的任务,但 Hierarchical-DQN 的具体实现有所不同,尤其在策略的选择和值函数的更新方面。
Hierarchical-DQN 的核心思想是将任务分解为高层次任务和低层次任务,分别学习不同的策略。其层次结构可以概括为:
通过这种分层结构,Hierarchical-DQN 能够在长时间跨度的任务中进行学习,并有效处理奖励稀疏的问题。
Hierarchical-DQN 的结构由两个主要的组件组成:高层策略(Meta-controller)和低层策略(Controller)。
Hierarchical-DQN 的工作流程包括以下几个步骤:
,该目标是低层策略需要实现的子任务。
,直到目标实现或到达时间地平线结束。
Hierarchical-DQN 通过 Q-learning 来进行策略的学习和更新,其核心公式如下:
高层策略使用 Q-learning 来选择最优目标
,并通过环境的全局奖励更新其 Q 函数。高层策略的 Q 函数更新公式为:
其中:
是高层策略在时间步
的状态。
是高层策略选择的目标。
是环境的全局奖励。
是折扣因子,用于平衡短期和长期奖励。
是学习率。
是时间地平线,表示高层策略选择目标的时间跨度。
低层策略使用 DQN 来学习在给定目标
下的最优动作。低层策略的 Q 函数更新公式为:
其中:
是低层策略在给定目标
时的 Q 值函数。
是低层策略的内在奖励,通常表示低层策略在当前时间步中是否朝着目标
取得进展。
与 FeUdal Networks 类似,Hierarchical-DQN 也采用了内在奖励机制来指导低层策略的学习。内在奖励
通常由目标
和当前状态
之间的距离或差异来决定。
内在奖励的一种简单形式为:
其中:
表示状态
与目标
之间的距离,距离越小,奖励越大。
这样设计内在奖励机制有助于指导低层策略逐步朝着高层策略设定的目标方向前进。
Hierarchical-DQN 将强化学习任务分解为高层和低层的两个深度 Q 网络。高层网络负责设定子目标,低层网络执行具体动作,并根据这些子目标进行学习。通过分层结构,可以有效减少低层的动作空间,提升学习效率。
在 CartPole 环境中,我们可以定义两个层次:
🔥若是下面代码复现困难或者有问题,欢迎评论区留言;需要以整个项目形式的代码,请在评论区留下您的邮箱📌,以便于及时分享给您(私信难以及时回复)。
"""《Hierarchical-DQN 实现》
时间:2024.10.07
环境:CartPole
作者:不去幼儿园
"""
import gym
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import random
# 超参数
GAMMA = 0.99
LEARNING_RATE = 0.001
EPSILON_DECAY = 0.995
MIN_EPSILON = 0.1
NUM_EPISODES = 500
HIGH_LEVEL_UPDATE_FREQUENCY = 10 # 高层更新频率
LOW_LEVEL_UPDATE_FREQUENCY = 1 # 低层更新频率
# Q网络
class QNetwork(nn.Module):
def __init__(self, input_dim, output_dim):
super(QNetwork, self).__init__()
self.fc1 = nn.Linear(input_dim, 128)
self.fc2 = nn.Linear(128, output_dim)
def forward(self, state):
x = torch.relu(self.fc1(state))
q_values = self.fc2(x)
return q_values
# Hierarchical-DQN 智能体
class HierarchicalDQNAgent:
def __init__(self, state_dim, action_dim, goal_dim):
self.high_level_net = QNetwork(state_dim, goal_dim) # 高层 Q 网络
self.low_level_net = QNetwork(state_dim + 1, action_dim) # 低层 Q 网络
self.high_level_optimizer = optim.Adam(self.high_level_net.parameters(), lr=LEARNING_RATE)
self.low_level_optimizer = optim.Adam(self.low_level_net.parameters(), lr=LEARNING_RATE)
self.epsilon = 1.0
def select_high_level_goal(self, state, epsilon):
if random.random() < epsilon:
return random.choice([0, 1]) # 随机选择目标
else:
state = torch.FloatTensor(state).unsqueeze(0)
q_values = self.high_level_net(state)
return torch.argmax(q_values).item()
def select_low_level_action(self, state, goal, epsilon):
if random.random() < epsilon:
return random.choice([0, 1]) # 随机选择动作
else:
state_goal = torch.cat((torch.FloatTensor(state).unsqueeze(0), torch.FloatTensor([[goal]])), dim=-1)
q_values = self.low_level_net(state_goal)
return torch.argmax(q_values).item()
def update_high_level(self, state, goal, reward, next_state):
state = torch.FloatTensor(state).unsqueeze(0)
next_state = torch.FloatTensor(next_state).unsqueeze(0)
goal = torch.tensor([goal], dtype=torch.float32)
q_values = self.high_level_net(state)
next_q_values = self.high_level_net(next_state).detach()
# 确保 target_q 维度匹配
target_q = torch.tensor([reward + GAMMA * torch.max(next_q_values)])
loss = nn.functional.mse_loss(q_values[0, goal.long()], target_q)
self.high_level_optimizer.zero_grad()
loss.backward()
self.high_level_optimizer.step()
def update_low_level(self, state, goal, action, reward, next_state):
state_goal = torch.cat((torch.FloatTensor(state).unsqueeze(0), torch.FloatTensor([[goal]])), dim=-1)
next_state_goal = torch.cat((torch.FloatTensor(next_state).unsqueeze(0), torch.FloatTensor([[goal]])), dim=-1)
q_values = self.low_level_net(state_goal)
next_q_values = self.low_level_net(next_state_goal).detach()
target_q = reward + GAMMA * torch.max(next_q_values)
loss = nn.functional.mse_loss(q_values[0, action], target_q)
self.low_level_optimizer.zero_grad()
loss.backward()
self.low_level_optimizer.step()
def train(self, env, num_episodes):
goal_dim = self.high_level_net.fc2.out_features
for episode in range(num_episodes):
state, _ = env.reset() # 修改后的reset返回值
goal = self.select_high_level_goal(state, self.epsilon) # 高层选择目标
done = False
episode_reward = 0
steps = 0
while not done:
steps += 1
action = self.select_low_level_action(state, goal, self.epsilon) # 低层选择动作
next_state, reward, done, _, _ = env.step(action) # 修改后的step返回值
# 更新低层
self.update_low_level(state, goal, action, reward, next_state)
# 每隔 HIGH_LEVEL_UPDATE_FREQUENCY 更新一次高层
if steps % HIGH_LEVEL_UPDATE_FREQUENCY == 0:
new_goal = self.select_high_level_goal(next_state, self.epsilon)
self.update_high_level(state, goal, reward, next_state)
goal = new_goal
state = next_state
episode_reward += reward
self.epsilon = max(MIN_EPSILON, self.epsilon * EPSILON_DECAY)
print(f"Episode {episode + 1}: Total Reward: {episode_reward}")
# 测试 Hierarchical-DQN 智能体并显示动画
def test_hdqn_agent(agent, env, num_episodes=5):
for episode in range(num_episodes):
state, _ = env.reset() # 修改后的reset返回值
goal = agent.select_high_level_goal(state, epsilon=0.0) # 高层选择目标
done = False
total_reward = 0
env.render()
while not done:
env.render()
action = agent.select_low_level_action(state, goal, epsilon=0.0) # 低层选择动作
next_state, reward, done, _, _ = env.step(action) # 修改后的step返回值
state = next_state
total_reward += reward
print(f"Test Episode {episode + 1}: Total Reward: {total_reward}")
env.close()
# 测试智能体并显示动画
test_hdqn_agent(agent, env)
train
方法中,高层每隔一定步数设定目标,低层则持续执行动作,并学习对应的策略。test_hdqn_agent
方法中,使用训练好的模型对智能体进行测试,并显示动画。由于博文主要为了介绍相关算法的原理和应用的方法,缺乏对于实际效果的关注,算法可能在上述环境中的效果不佳,一是算法不适配上述环境,二是算法未调参和优化,三是等等。上述代码用于了解和学习算法足够了,但若是想直接将上面代码应用于实际项目中,还需要进行修改。
Hierarchical-DQN 适用于需要解决长时间跨度、多步决策任务的场景,如:
Hierarchical-DQN算法结合了层次化强化学习的思想和深度 Q 网络,提出了一种将任务分解为高层策略和低层策略的层次结构,并通过内在奖励机制来增强学习效率。论文中详细介绍了 Hierarchical-DQN 的结构、机制和实验结果。
🔥想了解更多分层强化学习的文章,请查看文章: 【RL Latest Tech】分层强化学习(Hierarchical RL)
文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者