前面提到过,有一个由状态 s 描述的环境(s∈S,S 是所有可能状态的集合),一个能够执行动作 a 的 agent(a∈A,A 是所有可能动作的集合),智能体的动作致使智能体从一个状态转移到另外一个状态。智能体的行为会得到奖励,而智能体的目标就是最大化奖励。
在 Q learning 中,智能体计算能够最大化奖励 R 的状态-动作组合,以此学习要采取的动作(策略 π),在选择动作时,智能体不仅要考虑当前的奖励,还要尽量考虑未来的奖励:
智能体从任意初始状态 Q 开始,选择一个动作 a 并得到奖励 r,然后更新状态为 s'(主要受过去的状态 s 和动作 a 的影响),新的 Q 值为:
其中,α 是学习率,γ 是折扣因子。第一项保留 Q 的旧值,第二项对 Q 值进行更新估计(包括当前奖励和未来动作的折扣奖励),这会导致在结果状态不满意时降低 Q 值,从而确保智能体在下一次处于此状态时不会选择相同的动作。类似地,当对当前状态满意时,对应的 Q 值将增加。
Q learning 的最简单实现包括维护和更新一个状态-动作值的对应表,表格大小为 N×M,其中 N 是所有可能状态的数量,M 是所有可能动作的数量。对于大多数环境来说,这个表格会相当大,表格越大,搜索所需的时间越长,存储表格所需的内存越多,因此该方案并不可行。
本节将使用 Q learning 的 NN 实现,神经网络被用作函数逼近器来预测值函数(Q),NN的输出节点等于可能动作的数量,它们的输出表示相应动作的值函数。
本节将训练一个线性神经网络来实践 CartPole-v0 环境,目标是平衡小车上的杆子,观测状态由 4 个连续的参数组成:推车位置 [-2.4,2.4],车速 [-∞,∞],杆子角度 [~-41.8°,~41.8°] 与杆子末端速度 [-∞,∞]。
通过向左或向右推车能够实现平衡,所以动作空间由两个动作组成,下图就是 CartPole-v0 环境空间:
对于 Q learning,需要找到一种方法来量化连续的观测状态值。这里使用 FeatureTransformer 类来实现,首先生成观测空间中的 20000 个随机样本,然后用 scikit 的 StandardScaler 类将样本标准化,RBFSampler 用不同的方差来覆盖观测空间不同的部分。FeatureTransformer 类是用随机的观测空间样本实例化的,然后用 fit_transform 函数训练 RBFSampler。
上述过程执行结束之后,调用 transform 方法将连续观测空间转换为特征表示:
相同的逻辑可以用于在其他 OpenAI 环境中构建的智能体上,然而,对于像 Breakout 和 Pac-Man 这样的 Atari 游戏来说,观测空间并不是一个只有四个数字的数组。相反,它非常大(210×160=33600 像素,3 个 RGB 通道),没有一定形式的量化,可能的状态是无限的,用简单的神经网络不会产生好结果,在深度 Q learning 章节中使用 CNN 来解决这个问题。