一覧へ

「バックプロパゲーションはどのように機能するか - シグナルカスケードの逆方向因果関係を追跡する」

「3362万個のパラメータの偏微分を効率的に計算するにはどうすればよいでしょうか?バックプロパゲーションと連鎖律を、細胞シグナルカスケードの逆方向を追跡するものとして捉え、PyTorchの自動微分の原理を理解しましょう。」

入門
|
20
|
検証済み (2026-07)
進捗0/15 (0%)

バックプロパゲーションの仕組み:逆方向への信号の連鎖を追跡する

このトピックを完了した後

第3部で先送りした質問、「実際には3362万個のパラメータの勾配を、妥当な時間でどのように計算するのか?」に対する答えが得られます。これを可能にするアルゴリズムがバックプロパゲーションであり、その基盤となる数学は連鎖律です。

この部分は第3部の補完です。第3部が「どれだけ動かすか」について扱った場合、この部分は「どの方向に動かすべきかを知る方法」について扱います。第5部(Transformer)と第12部(PyTorchの実践)では、ここで提示する内容に基づいてさらに深く掘り下げていきます。


原始的なアプローチの圧倒的な失敗

第3部では、パラメータ θ_i の偏微分を次のように定義しました。

text
∂L/∂θ_i = lim_{ε → 0} [L(θ_1, ..., θ_i + ε, ..., θ_P) - L(θ)] / ε

教科書に示されているように、これを直接実装してみましょう。各パラメータに対して、わずかにεだけ値を変化させ、損失がどれだけ変化するかを観察し、それをεで割って偏微分を求めます。これは有限差分法と呼ばれます。

問題点:3362万個のパラメータがある場合、単一の偏微分を得るために、ニューラルネットワーク全体を一度実行する必要があります。3362万個すべての偏微分を得るためには、ニューラルネットワークを3362万回実行する必要があります。

スケール感を掴むために、病的なニューラルネットワークの例を考えてみましょう。単一のフォワードパスがGPU上で1ミリ秒かかると仮定すると、1ステップの勾配を計算するには、3362万ミリ秒、つまり約9.3時間かかります。そして、トレーニングにはこのステップを数千回、あるいは数百万回繰り返す必要があります。このアプローチでは、トレーニングに何百年もかかることになります。

これは、有限差分法が完全に役に立たないということではありません。後で見てわかるように、これはバックプロパゲーションの実装の検証ツールとして使用されます。「私たちのバックプロパゲーションコードは実際に正しいのか?」という疑問に対して、有限差分法を使用していくつかのパラメータの偏微分を計算し、それを「正解」と比較することができます。これは勾配チェックと呼ばれ、ニューラルネットワークライブラリの開発者が実行する重要な検証ステップです。

しかし、実際のトレーニングには、はるかに高速な方法が必要です。その方法がバックプロパゲーションです。


異常な信号の連鎖:問題はどこにあるのか?

バックプロパゲーションの直感的な理解を深めるために、実験室のシナリオを考えてみましょう。

細胞シグナル伝達実験を行っているとします。特定の配位体で細胞を処理すると、下流の遺伝子発現が誘導されるはずです。信号経路は次のようになります。

text
配位体(外部刺激)
   ↓
受容体活性化
   ↓
二次信号(例:cAMP)
   ↓
キナーゼカスケード(RAF → MEK → ERKなど)
   ↓
転写因子のリン酸化
   ↓
遺伝子発現の誘導(測定される結果)

細胞に配位体を処理し、下流の遺伝子発現を測定すると、予想よりも50%低くなることがわかりました。あなたの質問は、「問題はどこで発生したのか?」です。

おそらく、受容体が十分に活性化されていないか、二次信号が効果的に生成されていないか、特定のキナーゼの活性が低いか、または転写因子がリン酸化されていない可能性があります。原因を特定するには、**各上流ノードが下流の50%の誤差に「どれだけ貢献しているか」**を定量化する必要があります。

この問題にはどのように対処しますか?各ステップを定量的に測定し、それらを関係に沿って逆方向に追跡します。

  • 遺伝子発現は50%低い → 転写因子のリン酸化レベルは?30%低い → 転写因子段階での30%の貢献、および下流のマッピング段階(転写因子 → 発現)での20%の貢献
  • 転写因子のリン酸化は30%低い → 上流のERK活性は?15%低い → ERK段階での15%の貢献
  • ERK活性は15%低い → MEK?8%低い → MEKからの8%の貢献
  • ... 上流に続行

