Files
easy-rl/docs/chapter3/chapter3.md
2020-10-22 19:43:43 +08:00

29 KiB
Raw Blame History

Tabular Methods

这节课我们通过最简单的表格型的方法(tabular methods)来讲解如何使用 value-based 方法去求解强化学习。

MDP

**强化学习的三个重要的要素:状态、动作和奖励。**强化学习智能体跟环境是一步一步交互的,就是我先观察一下状态,然后再输入动作。再观察一下状态,再输出动作,拿到这些 reward 。它是一个跟时间相关的序列决策的问题。

举个例子,在 t-1 时刻,我看到了熊对我招手,那我下意识的可能输出的动作就是赶紧跑路。熊看到了有人跑了,可能就觉得发现猎物,开始发动攻击。而在 t 时刻的话,我如果选择装死的动作,可能熊咬了咬我,摔了几下就发现就觉得挺无趣的,可能会走开。这个时候,我再跑路的话可能就跑路成功了,就是这样子的一个序列决策的过程。

当然在输出每一个动作之前,你可以选择不同的动作。比如说在 t 时刻,我选择跑路的时候,熊已经追上来了,如果说 t 时刻,我没有选择装死,而我是选择跑路的话,这个时候熊已经追上了,那这个时候,其实我有两种情况转移到不同的状态去,就我有一定的概率可以逃跑成功,也有很大的概率我会逃跑失败。那我们就用状态转移概率 p\left[s_{t+1}, r_{t} \mid s_{t}, a_{t}\right] 来表述说在 s_t 的状态选择了 a_t 的动作的时候,转移到 s_{t+1} ,而且拿到 r_t 的概率是多少。

这样子的一个状态转移概率是具有马尔可夫性质的(系统下一时刻的状态仅由当前时刻的状态决定,不依赖于以往任何状态)。因为这个状态转移概率,它是下一时刻的状态是取决于当前的状态,它和之前的 s_{t-1}s_{t-2} 都没有什么关系。然后再加上说这个过程也取决于智能体跟环境交互的这个a_t ,所以有一个决策的一个过程在里面。我们就称这样的一个过程为马尔可夫决策过程(Markov Decision Process, MDP)

MDP 就是序列决策这样一个经典的表达方式。MDP 也是强化学习里面一个非常基本的学习框架。状态、动作、状态转移概率和奖励 $(S,A,P,R)$,这四个合集就构成了强化学习 MDP 的四元组,后面也可能会再加个衰减因子构成五元组。

如上图所示,我们把这些可能的动作和可能的状态转移的关系画成一个树状图。它们之间的关系就是从 s_ta_t ,再到 s_{t+1} ,再到 $a_{t+1}$,再到 s_{t+2} 这样子的一个过程。

我们去跟环境交互,只能走完整的一条通路。这里面产生了一系列的一个决策的过程,就是我们跟环境交互产生了一个经验。我们会使用 P 函数(probability function)R 函数(reward function)来去描述环境。P 函数就是状态转移的概率P 函数实际上反映的是环境的一个随机性。

比如,在熊发怒的情况下,我如果选择装死,假设熊看到人装死就一定会走的话,我们就称在这里面的状态转移概率就是 100%。但如果说在熊发怒的情况下,我选择跑路而导致可能跑成功以及跑失败,出现这两种情况。那我们就可以用概率去表达一下说转移到其中一种情况的概率大概 10%,另外一种情况的概率大概是 90% 会跑失败。

**如果知道这些状态转移概率和奖励函数的话,我们就说这个环境是已知的,因为我们是用这两个函数去描述环境的。**如果是已知的话,我们其实可以用动态规划去计算说,如果要逃脱熊,那么能够逃脱熊概率最大的最优策略是什么。很多强化学习的经典算法都是 model-free 的,就是环境是未知的。

因为现实世界中人类第一次遇到熊之前,我们根本不知道能不能跑得过熊,所以刚刚那个 10%、90% 的概率也就是虚构出来的概率。熊到底在什么时候会往什么方向去转变的话,我们经常是不知道的。我们是处在一个未知的环境里的,也就是这一系列的决策的 P 函数和 R 函数是未知的,这就是 model-based 跟 model-free 的一个最大的区别。强化学习就是可以用来解决用完全未知的和随机的环境。

