Trpo

https://arxiv.org/pdf/1502.05477.pdf

We describe a iterative procedure for optimizing policies, with guaranteed monotonic improvement. By making several approximations to the theoretically-justified procedure, we develop a practical algorithm, called Trust Region Policy Optimization (TRPO). This algorithm is similar to natural policy gradient methods and is effective for optimizing large nonlinear policies such as neural networks. Our experiments demonstrate its robust performance on a wide variety of tasks: learning simulated robotic swimming, hopping, and walking gaits; and playing Atari games using images of the screen as input. Despite its approximations that deviate from the theory, TRPO tends to give monotonic improvement, with little tuning of hyperparameters.

给出了一个迭代式优化策略的方法,保证单调改进. 通过对经理论验证的过程的几个近似,我们设计了一个实用的算法,称为 Trust Region Policy Optimization(TRPO),这个算法类似于 natural Policy gradient,对优化大型非线性策略(如神经网络)非常有效. 我们的实验展示了在众多不同的任务上(如学习模拟机器人游泳、跳跃和行走;使用游戏图像学习玩 Atari 游戏)健壮的性能. 尽管近似跟理论结构有所偏离,但是 TRPO 还是给出了单调的提升,也不需要太多的超参数调优.

引言

大多数策略优化的算法可以被分成:a. 策略迭代方法,轮换地估计当前策略下的值函数和提高策略(Bertsekas, 2015);b. 策略梯度方法,使用从样本轨迹获得的期望回报(总共奖励)的梯度的估计(Peter & Schaal, 2008a)(这个方法其实和策略迭代方法有很密切的关联);c. 免导数优化方法,如 交叉熵方法(CEM)和协方差矩阵适应(CMA),将回报当做是一个黑盒函数使用策略参数进行优化(Szita & Lörincz,2006).

通常的免导数随机优化方法适用于很多问题,因为他们能够获得很好的结果,也容易理解和实现. 例如 Tetris 是近似动态规划方法的经典的 benchmark 问题,随机优化方法其实在这个问题表现超过近似动态规划方法. 对于连续控制问题,如 CMA 的方法已经能够在给定低维度参数化的手工特征策略类情况下成功学习控制策略了(Wampler & Popvić,2009). ADP 和基于梯度的方法并不能一致性地超过免梯度随机搜索其实不太令人满意,因为相比免梯度方法,基于梯度优化的算法有着更加好的采样复杂度保证(Nemirovski,2015). 连续基于梯度优化已经在监督学习中的函数近似上表现神勇,并且将其成功迁移到强化学习上应该可以给出更加高效的复杂和强大策略的训练.

在本文中,我们首先证明最小化某个 surrogate 目标函数保证了策略依照非平凡的步长进行提升. 接着我们对理论验证算法进行一系列的近似,得到一个实际算法,这个我们称为 信頼域策略优化(TRPO)算法. 我们给出了这个算法的两个变种:1. 单路径 方法,可以应用在无模型场景下;2. vine 方法,要求系统可以由特定的状态进行重生,这个在模拟中是比较常见的. 这些算法都是可扩展的,并且可以优化上万参数的非线性策略,这其实是之前免模型策略搜索方法的主要挑战之一(Deisenroth等人,2013). 在我们的实验中,同样的 TRPO 算法可以学到复杂的游泳、跳跃和行走的策略,也能够学会玩 Atari 游戏.

预备知识

考虑一个无穷长度的折扣 MDP(Markov Decision Process),定义为元组 $(\mathcal{S},\mathcal{A},P,r,\rho_0,\gamma)$,其中 $\mathcal{S}$ 为有穷状态集,$\mathcal{A}$ 为有穷行动集合,$P:\mathcal{S}\times \mathcal{A} \times \mathcal{S} \rightarrow \mathbb{R}$ 是转移状态分布,$r:\mathcal{S} \rightarrow \mathbb{R}$ 是奖励函数,$\rho_0:\mathcal{S} \rightarrow \mathbb{R}$ 是初始状态 $s_0$ 的分布,而 $\gamma \in (0,1)$ 是折扣因子.

Dpg

基于值和基于策略的强化学习

  • 基于值
    • 学习到的值函数
    • 隐式的策略(如 $\epsilon$-贪婪)
  • 基于策略
    • 不使用值函数
    • 学习到的策略
  • Actor-Critic
    • 学习到的值函数
    • 学习到的策略
      优势:
  • 更好的收敛属性
  • 高维或者连续行动空间
  • 可以学习随机策略
    劣势:
  • 通常会收敛于一个局部最优点(而非全局最优)
  • 衡量策略通常低效和高方差

策略目标函数

  • 目的:给定策略 $\pi_\theta(s,a)$ 参数为 $\theta$,找到最优 $\theta$
  • 但是我们如何衡量策略 $\pi_\theta$ 的质量?
  • 在片段式环境中,我们使用开始值
    $$J_1(\theta) = V^{\pi_\theta}(s_1) = \mathbb{E}_{\pi_\theta}[v_1]$$
  • 在持续式环境我们可以使用平均值
    $$J_{avV}(\theta) = \sum_{s}d^{\pi_\theta}(s)V^{\pi_\theta}(s)$$
  • 或者使用每时间步的平均奖励
    $$J_{avR}(\theta) = \sum_{s}d^{\pi_\theta}(s) \sum_{a} \pi_\theta(s,a) \mathcal{R}_{s}^{a}$$
  • 其中 $d^{\pi_\theta}(s)$ 是 $\pi_\theta$ 的马尔科夫链的稳定分布

策略优化

  • 基于策略的强化学习其实就变成了优化问题
  • 找到 $\theta$ 最大化 $J(\theta)$
  • 存在一些不用梯度的方法
    • Hill climbing
    • Simplex / amoeba / Nelder Mead
    • Genetic algorithms
  • 使用梯度常会提升效率
    • 梯度下降
    • 共轭梯度
    • Quasi-newton
  • 我们主要讲梯度下降,可以有很多扩展
  • 并且只针对开发序列结构的方法

策略梯度

  • 令 $J(\theta)$ 为任意策略目标函数
  • 策略梯度算法通过上升策略关于参数 $\theta$ 的梯度来搜索其一个局部最大值
    $$\Delta\theta = \alpha \nabla_\theta J(\theta)$$
  • 其中 $\nabla_\theta J(\theta)$ 是策略梯度
    $$\nabla_\theta J(\theta) = \begin{pmatrix} \frac{\partial J(\theta)}{\partial \theta_1} \\
    \vdots \\
    \frac{\partial J(\theta)}{\partial \theta_n}
    \end{pmatrix}$$
  • 其中 $\alpha$ 是步长参数

使用有限差异(Finite Differences)计算梯度

  • 来衡量 $\pi_\theta(s,a)$ 的策略梯度
  • 对每个维度 $k \in [1,n]$
    • 估计目标函数关于 $\theta$ 的第 $k$ 个偏导数
    • 在第 $k$ 维以小的量 $\epsilon$ 微调 $\theta$
      $$\frac{\partial J(\theta)}{\partial \theta_k} \approx \frac{J(\theta + \epsilon u_k) - J(\theta)}{\epsilon}$$
      其中 $u_k$ 是单位向量,第 $k$ 维元素为 $1$,其他为 $0$
  • 使用 $n$ 个评估来计算 $n$ 个维度的策略梯度
  • 简单、有噪声、低效 - 但有时候实用
  • 对任意策略有效,甚至不可微的策略

计分函数

  • 我们现在解析的方式来计算策略梯度
  • 假设策略 $\pi_\theta$ 在非零处可微分
  • 我们知道梯度 $\nabla_\theta \pi_{\theta}(s,a)$
  • 似然比例利用了下面的等式

\begin{array} {lcl} \nabla_\theta \pi_{\theta}(s,a) & = & \pi_{\theta}(s,a) \frac{\nabla_\theta \pi_{\theta}(s,a)}{\pi_\theta(s,a)} \\ & = & \pi_{\theta}(s,a) \nabla_\theta \log \pi_{\theta}(s,a)
\end{array}

  • 计分函数为 $\nabla_\theta \log \pi_\theta(s,a)$

Drl-Intro

深度强化学习可以说是人工智能领域现在最热门的方向,吸引了众多该领域优秀的科学家去发掘其能力极限. 而深度强化学习本身也由于其通用性备受各个应用领域推崇,从端对端游戏控制、机器人手臂控制、推荐系统,甚至也来到了自然语言对话系统. 然而如何在日新月异,几乎每日都在更新迭代的深度强化学习的进展中保持好节奏,那是这篇文章带给大家的建议和思考.

我们首先简要介绍一下深度学习和强化学习技术,以及在两者融合两者过程可能会出现的问题,接着探讨了深度强化学习的几种范式,然后介绍近期有意思的一些工作和应用,最后给出总结和展望.

基础

深度学习

深度学习是人工神经网络 2006 年后重获新生的名称,伴随着其实际应用中的超越式效果而风靡全球. 使之成为可行的方法的计算设备 GPU 也因此大卖特卖,成为深度学习研究必备利器.

人工神经网络已经可以实现任意复杂度连续函数的逼近,这个可以在 Michael Nielsen 的《神经网络和深度学习》书中看到神经网络可以计算任何函数的具体化的证明. 而深度学习则可以利用超多的隐藏层来提升表示的能力(浅层网络需要指数级的隐藏元个数才能达到相当的深层网络的表达能力)。深度学习的表示其实是大量函数的复合,并可以通过反向传播进行训练,参见下图.

深度学习

现在深度学习已经席卷了语音识别、图像识别、计算机视觉、自然语言处理乃至视频预测等领域,主要的两种网络 CNN 和 RNN 完成了空间和时间的完备. 但由于对于深度学习本身仍旧有太多的认知空白,一部分人仍然对其无法完全接受. 尽管这样,我还是想建议大家去了解它,你可以从书本开始,比如说前面提到的 《神经网络和深度学习》 还有来自 Montreal University 的 《深度学习》,来走进这个领域. 这本书包含了深度学习学习、研究及应用所有需要的概念和直觉(并不含强化学习)

强化学习

强化学习,现在常常将其看作机器学习领域的一个分支,但如果细细去看,你会发现,强化学习本身也有完整的一条发展的脉络. 从动物行为研究和优化控制两个领域独立发展最终经 Bellman 之手汇集抽象为 MDP 问题而完成形式化. 之后经很多的科学家的不断扩大,形成了相对完备的体系——常被称为近似动态规划,参看 MIT 教授 Dimitri P. Bertsekas 的 动态规划系列,Dynamic Programming and Optimal Control, Vol. II, 4th Edition: Approximate Dynamic Programming.

强化学习是非常严谨的领域,适合各类人享受/被折磨(数学重起来可以直接 KO 一般的非数学系本科生). 但往往应用起来却非常困难,首先维度灾难的存在使得我们很难高效地求解最优的策略或者计算最优行动值. 另外深度学习其中包含的思想——贪婪、动态规划、近似等等都是算法中最为关键的部分,也是这些方法使用得比较极致的地方. 因此,才有不少人持续在其上很多年不断地推进研究的深入和一般性. (这里,其实要说一句,国内的强化学习研究并不是特别领先,也要引发我们的思考. 另一个有趣的现象是,作为强化学习研究的重镇 Alberta 大学,也就是 Richard Sutton 等计算机科学家领衔的强化学习中心,同样是在加拿大. 这种感觉让人想到了 Geoffrey Hinton 在 Toronto 领导的深度学习复兴. 个人感觉,国内强化学习研究不能够兴起的原因是研究者本身相对狭窄的视角,与不同学科和思想的连接甚弱,乃至于不敢想象——一句话概括的话,我觉得是勇气和想象力的缺失吧!在现在的研究中看到得更多是很多想法的全方位连接,交叉科学的研究是切切实实地交叉. )

在 Warren B. Powell 的一篇短文中说道,很多来自不同领域的人,都在忙着自己的一亩三分地上耕耘,自得其乐;实际上,大多人做出来同样的工作,因此他提出了 10 条意见. 简言之:建议大家从一个全貌看待问题和学科,找到相通联的点,以此出发,找到潜在的连线,最终形成整体的面的认知.

这里结合 David Silver 的强化学习课程给出一个强化学习的概貌:

强化学习

深度强化学习

深度学习模型的简单(实际上带来了更多的不可控制的难度)刚刚好是降低了一些使用的难度,短短数十行代码,便能够解决之前需要花费大量精力才可以设计出来的系统. 所以,各个应用领域(语音、图像、视觉、自然语言理解等)现在都把资源往深度学习上倾斜,在这里我们不去评判这会造成的未发生的不良后果,从乐观的角度来看,深度学习确实让人工智能领域重新焕发活力. 当然如何去疏导人们的激情是相当重要的事情,我相信过上一段时间后,大家都会找到合适的路径发展下去的.

一蹴而就的成功在科学领域往往是非常难以实现的. 存在的若干重要的数论、图论问题,也都是经过一代代科学家继往开来、在前人工作上不断推进的. 说完了历史,现在来看看最为激动人心的进展. 我们介绍深度强化学习的范式和相关算法. 看看究竟什么才是最为关键的因素. 实际上关键在于我们如何去应用这些技术解决问题——适合的问题建模,解决手段的提升.

强化学习之前并不能实用的原因在于面对过大的状态或者行动空间,很难有效地处理这些情形,往往看到的例子都是相对简化的场景. 深度学习的出现让人们能够去处理真正的问题,比如说视觉识别准确率的大幅提高至 ImageNet 数据急的 top-5 错误率下降到了 4% 以内,现在语音识别已经真正变得比较成熟,并且被广泛商用,且目前所有的商用语音识别算法没有一个不是基于深度学习的. 这些都是说明深度学习能成为一些实际应用的基础. 而现在深度强化学习的研究和应用也基本上针对上面的问题展开.