各ステップで、「このステップが下流の異常にどれだけ貢献したか」を計算します。方法は次のとおりです。

下流の既知の貢献 × このステップの、下流への感度 = このステップの貢献

これらの2つの要素を掛け合わせて上流に伝播させるのが、バックプロパゲーションが行うことです。これは数学的に連鎖律として定式化されます。

**重要な観察点:**この逆方向の追跡を実行する前に、最初にフォワード方向に通過し(配位体 → 発現)、各ステップの正常な値(ベースライン)を知っておく必要があります。言い換えれば、1回のフォワード測定 + 1回の逆方向の追跡により、各上流ノードの貢献がわかります。これが、バックプロパゲーションが有限差分法よりもはるかに高速である理由です(有限差分法では、各パラメータに対して繰り返しのフォワードパスが必要です)。

連鎖律:逆方向にたどる計算

バックプロパゲーションの根幹である連鎖律を、できるだけ少ない数学を使って理解しましょう。

複合関数があるとします。x が入力されると、まず y = f(x) が計算され、次に z = g(y) が計算されます。最後に、z = g(f(x)) となります。

x がわずかに変化したときに、z がどれだけ変化するかを知りたいのです。つまり、dz/dx を計算したいのです。

直接計算することもできますが、連鎖律はこれを2つのステップに分割します。

text
dz/dx = (dz/dy) × (dy/dx)

言葉で言うと、xy をどれだけ変化させるか」 に、yz をどれだけ変化させるか」 を掛け合わせると、xz をどれだけ変化させるか」 になります。

生物学的カスケードの比喩に戻ると、「リガンド濃度は遺伝子発現をどれだけ変化させるか」は、いくつかのステップの積で表されます。

text
Δ(expression)/Δ(ligand) =
   Δ(expression)/Δ(transcription_factor) × Δ(transcription_factor)/Δ(ERK) × Δ(ERK)/Δ(MEK) × ... × Δ(receptor)/Δ(ligand)

各矢印において、「このステップから次のステップへの感度」が掛け合わされ、最終的にリガンドから発現までの全体的な感度が得られます。

ニューラルネットワークも全く同じです。損失関数 L は、最後のレイヤーの出力の関数であり、最後のレイヤーの出力は、その前のレイヤーの出力の関数であり、最終的には最初のレイヤーのパラメータの関数となります。

連鎖律により、最初のレイヤーのパラメータに関する L の偏微分は、各レイヤーにおける感度の積となります。バックプロパゲーションは、この積を逆方向に計算するプロセスです。


バックプロパゲーションアルゴリズムの骨格

それでは、アルゴリズムを整理しましょう。L 個のレイヤーを持つニューラルネットワークがあると仮定します。

ステップ 1: 順伝播

ニューラルネットワークに、入力から出力までデータを渡し、各レイヤーの活性化値を計算して保存します。

text
a^(0) = input
a^(1) = σ(W^(1) · a^(0) + b^(1))
a^(2) = σ(W^(2) · a^(1) + b^(2))
...
a^(L) = σ(W^(L) · a^(L-1) + b^(L))

a^(l) はレイヤー l の活性化ベクトル、W^(l)·b^(l) はレイヤー l の重み行列・バイアスベクトル、σ は活性化関数です。これはパート2の図です。

重要なのは、各レイヤーの a^(l) の値をメモリに保存することです。これは、バックプロパゲーションのステップで必要になります。このため、トレーニングには推論よりもはるかに多くのGPUメモリが使用されます。推論には順伝播のみが必要ですが、トレーニングでは、バックプロパゲーションのステップまで、すべてのレイヤーの活性化値を保持する必要があります。

ステップ 2: 損失の計算

最後のレイヤーの出力 a^(L) と正解 y を使用して、損失を計算します。

text
L = CrossEntropy(a^(L), y)

これにより、損失の、最後のレイヤーの活性化値に対する偏微分である δ^(L) = ∂L/∂a^(L) が得られます。

