콘텐츠로 이동
Data Prep
상세

Neural Architecture Search (신경망 구조 탐색)

메타 정보

항목 내용
분류 AutoML / Architecture Design / Optimization
핵심 논문 "Neural Architecture Search with Reinforcement Learning" (Zoph & Le, ICLR 2017), "Learning Transferable Architectures for Scalable Image Recognition" (Zoph et al., CVPR 2018, NASNet), "Efficient Neural Architecture Search via Parameter Sharing" (Pham et al., ICML 2018, ENAS), "DARTS: Differentiable Architecture Search" (Liu et al., ICLR 2019), "ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware" (Cai et al., ICLR 2019), "EfficientNet: Rethinking Model Scaling for CNNs" (Tan & Le, ICML 2019), "Once-for-All: Train One Network and Specialize it for Efficient Deployment" (Cai et al., ICLR 2020), "A Survey on Neural Architecture Search" (Elsken et al., JMLR 2019)
주요 저자 Barret Zoph (NAS 개척), Quoc V. Le (Google Brain, NAS/EfficientNet), Hanxiao Liu (DARTS), Han Cai (ProxylessNAS, OFA, MIT HAN Lab), Song Han (MIT HAN Lab, Hardware-Aware NAS), Mingxing Tan (EfficientNet/EfficientDet), Frank Hutter (NAS-Bench, Survey)
핵심 개념 사람이 수동으로 설계하던 신경망 구조(layer 수, 연결 방식, 연산 종류 등)를 자동으로 탐색하는 기법으로, 탐색 공간(Search Space), 탐색 전략(Search Strategy), 성능 추정(Performance Estimation)의 세 축으로 구성
관련 분야 Bayesian Optimization, Meta-Learning, Knowledge Distillation, Model Compression, Transfer Learning

정의

Neural Architecture Search(NAS)는 주어진 태스크와 데이터셋에 대해 최적의 신경망 구조를 자동으로 발견하는 기법이다. 전통적인 딥러닝에서는 연구자가 수동으로 네트워크 아키텍처를 설계하지만, NAS는 이 과정을 최적화 문제로 정식화하여 알고리즘이 탐색하도록 한다.

NAS는 세 가지 핵심 구성요소로 이루어진다:

  1. Search Space (탐색 공간): 탐색 가능한 아키텍처의 집합을 정의
  2. Search Strategy (탐색 전략): 탐색 공간에서 후보 아키텍처를 효율적으로 선택하는 방법
  3. Performance Estimation Strategy (성능 추정): 후보 아키텍처의 성능을 빠르게 평가하는 방법
Neural Architecture Search 프레임워크:

                 탐색 공간 (Search Space)
                 - Cell-based / Global
                 - 연산 종류, 연결 패턴
                         |
                         v
  +-------------------------------------------+
  |         탐색 전략 (Search Strategy)         |
  |                                           |
  | RL-based   Evolutionary   Gradient-based  |
  | (NASNet)   (AmoebaNet)    (DARTS)         |
  |                                           |
  |         One-Shot / Weight Sharing          |
  |         (ENAS, SuperNet)                   |
  +-------------------------------------------+
                         |
                    후보 아키텍처
                         |
                         v
  +-------------------------------------------+
  |     성능 추정 (Performance Estimation)      |
  |                                           |
  | Full Training  |  Proxy Tasks  |  Predictor|
  | (정확하나 느림)  | (축소 데이터)  | (학습 기반) |
  |                |              |           |
  | Weight Sharing |  Early Stop  |  Zero-Cost|
  | (SuperNet)     |  (학습곡선)   |  (초기화) |
  +-------------------------------------------+
                         |
                         v
                  최적 아키텍처 A*

핵심 원리

1. 탐색 공간 (Search Space)

탐색 공간의 설계가 NAS의 성능과 효율성을 결정한다. 크게 두 가지 패러다임이 존재한다.

Global Search Space

