《NAS Neural Architecture Search》

NAS

本文的宗旨是对NAS有一个感性的认知,对具体算法的细节可以慢慢补充

  • 组成部分
    • 搜索空间 Search Space
    • 策略 Action/Decision
      • 我们需要一个Controller去从Search Space中采样出优秀的架构
    • 策略评估
      • 需要一个Evaluator来评估获得的架构效果如何,我们希望它尽量快
    • 迭代Decision和Evaluation直到得出最后结果
  • 搜索空间: 包含了对NN的结构定义(有多少哪些层和他们的类型 / 层内的超参数(NxN卷积) / 前驱节点和后续节点直接链接关系(add/Concat)
    • 对搜索空间进行限制以提升速度 (切分为基本单元Cell或者Block)
    • 由于搜索空间是离散的,且搜索空间很大,无法得到一个显示的优化函数,所以是一个黑盒问题
  • 搜索策略(做出决策) - 本质上是一个超参数优化的问题
    • 随机搜索
    • 贝叶斯搜索
    • RL
      • Agent(Controller)完成对网络的结构设计,输出的(Action)是网络结构,Reward是性能最优化
      • 由于结构参数长度不固定,可以用RNN来建模
      • Exmaple: NASNet:预测出基本Block,将预测的Block分为普通(不改变输出结构)以及简约(减少输出尺寸)
      • Example:ENAS: Shared Weights来加速
    • 遗传算法 (Mutation-Based)
      • 将网络结构编码成二进制串(首先分为几个Stage,再在下面分为Node),首先随机若干个初始解,训练所有子网络,计算适应值,随机选择结构交叉,产生后代
      • 在初始化/样本选择/交叉/变异等多个子方向都有改进空间
    • 基于梯度的方法
      • 将离散问题连续化,更好的利用梯度信息
      • 做松弛化,将层之间的链接从0-1松弛为一定概率
      • Exmaple:DARTS,将网络单元表示为有向无环图,可以在搜索架构的同时获得结构参数
  • 策略评估
    • 核心目标:减少训练轮数
    • Example:
      • 在一个小的集(比如降采样的图像)上进行训练
      • 粗训,并排序(有错误可能)
      • 对结果进行预测(外推Extrapolation)
      • Weight-Sharing,避免TrainFromScratch

Paper Reading

  1. NAS with RL - Google Brain
    • 真的很早,算是开端了
    • 比cifar10上的baseline提了0.1个点,并且快了一丢丢1.05,以及其他的dataset-PennTreebank以及language modeling的task
    • 建立在认为NN的connectivity和structure可以被表达成一个variable-length string(可用RNN做embedding,也就是作为controller)
    • 将采样(RNN生成)出来的子架构进行训练,将Acc作为reward信号,通过Policy Gradient的方式回传去update controller(Original RNN) * 在relatedwork中讲到
    • hyper-param optimization只能够做到在fixed-length的space进行模型优化,且对good initial model比较依赖
    • Bayesian方法可以寻找一个“不定长”的架构,但是不是很有意义 * The controller in Neural Architecture Search is auto-regressive, which means it predicts hyperpa- rameters one a time, conditioned on previous predictions. This idea is borrowed from the decoder in end-to-end sequence to sequence learning. * search space
    • * RNN
    • 将RNN看作一个树的结构 * 不是这是不是语法错误…
  2. Accelerating NAS using performance prediction
    • 核心在于提出predictor来加速evaluation
    • 还搭了一个early stopping * 认为human是从training curve来观察的,本文parameterize了这个过程,训练regression model来预测acc * 对应的counterpart是Bayesian的一些方法
    • 目测是人工设计一些拟合learning curve的base function,然后用expensive的MCMC来拟合
    • 也有用高斯过程核函数的 * 说白了建模的是Training Curve
    • 输出val acc,输入是configuration,在每个time step
    • 做了一个SRM(Sequential Regression model)比如RBM,RandomForest等
  3. eNAS - Efficient Architecture Search by Network Transformation
    • Reusing Weight(Weight Manager)不需要from scratch来训练网络
    • metacontroller采样架构based on Network transformation
    • 依然是Rl Controller - Policy Gradient更新,其action是指导transformation
    • 网络的结构encoder依然是一个Bi-LSTM
    • (也可以认为是muation-based,不过指导mutation产生的不是遗传或者SA这类heuristic的方法,但是是RL-Agent)
      • 有两种Actor形式,Net2Wider或者Net2Deeper
      • Wider用一个公用的sigmoid分类器来生成反馈信息,确定是否在该时刻需要expand
      • Net2Deeper则是是否需要insert一个新的layer
      • Deeper用一个RNN来建模是否需要在某个位置插入一个新层
      • 可以插入新层的位置是预先固定的,依据pooling层的位置把网络分成几个block
  4. BOGCN - Multi-Object Neural Architecture Search via Predictive Network Performance Optimzation
    • Improving Sample Efficiency for Multi-Object
      • multi-object指的是speed-acc trade off
    • Bayesian Opt + GCN
      • BO(Bayesian Optimization) - finding global optim of black-box
      • 用GCN换了原本的BO中的GP,as surrogate of the objective function
        • gp是本身是self-conjugate的,因为其输入和输出同分布
        • 将GCN后面的一些fc层,换成了BLR(Bayesian Linear Regression)
      • GCN的优势在于能够更好的embed图的信息,以及能够处理变长节点
      • GCN只extract network embedding
    • One-shot NAS采用了weight sharing,但是不能保证optimal;Sample-based的更加稳定但是很慢
  5. Learning Transferable Architectures for Scalable Image Recognition
    • Cell-based Search Space (NASNet SS) * Convolutional Blocks Repeated many times * 一般分成N个Normal Cellh后面接一个Reduction Cell
    • Regularization Technique - Schedule Drop Path * 基于RNN的Controller
  6. SMASH: One-Shot Model Architecture Search through HyperNetworks
    • one-shot表示从一个HyperNet中取出架构,不需要training作evaluation,采用weight sharing
    • HyperNet - Training an auxiliary HyperNet to generate weights
      • 加速arch selection
      • 从binary coded到optimal architecture weights的mapping,只训练output layer(?)
      • 其训练是用gardient-based的方式来做到的
    • 选取arch来evluate的方式
      • Memory-bank view,将其作为binary vector
      • 是否意味着会遍历整个search space?
    • 文章中提到了说训练一个arch开始的部分是整体acc的一个insight
      • 一般的方法把arch的perf看作一个black box,用BO或者rs去搜索,也有early-stopping这样的策略
    • 能够抛弃其他所有的hyper-param以及dynamic-regulariaztion的东西
      • 比如lr schedule
      • 比如DropPath之类的东西
  7. Hierarchical Representations for Efficient Architecture Search
    • EA-based
    • hierarchical genetic representation
    • 模仿的是modularized design pattern * 采用了EA,指出最naive的random search也可以获得不错的效果 * flat representation - 将NN作为一个DAG
    • 小的graph motif组成一个大的graph motif
    • * Tournament Selection Search
  8. PNAS - Progressive Neural Architecture Search
    • NO RL or EA, Sequential-Model-Based Method
    • 内部也含了一个predictor
    • LSTM as encoder * Progressive (Simple 2 Complex)
    • Simpler Arch train faster * Cell-based Search Space
  9. Efficient Neural Architecture Search via Parameter Sharing
    • Shared-Weights
    • Controller在一个庞大的Compuation Graph上搜索Subgraph作为子图
    • 对于child modules Share Parameter
      * RNN Controller
      • 采样出链接关系
      • 以及node是什么
    • 这个controller是怎么训练的?
      • Policy Gradient?
  10. DARTS
    • 将原先的离散搜索,改为Differentiable方式(Relax the Search space to be Differentiable)
    • 核心在于如何修改Search Space * Search Space如何设计
    • 一个Cell是一个DAG,Node是一个latent representation(代表Feature Map),每个有向的边和某种操作(Op)有关
      • 每个op以softmax来relax,取各个实际操作(Max-pool/Conv/No)发生的概率
    • 认为每个cell有两个输入一个输出,对卷积层输入来自previous 2 layer(? 2度近邻居?)
    • N=7 Node,没有strided * Bi-level Optimization
    • Learn Arch and Weight at the same time
    • 注意实际对alpha导数是用的,而不是单纯的 partial{L_val}/partrial{alpha}
      • *
  11. NAS Survey

  12. NAO-Neural Architecture Optimization
    • Discrete -> Continuos
      • 包含了一个encoder,将arch映射到一个连续空间,同时还搭配一个decoder
      • 还有predictor
    • 与此类似的是DARTS,说DARTS认为最好的arch是当前weight下的argmax,而NAO直接用一个decoder映射回模型
      • 还有一支是Bayesian Optimization,作者认为GP的性能于Covariance Function的设计强相关
    • Search Space设计
      • 两步,首先决定1)which 2 previous nodes as inputs 2)确定要用什么op
    • symmetric的design:为了保证symmetric的模型(实际上是一个模型)的embedding一致,predictor给出差不多的结果
      • 用了Augmentation(flip)来训练encoder
    • Encoder和Decoder都是LSTM,predictor是一个mean-pooling加mlp
    • 三者Jointly Train
      • 认为predictor could work as regularization去避免encoder只对应decoder的结果,而没有正常表征
        • 这一步和传统VAE中的加noise一致
    • 认为weight-sharing和NAO是complementary的
  13. SNAS-Stochastic NAS

  14. SemiNAS
    • 用Controller(其实是里面的predictor)去在大量无标注的arch上做标注(不经过Evaluation),将新的Data-Pair加入训练
    • 卖点是能够更快的找到比较好的架构,比EA之类的效率更高
      • 但是高的也不是很明显,怀疑是否是NAO带来的而不是Semi带来的(毕竟用自己推断出来的数据来训练自己(但是flow与Self-Supervised又不太一样))
    • 用NAO as example(因为它既可以用在conventional train from scratch也可以做Weight sharing)