强化学习要像人类一样去学习,人类学习的话就是一条路一条路地去尝试一下,先走一条路,看看结果到底是什么。多试几次,只要能活命的。我们可以慢慢地了解哪个状态会更好,

  • 我们用价值函数 V(s) 来代表这个状态是好的还是坏的。
  • 然后用 Q 函数来判断说在什么状态下做什么动作能够拿到最大奖励,用 Q 函数来表示这个状态-动作值。

Q-table

接下来就会介绍 Q 函数。在多次尝试和熊打交道之后,人类就可以对熊的不同的状态去做出判断,我们可以用状态动作价值来表达说在某个状态下,为什么动作 1 会比动作 2 好,因为动作 1 的价值比动作 2 要高,这个价值就叫 Q 函数

**如果 Q 表格是一张已经训练好的表格的话,那这一张表格就像是一本生活手册。**我们就知道在熊发怒的时候,装死的价值会高一点。在熊离开的时候,我们可能偷偷逃跑的会比较容易获救。

这张表格里面 Q 函数的意义就是我选择了这个动作之后,最后面能不能成功,就是我需要去计算在这个状态下,我选择了这个动作,后续能够一共拿到多少总收益。如果可以预估未来的总收益的大小,我们当然知道在当前的这个状态下选择哪个动作,价值更高。我选择某个动作是因为我未来可以拿到的那个价值会更高一点。所以强化学习的目标导向性很强,环境给出的 reward 是一个非常重要的反馈,它就是根据环境的 reward 来去做选择。

Q: 为什么可以用未来的总收益来评价当前这个动作是好是坏?

A: 举个例子,假设一辆车在路上,当前是红灯,我们直接走的收益就很低,因为违反交通规则,这就是当前的单步收益。可是如果我们这是一辆救护车,我们正在运送病人,把病人快速送达医院的收益非常的高,而且越快你的收益越大。在这种情况下,我们很可能应该要闯红灯,因为未来的远期收益太高了。这也是为什么强化学习需要去学习远期的收益,因为在现实世界中奖励往往是延迟的,是有 delay 的。所以我们一般会从当前状态开始,把后续有可能会收到所有收益加起来计算当前动作的 Q 的价值,让 Q 的价值可以真正地代表当前这个状态下,动作的真正的价值。

但有的时候你把目光放得太长远不好,因为如果事情很快就结束的话,你考虑到最后一步的收益无可厚非。如果是一个持续的没有尽头的任务,即持续式任务(Continuing Task),你把未来的收益全部相加,作为当前的状态价值就很不合理。股票的例子就很典型了,我们要关注的是累积的收益。可是如果说十年之后才有一次大涨大跌,你显然不会把十年后的收益也作为当前动作的考虑因素。那我们会怎么办呢,有句俗话说得好,对远一点的东西,我们就当做近视,就不需要看得太清楚,我们可以引入这个衰减因子 \gamma 来去计算这个未来总收益,$\gamma \in [0,1]$,越往后 \gamma^n 就会越小,也就是说越后面的收益对当前价值的影响就会越小。

举个例子来看看计算出来的是什么效果。这是一个悬崖问题,这个问题是需要智能体从出发点 S 出发,到达目的地 G同时避免掉进悬崖(cliff),掉进悬崖的话就会有负一百分的惩罚,但游戏不会结束,它会被直接拖回起点,游戏继续。为了到达目的地的话,我们可以沿着蓝线和红线走。

在这个环境当中,我们怎么去计算状态动作价值(未来的总收益)。

  • 如果 $\gamma = 0$ 假设我走一条路,并从这个状态出发,在这里选择是向上,这里选择向右。如果 $\gamma = 0$,用这个公式去计算的话,它相当于考虑的就是一个单步的收益。我们可以认为它是一个目光短浅的计算的方法。

  • 如果 $\gamma = 1$,那就等于是说把后续所有的收益都全部加起来。在这里悬崖问题,你每走一步都会拿到一个 -1 分的 reward只有到了终点之后它才会停止。如果 \gamma =1 的话,我们用这个公式去计算,就这里是 -1。然后这里的话未来的总收益就是 -1+-1=-2

  • 如果 $\gamma = 0.6$,就是目光没有放得那么的长远,计算出来是这个样子的。利用 G_{t}=R_{t+1}+\gamma G_{t+1} 这个公式从后往前推。


