DARTS:可微分架构搜索的算法与实践

FreeGuideOnline 最新 2026-06-21

DARTS:可微分架构搜索的算法与实践

什么是 DARTS?

DARTS(Differentiable Architecture Search)是一种将神经网络架构搜索(NAS)问题从离散搜索空间转换为连续优化空间的方法。它通过将候选操作(如卷积核大小、池化、跳跃连接等)的“选择”松弛为所有可能操作的加权和,并让这些权重通过梯度下降与网络权重共同优化,从而大幅提高搜索效率。DARTS 能够在单卡 GPU 上仅用数小时完成一次搜索,相比早期基于强化学习或进化算法的方法(需要数千 GPU 小时),效率提升了数个量级。

神经网络架构搜索背景

传统 NAS 的挑战

手工设计神经网络(如 ResNet、Transformer)需要大量专家经验和反复实验。NAS 旨在自动化这一过程,将架构设计问题形式化为:

  • 搜索空间:定义可选的网络组件(如卷积层、池化层、连接方式)。
  • 搜索策略:在搜索空间中寻找最优架构(如强化学习、进化算法、贝叶斯优化)。
  • 性能评估策略:评估候选架构的性能(通常是训练到收敛后验证准确率)。

早期方法如 NASNet 和 ENAS 使用 RNN 控制器生成架构描述,通过强化学习更新控制器,但评估每个候选架构需要从头完整训练,计算成本极高。

权重共享与加速搜索

为降低评估成本,ENAS(Efficient NAS)提出在搜索过程中共享子模型的权重,无需每次从头训练。DARTS 进一步将离散的架构选择连续化,实现在同一个超网络中通过梯度下降同时优化网络权重和架构参数。

DARTS 核心思想:可微分松弛

搜索空间定义(以 CNN 单元为例)

DARTS 搜索的是计算单元(cell),而不是整个网络。一个 cell 是一个有向无环图(DAG),包含 N 个节点,每个节点代表一个特征图,有向边代表某种操作(operation)。目标是为每条边选择最佳操作。

常见操作集合 O(以卷积 cell 为例):

  • 3×3 可分离卷积
  • 5×5 可分离卷积
  • 3×3 空洞卷积
  • 3×3 最大池化
  • 3×3 平均池化
  • 跳跃连接(skip connect)
  • 无连接(zero)

连续松弛(Continuous Relaxation)

核心创新:将离散的操作选择松弛为在所有可能操作上的 softmax 混合。 对于从节点 i 到节点 j 的边,其操作不再是固定的,而是对所有操作 o ∈ O 的加权组合:

o^{ (i,j) }(x) = Σ_{ o∈O }  (exp(α_o^{(i,j)}) / Σ_{ o'∈O } exp(α_{ o' }^{ (i,j) })) ・ o(x)

其中 x 是节点 i 的输出,α_o^{ (i,j) } 是与操作 o 相关联的架构参数,通过 softmax 得到该操作的混合权重。

这样,原本离散的搜索空间变成了关于连续参数 α 的优化问题。整个搜索空间被编码到所有边的架构参数 α = {α^{(i,j)}} 中。

双层优化(Bi-level Optimization)

我们希望找到最优的架构参数 α,使得在验证集上损失最小;同时对于给定的 α,网络权重 w 能通过训练集损失最小化。形式化描述为:

min_α  L_val(w*(α), α)
s.t.   w*(α) = argmin_w  L_train(w, α)

这是一个典型的双层优化问题,α 为上层变量,w 为下层变量。

近似迭代优化算法

直接求解双层优化计算成本高,DARTS 采用近似迭代方法:

  1. 使用当前 α,通过一步梯度下降近似更新 w:w' = w - ξ ∇_w L_train(w, α)
  2. 利用 w' 计算验证集损失对 α 的梯度,更新 α:α ← α - η ∇_α L_val(w', α)
  3. 重复直到收敛。

这种近似避免了内层优化的完整收敛,且经验表明效果良好。具体实现中,通常在一小批训练数据上更新 w,在另一小批验证数据上更新 α,实现交替优化。

DARTS 搜索流程

整体步骤

  1. 构建过参数化网络:按照 cell 结构构建有向图,所有边包含所有候选操作的混合(混合操作)。
  2. 双层优化训练:在训练集上优化网络权重 w,在验证集上优化架构参数 α,交替进行直至收敛或达到预设 epoch。
  3. 离散化得到最终架构:优化完成后,为每条边选择 softmax 权重最大的操作(保留 top-k 个最强边),得到离散 cell。
  4. 重新训练:用搜索到的 cell 堆叠构建完整网络,从头训练,评估最终性能。

连续松弛的反向传播

混合操作中每个操作 o(x) 的输出被 softmax 权重加权求和,因此梯度可以反向传播到架构参数 α 和网络权重 w。这使得搜索过程可以端到端地使用标准深度学习框架(如 PyTorch)完成。

实践:实现 DARTS 的关键步骤

以下以简化版的 CNN cell 搜索为例说明实现要点(伪代码)。

定义混合操作(MixedOp)

