ひとことで言うと
転移学習は、ソースタスクで学習済みのネットワークから特徴表現を持ち込み、ターゲットタスクの出力層を学習したり、全体を追加学習したりする枠組みです。ゼロから学習する代わりに、すでに獲得した表現を初期値または固定の特徴抽出器として使います。
画像の見分け方を、輪郭や色の見方から教わっている状態だと考えてください。別の分類を覚えるとき、見方まで最初から覚え直す必要はありません。ただし、最後の判断だけを差し替えるのか、対象に合わせて見方そのものも調整するのかは、二つの仕事の近さと手元のデータで変わります。
なぜ必要か
深いネットワークは多数のパラメータを持つため、ターゲットタスクのデータが少ないと、全層をランダム初期化して学習するのは不安定で過学習もしやすくなります。事前学習済みの下層を使えば、入力から局所的なパターンを取り出す部分を再利用でき、ターゲット側では少ないデータで上位の判断を学習できます。
ただし、転移できるものは層によって同じではありません。Yosinski らは自然画像を扱う畳み込みネットワークを調べ、下層の特徴は複数のデータセットやタスクに適用しやすく、上層に進むほど元タスクに特化するという、汎用的な特徴からタスク固有の特徴への移行を実験的に示しました。したがって「学習済みなら全層をそのまま使う」が原則ではなく、どの深さまで再利用するかが設計になります。
| 学習の始め方 | ターゲット側で背負う仕事 |
|---|---|
| スクラッチ学習 | 特徴の獲得から判断境界まで全て |
| 転移学習 | 既存特徴の利用と、必要な部分の適応 |
仕組み
ソースタスクで得たネットワークを、特徴抽出部 とターゲット用ヘッド に分けます。 は入力、 は特徴抽出部のパラメータ、 は中間特徴、 はヘッドのパラメータです。ターゲットの予測は次で表せます。
特徴抽出(凍結)では を更新せず、ターゲット損失 に対して だけを更新します。ファインチューニングでは も更新しますが、元タスクで得た値を初期値として使います。
| 方法 | 更新する部分 | 向いている状況 | 注意点 |
|---|---|---|---|
| 特徴抽出(凍結) | ヘッドのみ | データが少ない、タスクが近い、まず安定させたい | 表現のずれを補正できない |
| 部分的微調整 | 上層とヘッド | タスクは近いが、判断に使う特徴を調整したい | 凍結境界の選択が必要 |
| 全体の微調整 | 全層とヘッド | データが十分、タスクが異なる | 過学習と元表現の破壊に注意 |
判断軸は二つです。タスクが似ていれば下層だけでなく上層も有効な可能性があり、少量データなら凍結寄りにします。タスクの距離が大きいほど転移性は低下するため、上層を凍結したままにする根拠は弱くなります。原論文は、遠いタスクからでもランダム特徴より良い場合がある一方、距離が増すほど転移性が下がることを報告しています。
もう一つの落とし穴が co-adaptation です。ネットワーク内のニューロンが元タスクに合わせて互いに依存するよう調整されていると、途中でネットワークを分割して転移したとき、その組合せが崩れて最適化が難しくなります。論文では、高層の元タスクへの特化だけでなく、この「協調したニューロンの分割」による最適化困難も転移性を下げる要因として観察されています。つまり、上層を移植すれば表現が合うとは限らず、凍結境界の前後を微調整して協調関係を作り直す余地があります。
試験でどう問われるか
| 問われ方 | 正解に寄る条件 | 引っかけ |
|---|---|---|
| 転移学習の目的 | 学習済み特徴を別タスクの初期値または特徴抽出器として再利用する | 必ずラベルなしで学習する手法だとする |
| 層ごとの転移性 | 下層ほど汎用的、上層ほど元タスクに特化する傾向 | すべての層が同じ転移性を持つとする |
| 凍結と微調整の選択 | データ量とタスク類似度を見て、更新範囲を決める | データが少ないのに全層を無条件で更新する |
| タスク距離の影響 | 距離が大きいほど転移性は下がる。ただしランダム特徴より有利な例もある | 遠いタスクからの転移は常に無意味とする |
| co-adaptation | 共同適応したニューロンを分割すると最適化が難しくなり得る | 転移の失敗を上層の特化だけで説明する |
実装で確かめる
まず特徴抽出部を固定し、得られた特徴からターゲットの線形ヘッドだけを最小二乗で求める、という最小形を確認します。実際の深層モデルでは、このヘッド学習の後に上層または全層を微調整します。
import numpy as np
rng = np.random.default_rng(0)
X = rng.normal(size=(20, 3))
W_feature = rng.normal(size=(3, 4)) # 事前学習済みとして固定
H = np.tanh(X @ W_feature)
w_target = np.array([1., -2., .5, 1.5])
y = H @ w_target
w_head, *_ = np.linalg.lstsq(H, y, rcond=None)
prediction = H @ w_head
print("target head MSE:", np.mean((prediction - y) ** 2))
実行結果は target head MSE: 1.625793021853929e-30 です。ここでは W_feature を更新していないので特徴抽出に相当します。ターゲットの特徴分布がソースとずれて誤差が残るなら、上層から順に更新範囲を広げるのが次の選択肢です。
凍結は「勾配を計算しない」という意味ではなく、少なくとも対象パラメータを更新対象から外すことです。実装では optimizer に渡すパラメータ、requires_grad、学習モードの扱いを確認し、意図せず特徴抽出部まで更新していないかを切り分けます。
取り違えやすいもの
| 用語 | 転移学習との切り分け |
|---|---|
| ファインチューニング | 転移学習の実施方法の一つ。学習済み重みを初期値にして、選んだ層をターゲットデータで更新する |
| 特徴抽出 | 学習済み特徴を固定してヘッドだけを学習する転移の形。ファインチューニングとは更新範囲が違う |
| スクラッチ学習 | 事前学習済み重みを使わず、ターゲットタスク用に初期化して学習する |
| マルチタスク学習 | 複数タスクを同時に扱う枠組み。別タスクへ順に知識を持ち込む転移学習とは学習の構成が違う |
| ドメイン適応 | ソースとターゲットのデータ分布差への対応を主眼に置く問題設定。転移学習で現れる具体的な課題の一つ |
想起チェック
転移学習で再利用するものは何か
ソースタスクで学習した特徴表現や重みです。ターゲット用ヘッドの初期値、または固定特徴抽出器として使います。
特徴抽出とファインチューニングの更新範囲はどう違うか
特徴抽出は特徴抽出部を凍結してヘッドを更新します。ファインチューニングは学習済み重みを初期値にし、選択した特徴抽出部も更新します。
層の深さ、タスク類似度、データ量は何を決めるか
どこまで凍結し、どこから微調整するかを決めます。下層は汎用的になりやすく、タスクが遠いほど転移性は下がり、データが少ないほど凍結寄りの判断になります。
co-adaptation を分割すると何が起きるか
元タスクで協調していたニューロンの組合せが崩れ、ターゲット側での最適化が難しくなり、転移性が下がることがあります。