## Baselines

AW_NAS

  • ROOT下的base.py定义了MetaClass Components供其他类实现
    • Component包含了:
      • 有Logger
      • 有Set/Get State
      • 以及config
  • ROOT下的Plugin.py ❓ 管理诸如controller/dataset/evaluator取什么组件的,或者说是用来Manage各个Module的?

Search Space

实现了一些具体的SearchSpace

  • common.py 中包括了对SearchSpace相关的一些定义
    • SearchSpace <== CellSearchpace <== CNN/RNNSearchSpace
      • 提供了init和一些get以及plot方法
    • 包含了CNN和RNN的
    • (没有实现Hierarchy)

Datasets

从Dataset中取数,实现了一个DataSet类

  • BaseDataSet <== Cifar/ImageNet
    • 实现了一些split/get_name等方法
  • ❓:PTB.py - 看上去是维护了一些语料库?(为什么要这么封装)

Rollout

含义是NetworkStructure的一个编码,是Conreoller/WeightManager/Trainer都需要的一个InterfaceClass,跨组件之间交流的对象

  • 其中__init__.py内调用了Utils当中的expect方法,列举了每个文件中应该包含的模块
  • BaseRollout <== Rollout / DifferentiableRollout – 描述的是采样出来结构的信息
    • ❓ 一个Rollout和其SearchSapce相关(合理),但是内部为何会有RandomSample方法呢?
    • 一个Rollout包含了
      • 属性
        • arch
        • info
        • SearchSpace
        • candidate_net
      • 方法
        • random_sample_arch
        • 一些plot和get方法
        • ——– Differential 特有的 —————
          • discrete_arch_and_prob
            • 调用了parse:得到最终的DiscreteRollout
            • @Propoerty装饰器将类方法伪装为类属性(只有一个self参数),产生的原因是为了保持一个属性getter和setter方法的精简(如果不用getter/setter又暴露在外面)
    • BaseRollout中有一些抽象方法等待子类去继承
  • Dense.py内比较特殊,定义了Dense的SearchSapce以及Dense的Rollout(继承了Rollout而不是BaseRollout)
  • MNasNet同理
    • ❓ 为啥有个OFA的…
  • Mutation.py 包含了一系列与Mutation-Based相关的组件
    • objetc <== Population (物理意义上是SearchSpace的子集,Mutation中产生的模型集合)
    • CellMutation
    • BaseRollout <== MutationRollout
  • repr方法显示Obj的属性 (那我为啥还在用vars?)

