基于policy的强化学习

一、actor的作用和设计

和以往的机器学习手段类似,强化学习的目的是为了学习一个“function”,这个“function”描述了agent对环境的观测(observation)和他采取的action之间的关系。即:action=f(observation),具体寻找这个“function”的步骤主要分为三部:

1.定义这个抽象的actor

​ 比如我们可以使用神经网络来对这个抽象的“function”进行描述,在这种情况下,actor就指的是neural network。

​ 我们以深度强化学习为例,在深度强化学习中,我们使用神经网络作为actor,那么我们就需要定义neural network的输入输出。具体而言,该神经网络的输入应该定义为对当前environment的observation,二网络的输出可以定义为具体的action,一个简单的例子如下:

基于policy的强化学习

2.定义actor的好坏

在讲述这个问题之前,我们首先要明确一下强化学习的训练过程,这里要引入一个“episode”的概念,它指的是进行了若干次循环的“get observation”->“take action”->"obtain reward"过程。对于一个actor而言,我们衡量其优劣是站在整个“episode”的角度出发的,而不是从每一次得到“reward”的角度进行优化的。一般,我们为了衡量某个actor性能的优劣,可以将整个“episode”内的reward进行累加,从而通过优化手段,使得模型能够在一段我们期望的操作时间内得到最优的reward。接下来我们推导整个“episode”中的reward函数。

我们设置整个episode内的操作记录为:
τ={s1,a1,r1,s2,a2,r2,,sT,aT,rT} \tau=\{s_1,a_1,r_1,s_2,a_2,r_2,\cdots,s_T,a_T,r_T\}
其中,
st:tat:tactionrt:treward s_t:t时刻的环境状态\\ a_t:t时刻的action\\ r_t:t时刻的reward
该episode内的reward记作:
R(τ)=t=1Trt R(\tau)=\sum_{t=1}^{T}r_t
对这个actor进行多次的训练之后,每一个episode都对应着一个reward,在总共的N个episode中,变量τ\tau

的分布服从于概率P(τθ)P(\tau|\theta),为了依据这个概率分布求得所有N次训练中的reward,我们求reward对该概率分布的期望,即:
Rθ=τR(τ)P(τθ)1Nn=1NR(τn) \overline{R_\theta}=\sum_\tau R(\tau)\cdot P(\tau|\theta) \approx \frac{1}{N}\sum_{n=1}^N R(\tau_n)

3.选择最好的actor(对actor参数进行优化)

为了选择最好的actor,我们使用梯度上升的方法,对整体的reward进行最优化。具体而言,我们迭代的对网络参数θ\theta进行更新:
start with θ0θ1  θ0+ηRθ0θ2  θ1+ηRθ1 start\ with\ \theta_0\\ \theta_1\ \leftarrow\ \theta_0+\eta\nabla \overline{R}_{\theta_0}\\ \theta_2\ \leftarrow\ \theta_1+\eta\nabla \overline{R}_{\theta_1}\\ \cdots
其中,网络参数的梯度Rθn\nabla \overline{R}_{\theta_n}具体为:
Rθ=[Rθ/ω1Rθ/ω2Rθ/b1Rθ/b2]gradientdd \nabla \overline{R}_{\theta}= \begin{bmatrix} \partial \overline{R}_{\theta}/\partial \omega_1 \\ \partial \overline{R}_{\theta}/\partial \omega_2 \\ \cdots\\ \partial \overline{R}_{\theta}/\partial b_1 \\ \partial \overline{R}_{\theta}/\partial b_2 \\ \cdots \end{bmatrix}gradientdd
正如上式所描述的,gradient ascent的原理十分简单,但是在程序中,为了求出这个梯度Rθ0\nabla \overline{R}_{\theta_0},我们还需进行一些处理,以便使用程序快速有效的进行运算,同时使我们对参数更新的过程有一个新的认识。接下来我们就对一个episode内的total reward进行化简。
Rθ=τR(τ)P(τθ) \overline{R}_\theta=\sum_\tau R(\tau)\cdot P(\tau|\theta)

Rθ=τR(τ)P(τθ)=τR(τ)P(τθ)P(τθ)P(τθ)=τR(τ)P(τθ)logP(τθ)(dlog(f(x))dx=1f(x)df(x)dx)1Nn=1NR(τn)logP(τθ) \nabla \overline{R}_\theta = \sum_\tau R(\tau) \cdot \nabla P(\tau|\theta)\\ =\sum_\tau R(\tau)P(\tau|\theta) \cdot \frac{\nabla P(\tau|\theta)}{P(\tau|\theta)}\\ =\sum_\tau R(\tau)P(\tau|\theta) \nabla log P(\tau|\theta)\\(这一步基于微分关系:\frac{dlog(f(x))}{dx} = \frac{1}{f(x)} \cdot \frac{df(x)}{dx})\\ \approx \frac{1}{N} \cdot \sum_{n=1}^{N} R(\tau^{n}) \nabla log P(\tau|\theta)