전체 네트워크 구조를 한꺼번에 탐색한다. 초기 NAS(Zoph & Le, 2017)에서 사용된 방식으로, 탐색 공간이 매우 크다.

Cell-based Search Space

NASNet(Zoph et al., 2018)에서 도입된 방식으로, 전체 네트워크 대신 반복되는 셀(cell)의 구조만 탐색한다.

  • Normal Cell: 입력과 동일한 공간 해상도를 유지하는 특징 추출 블록
  • Reduction Cell: 공간 해상도를 절반으로 줄이는 다운샘플링 블록
Cell-based Search Space:

셀 내부 구조 탐색:
  Input1 ---+--- [op1] ---+
            |             |--- [combine] --- Output
  Input2 ---+--- [op2] ---+

  op in {3x3 conv, 5x5 conv, 3x3 sep_conv,
         max_pool, avg_pool, identity, zero}

전체 네트워크 = Normal Cell x N + Reduction Cell 반복 적재:

  [Normal] x 6 -> [Reduction] -> [Normal] x 6 -> [Reduction] -> [Normal] x 6

셀 기반 탐색은 (1) 탐색 공간을 크게 축소하고, (2) 작은 데이터셋에서 찾은 셀을 큰 데이터셋에 전이(transfer)할 수 있다는 장점이 있다.

2. 탐색 전략 (Search Strategy)

2.1 강화학습 기반 (RL-based)

Zoph & Le (2017)가 처음 제안한 방식. 컨트롤러(controller) RNN이 아키텍처를 토큰 시퀀스로 생성하고, 생성된 아키텍처의 검증 정확도를 보상(reward)으로 사용하여 REINFORCE 알고리즘으로 학습한다.

RL 기반 NAS:

Controller (RNN)
  |
  | 아키텍처 토큰 시퀀스 생성
  | [layer1_type, kernel_size, stride, ...]
  v
Child Network 학습 & 평가
  |
  | 검증 정확도 = Reward R
  v
Controller 파라미터 업데이트
  theta <- theta + alpha * nabla_theta * log(P(a|theta)) * R
  (REINFORCE)
  • 비용: 원본 NAS는 500 GPU-days (800 GPU로 28일). NASNet은 프록시 태스크로 줄였지만 여전히 2,000 GPU-hours 수준.

2.2 진화 알고리즘 기반 (Evolutionary)

Real et al. (2019)의 AmoebaNet이 대표적. 아키텍처 집단(population)을 유지하면서 돌연변이(mutation)와 선택(selection)을 반복하여 진화시킨다.

  • Tournament Selection: 무작위로 S개를 뽑아 가장 좋은 것을 부모로 선택
  • Aging Evolution: 가장 오래된 개체를 제거하여 최근 성능이 좋은 구조를 유지

2.3 미분 가능 탐색 (Differentiable / Gradient-based)

DARTS (Liu et al., 2019)가 개척한 방식으로, 이산적인 아키텍처 선택을 연속 완화(continuous relaxation)하여 경사하강법으로 탐색한다.

# DARTS 핵심 아이디어: Continuous Relaxation
# 이산적 연산 선택을 softmax 가중합으로 변환

import torch
import torch.nn.functional as F

class MixedOp(torch.nn.Module):
    """DARTS의 혼합 연산: 모든 후보 연산의 가중합"""
    def __init__(self, C, stride, ops_list):
        super().__init__()
        self.ops = torch.nn.ModuleList()
        for op_name in ops_list:
            self.ops.append(build_op(op_name, C, stride))

    def forward(self, x, weights):
        # weights = softmax(alpha): 각 연산의 가중치
        return sum(w * op(x) for w, op in zip(weights, self.ops))