\begin{array}{l}
G_{7}=R+\gamma G_{8}=-1+0.6 *(-2.176)=-2.3056 \approx-2.3 \\
G_{8}=R+\gamma G_{9}=-1+0.6 *(-1.96)=-2.176 \approx-2.18 \\
G_{9}=R+\gamma G_{10}=-1+0.6 *(-1.6)=-1.96 \\
G_{10}=R+\gamma G_{11}=-1+0.6 *(-1)=-1.6 \\
G_{12}=R+\gamma G_{13}=-1+0.6 * 0=-1 \\
G_{13}=0
\end{array}

这里的计算是我们选择了一条路,计算出这条路径上每一个状态动作的价值。我们可以看一下右下角这个图,如果说我走的不是红色的路,而是蓝色的路,那我算出来的 Q 值可能是这样。那我们就知道,当小乌龟在 -12 这个点的时候,往右边走是 -11往上走是 -15它自然就知道往右走的价值更大小乌龟就会往右走。

类似于上图,最后我们要求解的就是一张 Q 表格,

  • 它的行数是所有的状态数量,一般可以用坐标来表示表示格子的状态,也可以用 1、2、3、4、5、6、7 来表示不同的位置。
  • Q 表格的列表示上下左右四个动作。

最开始这张 Q 表格会全部初始化为零,然后 agent 会不断地去和环境交互得到不同的轨迹,当交互的次数足够多的时候,我们就可以估算出每一个状态下,每个行动的平均总收益去更新这个 Q 表格。怎么去更新 Q 表格就是接下来要引入的强化概念。

**强化就是我们可以用下一个状态的价值来更新当前状态的价值,其实就是强化学习里面 bootstrapping 的概念。**在强化学习里面,你可以每走一步更新一下 Q 表格,然后用下一个状态的 Q 值来更新这个状态的 Q 值,这种单步更新的方法叫做时序差分

Temporal Difference

**为了让大家更好地理解时序差分这种更新方法,这边给出它的物理意义。**我们先理解一下巴普洛夫的条件反射实验,这个实验讲的是小狗会对盆里面的食物无条件产生刺激,分泌唾液。一开始小狗对于铃声这种中性刺激是没有反应的,可是我们把这个铃声和食物结合起来,每次先给它响一下铃,再给它喂食物,多次重复之后,当铃声响起的时候,小狗也会开始流口水。盆里的肉可以认为是强化学习里面那个延迟的 reward声音的刺激可以认为是有 reward 的那个状态之前的一个状态。多次重复实验之后,最后的这个 reward 会强化小狗对于这个声音的条件反射,它会让小狗知道这个声音代表着有食物,这个声音对于小狗来说也就有了价值,它听到这个声音也会流口水。

巴普洛夫效应揭示的是中性刺激(铃声)跟无条件刺激(食物)紧紧挨着反复出现的时候,条件刺激也可以引起无条件刺激引起的唾液分泌,然后形成这个条件刺激。这种中性刺激跟无条件刺激在时间上面的结合,我们就称之为强化。 强化的次数越多,条件反射就会越巩固。小狗本来不觉得铃声有价值的,经过强化之后,小狗就会慢慢地意识到铃声也是有价值的,它可能带来食物。更重要是一种条件反射巩固之后,我们再用另外一种新的刺激和条件反射去结合,还可以形成第二级条件反射,同样地还可以形成第三级条件反射。

在人的身上是可以建立多级的条件反射的,举个例子,比如说一般我们遇到熊都是这样一个顺序,看到树上有熊爪,然后看到熊之后,突然熊发怒,扑过来了。经历这个过程之后,我们可能最开始看到熊才会瑟瑟发抖,后面就是看到树上有熊爪就已经有害怕的感觉了。也就说在不断的重复试验之后,下一个状态的价值,它是可以不断地去强化影响上一个状态的价值的。

为了让大家更加直观感受下一个状态影响上一个状态,我们再次推荐这个网站:Temporal Difference Learning Gridworld Demo