从以上表达式中可以看到,整个梯度只和条件概率P(τθ)P(\tau|\theta)有关,我们接下来对这个条件概率的梯度进行推导。首先注意到操作记录的定义为:
τ={s1,a1,r1,s2,a2,r2,,sT,aT,rT} \tau=\{s_1,a_1,r_1,s_2,a_2,r_2,\cdots,s_T,a_T,r_T\}

P(τθ)=p(s1)p(a1s1,θ)p(r1,s2s1,a1)p(a2s2,θ)p(r2,s3s2,a2)=p(s1)t=1Tp(atst,θ)p(rt,st+1st,at) P(\tau|\theta)=p(s_1)p(a_1|s_1,\theta)p(r_1,s_2|s_1,a_1)p(a_2|s_2,\theta)p(r_2,s_3|s_2,a_2) \cdots\\ =p(s_1) \prod_{t=1}^{T}p(a_t|s_t,\theta)p(r_t,s_{t+1}|s_t,a_t)

接下来根据之前梯度表达式,我们对上式取对数,得到:
logP(τθ)=logP(s1)+t=1TlogP(atst,θ)+logP(rt,st+1st,at) logP(\tau|\theta) = logP(s_1)+\sum_{t=1}^T logP(a_t|s_t,\theta)+logP(r_t,s_{t+1}|s_t,a_t)
在原有的梯度表达式中,我们需要求出上式的梯度,在上式中只有第二项与网络参数有关,所以求了梯度之后,只剩下第二项,我们把上式代入之前的梯度表达式。
Rθ1Nn=1NR(τn)logP(τnθ)=1Nn=1NR(τn)t=1TnlogP(atnstn,θ)=1Nn=1Nt=1TnR(τn)logP(atnstn,θ) \nabla \overline{R}_\theta \approx \frac{1}{N} \cdot \sum_{n=1}^{N} R(\tau^{n}) \nabla log P(\tau^n|\theta)\\ = \frac{1}{N} \cdot \sum_{n=1}^{N} R(\tau^{n}) \sum_{t=1}^{T_n} \nabla logP(a_t^n|s_t^n,\theta)\\ = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n})\nabla logP(a_t^n|s_t^n,\theta)
至此,我们就得到了一个episode中的reward的梯度。

在得到了梯度之后,我们将思路回到整个gradient ascent算法,与gradient ascent算法类似,整个网络参数的更新会使得目标函数沿着梯度最大的方向增加,然而目标函数的梯度变化至于其表达式中的“梯度目标项”logP(atnstn,θ)logP(a_t^n|s_t^n,\theta)有关,所以,随着网络参数的更新,“梯度目标项”也会不断增加。那么基于此,我们可以对整个梯度上升的过程产生一个定性的解释:

(1)当某一个episode内,reward函数为正时,网络参数θ\theta的更新会使得P(atnstn)P(a_t^n|s_t^n)增加,这一项增加就意味着更新后的网络参数θ\theta会使得actor增加之后当出现状态stns_t^n时的,采取动作atna_t^n的概率。
(2)当某一个episode内,reward函数为负时,网络参数θ\theta的更新会使得P(atnstn)P(a_t^n|s_t^n)减小,这一项减小就意味着更新后的网络参数θ\theta会使得actor减小之后当出现状态stns_t^n时的,采取动作atna_t^n的概率。
(1)question1:为什么使用微分关系对梯度表达式进行化简?

以上的解释无疑是十分符合一般逻辑的,因此,我们也从侧面印证了这种算法的正确性。

接下来,我们回到之前的式子,讨论为什么要使用那样一组微分关系对表达式进行化简,以及这么做能够带来什么好处。首先,我们已经知道,随着参数更新的过程,神经网络其实在调整所有的条件概率P(atnstn)P(a_t^n|s_t^n),对于那些使得reward为正的episode,神经网络会增加本次episode内所有操作的条件概率P(atnstn)P(a_t^n|s_t^n),反之当reward为负的情况,神经网络会将本次episode内所有操作的条件概率P(atnstn)P(a_t^n|s_t^n)减少。从这个过程我们发现,其实可能会存在这样一种情况,对于某一特定的环境状态ss,在整个训练过程中出现了若干次,在这若干次对应的action中,存在着一个概率分布,有些action被采取的次数比较多,而有些action被采取的次数比较少,但是这些采取次数多的action所引起的“immediate reward”可能比那些采取次数少的action所引起的“immediate reward”少,对于这种情况,根据整个网络参数更新的规则,随着网络参数的不断更新,这两种action对应的条件概率P(atnstn)P(a_t^n|s_t^n)可能都在增加,而且采取次数多但是“immediate reward”较小的那种action所对应的条件概率增加的会更多(因为梯度的增减其实就是依据“total reward”的正负,修改每个系统状态所对应的条件概率),然而这可能并不是一个最优的结果,为了解决这个问题,使用微分关系:dlog(f(x))dx=1f(x)df(x)dx)\frac{dlog(f(x))}{dx} = \frac{1}{f(x)} \cdot \frac{df(x)}{dx}),相当于对条件概率的梯度进行了归一化,从而避免了total reward因为这种情况从而没有达到全局最优:
1Nn=1Nt=1TnR(τn)p(atnstn,θ)p(atnstn,θ)=1Nn=1Nt=1TnR(τn)logP(atnstn,θ) \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n}) \cdot \frac{\nabla p(a_t^n|s_t^n,\theta)}{p(a_t^n|s_t^n,\theta)} = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n})\nabla logP(a_t^n|s_t^n,\theta)