根据 Berkeley 的深度强化学习课程我们可以其分成策略梯度方法(Policy Gradient Methods)、近似动态规划方法(Approximate Dynamic Programming Methods)和 搜索+监督学习(Search + Supervised Learning)三类. 我们这里挑几个代表性的方法简要介绍一下,如 DQN、Double Q-Network 和 DDPG 等方法及现在的一些应用,如机器人手臂控制、对话生成和游戏控制等等. 这些研究也不是突然一下子就出现的,他们的产生可以说伴随着强化学习的发展而恰好到深度学习的出现又产生了巨大的能量. DQN 实际上在 2013 年就已经发表,后经 DeepMind 众人改进成发表在 Nature 上的经典文章,由于现在已经有大量的文章介绍过,我们这里略过. DQN 是一种基于 Q-学习的神经网络版本. 通过神经网络来近似 Q 函数,但是并不是简单地替换,否则在 2006 年应该就能够产生一定的影响了. DQN 解决了三个困难,DQN 为深度基于值的强化学习问题提供了一种稳定解决方案:

  1. 使用经验回放将数据之间的关联打破,重回独立同分布的设定下,从过去的策略中学习,使用 免策略 Q-学习
  2. 目标 Q-网络避免振荡,将 Q-网络和目标网络之间的关联打破
  3. 截断奖励或者正规化网络,适应到合适的范围内可以得到健壮的梯度

Double Q-Network

http://arxiv.org/pdf/1509.06461v3.pdf

在某些随机环境中,Q-学习表现很糟糕. 罪魁祸首是很大的行动值的过估计(
overestimations). 这些过估计是由于 Q学习使用最大的行动值作为最大期望行动值的估计产生了正的偏差. 这里有另外一种方式来近似对于任意随机变量集的最大期望行动值. 所谓的双估计方法某些事件会欠估计而不是过估计. 将这种思想应用在 Q-学习上可以得到双 Q-学习方法,一种免策略强化学习方法. 这个算法可以收敛到最优策略上,并在某些设置下表现得要超过 Q-学习算法.

Double Q-Network 则是融合 Q-学习和深度学习的结果,在某些 Atari 游戏中 DQN 本身其实也会受到过估计的影响,通过双 Q-学习的引入,就能够处理大规模的函数近似问题. 最终的算法不仅仅降低了观察值过估计,而且在某些游戏中有着相当好的表现.

策略梯度方法

尽管现存若干本强化学习相关的书籍,但是对于策略梯度部分的介绍确实不够的.已有的强化学习(RL)课本没有给出足够的关于如何使用函数近似的指导;基本上都是聚焦在离散状态空间的领域. 而且,现有 RL 课本并没有对无导数优化和策略梯度方法给出充分讲述,而这些技术在很多的任务上都是相当重要的.

策略梯度算法通过梯度下降进行优化. 就是说,通过重复计算策略的期望回报梯度的噪声估计,然后按照梯度方向来更新策略. 该方法比其他 RL 方法(如 Q-学习)更有利,原因是我们可以直接优化感兴趣的量——策略的期望总收益. 该类方法由于梯度估计的高方差长期被认为不太实用,直到最近,Schulman 等人和 Mnih 等人的工作展示了神经网络策略在困难的控制问题上的采用策略梯度方法的成功应用.

你可能比较熟悉概率模型的监督学习,其中目标是最大化给定输入(x) 时的输出 (y) 的对数概率.

策略梯度方法通常需要假设一个随机策略,该策略给出了对每个状态 (s) 的行动 (a) 上的概率分布;我们将此分布写作 .
如果我们知道对每个状态正确的行动 ,我们可以简单地最大化监督学习的目标函数:

然而,我们并不知道正确的行动. 相反,我们会尝试对行动好坏进行粗略的猜测,试着去增加好的行动的概率. 更加具体地讲,假设我们刚收集完 agent 和环境一个 agent 和环境回合的交互,所以我们有了一个状态、行动和收益的序列:. 令 表示收益的和:. 最简单的策略梯度公式就是:

使用这个梯度的估计 ,我们可以用一个梯度上升的步骤, 进行策略的更新,其中 为学习率. 我们会收集所有的回合,对那个回合中所有的行动的对数概率按照回合的总收益 为比例进行增加. 换言之,如果我们收集了大量的回合数据,其中一些是好的(凭借运气),另外一些是差的. 我们本质上是在进行监督学习——最大化好的回合的概率.
尽管我们现在还没有给出对上述策略梯度公式的数学上的验证,但实际上已经给出了一个对策略梯度的无偏估计.

策略梯度定义为右式的策略期望总收益的梯度.
如果我们用充足的样本(充足的回合),那么就可以任意精度计算出策略梯度. 然而,估计量 通常噪声很大,即有很高的方差. 你可以想象,这里存在很大的提升空间. 与其提高好的轨迹(trajectory)的概率,我们应该提高好的行动的概率,也就是说,我们应试着去推断哪些行动影响轨迹的好坏.
有一系列形如下式的策略梯度估计量:

其中 是行动 有利度 (advantage)的估计——比平均值好还是坏的程度.
下面的有利度估计量更有效率,也更常见:

其中 是折扣因子,

状态-值 函数 的近似. 用来定义一个有效时间区域,其中你忽略所有可能的超过未来 的时间步的影响.

我们的策略其实是 ,那么我们如何使用一个神经网络进行表示?实际上,我们仅仅需要将 映射到某个向量 上,向量描述了行动 上的分布. 例如,
如果 来自一个离散的集合,那么我们设计一个神经网络将 到一个概率向量上. (我们一般在神经网络的最后层使用一个 softmax 函数)这完全就是我们用来进行分类器学习的形式.
如果 是连续的,那么我们可以将 映射到一个高斯分布的均值和方差上. 一般情况我们使用一个不依赖于 的对角协方差.
如果 是二值的,那么我们可以使用一个单个输出的网络,表示输出 1 的概率.

DDPG 深度确定型策略梯度方法

http://www0.cs.ucl.ac.uk/staff/d.silver/web/Publications_files/ddpg.pdf

这是 DPG 确定型策略梯度方法的深度学习化,利用 DQN 的思想将 DPG 进行改造. DDPG 可以解决连续行动空间上的强化学习问题. 在实验中,DDPG 给出了稳定的表现,并且在不同环境上都不需要做出改动. 另外,DDPG 在所有实验中都是以比 DQN 学习使用更少时间步的经验发现 Atari 游戏的解的,大概是性能 20 倍的差距. 给定更多模拟时间,DDPG 可能解决比现在 Atari 游戏更加困难的问题. DDPG 的未来方向应该是利用基于模型的方法来减少训练的回合次数,因为模型无关的强化学习方法通常需要大量的训练才能找到合理的解.

DDPG 实际上是 Actor-Critic 结构,融合了策略和值函数两者信息进行学习. 对 Actor 和 Critic 均使用深度神经网络进行近似.

使用一个权重为 的深度神经网络 来表示策略,定义目标函数为总折扣奖励


然后使用 SGD 来端对端优化目标函数,也即是说调整策略参数 来达到更大的奖励

确定型策略梯度是 David Silver 在 2014 年的工作,刚好为此铺垫,他们证明了确定型策略梯度算法给出的期望恰好就是策略梯度(这里可以参考 DPG 论文中的证明),策略的梯度由下式给出

策略梯度是最大化提升 的方向
确定型 Actor-Critic,使用两个网络,Actor 是参数为 的策略


Critic 是参数为 的值函数


Critic 为 Actor 提供损失函数,

梯度从 Critic 到 Actor 反向传播,

Critic 通过 Q-学习估计当前策略的值

而 Actor 按照提升 Q 的方向更新策略

确定型深度策略梯度(DDPG)由于基本的 actor-critic 使用神经网络会振荡或者发散,DDPG 给出了稳定解,采取了 DQN 中的技巧对 actor 和 critic 均使用经验回放并冻结目标网络来避免振荡

基于记忆的 DRL 架构

http://arxiv.org/abs/1605.09128
近期 Michigan 大学的研究组一篇论文提出了一种基于记忆的深度强化学习架构,专门设计了可控制的机制来处理第一人称视角的场景、延迟奖励及高维视觉信息,并引入主动感知能力,从而能够较好地完成既定任务. 上面提到的问题或者要求同时具备是现有的深度强化学习架构并不能完全应付. 这个新框架在实验中相比其他的深度强化学习模型表现出了较好的泛化能力.

其结构示例如图:

这两幅图展示了记忆操作的过程和不同的网络整体结构.
MQN 仅仅依赖当前观察,除了当前输入用来做强化学习问题中的时态上下文的内存检索类似于 MemNN,是一个单纯的前驱网络结构构造了上下文环境;RMQN 则是循环结构使用 LSTM 从观察的历史信息中刻画了空间和时间信息,保证能够从 LSTM 和外部记忆中获得时态信息;FRMQN 则包含了一个从检索得到的记忆中反馈到上下文向量的链接. 如图

最终使用的 FRMQN 网络架构包含了用来抽取图像特征的卷积网络、获取历史观察的记忆单元和一个上下文向量用于记忆查询和行动值的估计. 其中提及的 FRQMN 对于未曾见过的环境在学习值函数的时候能够表现出更好的泛化能力.

https://sites.google.com/a/umich.edu/junhyuk-oh/icml2016-minecraft 可以看到在实际的 Minecraft 中的 agent 行为的效果视频.

大规模离散行动空间上的深度强化学习

https://arxiv.org/pdf/1512.07679.pdf

这项工作建立在 DeepMind 之前的 DDPG 等工作之上,杂糅了若干模型,并使用嵌入的方式来大幅度降低行动空间的维数,其主要过程在下图中给出:

博弈均衡求解的深度强化学习方法

https://arxiv.org/pdf/1603.01121.pdf

NFSP 就是引入神经网络近似函数的 FSP,是一种利用强化学习技术来从自我博弈中学习近似纳什均衡的方法. 解决了三个问题:

  • 无先验知识 NFSP agent 学习
  • 运行时不依赖局部搜索
  • 收敛到自我对局的近似纳什均衡

这是一般的不完美信息二人零和博弈. 虚拟对弈同样也会收敛到合作、势力场博弈的纳什均衡. 所以 NFSP 也能够成功应用在这些博弈上. 另外,近期的研究关于连续空间行动的强化学习(Lillicrap et al. 2015)也能够应用在连续行动博弈中,目前的博弈论方法并不能直接处理这样的情形. 所以说,这系列工作是具有重要的意义的,揭示了可以完成部分真实场景博弈的均衡求解.

用于对话生成的深度强化学习

http://arxiv.org/pdf/1606.01541.pdf

循环神经网络在对话生成上的应用确实有所进展,可以为对话机器人生成回应的语句,但是这些反应相当地短视,常常就忽略了对未来产生的后果. 为对话的未来方向进行建模是产生连贯有趣的对话的关键,这也是传统 NLP 对话模型要采用强化学习的缘故. 这个工作,将这些目标进行整合,应用深度强化学习来建模机器人对话的未来奖励. 这个对话模型模拟了两个虚拟 agent 之间的对话,使策略梯度方法在包含三个有用的对话属性(信息量、连贯性和易答性)的奖励序列上. 实验在 diversity、长度和人类评判上进行,结果表明算法产生了更具交互性的答复并刺激出更加持久的对话模拟. 这也是基于对话长期成功的学习神经网络对话模型的第一次尝试.

未来发展


现在的深度强化学习中很多的模型是,强化学习中部分研究成果深度学习化的结果. 但最令人兴奋的是,一些新的想法,例如强化变分推断,在Theophane Weber 等人的论文中,就将 VI 和 RL 进行了联系. 参见下图的对比:

RL vs VI

他们给出了一种将推断看作是强化学习的视角,这样其实可以让变分推断的研究者们受强化学习技术启发创造出新的推断技术. 基线和值函数的方式来进行解释. 很多强化学习中其他的概念可用在变分推断中,如时间差分方法或者探索方法,未来这两者间的关系应该能够挖掘到更深的层次,这也使得我们能够找到更多的微分模型和关联技术.

而这篇文章中作者之一 John Schulman 和他 Berkeley 的合作者也有一个进行从计算方法的角度统一化工作,Gradient Estimation Using Stochastic Computation Graphs,将监督学习、非监督学习和强化学习中出现的共同问题进行提炼——损失函数由一个随机变量集上的期望定义,这些随机变量可能是概率模型的变量或者是外部环境的变量. 那么使用样本来估计损失函数的梯度就是基于梯度学习的算法的核心. 该文给出了随机计算图的形式化定义——包含确定型函数和条件概率分布的有向无环图,并解释如何自动推导出损失函数梯度的无偏估计. 得到的算法是对标准反向传播算法的微小改进. 该框架可以帮助研究者们开发复杂微妙的模型,方便地加入随机和确定型的操作,如注意力、记忆和行动控制等.

另外深度强化学习在博弈均衡求解中的应用也是令人兴奋的方向之一,随着这些技术的细化和深入,我们将理论计算机和更为实用的机器学习等等技术之间的鸿沟进一步缩小.

未来深度强化学习的发展必定是理论探索和应用实践的深入,这一方面取决于我们深度学习的认识,另一方面则倚重不断地实践.

最后,我想推荐一下 OpenAI 的 gym,这是一个强化学习算法测试的环境,可以在上面去尝试自己解决一些问题,同时也可以比对自己方法的优劣. 现在也是相当活跃的一个项目,OpenAI 的成员正在不断扩展这个环境,使之满足现在强化学习需要的环境,另外也在征求大家的意见列出最关键的一些相关问题. 深度学习有很多的标准的任务可以供大家测试算法,强化学习领域实际上在前几年并不是非常方便进行测试,现在的 Gym 可以算作深度强化学习算法的试金石了.

OpenAI 处于快速发展阶段,其中涉及的 POMDP 环境不断增加:

  • 经典控制和玩具文本:强化学习文献中的小规模的任务
  • 算法:执行诸如多位数字相加,序列逆变等等计算. 大多数这样的任务需要记忆,而难度可通过序列长度调整
  • Atari 游戏:屏幕图像或者 RAM 作为输入,使用的是 Arcade Learning Environment 作为底层支撑
  • 棋盘游戏:当前包括围棋的 9X9 和 19X19 棋盘,Pachi 作为对手
  • 2D 和 3D 机器人:在模拟环境中控制机器人,这些任务使用了 MuJoCo 物理引擎,还有部分来自 RLLAB

根据 OpenAI 发布的信息,他们也在扩展 Gym 中其他的环境,如:

  • 多 agent 场景,这些场景中的 agent 之间可以合作或者竞争
  • Curriculum 学习和迁移学习. 当前这些任务还只是初期,后面会形成任务的序列,这样算法可以一个接一个任务地进行训练. 这里的设计师创建不断提升难度的任务序列,来适应所需的场景.
  • 真实世界操作:最终目标是将 Gym API 和机器人硬件进行结合,在真实世界中检验强化学习算法

