神经架构搜索基础

神经架构搜索(Neural Architecture Search, NAS)的目标是在给定的搜索空间中,自动发现性能最优或接近最优的神经网络架构。NAS由三要素构成:搜索空间(Search Space)、搜索策略(Search Strategy)和评估策略(Evaluation Strategy)。1


1. 搜索空间定义

搜索空间定义了NAS可以探索的所有候选架构的集合。

1.1 基本结构类型

链式结构

最简单的架构形式,层按顺序堆叠:

输入 → Layer1 → Layer2 → ... → LayerN → 输出

数学表示为:

其中 为激活函数, 为第 层的权重矩阵。

多分支结构

引入跳跃连接(skip connection),允许特征融合:

          ↘ Layer2 → Add →
Input → Layer1 → Layer3 → ... → Output
          ↗              ↗

典型代表:ResNet的残差连接、DenseNet的密集连接。

细胞结构(Cell Structure)

NASNet2提出的革命性设计:将复杂网络分解为正常细胞(Normal Cell)缩减细胞(Reduction Cell)

Normal Cell:      保持空间分辨率
Reduction Cell:   空间分辨率减半

每个细胞内部包含 个节点的有向无环图(DAG),节点间通过操作连接。

1.2 搜索空间参数化

设搜索空间 由以下要素定义:

要素选项
操作集 conv_3x3, conv_5x5, max_pool, skip_connect, sep_conv_3x3, sep_conv_5x5
节点数 每个细胞的节点数
边连接全连接、稀疏连接
通道数固定、搜索
输入分辨率固定、弹性

DAG表示:一个细胞可表示为 个节点的有向图,每个节点 的特征 为:

其中 是从节点 到节点 的操作。

1.3 搜索空间大小分析

假设每个节点有 种操作可选,共有 条可能的边,则候选架构数:

以NASNet的搜索空间为例:

  • 节点数
  • 边数
  • 操作数

这解释了为何需要高效的搜索策略。


2. 搜索策略

2.1 强化学习方法

控制器网络

NASNet2使用RNN控制器预测网络架构:

class Controller(nn.Module):
    """RNN控制器预测架构编码"""
    def __init__(self, num_ops, hidden_size=64):
        super().__init__()
        self.rnn = nn.LSTM(
            input_size=hidden_size,
            hidden_size=hidden_size,
            num_layers=2
        )
        self.fc = nn.Linear(hidden_size, num_ops)
    
    def forward(self, embedded_input, hidden=None):
        output, hidden = self.rnn(embedded_input, hidden)
        logits = self.fc(output)
        return logits, hidden
    
    def sample_architecture(self):
        """采样一个架构"""
        arch_codes = []
        hidden = None
        for _ in range(num_layers):
            logits, hidden = self.rnn(self.embed, hidden)
            probs = F.softmax(logits, dim=-1)
            op_idx = torch.multinomial(probs, 1).item()
            arch_codes.append(op_idx)
        return arch_codes

奖励函数设计

其中 为架构 的验证准确率。

训练过程

  1. 控制器采样架构
  2. 训练架构 得到验证准确率
  3. 使用策略梯度更新控制器:

2.2 进化算法

基本框架

初始化: 生成初始种群 P
迭代:
    1. 选择: 从P中选择父代
    2. 变异: 对父代进行操作变异
    3. 评估: 评估子代适应度
    4. 更新: 替换种群中的个体
终止: 达到终止条件

操作符定义

操作类型描述示例
变异随机改变一条边conv_3x3 → conv_5x5
添加边添加新连接无连接 → skip_connect
删除边移除现有连接skip_connect → 无
添加节点在现有节点间插入-
改变通道数调整通道宽度64 → 128

NSGA-Net算法

NSGA-Net3使用NSGA-II框架同时优化多个目标:

class EvolutionSearch:
    def __init__(self, pop_size=20, n_gens=50):
        self.pop_size = pop_size
        self.n_gens = n_gens
        self.history = []
    
    def mutate(self, parent):
        """架构变异操作"""
        child = copy.deepcopy(parent)
        op = random.choice(['mutate_op', 'add_edge', 'remove_edge'])
        
        if op == 'mutate_op':
            # 随机选择一个边,改变其操作
            edge = random.choice(list(child.edges))
            ops = [op for op in OPS if op != child.get_op(edge)]
            child.set_op(edge, random.choice(ops))
        
        elif op == 'add_edge':
            # 添加新边
            child.add_random_edge()
        
        return child
    
    def select_parents(self, population, fitness):
        """锦标赛选择"""
        indices = random.sample(range(len(population)), k=2)
        winner_idx = indices[0] if fitness[indices[0]] > fitness[indices[1]] else indices[1]
        return population[winner_idx]

2.3 贝叶斯优化

高斯过程代理

使用高斯过程(GP)建模架构-性能映射:

采集函数(Acquisition Function):

函数公式特点
UCB平衡探索与利用
EI期望改进
PI概率改进

BOHB算法

BOHB(Bayesian Optimization with Hyperband)4结合贝叶斯优化与Hyperband早停:

class BOHB:
    def __init__(self, config_space, eta=3):
        self.config_space = config_space
        self.eta = eta  # 早停缩减因子
        self.trial_generator = TrialGenerator(config_space)
    
    def suggest(self):
        """基于GP模型建议下一个配置"""
        # 使用贝叶斯优化选择配置
        configs = self.trial_generator.generate_candidates(k=20)
        scores = [self.gp.predict(cfg) for cfg in configs]
        return configs[np.argmax(scores)]
    
    def observe(self, config, reward):
        """更新GP模型"""
        self.gp.update(config, reward)

2.4 梯度方法

详见 DARTS可微架构搜索


3. 评估策略

3.1 完整训练评估

传统方法:对每个候选架构完整训练至收敛。

问题:计算代价极高。以搜索空间大小 为例,即使每次训练仅需1小时,总训练时间也超过 年。

3.2 权重共享机制

ENAS(Efficient NAS)5提出的核心思想:所有候选架构共享一组权重

超网络构建

class SuperNet(nn.Module):
    """超网络,包含所有可能的路径"""
    def __init__(self, num_nodes, num_ops):
        super().__init__()
        self.num_nodes = num_nodes
        # 每个边有num_ops个可选操作,每种操作有独立权重
        self.edge_weights = nn.ParameterList([
            nn.Parameter(torch.randn(num_ops, C_in, C_out) / sqrt(C_in))
            for _ in range(num_edges)
        ])
    
    def forward(self, inputs, architecture):
        """基于架构编码前向传播"""
        nodes = [inputs]
        for node_idx in range(1, self.num_nodes):
            node_value = 0
            for prev_idx in range(node_idx):
                edge_idx = get_edge_idx(prev_idx, node_idx, architecture)
                op_idx = architecture[edge_idx]
                node_value += F.relu(
                    torch.einsum('bic,co->bio', nodes[prev_idx], 
                                self.edge_weights[edge_idx][op_idx])
                )
            nodes.append(node_value)
        return nodes[-1]

权重更新

其中 为架构 对应的权重, 为采样子架构集。

3.3 代理指标评估

使用无需训练的指标快速评估架构:

指标类型代表方法计算复杂度
参数相关参数量、FLOPs
梯度相关SNIP、GraSP
信息论熵、互信息
随机预言随机权重精度

详见 免训练NAS


4. 多目标优化

4.1 Pareto最优性

当存在多个优化目标时,引入Pareto最优概念:

定义:架构 是Pareto最优的,当且仅当不存在架构 使得:

其中至少一个是严格不等式。

Pareto前沿:所有Pareto最优解构成的集合。

4.2 优化方法

加权求和法

问题:无法发现非凸Pareto前沿。

