誤差逆伝播法はなぜ順伝播より微分の計算が楽になるのか

こんにちは。ゆうせいです。

ディープラーニングの学習では、誤差逆伝播法(バックプロパゲーション)という手法で、各パラメータの勾配を計算します。この名前を初めて聞いたとき、「なぜわざわざ逆向きに計算するのか。順伝播の途中で一緒に微分を計算すればよいのではないか」という疑問を持つ人は少なくありません。結論から言うと、誤差逆伝播法は、順伝播の途中で素直に微分を計算する方法と比べて、計算量が桁違いに少なくて済みます。この違いは、パラメータの数が多いニューラルネットワークにおいて、決定的な差になります。本記事では、なぜ逆向きに計算すると微分が楽になるのか、その理由を、具体的な計算量の比較を通じて、初心者向けに詳しく解説します。

順伝播と逆伝播の基本的な役割の違い

まず、二つの言葉の役割を整理します。

順伝播とは、入力データを受け取り、各層の計算を経て、最終的な出力(予測値)を計算するプロセスです。データは、入力層から出力層へ向かって、一方向に流れます。

誤差逆伝播法とは、出力層で計算した誤差(損失)を、出力層から入力層へ向かって逆方向に伝えながら、各パラメータが誤差にどれだけ影響しているかを計算するプロセスです。

この二つは、どちらも同じ計算グラフを使いますが、計算をたどる方向が逆です。順伝播が「原因から結果へ」向かうのに対し、逆伝播は「結果から原因へ」向かいます。

そもそも、なぜ微分が必要なのか

ニューラルネットワークの学習では、損失関数の値を小さくするように、各パラメータ(重みとバイアス)を少しずつ更新します。

どの方向にパラメータを動かせば損失が小さくなるかを知るには、損失関数を各パラメータで微分した値、つまり勾配が必要です。

\frac{\partial L}{\partial w}

この式は、パラメータ w をわずかに変化させたとき、損失 L がどれだけ変化するかを表しています。この値が分かれば、勾配降下法によってパラメータを更新できます。

ニューラルネットワークには、数百万から数十億という数のパラメータが存在します。したがって、この勾配を、すべてのパラメータについて、効率よく計算する方法が必要になるのです。

素朴な方法:順伝播の中で微分を計算する場合

数値微分という素朴な方法

最も単純な方法は、数値微分です。あるパラメータ w を、ほんの少しだけ動かして、損失がどれだけ変化するかを実際に計算する方法です。

\frac{\partial L}{\partial w} \approx \frac{L(w + h) - L(w)}{h}

hは、非常に小さな値です。

この方法の問題は明白です。一つのパラメータの勾配を求めるために、順伝播をもう一度、最初から最後まで計算し直す必要があります。

パラメータが100万個あるニューラルネットワークでは、勾配を求めるために、順伝播を100万回以上、繰り返し実行しなければなりません。これは、実用的な計算時間では到底終わりません。

順伝播にあわせて解析的に微分を計算する場合(フォワードモード自動微分)

数値微分ではなく、微分の公式(連鎖律)を使って、解析的に正確な微分値を計算する方法もあります。これを、順伝播の方向に沿って計算するため、フォワードモード自動微分と呼びます。

この方法では、入力から出力に向かって計算を進めながら、同時に「あるひとつのパラメータに対する微分値」も一緒に計算していきます。

問題は、この「あるひとつのパラメータに対する微分値」を、パラメータごとに別々に計算しなければならない点です。

パラメータが w1、w2、w3 と3つあるとします。w1 に関する勾配を求めるには、w1 の微分情報を持たせながら、1回、順伝播を計算します。w2 に関する勾配を求めるには、w2 の微分情報を持たせながら、もう1回、順伝播を計算します。w3 についても同様です。

つまり、パラメータの数だけ、順伝播に相当する計算を繰り返す必要があります。パラメータが100万個あれば、100万回分の計算が必要です。

誤差逆伝播法:逆向きに計算すると、なぜ1回で済むのか

連鎖律を逆向きにたどる発想

誤差逆伝播法は、同じ連鎖律を使いますが、計算の順序を逆にします。出力層の損失から出発し、入力層に向かって、逆向きに微分を伝えていきます。

この発想の転換により、驚くべきことが起こります。すべてのパラメータに関する勾配を、たった1回の逆向きの計算で、まとめて求められるのです。

簡単な例で確認する