所以从 OpenAI Gym 开始你可以逐步走近到走进这个有意思的领域了,通过实现那些 tricky 的算法来掌握它,对于很多人来说,实现了可以运作的算法代码才是真的懂了(我觉得可能还不够,仍旧有很多的指引需要我们去探索,也许数学证明才是真的理解象征……)

很开心能够有这样的一群人去实践人工智能技术的开放化,对此,我非常的钦佩,也希望能够借助自己的力量来帮助这个项目的成长.

OpenAI 环境

在 Gym 变得更加稳定后, OpenAI 近期向大家征求未来的研究项目,这里可以看到相应的项目和评分.
OpenAI request for research

学习建议


  • 现在网络上其实遍布了可以学习深度强化学习的资源,建议大家可以选择下面的课程:

    • Neural Networks for Machine Learning — Geoff Hinton (Coursera)
    • Neural Nets — Andrej Karpathy’s CS231N (Stanford)
    • Reinforcement Learning — David Silver UCL
    • Advanced Robotics (the MDP / optimal control lectures) — Pieter Abbeel’s CS287 (Berkeley)
    • Deep RL — John Schulman’s CS294-112 (Berkeley)
    • Deep RL — David Silver RLDM
    • Deep RL — John Schulman MLSS
  • 除了课程外,也有一些书籍,比如 Richard Sutton 等人的《Reinforcement Learning: An Introduction》,还有 Pieter 推荐了 Cover 和 Thomas 的《信息论》和 Nocedal 和 Wright 写的 nonlinear optimization 书,David Barber 的 Bayesian Reasoning and Machine Learning 等等

  • 如果你爱编程实现,那么 Ilya Sutskever 建议你从实现简单的 MNIST 分类器开始,卷积网络,重新实现 char-rnn,然后玩玩大的卷积网络. 同样还可以选择一些竞赛,比如说 Kaggle 的 Knowledge 系列. 不断地去寻找训练和实现的手感. 在 OpenAI 中也有很多的资源帮助你快速找到感觉.

  • 但实际上,深度学习和强化学习及深度强化学习需要有理论和实践的结合,所以理论课程和实践经历都是非常重要的. 通过读书听课可以找到自己的位置,还有知识本身所处的位置以及你在整个知识地图的位置,从而不至于迷失在日新月异的环境中,慢慢地你会发现自己感兴趣的那些目的地,然后逐步地探索这些有趣的目的地,最终能够取得令自己满意的成就. 而实现模型的重要性在于你可以将那些抽象的概念和理论转化为实实在在可以触及的经验,你飞动的指尖会慢慢告诉你什么是正确的节奏,哪些是让你兴奋的点. 通常理论和实践之间的差异之大会超乎想象,所以只能够通过实际应用去填补这些罅隙,实现完模型后往往需要成天成天的调试你才能达到满意的效果. 这个过程是非常痛苦的,但这种痛苦也是短暂的:当你最终完成了一个真正可用的模型时,那种快感无与伦比. 我想这也是很多人坚持挑战自己的缘故吧. Ilya Suskever 说道:“But each time you suffer, know that you’ve built a little bit of skill that will be invaluable for the future.”

后记

两周前答应刘昕博士,匆匆写完这篇,越到 deadline 越是能发现自己的漏洞,为了填补这些常常查资料到深夜,不过这个过程还是非常享受,乐在其中. 从深度学习基本的 MLP、SGD 的理解和掌握,到 RNN LSTM 及 NTM 和 MM 等网络的理解,再到慢慢地发现生成式模型的魅力所在,随之与变分推断的结合,然后后来的强化学习重新进入我的视野,这个过程跌宕起伏,也让我对这个庞大领域的脉络逐渐清晰. 可以说深度学习重新激活了我对机器学习的热情. 而且随着理解的深入,你会发现深度强化学习会将各个领域有趣的问题放在同样的一个框架内进行思考和处理,这是以前只有博弈论和复杂网络能够带来给我的体验. 相较于单纯掌握某个领域的知识和技术,我倾向于从更广的层面来理解它们,然后吸收进入自己的知识体系.

这个过程中,我们需要的一方面是接受新的技术,同时也要辨别清楚那些重要的东西,那么最好的方式就是去研习它们,观察它们,使用它们,这样才有最真切的体会,也能够告诉自己需要的究竟是什么.

我们给某个事物取了名字,一方面界定清楚了它,但另一方面也限制住了它. 实际上,并不需要太多严苛地将注意力限制在一个有“名”的物上,而是应该去感知它所能够触及的领域和问题,通过用之来增加认知. 对于技术或者理论均是如此,敢于突破前人列下的规则,才是我们创新的动力之源.

现在这个开放的时代,让技术的进步可以方便地获取,只要你有热情和兴趣,就能够找到释放的地方. 尽管有着诸多鸿沟拦在人类的面前,但是勇敢者必定能够迈出坚定的步伐去探知未来的奥秘!既然如此,大家尽情发挥吧~

记住,跟随你的好奇心,它会指引你找到属于自己的路!

I am a pessimist because of intelligence, but an optimist because of will.”


相关资料

OpenAI 的深度学习教程

强化学习研究决策制定和控制,以及一个进行决策的 agent 如何学会在一个未知环境中采取最优行动。深度强化学习研究如何在强化学习算法中使用神经网络,使得无需进行人工特征工程直接学习从原始感知数据到原始行动输出的映射变得可能。

本文讲解深度强化学习技术。受众是那些已经有了一定的机器学习基础,如监督学习、神经网络和强化学习基础的读者。

本教程和已有的强化学习教程的比对

已有的强化学习(RL)课本没有给出足够的关于如何使用函数近似的指导;基本上都是聚焦在离散状态空间的领域。而且,现有 RL 课本并没有对无导数优化和策略梯度方法给出充分讲述,而这些技术在很多的任务上都是相当重要的。

我对强化学习没有任何经验。我可以从何处开始学习?

现在有几个大学课程给出了免费的视频教程:

或者,你可能想要从课本学习:

我是否有理解这个教程的基础?

我们假设读者有下面的预备知识:

  • 如何训练神经网络进行回归和分类
  • 熟悉基本的 MDP、值迭代和策略迭代

目录:

1 预备知识、符号和术语

强化学习包含一个 agent 和一个环境:每个时间步,agent 会选择一个行动,然后环境会返回给 agent 一个收益然后转换到下一个状态。在标准设置中,agent 和环境的交互被划分成一系列 回合(episode) 的序列。在每个回合,初始状态 $s_0$ 从分布 $\mu(s_o)$ 中采样出来。每个时间步,agent 随机或者确定地选择出一个行动;我们记此作 $a_t \sim \pi(a_t|s_t)$ 表示行动是根据概率分布 $\pi$ 采样出来的。下一个状态和收益根据转换概率分布 $R(s_{t+1}, r_t | s_t, a_t)$。这个过程持续进行直到 终止 状态达到,此时该回合结束。其过程可以写成下面的形式:

$s_0 \sim \mu(s_0)$

$a_0 \sim \pi(a_0|s_0)$

$s_1, r_0 \sim P(s_1, r_0 | s_0, a_0)$

$a_1 \sim \pi(a_1 | s_1)$

$s_2, r_1 \sim P(s_2, r_1 | s_1, a_1)$

$a_{T-1}, r_{T-1}\sim \pi(a_{T-1} | s_{T-1})$

$s_T, r_{T-1} \sim P(s_T|s_{T-1},a_{T-1})$ ($s_T$ 是一个终止状态)

上面的定义是在 全-可观察设定下的,这种情形下的 agent 能够获得系统的全部状态。在 部分-可观察设定下,agent 只能在每个时间步获得一个观察(y),这个观察可能是一个状态的噪声和不完全的信息。agent 可以将许多前期时间步信息进行组合,所以行动 $a_t$ 依赖于前期历史 $(y_0, a_0,y_1, a_1,\dots,y_{t-1}, a_{t-1},y_t)$;我们将历史记作 $h_t$。

$s_0, y_0 \sim \mu(s_0)$ (初始状态和观察)

$a_0 \sim \pi(a_0|h_0)$

$s_1, y_1, r_0 \sim P(s_1, y_1, r_0 | s_0, a_0)$

$a_1 \sim \pi(a_1 | h_1)$

$s_2, y_2, r_1 \sim P(s_2, y_2, r_1 | s_1, a_1)$

$a_{T-1} \sim \pi(a_{T-1} | h_{T-1})$

$s_T, y_T, r_{T-1} \sim P(s_T, y_T, r_{T-1}|s_{T-1},a_{T-1})$ ($s_T$ 是一个终止状态)

如果我们称历史 $h_t$ 为系统的状态,那么这个部分-可观察设定等价于 全-可观察设定。因此,能够应用在 全-可观察设定下的 RL 算法同样能应用在 部分-可观察设定中,而无需做任何大的变动——所以,对算法的讨论就可以假设在全-可观察设定下。参考[BertsekasVol1] 对部分-可观察 MDP 如何规约到 MDP 的更加形式化的讨论。

在实际应用中,不适用整个原始的行动和观察的历史数据,agent 使用一个循环神经网络(RNN)将观察历史编码为一个定长向量 $h_t$,你可以将这个向量看成是 agent 的“短期记忆(short-term memory)”。

为了更加方便的表述问题,我们给出下面的包含将会使用到的符号的表格。

s 状态
a 行动
r 收益
y 观察
$\tau$ 轨迹
$\pi$ 策略
$\theta$ 策略参数
R 总收益
$\hat{A}$ 平均估计
V 状态-值函数
P 转换概率

2 黑盒优化和交叉熵方法

很多强化学习问题可以被描述为下面的优化问题:

$\mathrm{maximize}_{\theta} E[R|\theta]$,其中 $R$ 是一个回合的总收益,行动是根据策略 $\pi(a_t|s_t;\theta)$ 选择出来的。

(注意到我们可以仅仅使用一个确定的策略 $a_t = \pi(s_t, \theta)$;但是上面的随机形式是可以推广使用的。)

最简单的方式就是把整个问题看做一个关于策略参数 $\theta$ 的“黑盒”优化问题。也就是说,我们有一个参数向量 $\theta$ 包含所有 agent 的参数,我们可以得到目标函数 $E[R|\theta]$ 的带噪声的评价(evaluation)。我们称此为 黑盒 优化问题因为我们并不假设任何关于目标计算的知识,或者这是一个连续函数;我们仅仅通过在不同的输入 $\theta_1, \theta_2,\dots$ 进行查询来学习这个函数。黑盒优化可以用下面一般的形式描述:

$\max_\theta E_\zeta[f(\theta,\zeta)]$

其中我们通过重复提供参数 $\theta_i$ 来获得关于函数 $f$ 的信息;然后采样出未观察噪声随机变量 $\zeta_i$,获得值 $f(\theta_i, \zeta_i)$。(如果是在计算机模拟中计算 $f$,$\zeta$ 可以对应于随机数生成器。)

在 RL 设定中,因为 $\theta$ 是维度很高,黑盒方法(或者无导数优化算法)通常比其他 RL 算法(探索问题结构型的)低效。但是,在实际应用中,在小的问题上常常表现得很好,也是最为容易实现的算法。

交叉熵方法(CEM)是简单的黑盒优化算法。CEM 通过重复更新在候选参数向量 $\theta$ 上的高斯分布的均值和方差进行。

最简单的算法描述如下:

Algorithm 1: 交叉熵方法 CEM

初始化 $\mu\in \mathbb{R}^d$,$\sigma\in \mathbb{R}^d$
迭代 $= 1,2,\dots$
采样 $n$ 样本 $\theta_i\sim N(\mu, diag(\sigma))$
对每个样本执行噪声的评价 $f(\theta_i, \zeta_i)$
选择前 $p\%$ 样本 (e.g. $p=20$),称为“精英集合(elite set)”
用精英集合拟合一个高斯分布,使用对角协方差,得到新的 $\mu,\sigma$
返回最终的 $\mu$
更多细节和实践中的提升可以在[SzitaLorincz06]中找到。在 RL 设定中,我们通过对一个或者更多的回合执行策略参数化评价 $f(\theta_i, \zeta_i)$ ,并计算总收益。

2.1 练习

(实践 ) 实现交叉熵方法,将其应用在CartPole 环境中。
(实践
) 将其应用在 Swimmer 环境中,这是一个连续行动空间的情形。尝试人工增加方差和逐步降低噪声为 0,如[SzitaLorincz06]
(理论 *) CEM 的一个弱点是精英集合中的元素可能已经碰巧选中,如幸运地成为 $\zeta$ 的样本。 实际上,这会让 $\theta$ 在 $f$ 中产生高方差。所以,CEM 不会收敛到一个 $\eta(\theta) = E_{\zeta}[f(\theta, \zeta)]$ 的局部最大值点。
解释为何 CEM 不能收敛到 $\eta(\theta)$ 的局部最大值点
证明如果 $f$ 是确定性的(即,如果不依赖于噪声 $\zeta$),那么 CEM 不会收敛到一个局部最大值点
在随机情形下,什么目标函数让 CEM 收敛到一个局部最优值点?
你能不能设计出一个算法通过在多个不同的 $ \theta$ 处评价同样的噪声样本 $\zeta$ 在多个不同的 $ \theta$ 处解决这个问题?
更多的信息参见[GoschinWeinsteinLittman13]

2.2 笔记

你可能会想为何 CEM 叫这个名字。该名称最早来自积分估计的一种方法,你可以参考[Owen14]的第 10 章。

3 策略梯度

策略梯度算法通过梯度下降进行优化。就是说,通过重复计算策略的期望回报梯度的噪声估计,然后按照梯度方向来更新策略。该方法比其他 RL 方法(如 Q-学习)更有利主要是我们可以直接优化感兴趣的量——策略的期望总收益。该类方法由于梯度估计的高方差长期被认为不太实用,直到最近,[SchulmanEtAl15]和 [MnihEtAl16]等工作展示了神经网络策略在困难的控制问题上的采用策略梯度方法的成功应用。

3.1 直觉解释

你可能比较熟悉概率模型的监督学习,其中目标是最大化给定输入(x) 时的输出 (y) 的对数概率。

$\max_{\theta} \sum_{n=1}^{N}\log p(y_n|x_n;\theta)$