我们先初始化一下,然后开始时序差分的更新过程。在训练的过程中,你会看到这个小黄球在不断地试错,在探索当中会先迅速地发现有 reward 的地方。最开始的时候,只是这些有 reward 的格子 才有价值。当不断地重复走这些路线的时候,这些有价值的格子可以去慢慢地影响它附近的格子的价值。反复训练之后,有 reward 的这些格子周围的格子的状态就会慢慢地被强化,强化就是当它收敛到最后一个最优的状态了,就是把这些价值最终收敛到一个最优的情况之后,那个小黄球就会自动地知道,就是我一直往价值高的地方走,就能够走到能够拿到 reward 的地方。

如上图所示,这种强化方式可以用一行公式来表示,这种更新的方式叫做时序差分(Temporal Difference)。这个公式就是说可以拿下一步的 Q 值 Q(S_{t+_1},A_{t+1}) 来更新我这一步的 Q 值 Q(S_t,A_t)

为了理解这个公式,如上图所示,我们先把 R_{t+1}+\gamma Q\left(S_{t+1}, A_{t+1}\right.) 当作是一个目标值,就是 Q(S_t,A_t) 想要去逼近的一个目标值。我们想要计算的就是 Q(S_t,A_t)因为最开始 Q 值都是随机初始化或者是初始化为零,它需要不断地去逼近它理想中真实的 Q 值,我们就叫 target 。Target 就是带衰减的未来收益的总和。

我们用 G_t 来表示未来收益总和(return),并且对它做一下数学变化:


\begin{aligned}
G_{t} &=R_{t+1}+\gamma R_{t+2}+\gamma^{2} R_{t+3}+\gamma^{3} R_{t+4}+\cdots \\
&=R_{t+1}+\gamma\left(R_{t+2}+\gamma R_{t+3}+\gamma^{2} R_{t+4}+\cdots\right) \\
&=R_{t+1}+\gamma G_{t+1}
\end{aligned}

就可以知道 $G_t = R_{t+1}+ \gamma G_{t+1}$。

也就是说,我们拿 Q(S_t,A_t) 来逼近 $G_t$,那 Q(S_{t+1},A_{t+1}) 其实就是近似 $G_{t+1}$。我就可以用 Q(S_{t+1},A_{t+1}) 近似 $G_{t+1}$,然后把 R_{t+1}+Q(S_{t+1},A_{t+1}) 当成目标值。

Q(S_t,A_t) 就是要逼近这个目标值,我们用软更新的方式来逼近。软更新的方式就是每次我只更新一点点,\alpha 有点类似于学习率。最终的话Q 值都是可以慢慢地逼近到真实的 target 值。这样我们的更新公式只需要用到当前时刻的 $S_{t},A_t$,还有拿到的 R_{t+1}, S_{t+1}A_{t+1}

该算法由于每次更新值函数需要知道当前的状态(state)、当前的动作(action)、奖励(reward)、下一步的状态(state)、下一步的动作(action),即 (S_{t}, A_{t}, R_{t+1}, S_{t+1}, A_{t+1}) 这几个值 ,由此得名 Sarsa 算法。它走了一步之后,拿到了 (S_{t}, A_{t}, R_{t+1}, S_{t+1}, A_{t+1}) 之后,就可以做一次更新。

我们看看用代码去怎么去实现。了解单步更新的一个基本公式之后,代码实现就很简单了。右边是环境,左边是 agent 。我们每次跟环境交互一次之后呢,就可以 learn 一下,向环境输出 action然后从环境当中拿到 state 和 reward。Agent 主要实现两个方法:

  • 一个就是根据 Q 表格去选择动作,输出 action。
  • 另外一个就是拿到 (S_{t}, A_{t}, R_{t+1}, S_{t+1}, A_{t+1}) 这几个值去更新我们的 Q 表格。

Sarsa: On-policy TD Control

我们直接看这个框框里面的更新公式, 和之前的公式是一模一样的。S' 就是 S_{t+1} 。我们就是拿下一步的 Q 值 Q(S',A') 来更新这一步的 Q 值 $Q(S,A)$,不断地强化每一个 Q。

Q-learning: Off-policy TD Control

Sarsa 是一种 on-policy 策略。Sarsa 优化的是它实际执行的策略,它直接拿下一步会执行的 action 来去优化 Q 表格,所以 on-policy 在学习的过程中,只存在一种策略,它用一种策略去做 action 的选取,也用一种策略去做优化。所以 Sarsa 知道它下一步的动作有可能会跑到悬崖那边去,所以它就会在优化它自己的策略的时候,会尽可能的离悬崖远一点。这样子就会保证说,它下一步哪怕是有随机动作,它也还是在安全区域内。