Softmax + クロスエントロピーの組み合わせの場合、この偏微分は驚くほどエレガントです。

text
δ^(L) = a^(L) - y

つまり、「予測された確率分布から正解のワンホットベクトルを引く」ということです。このエレガントさこそが、Softmax + CEが一緒に使用される理由です。付録A.4で導出されます。

ステップ 3: バックプロパゲーション

δ^(L) から開始し、レイヤーを逆方向にたどりながら、各レイヤーの δ^(l) を計算します。

text
δ^(l) = (W^(l+1))^T · δ^(l+1) ⊙ σ'(z^(l))

は要素ごとの乗算、z^(l) = W^(l) · a^(l-1) + b^(l) は活性化関数を通す前の値です。σ' は活性化関数の微分です。

この方程式は何をするのでしょうか?

  • (W^(l+1))^T · δ^(l+1):これは、次のレイヤーからの誤差信号を、このレイヤーの活性化空間に投影します。これは、次のレイヤーに信号を送るために使用された重みを、逆方向に渡します。
  • ⊙ σ'(z^(l)):これは、このレイヤーでの活性化関数の局所勾配で乗算します。活性化関数が「死んでいる」(例えば、z < 0 のReLUニューロン)場合、σ' は0になり、誤差はブロックされます。

これをレイヤー L からレイヤー 1 まで繰り返して、すべてのレイヤーの δ^(l) を取得します。

ステップ 4: パラメータの偏微分の計算

各レイヤーの δ^(l) を取得したら、そのレイヤーの重みとバイアスに関する偏微分をすぐに取得できます。

text
∂L/∂W^(l) = δ^(l) · (a^(l-1))^T
∂L/∂b^(l) = δ^(l)

これらは、パート3で議論された実際の勾配です。次に、パート3のオプティマイザー(例:Adam)が、この勾配を使用してパラメータを更新します。


なぜこれほど高速なのか?

バックプロパゲーションの素晴らしい点は、すべてのパラメータの偏微分が、1回の順伝播と1回の逆伝播で取得できることです。これは、有限差分法とは対照的で、有限差分法では各パラメータに対して複数の順伝播が必要です。

スケール感を把握しましょう。バックプロパゲーションの計算量は、順伝播の約2〜3倍です。したがって、3362万個のパラメータを持つニューラルネットワークの1回のトレーニングステップには、順伝播のおおよそ3〜4倍の時間がかかります。有限差分法で必要な3362万回の順伝播と比較すると、これは約800万倍高速です。

このアルゴリズムがなければ、現代の深層学習は存在しないでしょう。実際、1986年にRumelhart-Hinton-Williams論文が発表され、現代的なバックプロパゲーションの形式が確立されたことで、多層ニューラルネットワークのトレーニングが現実的になり、今日私たちが目撃しているAIブームが始まりました。

生物学的シナリオに戻ると: シグナルカスケードの分析において、上流の各ノードに対して個別の実験を行うわけではありません。1つの通常の刺激 + 1つの異常な状況の観察 + 1回の逆方向のトレースによって、各上流ノードの貢献度を把握できます。有限差分法は、各ノードを個別にノックアウトまたはノックダウンすることに相当するため、各ノードに対して実験が必要になります。バックプロパゲーションスタイルの原因分析が実験コストの面でこれほど効率的である理由は、同じです。

計算グラフ:PyTorchが実際にどのように動作するか

これまでの説明では、層ごとにニューラルネットワークを扱ってきました。しかし、実際の深層学習フレームワーク(PyTorch、JAX)は、より一般的な形式で逆伝播を処理します。それが計算グラフです。

基本的な考え方は次のとおりです。フレームワークがフォワードパスのコードを実行すると、各演算(加算、乗算、行列乗算、softmaxなど)をグラフ内のノードとして記録します。グラフの辺は、データの流れを表します。

text
x → (W_1で乗算) → z_1 → (ReLU) → a_1 → (W_2で乗算) → z_2 → ...

各演算ノードは、実行する演算と、受け取った入力に関する情報を格納します。このグラフが完了すると、損失 L から始めて、逆順にグラフをたどり、各ノードの局所勾配を乗算して、すべてのパラメータの偏微分を求めます。