3層のネットワークを考えます。

入力 x が、パラメータ w1 を持つ層1を通り、中間出力 h1 になります。

h1 が、パラメータ w2 を持つ層2を通り、中間出力 h2 になります。

h2 が、パラメータ w3 を持つ層3を通り、最終出力 y になります。

y から損失 L が計算されます。

この計算の流れは、次の通りです。

x \rightarrow h_1 \rightarrow h_2 \rightarrow y \rightarrow L

連鎖律を使うと、w1、w2、w3 それぞれに関する勾配は、次のように書けます。

\frac{\partial L}{\partial w_3} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial w_3}

\frac{\partial L}{\partial w_2} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial h_2} \cdot \frac{\partial h_2}{\partial w_2}

\frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial h_2} \cdot \frac{\partial h_2}{\partial h_1} \cdot \frac{\partial h_1}{\partial w_1}

ここで注目してほしいのは、三つの式に、共通する部分がある点です。

w2 の式には、w3 の式で使った「損失Lをyで微分した値」がそのまま含まれています。

w1 の式には、w2 の式で使った「損失Lをyで微分した値」と「yをh2で微分した値」の積が、そのまま含まれています。

つまり、出力に近い層から順番に微分を計算していけば、その結果を、より入力に近い層の計算に、そのまま使い回せるのです。一度計算した部分を、もう一度計算し直す必要がありません。

使い回しがもたらす計算量の削減

この「使い回し」が、計算量削減の正体です。

逆伝播では、出力層側から入力層側へ、一度だけ計算をたどりながら、途中で計算した微分の値を、次の層の計算にそのまま渡していきます。

途中経過を保存しながら1回だけ逆向きにたどることで、すべてのパラメータの勾配が、まとめて手に入ります。

これに対して、順伝播の方向で一つずつパラメータの微分を計算するフォワードモードでは、パラメータごとに、この使い回しが起きません。w1 の計算をしている最中に、w2 やw3 のための情報を、同時に得ることができないのです。それぞれ独立に、最初から計算をやり直す必要があります。

計算量を数式で比較する

ここで、二つの方法の計算量を、もう少し一般化して比較します。

ネットワークの層の数を L、パラメータの総数を P とします。また、出力(損失)は、通常1つのスカラー値です。

フォワードモード自動微分の計算量

フォワードモードでは、1つのパラメータに関する勾配を求めるために、1回分の順伝播に相当する計算が必要です。

すべてのパラメータについて繰り返すため、計算量はおおよそ次のようになります。

計算量 \approx P \times (1回の順伝播の計算量)

パラメータPが100万個であれば、100万倍の計算が必要ということです。

誤差逆伝播法(リバースモード自動微分)の計算量

逆伝播では、出力の数に応じて、1回分の逆向きの計算で済みます。

計算量 \approx (出力の数) \times (1回の順伝播と同程度の計算量)

ニューラルネットワークの損失関数は、通常、1つのスカラー値です。したがって、出力の数は1です。

計算量 \approx 1 \times (1回の順伝播と同程度の計算量)

つまり、パラメータが100万個あっても、1000万個あっても、逆伝播1回分の計算量は、順伝播とほぼ同程度で済みます。

二つの方法の比較表

指標フォワードモード逆伝播(リバースモード)
必要な計算回数パラメータの数に比例出力の数に比例
ニューラルネットでの計算回数数百万回以上1回
適している場面入力の数が少なく、出力の数が多い関数入力の数が多く、出力の数が少ない関数
ニューラルネットとの相性悪い良い

ニューラルネットワークは、入力(パラメータ)の数が非常に多く、出力(損失)の数が1つという構造をしています。この構造こそが、逆伝播が圧倒的に有利になる理由です。

なぜ「逆向き」でなければならないのか

ここまでの説明で、「使い回しができるから速い」ということは分かりました。では、なぜその使い回しは、順向きではなく、逆向きでしか実現できないのでしょうか。

連鎖律の構造に理由がある

連鎖律を思い出してください。

\frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial h_2} \cdot \frac{\partial h_2}{\partial h_1} \cdot \frac{\partial h_1}{\partial w_1}

この式は、出力側の微分(損失Lをyで微分した値)を先に知っていることを前提として、入力側に向かって、掛け算を重ねていく形をしています。