而 off-policy 在学习的过程中,有两种不同的策略:

  • 第一个策略是我们需要去学习的策略,即target policy(目标策略),一般用 \pi 来表示Target policy 就像是在后方指挥战术的一个军师,它可以根据自己的经验来学习最优的策略,不需要去和环境交互。
  • 另外一个策略是探索环境的策略,即behavior policy(行为策略),一般用 \mu 来表示。\mu 可以大胆地去探索到所有可能的轨迹,采集轨迹,采集数据,然后把采集到的数据喂给 target policy 去学习。而且喂给目标策略的数据中并不需要 A_{t+1} ,而 Sarsa 是要有 A_{t+1} 的。Behavior policy 像是一个战士可以在环境里面探索所有的动作、轨迹和经验然后把这些经验交给目标策略去学习。比如目标策略优化的时候Q-learning 才不管你下一步去往哪里探索,会不会掉进悬崖,我就只选我收益最大一个最优的策略。

再举个例子。比如环境是一个波涛汹涌的大海,但 learning policy 太胆小了,没法直接跟环境去学习,所以我们有了 exploratory policyexploratory policy 是一个不畏风浪的海盗,他非常激进,可以在环境中探索。他有很多经验,可以把这些经验写成稿子,然后喂给这个 learning policy。Learning policy 可以通过这个稿子来进行学习。

在 off-policy learning 的过程中,我们这些轨迹都是 behavior policy 跟环境交互产生的,产生这些轨迹后,我们使用这些轨迹来更新 target policy $\pi$。

Off-policy learning 有很多好处:

  • 我们可以利用 exploratory policy 来学到一个最佳的策略,学习效率高;
  • 可以让我们学习其他 agent 的行为,模仿学习,学习人或者其他 agent 产生的轨迹;
  • 重用老的策略产生的轨迹。探索过程需要很多计算资源,这样的话,可以节省资源。

Q-learning 的算法有两种 policybehavior policy 和 target policy。

Target policy \pi 直接在 Q-table 上取 greedy就取它下一步能得到的所有状态如下式所示


\pi\left(S_{t+1}\right)=\underset{a^{\prime}}{\arg \max}~ Q\left(S_{t+1}, a^{\prime}\right)

Behavior policy \mu 可以是一个随机的 policy但我们采取 $\varepsilon\text{-greedy}$,让 behavior policy 不至于是完全随机的,它是基于 Q-table 逐渐改进的。

\varepsilon\text{-greedy} 的意思是说,我们有 1-\varepsilon 的概率会按照 Q-function 来决定 action通常 \varepsilon 就设一个很小的值, 1-\varepsilon 可能是 90%,也就是 90% 的概率会按照 Q-function 来决定 action但是你有 10% 的机率是随机的。通常在实现上 \varepsilon 会随着时间递减。在最开始的时候。因为还不知道那个 action 是比较好的,所以你会花比较大的力气在做 exploration。接下来随着 training 的次数越来越多。已经比较确定说哪一个 Q 是比较好的。你就会减少你的 exploration你会把 \varepsilon 的值变小,主要根据 Q-function 来决定你的 action比较少做 random这是 $\varepsilon\text{-greedy}$。

我们可以构造 Q-learning targetQ-learning 的 next action 都是通过 arg max 操作来选出来的,于是我们可以代入 arg max 操作,可以得到下式:


\begin{aligned}
R_{t+1}+\gamma Q\left(S_{t+1}, A^{\prime}\right) &=R_{t+1}+\gamma Q\left(S_{t+1},\arg \max ~Q\left(S_{t+1}, a^{\prime}\right)\right) \\
&=R_{t+1}+\gamma \max _{a^{\prime}} Q\left(S_{t+1}, a^{\prime}\right)
\end{aligned}

接着我们可以把 Q-learning update 写成 incremental learning 的形式TD target 就变成 max 的值,即


Q\left(S_{t}, A_{t}\right) \leftarrow Q\left(S_{t}, A_{t}\right)+\alpha\left[R_{t+1}+\gamma \max _{a} Q\left(S_{t+1}, a\right)-Q\left(S_{t}, A_{t}\right)\right]

