强化学习基础算法
文章目录
上节中讲到,强化学习可以按有无模型进行分类,即智能体是否对环境进行建模;如果将强化学习问题建模成马尔可夫决策过程(MDP)的话(即五元组<S,A,P,R,γ>),那么,有无模型可以根据MDP五元组(尤其是PP和RR)是否已知进行判断;若已知表明智能体对环境进行了建模,能模拟出与环境相同或近似的状况,为有模型学习,否则为无模型学习。接下来,会先介绍有模型学习中基于动态规划的算法,然后会介绍无模型学习中的蒙特卡洛算法和时序差分学习。
先回顾一下动态规划:
动态规划算法通过把复杂问题分解为子问题,通过求解子问题进而得到整个问题的解。在求解子问题的时候,其结果通常需要存储起来被用来解决后续复杂问题。
当问题具有下列特性时,通常可以考虑使用动态规划来求解:
①、一个复杂问题的最优解由子问题的最优解构成,可以通过寻找子问题的最优解来得到复杂问题的最优解;
②、子问题在复杂问题内重复出现,使得子问题的解可以被存储起来重复利用。
MDP具有以上两个属性:
①、贝尔曼方程把问题递归为求解子问题;
②、价值函数相当于存储了子问题的解,并可以重复利用。
因此,可以使用动态规划的算法来求解MDP。
在模型已知时,对任意策略\piπ进行评估,给出该策略获得的回报期望,即计算状态价值函数。
问题:评估一个给定的策略\piπ;
解决方法:利用贝尔曼方程反向迭代;
具体做法:每次迭代过程中,用所有的状态ss的第kk次迭代得到的v_k(s’)vk(s′)来计算第k+1k+1次的v_{k+1}(s)vk+1(s)的值,其中s’s′是ss的后继状态。经过这种方法的反复迭代,最终是可以收敛到最优的v_*(s)v∗(s)。迭代的公式如下:
{v_{k+1} }(s) = \sum\limits_{a \in A} {\pi (a|s)}(R_s^a + \gamma \sum\limits_{s’ \in S} {P_{ss’}^a{v_k }(s’))}vk+1(s)=a∈A∑π(a∣s)(Rsa+γs′∈S∑Pss′avk(s′))
例子:方格世界
已知:
①、状态空间SS:除了灰色的两个格子(0和15),其他都是非终止状态;
②、动作空间AA:在每个状态下,都有四种动作可以执行,即上下左右;
③、状态转移概率PP:任何想要离开方格世界的动作将保持状态不变,即原地不动。比如:格子4执行动作“左”,则执行动作后状态仍为格子4;其他情况下将100%转移到下一个状态,比如格子4执行动作“右”,则执行动作后进入格子5;
④、即时奖励RR:任何非终止状态间转移得到的即时奖励均为-1,进入终止状态的即时奖励为0;
⑤、折扣因子\gammaγ:1;
⑥、当前策略\piπ:在任何一个非终止状态下,智能体采取随机策略,执行的动作是随机选择的,即:
\pi(up|s)=\pi(down|s)=\pi(left|s)=\pi(right|s)=0.25π(up∣s)=π(down∣s)=π(left∣s)=π(right∣s)=0.25
问题:评估这个方格世界里给定的策略。也就是说,在给定策略(这里是随机策略)的情况下,求解改策略下每一个状态的价值。
求解示例:
上述方法的更新方式是更新某一状态的价值函数时用其他所有状态的价值函数在上一次迭代时的值,即第k+1k+1次的结果都是利用第kk次的结果来计算的。
状态价值函数在第153次迭代后收敛:
具体代码可参考:强化学习实践一 迭代法评估4*4方格世界下的随机策略
还有另外一种更新方式:
更新某一状态的价值函数时用其他状态最新的迭代值,而不用等所有状态一起更新,即第kk次的迭代直接用第kk次中先迭代好的值来计算。
策略评估的目的是为了找到更好的策略,即策略改进。
策略改进通过按照某种规则对当前策略进行调整,得到更好的策略。
我们的目标是得到最优策略,所以,在状态价值函数收敛后,可以对策略进行改进。
在这里,可以使用贪婪算法来进行策略改进,即:
\pi '(s) = \mathop {argmax}\limits_{a \in A} {q_\pi }(s,a)π′(s)=a∈Aargmaxqπ(s,a)
也就是说,仅执行那个(些)使得状态价值最大的动作。
比如上面的方格世界例子,当我们计算出最终的状态价值后:
①、对于第二行第1格,其周围的状态价值分别是0,-18和-20,此时使用贪婪法,则调整的策略方向为状态价值为0的方向,即向上;
②、对于第二行第2格,其周围的状态价值分别是-14,-14,-20和-20,此时使用贪婪法,则调整的策略方向为状态价值-14的方向,即向左或向上。
③、其他格子类似,即上图中的右图。
在上述的例子中,基于给定策略的迭代最终收敛得到的策略就是最优策略,但通过一次策略评估计算状态价值函数联合策略改进就能找到最优策略不是普遍现象。通常,还需要在改善的策略上继续评估,反复多次。不过,这种方法总能收敛至最优策略{\pi}^*π∗。也就是接下来介绍的策略迭代。
比如:当初始化策略改为不管任何状态都执行动作“下”,那么,该策略通过一次策略评估和策略改进的过程就无法得到最优策略。
策略迭代是策略评估和策略改进的结合。
基本思想:从一个初始策略开始,不断地改进这个策略达到最优解。每次迭代时首先用策略评估计算一个策略的状态价值函数,然后根据策略改进方案调整改策略,再计算新策略的状态价值函数,如此反复直到收敛。
从一个策略\piπ和一个状态价值函数VV开始,每一次箭头向上表示利用当前策略进行状态价值函数的更新,每一次箭头向下代表着根据更新的状态价值函数贪婪地选择新的策略,说它是贪婪的,是因为每次都采取转移到状态价值函数最高的新状态的动作。最终将收敛至最优策略和最优状态价值函数。
策略迭代算法伪代码:
注意:在上面的伪代码中,策略评估步骤中,状态价值函数的更新公式为:
V(s) \leftarrow \sum\nolimits_{s’,r} {p(s’,r|s,\pi (s))} [r + \gamma V(s’)]V(s)←∑s′,rp(s′,r∣s,π(s))[r+γV(s′)]
甚至有些人在看资料中,更新公式会写成:
{v_{k + 1}}(s) = \sum\limits_{a \in A} {\pi (a|s)\sum\limits_{s’ \in S} {{p_a}(s,s’)} } ({R_a}(s,s’) + \gamma {v_k}(s’))vk+1(s)=a∈A∑π(a∣s)s′∈S∑pa(s,s′)(Ra(s,s′)+γvk(s′))
而我们在上面策略评估过程中,我们的公式是这样的:
{v_{k+1} }(s) = \sum\limits_{a \in A} {\pi (a|s)}(R_s^a + \gamma \sum\limits_{s’ \in S} {P_{ss’}^a{v_k }(s’))}vk+1(s)=a∈A∑π(a∣s)(Rsa+γs′∈S∑Pss′avk(s′))
在上述公式里面,p_a(s,s’)pa(s,s′)和P^a_{ss’}Pss′a的含义一样的,代表的是在状态ss执行动作aa后转移到状态s’s′的概率;
上述公式其实是等价的,对比发现,其实最重要的是理解:
R_s^a = \sum\limits_{s’ \in S} {{p_a}(s,s’)} {R_a}(s,s’)Rsa=s′∈S∑pa(s,s′)Ra(s,s′)
等式左面代表的是在状态ss执行动作aa后得到的即时奖励的期望(这一点在上节介绍MDP五元组时有介绍);等式右面是把执行动作aa后可能到达的状态s’ \ (s’\in S)s′ (s′∈S)进行分开讨论,先得到到达各个状态s’s′下的即时奖励R_a(s,s’)Ra(s,s′),然后再进行概率求和,其本质也是执行动作aa后获得的即时奖励的期望。
在策略迭代算法中,策略评估的计算量很大,需要多次处理所有状态并不断地更新状态价值函数。实际上,不需要知道状态价值函数的精确值也能找到最优解,值迭代就是其中一种方法。
一个最优策略可以被分解成两部分:
①、从状态ss到s’s′执行了最优动作A_*A∗;
②、在状态s’s′时采用的策略也是最优的;
定理:一个策略\pi(a|s)π(a∣s)使得状态ss获得最优价值,v_{\pi}(s)=v_(s)vπ(s)=v∗(s),当且仅当:对于从状态ss可到达的任何状态s’s′,该策略\piπ能够使得状态s’s′获得最优价值,即v_{\pi}(s’)=v_(s’)vπ(s′)=v∗(s′)。
基本思想:对每一个当前状态ss,对每个可能的动作aa都计算一下执行动作后到达的下一个状态的期望价值。看看哪个动作可以到达的状态的期望价值函数最大,然后就将这个最大的期望价值函数作为当前状态的状态价值函数,循环执行这个步骤,直至收敛。
因此,v_{k+1}(s)vk+1(s)的迭代公式为:
{v_{k+1} }(s) = \mathop{max}\limits_{a \in A} (R_s^a + \gamma \sum\limits_{s’ \in S} {P_{ss’}^a{v_k }(s’))}vk+1(s)=a∈Amax(Rsa+γs′∈S∑Pss′avk(s′))
在上面的方格世界例子中,当k=1k=1时,即第1次迭代时:
①、对于第二行第1格,其周围价值分别是0,-1和-1,选取最大的期望价值函数,那么,此时调整的策略方向为状态价值为0的方向,即向上;
②、对于第一行第2格,其周围价值分别是0,-1和-1,那么,此时调整的策略方向为状态价值为0的方向,即向左;
③、其他格子类似,即上图中的右图。
值迭代算法的伪代码:
值迭代算法与策略迭代算法的区别:不是对某一策略的状态价值函数进行计算,而是直接收敛到最优的状态价值函数。
策略迭代算法和值迭代算法都依赖于环境的模型,都需要知道状态转移概率PP及即时奖励RR,因此,被称为有模型的强化学习。但是,对于很多应用场景,无法得到准确的状态转移概率和奖励函数,因此,上面两种算法在实际问题中使用价值有限。
那么无法建立环境模型呢?
对于无法建立精确的环境模型的问题,只能根据一些状态、动作、回报值序列样本进行计算,估计出价值函数和最优策略。基本思想是按照某种策略随机执行不同的动作,观察得到的回报,然后进行改进,即通过随机试探来学习。这类算法称为无模型的学习。其中,蒙特卡洛算法和时序差分学习是典型代表,接下来会对这两类算法进行讲解。
蒙特卡洛算法指在不清楚MDP状态转移和即时奖励的情况下,直接从完整的episode的经历中来学习状态价值函数,通常情况下某状态的价值等于在多个episode中以该状态计算得到的所有回报的平均值。
完整的episode指从某一个状态开始,执行一些动作,直到终止状态为止的一个完整的状态、动作和回报的序列。episode在不同的资料中翻译不同,比如片段、回合等,在这里直接用英文表示。
例子:下棋问题分出输赢。
蒙特卡洛强化学习有以下特点:
(1)不基于模型(或者说无模型,model free);
(2)直接从完整的episode中学习;
(3)理论上episode越多,结果越准确;
目标:在给定策略\piπ下,从一系列完整的episode经历中学习得到该策略下的状态价值函数v_{\pi}vπ。
基于策略\piπ的一个episode信息可以表示为以下的序列:
S_1,A_1,R_2,…,S_t,A_t,R_{t+1},…,S_k \ \sim \ \piS1,A1,R2,…,St,At,Rt+1,…,Sk ∼ π
回顾下:在策略\piπ下,状态ss的状态价值函数为:
{v_\pi }(s) = {E_\pi }[{G_t}|{S_t} = s]vπ(s)=Eπ[Gt∣St=s]
从上面式子可以看出,状态价值函数等于该状态下能够获得的回报期望。
对于蒙特卡洛算法来说,求一个状态的状态价值函数,只需先求出所有的完整episode中该状态的回报。即,tt时刻状态S_tSt的回报:
G_t=R_{t+1}+ \gamma{R_{t+2}}+…+{\gamma}^{T-t-1}{R_T}Gt=Rt+1+γRt+2+…+γT−t−1RT
其中,TT为终止时刻。
然后再求出平均值即可得到近似解:
v_{\pi}(s) \approx average(G_t),\ s.t. \ S_t=svπ(s)≈average(Gt), s.t. St=s
在状态转移过程中,从状态ss离开后,经过一段时间后,又一次或多次的回到这个状态。
对于这个问题有两种解决方法:
(1)First-Visit:仅把状态序列中第一次到达状态ss时所得到的回报值纳入到回报平均值的计算中,从而得到状态ss的状态价值函数,即:
v(s) = \frac{{{G_{11}}(s) + {G_{21}}(s) + {G_{31}}(s) + \cdots }}{{N(s)}}v(s)=N(s)G11(s)+G21(s)+G31(s)+⋯
因为仅计算第一次到达状态ss的计算值,所以,这里的N(s)N(s)代表的也可以是关于包含状态ss的episode数;
(2)Every-Visit:对每次到达状态ss所得到的回报值都纳入到回报平均值的计算中,从而得到状态ss的状态价值函数,即:
v(s) = \frac{{{G_{11}}(s) + {G_{12}}(s) + \cdots + {G_{21}}(s) + \cdots + {G_{31}}(s) + {G_{32}}(s) + \cdots }}{{N(s)}}v(s)=N(s)G11(s)+G12(s)+⋯+G21(s)+⋯+G31(s)+G32(s)+⋯
这里的N(s)N(s)代表的是所有episode中到达状态ss的次数。
在上面的方法中,需要等待所有的episode都经历完,然后再计算v(s)v(s),这是需要预先存储所有的数据,最后再计算平均值。
在这里,可以使用累进更新平均值(Incremental mean,也许翻译成“增量更新平均值”更好?)的方法。
理论依据:
对于序列x_1,x_2,…x1,x2,…,其平均值\mu_1,\mu_2,…μ1,μ2,…可以通过增量的方式进行计算:
KaTeX parse error: No such environment: eqnarray at position 8: \begin{̲e̲q̲n̲a̲r̲r̲a̲y̲}̲{\mu _k} &=& \f…
所以,根据以上理论依据,累进增量更新的做法是:
当一个episode(S_1,A_1,R_2,…,S_TS1,A1,R2,…,ST)结束后,可以增量更新V(s)V(s),对于每个状态S_tSt,回报G_tGt:
N(S_t) \leftarrow N(S_t)+1N(St)←N(St)+1
V({S_t}) \leftarrow V({S_t}) + \frac{1}{{N({S_t})}}({G_t} - V({S_t}))V(St)←V(St)+N(St)1(Gt−V(St))
而在有些情况下,尤其是海量数据做分布式迭代的时候,可能无法准确算出当前的次数N(S_t)N(St),这时可以用参数\alphaα来代替,即:
V(S_t) \leftarrow V(S_t)+{\alpha}(G_t-V(S_t))V(St)←V(St)+α(Gt−V(St))
例子:AB例子
已知:现在只有两个状态AA和BB,状态转移概率PP和奖励RR未知,衰减系数\gammaγ为1,但有以下8个完整的episode以及对应的即时奖励,其中,除了第1个episode有状态转移外,其余7个episode均只有一个状态,即:
根据上述仅有的episode,使用蒙特卡洛算法,计算状态AA和BB的状态价值分别是多少?
由于上述episode是完整的episode,所以,状态BB为终止状态;这里,可以将状态B假设为游戏结束时的状态,输赢的即时奖励分别为0和1;
对于状态AA,因为仅有第1个episode包含状态AA,所以,仅episode 1可以用于计算状态AA的价值,此时,状态AA的回报就是G_A = 0+1*0=0GA=0+1∗0=0,那么状态AA的价值为V(A)=0V(A)=0;
对于状态BB,所有的episode可用于计算其价值,此时,状态BB的价值为:
V(B) = \frac{{{G_1}(B) + {G_2}(B) + \cdots + {G_8}(B)}}{8} = \frac{{0 + 1 + \cdots + 0}}{8} = \frac{6}{8}V(B)=8G1(B)+G2(B)+⋯+G8(B)=80+1+⋯+0=86
类似地,对于动作价值函数Q(S_t,A_t)Q(St,At),其更新公式为:
Q(S_t,A_t) \leftarrow Q(S_t,A_t)+{\alpha}(G_t-Q(S_t,A_t))Q(St,At)←Q(St,At)+α(Gt−Q(St,At))
控制问题目标:求解最优的价值函数和策略。
先回顾下通用策略迭代的思想:
通用策略迭代的核心是在策略评估和策略改进两个交替的过程中进行策略优化。
使用动态规划算法来改善策略时需要知道某一状态的所有后续状态及状态间转移概率,这种方法不适合模型未知的情况,因为在模型未知的条件下,无法知道当前状态的所有后续状态,进而无法确定当前状态执行怎样的动作更合适。那么怎么解决呢?
解决这一问题的方法是:使用状态动作对(<s,a>)下的动作价值Q(s,a)Q(s,a)来代替状态价值:
\pi '(s) = \mathop {argmax}\limits_{a \in A} Q(s,a)π′(s)=a∈AargmaxQ(s,a)
这样做的目的是可以改善策略而不用知道整个模型,只需要知道在某个状态下执行什么样的动作价值最大即可。
具体做法是:从一个初始的QQ和策略\piπ开始,先根据这个策略更新每一个状态动作对的qq值,即动作价值函数,然后基于更新后的QQ和贪婪算法来确定改善的策略。
即使这样,还存在一个问题:当我们每次都使用贪婪算法来改善策略时,将可能由于没有足够的采样而导致产生一个并不是最优的策略,因此,需要尝试新的动作,即探索。一种做法是\varepsilonε-贪心策略。
\varepsilonε-贪婪策略:以1-\varepsilon1−ε的概率选择当前认为最好的动作,以\varepsilonε的概率在所有可能的动作中进行选择(也包括当前认为最好的动作)。数学公式表示如下:
\pi (a|s) = \left{ {\begin{array}{c} {\varepsilon /m + 1 - \varepsilon }&{if \ {a^*} = \mathop {{\mathop{\rm argmax}\nolimits} }\limits_{a \in A} Q(s,a)}\ {\varepsilon /m}&{otherwise} \end{array}} \right.π(a∣s)={ε/m+1−εε/mif a∗=a∈AargmaxQ(s,a)otherwise
这样做的目标是使得某一状态下的所有可能的动作都能被选中执行,从而保证了持续的探索。
定理:使用\varepsilonε-贪婪策略,对于任意一个给定的策略\piπ,在评估这个策略的同时也总在改善它。即:
蒙特卡洛控制的基本思想:使用Q函数进行策略评估,然后使用\varepsilonε-贪婪策略来改善策略。该方法最终可以收敛至最优策略。如下图所示:
图中的每一个向上或向下的箭头一般都对应着多个episode,也就是说,一半经历多episode后才进行依次QQ函数更新或策略改善。实际上,也可以每经历一个episode后就更新QQ函数或策略改善。
在实际求解控制问题时,为了使算法可以收敛,一般\varepsilonε会随着算法的迭代过程逐渐减小,并趋于0。这样,在迭代前期,鼓励探索,而在后期,由于有了足够的探索量,开始趋于保守,以贪婪为主,使算法可以稳定收敛。
GLIE(Greedy in the Limit with Infinite Exploration),就是在有限时间内进行无限可能的探索。
具体表现为:所有已经经历的状态动作对会被无限次探索;而随着迭代过程,贪婪算法中\varepsilonε的值会趋向于0。例如,取\varepsilon = 1/kε=1/k(kk为episode数目)。
基于GLIE的蒙特卡洛控制流程如下(基于every-visit更新动作价值函数):
输入:状态集SS,动作集AA,即时奖励RR,衰减因子\gammaγ,探索率\varepsilonε
输出:最优的动作价值函数q_*q∗和最优策略\pi_*π∗
①、初始化所有的动作价值函数Q(s,a)=0Q(s,a)=0,状态次数N(s,a)=0N(s,a)=0,采样次数k=0k=0,随机初始化一个策略\piπ
②、k=k+1k=k+1,基于策略\piπ进行第kk次蒙特卡洛采样,得到一个完整的episode(S_TST为终止状态):
S_1,A_1,R_2,S_2,A_2,R_3,…,S_TS1,A1,R2,S2,A2,R3,…,ST
③、对于该episode里出现的每个状态动作对(S_t,A_tSt,At),计算回报G_tGt,更新计数N(s,a)N(s,a)和动作价值函数Q(s,a)Q(s,a):
G_t\leftarrow R_{t+1}+ \gamma{R_{t+2}}+…+{\gamma}^{T-t-1}{R_T}Gt←Rt+1+γRt+2+…+γT−t−1RT
N(S_t,A_t)\leftarrow N(S_t,A_t)+1N(St,At)←N(St,At)+1
Q({S_t},A_t) \leftarrow Q({S_t},A_t) + \frac{1}{{N({S_t},A_t)}}({G_t} - Q({S_t},A_t))Q(St,At)←Q(St,At)+N(St,At)1(Gt−Q(St,At))
④、基于新计算出的动作价值改善策略:
\varepsilon \leftarrow 1/kε←1/k
\pi \leftarrow \varepsilon-greedy(Q)π←ε−greedy(Q)
⑤、如果所有的Q(s,a)Q(s,a)收敛,则对应的所有的Q(s,a)Q(s,a)即为最优的动作价值函数q_*q∗,对应的策略{\pi}(a|s)π(a∣s)即为最优策略\pi_*π∗;否则,不收敛则转到第②步。
时序差分学习(Temporal-Difference Learning)简称为TD学习,特点如下:
(1)和蒙特卡洛算法一样,也从episode中学习,不需要了解模型本身;
(2)可以从不完整的episode中学习;
预测问题就是求解策略的状态价值函数。
回顾下,在蒙特卡洛算法中,使用回报来更新状态价值,即:
V(S_t) \leftarrow V(S_t)+{\alpha}(G_t-V(S_t))V(St)←V(St)+α(Gt−V(St))
蒙特卡洛算法在计算回报时的方法是:
G_t=R_{t+1}+ \gamma{R_{t+2}}+…+{\gamma}^{T-t-1}{R_T}Gt=Rt+1+γRt+2+…+γT−t−1RT
其中,TT为终止时刻。
而对于TD,没有完整的episode,那么如何可以近似求出某个状态的回报呢?
在上一讲MDP讲解贝尔曼方程中,状态价值函数v_{\pi}(s)vπ(s)可以分解为即时奖励与其后继状态的折扣价值之和,即:
v_{\pi}(s)=E_{\pi}[R_{t+1}+{\gamma}v_{\pi}(S_{t+1})|S_t=s]vπ(s)=Eπ[Rt+1+γvπ(St+1)∣St=s]
那么,这就启发我们,可以用R_{t+1}+{\gamma}V(S_{t+1})Rt+1+γV(St+1) 来代替G_tGt;
那么,根据以上启发,在TD算法中,算法在估计某一个状态的价值时,用的是离开该状态的即时奖励R_{t+1}Rt+1与下一个状态S_{t+1}St+1的预估状态价值乘以衰减系数\gammaγ组成,即:
V(S_t) \leftarrow V(S_t)+{\alpha}(R_{t+1}+{\gamma}V(S_{t+1})-V(S_t))V(St)←V(St)+α(Rt+1+γV(St+1)−V(St))
其中,R_{t+1}+{\gamma}V(S_{t+1})Rt+1+γV(St+1)称为TD目标值(TD target);
{\delta}t=R{t+1}+{\gamma}V(S_{t+1})-V(S_t)δt=Rt+1+γV(St+1)−V(St)称为TD误差(TD error);
同样使用AB例子:
如果使用TD算法,那么状态AA和BB的状态价值分别是多少?
在TD算法中,在估计某一个状态的价值时,用的是离开该状态的即时奖励R_{t+1}Rt+1与下一个状态S_{t+1}St+1的预估状态价值乘以衰减系数\gammaγ组成。
本例子中状态BB是终止状态,没有下一个状态,因此,它的状态价值这接用其在8个episode中的回报求平均获得,即V(B)=\frac{6}{8}V(B)=86;
而对于状态AA,只存在一个episode使得状态AA有下一个状态BB,因此,状态AA的价值是通过状态BB的价值计算的:
V(A)=R_A+{\gamma}V(B)=\frac{6}{8}V(A)=RA+γV(B)=86
蒙特卡洛算法和TD算法在求解预测问题上的区别:
(1)TD算法在更新状态价值时使用的是TD目标值,即基于即时奖励和下一个状态的预估价值来替代当前状态在状态序列结束时可能得到的回报,是当前状态价值的有偏估计,而蒙特卡洛算法则使用实际的回报来更新状态价值,是某一策略下状态价值的无偏估计;
(2)蒙特卡洛算法必须等到最后结果才能学习,即完整的episode;TD算法在知道结果之前就可以学习,也可以在没有结果时学习,还可以在持续进行的环境里进行学习;
(3)虽然TD算法得到的价值是有偏估计,但是其方差却比蒙特卡洛算法得到的方差要低,且对初始值敏感,通常比蒙特卡洛算法更高效。
控制问题主要是为了求解最优价值函数和策略。
这里主要讲两种算法:SARSA算法和Q-learning算法。
为了便于理解,这里先以一个小例子开始,讲解Q-learning算法的过程,然后我们再将SARSA算法和Q-learning算法进行对比。
例子:
在上图中,将设一幢建筑里有5个房间,房间之间通过门相连,这5个房间按照从0至4进行编号,且建筑的外围可认为是一个大房间,编号为5。
对于这个例子,首先将智能体置于建筑中的任意一个房间,然后从那个房间开始,让其走到建筑外,那是我们的目标房间,即编号为5的房间。
我们为每一扇门设置一个reward值:直接连接到目标房间的门的reward的值为100,其他门的reward的值为0;所以,可以用一个图来表示:
在这个图中,每个节点表示一个房间,每条线代表一个门,线的箭头表示方向,线上面的值表示reward值。
注意:编号为5的房间有一个指向自己的箭头,其reward值为100,其他指向目标房间的边的reward值也为100。Q-learning的目标是达到reward值最大的状态,因此,当智能体到达目标房间后将永远停留在那里,这种目标也称为“吸收目标”(absorbing goal)。
假设现在智能体位于2号房间,我们希望智能体通过学习到达5号房间。
定义每一个房间为一个状态,将智能体从一个房间走到另外一个房间称为一个动作。在上图中,一个状态对应一个节点,一种动作对应一个箭头。
假设智能体当前处于状态2,从状态2可以到状态3(因为状态2与3之间有边相连),但从状态2不能到其他状态(因为没边相连)。其他情况类似。
此时,我们可以以状态为行,动作为列,构建一个如下所示的关于reward值的矩阵RR,其中-1表示空值,表示相应节点之间没有边相连。
类似地,可以构建一个矩阵QQ,用来表示智能体已经从经验中学到的知识,矩阵QQ与RR是同阶的,其行表示状态,列表示行为。由于刚开始时,智能体对外界环境一无所知,因此矩阵QQ被初始化为零矩阵。为简单起见,在本例中,我们假设状态的数目是已知的(即6)。对于状态数目未知的情形,可以让QQ从一个元素出发,每次发现一个新的状态时就可以在QQ中增加相应的行列。
Q-learning算法的转移规则(动作价值函数更新)如下:
Q(s,a)=R(s,a)+{\gamma} {\mathop {{\mathop{\rm max}\nolimits} }\limits_{a’} }[Q(s’,a’)]Q(s,a)=R(s,a)+γa′max[Q(s′,a′)]
其中,s,as,a表示当前状态和动作,s’,a’s′,a′表示下一个状态和动作,\gammaγ为[0,1]的常数。
那么,假设当智能体处在状态1时,观察矩阵RR的第二行,包含两个非负值,即当前状态1的下一个状态有两种可能:转至状态3或者状态5,随机地,我们选择转至状态5。
当智能体位于状态5后,观察矩阵RR的第六行,对应三种可能的动作:转至状态1,4,5,而根据上面的转移规则公式(在这里,我们设置\gamma=0.8γ=0.8):
\begin{array}{c} Q(1,5) &=& R(1,5) + 0.8max[Q(5,1),Q(5,4),Q(5,5)]\ &=& 100 + 0.8\max [0,0,0]\ &=& 100 \end{array}Q(1,5)===R(1,5)+0.8∗max[Q(5,1),Q(5,4),Q(5,5)]100+0.8∗max[0,0,0]100
现在状态5变成了当前状态,因为状态5为目标状态,所以一次episode便完成了。至此,智能体的QQ矩阵刷新为:
接下来,我们再进行一次episode的迭代:首先随机地选取一个初始状态,假设选状态3为初始状态。那么:
观察矩阵RR,对应三个可能的动作:转至状态1,2或4。随机地,我们选择转至状态1。那么,状态1对应两个可能的动作:转至状态3或5。
那么,根据转移规则公式:
\begin{array}{c} Q(3,1) &=& R(3,1) + 0.8max[Q(1,3),Q(1,5)]\ &=& 0 + 0.8\max [0,100]\ &=& 80 \end{array}Q(3,1)===R(3,1)+0.8∗max[Q(1,3),Q(1,5)]0+0.8∗max[0,100]80
此时,QQ矩阵变为:
此时,状态1变成了当前状态,因为状态1还不是目标状态,因此需要继续往前探索,当前状态1的下一个状态有两种可能:转至状态3或者状态5,假设幸运地选择了状态5。
当智能体位于状态5后,对应三种可能的动作:转至状态1,4,5,而根据上面的转移规则公式:
\begin{array}{c} Q(1,5) &=& R(1,5) + 0.8max[Q(5,1),Q(5,4),Q(5,5)]\ &=& 100 + 0.8\max [0,0,0]\ &=& 100\end{array}Q(1,5)===R(1,5)+0.8∗max[Q(5,1),Q(5,4),Q(5,5)]100+0.8∗max[0,0,0]100
经过这一步刷新,矩阵QQ没有发生变化。
现在状态5变成了当前状态,因为状态5为目标状态,所以一次episode便完成了。至此,智能体的QQ矩阵刷新为:
继续执行更多的episode,矩阵QQ将最终收敛为:
对矩阵进行规范化,每个非零元素都除以矩阵QQ的最大元素(这里为500),可得(这里省略了百分号):
一旦矩阵QQ足够接近于收敛状态,智能体便学习到了转移至目标状态的最佳路径。如图所示:
例如:从2位初始状态,利用QQ,可得:
从状态2,最大QQ元素值指向状态3;
从状态3,最大QQ元素值指向状态1或4(这里假设我们随机地选择了1);
从状态1,最大QQ元素值执行状态5;
因此,最佳路径序列为2-3-1-5。
从上面的例子中,我们可以看出有以下几个关键步骤:
①、随机选择一个初始状态作为当前状态ss;
②、对于当前状态ss,随机选择一个动作aa;
③、根据当前状态ss和选择的动作aa,得到下一个状态s’s′;
④、根据转移规则更新Q(s,a)Q(s,a);
⑤、状态s’s′变为当前状态,然后判断当前状态是否为终止状态,是则此episode完成,否则继续迭代(即转到②);
所以,Q-learning算法的伪代码是:
理解了Q-learning算法,我们直接对比SARSA算法的伪代码:
在这里,我们可以看到SARSA算法与Q-learning算法最本质的区别是:
在状态s’s′选择动作用于更新矩阵QQ所用的策略不同!!!
Q-learning算法是基于贪婪策略,选择使得Q(S’,a)Q(S′,a)最大的动作aa来更新Q(S,A)Q(S,A);此时不执行动作aa,当QQ更新后,新的执行动作基于状态S’S′,然后用\epsilon-greedyϵ−greedy策略重新得到。
而SARSA算法是再次基于\epsilonϵ-greedy策略,随机选择一个动作A’A′(在这里,所有动作都可能被选中),此时不执行这个动作A’A′,只是为了通过自身当前的状态价值函数得到Q(s’,A’)Q(s′,A′)来更新Q(S,A)Q(S,A);然后将A’A′留到下一个循环执行;
另外,学习率\alphaα代表有多么迫切地进行更新,当\alphaα接近于0时,说明并不急切的进行更新;当\alphaα接近于1时,就是在用更新的值来替换旧值。\alphaα越大表明采用新的尝试得到的结果的比例越大,保持旧的结果的比例越小。
本博客所有内容仅供学习,不为商用,如有侵权,请联系博主,谢谢。
[3] 机器学习原理、算法与应用
[4] 人工智能:一种现代的方法(第3版)
[5] An Introduction to Reinforcement Learning
[6] Algorithms for Reinforcement Learning
[7] 策略迭代
[8] 强化学习 值迭代和策略迭代
[10] 强化学习总结(4)–蒙特卡洛方法