class DARTSCell(torch.nn.Module):
    """DARTS 셀: 노드 간 혼합 연산으로 구성"""
    def __init__(self, steps, C, ops_list):
        super().__init__()
        self.steps = steps
        # 아키텍처 파라미터 alpha: 각 에지의 연산 가중치
        self.alphas = torch.nn.ParameterList()
        self.mixed_ops = torch.nn.ModuleList()

        for i in range(steps):
            for j in range(i + 2):  # 이전 노드 + 2개 입력
                alpha = torch.nn.Parameter(
                    torch.randn(len(ops_list)) * 1e-3
                )
                self.alphas.append(alpha)
                self.mixed_ops.append(MixedOp(C, stride=1, ops_list=ops_list))

    def forward(self, s0, s1):
        states = [s0, s1]
        offset = 0
        for i in range(self.steps):
            s = sum(
                self.mixed_ops[offset + j](
                    states[j],
                    F.softmax(self.alphas[offset + j], dim=-1)
                )
                for j in range(len(states))
            )
            offset += len(states)
            states.append(s)
        return torch.cat(states[-self.steps:], dim=1)

DARTS의 Bilevel Optimization:

  • 상위 문제: 아키텍처 파라미터 alpha를 검증 손실로 최적화
  • 하위 문제: 네트워크 가중치 w를 학습 손실로 최적화
min_{alpha}  L_val(w*(alpha), alpha)
s.t.         w*(alpha) = argmin_{w} L_train(w, alpha)

실제로는 w와 alpha를 번갈아 업데이트하는 근사를 사용한다. 탐색 비용은 약 1.5 GPU-days로, RL 기반 대비 1000배 이상 효율적이다.

DARTS의 한계와 개선

문제 설명 해결 방법
Performance Collapse skip connection에 과도하게 편향 DARTS+ (early stopping), Fair DARTS (sigmoid 대체)
Search-Eval Gap 탐색 시와 최종 학습 시 성능 차이 P-DARTS (점진적 깊이 증가), SDARTS (정규화)
메모리 비용 모든 연산을 동시 유지 ProxylessNAS (이진 게이트), GDAS (Gumbel sampling)
불안정한 탐색 alpha 수렴이 불안정 DARTS- (auxiliary skip), Single-DARTS

3. 성능 추정 전략 (Performance Estimation)

후보 아키텍처를 처음부터 끝까지 학습시키는 것은 비현실적이므로, 빠른 성능 추정이 필수적이다.

방법 설명 속도 정확도
Full Training 완전 학습 후 평가 매우 느림 가장 정확
Proxy Task 축소 데이터/에폭에서 학습 빠름 양호
Weight Sharing SuperNet에서 서브네트워크 추출 빠름 양호
Learning Curve Extrapolation 초기 학습 곡선으로 최종 성능 예측 빠름 보통
Zero-Cost Proxy 학습 없이 초기화 상태에서 점수 산출 매우 빠름 제한적
Predictor-based 학습된 예측기로 성능 추정 빠름 양호

Weight Sharing (One-Shot NAS)

ENAS(Pham et al., 2018)에서 제안된 핵심 기법. 하나의 SuperNet(과네트워크)에 모든 후보 아키텍처를 포함시키고, 파라미터를 공유한다.

Weight Sharing 개념:

SuperNet (모든 가능한 연산과 연결 포함)
  |
  +-- SubNet A (경로 1) ---> 성능 평가
  |
  +-- SubNet B (경로 2) ---> 성능 평가
  |
  +-- SubNet C (경로 3) ---> 성능 평가
  |
  ...

모든 SubNet이 SuperNet의 가중치를 공유
-> 각 SubNet을 독립적으로 학습할 필요 없음
-> 탐색 비용: 500 GPU-days -> 0.5 GPU-days

4. Hardware-Aware NAS

실제 배포 환경에서는 정확도뿐만 아니라 지연시간(latency), 에너지 소비, 모델 크기 등 하드웨어 제약을 함께 고려해야 한다.

ProxylessNAS (Cai et al., 2019)

  • DARTS처럼 미분 가능한 탐색을 사용하되, 이진 게이트(binary gate)로 메모리 문제를 해결
  • 하드웨어 지연시간을 미분 가능한 손실로 통합
  • GPU, CPU, Mobile 각 타겟에 맞춘 전용 아키텍처를 탐색