策略梯度方法通常需要假设一个随机策略,该策略给出了对每个状态 (s) 的行动 (a) 上的概率分布;我们将此分布写作 $\pi(a|s;\theta)$。

如果我们知道对每个状态正确的行动 $a^*$,我们可以简单地最大化监督学习的目标函数:

$\max_{\theta} \sum_{n=1}^{N}\log p(a^*_n|s_n;\theta)$

然而,我们并不知道正确的行动。相反,我们会尝试对行动好坏进行粗略的猜测,试着去增加好的行动的概率。更加具体地讲,假设我们刚收集完 agent 和环境一个 agent 和环境回合的交互,所以我们有了一个状态、行动和收益的序列:$\tau = (s_0, a_0, r_0,s_1, a_1, r_1,\dots,s_{T-1}, a_{T-1}, r_{T-1},s_T)$。令 $R$ 表示收益的和:$R=\sum_{t=0}^{T-1} r_t$。最简单的策略梯度公式就是:

$\hat{g} = R\nabla_\theta \log(\prod_{t=0}^{T-1}\pi(a_t|s_t;\theta)) = R\nabla_\theta \sum_{t=1}^{T} \log \pi(a_t|s_t;\theta)$

使用这个梯度的估计 $\hat{g}$,我们可以用一个梯度上升的步骤,$\theta\leftarrow \theta+\alpha \hat{g}$ 进行策略的更新,其中 $\alpha$ 为学习率。我们会收集所有的回合,对那个回合中所有的行动的对数概率按照回合的总收益 $R$ 为比例进行增加。换言之,如果我们收集了大量的回合数据,其中一些是好的(凭借运气),另外一些是差的。我们本质上是在进行监督学习——最大化好的回合的概率。

尽管我们现在还没有给出对上述策略梯度公式的数学上的验证,但实际上已经给出了一个对策略梯度的无偏估计。

$E[\hat{g}]=\nabla_\theta E[R]$

策略梯度定义为右式的策略期望总收益的梯度。

如果我们用充足的样本(充足的回合),那么就可以任意精度计算出策略梯度。然而,估计量 $\hat{g}$ 通常噪声很大,即有很高的方差。你可以想象,这里存在很大的提升空间。与其提高好的轨迹(trajectory)的概率,我们应该提高好的行动的概率,也就是说,我们应试着去推断哪些行动影响轨迹的好坏。

有一系列形如下式的策略梯度估计量:

$\hat{g} = \nabla_\theta \sum_{t=1}^{T} \hat{A_t}\log \pi(a_t|s_t;\theta)$

其中 $\hat{A_t}$ 是行动 $a_t$ 的有利度 (advantage)的估计——比平均值好还是坏的程度。

下面的有利度估计量更有效率,也更常见:

$\hat{A}_t=r_t + \gamma r_{t+1}+\gamma^2 r_{t+2} + \dots - V(s_t)$

其中 $\gamma$ 是折扣因子,$V(s_t)$ 是 状态-值 函数 $E[r_t+\gamma r_{t+1} + \gamma^2 r_{r+2}|s_t]$ 的近似。$\gamma$ 用来定义一个有效时间区域,其中你忽略所有可能的超过未来 $1/(1-\gamma)$ 的时间步的影响。关于有效度和时间区域更加详细的解释参见[SchulmanEtAl15]。

3.2 更加形式化的解释

推导策略梯度公式的最简单的方式是使用打分函数梯度估计量,这是估计期望梯度的通用方法。我们接着将此想法用在计算期望收益的梯度上。假设 $x$ 是一个随机变量,其概率密度是 $p(x|\theta)$,即概率密度依赖于参数向量 $\theta$。$f$ 是一个标量值函数(就是收益),我们想要计算 $\nabla_\theta E_x[f(x)]$。我们得到了下面的等式:

$\nabla_\theta E_x[f(x)] = E_x[\nabla_\theta \log p(x|\theta) f(x)]$

这个方程是可以根据将期望转写成积分形式获得的:

$\nabla_{\theta} E_{x}[f(x)] = \nabla_{\theta} \int \mathrm{d}x\ p(x | \theta) f(x) = \int \mathrm{d}x \nabla_\theta p(x|\theta) f(x) =\int \mathrm{d}x\ p(x|\theta) \nabla_\theta \log p(x|\theta) f(x)= E_x[\nabla_\theta \log p(x|\theta) f(x)]$

使用这个估计量,我们就可以采样 $x \sim p(x|\theta)$,然后计算方程的左式(对 $N$ 个样本进行平均)来获得梯度的估计(在 $N \rightarrow \inf$ 时准确度更高)。就是说,我们采样 $x_1, x_2, \dots, x_N \sim p(x|\theta)$,然后使用下面的梯度估计 $\hat{g}$

$\hat{g} = \frac{1}{N} \sum_{n=1}^{N} \nabla_\theta \log p(x_i|\theta)f(x_i)$

为了在强化学习中使用这个思想,我们需要用到随机策略。这意味着在每个状态 $s$,我们的策略给出了一个行动上的概率分布,记作 $\pi(a|s)$。因为策略同样有一个参数向量 $\theta$,我们就常写成 $\pi(a|s, \theta)$。

在后续讨论中,轨迹 $\tau$ 代表状态和行动的序列,即 $\tau \equiv (s_0, a_0, s_1, \dots, s_T)$。令 $p(\tau | \theta)$ 表示在策略参数 $\tau$ 下整个轨迹 $\tau$ 的概率,令 $R(\tau)$ 为整个轨迹的总收益。

然后打分函数估计量给出了

