Fine-tuning
ファインチューニングは、事前学習済みモデルをタスク固有のデータで継続学習させ、はるかに少ないデータと計算量で適応させます。仕組み、PEFT、コードについて解説します。
ファインチューニングとは、大規模なデータセットで学習済みのモデルの学習を継続し、その重みの一部またはすべてを、より小規模でタスク固有のデータセットを使って更新する処理です。事前学習済みモデルの重みには、ビジョンモデルのエッジ、テクスチャ、形状や、大規模言語モデル(LLM)の文法や事実など、一般的な知識がすでに含まれています。そのため、ランダムな重みから学習する場合と比べて、はるかに少ないラベル付きデータと計算リソースで高い精度を実現できます。ファインチューニングは転移学習の最も一般的な実施方法であり、大半のカスタム物体検出モデルやチャットアシスタントは、事前学習済みの基盤モデルからこの方法で構築されます。
ファインチューニングの仕組み#
ファインチューニングでは、事前学習済みの重みを読み込み、分類器や検出ヘッドなど、元のタスクに関連付けられたレイヤーを置き換えるかサイズ変更して、通常の損失関数とオプティマイザーを使って新しいデータで学習します。元のモデルをどれだけ維持するかは、次の3つの選択で決まります。
- 学習率: ファインチューニングでは、通常、短いウォームアップの後、事前学習より低い学習率を使います。これにより、事前学習済みの特徴を上書きするのではなく、微調整できます。ULMFiTではさらに、最上位より下のレイヤーごとに学習率を2.6分の1にする、層別学習率を採用しました。
- 学習するレイヤー: バックボーンの初期レイヤーを凍結すると、汎用的な特徴を固定し、メモリ使用量を抑え、小規模なデータセットでの過学習リスクを減らせます。段階的な凍結解除では、まず新しいヘッドを学習し、その後、より深いレイヤーを学習対象に加えます。
- 学習期間: 新しいデータだけで学習する期間が長くなるほど、モデルは破滅的忘却によって元の能力を失っていきます。
適切な設定は、利用可能なメモリ、ラベル付きデータの量、元の能力が引き続き必要かどうかによって異なります。
全パラメータのファインチューニングとパラメータ効率の高いファインチューニング#
全パラメータのファインチューニングでは、すべての重みを更新します。70億パラメーターのLLMの場合、70億個の値について勾配とオプティマイザー状態を保持し、タスクごとにモデル全体のコピーを保存する必要があります。パラメータ効率の高いファインチューニング(PEFT)では、事前学習済みの重みを凍結し、追加または選択した少数のパラメーターだけを学習します。Hugging FaceのPEFTライブラリは、一般的な手法を実装しています。LoRAは、凍結した重み行列の隣に学習可能な低ランク行列を追加します。GPT-3 175BをAdamで完全にファインチューニングする場合と比べて、学習可能なパラメーターを10,000分の1に、GPUメモリを3分の1に削減しました。QLoRAは、4ビット量子化したベースモデル上でLoRAアダプターを学習することで、単一の48 GB GPUで650億パラメーターのモデルをファインチューニングできるようにしました。
LLMは事前学習の後、複数段階のファインチューニングを経ます。インストラクションチューニングではプロンプトと応答のペアで学習し、その後、人間のフィードバックによる強化学習(RLHF)や直接選好最適化(DPO)などの選好ベースの手法で、人間の好みに合う応答へと調整します。
ファインチューニングと関連用語の違い#
- 転移学習: あるタスクで学習したモデルを別のタスクに再利用する、より広い概念です。ファインチューニングでは事前学習済みの重みを更新しますが、特徴抽出では重みを凍結したまま、新しいヘッドだけを学習します。
- スクラッチからの学習: ランダムな重みから学習を始めるため、より多くのラベル付きデータと計算リソースが必要です。新しいアーキテクチャや、利用可能な事前学習データと共通点が少ないドメインに適しています。
- 線形プロービング: 通常は事前学習済み表現がどの程度の情報をすでに捉えているかを測定するために、凍結した特徴量上で線形分類器だけを学習します。
- プロンプトエンジニアリングと検索拡張生成(RAG): 重みを変更せずに、入力を通じてLLMの動作を変えます。
物体検出器のファインチューニング#
新しいデータセットを使って、事前学習済みのYOLO26チェックポイントに対して train()を呼び出すと、モデルをファインチューニングできます。互換性のある重みはすべて引き継がれ、デフォルトのcls_remap=Trueはクラス名が一致する分類器の行をコピーします。そのため、African Wildlifeデータセットでは、ゾウとシマウマの出力はCOCOで事前学習された行から開始します。一方、COCOに含まれないバッファローとサイは、新しい重みから開始します。
from ultralytics import YOLO
# COCOで事前学習したYOLO26nの重みを読み込みます。代わりにYOLO("yolo26n.yaml")を使うと、スクラッチから学習します
model = YOLO("yolo26n.pt")
# バッファロー、ゾウ、サイ、シマウマの学習画像1,052枚でファインチューニングします
results = model.train(data="african-wildlife.yaml", epochs=30, imgsz=640)この30エポックの実行では、デフォルトのoptimizer="auto"がAdamWとlr0=0.00125を選択します。実行が10,000イテレーション未満であるため、データセットの4クラスに基づいて学習率を計算します。










