如何NAS之后的发展或者有什么独特见解,请大家一起讨论一下,相互启发。


之后的发展不知道,说下历史吧~

-----------------------------------------

神经网路架构搜索(NAS)今年也是火的不行,本文简单梳理一下个人觉得比较有代表意义的工作,如果有错误或者遗漏欢迎大家指出hhhh

另外推荐一篇survey(虽然到处都在说这个,但我还是要推荐一下)

Neural Architecture Search: A Survey

大致按照时间线来,内容分为这么几块:大力出奇迹平民化落地

1,大力出奇迹

--------------------------------

被人们所熟知的第一篇NAS工作应该是Google的这篇NEURAL ARCHITECTURE SEARCH WITH REINFORCEMENT LEARNING[ICLR17],充分展现了Google的实力和财力(划掉)。思路也是简单明了,以前每一层的filter数量大小等等都需要人为来定,那就可以做成一个优化问题列几个选项让它自己选个最好的,这样的选择组合起来就成了编码某个网路结构的token。为了让其更加灵活支持变长token,使用RNN来作为这里的controller,然后用policy gradient来最大化controller采样网路的期望reward,也就是validation accuracy

思路很直接,效果也不错,然鹅Google用了800块gpu跑了快一个月(还只是在cifar10)...直接劝退

后来这帮大佬可能觉得跑个cifar10太naive了,应该整个ImageNet,但是像之前这么搞直接在ImageNet上搜肯定是跑不动的,别说800张卡,8000张都搞不定。

于是Google又出了一篇Learning Transferable Architectures for Scalable Image Recognition[CVPR18]。那我不搜整个结构,搜个cell然后堆起来就行了,反正VGG/Inception/ResNet也是这么干的,于是沿用了之前的思路,继续用RNN和policy gradient在新的搜索空间中寻找最佳的结构,在cifar上搜cell然后堆起来用到ImageNet上。搜索目标只包括两种cell,一种是normal cell,另一种reduction cell用于downsample,每个cell里面包括一些block,新的搜索空间包括选择这些block使用什么op,用什么作为输入等。之后很多工作都沿用了NASNet Search Space这个套路。

最后整体结构和搜到的cell长这个样子,也就是NASNet

performance也很不错,cifar10最好的一次跑到了2.19%的error rate,在同样参数下ImageNet也都超过了手工设计的网路

这次的速度比上次快多了,500块gpu只跑了4天就跑完了(再次劝退)

之后大佬们可能觉得现在的token都定长了,或许RNN+policy gradient的优化方式可以换成一些其他的演算法(也可能是觉得强化学习调参太tm蛋疼了),于是Google又出来一篇Regularized Evolution for Image Classifier Architecture Search[AAAI19],搜索空间沿用上面的NASNet Search Space,只是将优化演算法换成了regularized evolution(具体演算法还是看paper吧...写出来感觉内容太多了(其实就是懒)),搜到的结构叫做AmoebaNet。实验表明确实evolution更加好使,收敛快,效果好,调参还没那么蛋疼。

右边两个是不同数据集上的

AmoebaNet这种方法用450块gpu跑了7天,依旧劝退。。

后来Google自己也觉得之前的方法太花时间了,于是又搞了个Progressive Neural Architecture Search[ECCV18],主要目标就是做加速。将搜索空间减小并且用预测函数来预测网路精度,最后时间缩短到大概225个gpu-day,相比AmoebaNet少了十几倍,然而对于普通玩家还是在劝退。。。

2,平民化

--------------------------------

像上面这种大力出奇迹的玩法平民玩家基本玩不起,但是计算量的问题摆在这里,自然就有一些解决方案来加速这个过程。

比较有代表性的就是weight sharing加速validation的Efficient Neural Architecture Search via Parameter Sharing[ICML18](咦,还是Google的Quoc V. Le他们),大概思路就是将NAS的采样过程变成在一个DAG里面采样子图的过程,采样到的子图里面的操作(卷积等)是参数共享的。与之前的方法主要差别就在于ENAS中子图的参数从DAG继承而来而不是重新初始化,不需要train-from-scratch即可以验证子图的精度,极大的加速了NAS的过程。

从DAG中采样子图,这里1是输入节点,3/6是输出节点

为了评估采样到的子图在数据集上的表现,DAG的参数(weight等)是需要优化的,除此之外为了找到最好的子图,采样器(这里使用的RNN)也是需要优化的。ENAS采用的是交替优化DAG中的参数和采样器中的参数。DAG参数的优化是通过采样一个子图,然后forward-backward计算对应操作的梯度,再将梯度应用到DAG上对应的操作通过梯度下降更新参数。采样器RNN的更新采用了之前policy gradient的优化方式。

ENAS搜索整个CNN,RNN采样每个节点的操作以及输入的前置节点