$\nabla_\theta E_{\tau} [R(\tau)] = E_{\tau} [\nabla_\theta \log p(\tau|\theta)R(\tau)$

我们只需要采样轨迹 $\tau$,然后使用上面的公式计算策略梯度估计量。现在,我们需要显式地写出 $\log p(\tau|\theta)$ 来推导出一个实用的公式。使用概率的链式法则,我们得到

$p(\tau|\theta) = \mu(s_0)\pi(a_0|s_0,\theta)P(s_1|s_0, a_0)\pi(a_1|s_1,\theta)P(s_2|s_1, a_1)\dots\pi(a_{T-1}|s_{T-1},\theta)P(s_T|s_{T-1}, a_{T-1})$

这里 $\mu$ 是初始状态分布。我们对其取对数后,就得到一个和式,关于 $\theta$ 求导,$P(s_t|s_{t-1}, a_{t-1})$ 和 $\mu$ 一样就被消去了。我们得到

$\nabla_\theta E_{\tau}[R(\tau)] = E_{\tau}[\sum_{t=0}^{T-1} \nabla_\theta \log \pi(a_t|s_t,\theta) R(\tau)]$

这个公式非常厉害,因为我们可以不许知道系统动态知识(由转换概率 $P$ 确定的)来计算策略梯度。直觉解释是我们收集了一个轨迹,然后与其总收益的好的程度(goodness)成比例提升概率。即,如果收益 $R(\tau)$ 非常高,我们应该按照在参数空间中提高 $\log p(\tau|\theta)$ 方向进行移动。

因此,通过一些数学推理,我们推导出一个更好(更低方差)的策略梯度估计。令 $r_t$ 表示在时间步 $t$ 的收益,令 $b(s_t)$ 表示基准函数,该基准函数计算出状态-值函数的某个近似,即 $b(s) \approx V^{\pi}(s) = E_{\tau} [\sum_{u=t}^{T}r_u|s_t = s]$(从状态 $s$ 开始,未来收益的期望和)。改进的策略梯度公式如下:

$\nabla_\theta E_{\tau}[R(\tau)] = E_\tau [\sum_{t=0}^{T-1} \nabla_\theta \log \pi(a_t|s_t,\theta) (\sum_{u=t}^{T}r_u - b(s_t))]$

如果轨迹非常长,那么上述公式会有较大的方差。因此人们通常使用一个折扣因子,这样可以引入偏差来降低方差。这时,策略梯度有偏估计公式就是

$\nabla_\theta E_{\tau}[R(\tau)] \approx E_\tau [\sum_{t=0}^{T-1} \nabla_\theta \log \pi(a_t|s_t,\theta) (\sum_{u=t}^{T}\gamma^{u-t} r_u - b(s_t))]$

其中 $b(s_t)$ 就是对收益折扣和的近似 $b(s) \approx E_{\tau} [\sum_{u=t}^{T}\gamma^{u-t} r_u|s_t = s]$。

3.3 实现注意事项

有一种方便的方法计算策略梯度,就是对许多时间步使用你喜欢的自动微分软件进行批量操作。定义 $L(\theta) = \sum_{t=0}^{T-1} \log \pi(a_t|s_t, \theta) \dot A_t$,其中 $A = (\sum_{u=t}^{T} r_u-b(s_t))$。这里 $A$ 表示有效度,因为它度量了回报超过期望值多少。这仅仅是不含梯度的上面策略梯度公式。你可以在程序中定义损失函数 $L$ 。然后关于其参数进行微分,你就能得到策略梯度了!注意,不用花费长时间的总和,我们就能对 $\log \pi(a_t|s_t,\theta)$ 进行向量化计算(该向量长度为 $T$ )然后与一个同样长度为 $ T$ 的有效度的向量进行内积。

3.4 参数化策略

我们已经抽象式描述策略为 $\pi(a|s,\theta)$。我们如何使用一个神经网络进行表示?我们仅仅需要将 $s$ 映射到某个向量 $\mu$ 上,向量描述了行动 $a$ 上的分布。例如,

如果 $a$ 来自一个离散的集合,那么我们设计一个神经网络将 $s$ 到一个概率向量上。(我们一般在神经网络的最后层使用一个 softmax 激活函数)这完全就是我们用来进行分类器学习的形式。
如果 $a$ 是连续的,那么我们可以将 $s$ 映射到一个高斯分布的均值和方差上。一般情况我们使用一个不依赖于 $s$ 的对角协方差。
如果 $a$ 是二值的,那么我们可以使用一个单个输出的网络,表示输出 1 的概率。

3.5 练习

实现一个策略梯度算法将其应用在 CartPole 环境中。比较下面的变体:
$\hat{A_t} = R$
$\hat{A_t} = r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \cdots -V(s_t)$,包含(不包含)折扣因子和基准(共有 4 中情形)
将其应用在 Swimmer 环境中
改变问题 1 和 2 的实现,使用不同的 SGD 变体,包含 momentum、RMSProp 和 Adam

4 自然策略梯度和信任区间方法

5 Q-学习

到现在为止,我们讨论的都是策略优化的技术,不管是黑盒优化还是基于梯度的方法。另外一种不同的方法是估计一个衡量所有可能的行动好坏的函数,使用这个函数来定义策略。回想一下最优的状态-值函数 $V^*(s)$ 衡量了在最优策略下状态的好坏,最优状态-行动值函数 $Q^*(s,a)$ 给出了在状态 $s$ 执行行动 $a$ 时的好坏的衡量。

$V^*(s)= E[r_0 +\gamma r_1 + \gamma^2 r_2 + \dots |s_0 = s, \pi^*]$

$Q^*(s,a)= E[r_0 +\gamma r_1 + \gamma^2 r_2 + \dots |s_0 = s, a_0 = a, \pi^*]$

(稍微解释一下上面的表述,在 $V^*$ 中,我们以开始状态 $s$ 为 $s_0$,依照 $\pi^$ 选择出的连续的变量 $a_0, r_0, s_1, a_1, r_1, \dots$ 序列,在这个序列上取期望。)$Q^$ 更加适合我们对系统的动态模型没有知识的设定,这个原因后面会解释清楚。

本节会讨论学习 Q-函数的算法。最优 Q-函数($Q^*$)满足下面的 Bellman 方程

$Q^*(s,a) = E_{s’}[r(s,a,s’) + \gamma V^*(s)] = E_{s’}[r(s,a,s’) + \gamma \max_{a’} Q^*(s,a’)]$

我们可以使用下面的值迭代(value iteration)算法迭代更新 Q-函数,收敛到 $Q^*$。

Algorithm 2: Q-值迭代

初始化 $Q^{(0)}$
对 $n = 1,2,\dots$
对 $(s,a)\in S\times A$ (所有状态行动对)
$Q^{(n)}(s,a) =E_{s’}[r(s,a,s’) + \gamma \max_{a’} Q^{(n-1)}(s,a’)]$ ()
最优 Q-函数(即,最优策略的 Q-函数)是更新 (
) 式的不动点,更严格点说,这是一个收缩(contraction),其误差指数级下降 $||Q^{(0)}-Q^*|| \propto \gamma^n$。

最优 Q-函数可用来引出一个形式——back-up 操作符 T,将 Q-函数映射到一个更新版本 TQ 上,定义如下:

$[TQ](s,a) = E_{s’}[r(s,a,s’) + \gamma \max_{a’} Q(s,a’)]$

这个被定义为 backup 操作符因为它使用向前看一步(对 $s’$ 求期望)更新了 Q-值——也就是说,它让信息按照时间回流。使用backup 操作符,Q-值迭代对 $(s,a)$ 的循环可以简洁地写作 $Q^{(n)} = TQ^{(n-1)}$。

如果我们知道准确的转换模型和系统的收益函数,我们就可以仅计算准确的关于 $s’$ 的期望。为了准确计算目标值,我们需要对 $s’$ 求期望,就必须能够获取转换模型和收益函数的信息。但是,给定一个状态、行动、收益和下一状态 $(s_t, a_t, r_t, s_{t+1}’)$ 的转换,我们可以构造出一个 $[TQ](s_t,a_t)$ 的无偏估计。然后我们可以给 $Q(s,a)$ 噪声估计了目标值 $[TQ](s,a) = E_{s’} [r(s,a,s’) + \gamma \max_{a’} Q^{(n-1)}(s’, a’)]$。我们称这个噪声估计为 $\hat{TQ}$,定义如下

$\hat{TQ}_t = r_t + \gamma \max_{a’} Q(s_{t+1},a’)$

因为这是无偏估计,

$E_{s_{t+1}} [\hat{TQ}_t|s_t,a_t] = TQ(s_t,a_t)$

注意 $\hat{TQ}$ 不依赖于我们在状态 $s_{t+1}$ 时采取的行动,因此,这个无偏性不依赖于我们执行的策略,所以我们有很多的自由来考虑使用什么策略来收集数据。使用这些估计量,我们可以设计出下面的算法,收集批量的数据然后使用值迭代更新 Q-函数。由于不管采取何种策略都能够获得一个无偏估计,很多模型未知的情况下,基于 Q-函数的算法比之基于 V-函数的算法常常更受青睐。(如果模型已知,我们可以存储 V-函数来定义 Q-函数。)

Algorithm 3: 基于模拟的 Q-值迭代

初始化 $Q^{(0)}$
对 $n = 1,2,\dots$
和环境交互 T 个时间步,通过从某种策略 $\pi^{(n-1)}$ 中选择行动获得轨迹 $(s_0, a_0, s_1, a_1,\dots,s_T)$ (如果是一个按照回合进行的任务,可能会包含多个回合)
$Q^{(n)} = \mathrm{minimize}_{Q} \sum_{t=1}^{T} ||Q(s_t,a_t) - \hat{TQ}||^2$,其中 $\hat{TQ}$ 使用当前 Q-函数 $Q^{(n-1)}$ 算出
在第 n 次迭代时该选择什么策略 $\pi^{(n-1)}$?由于 $\hat{TQ}$ 的无偏性,任何能够充分访问状态-值对的策略都能够给出所有目标 Q-值 $[TQ](s,a)$ 一致的估计,就是说,若用无穷多的数据就能够给出正确的 $[TQ](s,a)$。典型方法是使用 $\epsilon$-贪婪策略,按照概率 $\epsilon$ 随机行动,按照概率 $1-\epsilon$ 使用 $\mathrm{arg max}_{a} Q(s,a)$。随机行动概率 $\epsilon$ 通常从 $1$ 缓慢退火为 $0$。

算法 3 是一种批式算法:批式强化学习算法在收集数据和使用这个数据执行参数更新两步交替进行。这和在线算法有所不同,在线算法在数据收集的同时增量更新。我们能不能将 $n=1$ 设计一个在线算法?可以,但是我们需要作出小的调整来限制在每个迭代对 Q 更新的大小(现在只有一个时间步)。通常,我们通过混合有噪声的估计和当前值计算目标 Q-值,混合比例 $\alpha\in(0,1)$。

$\hat{TQ}_t = (1-\alpha)Q(s_t, a_t) + \alpha(r_t + \gamma \max_{a’} Q(s_{t+1},a’))$

$Q(s_t,a_t) \leftarrow \hat{TQ}_t$

这个算法称为 Watkins Q-学习算法[WatkinsDayan92]。给定合适的将 $\alpha$ 下降到 0 的设计,并给定能够访问所有状态-行动对无穷多次的策略(如使用 $\epsilon$-贪婪策略),这个算法能够保证收敛到最优策略。[JaaJorSingh94] 给出了一个简洁的分析。然而在现实应用中,这个算法需要相当大的时间步数。

前面我们讨论了 Q-函数 $Q(s,a)$。如果状态空间和行动空间是离散的(有限集合),那么最为直接的方式是使用一个 Q 函数表,将 Q-函数作为一个数组存放,每个 $(s,a)$ 对都有一个位置。而如果状态空间巨大或者是无穷的,这显然是不太现实的选择,所以我们需要找一个函数的近似方法,如神经网络,来表示 Q-函数。

我们记 $Q_\theta$ 为由参数向量 $\theta$ 参数化的 Q-函数。存在至少两个合理的方法来参数化 Q-函数:

网络以 $(s,a)$ 为输入,以标量 Q-值为输出。
网络将 $s$ 映射到某个参数向量 $\mu$,这个可以和行动组合来获得标量 Q-值。
实际情形下,第二种方式工作得更好,也得到了更加有效的算法。类比于我们前面对参数化策略的讨论,我们可以定义依赖于行动空间的 Q-函数的不同的参数化方式。

如果 $a$ 来自一个离散集合,那么我们设计一个神经网络将 $s$ 映射到一个 Q-值的向量
如果 $a$ 是连续的,那么我们可以使用一个神经网络将 $s$ 映射到一个二次函数的中心,其curvature,产生 Q-值 $Q(s,a) = ||(a-\mathrm{center}) \odot \mathrm{curvature}||^2$。参见[GuEtAl16]。
给定该参数化 Q-函数,我们可以运行 Q-值迭代算法,优化的步骤变成:

$\theta^{(n)} = \mathrm{minimize}_\theta \sum_t ||Q_\theta(s_t, a_t) - \hat{TQ}_t||^2$

这个算法被称为 神经网络拟合 Q-迭代(Neural-Fitted Q-Iteration) [Riedmiller05]。

最近,Mnih 等人提出了这个算法的变体版本,将数据采集纳入 Q-函数更新[MnihEtAl13]。他们使用了一个 目标网络,类似于前面的 Q-函数 $Q^{(n-1)}$。他们还使用了一个 回放缓冲区 (replay buffer),包含最近一些 Q-函数收集到的数据,而在算法 3 中,只是使用了 $Q^{(n-1)}$ 采集的数据来拟合 $Q^{(n)}$。

5.1 练习

实现 Watkins Q-学习算法,应用在 toy_text gym 环境中。你还可以使用策略迭代来计算最优解,比较一下性能。(注意这些环境给出了方便的转换模型和收益函数)
应用批式 Q-值迭代算法或者 DQN 在 classic_control 环境中。
应用批式 Q-值迭代算法或者 DQN 在 mujoco 环境中,使用一个二次的 Q-函数。

6 引用

[BertsekasVol1] Bertsekas, Dynamic Programming and Optimal Control, Volume I.
[SzitaLorincz06] (1, 2) Szita and Lorincz, Learning Tetris with the Noisy Cross-Entropy Method.
[SchulmanEtAl15] (1, 2) Schulman, Moritz, Levine, Jordan, Abbeel, High-Dimensional Continuous Control Using Generalized Advantage Estimation. http://arxiv.org/abs/1506.02438
[MnihEtAl13] Mnih et al., Playing Atari with Deep Reinforcement Learning. http://arxiv.org/abs/1312.5602
[MnihEtAl16] Mnih et al., Asynchronous Methods for Deep Reinforcement Learning.http://arxiv.org/abs/1602.01783
[Owen14] Owen, Monte Carlo theory, methods and examples. http://statweb.stanford.edu/~owen/mc
[GoschinWeinsteinLittman13] Goschin, Weinstein, Littman, The Cross-Entropy Method Optimizes for Quantileshttp://jmlr.org/proceedings/papers/v28/goschin13.pdf
[GuEtAl16] Gu et al., Continuous Deep Q-Learning with Model-based Accelerationhttp://arxiv.org/abs/1603.00748
[Riedmiller05] Riedmiller. Neural fitted Q iteration—first experiences with a data efficient neural reinforcement learning method.
[JaaJorSingh94] Jaakkola, Jordan, and Singh. On the convergence of stochastic iterative dynamic programming algorithms.
[WatkinsDayan92] Watkins, Dayan. Q-learning.
[KakadeLangford02] Kakade & Langford, Approximately optimal approximate reinforcement learning
[Kakade01] Kakade, Sham. A Natural Policy Gradient

Nac

Abstract. This paper investigates a novel model-free reinforcement
learning architecture, the Natural Actor-Critic. The actor updates are
based on stochastic policy gradients employing Amari’s natural gradient
approach, while the critic obtains both the natural policy gradient and
additional parameters of a value function simultaneously by linear regression.
We show that actor improvements with natural policy gradients are
particularly appealing as these are independent of coordinate frame of
the chosen policy representation, and can be estimated more efficiently
than regular policy gradients. The critic makes use of a special basis
function parameterization motivated by the policy-gradient compatible
function approximation. We show that several well-known reinforcement
learning methods such as the original Actor-Critic and Bradtke’s Linear
Quadratic Q-Learning are in fact Natural Actor-Critic algorithms. Empirical
evaluations illustrate the effectiveness of our techniques in comparison
to previous methods, and also demonstrate their applicability for
learning control on an anthropomorphic robot arm.

Natural Actor-Critic

RLDM 强化学习教程-David Silver

我们能够将深度学习应用在强化学习中。使用深度神经网络来端对端表示值函数/策略/模型,然后借助随机梯度下降进行参数更新。

深度值函数

Bellman 方程

Bellman 期望方程将值函数 $Q^{\pi}$ 展开:
$Q^\pi(s,a) = \mathbb{E}~[r_{t+1} + \gamma r_{t+1} + \gamma^2r_{t+1} + \dots | s,a] =\mathbb{E}_{s’,a’}[r + \gamma Q^\pi(s’,a’) | s, a]$

Bellman 最优方程将最优值函数 $Q^*$ 展开:

$Q^*(s,a) = \mathbb{E}_{s’} [r + \gamma \max_{a’} Q^*(s’,a’) | s, a]$

策略迭代算法求解了 Bellman 期望方程
$Q_{i+1}(s,a) = \mathbb{E}_{s’} [r + \gamma Q_i(s’, a’) | s,a]$

值迭代算法求解了 Bellman 最优方程
$Q_{i+1} (s, a) = \mathbb{E}_{s’,a’} [r + \gamma \max_{a’} Q_i(s’,a’)|s,a]$

非线性 Sarsa 策略迭代

使用参数为 w 的 Q-network 来表示值函数
$Q(s, a, w) \approx Q^\pi(s,a)$

通过 Q-值的均方误差来定义目标函数
$\mathcal{L}(w) = \mathbb{E} [(r + \gamma Q(s’,a’,w) - Q(s,a,w))^2]$

我们就有了下面的 Sarsa 梯度
$\frac{\partial \mathcal{L}(w)}{\partial w} = \mathbb{E}[(r + \gamma Q(s’,a’,w) - Q(s,a,w)) \frac{\partial Q(s,a,w)}{\partial w}]$

借助 SGD 使用 $\frac{\partial \mathcal{L}(w)}{\partial w}$ 端对端优化目标函数

深度强化学习的稳定性问题

基本的 Q-学习采用神经网络会出现振荡或者发散的情况

数据是序列化的
相邻的样本是相关的,非独立同分布的
Q-值微小变化会导致策略迅速变化
策略可能会振荡
数据的分布会从一个极端摇摆到另一个极端
奖励和 Q-值的范围未知
基本的 Q-学习梯度会在反响传播时变得很大从而不能稳定

深度 Q-网络(DQN)

DQN 为深度基于值的强化学习问题提供了一种稳定解决方案

使用经验回放
将数据之间的关联打破,重回独立同分布的设定下
从过去的策略中学习
使用 免策略 Q-学习
冻结 目标 Q-网络
避免振荡
将 Q-网络和目标网络之间的关联打破
截断奖励或者正规化网络,适应到合适的范围内
可以得到健壮的梯度

稳定的深度强化学习(1):经验回放

为了打破关联,我们从 agent 自己的经验中构建数据集

根据 $\epsilon$-贪婪策略采取行动 $a_t$
将转换 $(s_t, a_t, r_{t+1}, s_{t+1})$ 存放在记忆 $\mathcal{D}$ 中
从 $\mathcal{D}$ 中随机采样一个小批量样本 $(s,a,r,a’)$
优化 Q-网络和 Q-学习目标之间的均方误差 MSE,如
$\mathcal{L}(w) = \mathbb{E}_{s,a,r,s’ \sim \mathcal{D}} [(r + \gamma \max_{a’}Q(s’,a’,w) - Q(s,a,w))^2]$

稳定的深度强化学习(2):固定目标 Q-网络

为了避免振荡,固定在 Q-学习目标网络的参数

根据旧的,固定的参数 $w^-$ 计算 Q-学习目标函数
$r + \gamma \max_{a’} Q(s’,a’,w^-)$

优化 Q-网络和 Q-学习目标之间的均方误差 MSE
$\mathcal{L}(w) = \mathbb{E}_{s,a,r,s’\sim \mathcal{D}} [(r + \gamma \max_{a’}Q(s’,a’,w^-)-Q(s,a,w))^2]$

周期化地更新固定参数 $w^- \leftarrow w$

稳定的深度强化学习(3):奖励/值范围

DQN 截断奖励在 $[-1,+1]$ 之间
让 Q-值不会过大
确保梯度完好(well-conditioned)
不能够区分奖励的大小
更好的方式:正规化网络输出
比如,通过 batch 正规化

连续行动上的策略梯度

使用一个权重为 $u$ 的深度神经网络 $a = \pi(s,u)$ 来表示策略
定义目标函数为总折扣奖励
$J(u) = \mathbb{E} [r_1 + \gamma r_2 + \gamma^2 r_3 + \dots]$

使用 SGD 来端对端优化目标函数
即,调整策略参数 $u$ 来达到更大的奖励

确定型策略梯度

策略的梯度由下式给出

$\frac{\partial J(u)}{\partial u} = \mathbb{E}_s [\frac{\partial Q^\pi(s,a)}{\partial u}] = \mathbb{E}_s [\frac{\partial Q^\pi(s,a)}{\partial a} \frac{\partial \pi(s,u)}{\partial u}]$

策略梯度是最大化提升 $Q$ 的方向

确定型 Actor-Critic

使用两个网络

Actor 是参数为 $u$ 的策略 $\pi(s, u)$
$s \xrightarrow[u_1]{}\dots\xrightarrow[u_n]{} a$

Critic 是参数为 $w$ 的值函数 $Q(s, a, w)$
$s,a \xrightarrow[w_1]{}\dots\xrightarrow[w_n]{} Q$

Critic 为 Actor 提供损失函数
$s \xrightarrow[u_1]{}\dots\xrightarrow[u_n]{} a\xrightarrow[w_1]{}\dots\xrightarrow[w_n]{} Q$

梯度从 Critic 到 Actor 反向传播
$\frac{\partial a}{\partial u} \xleftarrow[]{}\dots\xleftarrow[]{} \frac{\partial Q}{\partial a} \xleftarrow[]{} \dots\xleftarrow[]{} $

确定型 Actor-Critic:学习规则

Critic 通过 Q-学习估计当前策略的值
$\frac{\partial \mathcal{L}(w)}{\partial w} = \mathbb{E} [(r + \gamma Q(s’,\pi(s’),w)-Q(s,a,w)) \frac{\partial Q(s,a,w)}{\partial w}]$

Actor 按照提升 Q 的方向更新策略
$\frac{\partial J(u)}{\partial u} = \mathbb{E}_s [\frac{\partial Q(s,a,w)}{\partial a} \frac{\partial \pi(s,u)}{\partial u}]$

确定型深度策略梯度(DDPG)

基本的 actor-critic 使用神经网络会振荡或者发散
DDPG 给出了稳定解
对 actor 和 critic 均使用经验回放
冻结目标网络来避免振荡
$\frac{\partial \mathcal{L}(w)}{\partial w} = \mathbb{E}_{s,a,r,s’\sim \mathcal{D}} [(r + \gamma Q(s’,\pi(s’,u^-),w^-)-Q(s,a,w)) \frac{\partial Q(s,a,w)}{\partial w}]$

$\frac{\partial J(u)}{\partial u} = \mathbb{E}_{s,a,r,s’\sim \mathcal{D}}[\frac{\partial Q(s,a,w)}{\partial a} \frac{\partial \pi(s,u)}{\partial u}]$

用于连续行动控制的 DDPG

从原始像素 $s$ 端对端学习控制策略
输入状态 $s$ 是前 4 帧的图像的原始像素的栈
对 $Q$ 和 $\pi$ 两个不同的卷积网络
在 MuJoCo 中进行模拟

基于模型的强化学习

学习环境的转移模型:$p(r,s’|s,a)$

使用转换模型来进行规划

使用转移模型来查找最优行动

深度模型

使用深度神经网络来表示转移模型 $p(r,s’|s,a)$
定义目标函数来评价模型的好坏
如,重新创建下一状态的比特数(Gregor et al.)
通过 SGD 来优化目标函数

基于模型的强化学习的挑战

综合误差

转换模型的误差会整个轨迹上复合
长轨迹的结尾,奖励就完全错了
基于模型的强化学习在 Atari 游戏上无效(到目前为止)
值/策略的深度神经网络可以隐式地“规划”

网络的每层执行任意的计算步骤
n-层网络可以向前看 n 步
转换模型是否需要?

围棋中的深度学习

Monte-Carlo 搜索

MCTS 模拟未来轨迹
构建巨大的拥有百万位置的向前搜索树
目前最佳 19X19 程序使用的是 MCTS
例如,第一个强大的围棋程序 MoGo (Gelly et al.)

卷积网络

12 层的卷积网络可以训练来预测专家走法
简单的卷积网络(只看一个位置,没有搜索)
等价于有 $10^5$ 位置的搜索树的 MoGo (Maddison et al.)

结论

强化学习为人工智能提供了一个通用途径的框架
强化学习问题可以用端对端深度学习解决
单个 agent 现在可以解决很多挑战性问题
强化学习 + 深度学习 = 人工智能

问题?

“The only stupid question is the one you never asked.” - Richard Sutton

不完全信息博弈中自我对弈的深度强化学习技术

近期阅读 UCL Johannes Heinrich 和 David Silver 关于博弈的均衡求解论文,我发现他们给出的方法实际上是一种比较强大且通用的技术,有必要深入研究一下。对这篇文章的解读,不得不提的是他们和在 2015 年的前篇。在那里对基础内容似乎讲解的更加详细。然而,由于其工作的交叉领域中各自的术语差异较大,所以在理解论文时会造成一定的麻烦,本文期望从 NSFP 出发完整地分析涉及到的相关领域中的问题,结合算法谈谈如何使用这项新的技术来解决若干领域中的有趣问题。

前期是为了理解所以大部分内容是直接翻译该论文的工作。计划在今后细化讲解,争取把这一套方法完整地展示清楚。

NFSP 就是引入神经网络近似函数的 FSP,是一种利用强化学习技术来从自我博弈中学习近似纳什均衡的方法。解决了三个问题:

  1. 无先验知识 NFSP agent 学习
  2. 运行时不依赖局部搜索
  3. 收敛到自我对局的近似纳什均衡

这是一般的不完美信息二人零和博弈。虚拟对弈同样也会收敛到合作、势力场博弈的纳什均衡。所以 NFSP 也能够成功应用在这些博弈上。另外,近期的研究关于连续空间行动的强化学习(Lillicrap et al. 2015)也能够应用在连续行动博弈中,目前的博弈论方法并不能直接处理这样的情形。

然而我们需要知道了解相关的基础,才能够真切地了解这篇文章给我们带来了什么启发。本文在对原文理解基础上进行翻译,后续会继续增加向前的回溯和向后的扩展。

强化学习

首先是强化学习基础。强化学习中的 agent 需要学会通过和环境交互中最大化自己的期望未来回报。一般来说,环境会被建模为一个 MDP。

很多强化学习算法从序列化经验中学习。这些经验的形如 $(s_t, a_t, r_{t+1},s_{t+1})$,其中的 $s_t$ 是在时间 $t$ 的状态,$a_t$ 是在那个状态下选择的行动,$r_{t+1}$ 是之后的回报,$s_{t+1}$ 是转移的下一个状态。常见的目标函数是学习 行动-值函数,$Q(s,a) = \mathbb{E}^{\pi}[G_{t} | S_{t} =s, A_{t} = a]$,定义为在状态 $s$ 采取行动 $a$ 并采取策略 $\pi$ 的期望收益。
同策略(on-policy)学习是指 agent 学习当前采用的策略。异策略(off-policy)学习则是 agent 从另一个 agent 或者另一个策略(如之前的策略)的经验中学习。

Q-learning 是一种异策略学习方法。其学习的是贪婪策略——在每个状态下,都会选择有最高的估计值的行动。通过应用异策略强化学习方法在 respective 转移元组来存储和回放过去的经验的方法称为经验回放。Fitted Q Iteration (FQI)是一种采用经验回放的 Q-learning 的批量强化学习方法。Neural Fitted Q Iteration(NFQ)和 Deep Q Network(DQN)则分别是在批量和在线更新的 FQI 两种扩展。

展开式博弈

这是一类包含多个参与人的序列化交互的模型。参与人的目标是最大化自身的收益(payoff)。在不完美信息博弈中,每个参与人只会观察到自身的信息状态(information state),例如,在扑克游戏中,玩家只会知道自己私有的牌,并不知道其他人的。每个参与人会选择行为策略(behaviourial strategy)将信息状态映射到可选的行动的概率分布上。我们假设博弈是有完美回忆(perfect recall)的,每个参与人当前信息状态 $s_{t}^i$ 暗含了他自己的导致达到当前状态的信息状态和行动序列,$s_{1}^{i},a_{1}^{i},s_{2}^{i},a_{2}^{i},\dots,s_{t}^{i}$。realisation-probability,$x_{\pi^i}(s_{t}^i) = \prod_{k=1}^{t-1} \pi^i(s_{k}^{i}, a_{k}^{i})$,给出了参与人 $i$ 行为策略 $\pi^i$ 对实现他信息状态的 $s_{t}^i$ 的概率。策略组合(strategy profile)$\pi = (\pi^1,…,\pi^n)$ 是对所有参与人策略的集合。$\pi^{-i}$ 则是除去 $\pi^i$ 之外的 $\pi$ 中的策略。给定一个固定的策略组合 $\pi^{-i}$,参与人 $i$ 在这个设置下任何达到最优的收益都是一个最优反应(best response)。近似反应或者 $\epsilon$-最优反应是不超过 $\epsilon$ 的亚最优。纳什均衡是一个策略组合,其中每个参与人的策略都是对其他策略的最优策略。而近似纳什均衡或者 $\epsilon$-纳什均衡就是 $\epsilon$-最优反应的策略组合。由于在纳什均衡中没有参与人可以通过策略的偏移来提升自己的收益。所以,纳什均衡可以被当成理性自我对局学习的不动点。实际上,纳什均衡是唯一个理性 agent 在自我对局中可以收敛的策略组合。

虚拟自我对局 Fictitious Self Play, FSP

虚拟对局是从自我对局中学习的博弈论模型。自我对局的参与人选择针对其对手的平均行为的最佳反应。自我对局参与人的平均策略在某些类型的博弈(如二人零和博弈和多人势力场博弈)中都会收敛到纳什均衡。Leslie 和 Collins 在 2006 年给出了推广的弱化自我对局。这种模型和通常的自我博弈有着类似的收敛保证,但是允许有近似最优反应和扰动的平均策略更新,也让这个扩展模型对机器学习尤其合适。

自我对局通常使用规范式博弈定义,这与扩展式博弈在有效性上存在指数级差距。Heinrich 等人在 2005 年引入了 Full-Width Extensive Form FSP(XSP),可以让自我对局参与人使用行为式,扩展式进行策略更新,得到了线性的时间和空间复杂性。这里一个关键的洞察是对规范式策略的凸组合,$\hat{\sigma} = \lambda_1 \hat{\pi}_1 + \lambda_2 \hat{\pi}_2$ ,我们可以达到一个实现等价的行为策略 $\sigma$,通过设置该值为成比例于对应的实现概率的凸组合,

$$\sigma(s,a)\propto \lambda_1 x_{\pi_1}(s) \pi_1(s,a) + \lambda_2 x_{\pi_2}(s) \pi_2(s,a)\; \forall s, a, \tag{1}$$

其中 $\lambda_1 x_{\pi_1}(s) + \lambda_2 x_{\pi_2}(s)$ 是在信息状态 $s$ 的策略的规范化常量。除了在行为策略下定义自我对局的 full-width 平均策略更新外,公式 (1) 给出了从这样的策略的凸组合中采样数据集的一种方法。Heinrich 等人在 2015 提出了 Fictitious Self Play (FSP)的基于采样和机器学习的算法来近似 XFP。FSP 分别用强化学习和监督学习来替换最优反应计算和平均策略更新。特别地,FSP agent 产生他们在自我对局中的经验转换的数据集。每个 agent 存放了自身的转移元组 $(s_t, a_t, r_{t+1},s_{t+1})$ 在记忆 $\mathcal{M}_{RL}$ 中 ,这个为强化学习设计。而 agent 自身的行为 $(s_t, a_t)$ 被存放在另一个分开的记忆 $\mathcal{M}_{SL}$ 中,这为监督学习设计。自我对局的采样通过 agent 的强化学习的记忆来近似用其他参与人的平均策略组合定义的 MDP 的数据。因此,通过强化学习的 MDP 的近似解会产生一个近似的最优反应。类似地,agent 的监督学习记忆近似了 agent 本身的平均策略,这可以通过监督式的分类方法学习。

神经网络虚拟自我对局

进行了多种扩展:神经网络函数近似,reservoir 采样,anticipatory 动态性和完全基于 agent 方法。NFSP agent 和博弈中的其他参与人进行交互,并记住自身关于博弈状态转移的经验和自身的行为。NFSP 将这些记忆分成两个数据集——一个给深度强化学习,一个给监督学习使用。特别地,这个 agent 从 $\mathcal{M}_{RL}$ 的数据中使用异策略强化学习训练一个神经网络 $F_{Q}$ 来预测行为值,$Q(s,a)$。得到的网络定义了 agent 的近似最优策略 $\beta = \epsilon\mbox{-}\mathrm{greedy}(F_Q)$,这里根据概率 $\epsilon$ 选择随机行动,根据概率 $1- \epsilon$ 选最大化预测行为值的行动。NFSP agent 训练了另外一个神经网络,$F_{S}$ 在 $\mathcal{M}_{SL}$ 的数据中使用监督学习来模拟自己过去的行为。这个网络将状态映射到了行动概率上,定义了 agent 的平均策略,$\pi = F_{S}$。在博弈进行过程中,agent 从两个策略 $\beta$ 和 $\pi$ 的混合中选择策略。

尽管虚拟参与人通常是针对对手的平均策略进行最优反应,但在连续时间的动态虚拟对局参与人是对对手平均规范式策略 $\hat{\pi}_t^{-i} + \eta \frac{d}{d t} \hat{\pi}_t ^{-i}$ 短期预测的最优反应。研究表明,选择合适的,博弈相关的 $\eta$ 可以提高在均衡处的自我对局的稳定性。NFSP 使用 $\hat{\beta}_{t+1}^{i}- \hat{\pi}_t^{i} \approx \frac{d}{d t} \hat{\pi}_t^{i}$ 作为用在 anticipatory 动态中的离散时间导数近似值。注意 $\Delta \hat{\pi}_t^{i} \propto \hat{\beta}_{t+1}^{i} - \hat{\pi}_t ^{i}$ 是常见的离散时间自我对局的规范化更新方向。为了让一个 NFSP agent 计算近似对对手预测平均策略组合 $\sigma^{-i} \equiv \hat{\pi}^{-i} + \eta(\hat{\beta}^{-i} - \hat{\pi}^{-i})$ 的最优反应,$\beta^{i}$,agent 需要迭代求值并最大化其行动值,$Q^i(s,a) \approx \mathbb{E}_{\beta^{i},\sigma^{-i}} [G_t ^{i}|S_t =s, A_t =a]$。这个可以使用异策略强化学习,如 Q-learning 或者 DQN 在和对手的预测策略,$\sigma^{-i}$ 对局的经验上获得。为了确保 agent 的强化学习记忆,$\mathcal{M}_{RL}$ ,包含这种类型的经验,NFSP 需要所有的 agent 从 $\sigma \equiv (1 - \eta)\hat{\pi} + \eta (\hat{\beta})$ 选择他们的行动,其中 $\eta \in \mathbb{R}$ 被称为预测参数(anticipatory parameter)。

虚拟自我对局通常要保留平均规范式博弈的最优反应策略,$\hat{\pi}_T^{i} = \frac{1}{T} \sum_{t=1}^T \beta_t^{i}$。Heinrich 等人在 2015 年给出了使用采样和机器学习技术来产生数据并学习用展开式博弈形式表示的规范式博弈策略凸组合。例如,我们可以通过使用 $\beta_t^{i},\;t = 1,\dots,T$ 按照 $\frac{1}{T}$ 的比例来采样整个博弈的过程来产生展开式数据。NFSP 使用蓄水池采样(reservoir sampling)来记忆其平均最优反应的经验。agent 的监督式学习记忆,$\mathcal{M}_{SL}$ 是一个蓄水池仅仅会在采用其近似最优策略 $\beta$ 时增加经验。NFSP agent 通常会训练自己的平均策略网络 $\pi = F_S$ 来匹配其存储在自身监督学习记忆中的平均行为,例如通过优化过去行为的对数概率来进行训练。算法 1 给出了 NFSP,其中使用 DQN 作为强化学习的方法。

算法 1:神经网络虚拟自我对局 NFSP 算法


输入:

  1. $\Gamma$ {博弈}
  2. $\mathcal{M}_{RL}$, $\mathcal{M}_{SL}$ {RL 和 SL 记忆}
  3. $F_{Q}$, $F_{S}$ {行动值网络和策略网络}
  4. $\beta = \epsilon\mbox{-}\mathrm{GREEDY}(\mathcal{M}_{RL})$ {最优反应策略}
  5. $\pi = F_{S}$ {平均策略}
  6. $\sigma$ {当前策略}

输出: $\pi$ 自我对弈中的纳什均衡近似


function $\mathrm{STEP()}$:

  1. $s_{t}, r_{t}, c_{t} \leftarrow \mathrm{OBSERVE}(\gamma)$
  2. $a_t \leftarrow \mathrm{THINK}(s_t, r_t, c_t)$
  3. $\mathrm{ACT}(\Gamma,a_t)$

end function


function $\mathrm{THINK}(s_t, r_t, c_t)$

  1. if $c_t = 0$ {episode terminated} then
    $\sigma \leftarrow \mathrm{SAMPLEPOLICY}(\beta, \pi)$
    end if
  2. if $s_{t-1} \not= \mathrm{nil}$ then
    $\tau_t \leftarrow (s_{t-1} ,a_{t-1},r_t,s_t,c_t)$
    $\mathrm{UPDATERLMEMORY}(\mathcal{M}_{RL} , \tau_t)$
    end if
  3. $a_t \leftarrow \mathrm{SAMPLEACTION}(\sigma)$
  4. if $\sigma = \beta$ then
    $\mathrm{UPDATESLMEMORY}(\mathcal{M}_{SL} , (s_t , a_t))$
    end if
  5. $s_{t−1}\leftarrow s_t$
  6. $a_{t−1} \leftarrow a_t$
  7. $\beta \leftarrow \mathrm{REINFORCEMENTLEARNING(\mathcal{M}_{RL})}$
  8. $\pi \leftarrow \mathrm{SUPERVISEDLEARNING}(\mathcal{M}_{SL})$

end function


function $\mathrm{REINFORCEMENTLEARNINIG}(\mathcal{M}_{RL})$

  1. $F_Q \leftarrow \mathrm{DQN}(\mathcal{M}_{RL})$
  2. return $\epsilon\mbox{-}\mathrm{GREEDY}(F_Q)$

end function


function $\mathrm{SUPERVISEDLEARNING}(\mathcal{M}_{SL})$

  1. $F_S \leftarrow$ 作用随机梯度下降到损失函数上:
    $$\mathbb{E}_{(s,a)\sim \mathcal{M}_{SL}} [−\log\pi(s,a)]$$
  2. return $F_S$

end function


实验

图 1

参考

  1. http://arxiv.org/abs/1603.01121
  2. http://jmlr.org/proceedings/papers/v37/heinrich15.pdf

Tf-Whitepaper

TensorFlow 从名称上看就是两个部分——张量 tensor 和流 flow。非常形象的组合。众所周知,矩阵已经成为机器学习中的基础单元,若干的针对矩阵的计算优化使得现如今的机器学习成为可能。而一些矩阵的方法也是一些重要的机器学习算法的基础。张量 就是矩阵概念的推广,其表示更多维度的矩阵。而计算流是一种抽象过程,在如今的深度学习领域,这种一层层地计算可以很形象地看做是张量在计算模型上的流动。而这里的流可以看做是更加一般的计算过程,可以在不同的层级间跨越式流动。

本文作者均来自 Google Research:Martín Abadi, Ashish Agarwal, Paul Barham, Eugene Brevdo, Zhifeng Chen, Craig Citro, Greg S. Corrado, Andy Davis, Jeffrey Dean, Matthieu Devin, Sanjay Ghemawat, Ian Goodfellow, Andrew Harp, Geoffrey Irving, Michael Isard, Yangqing Jia, Rafal Jozefowicz, Lukasz Kaiser, Manjunath Kudlur, Josh Levenberg, Dan Mane, Rajat Monga, Sherry Moore, Derek Murray, Chris Olah, Mike Schuster, Jonathon Shlens, Benoit Steiner, Ilya Sutskever, Kunal Talwar, Paul Tucker, Vincent Vanhoucke, Vijay Vasudevan, Fernanda Viegas, Oriol Vinyals, Pete Warden, Martin Wattenberg, Martin Wicke, Yuan Yu, and Xiaoqiang Zheng

摘要

TensorFlow [1] 是一个表达机器学习算法的接口,并且是执行算法的实现框架。使用 TensorFlow 表示的计算可以在众多异构的系统上方便地移植,从移动设别如手机或者平板电脑到成千的GPU计算集群上都可以执行。该系统灵活,可以被用来表示很多的算法包括,深度神经网络的训练和推断算法,也已经被用作科研和应用机器学习系统在若干的计算机科学领域或者其他领域中,例如语言识别、计算机视觉、机器人、信息检索、自然语言理解、地理信息抽取和计算药物发现。该论文描述了 TensorFlow 的接口和我们在 Google 构建的结构实现。TensorFlow API 和参考实现都已经作为开源项目按照 Apache 2.0 协议在 2015 年 11 月释出,可以在 这里 查看。

1 引言

Google 大脑项目开始于 2011 年,目的是探索在科研和 Google 的产品中超大规模深度神经网络的使用。作为这个项目的早期工作,我们构建了 DistBelief ——第一代的可扩展分布式训练和推断系统 [14],这个系统工作得很不错。我们和其他 Google 的同事使用 DistBelief 进行了广泛的研究包括非监督学习[31]、语言表示[35,52]、图像分类模型和目标检测[16,48]、视频分类[27]、语音识别[56,21,20]、序列预测[47]、Go 的移动选择[34]、行人检测[2]、强化学习[38] 等等。另外,和 Google Brain 团队合作中,超过 50 个 Google 内部的团队和其他 Alphabet 公司也已经部署了使用 DistBelief 的深度神经网络在众多产品中,包括 Google Search[11]、广告产品、语音识别系统[50,6,46]、Google Photos[43]、Google Maps 和 街景[19]、Google 翻译[18]、Youtube 和很多其他的产品。

基于我们使用 DistBelief 的经验和对于期望用来训练和使用神经网络的系统特性和需求更加完备地理解,我们构建了 TensorFlow——第二代大规模机器学习模型的实现和部署的系统。TensorFlow 使用通过类似数据流模型的计算,将这些计算映射到不同的硬件平台例如使用包含一个或者多个 GPU 显卡的装有 Android 和 iOS 的单个机器上进行推断,到运行在数百台包含数千个 GPU 的大规模系统训练推断。拥有一个单一的系统可以扩展分布到众多的平台上可以大大简化真实场景中机器学习系统的使用,正如我们在用分离的系统进行大规模训练和小规模的部署,会产生巨大的维护代价和较差的抽象效果。TensorFlow 的计算被表示为含状态的数据流图(在第二节详细讲解),我们聚焦在让这个系统足够灵活能够快速地实验研究中产生的新模型,并同时充分地提升产品级训练的性能和部署机器学习模型健壮性。为扩展神经网络训练搞更大的部署环境,TensorFlow 允许 client 简单地表达不同类型的并行通过复制和并行执行一个核心模型数据流图,依赖不同计算设备合作更新一个共享的参数或者其他的状态。 对计算描述的微妙变动可以使用较低的代价来达到和尝试很多不同的并行的方法。一些 TensorFlow 的用途借助参数更新的一致性来实现灵活性,我们可以在一些更大的部署环境中轻易表达和利用这些同步上的松弛。对比 DistBelief,TensorFlow 的编程模型更加灵活,性能也更好,支持在大规模的异构硬件平台上训练和使用很多的模型。

DistBelief 的内部用户已经切换成 TensorFlow 了。这些客户依赖 TensorFlow 来研究和产品,执行诸如在移动电话计算机视觉模型的推断到使用数百台机器进行千亿级样本的千亿级参数的深度神经网络的训练[11,47,48,18,53,41]。尽管这些应用集中在机器学习和深度神经网络上,我们希望 TensorFlow 的抽象可以用在其他的领域中,例如其他的机器学习算法或者可能其他类型的数值计算。我们按照 Apache 2.0 协议在 2015 年 11 月开源了 TensorFlow API,可以在 www.tensorflow.org 查看。

本文下面的部分更加细致地描述了 TensorFlow。第二节介绍编程模型和 TensorFlow 接口的基本概念,第三节介绍单机和分布式的实现 。第四节给出了基本编程模型的扩展,第五节介绍了一些基本实现的优化方法。第六节给出了一些使用 TensorFlow 的实验结果,第七节描述了一些使用 TensorFlow 编程的 idiom,第九节则是一些在 TensorFlow 核心外围的工具。第十节和第十一节分别讨论了未来和相关的工作,最后一节给出了总结性想法。

2 编程模型和基本概念

TensorFlow 的计算由一个有向图描述,这个图中由一个节点集合组成。该图表达了数据流计算,作出了一些类型的节点保持和更新持久状态和让分支及循环控制结构类似于 Naiad 的行为方式的扩展。客户一般都会使用 TensorFlow 支持的前端语言(C++或者Python)构建一个计算图。在图 1 中展示了一段样例使用 Python 构建并执行了一个 TensorFlow 的计算图,结构计算图在图 2 中展示。

图 1

图 2

在一幅 TensorFlow 图中,每个节点(node)有一个或者多个输入和零个或者多个输出,表示一种操作(operation)的实例化。流过图中正常的边(输出到输入)的值都是张量(tensor),任意维度的数组其中基础元素类型是指定的或者在图的构造过程中自动推断出来的。特别的边,我们称之为控制依赖(control dependencies),同样也存在在图中:这类边上没有数据流过,但是他们表示源节点必须在目标节点的控制依赖开始执行前完成运行。由于我们的模型包括可变状态,控制依赖可以被直接用来确保 happens-before 关系。我们的实现同样会插入控制依赖来确保独立操作之间的顺序,比如说作为控制内存使用最高峰值的方式。

In computer science, the happened-before relation (denoted: ) is a relation between the result of two events, such that if one event should happen before another event, the result must reflect that, even if those events are in reality executed out of order (usually to optimize program flow). This involves ordering events based on the potential causal relationship of pairs of events in a concurrent system, especially asynchronous distributed systems. It was formulated by Leslie Lamport.[1]
In Java specifically, a happens-before relationship is a guarantee that memory written to by statement A is visible to statement B, that is, that statement A completes its write before statement B starts its read.[1]

操作和核(kernel)

一个操作有一个名字。它表示一个抽象的计算(比如说,“矩阵相乘”或者“相加”)。一个操作可以有属性(attribute),所有的属性必须提供或者在图构造的过程中推断出以实例化一个节点来执行操作。属性通常的使用方式是让操作在不同的张量元素类型上多态(例如,两个 float 类型的张量和两个 int32 类型的张量)。(kernel)是一种操作的特别实现,可以运行在一个特定类型的设备上(如 CPU 或者 GPU)。TensorFlow 的 binary 定义了可以通过注册(registration)机制实现的操作和核的集合上,这个集合可以通过连接额外的操作/核的定义/注册。表 1 展示了内置于 TensorFlow 核心库的一些操作类型。

表 1:TensorFlow 的操作类型

会话(session)

客户端通过创建会话(session)和 TensorFlow 系统进行交互。为了创建一个计算图,会话接口支持外部(external)方法来提升当前由包含额外节点和边的会话的图(当会话创建时初始的图是空的)。另一个由会话接口提供的主要的操作就是 Run,以需要计算的输出名称和替换某些输出节点的张量的操作集合作为其参数输入。通过控制 Run 的参数,TensorFlow 的实现可以计算所有节点的必须执行传递闭包来计算需要的输出,然后安排执行合适节点来保证他们的依赖关系(在3.1小节详细讲解)。大多数 TensorFlow 的使用都是针对一个图启动一个会话,然后执行整个图或者通过 Run 调用来执行分离的子图数千或者数百万次。

变量(variable)

在大多数计算中,图都是执行多次的。大多数的张量在一次执行后不会存活。然而,变量(variable)是一种特别的操作可以返回一个在图执行若干次过程中存活的持久化的可变张量的句柄。这个句柄可以传递给一系列特定的操作,例如 Assign 和 AssignAdd(等同于 +=)就可以改变其引用的张量了。对应 TensorFlow 在机器学习中的应用,模型的参数典型地就存放在变量引用的张量中,并作为模型训练图的 Run 的一部分进行更新。

3 实现

TensorFlow 系统的主要部分就是客户端,它使用了会话接口来和 master 及一个或者多个的 worker processes 进行通信,每个 worker process 负责对一个或者多个计算设备(CPU 核或者 GPU card)的任意访问和在这些设备上进行图节点的计算按照 master 的要求执行。我们有本地和分布式实现的 TensorFlow 接口。本地实现通常是客户端、master 和 worker 都是在同一台机器上在一个单一的操作系统进程(可能包括多个设备,比如说装了多个 GPU card的设备)上运行。分布式实现采用了本地实现的很多的代码,但是扩展了对客户端、master 和 worker 可以在不同的机器的不同的进程上运行的场景支持。在我们的分布式环境中,这些不同的任务对应于 cluster 调度系统分配在 job 中的容器中[51]。这两种不同的模式在图 3 中进行的展示。本节剩下的部分讨论了在两种实现中遇到的问题,3.3 节讨论了针对分布式实现的一些问题。

设备

设备是 TensorFlow 的计算核心。每个 worker 负责一个或者多个设备,每个设备有一个设备类型和一个名字。设备名字由识别设备类型的部分,在 worker 中的设备索引,以及在分布式设定中,worker 的 job和任务(或者 localhost 当设备是和进程在同一机器时)的标志构成。一些例子如/job:localhost/device:cpu:0 或者 /job:worker/task:17/device:gpu:3。我们已实现了 CPU 和 GPU 的设备接口而其他的设备类型也有了通过注册机制完成的设备实现方式。每个设备对象负责管理分配和解除分配设备内存,对在 TensorFlow 实现中的更高层请求任意 kernel 的执行调度管理。

张量

实现中的张量是一种有类型的、多维度数组。我们支持若干张量元素类型,包含大小为从 8 bit 到 64 bit 的带符号和无符号整型,IEEE 浮点数和双精度类型、复数类型和字符串类型(任意长的字节数组)。合适大小的后台存储通过一个分配器进行管理,该分配器由张量所处的设备确定。张量的后端存储缓存是引用计数的并在没有引用存在时解除分配。

3.1 单设备执行

首先考虑最简单的执行场景:单一的worker进程运行在单一的设备上。图上的节点按照代表节点之间的顺序执行。特别地,我们会在每个节点上保持一个计数来记录这个节点上还没有执行的依赖。一旦这个计数变为 0,节点就可以被调度使用,并会加入到待续的队列中。待续队列按照某个非指定的顺序处理,指派节点执行的kernel 到设备对象上。当一个节点完成执行,所有依赖这个完成的节点的节点的计数都会增加。

3.2 多设备执行

一旦系统有了多个设备,有两个主要的复杂情形出现:确定图中每个节点的计算所处的设备,然后管理由上一步确定的置放决定产生的设备间的所需的数据通信。后续部分讨论这两个问题。

3.2.1 节点的置放

给定计算图,TensorFlow 实现的主要责任之一就是将计算映射到可用的设备集合上。这个算法的简单版本下面给出。参见第 4.3 节有关该算法支持的扩展。

该置放算法的输入是一个代价模型,包括对每个图节点的输入和输出张亮的规模的估计,和对每个节点在给于其输入张量时的计算时间的。这个代价模型或者是基于关联不同操作类型的启发式规则的静态估计,或者基于实际的为更早的图的执行而做的置放决定集合衡量。

置放算法首先运行模拟的图的执行过程。模拟按照下面描述进行,对每个节点使用贪心策略选择一个设备。节点到设备的置放过程也是用作真实执行的置放。

置放算法从计算图的源点开始,在系统中的每个设备上模拟相应的活动。对每个在遍历中抵达的节点,可选 available 设备的集合会被考虑到(设备可能会由于其没能提供实现了特定操作的kernel而不可选)。对那些拥有多个可选设备的节点,置放算法使用一种贪心策略来检查在每个可能谁被上置放节点需要完成的时间的效果完成决策。这种启发式规则考虑了根据代价模型在那种设备上估计的和衡量的执行时间,还有任何用来从其他设备传输输入到该节点的通信的代价。其中节点的操作完成最快的设备会被选作该操作的设备,置放决策然后会继续针对图中其他的节点进行处理,包含那些已经做好模拟执行的下游节点。第 4.3 节描述了一些扩展,让用户可以提供提示和部分限制来指导置放算法。这个算法现在还在持续开发的过程中。

3.2.2 交叉设备通信

一旦节点置放已经计算好,图就被划分成子图的集合,每个子图对应于一个设备。从 xy 任何交叉设备的边都会被移除并用一条从 x 到一个 x 的子图中新的 Send 节点的边和从在 y 子图中对应的 Receive 节点到 y 的边代替。参见图 4 中所进行的变换。

图 4

在运行时刻,Send 和 Receive 节点合作进行跨设备的数据交换。这使得我们可以隔离所有在 Send 和 Receive 内部实现的通信,这样简化了运行时刻剩下的部分工作。
当我们插入 Send 和 Receive 节点时,我们将在特定设备上的特定张量的所有使用者进行合并规整来使用单个 Receive 节点,而不是对特定设备上的每个下游使用者都给一个 Receive 节点。这确保了需要使用的张量数据仅仅会从源设备到目的设备传输一次,而在目的设备上的张量内存也只会分配一次(而非多次,参看图 4 的节点 bc)。

通过这种方式处理通信,我们也允许了不同设备上的图中的个别节点调度可以被去中心化到 workers 上:Send 和 Receive 节点传达了在不同的 worker 和 设备间必要的同步信息,master 仅仅需要对每个图的执行给出一个 Run 请求给那些包含图中任意节点的 worker,而不是会对所有节点或者每个跨设备通信都进行调度。这也让系统更加可扩展,并允许比通过 master 来强制进行所有的调度更加精确的节点执行。

3.3 分布式执行

计算图的分布式执行非常类似于多设备执行。在设备置放后,子图会针对每个设备创建。用于 worker 进程之间的通信的 Send/Receive 节点对使用了诸如 TCP 或者 RDMA 这样的远程通信机制进行跨机器的数据迁移。

容错

分布式执行中的错误可以在很多地方进行检测。最主要的有 (a) 在 Send 和 Receive 节点对之间的通信错误,(b) 从 master 进程到每个 worker 进程的周期性的健康状态检测。

如果发现了错误,整个图的执行就会终止,并从头开始。但是回想之前变量节点对应于那些在执行过程中记忆持有(persist)的张量。我们支持在重启过程中的一致的检查点和状态恢复。特别是,每个变量节点连接在一个 Save 节点上。这些 Save 节点周期性地执行,比如说每 N 次迭代,或者每隔 N 秒。他们执行的时候,变量的内容被写到持久化的存储中,比如说,一个分布式的文件系统。类似地,每个变量连接在一个 Restore 节点上,只会在一次重启后的第一个迭代中启用。在 4.2 节有某些节点仅能够在某些图的执行中启用的细节。

4 扩展

本节我们描述在第 2 节给出的编程模型中几个更加高级的特性。

4.1 梯度计算

很多优化算法,包括常用的机器学习训练算法,如随机梯度下降 [45],计算代价函数关于一个输入集合的梯度。由于该算法广泛的应用需求,TensorFlow 已经内置了对自动梯度计算的支持。如果张量 C 通过一个复杂的子图操作依赖于张量 {X_k} 集合,那么就有一个内置的函数可以返回张量 {dC/dX_k}。梯度张量如同其他张量一样通过扩展 TensorFlow 图使用下面的流程进行计算的。
图 5

当 TensorFlow 需要计算一个张量 C 关于某个张量 I 时,首先找出计算图中从 IC 的路径。然后从 C 回溯到 I,而对在回溯路径中的每个操作都会添加一个节点到 TensorFlow 的图上,包含回溯路径上使用链式法则的偏导数。新加的节点计算前向路径中相对应的操作的梯度函数。梯度函数可以是任何的操作。这个函数不但可以用在反向路径中计算出的偏导数作为输入,同样也能选择性地用前向操作的输入输出作为输入。图 5 展示了图 2 中例子的代价函数的梯度。Grey arrows show potential inputs to gradient functions that are not used for the particular operations shown. 图 1 所对应的是计算这些梯度:

1
[db, dW, dx] = tf.gradients(C, [b, W, x])

通常操作可能会有多个输出,C 可能仅仅会依赖于其中一部分。例如,如果操作 O 有两个输出 y_1y_2C 仅仅依赖于 y_2,那么 O 的梯度函数的第一个输入就可以设置为 0 因为 dC/dy_1 = 0

自动梯度计算让优化尤其是内存耗用变得复杂。在执行前向计算子图时,那些显式地由用户创建的操作,可能的启发式想法就是通过观察图被构建的次序来确定哪个节点执行下一步。

这通常指的是临时输出会在创建后不久就是用到,所以他们的内存可以很快重新用到。当这个启发式想法不适用时,用户可能会改变图构建的次序,或者增加在第 5 节将会介绍的控制依赖。当梯度节点自动加入到图中时,用户控制就会变弱,启发式想法就失效了。特别地,因为梯度逆转了前向计算的顺序,在图早期用到的张量会在梯度计算的结尾时重新被频繁用到。这样的张量会消耗很多的 GPU 内存,也就不必要地限制了计算的规模。我们正积极地提升内存关联的效果以更好地处理这个问题。是用更加精密的启发式想法来确定图执行的次序,重计算张量而不是存储在内存,将长效的张量从 GPU 内存中移到 CPU 内存中等等都是可以尝试的思路。

4.2 部分执行

常常有 client 希望执行整个图的子图。为了支持这一点,只要 client 在 Session 中构建出一个计算图,我们 Run 的方法运行他们执行整个计算图的任意的子图,并将任意的数据注入到图中的任何边上,以及获取流经任何边上的数据。

图中每个节点都有一个名字,一个节点的每个输出都通过源节点名和节点输出端口确定,从 0 开始计数(例如,“bar:0” 表示 “bar” 节点的第一个输出,而 “bar:1” 则是第二个输出)。

Run 调用的两个参数可以帮助定义准确的将要执行的子图。第一,Run 调用接受输入,一个可选的映射 name:port 名来填充张量值。第二,Run 调用接受 output_names,输出 name[:port] 列表指定了需要执行的节点,并且,如果端口出现在名字中,那么对那个节点的特定输出张量值就应该返回给 client 如果 Run 调用成功完成。

Paste_Image.png
计算图是基于输入输出的值进行变换的。每个在输入中指定的 node:port 使用 feed 节点替换,这个会选出从特定初始化的用来给 Run 调用的 Rensezvous 对象的入口选择出给定的输入向量。类似地,每个输出名字关联在一个特定的 fetch 节点上,可供输出张量的存储,并在 Run 调用完成时返回给客户端。最后,一旦图已经被这些特定的 feefetch 节点重写,将要执行的节点集合可以被从每个被输出命名的节点出发,然后使用图的依赖关系来确定必须在重写图中执行产生输出的整个节点的集合中进行反向传播。图 6 展示了左边的原始图,以及变换的图,其中 Run 被激活输入是 {b} 输出是 {f:0}。因为我们仅仅需要计算节点 f 的输出,我们不需要执行节点 de,因为他们没有对 f 做出贡献。

4.3 设备限制

TensorFlow 客户端可以通过为一个节点哪些设备可以在其上执行来提供部分的限制来控制节点在设备中的放置。例如,“仅仅放置这个节点在类型为 GPU 的设备上” 或者 “这个节点可以被放置在任何在 /job:worker/task:17 中的设备上”,或者 “共享这个节点和 variable13 节点”。按照这些限制,放置算法就可以负责选择节点的分配来提供快速执行,并且满足不同的设备本身的限制,例如内存的总量的限制来执行子图的计算。

支持这样的限制需要对 3.2.1 节介绍的放置算法进行调整。我们首先计算每个节点的可行设备集合,然后使用 union-find 算法来计算图中必须放在一起的图的组成部分。对每个这样的组成部分,我们计算可行设备集合的交集。计算出的每个节点可行设备和放置算法的模拟器很容易匹配。

4.4 控制流

尽管没有任何显式的控制流数据流图非常强大,但是我们发现了一些例子中支持条件和循环可以得到更加简洁而高效的机器学习算法的表示。

在 Arvind [3] 中描述的数据流机器观点,我们引入了一个小控制流操作的集合进入 TensorFlow 并且推广 TensorFlow 使之能够处理循环的数据流图。SwitchMerge 操作符可以让我们基于布尔值的张量来跳过整个子图的执行。Enter Leave NextIteration 操作符可以进行迭代。高级程序构造如 if-conditional 和 while-loop 可以很容易用这些控制流操作编译成数据流图。

TensorFlow 运行时刻实现了一个 tags 和 frames 概念,这与 MIT Tagged Token Machine 类似。每次迭代都使用了唯一一个 tag,这个执行的状态通过 frame 表示的。只要被使用,输入就可以进入一次迭代;因此,多次迭代可以被并发地执行。

TensorFlow 使用分布式协同机制来使用控制流进行图的执行。一般来说,循环可以包含被分配到多个不同的设备上的节点。因此,管理循环的状态成为了一个分布式终止检测的问题。TensorFlow 的解决方案基于图的重写。在图的划分(partitioning)过程中,我们自动地增加控制节点到每个划分(partition)上。这些节点实现了一个小的状态机,来管理每次迭代的开始和终止,确定整个循环的终止。

如上所示,我们通常通过随机梯度下降来训练机器学习模型,将梯度计算表示成数据流图的一部分。在模型包含控制流操作时,我们必须在对应的梯度计算中处理这些操作。例如,使用 if-conditional 来对模型梯度计算时,需要知道哪个分值会被选择,然后应用梯度逻辑到这个分支上。类似地,使用 while-loop 来对模型梯度计算时,需要知道多少次迭代,同样还依赖在这些迭代中出现的中间值。基本技术就是重写这些图来记住需要计算梯度计算的值。我们这里省略掉细节介绍。

4.5 输入操作

尽管输入数据可以被通过 feed 节点提供给计算,另一个用来训练大规模机器学习模型通常的机制是在图中采用特定的输入操作节点,这些节点一般来说会通过文件名配置,并产生一个包含一个或者多个样本的张量来自在每次执行时的那些文件集合中存放的数据。这使得数据可以被直接从底层存储系统读出到将要执行接下来处理的内存中。在配置中,从 worker 进程分隔开的客户端进程,如果数据给定,一般会需要一个额外的网络 hop(从存储系统到客户端然后从客户端到 worker vs. 使用一个输入节点时直接从存储系统到 worker)。

4.6 队列

队列是一个加入到 TensorFlow 中的有用的特性。他们允许图的不同部分来异步地执行,可能按照不同的节奏,来通过 Enqueue 和 Dequeue 操作来处理数据。在队列中空间尚存时,可以进行 Enqueue 操作;在指定的最小数量的元素可以取出时,可以进行 Dequeue 操作。队列的一个用途就是允许输入数据可以从磁盘文件中预先取出,这样可以同时进行前一批的数据的处理。同样还能用来进行其他类型的归类,包括聚合很多梯度来计算某种更加复杂的梯度组合,或者来组织不同的输入语句到递归语言模型到语句的近似同样长度的 bins 中,这样处理得更有效率。

在一般的 FIFO 队列上,我们还实现了一个 shuffling 队列,可以对内存内的缓冲区内的元素进行随机洗牌。洗牌功能在机器学习算法中比较有用,常常需要对样本进行随机化。

4.7 容器

容器 是用来管理长期存在的可变状态的机制。变量 Variable 反向存放在一个容器内。默认的容器是直到进程终止时都是存活的,但是我们也允许其他的容器。容器可以通过清除它的整个内容进行重置。使用容器,就可以分享状态在完全不相交的不同会话中的计算图中。

5 优化

5.1 通常子表达式消除

5.2 控制数据通信和内存分配

5.3 异步 kernel

5.4 用于 kernel 实现的优化库

5.5 有损压缩

6 状态和经验

7 常用编程规范

8 性能

9 工具

9.1 TensorBoard: 图结构和总结统计可视化

9.2 性能追踪

10 未来工作

11 相关工作

12 结论

参考文献


Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2017 Universality All Rights Reserved.

UV : | PV :