class MixedOp(nn.Module):
    def __init__(self, C, stride):
        super().__init__()
        self._ops = nn.ModuleList()
        for op_name in PRIMITIVES:
            op = OPS[op_name](C, stride, False)
            self._ops.append(op)

    def forward(self, x, weights):
        # weights: 经过 softmax 的 α
        return sum(w * op(x) for w, op in zip(weights, self._ops))

定义 Cell 结构

class Cell(nn.Module):
    def __init__(self, steps, multiplier, C_prev_prev, C_prev, C, reduction):
        super().__init__()
        # 对每一对节点 (i,j), i<j, 创建 MixedOp
        self._ops = nn.ModuleList()
        for i in range(steps):
            for j in range(2+i, steps+2):
                op = MixedOp(C, stride=...)
                self._ops.append(op)

    def forward(self, s0, s1, weights):
        # weights: 所有边的架构权重
        states = [s0, s1]
        offset = 0
        for i in range(self._steps):
            s = sum(self._ops[offset+j](h, weights[offset+j]) for j, h in enumerate(states))
            offset += len(states)
            states.append(s)
        return torch.cat(states[-self._multiplier:], dim=1)

架构参数 α 的初始化和优化

  • α 初始化为每个操作等概率(给予少量噪声)或全部为 0。
  • 优化器:Adam(对 w)和 Adam(对 α),学习率可以不同。
  • 损失:loss_train = criterion(model(x_train), y_train)loss_val = criterion(model(x_val), y_val)
  • 一步更新 w:
    w_optim.zero_grad()
    loss_train.backward()
    w_optim.step()
    
  • 更新 α:
    arch_optim.zero_grad()
    loss_val.backward()
    arch_optim.step()
    

离散化与最终架构导出

搜索结束后,对于每个中间节点,保留来自两个前驱节点的最强操作(根据 softmax 权重)。例如节点 j,检查所有 i<j 的边 (i,j),选取 softmax 权重最大的 k=2 条边(DARTS 默认取 2),并将对应的操作固定下来。这样就得到一个离散的 cell。

实验结果与讨论

原始 DARTS 在 CIFAR-10 和 ImageNet 上取得了极具竞争力的结果:

  • 搜索代价:0.4 GPU days(单卡 1080Ti)
  • CIFAR-10 错误率:2.76%(与当时最先进的模型相当,且参数更少)
  • 迁移到 ImageNet:在 mobile setting 下 top-1 错误率 26.7%,与 NASNet 相当而搜索成本低数百倍。

搜索到的 cell 展现出有趣的结构:跳跃连接非常流行,且网络深度较浅时更倾向于选择卷积,在较深层次时跳跃连接占比增大,这反映了梯度传播的有效策略。

DARTS 的优点与局限性

优点

  • 搜索效率极高:从数千 GPU 小时降至单卡数小时,使 NAS 研究民主化。
  • 端到端可微:直接利用梯度优化,与深度学习生态系统完美兼容。
  • 可扩展:可自然应用于不同的搜索空间(如 RNN、Transformer 的 cell 搜索)。
  • 发现的架构具有可解释的结构模式

局限性

  1. 搜索与评估的不一致:连续混合操作在搜索时存在,但离散化后丢弃了部分操作,可能导致性能落差。
  2. 架构参数 α 的过拟合与 skip-connect 主导:深层搜索时,跳跃连接权重常呈现不健康的增长,导致最终架构深度很浅,性能下降。这是著名的“跳跃连接富集”问题。
  3. 内存和计算与候选操作数量线性增长:当操作集合变大时,显存占用成为瓶颈。
  4. 搜索空间离散化时的启发式选择:保留最强边的策略可能次优。
  5. 对超参数(如学习率、权重衰减)敏感

后续工作与变体

P-DARTS(渐进式 DARTS)

逐步增加搜索深度并正则化 skip-connect,以缓解跳跃连接富集问题。通过搜索深度的渐进增长发现更深且高性能的架构。

DARTS+(稳健 DARTS)

引入早停机制,当两个领先操作的权重差距足够大(或多条边中 skip-connect 权重超过阈值)时提前停止搜索,避免退化。

PC-DARTS(部分通道连接)

通过只采样一部分通道进行混合操作计算,大幅降低内存消耗,使得搜索可以扩展到更大数据集和更多操作,同时通过边归一化缓解跳跃连接富集。

Other gradients-based methods

  • GDAS:采用 Gumbel-Softmax 采样离散操作,在搜索时即离散化,减少不一致性。
  • SNAS:引入随机神经网络中的策略梯度,使搜索更稳定。
  • DrNAS:使用狄利克雷分布建模架构参数,改善优化稳定性。

总结

DARTS 通过可微分架构松弛和双层优化的巧妙结合,将 NAS 从计算密集型任务转变为轻量级梯度优化问题,极大地推动了自动机器学习的研究与应用。尽管它仍存在一些固有问题(如 skip-connect 偏好),但其核心思想为后续众多高效 NAS 方法奠定了基础。对于希望入门 NAS 的实践者,DARTS 是理解梯度驱动架构搜索的绝佳起点。

参考资源

  • 原始论文:Liu, H., Simonyan, K., & Yang, Y. (2019). DARTS: Differentiable Architecture Search. ICLR.
  • 开源实现:https://github.com/quark0/darts (PyTorch 官方实现)