ProxylessNAS 목적함수:

  min_{alpha} E[L_val(w, alpha)] + lambda * E[Latency(alpha)]

  Latency(alpha) = sum_i sum_j p_j^i * lat_j^i
  (각 레이어 i의 연산 j 선택 확률 x 해당 연산의 지연시간)

Once-for-All (OFA, Cai et al., 2020)

한 번 학습한 SuperNet에서 다양한 하드웨어 제약에 맞는 서브네트워크를 추가 학습 없이 추출한다.

# Once-for-All 활용 예시: 타겟 하드웨어에 맞는 서브네트워크 추출
# OFA는 학습된 SuperNet에서 탐색만으로 최적 서브넷 획득

from ofa.model_zoo import ofa_net
from ofa.nas.efficiency_predictor import LatencyTable

# 1. 사전학습된 OFA 네트워크 로드
ofa_network = ofa_net("ofa_mbv3_d234_e346_k357_w1.2", pretrained=True)

# 2. 타겟 하드웨어의 지연시간 테이블
latency_table = LatencyTable(device="note10")  # Samsung Note 10

# 3. 제약 조건 하에서 진화 탐색
from ofa.nas.search_algorithm import EvolutionFinder

finder = EvolutionFinder(
    efficiency_predictor=latency_table,
    accuracy_predictor=accuracy_predictor,  # 학습된 정확도 예측기
    constraint_type="latency",
    constraint=25,  # 25ms 이내
)

best_config, best_info = finder.run_evolution_search()
# best_config: {"ks": [7,3,5,...], "d": [4,3,4,...], "e": [6,4,3,...]}

# 4. 서브네트워크 추출 (추가 학습 불필요)
ofa_network.set_active_subnet(**best_config)
subnet = ofa_network.get_active_subnet(preserve_weight=True)

# 5. 추출된 서브넷 평가
top1_acc = evaluate(subnet, imagenet_val_loader)
latency = measure_latency(subnet, device="note10")
print(f"Top-1: {top1_acc:.1f}%, Latency: {latency:.1f}ms")

5. NAS Benchmarks

공정한 비교를 위한 표준 벤치마크:

벤치마크 설명 탐색 공간 크기 논문
NAS-Bench-101 CIFAR-10 위 423K 아키텍처 사전 평가 ~423K Ying et al., ICML 2019
NAS-Bench-201 3개 데이터셋, 15,625 아키텍처 15,625 Dong & Yang, ICLR 2020
NAS-Bench-301 DARTS 탐색 공간의 surrogate benchmark ~10^18 Siems et al., 2020
TransNAS-Bench-101 7개 태스크, 아키텍처 전이성 평가 4,096 / 3,256 Duan et al., CVPR 2021

주요 방법론 계보

NAS 발전 계보:

2017  [NAS-RL]  강화학습 기반, 500 GPU-days
       (Zoph & Le, ICLR 2017)
        |
2018  [NASNet]  Cell-based 탐색 공간 도입, 전이 가능
       (Zoph et al., CVPR 2018)
        |
        +--- [ENAS]  Weight Sharing, 0.5 GPU-days
        |    (Pham et al., ICML 2018)
        |
        +--- [AmoebaNet]  진화 알고리즘, 정규화된 진화
             (Real et al., AAAI 2019)
        |
2019  [DARTS]  미분 가능 탐색, 1.5 GPU-days
       (Liu et al., ICLR 2019)
        |
        +--- [ProxylessNAS]  Hardware-Aware, 이진 게이트
        |    (Cai et al., ICLR 2019)
        |
        +--- [FBNet]  Facebook, 미분가능 + HW-Aware
        |    (Wu et al., CVPR 2019)
        |
        +--- [MnasNet / EfficientNet]  복합 스케일링
             (Tan & Le, ICML 2019)
        |
2020  [OFA]  한번 학습, 다수 배포
       (Cai et al., ICLR 2020)
        |
        +--- [Zero-Cost NAS]  학습 없는 프록시
             (Mellor et al., ICML 2021)
        |