Controller

  • 负责采样(Sample)出一个Neural Architecture(网络架构)
  • Component <=== BaseController
    • 属性
      • SearchSpace
      • RolloutType
      • Mode
    • 方法
      • SetMode
      • Sample(Sample a Rollout From Population(SearchSpace))
      • Step(Upadte Controller)
      • Summary / Save / Loads
  • Population.py(❓不是说没有实现吗?)
    • 包含了Mutation-Based的Agent训练方法
    • ❓文档中说包含了Bayesian方法,是否是RandomSamplerttr
      • Component <== BaseMutaionSampler <== RandomMutationSampler
        • 内部重要的是sample_mutation方法
      • BaseController <== Population Controller
        • 有一个mutation_Sampler的属性(BaseSampler)
        • ScoreFunction相关
        • ChooseParents
  • dense_controller(Unfinished)
  • BaseController/nn.Module <== DiffController
    • 属性
      • use_prob,是直接使用Probabilty还是relax Sampling
      • gumble_hard:对RelaxedVector前向使用GumbleSoftmax
      • gumble_Temperature
      • _init_nodes / edge_list
    • 方法
      • forward - 执行sample
      • Calc Gradient & Choose Loss
      • Summary
  • rl_networks.py
    • ❓ SCEDULABLE_ATTR 表示?
    • Components <== BaseRlController <== BaseLSTM <== AnchorControlNet / EmbeddedControlNet
      • 属性
        • 一些描述LSTM大小的参数
      • 方法
        • forward - Sample
  • rl_agent.py
    • Component <== BaseRLAgent
      • 属性
        • Controller
      • 方法
        • Step
    • BaseRLAgent <== PGAgent (Policy Gradient)
      • 方法
        • step / _step 方法的区别 ❓
    • BaseRLAgent <== PPOAgent (Proximal Policy Optimization)
  • rl.py
    • BaseRLAgent / nn.Module <== RLController
      • 属性
        • SearchSapce
        • RolloutType
        • ControllerNetwork
        • RLAgent
        • Mode (Train/Eval)
      • 方法
        • step - 计算loss
        • Sample - 获取Rollout

