CS294(5) 策略梯度法(总结版)
文章目录策略梯度法REINFORCEPartial observability问题一:高方差问题背景方差削减方法一:因果关系(causality)方法二:baseline问题二:on-policy问题问题三用自动差分器做策略梯度法策略梯度法在实践中的注意事项我们已经知道智能体通过增强学习与环境打交道的运作机理:状态sss下根据由参数θ\thetaθ的神经网络所表示的测量πθ(a∣s)\pi...
文章目录
我们已经知道智能体通过增强学习与环境打交道的运作机理:
- 状态 s s s下根据由参数 θ \theta θ的神经网络所表示的测量 π θ ( a ∣ s ) \pi_{\theta}(a|s) πθ(a∣s)得到行为 a a a;
- 在环境中执行行为 a a a,由环境状态转移概率 p ( s ′ ∣ s , a ) p(s'|s,a) p(s′∣s,a)得到新的状态 s ′ s' s′,循环往复,直到终止状态。
由马尔科夫性可知,一条轨迹出现的概率为(这里的
p
θ
(
τ
)
p_{\theta}(\tau)
pθ(τ)在ppt里也写作
π
θ
(
τ
)
\pi_{\theta}(\tau)
πθ(τ),比较混乱,可以直接理解为策略):
我们的目标是选出一组最优的神经网络参数
θ
∗
\theta^*
θ∗,最大化总收益的期望:
策略梯度法
REINFORCE
首先我们要研究怎么去评估这个目标,然后再考虑如何去改进当前的策略。我们把目标函数记作:
除非我们的分布性质非常干净譬如说高斯分布,通常我们不能精确地对这个期望进行评估,但我们可以去用蒙特卡洛方法抽样近似。如果我们根据轨迹分布来抽样的话,目标函数的一个无偏估计是:
其中样本量为
N
N
N,第
i
i
i个样本在
t
t
t时刻的状态为
s
i
,
t
s_{i,t}
si,t,行动为
a
i
,
t
a_{i,t}
ai,t。
现在考虑怎么去改进策略,在连续优化中最常见的方法是计算其梯度,然后让参数走一个梯度步。
令轨迹的收益为:
则目标函数为:
根据期望的定义可得:
其梯度为:
因此其实我们关心的主要是
▽
θ
p
θ
(
τ
)
\triangledown_{\theta}p_{\theta}(\tau)
▽θpθ(τ)这一部分。另外以下有一个非常重要的恒等式:
把上式带入梯度公式中得:
因为式子中又再度出现了
p
θ
(
τ
)
p_{\theta}(\tau)
pθ(τ)这个概率,它本质上又变回了一个期望:
回忆下前言中的轨迹概率表达形式,将两边取对数得:
我们只需要上式关于
θ
\theta
θ的梯度,去掉无关项,得:
再展开
r
(
τ
)
r(\tau)
r(τ)我们得到的最终形式如:
这个形式的最大优点是,它不需要我们知道状态的初始分布,也不需要我们知道转移概率:而这两者通常正是非常困难的!这一点是非常重要的,我们只需要从环境中抽一些样本来估计一个期望,更新策略的梯度,而不需要知道这个环境本身是什么样的。
与之前类似,使用蒙特卡洛估计方法,我们也可以从实际系统中抽样,用下式作为一个无偏估计:
得到梯度后使用梯度上升法(因为需要累积奖励最大)
θ
←
θ
+
α
▽
θ
J
(
θ
)
\theta\leftarrow\theta+\alpha\triangledown_{\theta}J(\theta)
θ←θ+α▽θJ(θ)走一个梯度步。这样,我们就得到了一个最简单的策略梯度法REINFORCE (Williams, 1992):
- 运行策略 π θ ( a ∣ s ) \pi_{\theta}(a|s) πθ(a∣s),抽取样本{ τ i {\tau^i} τi};
- 估计梯度 ▽ θ J ( θ ) ≈ 1 N ∑ i = 1 N [ ( ∑ t = 1 T ▽ θ log π θ ( a i , t ∣ s i , t ) ) ( ∑ t = 1 T r ( a i , t ∣ s i , t ) ) ] \bigtriangledown_{\theta}J(\theta)\approx\frac{1}{N}\sum_{i=1}^N[(\sum_{t=1}^T\bigtriangledown_{\theta}\log \pi_{\theta}(a_{i,t}|s_{i,t}))(\sum_{t=1}^Tr(a_{i,t}|s_{i,t}))] ▽θJ(θ)≈N1∑i=1N[(∑t=1T▽θlogπθ(ai,t∣si,t))(∑t=1Tr(ai,t∣si,t))];
- 更新一个梯度步 θ ← θ + α ▽ θ J ( θ ) \theta\leftarrow\theta+\alpha\triangledown_{\theta}J(\theta) θ←θ+α▽θJ(θ)。
不幸的是,通常直接这么做效果不会很好。 ▽ θ log π θ ( a t ∣ s t ) \bigtriangledown_{\theta}\log \pi_{\theta}(a_{t}|s_{t}) ▽θlogπθ(at∣st)可以理解为执行某一行为的概率,后面乘以 ∑ t = 1 T r ( a i , t ∣ s i , t ) \sum_{t=1}^Tr(a_{i,t}|s_{i,t}) ∑t=1Tr(ai,t∣si,t)表示策略梯度对行为进行了加权,增加高回报行为选择的概率,降低低回报行为的概率。
Partial observability
如果我们的观测不完全,即只有部分观测信息,怎么办?在策略梯度法中,这不是个问题。我们可以得到基于观测的梯度:
可以发现这个式子中完全没有用到Markov性。也就是说,我们可以直接在POMDP中使用策略梯度法,不需要任何的修改。但是在之后的诸如演员-评论家算法、Q学习算法之类的,这个性质往往是不成立的。这是策略梯度法的一大优势。但即便如此,它不能保证你能得到一个运行得很好的策略,因为非Markov性可能导致真正运行得好的策略和之前的历史有关,但是它能在你的策略簇中找到一个不错的策略。如果你觉得历史还是非常重要的,那么可能使用一个RNN会好一些。
问题一:高方差问题
背景
在两个图中,x轴代表轨迹,而y轴代表轨迹对应的收益。蓝色实线是我们选取策略的分布密度,蓝色虚线是我们梯度更新后策略的分布密度。我们从分布之中抽取了三个样本,在(a)图中,可以发现最左边的样本的收益是一个很大的负数,而右边两个都是很小的正数。我们想做的就是把我们的策略右移到右边的虚线,使得在坏的位置密度更低,好的位置密度更高。实际上,正负的数值对这个算法影响很大:两个小正数和一个大负数可能把步伐拉得比较大。
而(b)图中,我们只是把收益都加上了一个很大的常数,收益之间的相对差不变。如果我们把所有情况的收益都增减同一个常数,我们可以把这个常数从这个期望中提出来,作为一个与参数无关的部分,因此整个期望关于参数求梯度的结果是不发生变化的。此时,策略梯度法就会想增加第一个样本的概率(行为发生了根本性变化),但更想增加后两个的概率。这个情况下,移动的步伐就小了很多,取而代之的是密度曲线可能变得更平缓了,方差就增大了。
这一点被称为“高方差”问题。一个更极端的情形是,有很好的样本,但是它的收益函数是0(其他的样本收益为负数),那么如何动完全依赖于我现在的策略在什么位置。我们只需要把奖励函数整体上下移动,就可以完全改变策略梯度法的行为。这个问题主要是因为如果我们选取无数个样本的话,那么这些差异互相会被抵消掉;但是对有限个样本的选择会很有偏差,就会导致这样的问题:对于这样的高方差问题,当然增加样本总是能缓解的,但是增加样本也使得学习效率降低。
因此如果想通过有限样本估计梯度,当样本数量较少时,多次估计会出现较大方差。这导致梯度上升并不是沿一条直线,而是随意摆动。
方差削减
方法一:因果关系(causality)
回顾梯度为:
在时间点
t
′
t'
t′的策略不能影响时间点
t
<
t
′
t<t'
t<t′的收益。这个关系看起来很蠢,就像今天做的事情不会影响昨天已经发生的事情。而事实上我们可以用这个关系得到更好的估计量。我们把后者这个括号做进前面去:
我们将双重求和号调整顺序,得:
我们把
Q
^
i
,
t
=
∑
t
′
=
t
T
r
(
s
i
,
t
′
,
a
i
,
t
′
)
\hat{Q}_{i,t}=\sum_{t'=t}^Tr(s_{i,t'},a_{i,t'})
Q^i,t=∑t′=tTr(si,t′,ai,t′)记作今后收益 (reward-to-go),也就是从这个时刻起的收益。这样做的一大好处就是,数值求和上减少了,方差也随之减少(求和项数量越小方差越小)。
方法二:baseline
回顾
▽
θ
J
(
θ
)
≈
1
N
∑
i
=
1
N
▽
θ
log
π
θ
(
τ
)
r
(
τ
)
\bigtriangledown_{\theta}J(\theta)\approx\frac{1}{N}\sum_{i=1}^N\bigtriangledown_{\theta}\log \pi_{\theta}(\tau)r(\tau)
▽θJ(θ)≈N1∑i=1N▽θlogπθ(τ)r(τ),我们希望好的轨迹的收益函数是正的,而差的轨迹是负的。然而之前也提到了它对值非常敏感,如果收益函数增加或者减少一个常数,结果就会很不同。所以我们想做的,可能是不依赖于轨迹自身有多好,而是一条轨迹比平均好多少:这里的平均指的是我们平时通常情况的普遍收益。举个例子,平均可以是
b
=
1
N
∑
i
=
1
N
r
(
τ
i
)
b=\frac{1}{N}\sum_{i=1}^Nr(\tau_i)
b=N1∑i=1Nr(τi),然后使用
▽
θ
J
(
θ
)
≈
1
N
∑
i
=
1
N
▽
θ
log
π
θ
(
τ
)
[
r
(
τ
)
−
b
]
\bigtriangledown_{\theta}J(\theta)\approx\frac{1}{N}\sum_{i=1}^N\bigtriangledown_{\theta}\log \pi_{\theta}(\tau)[r(\tau)-b]
▽θJ(θ)≈N1∑i=1N▽θlogπθ(τ)[r(τ)−b]。
看起来是非常合理的,而且更重要的是在这里
b
b
b是某个常数的话,这样做上式的期望依然不变:
其中第一个等号是把期望写成积分形式,第二个等号直接利用了我们之前导数的恒等关系,第三个利用了
b
b
b是常数和积分微分可交换的性质,第四个利用了对一个概率密度积分恒等于1的性质。因此我们减去一个常数的基准线,这样得到的估计总是在期望意义下无偏的。
当然,我们这么取平均得到一个基线常数不见得是最好的,但是实际效果却通常较好。为了降低方差,我们可以求出一个理论上最优的
b
b
b。回忆方差的表达式为:
而:
其方差为:
而我们在前面已经证明了上式的后面一部分与
b
b
b的值无关。
令
g
(
τ
)
=
▽
θ
log
p
θ
(
τ
)
g(\tau)=\triangledown_{\theta}\log p_{\theta}(\tau)
g(τ)=▽θlogpθ(τ),则上式对
b
b
b求导可得:
本质上来说,它是一个关于概率梯度的加权平均,不同样本的权重不同是因为概率的梯度不同。而我们前面说的简单平均只是它的一个粗糙简化版本而已,也是有一些理论根据的。在实践中也没有发现很大的效果差异。
以下部分摘自David Silver强化学习公开课第七讲
原则上,和行为无关的函数都可以作为b。一个很好的b就是基于当前状态的状态价值函数
V
π
(
S
)
V_{\pi}(S)
Vπ(S)。
这样我们通过使用一个advantage function(优势函数),定义:
这个优势函数的现实意义在于,当个体采取行为
a
a
a离开
s
s
s状态时,究竟比该状态
s
s
s总体平均价值要好多少?如此一来,目标函数的梯度可以写成:
问题二:on-policy问题
我们不难发现策略梯度法是一个同策略 (on-policy) 算法,这是因为策略梯度求期望的时候必须是从当前的分布上采样才能有无偏性,而这就要求每次梯度更新之后就根据新分布全部重新采样。如果策略是一个非常复杂的神经网络,每次迭代可能只更新一点点,但也要求把之前的样本全都扔了然后重新采样,对数据的利用率是非常低的。在前面也提到了,使用策略梯度法选择学习率可能是很难的,收敛速度也可以非常低。
能否不从最新的 p θ ( τ ) p_{\theta}(\tau) pθ(τ)中得到样本?假设有一堆从分布 p ˉ ( τ ) \bar{p}(\tau) pˉ(τ)中得到的数据,知道其对应的轨迹和收益,则我们可以使用重要性抽样 (importance sampling) 方法。
重要性抽样原理如下:
则目标函数可转化为下式:
由于
则
最难处理的初始分布和转移概率可以直接消掉。现在使用IS技术求目标函数的梯度:
这个和之前还是比较相似的,只是前面加了一块权重。同样,之前所说的因果关系可以加到这里来,类似的推导过程可以得到:
那么这么做的问题主要在哪里呢?我们不难看出中间这块连乘部分的数值,是关于
T
T
T指数增长的,如果每个数都略小于1,而时间轴非常长,这个乘积最终将非常接近于0,这样梯度效果就会很差了。
在课程的后面会具体介绍怎么解决,而这里给一个预览。我们把目标函数重写为:
写成一个边际分布下的期望求和的形式。根据我们的决策过程,把期望进一步展开成:
这样,我们就可以在两个层面上做重要性抽样了:
这样就不再有指数乘积问题,但是同时又带来了一个新的难题:需要知道转换概率
p
θ
′
(
s
t
)
p_{\theta'}(s_t)
pθ′(st)。一个近似的处理方式是可以把
p
θ
′
(
s
t
)
p
θ
(
s
t
)
\frac{p_{\theta'}(s_t)}{p_{\theta}(s_t)}
pθ(st)pθ′(st)看成1,直接去掉。当然这样做的话理论上就不再无偏了,但是事实上当两个策略足够接近的话,可以说明这个比值是不重要的:在很多问题的实践上是好的,而且有一定的理论保证。
问题三
让我们考虑一个一维的连续状态和行动的增强学习问题。参数是
θ
=
(
k
,
σ
)
\theta=(k,\sigma)
θ=(k,σ)。对数策略函数是一个高斯分布,由这两个参数确定,整个簇的形式是:
依赖于行动和均值之差的平方,其中均值是当前状态的
k
k
k倍。收益函数
r
(
s
t
,
a
t
)
=
−
s
t
2
−
a
t
2
r(s_t,a_t)=-s_t^2-a_t^2
r(st,at)=−st2−at2,前一部分表明最终状态希望是0,后一部分说明我们希望行动大小尽量小:这在机械中是很合理的,如果我们的行动是电动机指令的话,通常不希望让电动机运转过强。在最优控制领域,这是一个LQR问题,可以用解析方法求出最优解,也很容易分析。但是在策略梯度法中,有趣的是,因为收益函数希望行动尽量小,梯度法总会倾向于减小
σ
\sigma
σ(见上图,蓝色箭头为梯度,总在降低[公式]的方向),用于减少很大的
a
t
a_t
at的概率:因为概率来源于高斯分布,而高斯分布的支撑集非常大。事实上,更小的
σ
\sigma
σ,更倾向于让我们进一步减少
σ
\sigma
σ。即便我们的梯度总是指向正确的方向,它在
σ
\sigma
σ上的分量更长些:在
σ
\sigma
σ很小时候,
k
k
k分量的大小可以忽略不计了。因此一个结果是,我们会快速下降
σ
\sigma
σ,然而逐渐地
k
k
k就不动了,所以最终得到一个正确结果的速度奇慢无比。这也导致了策略梯度法的收敛速度很慢,而且选择学习率也是一个很难的问题:如果因为收敛速度慢而使用了较大的步长,反而更快地进入了一个让
k
k
k难以动弹的状况。
用自动差分器做策略梯度法
我们现在想找到一个比较简单的方法去实现策略梯度法,以利用上TensorFlow或者PyTorch等自动差分器。回顾梯度:
我们不想显式地去计算这些对数梯度并做乘法。考虑到极大似然估计的目标函数为:
梯度为:
我们要把
Q
^
i
,
t
\hat{Q}_{i,t}
Q^i,t放进去。一个特性是
Q
^
i
,
t
\hat{Q}_{i,t}
Q^i,t本身是不依赖于参数的,我们所需要做的一切就是做一个虚拟的损失函数,加权损失函数:
其中权重就是
Q
^
i
,
t
\hat{Q}_{i,t}
Q^i,t,然后就用自动差分器求梯度就行了。当然,on-policy方法要求我们每一个梯度步重新采样,所以我们不能使用SGD。
Levine教授给出了TensorFlow样式的代码例子,给出了两者的区别(状态和行动认为是离散的,所以是one-hot编码,因此输入是二维张量):
- 最大似然估计:
# Given:
# actions -(N*T) x Da tensor of actions
# states -(N*T) x Ds tensor of states
# Build the graph:
logits = policy.predictions(states) # This should return (N*T) x Da tensor of action logits
negative_likelihoods = tf.nn.softmax_cross_entropy_with_logits(labels=actions, logits=logits)
loss = tf.reduce_mean(negative_likelihoods)
gradients = loss.gradients(loss, variables)
- 策略梯度法:
# Given:
# actions -(N*T) x Da tensor of actions
# states -(N*T) x Ds tensor of states
# q_values – (N*T) x 1 tensor of estimated state-action values
# Build the graph:
logits = policy.predictions(states) # This should return (N*T) x Da tensor of action logits
negative_likelihoods = tf.nn.softmax_cross_entropy_with_logits(labels=actions, logits=logits)
weighted_negative_likelihoods = tf.multiply(negative_likelihoods, q_values)
loss = tf.reduce_mean(weighted_negative_likelihoods)
gradients = loss.gradients(loss, variables)
可以发现差别还是很小的,只是加了一个加权的过程。
策略梯度法在实践中的注意事项
- 梯度的方差是非常大的:
这和监督学习是不一样的!
梯度噪声很大! - 使用很大的批量数据来降低方差;
- 调整学习率是很有挑战性的:
使用自适应的步长如ADAM等方法通常还可以。
在之后的课程中会讲一些针对策略梯度法的步长调整方法。
更多推荐
所有评论(0)