📚
NNの高速化/安定化/軽量化/精度向上手法など
はじめに
「kaggleに挑む深層プログラミングの極意」に記載のNNの基本知識を論点を補足しつつ纏めました。
(備忘録記事です)
NNの高速化/安定化/軽量化/精度向上手法一覧
🚀 高速化 (Throughput / Latency)
-
混合精度学習 (Mixed Precision) : 行列演算の大半を
float16/bfloat16
で実行し、勾配スケーリングで数値安定性を保つ。メモリ消費を 2 × 以上削減でき、大きなバッチを回しやすくなる。 -
データローダ最適化 :
prefetch
,num_workers
,pin_memory
,.cache()
等で I/O 待ちを隠蔽。GPU のアイドル時間を削減し、エポックあたりの実行時間を短縮。 - 勾配チェックポイント (Gradient Checkpointing) : 中間活性を都度再計算してメモリを節約。巨大モデルを 1 GPU で学習できるようにし、分散数を減らして結果的にウォールタイムを短縮。
- CUDA グラフ/XLA/Torch Compile : 計算グラフを JIT コンパイルしてカーネル呼び出しを融合。オーバーヘッドを削り推論・学習ともに数 10 % 速度向上が見込める。
Pytorchで高速化を促す際は、Pytorch Performance Tuning Guideを読むと良い。
🔒 安定化 (Training Stability)
- バッチ正規化 / レイヤー正規化 / グループ正規化 : 各層出力を正規化し勾配爆発・消失を抑制。小バッチ環境では GroupNorm / LayerNorm が有効。
- ラーニングレート・ウォームアップ : 学習開始直後の発散を防ぎ、大きな初期 LR でも安定収束。
- 勾配クリッピング (Gradient Clipping) : 勾配ノルムや値を上限で切ることで RNN・Transformer の爆発を防止。
- 勾配累積 (Gradient Accumulation) : 小バッチを複数回 forward/backward してから 1 回だけ重み更新。GPU メモリ制約下でも大バッチ学習の安定性を再現。
- 適切な重み初期化(He, Xavier など) : 深層でも信号を保ち、収束を高速化。
- Early Stopping + ReduceLROnPlateau : 過学習を防ぎつつ停滞時に自動で LR を減衰。
- Lookahead Optimizer : 先行・追従パラメータを用いて振動を抑え、より滑らかな最適化経路を確保。
📦 軽量化 (Model Size / Deployability)
-
モデル量子化 (Quantization) : 重み・アクティベーションを
int8
等へ変換し、メモリ帯域と演算量を大幅削減。TFLite / ONNX Runtime / TensorRT INT8 が代表例。 - 構造的プルーニング (Structured Pruning) : 重要度の低いチャネルやヘッドを丸ごと削除し、FLOPs とパラメータ数を圧縮。再蒸留で精度回復が定石。
- 知識蒸留 (Knowledge Distillation) : 大教師モデルの出力分布を小モデルに学習させ、軽量モデルでも高精度を維持。
- 重み共有 / 低ランク分解 : 畳み込みカーネルや全結合重みを分解・共有しパラメータを削減。
🎯 精度向上 (Generalization / Score Boost)
- 学習率スケジューラ : Cosine Annealing や One‑Cycle で LR を動的に変化させ、広い谷に収束。
- EMA (Exponential Moving Average) : 学習中の重みを指数移動平均し、推論時に使用。数% 精度改善が見込める。
- SWA (Stochastic Weight Averaging) : エポック終盤の重みを平均化し、局所最小値の一般化性能を底上げ。
- SAM (Sharpness‑Aware Minimization) : 勾配上昇方向へ一歩進んだ上で最小化し、鋭い谷を避けることで汎化を改善。
- Mixup / CutMix : 画像とラベルを線形混合・切貼りしてデータ多様性を拡張。特に小データで過学習を緩和。
- ラベルスムージング : one‑hot を 0.9/0.1 などに平滑化し、過信を抑制。
- Test‑Time Augmentation (TTA) : 反転・クロップ等で複数推論し平均。数クリックで LB を上げる定番技。
- K‑Fold CV+OOF 予測 : 情報リークを避けつつ全データを有効活用。メタ学習やスタッキングで必須。
- エポック/モデルアンサンブル : best, second‑best, last など複数チェックポイントを平均し、分散を低減。
※使い分け
使うタイミング | まず試す | 追加で効かせる |
---|---|---|
学習初期 | Mixed Precision / 正規化層 / 適切初期化 | Warm‑up, Cosine LR |
メモリ不足 | 勾配累積 / Checkpointing | Pruning, Distillation |
精度頭打ち | EMA / TTA / Label Smoothing | SAM, SWA, Mixup |
デプロイ | Quantization | Structured Pruning |
NNのモデル作成時の留意点
NNの実装を効率的に進めるためには,できる限り手戻りが少ないように順を追って挙動を確認するのが良い。以下は戦略の一例[参考文献: https://fullstackdeeplearning.com/spring2021/lecture-7/]。
-
単純なアーキテクチャや学習設定からはじめる:
モデルの学習が問題なくはじまることを確認する。最初の段階ではデータセットの一部のみを抽出することで読み込み時間を短縮し、データセットの形状の不一致などが発生せず,モデルの学習が進行するか確かめる。モデルの出力がNanになっていないか確認。少量データセットで確認できた後は全量データセットでも確認し、メモリ不足エラーになったら計算資源に適したバッチサイズに確認して設定をチューニング。 -
訓練データセットで学習できると確認する:
モデルが最低限動いたら次は学習で損失が問題なく下がることを確認する。NNの学習率は大きすぎると目的関数が発散したり、小さすぎると全く学習が進まなかったりする ( であることが多い)。10^{-6}~10^{-3}
NNでは、入力の各特徴量の取りえる値の範囲が異なると、学習がうまく進まない場合がある。そのようなときは以下のような方法が有効な場合がある。
・標準化: 線形変換で平均を0、標準偏差を1にする。
・min-maxスケーリング: 値を指定された最小値と最大値(通常は0~1)の範囲に収める。
・RankGaus: 数値関係を順位情報に変換し,その後に正規分布に変換する。
また,値の大小関係に意味がない質的変数(値が数値ではなくカテゴリで表される変数)については,数値表現に直す必要がある。数値表現に直す処理として以下のようなものがある。
・One-hot encoding: 各カテゴリをビット列(0or1)で表現する手法。
・Label Encoding: 各カテゴリを連番の整数で表す手法。
・Entity Embedding: カテゴリを学習可能なベクトル(密な表現)に変換して使う深層学習向けの手法。
特徴 | One-hot | Label Encoding | Entity Embedding |
---|---|---|---|
出力次元 | カテゴリ数 | 1次元 | 任意の低次元(学習) |
順序の誤解 | なし | あり(注意) | なし(意味ベース) |
スパース性 | 高い | 低い(整数) | 低い(密ベクトル) |
拡張性(カテゴリ数) | 小〜中 | 大歓迎 | 大歓迎 |
向いてるモデル | 線形 / 木系 | 木系 / 一部分類 | ニューラルネット |
学習される? | ✗ 固定 | ✗ 固定 | ✅ 学習される |
-
検証データセットに対する汎化性能を確認する:
未知のデータセットに対する性能(汎化性能)を確認し,少しずつモデルを改善していく。
Discussion