【Hierarchical RL】分层深度Q网络(Hierarchical-DQN)算法
Hierarchical-DQN (Hierarchical Deep Q-Network) 是一种分层强化学习算法,专门设计用于解决复杂的任务,通过将任务分解为层次化的子任务来学习。它结合了深度 Q 网络(DQN)和分层强化学习的思想,将复杂任务分解为多个具有不同时间尺度的子任务。Hierarchical-DQN 的设计思路和 FeUdal Networks 类似,都是通过层次结构来解决长时间跨
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:
【强化学习】(27)---《分层深度Q网络(Hierarchical-DQN)算法》
分层深度Q网络(Hierarchical-DQN)算法
目录
Hierarchical-DQN (Hierarchical Deep Q-Network) 是一种分层强化学习算法,专门设计用于解决复杂的任务,通过将任务分解为层次化的子任务来学习。它结合了深度 Q 网络(DQN)和分层强化学习的思想,将复杂任务分解为多个具有不同时间尺度的子任务。Hierarchical-DQN 的设计思路和 FeUdal Networks 类似,都是通过层次结构来解决长时间跨度的任务,但 Hierarchical-DQN 的具体实现有所不同,尤其在策略的选择和值函数的更新方面。
1. Hierarchical-DQN 的核心思想
Hierarchical-DQN 的核心思想是将任务分解为高层次任务和低层次任务,分别学习不同的策略。其层次结构可以概括为:
- 高层策略(Meta-controller):负责高层目标的选择,通常操作在状态的高层次表示空间中,时间跨度较长。它决定了低层任务的目标是什么。
- 低层策略(Controller):负责执行具体的动作序列来实现高层任务设定的目标。低层策略通常每个时间步都采取动作,在具体的动作空间中进行操作。
通过这种分层结构,Hierarchical-DQN 能够在长时间跨度的任务中进行学习,并有效处理奖励稀疏的问题。
2. Hierarchical-DQN 的主要组件
Hierarchical-DQN 的结构由两个主要的组件组成:高层策略(Meta-controller)和低层策略(Controller)。
(1) 高层策略(Meta-controller)
- 高层策略操作在一个抽象的状态空间中,选择目标来指导低层策略执行。
- 高层策略基于一个目标集合(goal set),这些目标通常是状态空间的子集或特定特征(例如到达某个区域,或触发某个特定事件)。
- 高层策略的动作是选择一个目标 ( g ),并交给低层策略去实现。
(2) 低层策略(Controller)
- 低层策略操作在每个时间步的原始状态空间中,基于高层策略设定的目标选择具体的动作。
- 低层策略的任务是尽可能快地完成高层策略设定的目标。
- 当低层策略成功实现目标后,高层策略将更新其目标,继续选择新的目标。
3. Hierarchical-DQN 的工作流程
Hierarchical-DQN 的工作流程包括以下几个步骤:
-
高层策略选择目标:在每个时间地平线(时间跨度较长,如 10 步)开始时,高层策略选择一个目标 ,该目标是低层策略需要实现的子任务。
-
低层策略执行动作:低层策略根据当前状态和高层策略设定的目标,执行一系列动作 ,直到目标实现或到达时间地平线结束。
-
奖励机制:
- 高层策略根据全局环境的奖励信号进行学习,优化目标选择。
- 低层策略则根据其是否成功完成高层策略设定的目标获取内在奖励,更新其 Q 值函数。
-
目标更新:当低层策略完成目标后,高层策略会选择新的目标,并继续迭代。
4. Hierarchical-DQN 的关键公式
Hierarchical-DQN 通过 Q-learning 来进行策略的学习和更新,其核心公式如下:
(1) 高层策略的 Q-learning 更新
高层策略使用 Q-learning 来选择最优目标 ,并通过环境的全局奖励更新其 Q 函数。高层策略的 Q 函数更新公式为:
其中:
- 是高层策略在时间步 的状态。
- 是高层策略选择的目标。
- 是环境的全局奖励。
- 是折扣因子,用于平衡短期和长期奖励。
- 是学习率。
- 是时间地平线,表示高层策略选择目标的时间跨度。
(2) 低层策略的 Q-learning 更新
低层策略使用 DQN 来学习在给定目标 下的最优动作。低层策略的 Q 函数更新公式为:
其中:
- 是低层策略在给定目标 时的 Q 值函数。
- 是低层策略的内在奖励,通常表示低层策略在当前时间步中是否朝着目标取得进展。
5. 内在奖励机制
与 FeUdal Networks 类似,Hierarchical-DQN 也采用了内在奖励机制来指导低层策略的学习。内在奖励 通常由目标和当前状态 之间的距离或差异来决定。
内在奖励的一种简单形式为:
其中:表示状态 与目标之间的距离,距离越小,奖励越大。
这样设计内在奖励机制有助于指导低层策略逐步朝着高层策略设定的目标方向前进。
[Python] Hierarchical-DQN 实现
Hierarchical-DQN 将强化学习任务分解为高层和低层的两个深度 Q 网络。高层网络负责设定子目标,低层网络执行具体动作,并根据这些子目标进行学习。通过分层结构,可以有效减少低层的动作空间,提升学习效率。
在 CartPole 环境中,我们可以定义两个层次:
- 高层(Manager):设定一个子目标(例如,平衡杆或保持杆在特定范围内)。
- 低层(Worker):根据高层的子目标选择具体动作(向左或向右移动)。
🔥若是下面代码复现困难或者有问题,欢迎评论区留言;需要以整个项目形式的代码,请在评论区留下您的邮箱📌,以便于及时分享给您(私信难以及时回复)。
算法训练代码
"""《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)
[Notice] 说明:
- 高层网络(High-Level Network):通过输入状态来选择目标(例如:保持平衡、移动到特定区域)。
- 低层网络(Low-Level Network):根据状态和高层提供的目标来执行具体的动作(例如:移动杆向左或向右)。
- 高层与低层的交互:高层负责设定长远目标,并每隔若干步更新一次;低层根据目标进行短期动作选择并更新 Q 值。
训练与测试:
- 训练:在
train
方法中,高层每隔一定步数设定目标,低层则持续执行动作,并学习对应的策略。 - 测试:在
test_hdqn_agent
方法中,使用训练好的模型对智能体进行测试,并显示动画。
由于博文主要为了介绍相关算法的原理和应用的方法,缺乏对于实际效果的关注,算法可能在上述环境中的效果不佳,一是算法不适配上述环境,二是算法未调参和优化,三是等等。上述代码用于了解和学习算法足够了,但若是想直接将上面代码应用于实际项目中,还需要进行修改。
6. Hierarchical-DQN 的优点与挑战
(1) 优点:
- 分层结构提升学习效率:通过将任务分解为多个层次,Hierarchical-DQN 能够更有效地处理长时间跨度的任务,并减少学习的难度。
- 内在奖励机制缓解稀疏奖励问题:低层策略通过内在奖励进行优化,解决了全局环境奖励稀疏时的学习困难。
- 任务分解可解释性强:高层策略设定的目标可以通过直观的方式理解,增强了算法的可解释性。
(2) 挑战:
- 目标空间设计难度:如何合理设计高层策略的目标集合是一个挑战,特别是在任务本身没有明显分解结构时。
- 子任务的依赖问题:低层策略可能依赖高层策略设定的目标,如何处理多个目标之间的冲突或依赖关系需要精心设计。
7. Hierarchical-DQN 的应用场景
Hierarchical-DQN 适用于需要解决长时间跨度、多步决策任务的场景,如:
- 机器人导航:例如机器人需要在复杂环境中进行路径规划,分层结构可以让高层策略决定目标位置,而低层策略负责执行局部导航。
- 复杂游戏策略:在视频游戏中,角色可能需要长时间制定策略,层次结构能够帮助角色进行长期和短期的策略决策。
- 稀疏奖励任务:对于那些环境中全局奖励非常稀疏的任务,通过内在奖励机制可以显著加速学习。
8.总结
Hierarchical-DQN算法结合了层次化强化学习的思想和深度 Q 网络,提出了一种将任务分解为高层策略和低层策略的层次结构,并通过内在奖励机制来增强学习效率。论文中详细介绍了 Hierarchical-DQN 的结构、机制和实验结果。
🔥想了解更多分层强化学习的文章,请查看文章:
文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者关注VX公众号:Rain21321,联系作者。✨
更多推荐
所有评论(0)