一文看懂JeffDean等提出的ENAS到底好在哪?

做者|第四范式先知平台架构师 陈迪豪
编辑|Natalie
本文经做者受权发布于 AI 前线,未经许可不得转载!
AI 前线导读:ENAS 全称为 Efficient Neural Architecture Search,出自谷歌 Jeff Dean 等人在 2018 年发表的论文《Efficient Neural Architecture Search via Parameter Sharing》,能够在一天内自动训练获得一个比人类设计效果更好的模型。那么这个看上去很神奇的 ENAS 到底有何奇妙之处?它与最近风头正盛的 AutoML 有何关系?

本文将按部就班地介绍业界主流的自动生成神经网络模型的 NAS 算法,以及目前最为落地的 ENAS 算法,带你一探 ENAS 究竟。

更多干货内容请关注微信公众号“AI 前线”,(ID:ai-front)
简介

随着机器学习算法的突破,AutoML 逐渐被业界所熟知并开始落地应用。Google 近期频频发布 AutoML 相关的论文,而且在 Google Cloud 平台推出了 AutoML Vision 服务,此服务容许用户上传少许标记过的图片数据便可从新训练一个专属的图像分类模型。在我微博中大概介绍了这项“AutoML”技术,实际上能够经过 Fine-tune 等方式实现,所以抛出本文第一个观点,AutoML 的定义没有强制标准,只要能自动训练出好的模型就是有价值的 AutoMLnode