この自動化された逆伝播は、**自動微分(autograd)**と呼ばれます。現在、ニューラルネットワークの開発者は、手動で逆伝播コードを書く必要はありません。フォワードパスのコードだけを記述すれば、フレームワークが自動的に計算グラフを作成し、逆伝播を処理します。

PyTorchでは、次のようになります。

python
import torch
x = torch.randn(32, 100) # バッチサイズ32、特徴量100
W1 = torch.randn(100, 50, requires_grad=True)
W2 = torch.randn(50, 3, requires_grad=True)
y_true = torch.randint(0, 3, (32,))
# フォワードパス - PyTorchが自動的に計算グラフを構築
z1 = x @ W1
a1 = torch.relu(z1)
logits = a1 @ W2
loss = torch.nn.functional.cross_entropy(logits, y_true)
# 逆伝播 - この1行で、すべての偏微分が計算されます
loss.backward()
# 各パラメータの偏微分は、W1.gradとW2.gradに格納されます
print(W1.grad.shape, W2.grad.shape)

loss.backward()という1行のコードには、上で説明した4つのステップがすべて含まれています。この自動化のおかげで、開発者は新しいアーキテクチャを試す際に、フォワードパスに集中できます。

生物学的な視点から: この計算グラフは、システム生物学における制御ネットワークの表現と概念的に同じです。各ノードは、反応または制御関係を表し、辺は因果的な流れを表します。システム生物学者が制御ネットワークにおいて、特定のダウンストリーム表現型への各遺伝子の寄与を分析する方法は、計算グラフにおける自動微分と本質的に同じロジックです。


勾配消失と勾配爆発:逆伝播の災い

逆伝播の乗算構造は、予期しない問題を引き起こす可能性があります。

勾配消失: 各層の局所勾配が1未満の場合(例えば、シグモイド活性化関数の微分は最大で0.25)、勾配は複数の層を通過して乗算されるにつれて、指数関数的に減少します。20層のニューラルネットワークでは、勾配が最初の層に到達する頃には、ほぼゼロになります。これにより、最初の層のパラメータは学習されません。

勾配爆発: 逆に、局所勾配が1より大きい場合、それらは指数関数的に増加します。最初の層のパラメータの勾配は、天文学的な大きさの値になり、パラメータが大きく変動し、学習が発散する原因となります。

