深度强化学习(DRL)算法 1 —— REINFORCE

60 阅读2分钟

“养成习惯的过程可以分为四个简单的步骤:提示、渴求、反应和奖励。”

摘录来自 掌控习惯 詹姆斯·克利尔(James Clear) 此材料可能受版权保护。

前言

就像引言里所描述的养成习惯的四个步骤,如果我们想让机器也有自己的“习惯”,去掉机器没有的渴求属性,就是强化学习所做的事情 —— 帮机器养成“习惯”,而 DRL 就是使用深度学习的技术去实现强化学习算法。今天是系列文章的第一篇,会介绍最基础的 policy-based 的算法 —— REINFORCE。

算法描述

就像人类养成习惯需要一遍遍经历四个步骤,机器也一样,需要经历上述的三个步骤,经历 T 时刻积累的经验形成的序列叫做 Trajectory,我们用 τ\tau 表示(有人可能还看过 episode 的概念,一个 τ\tau 可以有多个 episode)。s 代表机器所处的环境产生的提示或者状态,a 代表机器的反应或者行动,r 代表机器产生反应或者行动后获得的回报。 τ=s0,a0,r1,s1,a1,r2,s2,a2...rT,sT,aT\tau = {s0, a0, r1, s1, a1, r2, s2, a2 ... rT, sT, aT} 那么根据 MDP 属性有 p(τ)=t=0Tpθ(atst)p(st+1st,at)p(\tau) = \prod_{t=0}^{T}p_{\theta}(a_{t}|s_{t})p(s_{t+1}|s_{t}, a_{t}) 那么这里的 pθp_{\theta} 就是机器的策略,针对 s 会产生什么样的 a。因为当 s 和 a 都确定了,下一时刻的 s 是系统的固有属性,我们没办法控制,所以我们后面只关心 pθp_{\theta} 。 因为每一时刻的反应都会产生相应的回报,那么我们把每一时刻的回报加起来,就是这一系列反应产生的整体回报,我们用 R(τ)R(\tau) 表示。有了整体回报,我们就可以衡量机器行为的好坏。

R(τ)=t=1TrtR(\tau) = \sum_{t=1}^{T}r_{t}

机器应该更关心当下的回报还是未来的回报呢?我们引入系数 γ\gamma ,如果它是 0,我只关注当下,它的值越大,我们会越关心未来的回报。

R(τ)=t=1Tγt1rt,γ[0,1]R(\tau) = \sum_{t=1}^{T}\gamma^{t-1}r_{t},\gamma \in [0,1]

有了上面的信息,接下来我们只要使得机器的期望回报最大,我们的机器就会牛逼起来!

Rˉθ=Eτpθ(τ)[R(τ)]=τpθ(τ)R(τ)\bar{R}_{\theta} = E_{\tau\sim p_{\theta}(\tau)}[R(\tau)] = \sum_{\tau}p_{\theta}(\tau)R(\tau)

如何获得最大的期望回报?

由上面的期望回报的公式,我们可以通过调节策略增大可以获得更大回报的反应的概率,可以用深度神经网络表示策略,把 s 输入神经网络(可以是 MLP\CNN\LSTM\Transformer...)获得的输出就是每个反应的概率。s 输入到神经网络,得到 a,这里随机采样一个 a(为了探索,选最大的不一定是正确的) 然后得到下一时刻的 s,重复收集,就有了上面公式里的 τ\tau ,从而就积累了训练数据。那么有过机器学习经验的人,可以发现答案呼之欲出,就是求导,梯度下降是求最小值,那么求最大值就是加个负号。

θθ+αRˉ(θ)\theta \leftarrow \theta + \alpha \nabla \bar{R}(\theta)

其中:

Rˉ(θ)=θτp(τ)R(τ)            =τθp(τ)R(τ)            =τp(τ)θp(τ)p(τ)R(τ)    (因为θlog(z)=1zθz)            =τp(τ)θlog p(τ)R(τ)            1mi=1mθlog p(τ(i))R(τ(i))            =1mi=1mt=1Tθlog pθ(at(i)st(i))R(τ(i))            =1mi=1mR(τ(i))t=1Tθlog pθ(at(i)st(i))\nabla \bar{R}(\theta) = \nabla_{\theta}\sum_{\tau}p_{}(\tau)R(\tau) ~\\ \ \ \ \ \ \ \ \ \ \ \ = \sum_{\tau}\nabla_{\theta}p(\tau)R(\tau) ~\\ \ \ \ \ \ \ \ \ \ \ \ = \sum_{\tau}p(\tau)\frac{\nabla_{\theta}p(\tau)}{p(\tau)}R(\tau) \ \ \ \ (因为 ∇_θlog(z)=\frac{1}{z}∇_θz) ~\\ \ \ \ \ \ \ \ \ \ \ \ = \sum_{\tau}p(\tau)\nabla_{\theta}log\ p(\tau)R(\tau) ~\\ \ \ \ \ \ \ \ \ \ \ \ \approx \frac{1}{m}\sum_{i=1}^{m}\nabla_{\theta}log\ p(\tau^{(i)})R(\tau^{(i)}) ~\\ \ \ \ \ \ \ \ \ \ \ \ = \frac{1}{m}\sum_{i=1}^{m}\sum_{t=1}^{T}\nabla_{\theta}log\ p_\theta(a_{t}^{(i)}|s_{t}^{(i)})R(\tau^{(i)}) ~\\ \ \ \ \ \ \ \ \ \ \ \ = \frac{1}{m}\sum_{i=1}^{m}R(\tau^{(i)})\sum_{t=1}^{T}\nabla_{\theta}log\ p_\theta(a_{t}^{(i)}|s_{t}^{(i)})

实现

实现很简单,这里结合参考很快就可以看懂。

缺点

方法很简单,虽然说大道至简,但是用上述方法训练出来的机器还是不够牛逼。主要是因为方法里存在一些缺陷: 策略产生的 τ\tau 不能再次用于训练,因为策略一直在更新,策略更新了,那么更新之前产生的 τ\tau 就得丢掉了,训练效率很低。 τ\tau 里的每个 a 用的都是同样的 R,更好的情况应该是每个 a 用一个 R。

改进

针对 1,下一篇文章介绍的 PPO 提出了改进 针对 2: 我们可以这样设置 R(一种 Credit Assignment): Rt(τ)=t=t(a)Tγtt(a)rt,γ[0,1]R_{t}(\tau) = \sum_{t=t(a)}^{T}\gamma^{t-t(a)}r_{t},\gamma \in [0,1]

参考

  1. 深度强化学习——李宏毅
  2. Deep Reinforcement Learning: Pong from Pixels
  3. examples reinforcement learning
  4. hugging face deep rl class
  5. What does log_prob do?