0 前言
在过去的几年里,深度神经网络在许多具有挑战性的应用中取得了巨大的成功,从 AlexNet 到 VGGNet、GoogLeNet 以及 ResNet,网络模型变得越来越强大。虽然这些模型已经足够灵活,但人工神经网络设计不仅需要大量的专业知识,也需要充足的时间进行验证,调参对于深度模型来说更是项非常艰苦的事情,众多的超参数和网络结构参数会产生爆炸性的组合,常规的随机搜素和网格结构搜索效率非常低。与此同时,由于部署硬件的性能差异,其对模型指标的一致性要求更高。因此,最近几年,神经网络的结构搜索和模型优化成为了一个研究热点。
图 1. Neural Architecture Search 领域早期的工作
Google Brian 的 NEURAL ARCHITECTURE SEARCH WITH REINFORCEMENT LEARNING[1] 提出了构建网络结构搜索 (Neural Architecture Search, NAS) 的基本框架,通过强化学习把架构的生成看成一个智能体(Agent)在选择动作(action)的过程,通过在测试集上测试网络性能来获取奖励值 (reward),计算策略梯度(Policy Gradient)来更新 RNN 控制器,从而指导架构的生成。 为了将 NAS 迁移到更大数据集乃至 ImageNet 上,NASNet[2] 提出了一种方案:在 CIFAR-10 上学习一个网络单元 (Cell),然后通过堆叠更多的这些网络单元的形式将网络迁移到更复杂、尺寸更大的数据集上面。对于相同的搜索空间,AmoebaNet[3] 则采用 EA-based 搜索策略,在进化算法中使用了年龄进化的策略,并在进化时倾向于选择更年轻的模型,在算法策略角度上尝试了进化的方法。
NASNet 和 MetaQNN[4] 都是针对特定数据集基于层 (layer) 的搜索算法。网络一般是由数百个卷积层组成,每个卷积层在类型和超参数上都有众多的选择,这大大增加了网络架构的搜索空间和计算成本。针对以上问题,诞生了基于块(block) 的设计方法 BlockQNN[5]。块搜索空间的思想延续到了 PNAS[6]、ENAS[7]以及DARTS[8] 等主流工作中。在 Network Morphism[9] 工作中,基于网络态射结构的方法能够在原有的网络结构基础上做修改,所以能够在很大程度上保留原网络的优点,而且其特殊的变换方式能够保证新的网络结构还原成原网络,也就是说,它的表现至少不会差于原网络。基于网络态射理论,允许自网络不用从头开始训练模型,而是通过继承父模型的权重来进行初始化,使用权值继承方法进行 NAS 可以使计算量降低至数个 GPU days,该系列的思想推动了 NAS 在落地实践中应用。
图 2. 基于强化学习的网络结构搜索
如图 2 基于强化学习的网络结构搜索,对比 NasNet 以及 MnasNet[10] 中「RNN 控制器+策略梯度更新」的范式在移动端也同样可以搜索到时延优异的网络结构。此流程涉及到如下几个循环步骤:- 使用控制器生成相应的网络结构 - 训练该网络结构 - 评估该网络结构 - 更新相应的控制器以便于生成更优的网络结构
那么在该流程下,该如何应用强化学习理论优化生成更好的网络结构呢?首先,我们来看一下关于强化学习的基本理论。
1 强化学习的简介
与我们熟知的监督学习不同,强化学习不存在有标签的数据集。以围棋为例,每一步的决策没有绝对的正确错误的类别区分。同时,每一步的决策构成一个序列决策过程,它试图在棋局中间节点以及最后结果中获得一个最大的累积奖励。与监督学习相比,强化学习的每一步与时间顺序先后关系紧密,而监督学习的训练数据之间是独立的,没有先后的差别。
监督学习 | 强化学习 | |
---|---|---|
输入 | 独立同分布 | 变化的 |
输出 | 标注的标签(提前获知) | 试错的奖励(延后得出) |
经验 | 无 | 有 |
损失 | 有 | 无 |
从下图中我们可以看到,智能体 (Agent) 和环境 (Environment) 始终处于交互的过程,而策略 (policy) 是指在每个时刻智能体根据观察到的状态 (state) 做出的决策,强化学习的目的就是学习一个策略函数 (policy function),从而获得最大奖励。策略函数的输入是状态 (state) 和动作 (action),输出是一个 0 到 1 之间的概率值。
图 3. 强化学习的序列化过程
以超级玛丽为例,状态是游戏屏幕画面,把它作为策略函数的输入,策略函数可以告诉我每个动作(向左、上、右)的概率值。
假设一回合 (episode) 一共有 步,当完成这一回合之后,我们可以观测到所有 个奖励: 。这些奖励不是随机变量,而是实际观测到的数值。此时,我们可以计算出实际回报 。
回报有什么用呢?回报是该回合获得的奖励总和,因此智能体的目标就是让回报尽量大,越大越好。强化学习要寻找一个策略,使得该回报的期望最大化。这个策略称为最优策略 (optimum policy)。值得注意的是,强化学习的目标是最大化回报,而不是最大化当前的奖励。以围棋为例,你的目标是赢得一局比赛(回报),而非吃掉对方当前的一个棋子(奖励)。
在大多数情况下, 时刻的回报是一个随机变量 。在我们玩游戏的时候,在 时刻,我们总是想知道随机变量 的值,来知道自己会赢还是会输。但是,随机性使得我们不能知道 的值。那么,我们该怎样消除掉随机性呢?答案就是对 求期望,得到一个具体的数值。
假设我们已经观测到状态 ,且做完决策,选择了动作 ,那么, 中的随机性就来自于 时刻后的状态与动作:。此时,我们对 关于变量 求条件期望,可以得到条件期望的结果,也就是动作价值函数 (Action-Value Function) :
可以发现,动作价值函数 不仅和当前的状态 和动作 相关,同时也与影响之后动作的策略函数 密切相关。
再进一步,如果把动作 作为随机变量,在 的基础上,关于 求期望,可以得到状态价值函数 (State-Value Function) :
我们可以发现, 只依赖于策略 与当前状态 ,不依赖于动作。
状态价值函数 也是回报 的期望:
状态价值 越大,就意味着回报的期望 越大。用状态价值可以衡量策略 与状态 的好坏。
2 基于强化学习的网络结构搜索
在网络结构搜索的任务中,实际的优化目标是让通过 RNN 控制器生成的网络结构在验证集上有更好的表现(验证集准确率)。
这个过程不同于传统的监督学习,而是利用损失函数 计算小批量的梯度并不断更新权重,从而利用梯度下降算法学习损失函数最小的 。但是,目前的优化变量是控制器 RNN 的参数 ,验证集准确率 并不是参数 的可微函数。
图 4. 通过近似策略梯度优化 RNN 参数
此时要想个办法优化 RNN 控制器的参数 。强化学习可以将不可微的目标作为环境给的奖励,但是需要收集大量的奖励才能让强化学习收敛。策略学习 (policy-based reinforement learning) 可以通过求解近似策略梯度实现奖励最大化的目的。
假设我们有了这样一个策略网络 Williams 在 1987 年提出的 REINFORCE[11-12] 算法来训练策略网络。 其中,针对 RNN 生成网络结构这一步,要经过涉及到 个超参数的 RNN 才能构成一个 CNN,而在中间层的奖励均为 0,最后奖励是 CNN 在验证集的准确率 。第 步的回报 ,根据公式我们得知,其实 与 无关,均等于验证集的准确率。REINFORCE[11-12] 算法的核心是用观测的回报 去近似动作价值函数 。
从上一节我们得知,状态价值函数 既依赖当前状态 ,也依赖策略网络 的参数 。我们定义目标函数为
这个目标函数排除了状态 的约束,只依赖策略网络求解 的最大化问题 。我们使用梯度上升对 进行更新
可以得到新的参数 。其中, 作为学习率需要手动调整。最终策略梯度表示为
策略梯度展开为
2.1 蒙特卡洛近似期望
蒙特卡洛 (Monte Carlo) 是一大类随机算法 (randomized algorithms) 的总称,它通过随机样本来估算真实值。
蒙特卡洛近似期望: 设 是随机变量, 是观测值,蒙特卡洛用 近似期望 。强化学习中的策略梯度、Q 学习、SARSA 等算法都需要这样用蒙特卡洛近似期望。
REINFORCE 对 做蒙特卡洛近似,使用从采样出的轨迹样本得到估计的累积回报 来替换,从而更新策略网络的参数 。REINFORCE 算法能够有效,是因为采样的随机梯度 (stochastic gradient) 的期望值是真实梯度的无偏估计。
我们从环境中观测一个状态 作为随机变量 的观测值,根据当前的策略网络随机抽样得出动作 。根据 和 ,我们可以计算出随机梯度:
对于 时刻的回报 ,我们使用蒙特卡洛近似 的条件期望,也就是动作价值函数
因为 是随机变量 的观测值,所以 是上面公式中期望的蒙特卡洛近似。在实践中,可以用 代替 ,则随机梯度 可以近似成
随机梯度 是 的无偏估计。我们可以实际计算出 的值,进而做随机梯度上升来更新策略网络参数 。
根据上面的推导,我们可以将整个算法的训练流程整理如下:
1. 随机初始化策略网络参数
2. 使用当前策略参数控制智能体产生一条轨迹:
3. 对于每个时刻 (在网络结构搜索中即为生成网络结构的超参数序列):
- 计算累积回报
- 计算反向传播
- 更新策略网络参数
通过以上过程,我们就能够从控制器采样序列中计算并且使用它来去更新我们的策略梯度。
2.2 带基线的REINFORCE算法
基于上述策略梯度公式得出的 REINFORCE 方法虽然是一个梯度的无偏估计,但是有一个非常高的方差,所以效果并不好。为了减少方差,大幅提升表现,我们将引入基线函数:将不依赖于动作 的任意函数 作为动作价值函数 的基线 (baseline),用 替换掉 。下面是带基线的策略梯度定理:
以文章 [1] 来为例说明。优化的目标函数是
其中 是控制器 RNN 的参数, 是控制器预测的列表 tokens。在收敛时,该子网络将在 held-out 数据集上实现精确度 ,我们将其作为奖励。但由于 不可微,我们需要使用策略梯度方法迭代更新。这里我们使用 REINFORCE 规则:
其中, 是控制器在一批中采样的不同结构的数量, 是控制器设计神经网络结构时必须预测的超参数的数量。第 个神经网络在训练数据集上训练后所达到的验证精度为 。
在这里,我们使用先前结构精度的指数移动平均值作为基线,就得到:
这里我们要说明,基线的取值不影响策略梯度的正确性。不论是让 还是让 等于一个与动作无关的值,对期望的结果毫无影响,期望的结果都会等于最终的策略梯度,这里有详细的证明[13],不再赘述。
基线是如何在网络结构搜索中起到加速收敛的作用呢?这里有一个直观解释。
在策略梯度公式中,我们可以看到有一项是 。以上图为例,给定状态 ,动作空间是 ,动作价值函数给每个动作打分:
这些分值会乘到随机梯度 上。在做完梯度上升之后,新的策略会倾向于分值高的动作。根据上述分析,我们关注的是动作价值 、 、三者的相对大小,而非绝对大小。如果给三者都减去 ,那么三者的相对大小是不变的,选择卷积核为 5 仍然是最好的,卷积核为 7 仍然是最差的。因此
依然能指导 做调整,使得 变大,而 变小。
图 5. REINFORCE with baseline
3 基于硬件感知的 One-Shot-NAS 算法设计
基于强化学习的网络结构搜索,通过不断地「试错」的方式进行学习,通过迭代的方式更新控制器从而生成合适的架构。美中不足的是,在此类个体启发式的搜索策略中计算开销总是难以承受的,通过从头开始训练来评估每个架构,这提供了真实的性能,但非常耗时。目前我们在 weight-sharing NAS 方向进行了实验,并且解耦了整个 One-shot WS-NAS 算法流水线,并将现今的主要流行的工作进行归纳,在业务框架上完成搜索空间的设计以及评估的全流程,并且结合 OpenMMLab 的算法框架以及 Parrots.convert 模型级别的测速接口,实现搜索过程中多目标优化,可在 flops、latency、activations 等模型指标下进行帕累托最优搜索。其中具体组件分为搜索空间、超网训练策略、搜索算法、超参数优化等。
值得注意的包括:
- 搜索空间的统一性: 大多数 NAS 算法都将设计具体的搜索空间,但是算法的优势是否由搜索空间限制我们不得而知。因此,我们将搜索空间独立为统一格式的配置文件,在超网训练过程中,即时加载并替换原有的网络结构。
- 超网训练策略的统一性: NAS 算法中超网的训练至关重要。在超网训练过程中,统一超参数能够让我们更好地监控管理超网训练。
- 搜索算法横向比较: 在搜索空间限定的情况下,Random Search 的搜索方法可为基线,判断具体算法的效用提升,同时对于不同的子网进行评估也可支持在线测速,与查表以及代理指标的估计相比,更加准确稳定。
图 6.One-Shot-NAS 算法流水线
基于上述算法流水线,研究员可设计更加有效的搜索空间,并且可以测试避免搜索空间影响的搜索算法,同时将繁琐的超参数调整协同。目前,商汤内部算法库为不同 NAS 算法的比较提供了一个相对公平的基准。
以超网络训练策略设计以及测速接口举例,以下将说明超网训练的算法是如何嵌入到算法框架来保证业务框架不受太复杂的侵入性:
* 超网训练: 将原来的 optimizer_config 替换为 Controller
optimizer_config = dict( type='BigNasControllerHook', subnets_sampler=dict( type='StateslessSubnetsSampler', strategy='sandwish4'), grad_clip=None, iter_controller=dict( loss_name='loss',))
由于 mmcv 中的 Runner 对整个训练过程的控制固定了一些模式,牺牲了一些灵活性,这里的 ControllerHook 实际对应着里面的 OptimizerHook,并在原来的基础上增加了两个部分:subnets_sampler 用于控制在每次迭代中如何采样子网络,iter_contoller 用于控制如何使用子网络,并将 subnets_sampler 中采样的 mode 以 model_tag 字段传递到用户用于进行特定的控制。
* 搜索算法以及评估:
# GeneticFinder
search_find_cfg = dict(
type='GeneticFinder',
genetic_config=dict(
topk=10,
population_size=50,
total_epochs=50,
rand_epochs=25,
gen_trial_limit=100),
searcher_config=dict(mutate_prob=0.1),
accuracy_config=dict(descend=True),
# latency
resource_config=dict(
ref_resource_range=[0.7, 1.02],
resource_type='latency',
input_dims=4,
input_channel=1,
evaluator=dict(
type='NaiveEvaluator',
latency_eval_cfg={
'transform': {
'type': 'SketchParrots2Caffe',
'input_shape': (1, 3, 224, 224),
'filename': 'test',
'backend': 'ppl-caffe',
'repeat_num': 10,
'update': True,
'other_args': '',
},
'platform': {
'type': 'SKETCH_ANDROID_ARMV7',
'ip': '10.158.136.15',
'port': '2222',
'username': 'root',
'password': 'admin'
}
})),
save_dir=save_find_result_dir,
reward_attr='accuracy_top-1',
seed=0)
搜索算法横向比较也可进行配置。在以下配置文件中,GeneticFinder 是遗传算法,通过配置文件的参数,可控制其遗传、变异等逻辑的控制。其中,当 resource_type 为 latency 时,将采用速度评测对模型进行筛选,在搜索模型阶段可实时的获取到当前模型在目标平台的 latency。目前支持获取模型级别的 latency。
## 4 结语
本文是网络结构搜索系列文章中的第一篇。网络结构搜索是 AutoML 领域一个火热的方向,有意义的工作层出不穷,笔者所在的团队积极研究相关的落地算法并进行实现,研究方向不仅限于分类检测,还有关于网络结构搜索以及硬件适配等相关的课题。欢迎持续关注 AI 框架技术分享模型 AutoML 专题系列。
在本系列文章中,将讨论网络结构搜索领域目前存在的几个问题以及现阶段的解决方案。以下话题如果有感兴趣的小伙伴到评论区催更,很快就会有下一篇。
* 在搜索空间指数级增长的情况下,如何更加高效快速的进行网络结构搜索和评估;
* 针对搜索空间的设计理论以及在模型放缩情况下对推理时延的影响进行分析;
* 如何结合实际业务搭建协同统一性的网络结构搜索框架;
* 在排除各类涨点技巧后,如何合理地衡量各种搜索策略算法在不同搜索空间下的真实作用;
* 无监督网络结构搜索的趋势以及上手网络结构搜索领域的注意事项;
* 从 Autogluon、PyGlove、Retiarii 思考自动机器学习框架在搜索空间上的设计思想;
- ……
PS:欢迎大家关注AI框架技术分享专栏内容,如果有感兴趣的技术内容和难点欢迎随时指出,可以多多评论留言。我们也希望能通过本次技术分享让大家了解到更多的AI框架前沿技术,也期待和大家一起探讨,更欢迎大家加入我们,一同为AI框架及AI发展贡献力量!简历直投邮箱:parrotshr@sensetime.com
引用
- [1] Enzo, Leiva-Aravena, Eduardo, et al. Neural Architecture Search with Reinforcement Learning[J]. Science of the Total Environment, 2019.
- [2] Zoph B , Vasudevan V , Shlens J , et al. Learning Transferable Architectures for Scalable Image Recognition[J]. 2017.
- [3] Real E , Aggarwal A , Huang Y , et al. Regularized Evolution for Image Classifier Architecture Search[J]. Proceedings of the AAAI Conference on Artificial Intelligence, 2018, 33.
- [4] Mundt M , Majumder S , Murali S , et al. Meta-learning Convolutional Neural Architectures for Multi-target Concrete Defect Classification with the COncrete DEfect BRidge IMage Dataset[J]. IEEE, 2019.
- [5] Zhong Z , Yang Z , Deng B , et al. BlockQNN: Efficient Block-wise Neural Network Architecture Generation[J]. IEEE Transactions on Pattern Analysis and Machine Intelligence, 2020, PP(99):1-1.
- [6] Liu C , Zoph B , Neumann M , et al. Progressive Neural Architecture Search[J]. 2017.
- [7] Pham H , Guan M Y , Zoph B , et al. Efficient Neural Architecture Search via Parameter Sharing[J]. 2018.
- [8] Liu H , Simonyan K , Yang Y . DARTS: Differentiable Architecture Search[J]. 2018.
- [9] Wang C , Rui Y , Wei T . Network Morphism[J]. 2018.
- [10] Tan M , Chen B , Pang R , et al. MnasNet: Platform-Aware Neural Architecture Search for Mobile[J]. 2018.
- [11] R. J. Williams. Reinforcement-learning connectionist systems. College of Computer Science, Northeastern University, 1987.
- [12] R. J. Williams. Simple statistical gradient-following algorithms for connectionist reinforcement learning. Machine learning, 8(3-4):229–256, 1992.
- [13] Going Deeper Into Reinforcement Learning: Fundamentals of Policy Gradients
感谢阅读,欢迎在评论区留言讨论哦~
P.S. 如果喜欢本篇文章,请多多 赞同、喜欢、评论、收藏,让更多的人看见我们 :D
关注 公众号「SenseParrots」,获取人工智能框架前沿业界动态与技术思考。