(2)question2:当所有的total reward都为正会出现什么,怎么办?

在有些问题场景中,所有的action都对应着一个非负的reward,那么对于梯度更新算法来说,很明显,效果可能会受到一些影响。先观察理想情况:

基于policy的强化学习

在理想情况中,一个重要的假设就是**“对于每一个系统状态s,其对应的所有可能的action都会被采样到”**,那么经过若干次的参数更新之后,即便每一种action的reward都为正,最后采取每一种action的概率还是会按照每一种action对应的reward的相对关系进行变化。貌似这并不会造成什么影响。

但是在实际情况中,对于每一个系统状态s,其对应的所有action不一定都会被采样到。

基于policy的强化学习

比如,当状态s对应的action中,只有b和c被采样到,那么,根据参数更新的所造成的影响,b和c这两种action所对应的条件概率P(abs)P(a_b|s)P(acs)P(a_c|s)会增加,那么显然,a对应的条件概率P(aas)P(a_a|s)自然就会减少。然而这种情况是我们不想看到的。

为了解决这一问题,我们引入baseline:
Rθ1Nn=1Nt=1Tn(R(τn)b)logP(atnstn,θ) \nabla \overline{R}_\theta \approx \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}(R(\tau^{n})-b)\nabla logP(a_t^n|s_t^n,\theta)
通过这一措施,我们使得所有的reward有正有负,这样就不会盲目的增加所有的action对应的条件概率,从而导致的有些action由于没有被采样的从而其条件概率减少这种情况。

二、关于critic的作用和设计

在众多的强化学习模型中,“Actor-Critic”模型得到了许多研究者的青睐,它也作为一种常用的强化学习模型,在许多问题上取得了不错的效果。在“Actor-Critic”模型中,除了上文中所讲到的“Actor”,“Critic”也扮演者比较重要的角色。

(1)首先,critic没有办法决定所采取的action

(2)critic的作用是为了衡量一个给定的actor的优劣程度

1.基于neural network的reward estimator

一个基于neural network的reward estimator的critic可以表示为Vπ(s)V^\pi(s),这个意思就是,在给定的actorπ\pi条件下,根据当前的observation,计算出当前episode的total reward的期望值。值得注意的是,针对于同样的observation,如果actor不同,那么使用critic得出的值也可能是不一样的。

那么现在就出现了一个问题,如何计算上述的这种critic:Vπ(s)V^\pi(s),常见的解决方法有两种:1.基于Monte-Carlo的方法;2.Temporal-difference的方法

(1)基于Monte-Carlo的方法

这种方法是建立在大量的实验基础上的,我们首先要明确,我们所建立的Vπ(s)V^\pi(s)实际上是从observation到一个reward的期望之间的映射,所以我们可以采取以下的策略:

记录每次actor与环境进行交互的过程,每一次的observation和该批次的total reward作为用于训练critic的样本点,对神经网络进行训练,从而使得critic能够对之后的observation做出有价值的判断。

(2)Temporal-difference的方法

与上一个方法比较类似的是,这个方法同样是基于观察,但是,这个方法用于训练的样本点是每一次的observation和每一次的immediate reward,将这个immediate reward作为两个神经网络的差值进行训练,这两个神经网络只有输入不同,分别输入的是得到这个immediate reward 之前和之后的两次observation。

基于policy的强化学习

使用这个方法的优势在于,能够立即开始critic的训练,而不必等待一次episode结束,对于一些episode比较长的情况比较有优势。

2.基于Q-function的critic

这种critic可以写作Qπ(s,a)Q^\pi(s,a),它能够根据当前时刻的observation和当前时刻actor所采取的action,得到一个对于累积的reward的估计。与之前的critic比较类似,只不过它的输入参数多了当前时刻的action

基于policy的强化学习

一个简单的Q-function实现方式如上图所示,当actor所采取的action是可以穷举的时候,我们可以使用Q-function对所有可能的action计算得到相应的accumulated reward,如下图所示.

基于policy的强化学习

使用Q-function我们可以实现一种新的强化学习方法——Q-learning,一个简单的Q-learning的结构如下图所示,其基本思路是,在一个actor与环境发生互动之后,Q-function通过观察整个互动,根据observation和相应的action得到一个结果,该结果可以用于衡量该actor的优劣程度,之后,我们在对actor进行进一步的优化调整。

基于policy的强化学习