ENAS提出了两种模式(这里只介绍CNN),一种是搜整个网路结构,一种是搜个cell然后按照之前的方式堆起来,在搜索cell的时候只需要一张卡跑半天就能跑完。不过最近ICLR20的投稿中对于weight sharing有很多不同的声音,有兴趣的可以去openreview看一看。

还有一个很快就能跑完的NAS工作是用可微分的方式进行搜索的DARTS: Differentiable Architecture Search[ICLR19],在今年被各种魔改(我猜很可能是因为开源了pytorch的代码,然后代码写得很漂亮改起来也比较容易)。DARTS和ENAS很像,也是从DAG中找子图,并且同样采用了weight sharing,主要的区别在于搜索空间和搜索演算法上。搜索空间比较类似NASNet search space,搜索演算法则是采用了可微分的方式。

DARTS也是搜cell然后按照一定的模式堆起来,在搜索演算法上与之前的方法最大的区别在于DARTS选择某个操作的时候并不是像之前按照RNN的输出概率进行采样,而是把所有操作都按照权重(不是直接加权,先将权重softmax归一化)加起来,那这样权重就在计算图里面了,在计算验证集loss之后就可以backward计算权重的梯度,直接通过梯度下降来优化权重。搜索的过程也就是优化权重的过程,最后保留权重最大的操作就是最后搜到的结构。

DARTS里面的一个cell,不同颜色的边表示不同的操作,颜色深浅表示不同的权重,最后留下权重最大的

权重的优化和DAG里面weight的优化类似于ENAS,也是交替进行的(在训练集上优化weight,在验证集优化权重),不过DARTS是整个DAG进行forward-backward(这样的缺点在于内存开销会比较大)而不是像ENAS一样先采样子图。

DARTS的搜索演算法,很漂亮的工作

DARTS搜索一次只需要一张1080ti跑一天即可,对于平民玩家完全没压力hhhhh

上面这两项工作让很多只有几张显卡的平民玩家也能玩得起NAS。

3,落地

--------------------------------

上面所介绍的NAS工作很少有人工设计网路的影子,基本都是重新设计了新的搜索空间。从实验结果上来NAS搜到的网路确实能取得很好的效果,但并不一定适合实际部署(比如DARTS能在很小的参数量下达到很高的精度,但是实际forward其实很慢)。既然之前已经有了很多优秀的人工设计的网路结构,NAS可以通过引入这些先验知识来加速或者取得更好的实际部署性能。

先举个最直观的例子,EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks[ICML19]简单粗暴,既然MobileNet在同样精度下速度快,那我把它拿来搞大一点,同样的速度下精度会不会高一点?答案是肯定的

问题在于怎么放大这个网路,单独加深/加宽/加大解析度效果一般般,EfficientNet搜索了宽度/深度/解析度之间的相对缩放因子,将他们按照一定的比例放大,事实证明这种方式(我觉得这应该也算是NAS)虽然简单但是有效。

EfficientNet(缩放之后的MobileNetV2)性能很残暴并且缩放的组合方式很重要

还有一个魔改MobileNetV2的工作出自MIT Song Han组,ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware[ICLR19],这篇工作的point不在于魔改MobileNetV2(kernel size,expansion ratio等),而是在于proxyless的理念。想要某个数据集在某硬体上的结果就直接在对应的数据集和硬体上进行搜索,而不是像之前的工作先在cifar10搜然后transfer到ImageNet等大数据集上,并且在目标函数上加入硬体latency的损失项作为多目标NAS,直接面向部署的硬体。

另一个系列的工作也是出自Google,MnasNet: Platform-Aware Neural Architecture Search for Mobile[CVPR19]用来魔改MobileNetV2里面的layer数/卷积操作/加attention等等,然后用之前同样的RNN+policy gradient的方式来优化

除此之外,NetAdapt: Platform-Aware Neural Network Adaptation for Mobile Applications[ECCV18]针对特定硬体对已有的网路做压缩,相当于对网路在硬体上做一个结构上的fine-tune。

Google后来结合了上面这两项工作,推出了Searching for MobileNetV3[ICCV19],把MnasNet魔改的MobileNetV2再用NetAdapt做微调,然后加了一些工程技巧,得到了最后的MobileNetV3。

性能很强悍,超过了ProxylessNAS和MnasNet

最后再介绍一个同样是Song Han组最近的工作,Once for All: Train One Network and Specialize it for Efficient Deployment[Arxiv],直接train一个大网路,需要哪种网路直接去里面取就可以,将训练过程和搜索的过程解耦开来,相当于只需要train一次。

比较神奇的地方在于训完了之后不需要fine-tune就能取得很好的结果,应该是跟下面这种progressive shrinking的训练方式相关。如果再fine-tune精度会更高,openreview上的版本甚至比MobileNetV3高出4个点。

progressive shrinking

