精华内容
下载资源
问答
  • 详解策略梯度算法
    千次阅读
    2022-01-20 15:52:59

    本文首发于行者AI

    引言

    根据智能体学习的不同,可将其分为Value-based方法、Policy-based方法以及Actor-Critic方法。之前我们介绍的Q-learning、Saras和DQN都是基于价值去学习,虽然这种强化学习方法在很多领域都获得较多的应用,但是它的局限性也是比较明显。首先这类算法基本上都是处理离散动作,建立简单的Q表,很难对连续动作进行处理,更无法建立庞大的Q表;其次基于价值的方法使用值函数去近似Q值,虽然可以较高效率地解决连续状态空间的问题,但动作依然只是离散的,动作选择的策略也是不会变化的,通常是一个确定性的策略,但有些实际问题需要的最优策略并不是确定性的,而是随机策略,比如石头剪刀布,如果按照一种确定性策略出拳,那么当别人抓住规律时,你就会输。所以我们需要引入一个新的方法去解决以上问题,比如策略梯度的方法。

    1. 蒙特卡罗

    再讲解策略梯度算法(Policy Gradient,简称PG)前,大家可以先了解一下蒙特卡罗算法,首先我们来看一个小故事:

    在火影时代,还是下忍的鸣人为了提升自己的能力,从木叶忍者任务中心接了一个C级任务,在做任务的时候,突然被一个戴面具的人困在幻境中。类似迷宫的幻境(出口是光之门,可以理解为带光的门),鸣人怎么走都出不去,这个幻境虽然有很多出口,但只有最近的出口通过光之门才能走出幻境,其他的出口虽然有光之门,但是过不去。有可能鸣人对数学方面也颇有造诣,他用自己学习的禁术多重影分身之术,分出很多个分身(假设足够多,不要问作为下忍的鸣人查克拉够不够,在危急时刻,他可以向体内的九尾借啊),然后开始对每一个分身交代任务:

    注意: 分身都从起点出发,每走一步,都会得到相应的查克拉补充或降低能量(奖励,有正有负)。且每一个分身面对分叉路口的选择都是平均选择。忽略奖励的折扣因子。

    1. 你们每个人都需要找到一个出口,不论远近,且途中每走一步都需要将自己所经过的路径和得到查克拉的多少记录到卷轴上;
    2. 记录走过的这条路径获得的总查克拉,原路返回到出发点;
    3. 将你们每个人得到的总奖励进行平均,最终结果汇报给我,作为当前出发点的值。
    4. 然后将出发点换成下一步可以选择的出发地,重复1~3。

    鸣人拿到所有路口的值后,每遇到一个分叉路口就选择值最大的那个路口,最终鸣人成功的走出了幻境。

    上面的故事其实是类似蒙特卡罗算法,具体如下;

    蒙特卡罗算法是基于采样的方法,给定策略 π \pi π,让智能体与环境进行交互,就会得到很多条轨迹。 每条轨迹都有对应的回报,我们把每条轨迹的回报进行平均,就可以知道某一个策略下面对应状态的价值。这句话拆分开来可以对应上述故事:

    1. 蒙特卡罗是基于采样的方法。(对应故事中鸣人的分身足够多)
    2. 需要给定一个策略 π \pi π(对应故事中每个分身遇到分叉路口都是平均选择)
    3. 智能体与环境进行交互,得到很多轨迹。(对应故事中每一个分身在幻境中找出口的过程,每个分身对应一条轨迹)
    4. 每条轨迹都有对应的回报。(对应故事中每个分身得到的总奖励)
    5. 将每条轨迹的回报进行平均,就得到对应状态的价值了。(对应鸣人将每个分身的总奖励进行平均)

    2. 策略梯度算法

    2.1 介绍

    在强化学习中,有三个组成部分:演员(actor)、环境和奖励函数。其中环境和奖励函数不是我们可以控制的,在开始学习之前就已经事先给定。演员里会有一个策略,它用来决定演员的动作。策略就是给定一个外界输入,它会输出演员现在应该要执行的动作。我们唯一可以做的就是调整演员里面的策略,使得演员可以得到最大的奖励。

    当我们将深度学习与强化学习相结合时,策略π就是一个网络,用 θ \theta θ表示 π \pi π的参数。举上面幻境的例子,输入就是当前分身所在的分叉路口,假设可以向上,向下,向左走,经过策略网络后,输出就是三个动作可以选择的概率。然后演员就根据这个概率的分布来决定它要采取的动作,概率分布不同,演员采取的动作也不同。简单来说,策略的网络输出是一个概率分布,演员根据这个分布去做采样,决定实际上要采取的动作是哪一个。

    其实PG就是蒙特卡罗与神经网络结合的算法,PG不再像Q-learning、DQN一样输出Q值,而是在一个连续区间内直接输出当前状态可以采用所有动作的概率。

    我们之前在讲解基于价值的方法中,使用价值函数近似将Q表更新问题变成一个函数拟合问题,相近的状态得到相近的输出动作,如下式,通过更新参数w使得函数f逼近最优Q值。
    Q ( s , a ) ≈ f ( s , a , w ) Q(s, a) \approx f(s, a, w) Q(s,a)f(s,a,w)
    在PG算法中,因为策略是一个概率,不能直接用来迭代,所以我们采取类似的思路,将其转化为函数形式,如下式所示,这时我们的目的则是使用带有 θ \theta θ参数的函数对策略进行近似,通过更新参数 θ \theta θ,逼近最优策略。
    π ( a ∣ s ) ≈ π θ ( s , a ) = P ( a ∣ s , θ ) π(a|s)≈πθ(s,a)=P(a|s,θ) π(as)πθ(s,a)=P(as,θ)
    现在有了策略函数,我们的目标当然是优化它,那么该如何知道优化后的策略函数的优劣呢。大家肯定会想到需要一个可以优化的目标函数,我们让这个目标函数朝着最大值的方向去优化,它的主要作用就是用来衡量策略的好坏程度。

    2.2 算法内容

    首先,我们可以把环境看成一个函数,这个函数一开始就先吐出一个状态,假如这个状态是游戏的画面,接下来演员看到这个游戏画面 s 1 s_{1} s1以后,选择了 a 1 a_{1} a1这个动作。环境把 a 1 a_{1} a1当作它的输入,再吐出 s 2 s_{2} s2,也就是吐出新的游戏画面。演员看到新的游戏画面,再采取新的动作 a 2 a_{2} a2。环境再看 a 2 a_{2} a2,再吐出 s 3 s_{3} s3。这个过程会一直持续到环境觉得应该要停止为止。

    在一场游戏中,演员通过与环境的不断交互最终结束,根据上述的说明,可以得到一条轨迹,表示为 τ \tau τ,其中 s s s表示状态, a a a表示行动, s 1 s_{1} s1 a 1 a_{1} a1表示演员在状态1的时候选择了动作1,后面的以此类推。如下式所示。
    τ = { s 1 , a 1 , s 2 , a 2 , ⋯   , s t , a t } \tau=\left\{s_{1}, a_{1}, s_{2}, a_{2}, \cdots, s_{t}, a_{t}\right\} τ={s1,a1,s2,a2,,st,at}
    那么假设当前演员的策略网络参数是 θ \theta θ,我们就可以计算这一条轨迹发生的概率。它取决于两部分,环境的动作和智能体的动作,如下式所示,它就表示一条轨迹产生后所发生的概率。
    p θ ( τ ) = p ( s 1 ) p θ ( a 1 ∣ s 1 ) p ( s 2 ∣ s 1 , a 1 ) p θ ( a 2 ∣ s 2 ) p ( s 3 ∣ s 2 , a 2 ) ⋯ = p ( s 1 ) ∏ t = 1 T p θ ( a t ∣ s t ) p ( s t + 1 ∣ s t , a t ) \begin{aligned} p_{\theta}(\tau) &=p\left(s_{1}\right) p_{\theta}\left(a_{1} \mid s_{1}\right) p\left(s_{2} \mid s_{1}, a_{1}\right) p_{\theta}\left(a_{2} \mid s_{2}\right) p\left(s_{3} \mid s_{2}, a_{2}\right) \cdots \\ &=p\left(s_{1}\right) \prod_{t=1}^{T} p_{\theta}\left(a_{t} \mid s_{t}\right) p\left(s_{t+1} \mid s_{t}, a_{t}\right) \end{aligned} pθ(τ)=p(s1)pθ(a1s1)p(s2s1,a1)pθ(a2s2)p(s3s2,a2)=p(s1)t=1Tpθ(atst)p(st+1st,at)
    环境的动作是指环境的函数内部的参数或内部的规则长什么样子,它是无法控制的,提前已经写好, p ( s t + 1 ∣ s t , a t ) p\left(s_{t+1} \mid s_{t}, a_{t}\right) p(st+1st,at) 代表环境。智能体的动作是指能够自己控制, p θ ( a t ∣ s t ) p_{\theta}\left(a_{t} \mid s_{t}\right) pθ(atst)代表智能体,给定一个状态 s t s_{t} st,演员要采取什么样的动作 a t a_{t} at会取决于演员的参数 θ \theta θ,所以这部分是演员可以自己控制的。随着演员的动作不同,每个同样的轨迹,它就会有不同的出现的概率。

    除了环境跟演员以外,还有奖励函数。给它输入 s 1 s_{1} s1 a 1 a_{1} a1,它告诉你得到 r 1 r_{1} r1。给它 s 2 s_{2} s2 a 2 a_{2} a2,它告诉你得到 r 2 r_{2} r2。把所有的 r r r都加起来,我们就得到了 R ( τ ) R(\tau) R(τ),代表某一个轨迹 τ \tau τ的奖励。

    在某一场游戏里面,我们会得到 R R R。通过调整演员内部的参数 θ \theta θ, 使得 R R R的值越大越好,这就是PG算法的优化目标。但实际上奖励并不只是一个标量,奖励 R R R是一个随机变量,因为演员在给定同样的状态会做什么样的动作,是具有随机性的。环境在给定同样的观测要采取什么样的动作,要产生什么样的观测,本身也是有随机性的,所以 R R R是一个随机变量。那么我们就可以计算,在给定某一组参数 θ \theta θ的情况下,得到的 R θ R_{\theta} Rθ的期望值是多少。期望值如下公式所示。
    R ˉ θ = ∑ τ R ( τ ) p θ ( τ ) = E τ ∼ p θ ( τ ) [ R ( τ ) ] \bar{R}_{\theta}=\sum_{\tau} R(\tau) p_{\theta}(\tau)=E_{\tau \sim p_{\theta}(\tau)}[R(\tau)] Rˉθ=τR(τ)pθ(τ)=Eτpθ(τ)[R(τ)]
    我们需要穷举所有可能的轨迹 τ \tau τ,每一个轨迹 τ \tau τ都有一个概率和一个总奖励 R R R。也可以从分布 p θ ( τ ) p_{\theta}(\tau) pθ(τ)采样一个轨迹 τ \tau τ,计算 R ( τ ) R(\tau) R(τ)的期望值,就是期望奖励。我们要做的事情就是最大化期望奖励。

    如何最大化期望奖励呢,既然是最大化,那么我们可以采用梯度上升的方式更新参数,使得期望奖励最大化。对 R ˉ \bar{R} Rˉ取梯度,这里面只有 p θ ( τ ) p_{\theta}(\tau) pθ(τ)是跟 θ \theta θ有关。整个策略梯度公式如下图所示。

    图1. 策略梯度公式

    其中,对 ∇ p θ ( τ ) \nabla p_{\theta}(\tau) pθ(τ)使用 ∇ f ( x ) = f ( x ) ∇ log ⁡ f ( x ) \nabla f(x)=f(x) \nabla \log f(x) f(x)=f(x)logf(x),得到 ∇ p θ ( τ ) = p θ ( τ ) ∇ log ⁡ p θ ( τ ) \nabla p_{\theta}(\tau)=p_{\theta}(\tau) \nabla \log p_{\theta}(\tau) pθ(τ)=pθ(τ)logpθ(τ)这个 ∇ f ( x ) = f ( x ) ∇ log ⁡ f ( x ) \nabla f(x)=f(x) \nabla \log f(x) f(x)=f(x)logf(x)大家可以把这个理解成一个固定的公式转换,记住即可。

    如下式所示,对 τ \tau τ进行求和,把 R ( τ ) R(\tau) R(τ) log ⁡ p θ ( τ ) \log p_{\theta}(\tau) logpθ(τ)这两项使用 p θ ( τ ) p_{\theta}(\tau) pθ(τ)进行加权,既然使用 p θ ( τ ) p_{\theta}(\tau) pθ(τ)进行加权,它们就可以被写成期望的形式。也就是你从 p θ ( τ ) p_{\theta}(\tau) pθ(τ)这个分布里面采样 τ \tau τ出来,去计算 R ( τ ) R(\tau) R(τ)乘上 log ⁡ p θ ( τ ) \log p_{\theta}(\tau) logpθ(τ),把它对所有可能的 τ \tau τ进行求和,就是这个期望的值。
    ∇ R ˉ θ = ∑ τ R ( τ ) ∇ p θ ( τ ) = ∑ τ R ( τ ) p θ ( τ ) ∇ p θ ( τ ) p θ ( τ ) = ∑ τ R ( τ ) p θ ( τ ) ∇ log ⁡ p θ ( τ ) = E τ ∼ p θ ( τ ) [ R ( τ ) ∇ log ⁡ p θ ( τ ) ] \begin{aligned} \nabla \bar{R}_{\theta} &=\sum_{\tau} R(\tau) \nabla p_{\theta}(\tau) \\ &=\sum_{\tau} R(\tau) p_{\theta}(\tau) \frac{\nabla p_{\theta}(\tau)}{p_{\theta}(\tau)} \\ &=\sum_{\tau} R(\tau) p_{\theta}(\tau) \nabla \log p_{\theta}(\tau) \\ &=E_{\tau \sim p_{\theta}(\tau)}\left[R(\tau) \nabla \log p_{\theta}(\tau)\right] \end{aligned} Rˉθ=τR(τ)pθ(τ)=τR(τ)pθ(τ)pθ(τ)pθ(τ)=τR(τ)pθ(τ)logpθ(τ)=Eτpθ(τ)[R(τ)logpθ(τ)]
    实际上这个期望值没有办法算,所以我们是用采样的方式来采样 N N N τ \tau τ,去计算每一笔的这些值,把它全部加起来,就可以得到梯度。我们就可以去更新参数,就可以去更新智能体,如下式所示。
    E τ ∼ p θ ( τ ) [ R ( τ ) ∇ log ⁡ p θ ( τ ) ] ≈ 1 N ∑ n = 1 N R ( τ n ) ∇ log ⁡ p θ ( τ n ) = 1 N ∑ n = 1 N ∑ t = 1 T n R ( τ n ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \begin{aligned} E_{\tau \sim p_{\theta}(\tau)}\left[R(\tau) \nabla \log p_{\theta}(\tau)\right] & \approx \frac{1}{N} \sum_{n=1}^{N} R\left(\tau^{n}\right) \nabla \log p_{\theta}\left(\tau^{n}\right) \\ &=\frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}} R\left(\tau^{n}\right) \nabla \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right) \end{aligned} Eτpθ(τ)[R(τ)logpθ(τ)]N1n=1NR(τn)logpθ(τn)=N1n=1Nt=1TnR(τn)logpθ(atnstn)

    ∇ log ⁡ p θ ( τ ) \nabla \log p_{\theta}(\tau) logpθ(τ) 的具体计算过程,如下式所示

    ∇ log ⁡ p θ ( τ ) = ∇ ( log ⁡ p ( s 1 ) + ∑ t = 1 T log ⁡ p θ ( a t ∣ s t ) + ∑ t = 1 T log ⁡ p ( s t + 1 ∣ s t , a t ) ) = ∇ log ⁡ p ( s 1 ) + ∇ ∑ t = 1 T log ⁡ p θ ( a t ∣ s t ) + ∇ ∑ t = 1 T log ⁡ p ( s t + 1 ∣ s t , a t ) = ∇ ∑ t = 1 T log ⁡ p θ ( a t ∣ s t ) = ∑ t = 1 T ∇ log ⁡ p θ ( a t ∣ s t ) \begin{aligned} \nabla \log p_{\theta}(\tau) &=\nabla\left(\log p\left(s_{1}\right)+\sum_{t=1}^{T} \log p_{\theta}\left(a_{t} \mid s_{t}\right)+\sum_{t=1}^{T} \log p\left(s_{t+1} \mid s_{t}, a_{t}\right)\right) \\ &=\nabla \log p\left(s_{1}\right)+\nabla \sum_{t=1}^{T} \log p_{\theta}\left(a_{t} \mid s_{t}\right)+\nabla \sum_{t=1}^{T} \log p\left(s_{t+1} \mid s_{t}, a_{t}\right) \\ &=\nabla \sum_{t=1}^{T} \log p_{\theta}\left(a_{t} \mid s_{t}\right) \\ &=\sum_{t=1}^{T} \nabla \log p_{\theta}\left(a_{t} \mid s_{t}\right) \end{aligned} logpθ(τ)=(logp(s1)+t=1Tlogpθ(atst)+t=1Tlogp(st+1st,at))=logp(s1)+t=1Tlogpθ(atst)+t=1Tlogp(st+1st,at)=t=1Tlogpθ(atst)=t=1Tlogpθ(atst)
    注意, p ( s 1 ) p\left(s_{1}\right) p(s1) p ( s t + 1 ∣ s t , a t ) p\left(s_{t+1} \mid s_{t}, a_{t}\right) p(st+1st,at)来自于环境,

    p θ ( a t ∣ s t ) p_{\theta}\left(a_{t} \mid s_{t}\right) pθ(atst)是来自于智能体。 p ( s 1 ) p\left(s_{1}\right) p(s1) p ( s t + 1 ∣ s t , a t ) p\left(s_{t+1} \mid s_{t}, a_{t}\right) p(st+1st,at)由环境决定,所以与 θ \theta θ无关,因此
    ∇ log ⁡ p ( s 1 ) = 0 \nabla \log p\left(s_{1}\right)=0 logp(s1)=0
    ∇ ∑ t = 1 T log ⁡ p ( s t + 1 ∣ s t , a t ) = 0 \nabla \sum_{t=1}^{T} \log p\left(s_{t+1} \mid s_{t}, a_{t}\right)=0 t=1Tlogp(st+1st,at)=0

    我们可以直观地来理解图1最终推导出来的公式,也就是在我们采样到的数据里面,采样到在某一个状态 s t s_{t} st要执行某一 个动作 a t a_{t} at s t s_{t} st a t a_{t} at它是在整个轨迹 τ \tau τ的里面的某一个状态和动作的对。 假设我们在 s t s_{t} st执行 a t a_{t} at,最后发现 τ \tau τ的奖励是正的,我们就要增加这一项的概率,就要增加在 s t s_{t} st执行 a t a_{t} at的概率。反之,在 s t s_{t} st执行 a t a_{t} at会导致 τ \tau τ 的奖励变成负的,我们就要减少这一项的概率。

    要计算上式,首先我们要先收集一大堆的 s s s a a a的对(pair),还要知道这些 s s s a a a在跟环境互动的时候,会得到多少的奖励。具体我们要拿智能体,它的参数是 θ \theta θ,去跟环境做互动,互动完以后,就会得到一大堆游戏的纪录。

    我们就可以把采样到的数据代到梯度公式里面,把梯度算出来。也就是把采样到的数据中的每一个 s s s a a a的对拿进来,算一下它的对数概率,也就是计算在某一个状态采取某一个动作的对数概率,对它取梯度,这个梯度前面会乘一个权重,权重就是这场游戏的奖励。有了这些以后,就会去更新模型。

    图2. 策略梯度算法

    更新完模型以后,我们要重新去收集数据再更新模型。注意,一般策略梯度采样的数据就只会用一次。把这些数据采样起来,然后拿去更新参数,这些数据就丢掉了。接着再重新采样数据,才能够去更新参数。不过这也是有解决方法的,接下来我们会介绍如何解决。

    2.3 技巧

    (1)增加基线

    • 在很多游戏中,得到的奖励总是正的,或者说最低也就是0。由于采取行动的概率和为1,当所有的reward都为正的时候,可能存在进行归一化后, R R R(权重)大的上升的多, R R R小的,归一化后它就是下降的。比如下面这种情况,假设某一状态下有三个动作,分别是 a a a, b b b, c c c,奖励都是正的。根据公式 ∇ R ˉ θ \nabla \bar{R}_{\theta} Rˉθ,我们希望将这三个动作的概率以及对数概率都拉高,但是它们前面的权重 R R R不一样,有大有小,所以权重大的,上升的多一点;权重小的,上升的少一些,又因为对数概率是一个概率,三个动作的和要为0,那么在做完归一化后,上升多的才会上升,上升的少的就是下降的。
    图3. 添加基线
    • 采样应该是一个期望,对所有可能的 s s s a a a的对进行求和。但真正在学习时,只是采样了少量的 s s s a a a的对而已。有一些动作可能从来都没有采样到。同样假设在某一个状态可以执行的动作有 a a a, b b b, c c c,但你可能只采样到动作 b b b或者只采样到动作 c c c,没有采样到动作 a a a。 现在所有动作的奖励都是正的,根据公式 ∇ R ˉ θ \nabla \bar{R}_{\theta} Rˉθ,它的每一项概率都应上升。因为 a a a没有被采样到,其它动作的概率如果都要上升, a a a的概率就下降。但 a a a不一定是一个不好的动作,它只是没被采样到。但概率却下降了,这显然是有问题的,所以我们希望奖励不要总是正的。

    为了解决奖励总是正的这一问题,可以把奖励减掉一项 b b b,如下式所示。
    ∇ R ˉ θ ≈ 1 N ∑ n = 1 N ∑ t = 1 T n ( R ( τ n ) − b ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}}\left(R\left(\tau^{n}\right)-b\right) \nabla \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right) RˉθN1n=1Nt=1Tn(R(τn)b)logpθ(atnstn)
    其中, b b b叫做基线,减掉 b b b以后,就可以让 R ( τ n ) − b R\left(\tau^{n}\right)-b R(τn)b这一项有正有负。所以如果得到的总奖励 R ( τ n ) R\left(\tau^{n}\right) R(τn)大于 b b b的话,就让它的概率上升。如果这个总奖励小于 b b b,就算它是正的,正的很小也是不好的,就要让这一项的概率下降。 b b b通常是把 τ n \tau^{n} τn的值取期望,算一下 τ n \tau^{n} τn的平均值,即 b ≈ E [ R ( τ ) ] b \approx E[R(\tau)] bE[R(τ)]。在实际训练的时候,不断地把 R ( τ n ) R\left(\tau^{n}\right) R(τn)的分数记录下来,不断地计算 R ( τ n ) R\left(\tau^{n}\right) R(τn)的平均值当作 b b b

    (2)分配合适的分数

    • 在同一场游戏或者同一个回合中,所有的状态跟动作的对都会使用同样的奖励项进行加权,这不公平,因为在同一场游戏中也许有些动作是好的,有些动作是不好的。假设整场游戏的结果是好的,但不代表每一个动作都是对的,反之,也是。举个例子,假设游戏很短,在 s 1 s_{1} s1执行 a 1 a_{1} a1的奖励 r 1 r_{1} r1是5,在 s 2 s_{2} s2执行 a 2 a_{2} a2的奖励 r 2 r_{2} r2是0,在 s 3 s_{3} s3执行 a 3 a_{3} a3的奖励 r 3 r_{3} r3是-2。整场游戏结束,总奖励为3。但不代表在 s 2 s_{2} s2执行动作 a 2 a_{2} a2是好的,因为这个正的分数,主要来自于在 s 1 s_{1} s1执行了 a 1 a_{1} a1, 跟在 s 2 s_{2} s2执行 a 2 a_{2} a2是没有关系的,也许在 s 2 s_{2} s2执行 a 2 a_{2} a2反而是不好的,因为它导致你接下来会进入 s 3 s_{3} s3,执行 s 3 s_{3} s3被扣分,所以整场游戏得到的结果是好的,并不代表每一个动作都是对的。因此在训练的时候,每一个状态跟动作的对,都会被乘上3。

    在理想的状况下,这个问题,如果采样够多是可以被解决的。但现在的问题是我们采样的次数不够多,所以我们计算这个状态-动作对的奖励的时候,不把整场游戏得到的奖励全部加起来,只计算从这个动作执行以后所得到的奖励。因为这场游戏在执行这个动作之前发生的事情是跟执行这个动作是没有关系的,所以在执行这个动作之前得到多少奖励都不能算是这个动作的功劳。跟这个动作有关的东西,只有在执行这个动作以后发生的所有的奖励把它加起来,才是这个动作真正的贡献。如下式。
    ∇ R ˉ θ ≈ 1 N ∑ n = 1 N ∑ t = 1 T n ( ∑ t ′ = t T n γ t ′ − t r t ′ n − b ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}}\left(\sum_{t^{\prime}=t}^{T_{n}} \gamma^{t^{\prime}-t} r_{t^{\prime}}^{n}-b\right) \nabla \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right) RˉθN1n=1Nt=1Tn(t=tTnγttrtnb)logpθ(atnstn)
    我们对未来的奖励做了一个折扣,因为时间越久,奖励的重要性就越小,折扣因子 γ \gamma γ γ ∈ [ 0 , 1 ] \gamma \in[0,1] γ[0,1],一般设置为0.9或0.99,如果 γ \gamma γ=0,这表示只关心即时奖励;如果 γ \gamma γ=1, 这表示未来奖励等同于即时奖励。

    举个例子大家就明白了,比如现在给你100块钱,和过个10年再把这个100块钱给你,你愿意选择哪一个,当然是前者啦,10年后的100块钱,有可能就相当于现在的10块钱的价值了。换句话说,60年代的1块钱和现在的1块钱的价值是一样的吗?

    3.代码实现

    案例:模拟登月小艇降落在月球表面时的情形。任务的目标是让登月小艇安全地降落在两个黄色旗帜间的平地上。测试环境:LunarLander-v2

    Obs:这个游戏环境有八个观测值,分别是水平坐标x,垂直坐标y,水平速度,垂直速度,角度,角速度,腿1触地,腿2触地;

    Action:agent可以采取四种离散行动,分别是什么都不做,发动左方向引擎喷射,发动主引擎向下喷射,发动右方向引擎喷射。

    Reward:小艇坠毁得-100分;小艇成功着陆在两个黄色旗帜之间得100~140分;喷射主引擎向下喷火每次得-0.3分;小艇最终完全静止则再得100分;每条腿着地各得10分。

    这里我们虽然采用的是离散的动作空间,但是整体代码是相差不大的,感兴趣的同学可以尝试下连续的动作空间。

    定义网络结构:

    class PolicyNet(nn.Module):
        def __init__(self, n_states_num, n_actions_num, hidden_size):
            super(PolicyNet, self).__init__()
            self.data = []  # 存储轨迹
            # 输入为长度为8的向量 输出为4个动作
            self.net = nn.Sequential(
                # 两个线性层,中间使用Relu激活函数连接,最后连接softmax输出每个动作的概率
                nn.Linear(in_features=n_states_num, out_features=hidden_size, bias=False),
                nn.ReLU(),
                nn.Linear(in_features=hidden_size, out_features=n_actions_num, bias=False),
                nn.Softmax(dim=1)
            )
    
        def forward(self, inputs):
            # 状态输入s的shape为向量:[8]
            x = self.net(inputs)
            return x
    

    定义PG类:

    class PolicyGradient():
    
        def __init__(self, n_states_num, n_actions_num, learning_rate=0.01, reward_decay=0.95 ):
            # 状态数   state是一个8维向量,分别是水平坐标x,垂直坐标y,水平速度,垂直速度,角度,角速度,腿1触地,腿2触地
            self.n_states_num = n_states_num
            # action是4维、离散,即什么都不做,发动左方向引擎,发动主机,发动右方向引擎。
            self.n_actions_num = n_actions_num
            # 学习率
            self.lr = learning_rate
            # gamma
            self.gamma = reward_decay
            # 网络
            self.pi = PolicyNet(n_states_num, n_actions_num, 128)
            # 优化器
            self.optimizer = torch.optim.Adam(self.pi.parameters(), lr=learning_rate)
            # 存储轨迹  存储方式为  (每一次的reward,动作的概率)
            self.data = []
            self.cost_his = []
    
        # 存储轨迹数据
        def put_data(self, item):
            # 记录r,log_P(a|s)z
            self.data.append(item)
    
        def train_net(self):
            # 计算梯度并更新策略网络参数。tape为梯度记录器
            R = 0  # 终结状态的初始回报为0
            policy_loss = []
            for r, log_prob in self.data[::-1]:  # 逆序取
                R = r + gamma * R  # 计算每个时间戳上的回报
                # 每个时间戳都计算一次梯度
                loss = -log_prob * R
                policy_loss.append(loss)
            self.optimizer.zero_grad()
            policy_loss = torch.cat(policy_loss).sum()  # 求和
            # print('policy_loss:', policy_loss.item())
            # 反向传播
            policy_loss.backward()
            self.optimizer.step()
            self.cost_his.append(policy_loss.item())
            # print('cost_his:', self.cost_his)
            self.data = []  # 清空轨迹
    
        # 将状态传入神经网络 根据概率选择动作
        def choose_action(self, state):
            # 将state转化成tensor 并且维度转化为[8]->[1,8]  
            s = torch.Tensor(state).unsqueeze(0)
            prob = self.pi(s)  # 动作分布:[0,1,2,3]
            # 从类别分布中采样1个动作, shape: [1] torch.log(prob), 1
            
            # 作用是创建以参数prob为标准的类别分布,样本是来自“0 … K-1”的整数,其中K是prob参数的长度。也就是说,按照传入的prob中给定的概率,
            # 在相应的位置处进行取样,取样返回的是该位置的整数索引。不是最大的,是按照概率采样的那个,采样到那个就是哪个的索引
            m = torch.distributions.Categorical(prob)  # 生成分布
            action = m.sample()
            return action.item(), m.log_prob(action)
        def plot_cost(self, avage_reward):
            import matplotlib.pyplot as plt
            plt.plot(np.arange(len(avage_reward)), avage_reward)
            plt.ylabel('Reward')
            plt.xlabel('training steps')
            plt.show()
    

    训练模型:

       for n_epi in range(1000):
    
            state = env.reset()  # 回到游戏初始状态,返回s0
            ep_reward = 0
            for t in range(1001):  # CartPole-v1 forced to terminates at 1000 step.
                # 根据状态 传入神经网络 选择动作
                action, log_prob = policyGradient.choose_action2(state)
                # print(action, log_prob)
                # 与环境交互
                s_prime, reward, done, info = env.step(action)
                # s_prime, reward, done, info = env.step(action)
                if n_epi > 1000:
                    env.render()
                # 记录动作a和动作产生的奖励r
                policyGradient.put_data((reward, log_prob))
                state = s_prime  # 刷新状态
                ep_reward += reward
                if done:  # 当前episode终止
                    break
                # episode终止后,训练一次网络
            running_reward = 0.05 * ep_reward + (1 - 0.05) * running_reward
            avage_reward.append(running_reward)
            # 交互完成后 进行学习
            policyGradient.train_net()
            if n_epi % print_interval == 0:
                print('Episode {}\tLast reward: {:.2f}\tAverage reward: {:.2f}'.format(
                    n_epi, ep_reward, running_reward))
            if running_reward > env.spec.reward_threshold:  # 大于游戏的最大阈值时,退出游戏
                print("Solved! Running reward is now {} and "
                      "the last episode runs to {} time steps!".format(running_reward, t))
                torch.save(policyGradient.pi.state_dict(), 'pg.pkl')
                break
        policyGradient.plot_cost(avage_reward)
    

    最后得到Reward的曲线如下图,趋于收敛:

    图4. Reward曲线图

    最后的动画效果如下图:

    7efynA.gif

    图5. 结果演示图

    4.总结

    策略梯度可以很好的解决具有连续动作空间的场景,可以学习到一些随机策略,有时是最优策略。可能还会有较好的收敛性,但也有可能收敛到局部最优,而不是全局最优,评价策略的过程有时也会比较低效,方差很大。不过总体还是不错的,之后我们再介绍相对更好的算法来解决这些缺点。

    5.参考文献

    [1]《Reinforcement+Learning: An+Introduction》

    [2] https://blog.csdn.net/baidu_41871794/article/details/111057371

    我们是行者AI,我们在“AI+游戏”中不断前行。
    快来【公众号 | 行者AI】,和我们讨论更多技术问题吧!

    更多相关内容
  • 针对深度确定策略梯度算法收敛速率较慢的问题,提出了一种增强型深度确定策略梯度(E-DDPG)算法。该算法在深度确定策略梯度算法的基础上,重新构建两个新的样本池——多样性样本池和高误差样本池。在算法执行过程中...
  • PyTorch实现的“ SeqGAN:具有策略梯度的序列生成对抗网络”。 (于兰涛等)。 该代码经过高度简化,注释和(希望)易于理解。 实施的策略梯度也比原始工作( )简单得多,并且不涉及推广-整个句子使用单一奖励(受...
  • 深度增强学习算法的PyTorch实现(策略梯度/生成对抗模仿学习)
  • 多代理深确定性策略梯度 多主体深度确定性策略梯度(MADDPG)算法的Pytorch实现 这是我在论文中提出的算法的实现:“针对混合合作竞争环境的多主体Actor评论家”。 您可以在这里找到本文: : 您将需要安装多代理...
  • 21. 策略梯度算法.zip

    2019-05-08 17:27:42
    策略梯度算法(搭建网络、训练网络),采用python语言代码实现
  • Policy Gradient algorithms (REINFORCE, NPG, TRPO, PPO)
  • 策略梯度

    千次阅读 2019-03-08 21:47:56
    在强化学习的算法中存在两种算法,一个是基于价值函数的算法,另一个是基于策略梯度的算法。为什么要提出策略梯度算法呢? 基于策略的学习可能会具有更好的收敛性,这是因为基于策略的学习虽然每次只改善一点点,但...

    Policy Gradient Methods for Reinforcement Learning with Function Approximation(PG)

     

    在强化学习的算法中存在两种算法,一个是基于价值函数的算法,另一个是基于策略梯度的算法。为什么要提出策略梯度算法呢?

    1. 基于策略的学习可能会具有更好的收敛性,这是因为基于策略的学习虽然每次只改善一点点,但总是朝着好的方向在改善;而在基于值函数的算法中,价值函数在后期会一直围绕最优价值函数持续小的震荡而不收敛。
    2. 在对于那些拥有高维度或连续状态空间来说,使用基于价值函数的学习在得到价值函数后,制定策略时,需要比较各种行为对应的价值大小。这样如果行为空间维度较高或者是连续的,则从中比较得出一个有最大价值函数的行为这个过程就比较难了,这时候使用基于策略的学习就高效的多。
    3. 基于价值函数的学习通常是学不到随机策略的,使用策略梯度算法可以直接输入转态,得到对应动作或者动作的概率分布。

    在PG这篇论文中探讨了RL中函数逼近的另一种方法。我们不是近似一个值函数并用它来计算一个确定性策略,而是直接用一个独立的函数逼近器用它自己的参数来近似一个随机策略。例如,策略可以由一个神经网络来表示,该神经网络的输入是状态的表示,其输出是动作选择概率,其权值是策略参数。让作为策略参数的向量表示,表示策略的最终表现。然后,在策略梯度方法中,策略参数的更新与梯度近似成比例。

    与价值函数方法不同,这里θ的微小变化只会导致策略和状态分布的微小变化。定义策略的目标函数存在两种,一种是平均报酬公式,另一种是从初始状态获得的长期回报。

    1. 平均报酬

     

    1. 长期报酬回报

     

           对于上述两种目标函数,梯度均为

           当我们使用函数逼近器fws,a来模拟Qπs,a时,上式可以改写为:

     

    Deterministic Policy Gradient Algorithms(DPG)

    策略梯度算法广泛应用于具有连续动作空间的强化学习问题。基本思想是代表策略参数概率分布。在某个状态下根据参数向量随机选择行动。策略梯度算法通常是通过对这种随机策略进行抽样,并根据累积收益的增加来调整策略参数。

    在这篇文章中,考虑确定性策略为。从实际的角度来看,随机策略梯度与确定性策略梯度存在着重要的区别。在随机的情况下,策略梯度在状态空间和动作空间上积分,而在确定性的情况下,它只在状态空间上积分。因此,计算随机策略梯度可能需要更多的样本,特别是在行动空间有多个维度的情况下。为了学习确定性目标策略(利用确定性策略梯度的效率)。我们利用确定性策略梯度推导出一种离线行为批评算法,该算法使用可微分函数逼近器估计行为价值函数,然后在近似行为价值梯度的方向上更新策略参数。

    1. Stochastic Policy Gradient 理论

    评价表现目标方程为:

     

     

    根据策略梯度理论(PG),最基本的策略梯度计算方程为如下

     

    利用这个方程,可以通过策略梯度来调整参数来以优化最终的表现。但是问题在于还需要估计的值。

    1. Stochastic Actor-Critic 算法

    Actor-Critic是基于策略理论的常用框架。Actor会通过计算上述方程来调整策略函数πθs的参数θ。由于真实的动作价值函数 是未知的,我们使用一个参数化的函数近似器来代替,并且让Critic使用策略评估算法来估量它。

    由于是 是近似,使用它会造成与真实值的偏差。为了消除偏差,应满足两个条件:

    参数w应该最小化均方误差

     

    1. Deterministic Policy Gradient理论

    对于确定性策略,定义概率分布以及目标方程:

     

    那么确定性策略梯度可以推导出如下:

     

    1. On-Policy Deterministic Actor-Critic

    和随机化策略Actor-Critic一样,确定性策略也包含两部分,Critic估计行为价值函数,Actor估计行为价值函数的梯度。Actor根据上面的方程调整的参数,并且用来逼近真实值。例如,Critic使用Sarsa更新来评估动作价值函数:

     

    1. Off-Policy Actor-Critic

    我们称已探索过的轨迹为已知策略,未探索过的为目标策略。在off-policy中表现目标方程定义为:目标策略的状态价值函数在已知策略上的状态分布上取平均:

     

    对其进行微分即得到off-policy策略梯度:

    θJβπθS A ρβsθπθa|sQπs,adads

     

    这个近似式去掉了一个依赖动作价值梯度的项

    1. Off-Policy Deterministic Actor-Critic

    现在要用off-policy的方法去让智能体通过随机已知策略生成的轨迹学习确定目标策略

    定义目标方程以及策略梯度:

    同样确定性策略梯度中也丢弃了依赖于动作价值梯度的项:

    这里,用一个可微的动作价值函数来代替真实的动作价值函数,需要同时满足两个条件:

     

    并且让Critic通过已知策略生成的轨迹来评估它。比如使用Q-learning:

     

    Asynchronous Methods for Deep Reinforcement Learning(A3C)

    深度强化学习最近被人发现貌似不太稳定,有人提出很多改善的方法,这些方法有很多共同的地方:一个online的agent碰到的观察到的数据序列是非静态的,然后就是,online的RL更新是强烈相关的。通过将agent的数据存储在一个 experience replay 单元中,数据可以从不同的时间步骤上,批处理或者随机采样。这种方法可以降低不平稳性,然后去掉了更新的相关性,但是与此同时,也限制了该方法只能是 off-policy 的 RL 算法。

    Experience replay 有如下两个缺点:

    1. 每一次交互都会耗费更多的内存和计算;

    2. 需要 off-policy 的学习算法从更老的策略中产生的数据上进行更新。

    本文中我们提出了一种很不同的流程来做 DRL。不用 experience replay,而是以异步的方式,并行执行多个 agent,在环境中的多个示例当中。这种平行结构可以将 agent的数据“去相关(decorrelates)”到一个更加静态的过程当中去,因为任何给定的时间步骤,并行的agent都会经历不同的状态。这个简单的想法确保了一个更大的范围,基础的 on-policy RL 算法,如:Sarsa,n-step methods,以及 actor-critic 方法,以及 off-policy 算法,如:Q-learning,利用CNN可以更加鲁棒和有效的进行应用。

    本文的并行RL结构也提供了一些实际的好处,前人的方法都是基于特定的硬件,如GPUs或者大量分布式结构,本文的算法可以在单机上用多核 CPU 来执行。取得了比 之前基于 GPU 的算法 更好的效果,(A3C)算法的效果更优秀。

     one-step Q-learning 是朝着one-step返回的方向去更新动作值函数。但是利用one-step方法的缺陷在于:得到一个奖励r仅仅直接影响了 得到该奖励的状态动作对的值。其他状态动作对的值仅仅间接的通过更新 来影响。这就使得学习过程缓慢,因为许多更新都需要传播一个奖赏值给相关进行的状态和动作。

     

    一种快速的传播奖赏的方法是利用n-step returns。 在n-step Q-learning中,Qs,a是朝向 n-step return 进行更新。这样就使得一个奖赏直接地影响了n个正在进行的状态动作对的值。这也使得给相关 状态动作对的奖赏传播更加有效。

    另外就是定义了“优势函数”,即:利用Q值减去状态值,定义为:

           这种方法也可以看做是actor-critic结构,其中,策略π可以看做是actor,bt是critic。

    我们在这里介绍A3C算法,其中维持一个策略以及一个估计值函数。就像我们的n步q学习的变体一样,我们的角色-批评家的变体也在前视图中起作用并使用相同的n步返回组合来更新策略和值函数。当迭代步数达到或者到达终止状态时,更新策略和值函数。我们通常使用一个卷积神经网络有一个softmax输出策略和一个线性输出的价值函数,共享所有非输出层参数。

    下面简单介绍一下使用n步回报的A3C算法步骤:

    (1) 假设全局和线程内部的策略模型参数向量分别为';全局和线程内部的价值模型参数:;设置全局变量

    (2) 初始化线程步数计数器

    (3)重新设置全局策略模型参数的梯度,设置全局价值模型参数梯度

    (4) 同步全局和线程内部的策略模型参数,同步全局和线程内部的价值模型参数

    (5)设置,并获得初始状态

    (6)在状态通过策略模型选择动作,并执行该动作;

    (7) 通过步骤(6)获得对应的奖赏值,并达到新的状态

    (8) 更新参数,:

    (9) 判断是否为终止状态或者,如果满足上述条件跳转到步骤(6),否则跳出循环,执行步骤(10);

    (10) 计算每一次采样的价值:

    (11)设置变量

    (12)设置变量,如果i不等于,进行下一步,否则跳转到步骤(17);

    (13) 设置

    (14) 计算积累策略模型参数的梯度:

    (15) 计算积累价值模型参数的梯度

    (16) 跳转到步骤(12);

    (17) 对全局模型θ进行异步更新:

    (19) 判断是否大于,如果是则跳出循环,否则跳到步骤(3)。

     

    Continuous Control With Deep Reinforcement Learning(DDPG)

    虽然DQN算法目前在RL游戏领域表现良好,但是DQN在解决高维观测空间的问题时,只能处理离散的低维动作空间。许多有趣的任务,尤其是身体控制任务,有连续的(实值)和高维的行动空间。DQN不能直接应用于连续域,因为它依赖于找到使动作值函数最大化的动作,而在连续值情况下,每一步都需要迭代优化过程。

    我们称之为深度DDPG (Deep DPG)的model-free方法可以为所有人学习竞争策略,我们的任务使用低维观测(例如笛卡尔坐标或关节角度)使用相同的超参数和网络结构。在许多情况下,我们还能够直接从像素中学习良好的策略,再次保持超参数和网络结构不变。

    以往的实践证明,如果只使用单个”Q神经网络”的算法,学习过程很不稳定,因为Q网络的参数在频繁梯度更新的同时,又用于计算Q网络和策略网络的梯度。基于此,DDPG分别为策略网络、Q网络各创建两个神经网络拷贝,一个叫做online,一个叫做target:

     

    在训练完一个mini-batch的数据之后,通过SGA/SGD算法更新online网络的参数,然后再通过soft update算法更新 target 网络的参数。soft update是一种running average的算法:

           DDPG算法的步骤如下:

     

    展开全文
  • 什么是_策略梯度_Policy_Gradients_(Reinforcement_Learning_强化学习)
  • 确定性策略梯度中的特征选择
  • 循环确定性策略梯度(RDPG) 概述 递归确定性策略梯度的实现来自本文 要求 $ python -m pip install --upgrade pip $ pip install -r requirements.txt 跑步 训练: 摆v0 $ python main.py --env Pendulum-v0 --...
  • 基于Actor-Critic框架的深度确定性策略梯度(Deep Deterministic Policy Gradient,DDPG)算法虽然解决了连续动作控制问题,但是仍然存在采样方式缺乏科学理论指导、动作维度较高时的最优动作与非最优动作之间差距被...
  • 为什么需要策略梯度 基于值的强化学习方法一般是确定性的,给定一个状态就能计算出每种可能动作的奖励(确定值),但这种确定性的方法无法处理一些现实的问题,比如玩100把石头剪刀布的游戏,最好的解法是随机的...

    为什么需要策略梯度

    基于值的强化学习方法一般是确定性的,给定一个状态就能计算出每种可能动作的奖励(确定值),但这种确定性的方法无法处理一些现实的问题,比如玩100把石头剪刀布的游戏,最好的解法是随机的使用石头、剪刀和布并尽量保证这三种手势出现的概率一样,因为任何一种手势的概率高于其他手势都会被对手注意到并使用相应的手势赢得游戏。

    再比如,假设我们需要探索上图中的迷宫拿到钱袋。如果采用基于值的方法,在确定的状态下将得到确定的反馈,因此在使用这种方法决定灰色(状态)方格的下一步动作(左或右)是确定的,即总是向左或向右,而这可能会导致落入错误的循环中(左一白格和左二灰格)而无法拿到钱袋。也许有人要质疑这时的状态不应用一个方格,而是迷宫中的所有方格表示。但是考虑如果我们身处一个巨大的迷宫无法获得整个迷宫的布局信息,如果在相同的可感知的状态下总是做出固定的判断的话,仍然会导致在某个局部原地打转。事实上很多实际问题特别是对弈类问题都有类似的特征,即需要在貌似相同的状态下应用不同的动作,如棋类游戏的开局。

    策略梯度正是为了解决上面的问题产生的,它的秘密武器就是“随机”。首先随机能提供非确定的结果,这种非确定的结果并不是完全的随意,而是服从某种概率分布的随机。策略梯度不计算奖励(reward),而是输出选择所有动作的概率分布,然后基于概率选择动作。 其训练的基本原理是通过反馈调整策略,具体来说就是在得到正向奖励时,增加相应的动作的概率;得到负向的奖励时,降低相应动作的概率。下面左图中的绿点表示获得正向奖励的动作,右图表示更新后的策略,可以发现产生正向奖励的区域的概率都增加了(离圆心的距离更近)。

    下面我们来具体了解策略梯度算法。

    基本概念

    对象系统:策略梯度的学习对象,这个对象即可以是一个系统,比如汽车或一个游戏,也可以是一个对手,比如势头剪刀布的游戏对手或者一个职业围棋手。

    Policy策略:\pi_{\theta } (\alpha | s)表示在状态s和参数\theta条件下发生动作\alpha的概率。

    Episode轮次:表示从起始状态开始使用某种策略产生动作与对象系统交互,直到某个终结状态结束。比如在围棋游戏中的一个轮次就是从棋盘中的第一个落子开始直到对弈分出胜负,或者自动驾驶的轮次指从汽车启动一直到顺利抵达指定的目的地,当然撞车或者开进水塘也是种不理想的终结状态。

    Trajectory轨迹:\tau表示在PG一个轮次的学习中,状态s、动作\alpha和奖励r的顺序排列。举个栗子:\tau=((s_0,\alpha_0,r_0),(s_1,\alpha_1,r_1),......)。由于策略产生的是非确定的动作,同一个策略在多个轮次可以产生多个不同的轨迹。

    轮次奖励:\sum r(\tau)表示在一个轮次中依次动作产生的奖励的总和。在实现中,对每个策略评估奖励期望时,会求多个轮次的平均值。

    策略梯度的学习是一个策略的优化过程,最开始随机的生成一个策略,当然这个策略对对象系统一无所知,所以用这个策略产生的动作会从对象系统那里很可能会得到一个负面奖励。为了击败对手,我们需要逐渐的改变策略。策略梯度在一轮的学习中使用同一个策略直到该轮结束,通过梯度上升改变策略并开始下一轮学习,如此往复,直到轮次累计奖励收敛为止。

    目标函数

    根据上述策略梯度的基本原理,我们可以把它的目标形式化的描述为以下表达式:

    J(\theta )=argmax_\theta E[r_0+r_1+r_2+......|\pi_\theta ]

    这个函数表示策略\pi_\theta在0到t步累计奖励的期望值。之所以是期望值,是因为每一步的奖励是根据策略(生成动作选择的概率分布)得到的奖励期望;而不是选择一个确定动作,得到确定的奖励。策略梯度的目标就是确定构成策略的参数\theta,使得J(\theta )取得最大的期望值。即:

    \theta ^*=argmaxJ(\theta )

    策略梯度算法中使用梯度上升来更新参数\theta,根据数学期望的定义:

    J(\theta )=E_{r\sim \pi_\theta (\tau)}[\sum r_\tau]=\int_{​{}^{\tau}} r(t)\pi_\theta (t)dt

    求导得:

    \nabla_\theta J(\theta)=\int_{​{}^{\tau}}r(t)\nabla_\theta\pi_\theta(t)dt

    这里进行不下去了,由于\pi_\theta(t)依赖于\theta,无法直接求导,因此要使用一个小技巧。根据\nabla logf(x)=\frac{\nabla f(x)}{f(x)}进行转换:

    \nabla_\theta \pi_\theta(t)=\pi_\theta(t)\frac{\nabla_\theta \pi_\theta(t)}{\pi_\theta(t)}=\pi_\theta(t)\nabla_\theta log\pi_\theta(t)

    代入得:

    \nabla_\theta J(\theta)=\int_{​{}^{\tau}}r(t)\pi_\theta(t)\nabla_\theta log\pi_\theta(t) dt

    这回求完了,根据期望的定义往回转换,得:

    \nabla_\theta J(\theta)=E_{\tau \sim \pi_\theta(\tau)}[\nabla_\theta log\pi_\theta(\tau)r(\tau)]

    由于:

    log(\pi_\theta(\tau))=\sum_{t=1}^{T} log(\pi_\theta(\alpha_t|s_t))+logp(s_{t+1}|s_t,\alpha_t)

    r(\tau)=\sum_{t=1}^{T} r(s_t,\alpha_t)

    可得最终结果:

    \nabla_\theta J(\theta)=E_{\tau \sim \pi_\theta(\tau)}[\sum_{t=1}^{T}\nabla_\theta log\pi_\theta(\alpha_t|s_t)(\sum_{t=1}^{T} r(s_t,\alpha_t))]

    把期望用均值来近似:

    \nabla_\theta J(\theta)=\frac{1}{N}\sum_{i=1}^{N}[\sum_{t=1}^{T}\nabla_\theta log\pi_\theta(\alpha_t|s_t)(\sum_{t=1}^{T} r(s_t,\alpha_t))]

    折腾这么一大顿,终于求完了,这就是要优化的目标函数。即使你没太看懂,也能从这里大概做一个直观理解:奖励高时策略倾向于增加相应动作的概率,奖励低时就减小。策略梯度和传统的监督式学习的学习过程还是比较相似的:每轮次都由前向计算和反向传播构成,前向计算负责计算目标函数,反向传播负责更新算法的参数,依此进行多轮次的学习指导学习效果稳定收敛。唯一不同的是,监督式学习的目标函数相对直接,即目标值和真实值的差,这个差值通过一次前向反馈就能得到;而策略梯度的目标函数源自轮次内所有得到的奖励,并且需要进行一定的数学转换才能计算,另外由于用抽样模拟期望,也需要对同一套参数进行多次抽样来增加模拟的准确性。

    应用实例

    下面我们通过一个实例介绍如何应用PG解决具体问题:学习玩Atari PONG游戏。 PONG是一个模拟打乒乓球的游戏,玩家控制屏幕一侧的一小块平面模拟乒乓球拍上下移动来击球。如果迫使对方失球则己方一侧的得分加一,反之对方得分。使用策略梯度学习PONG游戏的基本思路是使用算法控制的一方与游戏控制的另一方进行对弈,通过观察游戏状态以及比分变化调整动作(向上或向下)的概率分布,使本方得分最大化。学习的过程可以写成以下代码:

    policy = build_policy_model()
    game.start()
    while True:
        state = game.currentState()
        action, prob = policy.feedforward(state)
        reward = game.play(action)
        trajectory.append((state, prob, action, reward))
        if game.terminated():
            if count < SAMPLE_COUNT:
                trajectories.append(trajectrory)
                trojectroy = []
                count += 1
                break
            else:
                policy.backpropagation(trajectories)
                game.restart()
                trajectory = []
                trajectories = []
                count = 0

    第 1 行构造一个策略模型并随机的初始化模型的参数\theta。模型的功能是通过前向反馈由状态信息计算出所有动作的概率分布,例如(向上 90%,向下 10%),并选取概率最大的动作发给游戏作为指令。

    第 2 行开始游戏。

    第 4 行获得当前的状态,如球拍的位置和球的移动速度方向信息。

    第 5 行将状态信息传入策略模型计算相应的动作。这里还要记录动作的概率\pi_\theta(s),这是为了在反向阶段计算目标函数导数。

    第 6 行使用 4 计算出的动作进行游戏并获得奖励

    第 7 行将一轮的交互信息(状态,动作概率,动作和奖励)存入当前轨迹\tau

    第 8 行如果游戏未结束(乒乓球还在被双方击打中)则继续使用当前的策略模型进行下一步的交互。

    第 10 行如果游戏结束(一方未击中乒乓球)则保存上一轮轨迹信息并使用相同的策略模型开始新一轮的游戏,也就是为了降低个体差异的影响,为同一个策略模型生成多个样本。

    第 15 行产生足够的样本以后,通过策略模型的反向传递进行参数的更新,再用更新后的策略开始新一轮次的学习

    问题和改进

    虽然策略梯度理论上能处理基于值的方法无法处理的复杂问题,但由于依赖样本来优化策略,导致这种方法受样本个体差异影响有比较大的方差,学习的效果不容易持续增强和收敛。一个基本的改进思路是通过减少无效的元素来降低方差,由于当前的动作不会对过去的奖励产生影响,因此可以将目标函数改为:

    \nabla_\theta J(\theta)=\frac{1}{N}\sum_{i=1}^{N}[\sum_{t=1}^{T}\nabla_\theta log\pi_\theta(\alpha_t|s_t)(\sum_{t^{'}=t}^{T} r(s_{t^{'}},\alpha_{t^{'}}))]

    还可以用经典的折扣系数来降低距离较远动作带来的影响:

    \nabla_\theta J(\theta)=\frac{1}{N}\sum_{i=1}^{N}[\sum_{t=1}^{T}\nabla_\theta log\pi_\theta(\alpha_t|s_t)(\sum_{t^{'}=t}^{T} \gamma ^{|t-t^{'}|}r(s_{t^{'}},\alpha_{t^{'}}))]

    另外我们还需要考虑一个问题:实际计算中产生的轮次奖励并不能准确代表这个策略的好坏程度,比如当策略已经较好时,使用一个不太好的样本生成了较小的轮次奖励,由于这个奖励非负,传统的策略梯度算法仍然尝试增加产生这个轨迹的动作的概率,从而导致学习效果不升反降。所以我们需要引入一个基准值(baseline value),使得算法能够增加优于基准值的动作的概率,降低低于基准值动作的概率,即:

    \nabla_\theta J(\theta)=\frac{1}{N}\sum_{i=1}^{N}[\sum_{t=1}^{T}\nabla_\theta log\pi_\theta(\alpha_t|s_t)(\sum_{t^{'}=t}^{T} r(s_{t^{'}},\alpha_{t^{'}})-b)]

    基准值b目前一般常取的是均值,即b=\frac{1}{N}\sum_{i=1}^{N}r(\alpha_i,s_i)。可以看出,这个基准值也是随着更新动态变化的。研究人员们还在尝试用其他方法生成更好的基准值,其实如果你仔细想一下就会发现,对基准值的动态估计其实就是值函数的估计问题。因此,策略梯度算法可以和基于值的算法相结合,以实现更好的效果。比如Actor-critic,在我看来其实就是策略梯度法和DQN的一种结合,这个我们以后有机会再聊吧~

    展开全文
  • pytorch-ddpg, 利用PyTorch实现深度确定策略梯度( DDPG )的实现 在 PyTorch 上的深度确定策略渐变概述这是使用 PyTorch 实现的深度确定策略渐变的实现。 utilities缓冲缓冲区和随机进程等实用程序的一部分来自 keras...
  • 策略梯度中的baseline

    2021-09-04 22:07:45
    策略梯度中的Baseline Policy Gradient with Baseline Policy Gradient 策略梯度是关于策略网络的参数求的,策略网络π(a∣s;θ)\pi (a|s;\theta)π(a∣s;θ)的参数是θ\thetaθ,我们使用策略网络来控制Agent做...

    策略梯度中的Baseline

    Policy Gradient with Baseline

    Policy Gradient

    • 策略梯度是关于策略网络的参数求的,策略网络 π ( a ∣ s ; θ ) \pi (a|s;\theta) π(as;θ)的参数是 θ \theta θ,我们使用策略网络来控制Agent做运动。状态价值函数 V π ( s ) V_{\pi}(s) Vπ(s)是动作价值函数的期望,期望是关于动作A求的,动作A的概率密度函数是 π \pi π,可以将期望等价写为连加的形式。这里期望中包含策略网络的参数 θ \theta θ,所以得到的状态价值函数 V π ( s ) V_{\pi}(s) Vπ(s)依赖于参数 θ \theta θ,策略梯度是 V π V_{\pi} Vπ关于参数 θ \theta θ的导数,也可以写为期望的形式。

    在这里插入图片描述

    Baseline

    • 策略梯度方法常用Baseline来降低方差,让收敛更快,Baseline指的是一个函数b,它可以是任何东西,但是不能依赖于动作A。
    • 证明这个期望 E A   π [ b ⋅ ∂ l n π ( A ∣ s ; θ ) ∂ θ ] \mathbb{E}_{A~ \pi}[b\cdot \frac{\partial ln\pi (A|s;\theta)}{\partial \theta}] EA π[bθlnπ(As;θ)]为0,可以将b提出去,将得到后的期望展开得到连加的形式,使用链式法则将导数展开,这样接可以消去一项。因为连加是关于a求的,求导是关于 θ \theta θ求的,所以可以将连加放入到求导内部,因为 π \pi π是对a的概率密度函数,所以它的连加和为1,故结果为0.
    • 通过上面推导我们可以得到baseline的重要性质,就是它乘以策略梯度然后对A求期望,得到的期望为0

    在这里插入图片描述

    Policy Gradient with Baseline

    • 上面我们得到了 E A   π [ b ⋅ ∂ l n π ( A ∣ s ; θ ) ∂ θ ] = 0 \mathbb{E}_{A~ \pi}[b\cdot \frac{\partial ln\pi (A|s;\theta)}{\partial \theta}]=0 EA π[bθlnπ(As;θ)]=0,使用这个性质向策略梯度中添加baseline,
    • 之前我们得到了策略梯度为下面的等式,又因为baseline为0,所以可以减去它,使得等式仍然成立。合并我们就可以得到第二个等式,等式中包含baseline

    在这里插入图片描述

    • 这样我们就可以得到下面的定理:
      • 但是我们肯定会有这样一个问题:既然b不会影响期望,那么我们加不加b有什么区别呢?实际上,在算法中我们求的不是期望,因为期望太复杂啦,我们使用的是对期望的蒙特卡洛近似,如果我们选择的b比较好,比较接近于 Q π Q_{\pi} Qπ,算法会将蒙特卡洛近似的方差降低,收敛更快。

    在这里插入图片描述

    Monte Carlo Approximation

    • 我们直接求期望往往很困难,所以我们通常使用期望的蒙特卡洛近似。我们将期望中的函数记为 g ( A t ) g(A_t) g(At),它依赖于随机变量 A t A_t At,期望是按照随机变量 A t A_t At求的,它的概率密度函数是 π \pi π,我们根据 π \pi π做随机抽样,得到一个动作 a t a_t at,然后计算 g ( a t ) g(a_t) g(at),即为上面期望的蒙特卡洛近似, g ( a t ) g(a_t) g(at)显然是策略梯度的一个无偏估计,这是因为g关于 A t A_t At的期望为策略梯度, g a t g_{a_t} gat实际上是随机梯度,实际中我们往往用随机梯度。

    在这里插入图片描述

    Stochastic Policy Gradient

    • 实际我们训练策略网络的时候,我们通常使用随机梯度上升来训练参数,使用的是 g ( a t ) g(a_t) g(at),这样做策略梯度上升可以使得状态价值变大,也就以为着让策略变得更好。

    在这里插入图片描述

    • 在看上面 g ( a t ) g(a_t) g(at)的公式,里面有b,前面我们证明了只要b于 A t A_t At无关,那么我们就可以使得期望保持不变。虽然b不影响 g ( A t ) g(A_t) g(At)的期望,但是b影响 g ( a t ) g(a_t) g(at),看下上面公式用不同的b可以得到不同的 g ( a t ) g(a_t) g(at),如果我们选择的b很好,很接近 Q π Q_{\pi} Qπ,那么随机梯度方差就会小,就会让算法收敛的更快。

    在这里插入图片描述

    Choices of Baselines

    • Choice 1:b=0。也就是不用baseline,这样我们就得到了标准的策略梯度,不带baseline
    • Choice 2: b = V π ( s t ) b=V_{\pi}(s_t) b=Vπ(st),因为状态 s t s_t st是先于动作被观测到的,所以它不依赖于动作。我们为啥要用这个呢?因为上面我们提到了,如果我们选择的b很好,非常的接近动作价值函数 V π V_{\pi} Vπ这样我们在用蒙特卡洛近似策略梯度的期望的时候,就可以使得方差很小,收敛更快。根据定义状态价值函数 V π V_{\pi} Vπ是动作价值函数 Q π ( s t , A t ) Q_{\pi}(s_t,A_t) Qπ(st,At)关于动作 A t A_t At的期望。作为期望显然很接近动作价值函数,所以很合适。

    在这里插入图片描述

    REINFORCE with Baseline

    • 复习

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    • 之前我们推导出了随机策略梯度,也就是上面的公式,但是它里面还有未知项,所以我们要近似,我们可以使用观测到的值 u t u_t ut来近似 Q π ( s t , a t ) Q_{\pi}(s_t,a_t) Qπ(st,at),这也是蒙特卡洛近似,这个算法就是REINFORCE。
      • 我们观测到一个轨迹,也就是一直到游戏结束。
      • 计算return,这样我们就可以得到回报 u t u_t ut
      • u t u_t ut就是动作价值函数的无偏估计,REINFORCE算法就用这个方法来近似 Q π Q_{\pi} Qπ
    • 上面的公式中还有一个未知的东西,就是 V π V_{\pi} Vπ,我们可以使用神经网络来近似它,也就是价值网络,最终可以直接算出近似的策略梯度。

    在这里插入图片描述

    在这里插入图片描述

    • 为了能够计算策略梯度我们进行了3次近似
      • 使用蒙特卡洛来近似期望,将策略梯度近似为随机梯度 g ( a t ) g(a_t) g(at)
      • 使用观测到的 u t u_t ut来近似动作价值函数,这也是蒙特卡洛近似
      • 使用价值网络来近似状态价值函数
        在这里插入图片描述

    Policy and Value Network

    • 我们需要两个神经网络,策略网络来控制Agent,价值网络作为baseline

    • 策略网络

      • 策略网络是对策略函数的近似,

    在这里插入图片描述

    • 价值网络
      • 价值网络的输入是状态s,它是对状态价值函数的近似。

    在这里插入图片描述

    • 共享卷积层参数,因为他们的输入都是对状态s提取特征。

    在这里插入图片描述

    REINFORCE with Baseline

    • 我们使用REINFORCE方法训练策略网络,使用回归方法训练价值网络。
    • 之前我们已经近似出了策略梯度,有了策略梯度我们就可以根据梯度上升来更新策略网络,我们将圈出来的记为 − δ t -\delta_t δt,在后面我们训练价值网络的时候也会用到它。

    在这里插入图片描述

    • 更新价值网络就是让它去拟合回报 u t u_t ut,因为之前我们将状态价值函数近似为了 u t u_t ut,这样我们就可以得到预测的误差,因为我们希望误差越小越好,所以我么可以使用误差的平方作为损失函数。然后求导,就可以得到梯度,然后做梯度下降更新参数。

    在这里插入图片描述

    Summary

    • 每当我们打一局游戏,我们就可以观测到一条轨迹
    • 使用观测到的奖励r来计算回报,价值网络于回报之间的差,就是预测误差
    • 更新策略网络的参数
    • 最后做梯度下降来更新价值网络
    • 因为我们可以在一局游戏中我们可以得到n个回报,这样我们就可以对两个策略网络做n轮更新。

    在这里插入图片描述

    Advantage Actor-Critic (A2C)

    在这里插入图片描述

    在这里插入图片描述

    Training of A2C

    • 每一轮我们观测到一个transition
    • 然后计算TD target
    • 然后计算TD error
    • 使用近似的策略梯度来更新策略网络参数 θ \theta θ
    • 然后更新价值网络的参数

    在这里插入图片描述

    Properties of Value Functions

    在这里插入图片描述

    • t时刻的动作价值可以写为下面的公式,期望中的随机性来自于动作 A t + 1 A_{t+1} At+1和状态 S t + 1 S_{t+1} St+1,将这两个变量求期望消除随机性,将对 A t + 1 A_{t+1} At+1的期望推到里面,我们就可以得到第二个公式。 这样我们根据定义动作价值对动作求期望就是状态价值,这样进行替换,就可以得到定理1.

    在这里插入图片描述

    Properties of State-Value Function

    • 我们知道动作价值函数对 A t A_t At的期望就是状态价值函数,将期望中的 Q π Q_{\pi} Qπ使用我们上面得到的定理1替换。这样我们就可以得到定理2.

    在这里插入图片描述

    Monte Carlo Approximations

    • 通过我们上面推导出的定理。我们对它们做蒙特卡洛近似
    • 对定理1做蒙特卡洛近似,假设我们观测到一个transition,利用它来对期望做近似,这样我们就得到了一个公式。

    在这里插入图片描述

    • 对定理2做蒙特卡洛近似,假设我们观测到一个tranistion,来近似,这样我们又得到了一个公式
      在这里插入图片描述

    • 这样我们就的到了两个公式,第一个公式可以用来训练策略网络,第二个公式可以用来训练价值网络。
      在这里插入图片描述

    Updating Policy Network

    • 在前面我们推导出了下面的公式, g ( a t ) g(a_t) g(at)是对策略网络的策略梯度的蒙特卡洛近似,其实就是一个随机梯度,里面的 Q π ( s t , a t ) − V π ( s t ) Q_{\pi}(s_t,a_t)-V_{\pi}(s_t) Qπ(st,at)Vπ(st)被称为优势函数。我们不知道他们两的值,但是我们在前面得到了他们两的蒙特卡洛近似。然后我们进行替换,然后公式中就只有状态价值函数了,我们使用价值网络对它进行替换。我们可以用做后得到的公式来更新策略网络。

    在这里插入图片描述
    在这里插入图片描述

    • 这里我们观察下面蓝色方框中式子,它其实就是TD target

    在这里插入图片描述

    • 这样我们就可以使用梯度上升来更新策略网络了。

    在这里插入图片描述

    Updating Value Network

    • 训练价值网络我们要用到TD算法,下面我们来推导TD target,上面我们得到了状态价值的蒙特卡洛近似,使用价值网络来替换,
      在这里插入图片描述

    • 我们将上面得到的公式叫做TD target,它比纯粹的估计更靠谱,TD算法鼓励价值网络的估计接近TD target

    在这里插入图片描述

    • 使用TD算法更新价值网络

    œ

    Summary

    在这里插入图片描述

    REINFORCE vs A2C

    • 它们两使用的网络结构完全相同,策略网络也是一样的,但是价值网络的功能却有些区别。A2C的价值网络叫做Critic,用来评价策略网络的表现,REINFORCE的价值网络仅仅是个baseline,不会评价价值的好坏。

    A2C with Multi-Step TD Target

    • A2C

    在这里插入图片描述

    • 上面的TD target我们只用到了一个奖励,我们可以用多个奖励放进去,这样我们可以得到更好的效果。

    在这里插入图片描述

    • One-Step VS Multi-Step Target

    在这里插入图片描述

    • 下面就是多步的算法

    在这里插入图片描述

    Review REINFORCE

    在这里插入图片描述

    • 如果我们考虑用一局游戏的所有奖励来更新TD target的话,A2C就变为了Reinforce

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 强化学习:确定性策略梯度(DDPG)

    千次阅读 2022-03-29 19:44:09
    1,确定性策略梯度 1.1,基本概念 随机性策略梯度算法被广泛应用于解决大型动作空间或者连续动作空间的强化学习问题。其基本思想是将策略表示成以为参数的策略函数。基于采样数据,通过调整参数使得最终的累计...
  • 本文是强化学习入门系列的第六篇,将介绍一种有别于前面Q-learning这些基于价值的算法——策略梯度
  • 1,随机策略梯度 1.1,简介 离散动作和连续动作: (1)要输出离散动作的话,我们就是加一层 softmax 层来确保说所有的输出是动作概率,而且所有的动作概率加和为 1。 (2)要输出连续动作的话,一般可以在...
  • 深度强化学习-策略梯度算法推导

    千次阅读 2021-12-24 21:08:15
    之前我们讨论过DQN算法:深度强化学习-DQN算法原理与代码、Double DQN算法:深度强化学习-Doubel DQN算法原理与代码、Dueling DQN...但是求解最优策略梯度不一定要估计最优价值函数,策略梯度算法(policy gradient algo
  • 本文通过整理李宏毅老师的机器学习教程的内容,简要介绍深度强化学习(deep reinforcement learning)中的策略梯度法(policy gradient)。
  • 如果想深入理解策略梯度算法公式,可以参考我的另一篇博文:深度强化学习-策略梯度算法深入理解,里面将其与手写数字识别问题进行了类比,深入剖析了策略梯度算法公式。代码已经上传到我的Github上,喜欢的话可以点...
  • 深度确定性策略梯度 ​ 在连续控制领域,比较经典的强化学习算法就是深度确定性策略梯度(deep deterministic policy gradient,DDPG)。DDPG的特点可以从名字当中拆解后取理解。拆解成深度、确定性和策略梯度。 ...
  • 而在策略搜索方法中,我们直接对策略进行迭代计算,也就是迭代更新参数值,直到累积回报的期望最大,此时的参数所对应的策略为最优策略。 比较一下值函数方法和直接策略搜索方法的优缺点: 直接策略搜索方法是对...
  • 强化学习—— 离散与连续动作空间(随机策略梯度与确定策略梯度)1. 动作空间1.1 离散动作空间1.2 连续动作空间 1. 动作空间 1.1 离散动作空间 比如:{left,right,up}\{left,right,up\}{left,right,up} DQN可以用于...
  • 在深度强化学习-策略梯度算法推导博文中,采用了两种方法推导策略梯度算法,并给出了Reinforce算法的伪代码。可能会有小伙伴对策略梯度算法的形式比较疑惑,本文就带领大家剖析其中的原理,深入理解策略梯度算法的...
  • Policy gradient(策略梯度详解)

    千次阅读 多人点赞 2020-10-11 15:07:47
    文章目录策略梯度基本知识什么是策略梯度?强化学习案例策略梯度公式详解如何使你的损失函数更好增加一个基准为每一个action分配不同的权重 策略梯度基本知识 什么是策略梯度? 直接根据状态输出动作或者动作的概率...
  • 针对该问题,将强化学习中的策略梯度算法引入生成式对抗网络GAN(Generative Adversarial Networks),提出了一种基于策略梯度和GAN的变压器油色谱案例生成方法。仿真结果表明,与传统的样本扩充算法相比,利用所提...
  • 策略梯度简介基于价值和基于策略的强化学习policy based方法的优缺点基于价值函数的策略有时无法得到最优策略策略目标函数三种形式的策略目标函数优化目标函数有限差分策略梯度策略梯度有限差分法计算策略梯度...
  • 策略梯度,顾名思义,就是优化策略的梯度。我们之前讲了Policy-based和Value-based,而Policy-based方法就是直接训练策略的一组参数。如何训练?策略梯度就是一种方法。 基本思路 要训练一个Policy-based的方法,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,411
精华内容 20,164
关键字:

策略梯度

友情链接: DFT.rar