WeightManager

与Evaluator联系,因为TrainFromScratch太慢了,所以需要一定程度上ShareWeights或者以其他方式利用之前的Weights

  • base.py
    • Component <== BaseWeightManager
      • 属性
        • SearchSpace
        • RolloutType
      • 方法
        • Assemble_Candidate(via Rollout)
        • Step - Update Weight Manager Accoding to Gradients
    • nn.Module <== CandidateNet
      • Different Forward Methods
      • Get Gradient
      • Train/Eval Queue
  • share.py - **
    • BaseWeightManager / nn.Module <== SharedNet
      • ❓ use_stem?
    • SharedCell <== nn.Module
    • SharedOp <== nn.Module
  • SuperNet.py
    • CandidateNetwork <== SubCandidateNet
    • SharedNet <== SuperNet - (Cell—Based SuperNet)
  • DiffSuperNet.py
    • CandidateNet <== DiffSubCandidateNet
  • dense.py
    • BaseWeightManager <== DenseMorphismWeightManager
      • 属性
        • NoiseType
      • 方法
        • Assemble Rollout
        • add noise
        • widen
        • Deepen

Trainer

用来调和(Orchestra)整个搜索过程

  • GenoType ❓

  • async.py
    • 多进程相关
  • base.py
    • Component <== BaseTrainer
      • 属性
        • Cotroller
        • Evaluator
        • RolloutType
      • 方法
        • Setup
  • simple.py
    • BaseTrainer <== SimplerTrainer
      • _evaluator_update
      • _controller_update
      • _backward_rollout_to_controller
      • Train
      • Test
      • derive

Evaluator

用来测试Sample出来的Rollout(或者说是CandidateNetwork❓这两者是不是共同,或者说CandidateNetwork在什么时候会选择)

  • base.py
    • Component <== BaseEvaluator
      • 方法
        • Evaluate_Rollout
        • Upadte Rollout / update evaluator
  • mepa.py
  • ❓ MEPA是啥?
    • Component/nn.Module <== LearnableLROutPlaceSGD
    • BaseEvaluator <== MepaEvaluator
  • tune.py
    • BaseEvaluator <== TuneEvaluator

OPs

其中列举了一些NN Operator

  • Baseline_Ops.py
    • 一些常见网络的Block,比如VGG/MobileNet等
  • OPs.py
    • 一些自定义的Block和NN组件
      • 类似Conv-BN-Relu

Objectives

指定不同的任务的

  • ❓Perfs的全程?这个模块的意义?描述了什么东西,以及在社么场景下使用(这些问题概括下来好像就是我完全没懂这个是干啥的)

Utils

Final

原文地址:https://www.cnblogs.com/cx2016/p/12933589.html