感觉是一个很好的思路,大部分NAS的主要时间到都花在验证/比较网路精度上,那么把这个时间都花在训练一个大网路上,然后再选所需要的小网路或许是一种更高效/性能更好的方式。Once for All使用的一些技巧也比较多,推荐大家看一下原paper

最后再说一个Rethinking the Value of Network Pruning[ICLR19]里面的结论,对于结构化的剪枝,Training---Pruning---Fine-tuning的pipeline得到的精度并不如将目标网路train-from-scratch的精度高,也就是说剪枝的目标网路的结构设计其实最为重要,这也就是NAS正在做的事情。不过在train-from-scratch代价比较大的时候,pruning和fine-tuning的策略也很重要,争取在计算量尽量少的情况下维持原有精度。


我看到的目前NAS领域比较热的基本上是基于可微分的方案的一些方法,然后内容是定义一个有一定容量的residual block空间,在这个空间内搜索最优的residual block,数据集基本上是在cifar10上搜索架构,然后在cifar100/imagenet测,运行时间基本上在一天以内,总的来说比较无聊~

说实话我觉得开始那些耗时1000+ gpu days的才是真正意义上NAS,而这类可微分NAS我觉得纯粹就是小打小闹的炼丹~~


公众号:将门创投 (thejiangmen)

网路结构搜索(神经架构搜索)是自动化机器学习的重要分支,具有广泛的应用前景。

我「门」有幸邀请到微软亚洲研究院研究员—彭厚文博士来到将门TechBeat,为我们带来NeurIPS 2020 系列Talk之「"百里挑一":基于优先路径蒸馏的网路结构搜索

本次Talk中,彭厚文分享了他的NeurIPS 2020工作,重点介绍了One-Shot NAS方法,并提出基于优先路径蒸馏的结构搜索方法。采用优先路径搜索得到的网路结果在ImageNet上达到了80.0% 的Top-1分类准确率,超越了现有的EfficientNet-B0/B1以及MobileNetV3方法。

Talk已在将门TechBeat上线!【点击这里】,即可马上免费观看!

本次分享的主要内容如下:

1. One-Shot NAS

2. One-Shot NAS with Knowledge Distillation

3. Distilling Prioritized Paths for One-Shot NAS

4. Experiments and Results

5. Applications

? Talk·参考资料

这是本次分享中将会提及的资料,建议提前预习哦!

论文链接:

https://arxiv.org/pdf/2010.15821.pdf

代码链接:

https://github.com/microsoft/Cream

? Talk·精彩片段

? Talk·嘉宾介绍

彭厚文 微软亚洲研究院研究员

彭厚文现在是微软亚洲研究院多媒体组研究员。他的研究兴趣包括神经网路结构搜索与设计,视频目标跟踪、分割与检测,视频内容检索,以及显著物体检测等。他曾在领域内多个学术会议和期刊上发表过论文,其中包括TPAMI的Featured Paper;同时,也在多个领域内竞赛中获得过冠亚军,例如VOT2019-RGBD Track第一名。

在2018年加入微软亚洲研究院之前,他曾是高通研究院的高级工程师。他于2016年获得中国科学院自动化研究所的博士学位,并于2015年至2016年作为Research Scholar在Temple University研究学习。

? 点击【这里】,一起听Talk啦~


1:全自动方向:初始化就是一个神经元并且不指定搜索空间,以神经元为单位进行search,执行过程中也不需要人为干预。

2:无需借助大量计算资源:不需要大量计算资源就能够进行NAS,这样才能够真正落地。

现在的方法都很对得起名字里的「search」,期待「generate」能成为主流


NAS炼丹巨痛苦。

NAS离落地还远,首先有个问题,它的搜索空间是提前设定好的,超参数也是设定好的,相当于在指定的搜索空间内,搜索到相对较好的网路结构。那么问题来了,指定的搜索空间怎么定义好坏,超参数怎么设定。。

ps:最近我在NAS练丹,需求是超低Flops,0.3M级别的,有同好,可以交流交流。


从对特征的特征工程,到对网路结构的特征工程,再到对NAS搜索空间的特征工程,我们一直在扩展解空间。相应的,完成任务所需要的数据也要相应扩展,对于特征的特征工程,我们只需要少量代表性数据,我们需要找到局部的特征;对于网路结构的特征工程,我们需要大量特定任务的数据,我们需要找到的是一个网路整体的特征;现在对于NAS,我们可能实际需要的是针对某一类别的不同任务的大量数据,相应的,我们需要找到一类网路的特征;这其实就进入了元学习的领域。感觉针对一个特定任务的NAS可能是一种过渡阶段的系统,NAS可能更应该针对元学习。


目前好像大多数还是CV的分类检测分割用的多,想请问一下NAS有没有在NLP/推荐方面的工作?NLP只看到一篇用在NER上的。


推荐阅读:
相关文章