在以上的这个过程中,一个十分重要的环节就是,如何根据现有的actor π\pi和Q-function,得到一个更优的actor π\pi'呢?其实思路还是比较简单,我们首先定义这个“更优的”actor:
Vπ(s)Vπ(s)πis  better  than  π V^{\pi'}(s) \ge V^{\pi}(s) \Leftrightarrow \pi' \, is \,\,better \,\, than \,\, \pi
我们可以通过以下的表达式得到一个更优的actor的输出π(s)\pi'(s)
π(s)=argmaxaQπ(s,a) \pi'(s)=arg\, \mathop{max}\limits_{a} Q^\pi(s,a)
这个表达式的意义在于,一个更优的actor的输出是所有action中使得Q-function最大的那一个,这也就意味着,要想得到最优的actor,就必须要遍历所有可能的action,然而这只有在action为离散的情况下才能实现。其实“找到更优的actor”是通过直接给出“更优的actor”对应的输出实现的。

具体得到这样一个Q-function的方法,与上述的critic类似,可以使用MC或TD的方法得到。

那么常用的实现Q-learning的具体网络就是DQN,具体的网络架构以及基本概念可以参考文献:

《Rainbow: Combining Improvements in Deep Reinforcement Learning》,文献连接:https://www.aaai.org/ocs/index.php/AAAI/AAAI18/paper/viewPaper/17204

三、如何实现 policy gradient算法

实现policy gradient算法的核心是得到actor的参数。

首先,我们先回顾一下整个算法的流程:

对于一个给定的actor参数θ\theta,我们训练若干个episode,得到若干个对应的操作记录τ1,τ2,τN\tau^1,\tau^2,\cdots\tau^N,然后再利用这些操作记录,依据梯度更新公式Rθ=1Nn=1Nt=1TnR(τn)logP(atnstn,θ)\nabla \overline{R}_\theta = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n})\nabla logP(a_t^n|s_t^n,\theta)对网络参数进行更新。这两个步骤是一个相互迭代进行的过程。

接下来,我们来具体分析如何在程序中实现上述的操作,为了清晰的理解这一点,我们先考虑一个最基本的分类问题。

基于policy的强化学习

在这样一个基本的分类问题中,我们需要给网络送入打好标签的数据,在神经网络接受了训练样本点之后,得到相应的网络输出yiy_i,在经过onehot编码,得到了最终的action,我们将该样本点的标签记作y^i\hat y_i,对于这样的网络,我们进行训练时,选取的loss function为交叉熵:
i=1ny^ilogyi -\sum_{i=1}^n \hat y_i \cdot logy_i
训练的过程实际就是减少交叉熵的过程,观察交叉熵的表达式,我们不难发现,减小交叉熵的同时,其实就是将对数项logyilogy_i最大化,实际上,在用于分类的神经网络中,网络的输出yiy_i一般是经过了softmax层,被归一化为了概率的结果。所以我们可以将yiy_i理解作在给定当前输入(observation)条件下,采取各个action的概率,即:
logyi=logP(ais) logy_i = logP(a_i|s)
我们要最大化上式,就可以采用对上式进行gradient ascent,来达到它的最大值,即:
θθ+ηP(ais) \theta \leftarrow \theta + \eta \cdot \nabla P(a_i|s)
至此,我们来分析之前的梯度表达式:
Rθ=1Nn=1Nt=1TnR(τn)logP(atnstn,θ) \nabla \overline{R}_\theta = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n})\nabla logP(a_t^n|s_t^n,\theta)
我们发现,当我们去掉中间的reward,得到了以下的表达式:
Rθ=1Nn=1Nt=1TnlogP(atnstn,θ) \nabla \overline{R}_\theta = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}\nabla logP(a_t^n|s_t^n,\theta)
这个表达式中的梯度项就是之前的$logP(a_i|s)=logy_i $,也就是说,当我们将之前的梯度表达式中的reward项去掉之后,问题就退化成了一个基本的分类问题,而且该分类问题的每一个训练样本点就是一个操作记录中的每一个action与其对应的reward。

问题回到最初的如何实现policy gradient,我们可以得出一下的结论:只需要将每一次操作记录中的所有“observation-action”样本点都乘以这次episode中的reward,也就是一个权重。其实,在这个框架下,我们训练reinforcement learning的过程就比较清晰了:

(1)初始化网络参数

(2)使用当前网络参数在environment中进行一次交互,记作一个episode,得到一组“observation-action”,和当前episode对应的total reward

(3)进行此次训练,训练的过程就是将每一个“observation-action”作为一个样本点,对神经网络进行训练,只不过在训练的过程中,要在交叉熵的前面乘以当前episode的total reward

(4)反复进行步骤(2)、(3),完成训练# 基于policy的强化学习

一、actor的作用和设计

和以往的机器学习手段类似,强化学习的目的是为了学习一个“function”,这个“function”描述了agent对环境的观测(observation)和他采取的action之间的关系。即:action=f(observation),具体寻找这个“function”的步骤主要分为三部:

1.定义这个抽象的actor

​ 比如我们可以使用神经网络来对这个抽象的“function”进行描述,在这种情况下,actor就指的是neural network。

​ 我们以深度强化学习为例,在深度强化学习中,我们使用神经网络作为actor,那么我们就需要定义neural network的输入输出。具体而言,该神经网络的输入应该定义为对当前environment的observation,二网络的输出可以定义为具体的action,一个简单的例子如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wa1wrwCe-1596428175435)(F:\youdao_note\[email protected]\8437305fac71400ebaa75c598692049c\clipboard.png)]

2.定义actor的好坏

在讲述这个问题之前,我们首先要明确一下强化学习的训练过程,这里要引入一个“episode”的概念,它指的是进行了若干次循环的“get observation”->“take action”->"obtain reward"过程。对于一个actor而言,我们衡量其优劣是站在整个“episode”的角度出发的,而不是从每一次得到“reward”的角度进行优化的。一般,我们为了衡量某个actor性能的优劣,可以将整个“episode”内的reward进行累加,从而通过优化手段,使得模型能够在一段我们期望的操作时间内得到最优的reward。接下来我们推导整个“episode”中的reward函数。

我们设置整个episode内的操作记录为:
τ={s1,a1,r1,s2,a2,r2,,sT,aT,rT} \tau=\{s_1,a_1,r_1,s_2,a_2,r_2,\cdots,s_T,a_T,r_T\}
其中,
st:tat:tactionrt:treward s_t:t时刻的环境状态\\ a_t:t时刻的action\\ r_t:t时刻的reward
该episode内的reward记作:
R(τ)=t=1Trt R(\tau)=\sum_{t=1}^{T}r_t
对这个actor进行多次的训练之后,每一个episode都对应着一个reward,在总共的N个episode中,变量τ\tau

的分布服从于概率P(τθ)P(\tau|\theta),为了依据这个概率分布求得所有N次训练中的reward,我们求reward对该概率分布的期望,即:
Rθ=τR(τ)P(τθ)1Nn=1NR(τn) \overline{R_\theta}=\sum_\tau R(\tau)\cdot P(\tau|\theta) \approx \frac{1}{N}\sum_{n=1}^N R(\tau_n)

3.选择最好的actor(对actor参数进行优化)

为了选择最好的actor,我们使用梯度上升的方法,对整体的reward进行最优化。具体而言,我们迭代的对网络参数θ\theta进行更新:
start with θ0θ1  θ0+ηRθ0θ2  θ1+ηRθ1 start\ with\ \theta_0\\ \theta_1\ \leftarrow\ \theta_0+\eta\nabla \overline{R}_{\theta_0}\\ \theta_2\ \leftarrow\ \theta_1+\eta\nabla \overline{R}_{\theta_1}\\ \cdots
其中,网络参数的梯度Rθn\nabla \overline{R}_{\theta_n}具体为:
Rθ=[Rθ/ω1Rθ/ω2Rθ/b1Rθ/b2]gradientdd \nabla \overline{R}_{\theta}= \begin{bmatrix} \partial \overline{R}_{\theta}/\partial \omega_1 \\ \partial \overline{R}_{\theta}/\partial \omega_2 \\ \cdots\\ \partial \overline{R}_{\theta}/\partial b_1 \\ \partial \overline{R}_{\theta}/\partial b_2 \\ \cdots \end{bmatrix}gradientdd
正如上式所描述的,gradient ascent的原理十分简单,但是在程序中,为了求出这个梯度Rθ0\nabla \overline{R}_{\theta_0},我们还需进行一些处理,以便使用程序快速有效的进行运算,同时使我们对参数更新的过程有一个新的认识。接下来我们就对一个episode内的total reward进行化简。
Rθ=τR(τ)P(τθ) \overline{R}_\theta=\sum_\tau R(\tau)\cdot P(\tau|\theta)

Rθ=τR(τ)P(τθ)=τR(τ)P(τθ)P(τθ)P(τθ)=τR(τ)P(τθ)logP(τθ)(dlog(f(x))dx=1f(x)df(x)dx)1Nn=1NR(τn)logP(τθ) \nabla \overline{R}_\theta = \sum_\tau R(\tau) \cdot \nabla P(\tau|\theta)\\ =\sum_\tau R(\tau)P(\tau|\theta) \cdot \frac{\nabla P(\tau|\theta)}{P(\tau|\theta)}\\ =\sum_\tau R(\tau)P(\tau|\theta) \nabla log P(\tau|\theta)\\(这一步基于微分关系:\frac{dlog(f(x))}{dx} = \frac{1}{f(x)} \cdot \frac{df(x)}{dx})\\ \approx \frac{1}{N} \cdot \sum_{n=1}^{N} R(\tau^{n}) \nabla log P(\tau|\theta)