ENAS 全称 Efficient Neural Architecture Search,出自 Google 在 2018 年发布的论文《Efficient Neural Architecture Search via Parameter Sharing》(论文连接:https://arxiv.org/pdf/1802.03268.pdf ),经过共享模型参数的形式高效实现神经网络模型结构的探索,也就是说 能够在一天内自动训练获得一个比人类设计效果更好的模型。ENAS 使用了强化学习、动态构建计算图等技术,从宏观角度看是一种搜索算法,产出是一个精心挑选的 NN 模型,所以这是一种很符合指望的 AutoML,除此以外要实现完整的“自动 (Auto) 机器学习 (ML)”还须要有自动特征抽取、自动超参调优等技术支持,但暂时不在本文的讨论范围。git

对于 ENAS 的介绍,你们可能已经看过媒体界吹捧的《谷歌大脑发布神经架构搜索新方法:提速 1000 倍》、《Jeff Dean 等人提出 ENAS:经过参数共享实现高效的神经架构搜索》等文章。这里抛出本文第二个观点,看媒体翻译的技术文章没有用,想学习技术能够看论文原文或者本文。在介绍 ENAS 算法实现细节以前,但愿能够按部就班地介绍一些前置的基础知识理解。github

NAS 的原理

NAS 也就是 Neural Architecture Search,目标是从一堆神经网络组件中,搜索到一个好的神经网络模型。咱们知道神经网络模型是一种可任意堆砌的模型结构,基础的组件包括 FC(全链接层)、Convolution(卷积层)、Polling(池化层)、Activation(激活函数)等,后一个组件能够之前一个组件做为输入,不一样的组件链接方式和超参配置方式在不一样应用场景有不一样的效果,例以下面就是在图像分类场景很是有效的 Inception 模型结构。算法

图内结构比较复杂不理解也不要紧,咱们只须要知道这个神经网络结构是由图像领域专家花费大量精力设计出来的,而且通过了巨量的实验和测试才能(在不能解释深度学习原理的状况下)肯定这个网络结构。编程

那么计算机是否能够本身去学习和生成这个复杂的网络结构呢?目前是不行的,包括各类 NAS 算法的变形还有 ENAS 算法暂时也没法生成这样的网络结构,这里抛出本文第三个观点,绝大部分机器学习都不是人工智能,计算机不会平白无故得到既定目标之外的能力。所以,计算机并非本身学会编程或者建模,咱们尚未设计出自动建模的数据集和算法,所谓的“AI 设计神经网络模型”,其实只是在给定的搜索空间中查找效果最优的模型结构。后端

例如咱们假设模型必须是一个三层的全链接神经网络(一个输入层、一个隐层、一个输出层),隐层能够有不一样的激活函数和节点个数,假设激活函数必须是 relu 或 sigmoid 中的一种,而隐节点数必须是 十、20、30 中的一个,那么咱们称这个网络结构的搜索空间就是{relu, sigmoid} * {10, 20 ,30}。在搜索空间中能够组合出 6 种可能的模型结构,在可枚举的搜索空间内咱们能够分别实现这 6 种可能的模型结构,最终目标是产出效果最优的模型,那么咱们能够分别训练这 6 个模型并以 AUC、正确率等指标来评价模型,而后返回或者叫生成一个最优的神经网络模型结构。数组

所以,NAS 算法是一种给定模型结构搜索空间的搜索算法,固然这个搜索空间不可能只有几个参数组合,在 ENAS 的示例搜索空间大概就有 1.6*10^29 种可选结构,而搜索算法也不可能经过枚举模型结构分别训练来解决,而须要一种更有效的启发式的搜索算法,这种算法就是后面会提到的贝叶斯优化、加强学习、进化算法等。微信

使用超参自动调优

前面提到 NAS 是一种搜索算法,是从超大规模的搜索空间找到一个模型效果很好的模型结构,这类问题咱们也能够看做一个优化问题,也就是从搜索空间中找到另外一个模型效果更优的模型结构。而神经网络模型的结构和效果并非线性关系的,也没有一个函数能够描述这种关系,若是存在这样的函数咱们就能够经过求导、SGD 等方法用数学的方式找到最优解了,所以这能够看做一类黑盒优化(Black-box optimization)问题,或者是多臂老虎机(Multi-armed bandit)问题,对于黑盒优化问题的解法能够参考专栏另外一篇文章《贝叶斯优化: 一种更好的超参数调优方式》(https://zhuanlan.zhihu.com/p/29779000) 。网络

回到 NAS 的场景,咱们须要定义一个搜索空间来让算法选择更优的网络结构,而这个搜索空间无外乎就是网络层个数、网络层的类型、网络层的激活函数类型、网络层是否加 Dropout、网络层是否加 Batch normalization,还有就是诸如卷积层的 filter size、strip、padding 和池化层的 polling type、kernel size 等等,这些咱们均可以认为是神经网络的超参数。架构

若是你使用过我开源的 tensorflow_tempalate_application 应该就理解,为何是 template application?由于咱们能够经过传入的参数 --model={dnn, lr, wide_and_deep, cnn}来选择更好的模型结构,也能够经过参数 --optimizer={sgd, adadelta, adagrad, adam, ftrl, rmsprop}来选择更好的优化算法等等,这里再也不细说,感兴趣能够在 Github 上了解下:

https://github.com/tobegit3hub/tensorflow_template_application

实际上,NAS 能够是一个普通的超参调优问题,也能够是一个针对模型结构场景的调优问题。例如 Google 开源的 NASnet 模型和 ENAS 算法就是在通用的超参调优上更进一步,固然并非说后者的方法更优更先进,而是有些问题是超参很差描述的,例如用超参来表达每一层的输入是前面的哪一层,这里不妨推荐一篇文章介绍基于 Policy gradient 的 NAS 经典实现:

https://lab.wallarm.com/the-first-step-by-step-guide-for-implementing-neural-architecture-search-with-reinforcement-99ade71b3d28

对于能够用超参轻易描述而且实现的模型结构,实现 NAS 并无那么难,咱们不须要本身去实现相似 Policy gradient 的启发式调优算法(后面会详细介绍到),可使用一些已有的超参调优库,只要本身实现机器学习模型的训练过程和返回最终的指标结果便可。

所以我尝试在 Google Vizier 的开源实现 Advisor 上使用 NAS 的功能,发现不到一百行代码就能够实现完整的自动生成网络结构功能,并且不须要服务端作任何修改,咱们用几十行 Keras 代码或者是 TensorFlow 等任意的框架均可以使用,只须要提早描述好超参的搜索空间便可,示例代码我也提交到 Github 上了。

Github 连接:

https://github.com/tobegit3hub/advisor/tree/master/examples/keras

NAS 的优化算法

前面提到 NAS 算法是一种搜索算法,除了须要定义好搜索空间外,还须要有一种启发式的能够收敛的调优算法实现。由于通常生成网络模型的搜索空间都很大,若是搜索空间不大就能够暴力枚举了,并且生成一个模型要评估好坏就须要训练,这个成本也是很是大了。

这时咱们想到的调优算法就是贝叶斯优化(Bayesian optimization)、粒子群优化(Particle swarm optimization)、Policy gradient、DQN 等等,这些算法均可以用于 NAS 内部的模型的优化。是的,NAS 内部也有一个模型,通常在论文或者代码中称为 controller 模型,又它来控制想要生成的神经网络模型的结构,而生成的神经网络模型会根据客户的使用场景(例如图像分类)来返回模型效果对应的指标,这个通常称为 child 模型。

前面介绍了基于 Advisor 来实现的 NAS,其实就是使用了 Advisor 内置的调优模型做为 NAS 的 controller 模型,默认就是贝叶斯优化,并且只须要修改一个参数就能够经过统一的接口来使用后端已经支持的 Random search、Grid search 等调优算法。

前面推荐的博客使用的是加强学习中的 Policy gradient 算法,包括后面提到的 ENAS 论文也是使用这个算法,而在 Google 的其余论文中有介绍使用 Evolution algorithm 和 DQN 的,AlphaZero 在超参调优中使用的是贝叶斯优化,而 Deepmind 最新的调参论文介绍了相似 PSO 的群体优化算法。

你们须要理解这些算法从本质上没有区别,都是黑盒优化算法,由于假设不知道优化的目标和优化的参数是否有函数关系而且不能从中获取梯度等信息,只能从历史的模型训练结果中根据超参组合还有最后模型效果来选择超参的变化值。而 这些算法的区别在于运行效率和算法复杂度上,所以也会应用到不一样的领域上

咱们常常看到下围棋、打游戏的人喜欢用 DQN、A3C 算法来优化模型,是由于下棋和打游戏都是能够经过软件模拟操做而且能够快速收到 reward 的,例如一分钟收集到几十万的 state 和 reward 彻底足够训练一个高度复杂的 AlphaZero 模型(基于 ResNet)。而 AlphaZero 的超参调优却使用基于高斯过程的贝叶斯优化,是由于调整超参须要从新训练模型代价很大,大概几小时才能获得一个 state 和 reward,这不足以训练一个比 ResNet 弱不少的神经网络模型,但能够经过在数学上假设全部超参之间符合联合高斯分布而后经过高斯过程求 state、reward 关联关系的均值和方差,而后基于 exploration/exploitation 原则选择下一个更优的探索点,这也就是贝叶斯优化的实现原理了。这其实也解释了为何 Google 之前基于 DQN、进化算法的 NAS 模型须要几百块 GPU 并发训练多个月,由于评估一个模型结构是好是坏真的很耗时,这也是为何 ENAS 解决评估模型这个问题后这么 Efficient,后面会有详细的介绍。

下面有一个更直观的图介绍为何贝叶斯优化在数学上会比瞎猜(Random search 算法)更好。首先红色的点表示已经探索过超参数,这里只有一个超参数 X 须要调整,Y 轴表示选择这个超参数 X 后模型的效果,能够认为 Y 就是模型正确率也就是越大越好,蓝线真实的超参 X 与正确率 Y 的对应关系,由于咱们不可能遍历全部 X 所以蓝线咱们是未知的,而咱们的目标是已知几个红点去找到蓝线中的最高点。其中上图有一条虚线和浅蓝色区域,那就是贝叶斯优化中高斯过程返回的均值和方差,这个均值和方差是在 X 取值范围内都有的,分别表明了这个 X 点指望的正确率是多少和这个 X 点可能浮动的空间。

若是仔细观察能够发现,红点必然会在虚线上,由于这个点是已经探索过的,也就是用这个 X 去训练模型已经获得了正确率,所以这个点也必然在蓝线上。而浅蓝色区域表明了这一块可能浮动的空间,所以浅蓝色区域里虚线越大表示这块越值得 exploration,可能发现新的高点也不必定,而虚线越高表示对这块指望的 Y 值也越大,也是越值得 exploitation。为了权衡 exploration 和 exploitation 所以有了下面的 Utility function,这也是一种算法。咱们能够简单认为它就是用均值加上λ倍的方差获得的曲线,而后取最高值做为下一个探索点,由于这个探索点表明了这个 X 位置指望的 Y 值还有想要探索更多未知的可能性,若是以为比较难理解建议先参考《贝叶斯优化:一种更好的超参数调优方式》(https://zhuanlan.zhihu.com/p/29779000 )。

ENAS 的实现

前面一直介绍的是 NAS,为了让你们了解 NAS 只是一种搜索算法。NAS 没有学会建模也不能替代算法科学家设计出 Inception 这样复杂的神经网络结构,但它能够用启发式的算法来进行大量计算,只要人类给出网络结构的搜索空间,它就能够比人更快更准地找到效果好的模型结构。

ENAS 也是一种 NAS 实现,所以也是须要人类先给出基本的网络结构搜索空间,这也是目前 ENAS 的一种限制(论文中并无提哦)。ENAS 须要人类给出生成的网络模型的节点数,咱们也能够理解为层数,也就是说人类让 ENAS 设计一个复杂的神经网络结构,但若是人类说只有 10 层那 ENAS 是不可能产出一个超过 10 层网络结构,更加不可能凭空产生一个 ResNet 或者 Inception。固然咱们是能够设计这个节点数为 10000 或者 1000000,这样生成的网络结构也会复杂不少。那为何要有这个限制呢?这个缘由就在于 ENAS 中的 E(Efficient)。

你们大概了解过 ENAS 为何比其余 NAS 高效,由于作了权值共享 (Parameter sharing),这里的权值共享是什么意思呢?是你们理解的模型权重共享了吗,但 ENAS 会产生和尝试各类不一样的模型结构,模型都不同的权重还能共享吗?实际上这里我把 Parameter sharing 翻译成权值共享就表明则这个 Parameter 就是模型权重的意思,而不一样模型结构怎样共享参数,就是 ENAS 的关键。ENAS 定义了节点(Node)的概念,这个节点和神经网络中的层(Layer)相似,但由于 Layer 确定是附着在前一个 Layer 的后面,而 Node 是能够任意替换前置输入的。

下面有一个较为直观的图,对于普通的神经网络,咱们通常每一层都会接前一层的输入做为输出,固然咱们也能够定义一些分支不必定是一条线的组合关系,而 ENAS 的每个 Node 都会一个 pre-node index 属性,在这个图里 Node1 指向了 Node0,Node2 也指向了 Node0,Node3 指向了 Node1。

事实上,ENAS 要学习和挑选的就是 Node 之间的连线关系,经过不一样的连线就会产生大量的神经网络模型结构,从中选择最优的连线至关于“设计”了新的神经网络模型。若是你们理解了可能以为这种生成神经网路的结构有点 low,由于生成的网络结构样式比较类似,并且节点数必须是固定的,甚至很难在其中创造出 1x1 polling 这样的新型结构。是的,这些吐槽都是对的,目前 ENAS 能够作的就是帮你把连线改一下而后生成一个新的模型,但这个就是 ENAS 共享权重的基础,并且能够以极低的代码量帮你调整模型结构生成一个更好的模型,接下来就是本文最核心的 ENAS 的 E(Efficient)的实现原理介绍了。

咱们知道,TensorFlow 表示了 Tensor 数据的流向,而流向的蓝图就是用户用 Python 代码定义的计算图(Graph),若是咱们要实现上图中全部 Layer 连成一条直线的模型,咱们就须要在代码中指定多个 Layer,而后以此把输入和输出链接起来,这样就能够训练一个模型的权重了。当咱们把上图中全部 Layer 连成一条直线的模型改为右边交叉连线的模型,显然二者是不一样的 Graph,而前一个导出模型权重的 checkpoint 是没法导入到后一个模型中的。但直观上看这几个节点位置本没有变,若是输入和输出的 Tensor 的 shape 不变,这些节点的权重个数是同样的,也就是说左边 Node0、Node一、Node二、Node3 的权重是能够彻底复制到右边对应的节点的。

这也就是 ENAS 实现权重共享的原理,首先会定义数量固定的 Node,而后经过一组参数去控制每一个节点链接的前置节点索引,这组参数就是咱们最终要挑选出来的,由于有了它就能够表示一个固定神经网络结构,只要用前面提到的优化算法如贝叶斯优化、DQN 来调优选择最好的这组参数就能够了。

那评估模型也是先生成多组参数,而后用新的网络结构来训练模型获得 AUC 等指标吗?答案是否认的,若是是这样那就和普通的 NAS 算法没什么区别了。由于训练模型后评估就是很是不 Efficient 的操做,这里评估模型是指各组模型用相同的一组权重,各自在未被训练的验证集中作一次 Inference,最终选择 AUC 或者正确率最好的模型结构,其实也就是选择节点的连线方式或者是表示连线方式的一组参数。

稍微总结一下,由于 ENAS 生成的全部模型节点数是同样的,并且节点的输入和输出都是同样的,所以全部模型的全部节点的全部权重都是能够加载来使用的,所以咱们 只须要训练一次模型获得权重后,让各个模型都去验证集作一个预估,只要效果好的说明发现了更好的模型了。实际上这个过程会进行不少次,而这组共享的权重也会在一段时间后更新,例如我找到一个更好的模型结构了,就能够用这个接口来训练更新权重,而后看有没有其余模型结构在使用这组权重后能在验证机有更好的表现。

回到前面 TensorFlow 实现 ENAS 的问题,咱们知道 TensorFlow 要求开发者先定义 Graph,而后再加载权重来运行,但定义 Graph 的过程与模型训练过程是分开的,而 ENAS 要求咱们在模型训练过程当中不断调整 Graph 的结构来尝试更好的 Graph 模型结构。这在声明式(Declarative)编程接口的 TensorFlow 上其实很差实现,而命令式(Imperative)编程接口的 PyTorch 上反而更好实现。固然这里能够为 TensorFlow 正名,由于 ENAS 的做者就提供了基于 TensorFlow 的 ENAS 源码实现,开源地址 https://github.com/melodyguan/enas 。咱们也深刻看了下代码,做者用了大量 tf.case()、tf.while() 这样的接口,实际上是 在 TensorFlow 的 Graph 中根据参数来生成最终训练的 child 模型的 Graph,所以没有用 Python 代码定义全部 child 模型的 Graph 的集合,也不须要每次都从新构建 Graph 来影响模型训练的性能。

除了 Node 之间的连线外,ENAS 论文里面能够训练的超参数还包括上图中的激活函数,也是经过 controller 模型输出的一组参数来决定每一个 Node 使用的激活函数,而这些激活函数不须要从新训练,只须要直接加载共享权重而后作一次 Inference 来参与模型评估便可。

不少人可能以为目前共享的权重比较简单,只能实现矩阵乘法和加法,也就是全链接层的做用,但在图像方面会用到更多的卷积网络,也会有 filter size、polling kernel size 等参数须要选择。实际上 ENAS 已经考虑这点了,这些 Node 拥有的权重以及使用权重的方法被称为 Cell,目前已经提供乘法和卷积这两种 Cell,而且在 PTB 和 Cifar10 数据集上作过验证,固然将来还能够加入 RNN 等 Cell,甚至多种 Cell 一块儿混用,固然这个在实现上例如前置节点的连线上须要有更复杂的判断和实现。

对于 ENAS 的 controller 模型的参数调优,论文中使用的是加强学习中的 Policy gradient,固然正如前面所提到的,使用贝叶斯优化、DQN、进化算法也是没问题的。不过目前 ENAS 的 controller 模型和共享权重的实现放在了一块儿,所以要拓展新的 controller 提优算法比较困难,将来咱们但愿把更多的调优算法集成到 Advisor 中(目前已经支持 Bayesian optimization、Random search、Grid search,正在计划支持 Policy gradient、DQN、Evolution algorithm、Particle swarm optimization 等),让 ENAS 和其余 NAS 算法也能够更简单地使用已经实现的这些调优算法。

整体而言,ENAS 给咱们自动超参调优、自动生成神经网络结构提供了全新的思路。经过权值共享的方式让全部生成的模型都不须要从新训练了,只须要作一次 Inference 就能够得到大量的 state 和 reward,为后面的调优算法提供了大量真实的训练样本和优化数据。这是一种成本很是低的调优尝试,虽然不必定能找到更优的模型结构,但在这么大的搜索空间中能够快速验证新的模型结构和调优生成模型结构的算法,至少在已经验证过的 PTB 和 CIFAR-10 数据集上有了巨大的突破。

固然也不能忽略 ENAS 自己存在的缺陷(这也是将来优化 ENAS 考虑的方向)。首先是为了共享权重必需要求 Node 数量一致会限制生成模型的多样性;其次目前只考虑记录前一个 Node 的 index,后面能够考虑链接多个 Node 制造更大的搜索空间和更复杂的模型结构;第三是目前会使用某一个模型训练的权重来让全部模型复用进行评估,对其余模型不必定公平也可能致使找不到比当前训练的模型效果更好的了;最后是目前基于 Inference 的评估能够调优的参数必须能体现到 Inference 过程当中,例如 Learning rate、dropout 这些超参就没法调优和选择了。

总结

最后总结下,本文介绍了业界主流的自动生成神经网络模型的 NAS 算法以及目前最为落地的 ENAS 算法介绍。在整理本文的时候,发现 NAS 其实原理很简单,在必定空间内搜索这个你们都很好理解,但要解决这个问题在优化上使用了贝叶斯优化、加强学习等黑盒优化算法、在样本生成上使用了权值共享、多模型 Inference 的方式、在编码实现用了编写一个 Graph 来动态生成 Graph 的高级技巧,因此要 读好一篇 Paper 须要有一对懂得欣赏的眼睛和无死角深挖的决心

本文致谢 Hieu Pham、Melody Y Guan、Barret Zoph、Quoc V Le、Jeff Dean。

做者介绍

陈迪豪,第四范式先知平台架构师,曾在小米科技和 UnitedStack 担任基础架构研发工程师。活跃于 OpenStack、Kubernetes、TensorFlow 等开源社区,实现了 Cloud Machine Learning 云深度学习平台,Github 帐号 https://github.com/tobegit3hub。


更多干货内容请关注微信公众号“AI 前线”,(ID:ai-front)

相关文章
相关标签/搜索