2021+ [NAS for Transformers / LLMs]
       AutoFormer, BossNAS, LiteTransformerSearch
       하드웨어 효율적 Transformer 구조 탐색

EfficientNet: NAS의 산업적 성공 사례

EfficientNet(Tan & Le, 2019)은 NAS의 가장 성공적인 산업 적용 사례 중 하나이다.

  1. MnasNet의 NAS로 기본 아키텍처(EfficientNet-B0)를 탐색
  2. Compound Scaling: 깊이(depth), 너비(width), 해상도(resolution)를 동시에 스케일링
Compound Scaling:

  depth:      d = alpha^phi
  width:      w = beta^phi
  resolution: r = gamma^phi

  제약: alpha * beta^2 * gamma^2 ~= 2
  (FLOPS가 약 2^phi 배 증가)

  EfficientNet-B0 (NAS로 탐색) -> B1 -> B2 -> ... -> B7
  phi = 1.0                       1.0    1.1          5.3
모델 Top-1 (ImageNet) Params FLOPS
EfficientNet-B0 77.1% 5.3M 0.39B
EfficientNet-B3 81.6% 12M 1.8B
EfficientNet-B7 84.3% 66M 37B
ResNet-50 76.0% 26M 4.1B
ResNet-152 78.3% 60M 11.6B

EfficientNet-B0은 ResNet-50보다 적은 파라미터와 FLOPS로 더 높은 정확도를 달성한다.

실전 Python 예시

NNI를 활용한 NAS

# Microsoft NNI 프레임워크를 활용한 NAS 파이프라인
# NNI는 다양한 NAS 알고리즘을 통합된 인터페이스로 제공

import nni
import nni.nas.nn.pytorch as nas_nn
from nni.nas import strategy, evaluator
import torch
import torch.nn as nn


# 1. 탐색 공간 정의: ValueChoice로 후보 설정
class SearchableBlock(nas_nn.Module):
    """탐색 가능한 CNN 블록"""
    def __init__(self, in_channels, out_channels):
        super().__init__()
        # 커널 크기 탐색: 3x3, 5x5, 7x7 중 선택
        kernel_size = nni.nas.nn.ValueChoice([3, 5, 7])
        self.conv = nas_nn.Conv2d(
            in_channels, out_channels,
            kernel_size=kernel_size,
            padding=kernel_size // 2
        )
        self.bn = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU()

    def forward(self, x):
        return self.relu(self.bn(self.conv(x)))


class SearchableNetwork(nas_nn.Module):
    """탐색 가능한 전체 네트워크"""
    def __init__(self, num_classes=10):
        super().__init__()
        # 레이어 수 탐색: 2, 3, 4 중 선택
        num_layers = nni.nas.nn.ValueChoice([2, 3, 4])
        channels = [32, 64, 128, 256]

        self.stem = nn.Sequential(
            nn.Conv2d(3, 32, 3, padding=1),
            nn.BatchNorm2d(32),
            nn.ReLU()
        )

        self.layers = nni.nas.nn.Repeat(
            lambda i: SearchableBlock(
                channels[min(i, len(channels)-2)],
                channels[min(i+1, len(channels)-1)]
            ),
            depth=num_layers
        )

        self.classifier = nn.Sequential(
            nn.AdaptiveAvgPool2d(1),
            nn.Flatten(),
            nn.Linear(256, num_classes)
        )

    def forward(self, x):
        x = self.stem(x)
        x = self.layers(x)
        return self.classifier(x)


# 2. 평가기 정의
from nni.nas.evaluator.pytorch import Classification

eval = Classification(
    train_dataloaders=train_loader,
    val_dataloaders=val_loader,
    max_epochs=50,
    learning_rate=0.025,
)

# 3. 탐색 전략 선택 및 실행
# DARTS 전략 사용
search_strategy = strategy.DARTS()

