• 【机器学习笔记】强化学习概述


    作者:老董
    链接:https://zhuanlan.zhihu.com/p/34298295
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    目前关于强化学习(RL)的论述和公开课程已经很多了,虽然已经有了不少深入了解的文章,但是我觉得为了能够更好地理解RL并对其开展研究,还是需要暂时挪开放大镜,给予其一个宏观地了解。

    所以本文我希望从实际问题的角度入手,逐渐地将相关的概念都串起来。尽可能从概念而不是理论上去理解---做到既知树木又见森林。所以本文合适对RL有过了解但对整体概念还有点模糊的同学看,比如笔者~ 。

    同时也因为概念性的理解,所以若有什么地方讲得不够紧凑或不合理的还请多多包涵。

    参考资料

    主要参考:《Reinforcement Learning- An Introduction》第二版 Complete Draft ---若无特别说明,下文中所指的书即为本书

    Edx公开课:BerkeleyX - CS188x_1

    知乎:David Silver强化学习公开课中文讲解及实践

    知乎:强化学习知识大讲堂专栏

    知乎:DQN从入门到放弃系列文章

    3个问题

    要想理解一个东西,尤其是理论性的。需要回答3个问题:
    1. 这东西是什么?(What)
    2. 为什么需要这东西?(Why)
    3. 如何使用这个东西?(How)

    RL是什么?

    给定一个任务,RL就是一种通过和(可能未知的)环境不断地交互进而习得最优策略(Ploicy)的针对计算机(Agent)的一种学习方法。

    为何需要RL?

    在任务中的某个状态下,传统的搜索策略需要一层层的往下搜索,需要消耗不少时间来计算该状态下的(近似)最优操作,而RL可以直接习得一个从状态到操作的映射---这个映射可以是个函数,也可以是个存储状态和操作的查询表。所以RL在实时任务中总是能更快,也更节省内存地得到最优操作(action)。

    另外,很多时候并不清楚任务的环境是如何和操作交互的。这个时候需要实际的探险,这个时候只能依赖RL这种“有探险精神”的方法,不断地在实际交互中更新信息---这也就是为什么RL叫“强化学习”(又名:增强学习)。

    最后,RL由于是直接从环境中进行学习,其习得的策略能更好的反应最近获得的经验,即若环境发生了改变,RL也能通过学习很快适应,而不用像搜索那样重新人为的对环境进行建模修正。

    所以需要RL的理由是:
    1. 比传统搜索更快;
    2. 可以处理未知环境的任务;
    3. 经验主义,能更好地适应不断变化的环境;

    如何使用RL?

    哦,这是个非常庞大的问题,因为这实际在问RL到底是怎么一个思考流程的,也是RL的核心问题。笔者会在下个章节详细讲述,但这里我们还是需要了解下RL的基本结构和构成要素:

    • 状态( S )---一个任务中可以有很多个状态,且我们设每个状态在时间上是等距的;
    • 操作( A )---针对每一个状态,应该有至少1个操作可选;
    • 回馈( R )---针对每一个状态,环境会在下一个状态直接给予一个数值回馈,这个值越高,说明该状态越值得青睐;
    • 策略( pi )---给定一个状态,经过π的处理,总是能产生唯一一个操作a,即a=π(s),π可以是个查询表,也可以是个函数;

    以上就是RL中最基本的4大要素。总的来说,RL的思考流程就是:给定一个任务,agent会每隔固定的时间time step(以下简称step)得到一个状态,此时agent需要根据预先设定的操作集合中选择一个操作并实施,然后任务环境会对此做出反应,然后在下个step中agent又会获得下个step的状态和本step的回馈; 所以简单的说,每个step agent干2件事:

    1. 获取本step的状态和上个step的回馈;
    2. 给出本step的操作并与环境交互;
    流程图,摘自书中第3.1节

    另外,为了能够习得最优策略,agent还会基于获得的信息更新策略;这个更新可能是直接在和环境的交互中完成的,即线上(online)更新,也可能是在本次(episode)任务结束后线下(offline)更新的,当然可以同时线上线下更新。

    注意:所有的操作都是仅仅基于本step获取到的信息来完成的。换言之,在RL中的一个基本思想是认为只需要当前step的状态信息即可给出一个合理的操作,而和本step之前的信息无关----这种认为未来的发展只和当下有关的特性叫马尔可夫性。而由具有这种特性组成的状态所组成的时间序列就叫马尔科夫过程(Markov Process)。再加上每个状态需要执行的操作(决策),整个过程就是马尔科夫决策过程(Markov Decisioon Process,简称MDP)。可以认为现在的RL多数情况都是在建立在MDP的思想上的。

    所以如何使用RL?

    1. 给定一个任务;
    2. 给定一个操作集合A;
    3. 设计一个回馈函数R;
    4. 设计一个方法,让agent可以基于信息来更新策略;
    5. 给定一个初始策略π;
    6. 让agent在环境中不断地通过策略和环境交互并吸收新的信息及更新策略;

    那么现在就有个很自然的问题---怎样才能找到最优策略呢?

    最优策略

    在考虑如何寻找最优策略前,首先需要知道针对策略,怎么评价策略的优劣。

    所谓没有比较就没有伤害,本质上评价策略的优劣就是比较两个或以上策略哪个更好。那怎么比较呢?

    假设现在让agent玩象棋,定义agent下的棋为操作,初始局面或对方落子后的每一个局面为一个状态,直到将死对方为胜利,否则失败。若现在有两个策略 pipi' ,它们都胜利了。那能说两个策略一样好吗?当然我们可以这样去定义,但是经验告诉我们,往往一个任务中并不是每个操作都是最优的。即极有可能同一个策略会在不同的棋局任务中有不同的结果,这样显然就无法比较不同策略的优劣了。

    可以想象,虽然有点极端---若有一个策略 pi ,其每个状态下的操作的结果都能优于另一个策略 pi' 对应状态下的结果,那显然可以说策略 pi 更优。为何?通俗的理解就是:不管站在状态哪个角度, pi 的表现总是比 pi' 好,那总的来说当然 pi 更好咯。

    这里需要先给出个在RL中经常用到的两个概念:

    1. v_{pi}(s)指在给定策略 pi 下,状态 s 在该策略下的期望回报(return,注意不是回馈reward);
    2. q_pi(s,a) 指在给定策略 pi 下,状态 s 在该策略下执行了操作a后的期望回报;

    两者的区别在于前者表示的是一种期望回报,而后者则是在给定具体的操作 a 下的期望回报。

    回到刚刚的策略话题。那么即对所有 s ,若满足 q_pi(s,a)geq q_{pi'}(s,a) ,则有 pi>pi' 。那么自然所谓得最优策略 pi 应该满足:

     q_(s,a)doteqmax_pi q_pi (s,a) 	ag{1}

    v*(s)doteq max_pi v_{pi}(s) 	ag{2}

    这里以式1为例,我们会很自然地问:给定一个状态 s ,怎么定义一个操作 a 的好坏?

    之前说过,针对每个状态,回馈 R 越高越好。也就是针对每一个状态,会对其有一个即时反馈,即回馈 R 。但是这个 R 只是针对某一个状态的即时反馈,显然作为一个理性的agent,应该有长远的眼光。若只针对 R 来选择针对每个状态的操作就太短视了。既然一个任务只有等到结束时(暂不考虑连续任务/continuing task)才能知道是否完成,则要评估某时刻 t 的状态 S_t 的估值,合理的做法是将该状态之后所有的回馈全部考虑进来:

     G_t = R_{t+1}+ R_{t+2}+...+ R_{T}

    而考虑到时间因素,那么应该再增加一个折扣因子,越往后折扣的越多。即:

     G_t = R_{t+1}+ gamma R_{t+2}+gamma^2R_{t+2}...=sum^{infty}_{k=0}gamma^kR_{t+k+1}

    这种考虑所有后续结果的回馈就是期望回报(return),简称回报。另外由于实际任务中往往一个操作后有很多不同的状态(注:每个状态都会一个固定的反馈 R ),所以其中的 R 需要考虑后续的状态转移概率,即针对状态 s_t 的回馈 R_{t+1} 有:

    R_{t+1}=sum_{s_{t+1},r_{t+1}}p(s_{t+1},r_{t+1}|s_{t},a_t)r_{t+1}

    所以针对某个特定的状态和操作--- q(s_t,a_t) 有:

    egin{eqnarray} q(s_t,a_t) &=& sum_{s_{t+1},r_{t+1}}p(s_{t+1},r_{t+1}|s_{t},a_t)r_{t+1}+sum_{s_{t+2},r_{t+2}}p(_{t+2},r_{t+2}|s_{t+1},a_{t+1})r_{t+2}+...\&+&sum_{s_{T},r_{T}}p(s_{T},r_{T}|s_{T-1},a_{T-1})r_{T} end{eqnarray}

    同时,由于任务中的每个状态操作对(以下简称 Q)的估值都是这种形式,所以可递归地写成:

    q(s_t,a_t) = sum_{s_{t+1},r_{t+1}}p(s_{t+1},r_{t+1}|s_{t},a_t)[r_{t+1}+ gamma q(s_{t+1},a_{t+1})]

    这里我们发现,后续使用的状态估值是用的一个特定的操作 a_{t+1} ,而每个状态下所选择的操作又都是跟着策略走的,即所求的值应该是基于某个特定的策略,比如 pi 。所以该公式应该加上策略标志:

    q_pi(s_t,a_t) = sum_{s_{t+1},r_{t+1}}p(s_{t+1},r_{t+1}|s_{t},a_t)[r_{t+1}+ gamma q_pi(s_{t+1},a_{t+1})]

    上式是直接考虑每个 Q的估值;若只考虑每个状态的整体估值,那么同样的思路,可得:

    v_pi(s_t)=sum_a pi(a|s_t)sum_{s_{t+1},r_{t+1}}p(s_{t+1},r_{t+1}|s_{t},a_t)[r_{t+1}+ gamma v_pi(s_{t+1})]

    上面两个式子就是RL中经典的状态估值公式了,其有个很学术的名字叫贝尔曼(Bellman)方程。同时根据最优策略的定义,其每个状态的估值都应满足:

    v_*(s_t)=max_asum_{s_{t+1},r_{t+1}}p(s_{t+1},r_{t+1}|s_{t},a_t)[r_{t+1}+ gamma v_*(s_{t+1})] \ q_*(s_t,a_t) = sum_{s_{t+1},r_{t+1}}p(s_{t+1},r_{t+1}|s_{t},a_t)[r_{t+1}+ gammamax_{a_{t+1}}q_*(s_{t+1},a_{t+1})]

    上面这2个公式就是所谓的最优贝尔曼方程了。

    最后为了表述方便,我们去除表示当前step的下标 t ,并用 ' 代替 t+1 ,就有了针对状态值的(最优)贝尔曼方程:

    egin{eqnarray} v_pi(s)&=&sum_a pi(a|s)sum_{s',r'}p(s',r'|s,a)[r'+ gamma v_pi(s')] 	ag{3} \ v_*(s)&=&max_asum_{s',r'}p(s',r'|s,a)[r'+ gamma v_*(s')] 	ag{4} end{eqnarray}

    以及针对 Q的(最优)贝尔曼方程:

    egin{eqnarray} q_pi(s,a) & = &sum_{s',r'}p(s',r'|s,a)[r'+ gammasum_{a'}pi(a'|s') q_pi(s',a')] 	ag{5} \ q_*(s,a) &= &sum_{s',r'}p(s',r'|s,a)[r'+ gammamax_{a'}q_*(s',a')] 	ag{6} end{eqnarray}

    记住这4个公式!其涵盖了RL中所有基本元素。讲白了,找最优策略就是找可以满足最优贝尔曼方程的策略!

    如何寻找最优策略

    概念清楚了后,接下来要解决的就是如何寻找了。如上所述,最优策略就是能满足最优贝尔曼方程的策略,可具体怎么找呢?

    思路:给定一个策略,不断地更新该策略,使其接近最优策略。

    我们知道,若两个策略满足其中一个策略 pi 的每个状态(或 Q,以下略)的估值都要优于或等于另一个策 pi' ,我们就说 pi geq pi' 。换言之, pi 更好。

    若现在针对某个 pi ,我们找到了一个新的策略 pi' ,其只针对原策略中的一个状态进行了改进,使其状态估值比原策略更好,那也可以说 pi' geq pi ---why? 书中(P63)作者用了大量公式从理论证明了。但笔者认为这个可以很直观地理解---若其他状态因为这个状态的改进而受到影响,那么由于整个状态估值都是由加乘法组成的,所以对于新策略的每个状态估值,只会更优不会更差,因此有 pi' geq pi

    现在很清楚了,只要不断地更新策略,哪怕每次只改进一个状态的操作,那么长此以往,也定能找到最优策略 pi*

    3大主流寻策法

    寻策法1: 动态规划

    现在假设一个最完美的设定:给定一个任务,我们知道关于该任务的所有状态下的的回馈、转移概率和每个状态可用的操作集合。现需找到最优策略,具体该怎么做呢? 一种普遍的做法是“策略迭代”法:

    策略迭代:摘自书中第4.3节

    策略迭代的思路:
    1. 初始化;
    2. 首先给定一个策略,不断地迭代使得最后能够得到关于该策略下各个状态的估值;
    3. 有了估值,就可以着手针对每个状态来更新策略了;

    而我们知道,哪怕就是改进一个状态的操作也可以提升整个策略,而改进了策略后,自然地新策略的估值需要重新评估。所以第2和3步需要周而复始的循环直到发现某个策略足够稳定(没有改进的空间了),那就说明我们找到了最优策略。

    但上述这种做法有个问题---其每次更新策略估值时把每个状态都更新了n多遍,感觉有点浪费时间。因为我们更新状态估值的真正目的只是为了通过比较某状态下各操作的回报差异,进而根据贝尔曼方程选择针对不同状态选择最优操作,所以每个状态的估值也许并不需要绝对精确。基于这种思想就催生了“值迭代”法:

    值迭代:摘自书中第4.4节

    “值迭代”的基本思想是:

    虽然起初通过max更新的最优策略下的估值是基于不完整的状态信息的,但每个状态总是有一个最优操作的。那么通过不断地迭代更新,总是有机会能先找到某个状态下的最优操作,保证其足够平稳(即该状态下的操作不会随着迭代经常变)。然后就能以点破面,找到更多周边的平稳的最优估值。久而久之,平稳的状态会越来越多,最后也就能找到最优策略了。

    可喜的是,不管是策略迭代又或是值迭代的可收敛想法是可从理论上证明的,但证明的原理好像不同。分别是通过“单调有界”和“巴拿赫不动点”定理证明的(这个笔者并不很清楚)。

    那么具体那种能更快收敛呢?目前没有理论的证明,但经验上值迭代总是能更快地收敛。而不管是策略迭代还是值迭代又或者其他变种,这种通过估值和改进策略的方法统一为GPI,如图:

    GPI:摘自书中第4.6节

    注:上述给出GPI法都是站在对状态估值的角度,同样思路也可以给出基于 Q值的策略迭代和值迭代算法(此略)。而不管是策略迭代还是值迭代,都需要对所有状态进行遍历。这很低效,所以就有了针对性的异步动态规划的技术---比如,可以只对一些比较重要的状态进行先行遍历(参考书中P69之4.5节)。

    可以认为在RL中,MDP框架给出了agent看待任务(环境)的视角,而GPI框架则告诉了agent如何对任务进行分析并学习的基本思想。而这类基于状态和转移概率”动态地去规划”策略的方法叫做动态规划(DP)法(更具体地说是采用了GPI框架的DP法)。

    可见,DP法是一类线下(off-line)学习法,即其不需要真的和环境交互就能学到最优策略。而由于DP法中值的更新用到了后续状态v(s'),我们说这种做法叫自举(bootstrapping)。DP法在理论上总是能保证找到最优策略,但这类方法有个很理想假设:即开头说的我们知道关于该任务的所有状态下的的回馈,和转移概率和每个状态可用的操作集合。换言之,我们对任务的环境(模型)完全可知。然而真实的情况真的有那么好吗?即便如此,若任务状态空间很大,又如何保证学习效率呢?

    寻策法2: 蒙特卡洛法

    为了解决实际任务种多数是不知道模型的问题,所以需要开发一种可以不依赖模型的方法来获取信息。可以想象,最直接的方法是“开荒”---直接让agent在任务中根据真实反馈来获取必要信息。于是就有了蒙特卡洛(MC)法。

    MC法基本思想: 通过在实际任务中的交互,记录下每个实际遇到的状态的回馈。然后通过n个回合(episode)的任务后,对每个遇到的状态求算数平均---即为状态的估值。 由于同一个状态可以在一个回合中多次碰到,所以根据是否考虑所有的同状态,可以分为first-visit和every-visit两种模式,2种方法各有利弊。

    注意,由于MC法中没有状态转移概率,所以若只是对状态v(s)估值,在寻策时无法找到某个状态的最优操作,所以这里只有对 Q值估计才有意义。
    而又因为MC法中没有状态转移概率,所以为了找到最优策略,必需尽可能多的在实际任务种遍历到足够多的 Q,即需要足够多的Exploration。 因为这个约束,就引出了一个在无模型(转移概率)寻策法(比如MC)中所特有的问题:

    因为对环境的无知,所以为了收集资料需要探索Exploration,所以就不能改进策略。但根据GPI思想,为了找到最有策略又需要改进策略,而这个会导致某个状态下(基于当前基本是不完整所以不合理的估值)偏爱某个特定的操作,即Exploitation,而忽视其他操作,这样就无法收集到足够的资料。

    那怎么去权衡Exploration-Exploitation呢?这就引出了RL无模型法中的另一个重要概念:在策(on-policy)和离策(off-policy)

    在策(on-policy): 既然既要改进策略又需要保证探索,那么就设计一个策略(如 ε-soft策中的ε-greedy策略),使得其有比较大的概率在任务中利用目前探索到的最优操作,而以比较小的概率随机选择一个其他操作来探索。这样就保证了Exploration-Exploitation的平衡,如下图:

    在策版本的MC算法:摘自书中第5.4节

    可以证明若采用的ε-soft策略(即保证每个操作都有可能被选择),经过足够多的迭代,其可保证找到ε-soft空间下的下的最优策略---书中p83 5.4节。

    离策(off-policy): 既然既需Exploration也需要Exploitation,那为什么不设计两个策略呢?一个专门负责实际探索,一个专门负责寻找最优策略。

    这里负责实施的策略叫做行为策略(behavior policy)设为b,负责学习的策略为目标策略(target policy)设为π。而由于π本身并没有样本,需要从b策略产生的样本回报来估算,所以需要通过两个策略的关系来推测---由此引入统计学中的重要性采样:

    重要性采样:摘自书中第5.5节

    这个参数 
ho 就是用来调整某个样本回报G的系数。可见,该参数意义就是若目标策略π选择某个操作的概率大于b选择该操作的概率,那么应该放大G的效果,反之则应该缩小。而总体上为了计算估值有2种方式,一种是通过普通加权平均的普通模式:

    普通加权:摘自书中第5.5节

    另一种就是考虑各个回合不同权重的经典加权模式:

    经典加权:摘自书中第5.6节

    这里使用大写的 V(s) 代表状态 s 的“估值”,下文的 Q(s,a) 同理也是估值。

    由于分母不同,可见普通模式有高方差但低偏差(即样本足够真实但泛化性较差),而加权模式则相反。就实际情况而言,加权模式效果会比较好,而普通模式则极有可能因为高方差而无法收敛。不过根据书中说法,在函数拟合中普通模式也是有用武之地的。
    注意:为了保证这个p系数是有意义的,必需保证π中的每个会被选择的操作都有一定可能被b所选择。

    离策版MC法:摘自书中第5.7节

    上图就是off-policy的MC法了。这里特别注意看下对 Q值更新这一句。我们知道若是求算术平均的话可以写作:

    这里的 Q_{n+1} 指的是给定某个特定状态 s 和操作 a ,第 n+1 回合的估值。可见,所谓的算数平均 Q_{n+1} 就等价于是之前求的算术平均值 Q_n 加上最新获得样本回报 G_nQ_n 的差异。这个直观上也很好理解---一个新的估值总是建立在之前的经验上的,然后具体要修正的部分取决于新样本和经验上的差异。当每个样本所占的权重是一样的时候,这个差异所占的比例应该是 1over n 。 类似地,对于经典加权平均的版本,可得:

    egin{eqnarray} Q_{n+1}&=&Q_n+{W_nover C_n}[G_n-Q_n], spacespace ngeq 1 \&其中&\ C_{n+1}&=& C_n+W_{n+1} end{eqnarray}

    按照算术平均的概念,这个 1over n 会越来越大,即新的样本所含的话语权会越来越小。可见在RL中这种设定并不合理,所以使用加权模式的做法更好。

    而更一般地,我们可以将该差异的比例值抽象为 alpha 。由于其决定了对新样本的学习程度,我们也管它叫学习率,所以该估值就有了更一般的形式: Q_{n+1}=Q_n+alpha(G_n-Q_n)
    这种形式的更新由于不需要像传统做法那样将每个样本的值都存放在内存中,所以是一个很有效率的做法---被称为递增法(Incremental Implementation)。

    总的来说, 
m MC 法不管是哪种形式,其总算是给出了一种基于无模型的方法,可操作性比 
m DP 法更强。但作为一个线下学习方法,其只有等到每个回合结束后才能对策略进行更新,效率不高。那该怎么克服这个问题呢?

    寻策法3:时间差法(Temporal Difference)

    为了克服MC法只有等到回合结束才能更新的弊端,而同时又要保证无模型的前提。自然会想:真的有必要等到回合结束后才能够更新估值吗?

    为了便于说明,我们将之前提到的递增式估值公式写成如下形式:

    Q_{n+1}(s,a)=Q_n(s,a)+alpha[G_n-Q_n(s,a)]

    这里为了不用等到回合结束才能更新估值,我们对 G_n 做下改造,其中的s’代表同一回合中的下一step的状态, a' 泛指该 s' 状态下的某一操作:

    G_n=r+Q(s',a')

    上式直接将当前状态的回馈和下一状态的估值结合在一起作为本状态的回报 G_n ,这种方法叫做TD法。

    那么这种方法靠谱吗?幸运的是,有理论证明在保证学习率足够小的情况下,TD法的估值是可以收敛的。至于其和MC法孰优孰劣,目前虽无理论证明,但是一般情况下TD法总是能比MC法更快收敛。(这类方法是目前RL界的主流,务必记住)

    同样的因和MC法一样都是无模型法,所以会有在策和离策2种情况:

    sarsa算法:摘自书中第6.4节

    上图就是在策形式的TD法了,一般叫sarsa。下图是离策版本的TD法,一般叫Q-learning:

    Q-learning算法:摘自书中第6.5节

    注意,在Q-learning中其Q值的估算是直接用到下个状态在目标策略π下的估值,因此,这里不需要像MC的离策版那样使用重要性采样系数。

    可以通过Cliff Walking任务来比较下Sarsa和Q-Learning思想上的区别:

    sarsar和Q-learning差异,cliff-walking演示:摘自书中第6.5节

    可见:Sarsa因为会根据e-greedy(非最优)的策略操作来学习估值并实战应用,所以在这类框架下,其找到的“最优”策略会为了规避e-greedy策略本身的探索风险而绕远路,但相应的其在训练中的平均得分较高;相反Q-Learning因为在后台是学习的最优策略的估值,则基于此agent在实际交互中最后所选择的操作会因为e-greedy策略中探索因子而收到影响,所以得分并不高。 一句话:Sarsa要面子不要里子,Q-Learning要里子不要面子。

    关于Q-learning这一部分内容可以参考这个视频:Active Reinforcement Learning -- Q-Learning

    一般来说,人们倾向于使用Q-Learning这类离策学习方法,因为其只要结果收敛,则找到的一定是最优策略。但问题正在于离策法的收敛性不能绝对保证,这也是目前RL中比较热门的研究课题。

    寻策法总结

    到目前为止,我们已经讨论了3大类RL寻策方法,分别是需要模型的DP法、不需要模型的线下学习MC法及不需要模型且可以在线学习的TD法。这些方法的属性大致如下:

    各类方法对比图

    让Agent学会举一反三:函数拟合(Function Approximation)

    前面讲述的所有方法都有个共同点---通过将每个状态(或 Q值)值保存下来,然后不断更新---即查表法。不难理解,现实中碰到的很多任务其状态空间非常的大,所以若是像之前讲述的根据每一个状态进行估值(即查表法),显然不现实。所以必须有一种办法可以通过已观测到的状态来泛化推测其他还未曾观测到的状态估值。

    我们知道人从来不可能遇到同一条河流2次,但我们依然可以对过往的现实进行总结并将总结的规律利用到未来。原理正在于虽然同样的状态理论上是不可能再次碰到的,但状态与状态间总是有相似性的,其规律是共通的----鉴于该思想,我们可以采用函数拟合(Function Approximation)来对为曾见过的状态给予一个较合理的估值。

    (这里的内容若你对机器学习中的监督学习比较熟悉的话会比较好理解)

    类似于机器学习领域的监督学习,既然要拟合,那就要知道输入、输出以及优化的目标函数是什么。在RL中,输入的是状态,输出的是该状态的估值, Q值的情况类似。若使用常见的均方误差作为优化目标,以w为参数,整个更新(学习)过程的公式就是:

    egin{eqnarray} w_{t+1}&=&w_t-{1over 2}alpha
ablaleft[v_pi(S_t)-hat v(S_t,w_t)
ight]^2\ &=&w_t+alpha[v_pi(S_t)-hat v(S_t,w_t)]
abla hat v(S_t,w_t) end{eqnarray}

    所以,MC版的函数拟合算法就是:

    带函数拟合的MC算法:摘自书中第9.3节

    但注意到,MC法中的“真标签”可以写成从某一time step到该回合结束后的整体回报 G_t,这是无偏的---梯度下降法这样用没问题。然而TD法这种需要在线学习的方法,我们只能将 v_pi(S_t) 替换成对状态 S_t 的估值,即:

    w_{t+1}=w_t+alpha[{U(S_t)}-hat v(S_t,w_t)]
abla hat v(S_t,w_t)

    那么利用基于bootstrapping的 
m TD 法就可以写成:

    带函数拟合的基本TD算法:摘自书中第9.3节

    这种在真标签中也使用了估值的梯度下降法叫“半梯度下降法”(semi-gradient descent)。

    注意:这种方法不一定能保证收敛。

    sarsa:

    带函数拟合的sarsa算法:摘自书中第10.1节

    Q-learning:

    从sarsa到Q-Learning只需将w的更新那句更改为:

    wleftarrow w+alpha[R+gamma argmax_a hat q(S',a,w)-hat q(S,A,w)] 
ablahat q(S,A,w)

    常用的拟合模型

    应该说但凡是可以在监督学习中使用的模型,都可以被用在RL中作为拟合的模型。最简单的不外乎是线性回归。复杂一点的有神经网络。其他类型的模型详见书中第9章的第9.4~9.9小节。

    函数拟合法的收敛性

    对监督学习有所了解的应该知道,收敛的保证需要训练样本满足IID(即独立同分布),或至少是近似IID。因此在RL的训练中,但凡满足以下全部3点的,则一定不收敛,否则可保证最终收敛:

    • 使用了函数拟合而不是表格法来训练(增加了不可收敛的隐患);
    • 真标签中使用了函数估值bootstapping(违反样本的独立性要求);
    • 使用了off-policy(违反样本的同分布性要求);

    上述三点的原话可参考书中第11.3节。

    换个角度思考问题:策略梯度法(Policy Gradient)

    考虑这样一个问题:有一个开车任务需要agent学习,操作集是关于方向盘的旋转角度的离散集合。那么很自然地,我们会知道当车辆需要经过一个左转弯道时,若最优操作是左转45°,那么左转46°或44°的结果应该是差不大多的。然而,基于之前所讨论的学习方法会有个很大的问题:e-greedy的策略极有可能会给出45°为最优操作,而其他所有操作均为同样糟糕(概率)的操作。这种结果(尤其是在部分可观测环境的任务中)明显是不合理的。那么要怎么规避呢?

    策略梯度法(以下简称:PG法)是另一种RL中的学习方法。相较于之前的方法需要知道每个状态(或 Q值),PG法的思路是直接从指定状态得到操作集的概率分布,然后根据分布选择相应操作。可见计算概率分布的方式先天的解决了上述开车问题,这是PG法的一个优势。而PG法的另一个优势在于真实世界的很多任务的操作空间不是离散分布的,借助于PG法,可以让agent更快的学习到相似操作的概率!。

    由于是学习概率分布,所以一般来说PG法需要用到函数拟合来学习策略参数 	heta

    J(	heta)=v_{pi_	heta}(s_0)	ag{7}

    	heta_{t+1}=	heta_t+alpha{widehat{ 
abla J(	heta_t)}} 	ag{8}

    式7的 J(	heta) 表示始于状态  s_0的策略 pi_	heta 的整体表现。而最终的目标就是通过式8学习到能使得整体表现越来越好的策略参数 	heta 。可见整个更新过程就是一个梯度上升法。现在问题是这个所谓的表现 J(	heta) 在理论上应该怎么表示呢?

    可以证明,若服从策略 pi 的状态分布为 mu(s) ,则衡量策略整体表现的 J(	heta) 是正比例于 sum_smu(s)sum_aq_pi(s,a)
abla_	hetapi(a|s,	heta) 的(证明详见书中p269)。那么有:

    egin{eqnarray} J(	heta)&propto&sum_smu(s)sum_aq_pi(s,a)
abla_	hetapi(a|s,	heta), \&=&mathbb E_pileft[sum_aq_pi(s_t,a)
abla_	hetapi(a|s,	heta)
ight], 	ag{9.1} \&=&mathbb E_pileft[sum_a pi(a|S_t,	heta)q_pi(s_t,a){
abla_	hetapi(a|s,	heta)over pi(a|S_t,	heta) }
ight], \&=&mathbb E_pileft[q_pi(S_t,A_t) {
abla_	hetapi(A_t|S_t,	heta)over pi(A_t|S_t,	heta) } 
ight], \&=&mathbb E_pileft[G_t{
abla_	hetapi(A_t|S_t,	heta)over pi(A_t|S_t,	heta) } 
ight],	ag{9.2} \&=&mathbb E_pileft[G_t
abla_	heta {
m ln}\,pi(A_t|S_t,	heta)
ight].	ag{9.3} end{eqnarray}

    上述公式就是一个从总体到样本的过程。首先是式9.1这里去掉了状态的分布,然后式9.2则是更进一步去掉了状态 S_t 下的操作分布 a ,取而代之的是样本 A_t ,以及最后的简化形式9.3。之所以这么做的目的正在于RL的学习往往是基于不断增加的样本的,所以只有样本化的公式才有意义。所以PG法的参数更新公式是:

    egin{eqnarray} 	heta_{t+1}=	heta_t+alpha G_t
abla_	heta {
m ln}\,pi(A_t|S_t,	heta_t) end{eqnarray}

    REINFORCE算法

    利用上述这种更新方法来更新参数的PG法叫做 
m REINFORCE 法,也是最基本的一种方法。但这种方法的方差很大,因其更新的幅度完全某回合中依赖于 t 时刻到结束时候的真实样本回报 G_t 。所以更常见的一种做法是引入一个基准线(baseline) b(s) ,于是有:

    	heta_{t+1}=	heta_t+alpha (G_t-b(S_t))
abla_	heta {
m ln}\,pi(A_t|S_t,	heta_t)

    至于这 b(s) 是什么,这取决于算法的设计。但一般的做法是取 b(s)=hat v(s) ,如此一来 Gt-b(St)=Gt-hat v(St) 。易得,这种情况下参数的更新主要取决于状态 S_tA_t 相对于状态均值的优势。该值大于0,则代表有优势---则更新后的参数会增加该操作的概率。小于0,则代表有劣势---泽更新后的参数会减少该操作的概率。

    带有基准的REINFORCE算法:摘自书中第13.5节

    根据书中的说法,可凭借经验对 alpha^w 取值,但 alpha^	heta 的取值则需要针对策略的参数和回馈大小来认真设计。

    另外,虽然PG法需要2组参数来分别应对状态值和策略,但实际上这2组参数并不要求完全独立。比如若使用神经网络,那么可以设计2个输出---一个针对策略的概率分布,另一个是针对状态的估值,并共享一部分的参数。

    Actor-Critic算法

    REINFORCE法在更新时依然需要每回合的真实回报 G_t ,即这是一个线下学习的方法。那么相应的,使用状态估值作为基准线的线上学习法的更新公式为: egin{eqnarray} 	heta_{t+1}&=&	heta_t+alpha (G_{t:t+1}-b(S_t))
abla_	heta {
m ln}\,pi(A_t|S_t,	heta_t)\ &=&	heta_t+alpha left(R_{t+1}+gammahat v(S_{t+1},{
m w})-hat v(S_{t+1},{
m w})
ight)
abla_	heta {
m ln}\,pi(A_t|S_t,	heta_t)\ end{eqnarray}

    关于Actor-Critic法的成功案例可以参考热门的A3C算法

    后记

    笔记记录到目前为止,基本是已经把RL中所有的核心概念都梳理了一遍。当然还有细节没有讲,比如TD估值的时候可以从单纯的考虑下一step的估值到考虑下n个step的估值,即TD(N)(书中第7章)。甚至更进一步,调整agent观察的角度,反向地去更新估值---即资格迹(eligibility trace)(书中第12章,参考1参考2参考3)。这些内容之所以不细说,一是为了结构简介,二是笔者也未完全掌握,所以就不细说了 。

    另外,笔者在学习RL的时候为了整理思路,也画了一个思维导图。目前还在完善中,可能有点乱。But anyway,希望能够帮助到大家~

  • 相关阅读:
    Oracle中查看建立索引和使用索引的注意点
    一个父亲的教育札记——leo鉴书58
    puma 配置,启动脚本
    HDU 6003 Problem Buyer
    c# 类间关系
    前台线程和后台线程总结
    多线程学习进程
    进程类的使用
    c#异步编程
    【程序17】
  • 原文地址:https://www.cnblogs.com/legendsun/p/8660583.html
Copyright © 2020-2023  润新知