我们再通过对比的方式来进一步理解 Q-learning。Q-learning 是 off-policy 的时序差分学习方法Sarsa 是 on-policy 的时序差分学习方法。

  • Sarsa 在更新 Q 表格的时候,它用到的 A' 。我要获取下一个 Q 值的时候A' 是下一个 step 一定会执行的 action。这个 action 有可能是 $\varepsilon$-greedy 方法 sample 出来的值,也有可能是 max Q 对应的 action也有可能是随机动作但这是它实际执行的那个动作。
  • 但是 Q-learning 在更新 Q 表格的时候,它用到这个的 Q 值 Q(S',a) 对应的那个 action ,它不一定是下一个 step 会执行的实际的 action因为你下一个实际会执行的那个 action 可能会探索。
  • Q-learning 默认的 next action 不是通过 behavior policy 来选取的Q-learning 直接看 Q-table取它的 max 的这个值,它是默认 A' 为最优策略选的动作,所以 Q-learning 在学习的时候,不需要传入 A',即 A_{t+1} 的值。

事实上Q-learning 算法被提出的时间更早Sarsa 算法是 Q-learning 算法的改进。

Sarsa 和 Q-learning 的更新公式都是一样的,区别只在 target 计算的这一部分,

  • Sarsa 是 R_{t+1}+\gamma Q(S_{t+1}, A_{t+1})
  • Q-learning 是 R_{t+1}+\gamma \underset{a}{\max} Q\left(S_{t+1}, a\right)

Sarsa 是用自己的策略产生了 S,A,R,S',A' 这一条轨迹。然后拿着 Q(S_{t+1},A_{t+1}) 去更新原本的 Q 值 $Q(S_t,A_t)$。

但是 Q-learning 并不需要知道我实际上选择哪一个 action ,它默认下一个动作就是 Q 最大的那个动作。Q-learning 知道实际上 behavior policy 可能会有 10% 的概率去选择别的动作,但 Q-learning 并不担心受到探索的影响,它默认了就按照最优的策略来去优化目标策略,所以它可以更大胆地去寻找最优的路径,它会表现得比 Sarsa 大胆非常多。

对 Q-learning 进行逐步地拆解的话,跟 Sarsa 唯一一点不一样就是并不需要提前知道 A_2 ,我就能更新 Q(S_1,A_1) 。在训练一个 episode 这个流程图当中Q-learning 在 learn 之前它也不需要去拿到 next action $A',它只需要前面四个 (S,A,R,S')$ ,这跟 Sarsa 很不一样。

Q-function Bellman Equation

记策略 \pi 的状态-动作值函数为 $Q^{\pi}(s_t,a_t)$,它表示在状态 s_t 下,执行动作 a_t 会带来的累积奖励 G_t 的期望,具体公式为:


\begin{aligned} Q ^ { \pi } \left( s _ { t } , a _ { t } \right) & = \mathbb { E } \left[ G _ { t } \mid s _ { t } , a _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma r _ { t + 1 } + \gamma ^ { 2 } r _ { t + 2 } + \cdots \mid s _ { t } , a _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma \left( r _ { t + 1 } + \gamma r _ { t + 2 } + \cdots \right) \mid s _ { t } , a _ { t } \right]  
\\ & =\mathbb { E } [ r _ { t }|s_t,a_t] + \gamma \mathbb{E}[r_{t+1}+ \gamma r_{t+2}+\cdots|s_t,a_t] \\
& = \mathbb{E}[ r _ { t }|s_t,a_t]+ \gamma \mathbb{E}[G_{t+1}|s_t,a_t]
\\ &= \mathbb { E } \left[ r _ { t } + \gamma Q ^ { \pi } \left( s _ { t + 1 } , a _ { t + 1 } \right) \mid s _ { t } , a _ { t } \right] \end{aligned}

上式是 MDP 中 Q-function 的 Bellman 方程的基本形式。累积奖励 G_t 的计算,不仅考虑当下 t 时刻的动作 a_t 的奖励 $r_t$,还会累积计算对之后決策带来的影响(公式中的 \gamma 是后续奖励的衰减因子)。从上式可以看出,当前状态的动作价值 Q^{\pi}(s_t,a_t) ,与当前动作的奖励 r_t 以及下一状态的动作价值 Q^{\pi}(s_{t+1},a_{t+1}) 有关,因此,状态-动作值函数的计算可以通过动态规划算法来实现。