# 탐색 실행
from nni.nas.experiment import NasExperiment

experiment = NasExperiment(
    model=SearchableNetwork(),
    evaluator=eval,
    strategy=search_strategy,
)
experiment.run()

# 4. 최적 아키텍처 추출
best_arch = experiment.export_top_models(top_k=1)[0]
print("Best architecture:", best_arch)

Optuna + NAS 스타일 하이퍼파라미터 탐색

# Optuna를 활용한 경량 NAS: 아키텍처 하이퍼파라미터 탐색
# 실무에서 가장 접근하기 쉬운 방법

import optuna
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms


def build_model(trial):
    """Optuna trial로 아키텍처 구성"""
    layers = []
    in_channels = 3

    # 레이어 수 탐색
    n_layers = trial.suggest_int("n_layers", 2, 5)

    for i in range(n_layers):
        out_channels = trial.suggest_categorical(
            f"channels_{i}", [32, 64, 128, 256]
        )
        kernel_size = trial.suggest_categorical(
            f"kernel_{i}", [3, 5]
        )
        use_bn = trial.suggest_categorical(
            f"use_bn_{i}", [True, False]
        )

        layers.append(nn.Conv2d(
            in_channels, out_channels,
            kernel_size=kernel_size,
            padding=kernel_size // 2
        ))
        if use_bn:
            layers.append(nn.BatchNorm2d(out_channels))
        layers.append(nn.ReLU())

        # 매 2번째 레이어마다 풀링
        if i % 2 == 1:
            layers.append(nn.MaxPool2d(2))

        in_channels = out_channels

    model = nn.Sequential(
        *layers,
        nn.AdaptiveAvgPool2d(1),
        nn.Flatten(),
        nn.Linear(out_channels, 10)
    )
    return model


def objective(trial):
    """Optuna 목적함수: 검증 정확도 최대화"""
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = build_model(trial).to(device)

    lr = trial.suggest_float("lr", 1e-4, 1e-1, log=True)
    optimizer = torch.optim.Adam(model.parameters(), lr=lr)
    criterion = nn.CrossEntropyLoss()

    transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
    ])
    train_data = datasets.CIFAR10("./data", train=True, transform=transform)
    val_data = datasets.CIFAR10("./data", train=False, transform=transform)
    train_loader = DataLoader(train_data, batch_size=128, shuffle=True)
    val_loader = DataLoader(val_data, batch_size=256)

    # 프록시 태스크: 적은 에폭으로 빠르게 평가
    for epoch in range(10):
        model.train()
        for x, y in train_loader:
            x, y = x.to(device), y.to(device)
            loss = criterion(model(x), y)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        # 중간 결과 보고 (pruning 지원)
        model.eval()
        correct, total = 0, 0
        with torch.no_grad():
            for x, y in val_loader:
                x, y = x.to(device), y.to(device)
                correct += (model(x).argmax(1) == y).sum().item()
                total += y.size(0)
        accuracy = correct / total
        trial.report(accuracy, epoch)

        if trial.should_prune():
            raise optuna.TrialPruned()

    return accuracy


# 탐색 실행
study = optuna.create_study(
    direction="maximize",
    pruner=optuna.pruners.MedianPruner(n_warmup_steps=3),
)
study.optimize(objective, n_trials=100)

print(f"Best accuracy: {study.best_value:.4f}")
print(f"Best architecture: {study.best_params}")

비교 분석

탐색 전략 비교

전략 탐색 비용 대표 방법 장점 단점
RL 기반 500+ GPU-days NAS, NASNet 유연한 탐색 공간 매우 높은 비용
진화 알고리즘 300+ GPU-days AmoebaNet 병렬화 용이, 다목적 최적화 높은 비용
미분 가능 1-4 GPU-days DARTS, ProxylessNAS 효율적, 그래디언트 활용 안정성 이슈, 메모리
One-Shot 0.5-2 GPU-days ENAS, SPOS 매우 효율적 순위 상관 불완전
Zero-Cost 수 초 SynFlow, NASWOT 즉시 평가 낮은 상관성