从以上表达式中可以看到,整个梯度只和条件概率P(τθ)P(\tau|\theta)有关,我们接下来对这个条件概率的梯度进行推导。首先注意到操作记录的定义为:
τ={s1,a1,r1,s2,a2,r2,,sT,aT,rT} \tau=\{s_1,a_1,r_1,s_2,a_2,r_2,\cdots,s_T,a_T,r_T\}

P(τθ)=p(s1)p(a1s1,θ)p(r1,s2s1,a1)p(a2s2,θ)p(r2,s3s2,a2)=p(s1)t=1Tp(atst,θ)p(rt,st+1st,at) P(\tau|\theta)=p(s_1)p(a_1|s_1,\theta)p(r_1,s_2|s_1,a_1)p(a_2|s_2,\theta)p(r_2,s_3|s_2,a_2) \cdots\\ =p(s_1) \prod_{t=1}^{T}p(a_t|s_t,\theta)p(r_t,s_{t+1}|s_t,a_t)

接下来根据之前梯度表达式,我们对上式取对数,得到:
logP(τθ)=logP(s1)+t=1TlogP(atst,θ)+logP(rt,st+1st,at) logP(\tau|\theta) = logP(s_1)+\sum_{t=1}^T logP(a_t|s_t,\theta)+logP(r_t,s_{t+1}|s_t,a_t)
在原有的梯度表达式中,我们需要求出上式的梯度,在上式中只有第二项与网络参数有关,所以求了梯度之后,只剩下第二项,我们把上式代入之前的梯度表达式。
Rθ1Nn=1NR(τn)logP(τnθ)=1Nn=1NR(τn)t=1TnlogP(atnstn,θ)=1Nn=1Nt=1TnR(τn)logP(atnstn,θ) \nabla \overline{R}_\theta \approx \frac{1}{N} \cdot \sum_{n=1}^{N} R(\tau^{n}) \nabla log P(\tau^n|\theta)\\ = \frac{1}{N} \cdot \sum_{n=1}^{N} R(\tau^{n}) \sum_{t=1}^{T_n} \nabla logP(a_t^n|s_t^n,\theta)\\ = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n})\nabla logP(a_t^n|s_t^n,\theta)
至此,我们就得到了一个episode中的reward的梯度。

在得到了梯度之后,我们将思路回到整个gradient ascent算法,与gradient ascent算法类似,整个网络参数的更新会使得目标函数沿着梯度最大的方向增加,然而目标函数的梯度变化至于其表达式中的“梯度目标项”logP(atnstn,θ)logP(a_t^n|s_t^n,\theta)有关,所以,随着网络参数的更新,“梯度目标项”也会不断增加。那么基于此,我们可以对整个梯度上升的过程产生一个定性的解释:

(1)当某一个episode内,reward函数为正时,网络参数θ\theta的更新会使得P(atnstn)P(a_t^n|s_t^n)增加,这一项增加就意味着更新后的网络参数θ\theta会使得actor增加之后当出现状态stns_t^n时的,采取动作atna_t^n的概率。
(2)当某一个episode内,reward函数为负时,网络参数θ\theta的更新会使得P(atnstn)P(a_t^n|s_t^n)减小,这一项减小就意味着更新后的网络参数θ\theta会使得actor减小之后当出现状态stns_t^n时的,采取动作atna_t^n的概率。
(1)question1:为什么使用微分关系对梯度表达式进行化简?

以上的解释无疑是十分符合一般逻辑的,因此,我们也从侧面印证了这种算法的正确性。

接下来,我们回到之前的式子,讨论为什么要使用那样一组微分关系对表达式进行化简,以及这么做能够带来什么好处。首先,我们已经知道,随着参数更新的过程,神经网络其实在调整所有的条件概率P(atnstn)P(a_t^n|s_t^n),对于那些使得reward为正的episode,神经网络会增加本次episode内所有操作的条件概率P(atnstn)P(a_t^n|s_t^n),反之当reward为负的情况,神经网络会将本次episode内所有操作的条件概率P(atnstn)P(a_t^n|s_t^n)减少。从这个过程我们发现,其实可能会存在这样一种情况,对于某一特定的环境状态ss,在整个训练过程中出现了若干次,在这若干次对应的action中,存在着一个概率分布,有些action被采取的次数比较多,而有些action被采取的次数比较少,但是这些采取次数多的action所引起的“immediate reward”可能比那些采取次数少的action所引起的“immediate reward”少,对于这种情况,根据整个网络参数更新的规则,随着网络参数的不断更新,这两种action对应的条件概率P(atnstn)P(a_t^n|s_t^n)可能都在增加,而且采取次数多但是“immediate reward”较小的那种action所对应的条件概率增加的会更多(因为梯度的增减其实就是依据“total reward”的正负,修改每个系统状态所对应的条件概率),然而这可能并不是一个最优的结果,为了解决这个问题,使用微分关系:dlog(f(x))dx=1f(x)df(x)dx)\frac{dlog(f(x))}{dx} = \frac{1}{f(x)} \cdot \frac{df(x)}{dx}),相当于对条件概率的梯度进行了归一化,从而避免了total reward因为这种情况从而没有达到全局最优:
1Nn=1Nt=1TnR(τn)p(atnstn,θ)p(atnstn,θ)=1Nn=1Nt=1TnR(τn)logP(atnstn,θ) \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n}) \cdot \frac{\nabla p(a_t^n|s_t^n,\theta)}{p(a_t^n|s_t^n,\theta)} = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n})\nabla logP(a_t^n|s_t^n,\theta)