解決策(パート#2 A.8 初期化、詳細はパート#12を参照):

  • ReLUベースの活性化関数: 活性化値が正の領域では、微分が正確に1になるため、乗算されると消失することはありません。
  • Xavier/He初期化: 勾配が最初から消失しないように、層のサイズに基づいて初期重みの分散を調整します。
  • バッチ正規化/レイヤー正規化: 層の活性化値の分布を調整して、勾配のスケールを維持します。
  • 残差接続(パート#5): 層をスキップするショートカットを作成することで、勾配が複数の層を通過して乗算される必要がなくなります。これは、ResNetとTransformerの鍵となります。
  • 勾配クリッピング: 勾配爆発を強制的に特定の値以下にクリップします。

生物学的なアナロジー: これは、シグナルカスケードの各ステップが、乗算される増幅または減衰係数を持つという構造と同じです。自然界では、細胞はこの問題を解決するために進化してきました。各ステップには、正と負のフィードバックループ、MAPKスカフォールドタンパク質(シグナル強度を調整)、およびリン酸化と脱リン酸化のバランスがあります。ニューラルネットワークで使用される初期化、正規化、および残差技術は、概念的に細胞シグナル伝達システムのこれらの制御メカニズムに対応します。

生物学における応用シナリオ

シナリオ1:細胞タイプ分類器の学習の現実

パート#3で説明したscRNA-seq細胞タイプ分類器の学習を行います。これをPyTorchで実装する場合、フォワードパスのみを記述すればよいのです。

python
class CellTypeClassifier(torch.nn.Module):
def __init__(self, n_genes, n_types, hidden=512):
super().__init__()
self.encoder = torch.nn.Sequential(
torch.nn.Linear(n_genes, hidden),
torch.nn.ReLU(),
torch.nn.Dropout(0.3),
torch.nn.Linear(hidden, hidden // 2),
torch.nn.ReLU(),
torch.nn.Linear(hidden // 2, n_types),
)
def forward(self, expr_matrix):
return self.encoder(expr_matrix)
model = CellTypeClassifier(n_genes=20000, n_types=25)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3)
for cells, labels in train_loader:
logits = model(cells) # フォワードパス
loss = torch.nn.functional.cross_entropy(logits, labels)
optimizer.zero_grad()
loss.backward() # 自動バックプロパゲーション
optimizer.step() # Adamによる更新

loss.backward()は、このセクションで説明した4ステップアルゴリズムを自動的に実行します。開発者は、フォワードパスの構造と、細胞タイプ分類に必要な損失関数を選択することに集中すればよいのです。

シナリオ2:タンパク質配列の埋め込み(ESM)の学習

Meta AIのESM(Evolutionary Scale Modeling)は、タンパク質配列の埋め込みを学習するモデルです。UniProtから得られた数億ものタンパク質配列を学習データとして使用します。この学習も、バックプロパゲーションの力を利用しています。パラメータ数は、パート#2で見た規模(約150億パラメータ)の数千倍も大きくなっています。これほど大規模なニューラルネットワークを実際に学習できるのは、バックプロパゲーションの計算効率の高さによるものです。

ESMが学習されると、各タンパク質配列はベクトルとして表現され、このベクトルはAlphaFold、タンパク質機能予測、および創薬において広く使用されています。

シナリオ3:システム生物学モデルのパラメータ推定

一部のシステム生物学の研究室では、自動微分を使用して、細胞シグナル伝達カスケードの常微分方程式(ODE)モデルのパラメータをデータに適合させています。損失の各パラメータに関する勾配は、自動微分を使用して取得され、パラメータは勾配降下法を使用して最適化されます。これは本質的に、ニューラルネットワークの学習と同じ手順です。これは微分可能なプログラミングまたはScientific MLと呼ばれ、JAXやPyTorchなどのフレームワークにおける新しい応用分野です。


主要なポイント

  • バックプロパゲーションは、1回のフォワードパスと1回のバックワードパスで、すべてのパラメータの偏微分を取得する効率的なアルゴリズムです。
  • 基盤となる数学は連鎖律です。複数の関数の合成の導関数は、各ステップの局所的な導関数の積です。
  • アルゴリズムは、次の4つのステップで構成されます:フォワードパス(活性化値を保存)、損失の計算、誤差信号のバックプロパゲーション(δの計算)、および各層のパラメータの偏導関数の計算。
  • 今日のフレームワーク(PyTorch、JAX)は、計算グラフ+自動微分を使用して、このプロセスを完全に自動化します。開発者は、フォワードパスのみを記述すればよいのです。
  • 勾配消失と勾配爆発の問題は、活性化関数、初期化、正規化、残差接続、および勾配クリッピングの組み合わせによって軽減されます。
  • 自動微分は、ニューラルネットワークの外部でも、システム生物学や科学計算におけるパラメータ最適化ツールとして使用されています。

📐 付録 — 専門家向けの数学的公式

難易度: 非常に難しい 対象読者: 線形代数、多変数微分積分学、および最適化理論に関する大学院レベルの知識を持つ読者。

A.1 スカラー関数の連鎖律

最も単純な形。z = g(y)y = f(x)、かつ両方がスカラー関数である場合:

text
dz/dx = (dz/dy) · (dy/dx)

複数のステップがある場合:

text
dz/dx = (dz/dy_k) · (dy_k/dy_{k-1}) · ... · (dy_2/dy_1) · (dy_1/dx)

A.2 多変数関数の連鎖律

z = g(y_1, y_2, ..., y_m)、かつ各y_i = f_i(x_1, ..., x_n)である場合:

text
∂z/∂x_j = Σ_{i=1}^{m} (∂z/∂y_i) · (∂y_i/∂x_j)

これはベクトル/行列形式で、ヤコビ行列の積として書き直すことができます。

y = f(x)、かつx ∈ ℝ^ny ∈ ℝ^mの場合、ヤコビ行列は次のようになります:

text
J_f = ∂y/∂x = [ ∂y_i/∂x_j ]_{i,j}    (m × n 行列)

z = g(f(x))のヤコビ行列は次のようになります:

text
J_{g∘f} = J_g · J_f

バックプロパゲーションは、まさにこの行列積を右から左(入力方向)へ計算するプロセスです。左から右へ計算すると、フォワードモード自動微分になります。ニューラルネットワークのように、入力次元が大きく、出力がスカラー(損失)である場合、バックワードモードの方がはるかに効率的です。

A.3 バックプロパゲーションの層ごとの公式(完全形)

L層の全結合ニューラルネットワークの場合:

フォワードプロパゲーション:

text
z^(l) = W^(l) a^(l-1) + b^(l)
a^(l) = σ(z^(l))

損失:

text
L = ℓ(a^(L), y)

バックプロパゲーション - 最終層のエラー信号:

text
δ^(L) = ∂L/∂z^(L) = (∂ℓ/∂a^(L)) ⊙ σ'(z^(L))

バックプロパゲーション - 層 l のエラー信号(l = L-1, L-2, ..., 1):

text
δ^(l) = ((W^(l+1))^T δ^(l+1)) ⊙ σ'(z^(l))

各層のパラメータの損失に対する偏微分:

text
∂L/∂W^(l) = δ^(l) (a^(l-1))^T
∂L/∂b^(l) = δ^(l)

ミニバッチの場合、これらの偏微分は、バッチ内のサンプルに対して平均化されます。

A.4 ソフトマックス + クロスエントロピーの簡潔な偏微分

ソフトマックス:

text
p_i = exp(z_i) / Σ_k exp(z_k)

クロスエントロピー(正解のクラスがcの場合):

text
L = -log(p_c)

∂L/∂z_iを計算します。

ケース1: i = c(正解のクラス):

text
∂L/∂z_c = -1 + p_c = p_c - 1

ケース2: i ≠ c(不正解のクラス):

text
∂L/∂z_i = p_i

正解をワンホットベクトルyで表すと、両方のケースを1つの式にまとめることができます:

text
∂L/∂z = p - y

つまり、予測された確率分布からワンホットエンコードされた正解を引いたものです。非常にエレガントで、ソフトマックス + クロスエントロピーが一緒に使用される理由です。

A.5 活性化関数の導関数

シグモイド: σ(z) = 1/(1+e^{-z})

text
σ'(z) = σ(z)(1 - σ(z))

最大値は0.25(z=0の場合)。複数の層で乗算すると、指数関数的に減衰する→勾配消失問題。

Tanh: tanh(z) = (e^z - e^{-z})/(e^z + e^{-z})

text
tanh'(z) = 1 - tanh^2(z)

最大値は1。シグモイドよりも優れているが、極端な値では導関数が0になる。

ReLU: ReLU(z) = max(0, z)

text
ReLU'(z) = 1 if z > 0 else 0

正の値の領域では正確に1。勾配消失問題を大幅に軽減する。ただし、dying ReLU問題(負の領域にあるニューロンは、勾配が0になるため学習が停止する)が発生する。

Leaky ReLU: LeakyReLU(z) = z if z > 0 else αz (α=0.01)

text
LeakyReLU'(z) = 1 if z > 0 else α

負の領域で小さな勾配を維持する。

GELU: GELU(z) = z · Φ(z) (Φ: 標準正規分布の累積分布関数)

text
GELU'(z) ≈ Φ(z) + z · φ(z)

Transformerで標準的に使用される。自然な平滑化。

A.6 計算グラフと逆モード自動微分

計算グラフ G = (V, E):

  • ノード V: 各原子操作(加算、乗算、行列乗算、活性化関数など)
  • エッジ E: データの流れ

各ノード v に対して:

  • 事前に、局所的な偏微分 ∂v/∂parent_i を計算できる関数を定義する(フレームワークに組み込まれている)。

逆モード自動微分:

  1. 出力ノードから ∂L/∂L = 1 で開始する。
  2. グラフの逆トポロジ順にノードをたどる。
  3. 各ノードで、上流ノードの偏微分と局所的な偏微分の積を伝播させる。
  4. パラメータノードに到達したら、それが最終的なパラメータ偏微分になる。

時間計算量:フォワードプロパゲーションと同程度(O(F) — ニューラルネットワーク内の総演算回数)。 空間計算量:すべての活性化を保存する必要があるため、メモリ要件はフォワードプロパゲーションと同程度。

A.7 勾配チェックポイント

トレーニングメモリを削減するためのテクニック。フォワードプロパゲーション中に、すべての活性化を保存するのではなく、一部のみを保存し、バックプロパゲーション中に、必要な活性化をフォワードプロパゲーションを再度実行して再計算する。

  • 時間:フォワードプロパゲーションを2回、バックプロパゲーションを1回実行する→約1.5倍の時間がかかる。
  • 空間:活性化の保存量を、L(L層のニューラルネットワーク)の平方根に削減する。

Part #14(大規模言語モデルのトレーニングの実践)で述べられているように、大規模なモデルをトレーニングするための重要なテクニック。

A.8 勾配クリッピング

勾配爆発に対処するためのテクニック。勾配のL2ノルムが閾値 c を超える場合、スケールダウンする:

text
if ||∇||_2 > c:
    ∇ ← ∇ · (c / ||∇||_2)

c は通常1.0。Transformerトレーニングではほぼ標準。

A.9 勾配チェック(実装の検証)

バックプロパゲーションコードと有限差分を比較して、精度をチェックする:

text
∂L/∂θ_i ≈ [L(θ + ε · e_i) - L(θ - ε · e_i)] / (2ε)

e_i は i 番目の単位ベクトルで、ε ≈ 1e-5

相対誤差メトリック:

text
relative_error = |grad_analytic - grad_numeric| / max(|grad_analytic|, |grad_numeric|)

一般に、相対誤差が1e-7未満であれば、実装は正確であると見なされ、1e-5未満であれば、許容範囲内の数値誤差であり、1e-3を超える場合は、バグが疑われます。

A.10 バックプロパゲーションの時間計算量の概要

  • フォワードプロパゲーション時間: O(F) — ニューラルネットワーク内の総演算回数(FLOPs)。
  • バックプロパゲーション時間: O(F) — フォワードプロパゲーションと同程度(定数因子は2〜3)。
  • 有限差分を使用して勾配全体を計算する時間: O(P · F) — パラメータ数 × フォワードプロパゲーション。

バックプロパゲーションは、パラメータ数に依存しない時間で、勾配全体を計算します。これが、大規模なニューラルネットワークのトレーニングを可能にする主な理由です。

この時間計算量の優雅さは、バウア-シュトラーセンの定理(1983年)として知られ、自動微分の理論的根拠を形成しています。

参考文献

このセクションで紹介するすべてのコンテンツ、シナリオ、比喩、図は、BioPlaygroundが社内で開発したものです。以下の参考文献は、これらの概念を理解するのに役立ちます。

  • バックプロパゲーションに関する原著論文: Rumelhart, Hinton, Williams, "Learning representations by back-propagating errors" (Nature 1986)
  • 自動微分に関する計算理論: Baur & Strassen, "The complexity of partial derivatives" (Theoretical Computer Science 1983)
  • 標準的な深層学習の教科書: Goodfellow et al., "Deep Learning" 第6章(バックプロパゲーション)
  • 自動微分に関する実践的なガイド: Baydin et al., "Automatic Differentiation in Machine Learning: a Survey" (JMLR 2018)
  • PyTorchの自動微分に関するドキュメント: pytorch.orgの自動微分チュートリアル
  • JAXの自動微分: jax.readthedocs.io — 関数型自動微分の最新の実装
  • 深層学習の可視化による教育: 3Blue1Brown "Deep Learning" 第3章・第4章 (YouTube) — 教育目的での参考文献
  • ESM論文: Rives et al., "Biological structure and function emerge from scaling unsupervised learning to 250 million protein sequences" (PNAS 2021)

このセクションで、ニューラルネットワークのトレーニングにおける両方の軸(損失関数の探索方法と勾配の計算方法)について説明しました。第5部から、このトレーニング機械がどのように言語に合わせて再構築され、Transformerになったのかについて説明します。

次の概念

  • エピソード #5 transformer-and-embedding — Transformerの埋め込み、位置エンコーディング、残差接続は、なぜ学習を安定させるのでしょうか?
  • エピソード #6 attention-mechanism — 注意スコアの勾配は、なぜ文脈を理解するための鍵となるのでしょうか?
  • エピソード #12 pytorch-basics — このエピソードで学んだ理論をコードで実践しましょう。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...