NAS 발견 아키텍처 vs 수동 설계

모델 설계 방법 CIFAR-10 Error ImageNet Top-1 탐색 비용
ResNet-110 수동 6.41% - -
DenseNet-BC 수동 3.46% - -
NASNet-A RL-NAS 2.65% 82.7% 2,000 GPU-hrs
AmoebaNet-A 진화-NAS 2.55% 83.1% 3,150 GPU-hrs
DARTS (2nd) 미분-NAS 2.76% 73.3% 4 GPU-days
ProxylessNAS 미분-NAS (HW) 2.08% 75.1% 200 GPU-hrs
EfficientNet-B0 NAS + Scaling - 77.1% -

최근 동향 (2023-2025)

NAS for Large Language Models

Transformer 아키텍처에 NAS를 적용하여 효율적인 LLM 구조를 탐색하는 연구가 활발하다.

방향 설명 예시
Attention 구조 탐색 Multi-Head, Group-Query, Sparse Attention 등 자동 선택 AutoFormer, S3 (Searching for Sparse Transformers)
MoE 라우팅 구조 Expert 수, 라우팅 전략 자동 탐색 AutoMoE
경량 모델 탐색 Edge/Mobile 배포를 위한 소형 LM LiteTransformerSearch
Elastic Inference 입력에 따라 동적으로 구조 조정 MatFormer, FlexiBERT

Zero-Cost NAS

학습 없이 초기화 상태에서 아키텍처의 잠재적 성능을 추정하는 프록시 지표:

  • SynFlow: 시냅스 흐름 기반 파라미터 중요도
  • NASWOT: 학습 없는 상태에서의 activation overlap
  • GradNorm: 그래디언트 노름 기반 추정

초 단위로 수천 개 아키텍처를 스크리닝할 수 있어, 기존 NAS의 전처리 단계로 활용된다.

실무 가이드

언제 NAS를 사용하는가

상황 권장 접근 이유
컴퓨팅 자원 제한적 Optuna/Ray Tune으로 HPO NAS 대비 간단하고 효과적
특정 하드웨어 타겟 OFA / ProxylessNAS HW-Aware 탐색이 핵심
연구/논문 목적 DARTS + NAS-Bench 공정 비교 가능
산업 배포 EfficientNet 계열 직접 사용 이미 최적화된 아키텍처
Edge/Mobile 최적화 OFA + TensorRT/ONNX 한번 학습, 다수 배포

실무 체크리스트

  1. 먼저 기존 아키텍처 시도: ResNet, EfficientNet 등을 먼저 실험
  2. HPO 우선: 아키텍처보다 하이퍼파라미터 튜닝이 효과적인 경우가 많음
  3. 탐색 공간 축소: 도메인 지식으로 불필요한 연산 제외
  4. 프록시 태스크 설계: 작은 데이터/에폭으로 빠르게 평가
  5. 재현성 확보: NAS-Bench 사용 또는 시드 고정

참고 자료

자료 유형 URL
Zoph & Le (2017) "NAS with RL" 논문 https://arxiv.org/abs/1611.01578
Liu et al. (2019) "DARTS" 논문 https://arxiv.org/abs/1806.09055
Cai et al. (2019) "ProxylessNAS" 논문 https://arxiv.org/abs/1812.00332
Cai et al. (2020) "Once-for-All" 논문 https://arxiv.org/abs/1908.09791
Tan & Le (2019) "EfficientNet" 논문 https://arxiv.org/abs/1905.11946
Elsken et al. (2019) "NAS Survey" 서베이 https://arxiv.org/abs/1808.05377
Lilian Weng "NAS" Blog 블로그 https://lilianweng.github.io/posts/2020-08-06-nas/
NNI NAS Documentation 도구 https://nni.readthedocs.io/en/stable/nas/
NAS-Bench-201 벤치마크 https://github.com/D-X-Y/NAS-Bench-201