5.6 Q-learning在FrozenLake中的应用
整个示例在Chapter05/02_frozenlake_q_iteration.py
文件中,两者之间的差别很小。最明显的变化是价值表。在前面的示例中,我们保留了状态价值,因此字典中的键只有状态。现在,我们需要存储Q函数的值,该函数具有两个参数:状态和动作,因此价值表中的键现在是组合键。
第二个区别是有无calc_action_value()
函数。我们不再需要它了,因为动作价值存储在价值表中。
最后,代码中最重要的变化是智能体的value_iteration()
方法。以前,它只是对calc_action_value()
调用的包装,完成了Bellman近似工作。现在,由于该函数已被价值表取代,因此我们需要在value_iteration()
方法中进行此近似处理。
我们来看代码。它们几乎一样,因此直接跳到最有趣的value_iteration()
函数:
该代码与上一个示例中的calc_action_value()
非常相似,实际上,它们的作用也几乎相同。对于给定的状态和动作,它需要通过某动作达到目标状态的统计信息来计算动作的价值。为了计算该价值,我们使用Bellman方程和计数器,这些计数器让我们能够估计目标状态的概率。然而,根据Bellman方程,可以计算状态的价值。现在,我们需要用不同的方法进行计算。
之前,我们将其存储在价值表中(因为我们近似了状态的价值),因此只需从该表中读取它。我们不能再这样做了,因此需要调用select_action
方法,该方法可以选择具有最大Q值的动作,然后我们将这个Q值用作目标状态的价值。当然,也可以实现另一个函数来计算状态价值,但是select_action
几乎完成了我们需要的所有功能,因此在此处重用它即可。
在此想强调这个示例的另一部分。我们来看select_action
方法:
就像我说的那样,我们不再有calc_action_value
方法,因此,要选择动作只需遍历这些动作并在价值表中查找它们的价值即可。这看起来似乎是一个较小的改进,但是如果考虑到在calc_action_value
中所用的数据,就可以明显感受到为什么在RL中Q函数学习比V函数学习更受欢迎。
calc_action_value
函数同时使用了奖励和概率信息。对于价值迭代方法而言,这不是一个大问题,它在训练过程中依赖于此信息。但是,下一章中将学习价值迭代方法的扩展,它不需要概率近似,而是从环境样本中直接获取。对于此类方法,这种对概率的依赖性会增加智能体的负担。而在Q-learning中,智能体只依赖Q值做决定。
我不想说V函数是完全无用的,因为它是actor-critic方法(将在本书第三部分中对其进行讨论)的重要组成部分。但是,在价值学习领域,Q函数无疑是最受欢迎的。关于收敛速度,两个版本几乎相同(但是Q-learning版本的价值表需要四倍的内存)。