(2)question2:当所有的total reward都为正会出现什么,怎么办?

在有些问题场景中,所有的action都对应着一个非负的reward,那么对于梯度更新算法来说,很明显,效果可能会受到一些影响。先观察理想情况:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UM3JkVv9-1596428175436)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200730211141954.png)]

在理想情况中,一个重要的假设就是**“对于每一个系统状态s,其对应的所有可能的action都会被采样到”**,那么经过若干次的参数更新之后,即便每一种action的reward都为正,最后采取每一种action的概率还是会按照每一种action对应的reward的相对关系进行变化。貌似这并不会造成什么影响。

但是在实际情况中,对于每一个系统状态s,其对应的所有action不一定都会被采样到。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1YmNrSBA-1596428175436)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200730211831670.png)]

比如,当状态s对应的action中,只有b和c被采样到,那么,根据参数更新的所造成的影响,b和c这两种action所对应的条件概率P(abs)P(a_b|s)P(acs)P(a_c|s)会增加,那么显然,a对应的条件概率P(aas)P(a_a|s)自然就会减少。然而这种情况是我们不想看到的。

为了解决这一问题,我们引入baseline:
Rθ1Nn=1Nt=1Tn(R(τn)b)logP(atnstn,θ) \nabla \overline{R}_\theta \approx \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}(R(\tau^{n})-b)\nabla logP(a_t^n|s_t^n,\theta)
通过这一措施,我们使得所有的reward有正有负,这样就不会盲目的增加所有的action对应的条件概率,从而导致的有些action由于没有被采样的从而其条件概率减少这种情况。

二、关于critic的作用和设计

在众多的强化学习模型中,“Actor-Critic”模型得到了许多研究者的青睐,它也作为一种常用的强化学习模型,在许多问题上取得了不错的效果。在“Actor-Critic”模型中,除了上文中所讲到的“Actor”,“Critic”也扮演者比较重要的角色。

(1)首先,critic没有办法决定所采取的action

(2)critic的作用是为了衡量一个给定的actor的优劣程度

1.基于neural network的reward estimator

一个基于neural network的reward estimator的critic可以表示为Vπ(s)V^\pi(s),这个意思就是,在给定的actorπ\pi条件下,根据当前的observation,计算出当前episode的total reward的期望值。值得注意的是,针对于同样的observation,如果actor不同,那么使用critic得出的值也可能是不一样的。

那么现在就出现了一个问题,如何计算上述的这种critic:Vπ(s)V^\pi(s),常见的解决方法有两种:1.基于Monte-Carlo的方法;2.Temporal-difference的方法

(1)基于Monte-Carlo的方法

这种方法是建立在大量的实验基础上的,我们首先要明确,我们所建立的Vπ(s)V^\pi(s)实际上是从observation到一个reward的期望之间的映射,所以我们可以采取以下的策略:

记录每次actor与环境进行交互的过程,每一次的observation和该批次的total reward作为用于训练critic的样本点,对神经网络进行训练,从而使得critic能够对之后的observation做出有价值的判断。

(2)Temporal-difference的方法

与上一个方法比较类似的是,这个方法同样是基于观察,但是,这个方法用于训练的样本点是每一次的observation和每一次的immediate reward,将这个immediate reward作为两个神经网络的差值进行训练,这两个神经网络只有输入不同,分别输入的是得到这个immediate reward 之前和之后的两次observation。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n9FMLcEZ-1596428175437)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200731160032155.png)]

使用这个方法的优势在于,能够立即开始critic的训练,而不必等待一次episode结束,对于一些episode比较长的情况比较有优势。

2.基于Q-function的critic

这种critic可以写作Qπ(s,a)Q^\pi(s,a),它能够根据当前时刻的observation和当前时刻actor所采取的action,得到一个对于累积的reward的估计。与之前的critic比较类似,只不过它的输入参数多了当前时刻的action

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ynjIYgx-1596428175438)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200731161631227.png)]

一个简单的Q-function实现方式如上图所示,当actor所采取的action是可以穷举的时候,我们可以使用Q-function对所有可能的action计算得到相应的accumulated reward,如下图所示.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sn5XQsIc-1596428175439)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200731161914038.png)]

使用Q-function我们可以实现一种新的强化学习方法——Q-learning,一个简单的Q-learning的结构如下图所示,其基本思路是,在一个actor与环境发生互动之后,Q-function通过观察整个互动,根据observation和相应的action得到一个结果,该结果可以用于衡量该actor的优劣程度,之后,我们在对actor进行进一步的优化调整。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-INMcLHN5-1596428175440)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200731162713528.png)]

