在这篇文章中,我将使用一个简单的示例来帮助您理解 Q-learning 并回答以下问题:
- 什么是TD(λ) 以及如何使用它?
- Q-learning的经典off-policy ****方法是如何工作的?
- Q-learning 的Python实现是什么样的?
时间差异学习:TD(λ)
在我的上一篇文章中,我们提到如果 我们将MC 更新公式中的Gt替换为估计回报 Rt+1+V(St+1), 我们可以得到TD(0) :
在哪里:
- Rt+1+V(St+1) 称为TD目标值
- Rt+1+V(St+1)- V(St) 称为TD误差
现在,我们用Gt()替换 TD 目标值,我们可以得到 TD(λ)。Gt() 生成如下:
所以TD(λ) 公式为:
其中:
如前所述,Q 学习是蒙特卡洛 (MC) 和时间差分 (TD) 学习的组合。有了第 5 部分介绍的MC 和TD(0) 以及现在我们掌握的TD(λ) ,我们终于准备好拿出大炮了!
Q学习
Q值公式:
从上面我们可以看出Q-learning是直接从TD(0) 推导出来的。对于每个更新的步骤,Q-learning 采用贪心的方法:maxaQ (St+1, a)。
这是 Q-learning 和另一种基于 TD 的方法 Sarsa 之间的主要区别,我不会在本系列中解释。但是作为 RL 学习者,你应该知道 Q-learning 并不是唯一基于 TD 的方法。
Q-Learning 如何工作的一个例子
让我们尝试通过一个例子更好地理解这一点:
您正在一家意大利餐厅与朋友共进晚餐,因为您以前来过这里一两次,他们希望您点餐。根据经验,您知道 Margherita 比萨饼和意大利肉酱面很美味。所以如果你必须点十道菜,经验可能会告诉你每道菜点五道菜。但是菜单上的其他东西呢?
在这个场景中,你就像我们的“代理”,负责寻找十种菜肴的最佳组合。想象一下这变成了每周一次的晚餐;您可能会开始带笔记本来记录每道菜的信息。在 Q 学习中,代理在Q 表中收集 Q 值。对于餐厅菜单,您可以将这些值视为每道菜的分数。
现在假设您的派对第三次回到餐厅。现在您的笔记本中已经有了一些信息,但您肯定还没有探索整个菜单。你如何决定从你的笔记中点多少道菜——你知道哪些菜是好的,以及要尝试多少道新菜?
这就是ε-greedy发挥作用的地方。
ε-贪心探索策略
在上面的例子中,餐厅里发生的事情就像我们的 MDP马尔可夫决策过程,而你,作为我们的“代理人”,只有在你足够彻底地探索的情况下,才能成功地为你的聚会找到最佳的菜肴组合。
Q-Learning 也是如此:只有当代理足够彻底地探索 MDP 时,它才能工作。当然,这需要非常长的时间。您能想象您需要多少次回到餐厅才能尝试菜单上的每道菜的每一种组合吗?
这就是 Q-learning 使用ε-greedy policy的原因,即最高 Q 值的 ε 度“贪婪”和随机探索的1 - ε 度“贪婪”。
在训练 agent 的初始阶段,随机探索环境(即尝试菜单上的新事物)通常比固定行为模式(即订购你已经知道的好东西)更好,因为这是 agent 积累经验和填充的时候上Q表。
因此,通常从 ε 的高值开始,例如 1.0。这意味着代理将花费 100% 的时间探索(例如使用随机策略)而不是参考 Q 表。
从那里,ε 的值可以逐渐减小,使智能体对 Q 值更加贪婪。例如,如果我们将 ε 降至 0.9,则意味着代理将花费 90% 的时间根据 Q 表选择最佳策略,并花费 10% 的时间探索未知事物。
与完全贪心策略相比, ε-贪心策略的优势在于它始终不断地测试 MDP 的未知区域。即使目标策略看起来是最优的,算法也永远不会停止探索:它只会变得越来越好。
探索的功能多种多样,网上可以找到很多定义好的探索策略。请注意,并非所有探索策略都适用于离散和连续的动作空间。
Q-Learning 的 Python 实现
以下是 Q-learning 的实现方式:
将 numpy 导入为 np
# 问
q = np.matrix(np.zeros([6, 6]))
# 报酬
r = np.matrix([[-1, -1, -1, -1, 0, -1],
[-1, -1, -1, 0, -1, 100],
[-1, -1, -1, 0, -1, -1],
[-1, 0, 0, -1, 0, -1],
[ 0, -1, -1, 0, -1, 100],
[-1, 0, -1, -1, 0, 100]])
伽玛 = 0.8
epsilon = 0.4
# 主训练循环对于范围内的剧集(101):
# 随机初始状态
状态 = np.random.randint(0, 6)
# 如果不是最终状态
而(状态!= 5):
# 选择一个可能的动作
# 即使在随机情况下,我们也不能选择 r[state, action] = -1 的动作。
possible_actions = []
possible_q = []
对于范围 (6) 内的操作:
如果 r[state, action] >= 0:
possible_actions.append(动作)
possible_q.append(q[state, action])
# Step next state,这里我们使用epsilon-greedy算法。
动作 = -1
如果 np.random.random() < epsilon:
# 选择随机动作
action = possible_actions[np.random.randint(0,
len(possible_actions))]
别的:
# 贪婪的
动作 = possible_actions[np.argmax(possible_q)]
# 更新Q值
q[状态,动作] = r[状态,动作] + gamma * q[动作].max()
# 进入下一个状态
状态 = 动作
# 显示训练进度
如果第 10 集 == 0:
打印(” - - - - - - - - - - - - - - - - - - - - - - - - -")
print("训练集:%d" % 集)
打印(q)
如果迭代次数足够多,该算法将收敛到最佳 Q 值。这称为离策略 算法,因为正在训练的策略不是正在执行的策略。******
总之
Q-Learning是一种基于TD方法的off-policy算法。随着时间的推移,它会创建一个 Q 表,用于得出最优策略。为了学习该策略,代理必须探索。通常的方法是让代理遵循不同的随机策略,该策略在选择动作时最初会忽略 Q 表。
这就是今天的全部内容;你做到了!通过本文,我们完成了对 TD 的讨论,希望您从中获得以下基本知识:
- 时间差分学习:TD 目标值、TD 误差和 TD(y)
- Q-learning的Python实现
- 具有ε-greedy的 Q-learning 探索策略**
TD 和 Q-learning 在 RL 中非常重要,因为很多优化方法都源自它们。有双 Q 学习、深度 Q 学习等等。
最重要的是,还有一些其他方法——与 TD 和 Q-learning 截然不同——我们在本系列中还没有涉及,比如策略梯度 (PG)。