Neural Architecture Search (NAS)
ニューラルアーキテクチャ探索(NAS)は、レイヤーや接続を探索してニューラルネットワークの設計を自動化します。手法、計算コスト、NASで構築されたモデルを解説します。
ニューラルアーキテクチャサーチ (NAS) は、ニューラルネットワークの構造を自動設計する自動機械学習 (AutoML)の分野です。エンジニアが畳み込みなどのレイヤーの種類、深さ、幅、接続を手作業で選ぶ代わりに、探索アルゴリズムが候補アーキテクチャを提案し、それぞれのタスク性能を推定して、その結果をもとにより良い候補を提案します。目的は通常精度であり、推論レイテンシ、パラメーター数、対象ハードウェアでのFLOPsなどのコストを組み合わせることもよくあります。NASからは、EfficientNetやMobileNetV3など、広く使われている複数のコンピュータービジョン用バックボーンが生まれました。
NASの仕組み#
Journal of Machine Learning Researchのサーベイでは、NASの手法を次の3つの観点から分類しています。
- 探索空間:構築可能なアーキテクチャの集合です。許可する演算の種類、カーネルサイズ、スキップ接続、接続方法などが含まれます。多くの手法では、小さなデータセットで見つかったセルを大規模データセットに転用できるように、少数の繰り返しセルを探索して複製を積み重ね、探索空間を縮小します。
- 探索戦略:強化学習コントローラーや進化的手法から、勾配ベースの手法や単純なランダムサンプリングまで、試す候補を選ぶアルゴリズムです。
- 性能推定戦略:学習エポック数や画像・データセットの規模を減らす、最終精度を予測する、候補間で重みを共有するなど、候補を完全に学習させずに評価する方法です。
GPU数千日分から数時間へ#
初期のNASは、候補ごとに収束するまで学習させていたため、高コストでした。ZophとLeによる2016年の研究では、強化学習で学習した再帰型コントローラーがネットワークを生成し、800台のGPUで同時に探索を実行しました。続くNASNetでは、500台のGPUを4日間使ってCIFAR-10上でセルを探索し、それをImageNetに転用しました。AmoebaNetは正則化した進化的手法を用い、約3,150 GPU日で同程度の結果を達成しました。ENASでは、すべての候補を大規模ネットワーク1つの部分グラフとして扱い、モデルの重みを共有することで、単一GPUでの探索時間を16時間未満に短縮しました。DARTSは演算の離散的な選択を連続的な重みに置き換え、アーキテクチャ自体を勾配降下法で数GPU日以内に最適化できるようにしました。ベンチマークの評価によって、この分野の見方も変わりました。早期終了を用いたランダム探索は、Penn TreebankとCIFAR-10のベンチマークでENASと同等以上の性能を示しました。
ハードウェアを考慮したNASとNASで構築したモデル#
NASが実用面で最も大きな影響を与えたのは、特定のデバイス上で精度と速度のバランスを取る必要があるエッジAI向けの効率的なモデルです。MnasNetは実際のスマートフォンで測定したレイテンシを探索目的に取り入れ、Pixelスマートフォンで78 ms、ImageNet top-1精度75.2%を達成しました。これは、MobileNetV2より1.8倍高速で、精度も0.5%高い結果です。EfficientNet-B0も同様の探索から生まれ、その後、複合スケーリングによってB1からB7の系列に拡張されました。MobileNetV3は、ハードウェアを考慮したNASとNetAdaptアルゴリズムを組み合わせ、モバイルCPU向けに最適化しています。物体検出では、DeciのYOLO-NASモデルは、AutoNAC探索エンジンで発見され、INT8量子化後の精度低下を抑えるように設計されています。Ultralyticsパッケージでは、推論、検証、エクスポートにNASクラスを使って実行できますが、学習には対応していません。その後、NVIDIAがDeciを買収し、これらのモデルは元のチームによる更新が終了しています。
最小限のNASの例#
次の例では、scikit-learnの手書き数字データセットを使い、多層パーセプトロンの小規模な探索空間で、最も単純な探索戦略であるランダムサンプリングを実行します。各候補は、簡易的な性能推定としてわずか30 エポックだけ学習し、検証データでスコアを算出します。
import random
import warnings
from sklearn.datasets import load_digits
from sklearn.exceptions import ConvergenceWarning
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
warnings.simplefilter("ignore", ConvergenceWarning) # short training runs are the cheap estimate
X, y = load_digits(return_X_y=True)
X_train, X_val, y_train, y_val = train_test_split(X / 16, y, random_state=0)
# Search space: 1-3 hidden layers, each 8-128 units wide. Search strategy: 12 random samples
random.seed(0)
space = [8, 16, 32, 64, 128]
candidates = {tuple(random.choices(space, k=random.randint(1, 3))) for _ in range(12)}
# Performance estimation: train each candidate for only 30 epochs, then score it on validation data
scores = {}
for layers in candidates:
model = MLPClassifier(hidden_layer_sizes=layers, max_iter=30, random_state=0)
scores[layers] = model.fit(X_train, y_train).score(X_val, y_val)
worst, best = min(scores, key=scores.get), max(scores, key=scores.get)
print(f"{len(scores)} architectures: worst {worst} {scores[worst]:.3f}, best {best} {scores[best]:.3f}")12回のサンプリングで10種類の異なるアーキテクチャが得られました。検証精度は、ユニット数8のレイヤーを2つ持つ構成の0.398から、ユニット数128、128、16のレイヤーを持つ構成の0.978まで幅があり、アーキテクチャの選択だけで精度に約60ポイントの差が生じます。本格的なNASでは、最良の候補を収束するまで再学習し、別のテストセットでスコアを報告します。
NASと関連用語#
- ハイパーパラメーター調整: 固定されたアーキテクチャに対して、学習率などの学習設定を最適化します。NASではアーキテクチャ自体を変数として扱い、両者は同時に実行されることもよくあります。
- モデルの枝刈りと知識蒸留: 学習後に既存のネットワークを縮小または模倣しますが、NASは学習前に効率的な設計を探索します。
- 転移学習: 事前学習済みモデルの学習済み重みを再利用します。NASはその重みを収める構造を決定し、EfficientNetなどのNASで発見されたネットワーク自体も、人気の高い事前学習済みバックボーンです。