在以上的这个过程中,一个十分重要的环节就是,如何根据现有的actor π\pi和Q-function,得到一个更优的actor π\pi'呢?其实思路还是比较简单,我们首先定义这个“更优的”actor:
Vπ(s)Vπ(s)πis  better  than  π V^{\pi'}(s) \ge V^{\pi}(s) \Leftrightarrow \pi' \, is \,\,better \,\, than \,\, \pi
我们可以通过以下的表达式得到一个更优的actor的输出π(s)\pi'(s)
π(s)=argmaxaQπ(s,a) \pi'(s)=arg\, \mathop{max}\limits_{a} Q^\pi(s,a)
这个表达式的意义在于,一个更优的actor的输出是所有action中使得Q-function最大的那一个,这也就意味着,要想得到最优的actor,就必须要遍历所有可能的action,然而这只有在action为离散的情况下才能实现。其实“找到更优的actor”是通过直接给出“更优的actor”对应的输出实现的。

具体得到这样一个Q-function的方法,与上述的critic类似,可以使用MC或TD的方法得到。

那么常用的实现Q-learning的具体网络就是DQN,具体的网络架构以及基本概念可以参考文献:

《Rainbow: Combining Improvements in Deep Reinforcement Learning》,文献连接:https://www.aaai.org/ocs/index.php/AAAI/AAAI18/paper/viewPaper/17204

三、如何实现 policy gradient算法

实现policy gradient算法的核心是得到actor的参数。

首先,我们先回顾一下整个算法的流程:

对于一个给定的actor参数θ\theta,我们训练若干个episode,得到若干个对应的操作记录τ1,τ2,τN\tau^1,\tau^2,\cdots\tau^N,然后再利用这些操作记录,依据梯度更新公式Rθ=1Nn=1Nt=1TnR(τn)logP(atnstn,θ)\nabla \overline{R}_\theta = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n})\nabla logP(a_t^n|s_t^n,\theta)对网络参数进行更新。这两个步骤是一个相互迭代进行的过程。

接下来,我们来具体分析如何在程序中实现上述的操作,为了清晰的理解这一点,我们先考虑一个最基本的分类问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9eVKvXS3-1596428175441)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200731105257385.png)]

在这样一个基本的分类问题中,我们需要给网络送入打好标签的数据,在神经网络接受了训练样本点之后,得到相应的网络输出yiy_i,在经过onehot编码,得到了最终的action,我们将该样本点的标签记作y^i\hat y_i,对于这样的网络,我们进行训练时,选取的loss function为交叉熵:
i=1ny^ilogyi -\sum_{i=1}^n \hat y_i \cdot logy_i
训练的过程实际就是减少交叉熵的过程,观察交叉熵的表达式,我们不难发现,减小交叉熵的同时,其实就是将对数项logyilogy_i最大化,实际上,在用于分类的神经网络中,网络的输出yiy_i一般是经过了softmax层,被归一化为了概率的结果。所以我们可以将yiy_i理解作在给定当前输入(observation)条件下,采取各个action的概率,即:
logyi=logP(ais) logy_i = logP(a_i|s)
我们要最大化上式,就可以采用对上式进行gradient ascent,来达到它的最大值,即:
θθ+ηP(ais) \theta \leftarrow \theta + \eta \cdot \nabla P(a_i|s)
至此,我们来分析之前的梯度表达式:
Rθ=1Nn=1Nt=1TnR(τn)logP(atnstn,θ) \nabla \overline{R}_\theta = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}R(\tau^{n})\nabla logP(a_t^n|s_t^n,\theta)
我们发现,当我们去掉中间的reward,得到了以下的表达式:
Rθ=1Nn=1Nt=1TnlogP(atnstn,θ) \nabla \overline{R}_\theta = \frac{1}{N} \cdot \sum_{n=1}^{N} \sum_{t=1}^{T_n}\nabla logP(a_t^n|s_t^n,\theta)
这个表达式中的梯度项就是之前的$logP(a_i|s)=logy_i $,也就是说,当我们将之前的梯度表达式中的reward项去掉之后,问题就退化成了一个基本的分类问题,而且该分类问题的每一个训练样本点就是一个操作记录中的每一个action与其对应的reward。

问题回到最初的如何实现policy gradient,我们可以得出一下的结论:只需要将每一次操作记录中的所有“observation-action”样本点都乘以这次episode中的reward,也就是一个权重。其实,在这个框架下,我们训练reinforcement learning的过程就比较清晰了:

(1)初始化网络参数

(2)使用当前网络参数在environment中进行一次交互,记作一个episode,得到一组“observation-action”,和当前episode对应的total reward

(3)进行此次训练,训练的过程就是将每一个“observation-action”作为一个样本点,对神经网络进行训练,只不过在训练的过程中,要在交叉熵的前面乘以当前episode的total reward

(4)反复进行步骤(2)、(3),完成训练

相关文章: