📢本篇文章是博主强化学习RL领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:
【强化学习】(13)---《分层强化学习:MAXQ分解算法》
分层强化学习:MAXQ分解算法
目录
1. MAXQ分解算法的核心思想
2. 任务层次结构(Task Hierarchy)
3. MAXQ值函数分解
4. MAXQ学习过程
[Python] MAXQ分解算法实现
主要步骤:
训练代码实现:
测试代码实现:
[Notice] 注意事项
5. 优点与挑战
6. MAXQ的应用场景
7.总结
MAXQ分解是一种用于分层强化学习(Hierarchical Reinforcement Learning, HRL)的算法,由Thomas G. Dietterich提出。该算法通过将复杂的任务分解成更小的子任务来简化问题,并利用这些子任务来构建更复杂的策略。
1. MAXQ分解算法的核心思想
MAXQ分解的主要思想是将一个复杂的Markov决策过程(MDP)分解成一系列嵌套的子MDP,以便更容易解决。MAXQ算法引入了一种分层的结构,将原始任务逐步分解为多个子任务,从而形成一个任务树(task hierarchy),并通过各个子任务的求解来最终解决整个任务。
2. 任务层次结构(Task Hierarchy)
在MAXQ分解算法中,任务被组织成一个分层结构,其中每一个节点都是一个子任务。任务层次结构的关键特征包括:
- 根任务(Root Task):这是整个任务的顶层,即原始的MDP问题。
- 子任务(Subtasks):根任务可以分解成一系列子任务,每个子任务又可以进一步分解成更小的子任务,直到最底层为不可再分的原子动作(Primitive Actions)。
- 子任务的目标:每个子任务都有一个特定的目标(Goal),即在某个状态下完成该子任务。
任务树中的每个子任务对应一个子MDP,包含其状态、动作和奖励结构。子任务的动作可以是原子动作(如“向前移动一步”),也可以是其他子任务(递归地分解)。
3. MAXQ值函数分解
MAXQ算法的核心是将值函数(Value Function)分解成一系列子任务的值函数。这种分解被称为“MAXQ值函数分解”,包括以下两个部分:
- Completion Function :表示在给定状态 s 下,执行子任务 a 的完成过程中所累积的期望奖励。
- Q函数:描述了在给定状态 s 下,不同子任务 a 的选择带来的期望回报。
公式表示为:
其中, 表示在状态 s 选择动作(子任务) a 的值。
4. MAXQ学习过程
MAXQ分解的学习过程是通过策略梯度或Q-learning等强化学习算法来进行的。学习过程包括以下几个步骤:
- 策略学习:对于每个子任务,学习其最优策略,使得完成该子任务的期望奖励最大化。
- 值函数更新:通过子任务的执行和奖励反馈来更新对应的值函数和完成函数。
- 分层执行:在执行过程中,首先选择顶层任务,然后递归地选择各个子任务,直到执行到原子动作。
[Python] MAXQ分解算法实现
在 CartPole 环境中使用 MAXQ 分解算法的 Python 实现。MAXQ 分解是分层强化学习的一种方法,它通过将任务分解为多个子任务,从而减少问题的复杂性,达到更高效的学习效果。具体来说,MAXQ 会将任务分解成多个层次的子任务,智能体会根据不同的子任务学习不同的策略。
🔥若是下面代码复现困难或者有问题,欢迎评论区留言;需要以整个项目形式的代码,请在评论区留下您的邮箱📌,以便于及时分享给您(私信难以及时回复)。
主要步骤:
- 设置 CartPole 环境。
- 定义 MAXQ 分解结构,将任务分解为子任务。
- 在各个子任务中分别学习Q值。
- 通过递归结构自上而下地选择动作,并利用低层策略解决高层问题。
- 通过Q值更新来优化分层结构中的各个任务。
训练代码实现:
"""《MAXQ分解算法实现》
时间:2024.10.03
环境:CartPole
作者:不去幼儿园
"""
import gym
import numpy as np
import random
# 定义超参数
GAMMA = 0.99
LEARNING_RATE = 0.1
EPSILON_DECAY = 0.995
MIN_EPSILON = 0.1
NUM_EPISODES = 500
# 定义 MAXQ 子任务节点
class MAXQNode:
def __init__(self, num_actions, is_primitive=False):
self.num_actions = num_actions
self.is_primitive = is_primitive # 是否为原子任务
self.q_values = {} # Q 值字典,(state, action) -> Q 值
def get_q(self, state, action):
state = tuple(state) # 将 state 转换为元组
if (state, action) not in self.q_values:
self.q_values[(state, action)] = 0.0 # 初始化 Q 值
return self.q_values[(state, action)]
def set_q(self, state, action, value):
state = tuple(state) # 将 state 转换为元组
self.q_values[(state, action)] = value
# 创建 MAXQ 分解的顶层任务
class MAXQTask:
def __init__(self, num_actions):
self.num_actions = num_actions
self.subtasks = []
self.root = MAXQNode(num_actions) # 顶层任务节点
def add_subtask(self, subtask):
self.subtasks.append(subtask)
# 定义智能体
class MAXQAgent:
def __init__(self, env):
self.env = env
self.epsilon = 1.0
self.maxq_root = MAXQTask(env.action_space.n) # CartPole 的动作数为 2
# 添加子任务
self.pickup_subtask = MAXQNode(env.action_space.n, is_primitive=True) # 装载任务
self.dropoff_subtask = MAXQNode(env.action_space.n, is_primitive=True) # 卸载任务
self.navigate_subtask = MAXQNode(env.action_space.n) # 导航任务
# 将子任务添加到根节点
self.maxq_root.add_subtask(self.pickup_subtask)
self.maxq_root.add_subtask(self.dropoff_subtask)
self.maxq_root.add_subtask(self.navigate_subtask)
def select_action(self, state, subtask, epsilon):
# ε-贪婪策略选择动作
if random.random() < epsilon:
return self.env.action_space.sample() # 探索
else:
q_values = [subtask.get_q(state, action) for action in range(subtask.num_actions)]
return np.argmax(q_values) # 利用当前策略
def update_q(self, state, subtask, action, reward, next_state):
# 确保传入的是 MAXQNode 而不是 MAXQTask
if not isinstance(subtask, MAXQNode):
subtask = subtask.root # 传入的是 MAXQTask,则使用其根节点
next_q_values = [subtask.get_q(next_state, a) for a in range(subtask.num_actions)]
max_next_q = max(next_q_values)
# Q 值更新
current_q = subtask.get_q(state, action)
new_q = current_q + LEARNING_RATE * (reward + GAMMA * max_next_q - current_q)
subtask.set_q(state, action, new_q)
def train(self, num_episodes):
for episode in range(num_episodes):
state,_ = self.env.reset()
done = False
total_reward = 0
while not done:
# 确保传递的是 MAXQNode
action = self.select_action(state, self.maxq_root.root, self.epsilon)
next_state, reward, done, _, __ = self.env.step(action)
# 这里传递的是 MAXQNode,而不是 MAXQTask
self.update_q(state, self.maxq_root.root, action, reward, next_state)
state = next_state
total_reward += reward
# 逐渐减少 epsilon 以减少探索
self.epsilon = max(MIN_EPSILON, self.epsilon * EPSILON_DECAY)
print(f"Episode {episode + 1}: Total Reward: {total_reward}")
# 创建 CartPole 环境并训练智能体
env = gym.make('CartPole-v1')
agent = MAXQAgent(env)
agent.train(NUM_EPISODES)
env.close()
测试代码实现:
[Notice] 注意事项
主要思路:
- MAXQNode 类定义了一个子任务。每个子任务都可以拥有自己的 Q 值,并且可以是一个原子任务或复合任务。
- MAXQTask 是根任务,它管理多个子任务。
- MAXQAgent 使用 MAXQ 分解结构来训练智能体。每个状态下会通过 MAXQ 的结构选择动作,并递归调用子任务的策略。
代码解读:
- MAXQ 分解:任务被分解为多个层次的子任务。在这里,假设有两个子任务:保持平衡和终止任务。终止任务是一个原子任务,即在某些条件下智能体选择终止,而不是继续执行其他任务。
- Q 值更新:基于每个子任务的动作和状态,更新对应的 Q 值。
运行提示:
此代码将 MAXQ 分解方法应用于 CartPole 环境。该方法通过分层强化学习的方式来解决问题。您可以通过调整超参数(如 LEARNING_RATE
和 GAMMA
)来进一步优化结果。
优化建议:
- 增加训练回合数:Taxi Domain 是一个复杂环境,可能需要较长的训练时间来收敛。
- 调节 ε-greedy 策略:可以加快 ε 的衰减速度,以减少后期训练中的探索。
- 优化子任务分解:可以进一步细化任务分解,增加中间子任务以加快训练过程。
由于博文主要为了介绍相关算法的原理和应用的方法,缺乏对于实际效果的关注,算法可能在上述环境中的效果不佳,一是算法不适配上述环境,二是算法未调参和优化,三是等。上述代码用于了解和学习算法足够了,但若是想直接将上面代码应用于实际项目中,还需要进行修改。
5. 优点与挑战
优点
- 分解问题复杂度:通过将复杂的任务分解成子任务,减少了原问题的复杂度。
- 复用子任务:相同的子任务可以被多个父任务复用,从而提高学习效率。
- 减少探索空间:分层结构使得每个子任务只需探索自己相关的状态空间,减小了整体的搜索空间。
挑战
- 任务分解:如何将复杂的任务合理地分解成子任务仍然是一个挑战性问题。
- 子任务依赖:在某些情况下,不同子任务之间可能存在复杂的依赖关系,处理这些依赖关系需要更加复杂的策略设计。
6. MAXQ的应用场景
MAXQ分解算法适用于需要分解和递归解决的问题,如:
- 多阶段决策过程,例如机器人路径规划、复杂游戏策略。
- 任务中存在天然的分解结构,或者通过人工设计可以合理分解的任务。
7.总结
MAXQ算法提供了一种分层强化学习的方法,可以显著简化复杂任务的求解过程,并利用层次结构来提高学习的效率和策略的可解释性。
参考文献: Hierarchical Reinforcement Learning with the MAXQ Value Function Decomposition
文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者添加VX公众号:Rainbook_2,联系作者。✨
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)