1、前言
这篇博客主要是参考了李宏毅的强化学习课程,感觉讲的挺不错的,有兴趣的同学可以去看一下。
通俗点来说,强化学习是通过将惩戒来学习正确行为的机制。基本结构可以看下面的一个图:

也就是说 Agent 需要通过强化学习的方法来学习到正确的 Action。上图中,Environment一般是写好的规则,Reward 也是事先定好的,我们需要优化的是 Agent 所执行的 Action。
Policy Gradient 是强化学习的一种,它与基于价值的方式不同,是直接进行策略(Policy)的学习,即将策略看成是状态和行为的带参数的策略函数。简单来说,Policy Gradient 方法是直接输出下一步的动作。
2、策略目标函数
Policy π\piπ 决定了 Agent 的行为。所谓的 Policy 就是给定一个外界输入,然后它会输出 Agent 现在要执行的一个行为。Policy π\piπ 可以被描述为一个包含参数 θ\thetaθ 的函数:
πθ=P(a∣s,θ)\pi_{\theta} = P(a|s, \theta)πθ=P(a∣s,θ) 从公式可以看出,策略函数 πθ\pi_{\theta}πθ 是一个概率密度函数,它是在给定的状态和一定的参数设置下 ,采取任何可能行为的概率。简单来说就是输入状态 sss,输出下一个动作。 其中,sss 一般是给定的,所以,我们的目标是求最优参数 θ\thetaθ ,来使得下一步的动作 aaa 最优。
3、例子
加入现在有个游戏如下图所示,Env表示环境 Environment,Actor即为 Agent,Trajectory代表一个回合:

pθ(τ)=p(s1)pθ(a1∣s1)pθ(s2∣s1,a1)p(a2∣s2)p(s3∣s2,a2)⋯=p(s1)∏t=1Tpθ(at∣st)p(st+1,at)\begin{aligned}
p_{\theta}(\tau) &= p(s_1)p_{\theta}(a_1|s_1)p_{\theta}(s_2|s_1,a_1)p(a_2|s_2)p(s_3|s_2, a_2)\cdots \\\\
&= p(s_1)\prod_{t=1}^T p_{\theta}(a_t|s_t)p(s_{t+1}, a_t)
\end{aligned}pθ(τ)=p(s1)pθ(a1∣s1)pθ(s2∣s1,a1)p(a2∣s2)p(s3∣s2,a2)⋯=p(s1)t=1∏Tpθ(at∣st)p(st+1,at)
其中,p(s1)p(s_1)p(s1) 是初始的环境,环境之间通常是有联系的。其中 p(st+1,at)p(s_{t+1}, a_t)p(st+1,at) 是游戏已经写好了的,就像输入一个动作,它的下一个画面自己就会出来。所以我们能改变的是 pθ(at∣st)p_{\theta}(a_t|s_t)pθ(at∣st)。
现在我们再来看 Reward,Reward Function 的意思是在当前环境下,相应的行为会得到多少分数:

R(τ)=∑t=1Trt
\begin{aligned}
R(\tau) = \sum_{t=1}^Tr_t
\end{aligned}
R(τ)=t=1∑Trt
我们现在需要做的就是调整 θ\thetaθ 的值,使得 R(τ)R(\tau)R(τ) 的值越大越好。因为 Actor 采取的动作是具有随机性的,所以我们最终的奖励也是具有随机性的,所以我们应该算一个期望值,也就是穷举所有的 Trajectory:
Rθ‾=∑τR(τ)∗pθ(τ)=Eτ∼pθ(τ)[R(τ)]
\begin{aligned}
\overline{R_\theta} = \sum_{\tau}R({\tau})*p_{\theta}(\tau) = E_{{\tau}\sim {p_{\theta}}(\tau)}[R(\tau)]
\end{aligned}
Rθ=τ∑R(τ)∗pθ(τ)=Eτ∼pθ(τ)[R(τ)]
然后我们来求梯度,下式中的上标只是单纯的上标,不是次方:
∇Rθ‾=∑τR(τ)∇pθ(τ)=∑τR(τ)pθ(τ)∇logpθ(τ)=Eτ∼pθ(τ)[R(τ)∇logpθ(τ)]≈1N∑n=1NR(τn)∇logpθ(τn)=1N∑n=1N∑t=1TnR(τn)∇logpθ(atn∣stn)
\begin{aligned}
\nabla \overline{R_\theta} &= \sum_{\tau} R(\tau) \nabla p_{\theta}(\tau) \\\\
&= \sum_{\tau} R(\tau)p_{\theta}(\tau)\nabla \log p_\theta(\tau) \\\\
&= E_{{\tau} \sim {p_{\theta}(\tau)}} [R(\tau) \nabla \log p_\theta (\tau)] \\\\
&\approx \frac{1}{N} \sum_{n=1}^{N} R({\tau} ^ n) \nabla \log p_{\theta}({\tau}^n) \\\\
&= \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_n} R({\tau}^n)\nabla \log p_{\theta}(a_t^n|s_t^n)
\end{aligned}
∇Rθ=τ∑R(τ)∇pθ(τ)=τ∑R(τ)pθ(τ)∇logpθ(τ)=Eτ∼pθ(τ)[R(τ)∇logpθ(τ)]≈N1n=1∑NR(τn)∇logpθ(τn)=N1n=1∑Nt=1∑TnR(τn)∇logpθ(atn∣stn)
剩下就正常更新参数 θ\thetaθ 就行了,只是一般我们都是最小化损失函数,这里是最大化 Reward,更新时改变一下正负号。另外,它的奖励是很多轮结束后的奖励(也就是游戏结束后,根据游戏的输赢给奖励),所以跟新梯度与普通有些不同。
这里说一个小提示:游戏的奖励都为正的话,那么应该考虑加一个 baseline ,也就是用 reward-baseline 来当做最终的reward。
另外,理想的状况下,我们更希望每一个不同的 Action,我们都给一个 reward,这样才能真正反应每一个 action 到底是不是好的。所以嘞,我们可以将奖励 R(τn)R(\tau ^n)R(τn) 用下式代替,也就是只考虑当前步与后面步骤的联系:
∑t′=tTnrt′n \begin{aligned}
\sum_{t \prime = t}^{T_n}r_{t \prime}^n
\end{aligned}t′=t∑Tnrt′n
这样我们给奖励时就不考虑前面的 action 了,进一步地,为了减少当前步与距离远的后续步骤的联系,可以继续变换成:
∑t′=tTnrt′nγt′−t \begin{aligned}
\sum_{t \prime = t}^{T_n}r_{t \prime}^n \gamma ^{t \prime - t}
\end{aligned}t′=t∑Tnrt′nγt′−t
其中 γ<1\gamma < 1γ<1,这样距离当前 action 远的后续 action 的影响就会很小。通常我们将 R(τn)−bR(\tau ^ n)-bR(τn)−b 合起来称作 Advantage Function,通常用 Aθ(st,at)A^\theta(s_t, a_t)Aθ(st,at) 表示。
4、后续
最后,我们可以看出来,每一次更新,我们都需要 sample 很多 data,而且,更新后,这些 data 就没有用了。为了解决这个问题,就有了 Policy Gradient 的一个变形:Proximal Policy Optimization (PPO)。