NSGA-III

NSGA-III6使用参考点方法处理多目标:

class NSGA_III:
    def __init__(self, n_objectives, n_ref_points):
        self.n_objectives = n_objectives
        self.reference_points = self.generate_reference_points(n_ref_points)
    
    def niching_selection(self, combined_pop, n_select):
        """基于参考点的选择"""
        # 计算每个个体到参考点的距离
        distances = self.compute_perpendicular_distances(combined_pop)
        # 选择最近的参考点对应的个体
        selected = self.select_closest_to_reference_points(
            combined_pop, distances, n_select
        )
        return selected

5. NAS关键挑战

5.1 搜索-评估差距

搜索过程中评估的架构与最终部署架构性能不一致:

问题原因解决方案
权重初始化影响不同架构权重初始化不同预训练超网络
过拟合搜索空间过拟合训练集正则化、验证集
早停误差早停评估不准确延长训练、代理指标

5.2 可复现性问题

NAS结果的可复现性较低,主要原因:

  1. 随机性:初始化、采样、变异
  2. 硬件差异:浮点精度、并行化
  3. 超参数敏感:学习率、批量大小
  4. 环境依赖:库版本、CUDA版本

解决方案:NAS-Bench基准测试库(详见 NAS基准测试)。

5.3 扩展性问题

问题描述研究方向
搜索空间指数增长边数/操作数增加导致空间指数爆炸层次化搜索、模块化
评估成本大规模网络训练成本高早停、知识蒸馏
多任务迁移搜索结果难以迁移到不同任务任务无关表示

6. 实践指南

6.1 何时使用NAS

适合场景

  • 计算资源充足(>100 GPU days)
  • 搜索空间定义清晰
  • 目标硬件明确
  • 需要超越人工设计的最优结果

不适合场景

  • 小规模数据集(可能过拟合搜索空间)
  • 快速原型开发(NAS开销过大)
  • 资源受限环境(建议使用 现成的高效架构

6.2 推荐工作流

┌─────────────────────────────────────────────────────────┐
│                    NAS工作流程                           │
├─────────────────────────────────────────────────────────┤
│ 1. 明确需求                                             │
│    - 任务类型(分类/检测/分割)                          │
│    - 约束条件(延迟/参数量/FLOPs)                       │
│    - 部署环境(GPU/移动端/嵌入式)                       │
│                                                         │
│ 2. 定义搜索空间                                         │
│    - 选择基础操作集                                      │
│    - 确定网络深度/宽度范围                                │
│    - 设计细胞结构或层次化模式                             │
│                                                         │
│ 3. 选择搜索策略                                         │
│    - 资源充足 → DARTS/进化算法                          │
│    - 资源受限 → 免训练NAS                               │
│    - 多目标 → NSGA-III                                 │
│                                                         │
│ 4. 评估与选择                                           │
│    - 多指标Pareto最优                                   │
│    - 完整训练验证                                       │
│    - 目标硬件实测                                       │
└─────────────────────────────────────────────────────────┘

参考文献

Footnotes

  1. Elsken T, Metzen JH, Hutter F. Neural Architecture Search: A Survey. JMLR 2019.

  2. Zoph B, Vasudevan V, Shlens J, Le QV. Learning Transferable Architectures for Scalable Image Recognition. CVPR 2018. 2

  3. Lu ZY, et al. NSGA-Net: Neural Architecture Search using Multi-objective Genetic Algorithm. GECCO 2020.

  4. Falkner S, Klein A, Hutter F. BOHB: Robust and Efficient Hyperparameter Optimization at Scale. ICML 2018.

  5. Pham H, et al. Efficient Neural Architecture Search via Parameters Sharing. ICML 2018.

  6. Deb K, Jain H. An Evolutionary Many-Objective Optimization Algorithm Using Reference-Point-Based Nondominated Sorting Approach. IEEE TEVC 2014.