1. 前言
最近做了一段时间的模型搜索,实验过程中发现模型搜索作用还是很明显的。本篇文章主要回顾了一下近几年一些关于模型搜索的文章:
RL-based
- Neural Architecture Search with Reinforcement Learning
- Efficient Neural Architecture Search via Parameter Sharing
Gradient-based
- DARTS: Differentiable Architecture Search
- SNAS: Stochastic Neural Architecture Search
- FBNet: Hardware-Aware Efficient ConvNet Design via Differentiable Neural Architecture Search
- ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware
2. Neural Architecture Search with RL
http://cn.arxiv.org/pdf/1611.01578v2
这篇论文应该是比较早的关于模型结构搜索的论文,主要基于增强学习算法,将搜索得到的模型的performance作为reward,反馈给agent,不断更新agent以最大化。
论文使用了一个RNN来作为agent,也就是controller,如下图:
可以看到,通常我们使用RNN在每一个时刻输出一个word的表示,现在改为输出网络结构的参数。
每一次当RNN选择一组参数,就根据参数构建网络,然后在一个数据集上进行训练,训练结束后使用一个验证集,对得到的网络进行评测,评测的结果计算一个reward值返回给RNN。
作者使用验证集的准确度(accuracy)作为reward ,RNN的参数更新使用REINFORCE算法。该算法是增强学习的基础算法,可以直接使用agent的动作得到的reward对策略梯度进行近似,也就是RNN的参数的梯度。公式如下:
从公式中可以看出,可以直接将的梯度作为策略的梯度。
通常还会增加一个baseline,用于减少variance,baseline的选择可以为之前reward的moving average。
有了RNN参数的梯度公式,我们就可以用任何常见的深度学习框架来建模训练啦。
但是非常明显,这种每次都要训练一个模型的方式必然是非常非常慢的,论文中提出了可以使用一大堆GPU服务器,来异步训练的方式。
整个架构如下图:
RNN的参数保存在PS(参数服务器)的服务器端,然后复制个RNN,它们的参数都与服务器端参数一致(在某些时刻)。之后每个RNN,每人按照之前说到的方式,采样出个模型,这的模型异步地在不同的GPU上进行训练,得到accuracy。
然后每个agent,也就是每个RNN的复制,根据自己的个得到的accuracy,计算出RNN参数的梯度,将梯度push给服务器,服务器根据梯度进行参数的更新,由于是异步的,服务器不会等待得到所有 个agent的梯度,就进行参数的更新,RNN push完梯度后,会将新的参数pull下来。
作者还期望能够对结构的复杂度进行选择,也就是对网络节点之间的链接进行选择,因此如下图:
对每个节点增加了anchor point,第层的anchor point预测个值,表示与之前节点的链接:
论文后面还提出了搜索RNN结构的方式,类似于LSTM,LRU之类的结构,就不赘述了。
3. Efficient Neural Architecture Search via Parameter Sharing
http://cn.arxiv.org/pdf/1802.03268v2
上篇论文太贵,因此这篇论文提出了更加高效的搜索方式。
这篇论文的核心思想:将整个搜索空间看作一个巨大的图,搜索得到的模型就是这个图的子图,所以可以进行参数共享。
如下图:
红线代表了选择的模型,它其实是一个DAG的一个子图。
因此,在整个模型搜索中可以认为有两种参数:RNN的参数,共享模型的参数。训练是交替进行的:
- 训练共享模型的参数:固定RNN的参数,sample一个模型,按照标准的方式训练参数。
- 训练RNN参数:固定,使用REINFORCE算法,不断sample模型,计算reward,这里reward是在验证集上计算。
其实后面很多的模型搜索方法,都和这里训练的框架一致。
论文后面还介绍了具体的模型搜索空间的设计,就不赘述了。
4. DARTS: Differentiable Architecture Search
http://cn.arxiv.org/pdf/1806.09055v1
之前的两篇是使用增强学习算法,这一篇是比较早的使用梯度法的模型搜索,并且在github上开源了搜索源码。
整体思路如下图:
从图中可以看出,每个小的block有个节点,每个节点都进行了编号,并且每个节点和编号比它小的节点之间都有链接。然后每个节点的输入,就是和它有链接的节点的加权和。公式如下:
这里的就代表了边,每个边都有一组可选择的操作,通常我们想要从这个DAG中选择一个模型,就需要这个是,也就是:
论文中作者使用的是softmax:
这样就将选择模型这个任务,转换为了训练一组参数的任务。就像Figure 1。
因此,任务转换称为了一个bilevel优化问题:
需要在最优的情况下,不断地优化,但是这种优化问题需要在每次改变是优化,这将是非常耗时的。
因此,作者提出一种迭代优化的策略,来近似地优化上面的问题。算法如下图所示:
在每一步,首先将按照最小化的梯度方向进行更新得到,接着固定,然后按照最小化下面公式的梯度方向更新
上面公式的直观解释就是,在假设进行了一步虚拟的更新之后,优化validation loss,这里,我并不是特别理解对进行更新的必要性,为什么不直接用呢?就好像的更新,是在预测的下一步的情况下进行的。
作者给出了梯度公式,然后又因为需要计算二阶导数运算量太大又给出了近似公式(这是在向我等渣渣秀数学功底嘛):
二阶导数主要是用差分来近似。
在算法收敛后,我们就得到了一组,使用它就可以选择每个边的具体操作是什么了,以及选择每个节点的输入节点。看代码貌似是stride为2的层是一组,为1的层共享一组。这里为什么不每层都一组参数呢?
其实对比一下上一篇论文ENAS,差别主要在于将ENAS中的RNN,替代为了这里的,然后更改了训练算法,RNN使用REINFORCE训练,采用梯度下降法训练。
5. SNAS: Stochastic Neural Architecture Search
http://cn.arxiv.org/pdf/1812.09926v2
这是一篇会议收录的论文,出自商汤。这篇论文使用了很多增强学习中的概念来解释论文提出的搜索方法。
论文首先在介绍里指出里RL-based的NAS和darts的不足之处。论文指出在RL-based的NAS中,NAS通过Markov Decision Process来进行建模,我们知道MDP描述的是一个agent不断选择action与环境交互的过程。作者提到MDP中如果使用TD learning,会由于delayed reward导致效率和可解释性变差。在ENAS中,一个agent的reward只有在它作出了一系列的action之后,也就是得到模型之后才能得到,因此就出现了delayed reward。
darts虽然没有这样的问题,但是由于operation的非线性,在loss中引入了untractable bias。这里并不是特别理解,我认为大意是在说darts在最终选择模型的时候,会去掉权重较小的部分,导致搜索时的loss与最终选择的模型的loss直接存在一个偏差。
因此,这篇论文提出了SNAS,试图解决上面的问题。
首先,SNAS去掉了对于模型搜索的MDP假设,也就是摆脱掉了reward。并且使用了完全可求导的loss,sample的过程被可微分的relaxing的分布代替。
作者证明了SNAS优化的是RL-based相同的目标,以及loss是如何分布在每一次sample的action中。
单纯从方法论的角度,SNAS并不是特别的复杂。如下图:
与darts非常相似,每一边都是一组operation,参数的大小代表了它们的权重。公式如下,
这里使用
那么我们的目标函数就是:
问题是它可以求导吗?我们知道在
可以证明在趋近于0的时候,是趋近于max分布的。
这样就减轻了搜索时的loss与真实搜索出来的模型的loss之间的bias。
那么SNAS怎么解决了像ENAS中的delayed reward的问题呢?首先SNAS中没有常数项的reward,reward在SNAS中是可导的。我们可以求出reward对于模型搜索参数的导数:
其中
也就是说每个边都得到了自己的reward,它并不是delayed。
在模型搜索中,除了将accuracy,loss作为目标之外,我们还期望搜索得到的模型的计算量,效率得到优化。因此,SNAS引入了resource constraints,如下图:
6. FBNet: Hardware-Aware Efficient ConvNet Design via Differentiable Neural Architecture Search
http://cn.arxiv.org/abs/1812.03443
这是一篇Facebook出的,这篇论文的思路是之前又不太一样,与其在小的block上做文章,这篇论文尝试在整个模型架构上进行搜索。
其实从方法上来讲,FBNet依旧采用了使用一组参数代表权重的方式,只不过darts代表的是节点之间op的权重,FBNet中代表的是一组给定block,每个block的权重。具体来讲就是,FBNet整体结构如下图:
TBS代表等待搜索的block,每一层有8个或9个block,block的设计如下:
根据参数计算得到的权重,就代表了每个block被选中的概率。
论文有两点值得注意,一是根据参数计算概率的方式,二是论文引入了真实环境中,block运算所需时间,作为loss。
首先是loss,如下图:
这里我非常不理解乘一个
然后是block的概率,在正常情况下,我们最终使用的模型应该是从每层中的多个选择一个block,选择的概率分布为:
每一层的输出为:
其中表示0,1随机变量,代表是否被选中。显然,这个没法求导,因此,类似于SNAS,FBNet也采用了reparameterize trick,使用gumbel分布代替真实分布:
7. ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware
http://cn.arxiv.org/abs/1812.00332
这篇来自于MIT,论文作者貌似曾经出过很多关于模型压缩的文章。其实模型搜索类似于模型压缩,都是将一个大的网络,弄成一个小的网络。
其实proxyless nas与FBNet非常类似,不同处在于FBNet是每一层的所有block一起训练,输出是加权平均,然而proxyless nas是真正地去sample一个block来训练。
整个训练框架如下图:
每一层的输出为:
那么训练流程依旧采取交替的方式,首先使用采样出来的block训练weight parameters,接着固定weight parameters训练architecture parameteres。
weigh的训练类似于一个神经网络的训练,容易理解,那么architecture参数是怎么训练的呢?
一种是类似于RL-based的方式,采用REINFORCE算法。每层选择block看作是agent的action,将得到的网络的performance作为reward,可是在论文中好像并没有给出reward的计算公式。这个reward可以有各种形式,accuracy,-ce,或者是负的时间代价,以及它们的组合。
还有一种方式,感觉实现起来很复杂,由于作者并没有开源出search的代码,具体的细节我也不清楚,这里就不赘述了。
8. 小结
模型搜索应该是近两年非常热门的内容,它其实属于AutoML的大框架之下,有兴趣的可以在https://www.automl.org/ 找到很多相关内容。
最后,有没有今年(2019)考研计算机的小伙伴呀。