从另一方面考虑,在计算 t 时刻的动作价值 Q^{\pi}(s_t,a_t) 时,需要知道在 $t$、$t+1$、t+2 \cdots \cdots 时刻的奖励这样就不仅需要知道某一状态的所有可能出现的后续状态以及对应的奖励值还要进行全宽度的回溯来更新状态的价值。这种方法无法在状态转移函数未知或者大规模问题中使用。因此Q-learning 采用了浅层的时序差分采样学习,在计算累积奖励时,基于当前策略 \pi 预测接下来发生的 n 步动作(n 可以取 1 到 $+\infty$)并计算其奖励值。

具体来说,假设在状态 s_t 下选择了动作 $a_t$,并得到了奖励 r_t ,此时状态转移到 $s_{t+1}$,如果在此状态下根据同样的策略选择了动作 a_{t+1} ,则 Q^{\pi}(s_t,a_t) 可以表示为


Q^{\pi}\left(s_{t}, a_{t}\right)=\mathbb{E}_{s_{t+1}, a_{t+1}}\left[r_{t}+\gamma Q^{\pi}\left(s_{t+1}, a_{t+1}\right) \mid s_{t}, a_{t}\right]

Q-learning 算法在使用过程中,可以根据获得的累积奖励来选择策略,累积奖励的期望值越高,价值也就越大,智能体越倾向于选择这个动作。因此,最优策略 \pi^* 对应的状态-动作值函数 Q^*(s_t,a_t) 满足如下关系式:


Q^{*}\left(s_{t}, a_{t}\right)=\max _{\pi} Q^{\pi}\left(s_{t}, a_{t}\right)=\mathbb{E}_{s_{t+1}}\left[r_{t}+\gamma \max _{a_{t+1}} Q\left(s_{t+1}, a_{t+1}\right) \mid s_{t}, a_{t}\right]

Q-learning 算法在学习过程中会不断地更新 Q 值,但它并没有直接采用上式中的项进行更新,而是采用类似于梯度下降法的更新方式,即状态 s_t 下的动作价值 Q^*(s_t,a_t) 会朝着状态 s_{t+1} 下的动作价值 r_{t}+\gamma \max _{a_{t+1}} Q^{*}\left(s_{t+1}, a_{t+1}\right) 做一定比例的更新:


\begin{aligned}
Q^{*}\left(s_{t}, a_{t}\right) \leftarrow Q^{*}\left(s_{t}, a_{t}\right)+\alpha\left(r_{t}+\gamma \max _{a_{t+1}} Q^{*}\left(s_{t+1}, a_{t+1}\right)-Q^{*}\left(s_{t}, a_{t}\right)\right)
\end{aligned}

其中 \alpha 是更新比例(学习速率)。这种渐进式的更新方式,可以减少策略估计造成的影响,并且最终会收敛至最优策略。

On-policy vs. Off-policy

总结一下 on-policy 和 off-policy 的区别。

  • Sarsa 是一个典型的 on-policy 策略,它只用了一个 policy \pi 。如果 policy 采用 $\varepsilon$-greedy 算法的话,它需要兼顾探索,为了兼顾探索和利用,它训练的时候会显得有点胆小怕事。它在解决悬崖问题的时候,会尽可能地离悬崖边上远远的,确保说哪怕自己不小心探索了一点,也还是在安全区域内。此外,因为采用的是 $\varepsilon$-greedy 算法,策略会不断改变(\varepsilon 会不断变小),所以策略不稳定。
  • Q-learning 是一个典型的 off-policy 的策略它有两种策略target policy 和 behavior policy。它分离了目标策略跟行为策略。Q-learning 就可以大胆地用 behavior policy 去探索得到的经验轨迹来去优化目标策略从而更有可能去探索到最优的策略。Behavior policy 可以采用 $\varepsilon$-greedy 算法,但 target policy 采用的是 greedy 算法,直接根据 behavior policy 采集到的数据来采用最优策略,所以 Q-learning 不需要兼顾探索。
  • 比较 Q-learning 和 Sarsa 的更新公式可以发现Sarsa 并没有选取最大值的 max 操作。
    • 因此Q-learning 是一个非常激进的算法,希望每一步都获得最大的利益;
    • 而 Sarsa 则相对非常保守,会选择一条相对安全的迭代路线。

Summary

总结如上图所示。

References