出力に近い部分の微分値は、それより先(入力側)のどのパラメータについて計算する場合でも、共通して必要になる部分です。だからこそ、出力側から先に計算しておけば、後はその値を使い回すだけで済みます。

逆に、入力側から先に微分を計算しようとすると、この共通部分をまだ手に入れていない状態で、パラメータごとに別々の計算を進めることになります。共通部分が後から分かる構造になっているため、使い回しが起きないのです。

損失に近い場所の情報が、すべての計算の土台になる

言い換えると、逆伝播が効率的なのは、ニューラルネットワークの構造上、「損失に一番近い場所の情報」が、すべてのパラメータの勾配計算に共通して必要とされるからです。

この共通の土台を最初に計算し、それを各層に配りながら奥へ進んでいく。これが、誤差逆伝播法の本質です。

実務上のたとえ

この関係を、身近な例で考えてみます。

工場で、100個の部品それぞれが、最終製品の品質にどれだけ影響しているかを調べたいとします。

一つ目の方法は、部品を一つずつ、実際に交換してみて、そのたびに完成品を作り直し、品質の変化を確認する方法です。部品が100個あれば、100回、製品を作り直す必要があります。これがフォワードモードに相当します。

二つ目の方法は、完成品の品質のズレを、工程の最後から最初に向かって、逆にたどっていく方法です。最終工程での品質への影響度が分かれば、その情報をもとに、一つ前の工程への影響度が計算でき、さらにその情報をもとに、さらに前の工程への影響度が計算できます。1回、最後から最初まで逆向きにたどるだけで、100個すべての部品の影響度が分かります。これが誤差逆伝播法に相当します。

部品の数が増えるほど、二つ目の方法の効率のよさが際立ちます。

誤差逆伝播法を実装する際の注意点

順伝播の計算結果を保存しておく必要がある

逆伝播で微分を計算する際には、順伝播のときに計算した中間出力(h1、h2 など)の値が必要になります。

そのため、実装上は、順伝播の計算を行いながら、各層の出力を一時的にメモリへ保存しておきます。逆伝播の計算が終わったら、その保存領域は不要になります。

このメモリ消費が、大きなモデルを訓練する際の制約になることがあります。層の数が多いモデルほど、保存しておくべき中間出力が増えるためです。

PyTorchなどのフレームワークが自動で行っている

PyTorchやTensorFlowといったディープラーニングのフレームワークでは、この逆伝播の計算を、開発者が手動で書く必要はありません。

順伝播の計算式を書くだけで、フレームワークが自動的に計算グラフを構築し、loss.backward() のような命令一つで、すべてのパラメータの勾配を計算してくれます。これを自動微分と呼びます。

内部で行われている処理は、まさに本記事で説明した、出力側から入力側へ向かう連鎖律の計算です。

まとめ

誤差逆伝播法が、順伝播の方向で微分を計算する方法よりも計算が楽になる理由は、連鎖律における共通部分の使い回しにあります。

出力側に近い部分の微分値は、どのパラメータの勾配を求める場合でも共通して必要になります。この共通部分を、出力から入力へ向かって先に計算し、後の計算に使い回すことで、パラメータの数がどれだけ多くても、1回の逆向きの計算だけで、すべての勾配をまとめて求められます。

これに対して、順伝播の方向でパラメータごとに微分を計算する方法では、この使い回しが起きず、パラメータの数だけ計算を繰り返す必要があります。

ニューラルネットワークは、パラメータの数が非常に多く、損失という出力は1つしかないという構造をしているため、この構造上の理由から、誤差逆伝播法が圧倒的に効率的な方法として使われています。

次のステップとして、実際に3層程度の簡単なネットワークを紙の上に書き、連鎖律を使って手計算で勾配を求めてみたり、PyTorchで簡単なモデルを作り、loss.backward() の前後でパラメータの勾配がどう変化するかを確認してみたり、順伝播で保存される中間出力が、モデルのメモリ消費にどう影響するかを調べてみたりすることをお勧めします。その体験を通じて、誤差逆伝播法の効率性が、単なる理論ではなく、実際の学習速度に直結していることが、より実感できるようになるでしょう。

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
海外放浪の末、2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。

学生時代は趣味と実益を兼ねてリゾートバイトにいそしむ。長野県白馬村に始まり、志賀高原でのスキーインストラクター、沖縄石垣島、北海道トマム。高じてオーストラリアのゴールドコーストでツアーガイドなど。現在は野菜作りにはまっている。