web-dev-qa-db-ja.com

ニューラルネットワークのバックプロパゲーションを理解する

更新:問題のより良い定式化。

例としてXORニューラルネットワークを使用してバックプロパゲーションアルゴリズムを理解しようとしています。この場合、2つの入力ニューロン+ 1つのバイアス、隠れ層に2つのニューロン+1つのバイアス、および1つの出力ニューロン。

_ A   B  A XOR B
 1    1   -1
 1   -1    1
-1    1    1
-1   -1   -1
_

A sample XOR neural network
(出典: wikimedia.org

確率的バックプロパゲーション を使用しています。

もう少し読んだ後、出力ユニットのエラーが隠れ層に伝播することがわかりました...ニューラルネットワークの入力層に到達すると、各ニューロンがエラー調整を受けるため、最初は混乱していました隠れ層の両方のニューロンから。特に、エラーの分布の仕方を最初は把握するのが難しい。

ステップ1入力の各インスタンスの出力を計算します。
ステップ2出力ニューロン(この場合は1つのみ)とターゲット値の間の誤差を計算します)::
Step 2
ステップ3ステップ2のエラーを使用して、各非表示ユニットhのエラーを計算します。
Step 3

「重みkh」は、非表示ユニットhと出力ユニットkの間の重みです。入力ユニットには出力ユニットに関連付けられた直接の重みがないため、これは混乱を招きます。式を数時間見つめた後、合計の意味について考え始めました。隠れ層ニューロンに接続する各入力ニューロンの重みに出力エラーを掛けて合計するという結論に達し始めました。 。これは論理的な結論ですが、式は「重みkh」(出力層kと隠れ層hの間)を明確に示しているため、少し混乱しているように見えます。

私はここですべてを正しく理解していますか?誰かがこれを確認できますか?

入力層のO(h))とは何ですか?私の理解では、各入力ノードには2つの出力があります。1つは隠れ層の最初のノードに入り、もう1つは2番目のノードに入ります。隠れ層。2つの出力のどちらを式のO(h)*(1 - O(h))部分にプラグインする必要がありますか?
Step 3

47
Kiril

ここに投稿したチュートリアルは、実際には間違っています。私はそれをビショップの2冊の標準的な本と2冊の私の実用的な実装に対して再確認しました。以下に正確に指摘します。

覚えておくべき重要なことは、単位または重みに関して誤差関数の導関数を常に検索しているということです。前者はデルタであり、後者はウェイトを更新するために使用するものです。

バックプロパゲーションを理解したい場合は、連鎖律を理解する必要があります。ここでは連鎖律がすべてです。正確にどのように機能するかわからない場合は、ウィキペディアで確認してください。それほど難しくはありません。しかし、派生を理解するとすぐに、すべてが適切に機能します。約束する! :)

∂E/∂Wは連鎖律を介して∂E/∂o∂o/∂Wに構成することができます。 ∂o/∂Wは、重みに関するユニットのアクティブ化/出力の導関数にすぎないため、簡単に計算できます。 ∂E/∂oは実際にはデルタと呼ばれるものです。 (ここでは、E、o、およびWがベクトル/行列であると想定しています)

エラーを計算できるので、出力ユニット用にそれらを用意しています。 (ほとんどの場合、(t_k --o_k)のデルタに達する誤差関数があります。たとえば、線形出力の場合は2次誤差関数、ロジスティック出力の場合はクロスエントロピーです。)

ここで問題となるのは、内部ユニットの導関数をどのように取得するかです。ユニットの出力は、それらの重みとその後の伝達関数の適用によって重み付けされたすべての入力ユニットの合計であることがわかっています。したがって、o_k = f(sum(w_kj * o_j、for all j))。

つまり、o_jに関してo_kを導出します。 delta_j =∂E/∂o_j=∂E/∂o_k∂o_k/∂o_j=delta_k∂o_k/ o_jなので。したがって、delta_kが与えられると、delta_jを計算できます。

これをやろう。 o_k = f(sum(w_kj * o_j、for all j))=>∂o_k/∂o_j= f '(sum(w_kj * o_j、for all j))* w_kj = f'(z_k)* w_kj。

シグモイド伝達関数の場合、これはz_k(1-z_k)* w_kjになります。 (これがチュートリアルのエラーです、作者はo_k(1-o_k)* w_kj!と言います

30
bayer

あなたの質問が何であるかはわかりませんが、私は実際にそのチュートリアルを自分で試しました。明らかなタイプミスが1つあることを除けば、間違いはありません。

あなたの質問は、バックプロパゲーションhiddenデルタがどのように導出されるかについて混乱しているためだと思います。これが本当にあなたの質問であるなら、考慮してください

alt text
(出典: pandamatak.com

著者がこの方程式をどのように導き出したかについて、あなたはおそらく混乱しています。これは実際には多変量連鎖律の簡単な適用です。つまり、(以下は wikipedia から取得)

「z = f(u、v)の各引数が、u = h(x、y)およびv = g(x、y)のような2変数関数であり、これらの関数はすべて微分可能であると仮定します。連鎖律は次のようになります。

alt text

alt text 「」

ここで、帰納引数によって連鎖律を拡張することを想像してください。

E(z '1、z '2、..、z 'n)ここでz 'k はk番目の出力層の事前アクティブ化の出力であり、z 'k(wji)つまり、Eはz 'の関数であり、z'自体はwの関数です。ji (これが最初は意味をなさない場合think NNの設定方法について非常に注意深く。)n個の変数に直接拡張された連鎖律を適用する:

δE(z '1、z '2、..、z 'n/δwjikδE/δz 'kδz 'k/δwji

これが最も重要なステップです。次に、作成者はチェーンルールを再度適用します。今回は合計内で、 δz 'k/δwji 用語、つまり

δz 'k/δwjiδz 'k/δojδoj/δzjδzj/δwji

連鎖律を理解するのが難しい場合は、多変数微積分のコースを受講するか、教科書のそのようなセクションを読む必要があります。

幸運を。

8
ldog

ステップ3の方程式から読んだものは次のとおりです。

  1. O_h =この非表示ユニットの最後の出力(入力レイヤーのO_hは実際の入力値です)
  2. w_kh =この隠しユニットと次のレイヤーのユニットの間の接続の重み(出力に向けて)
  3. delta_k =次のレイヤーの単位のエラー(出力に向かって、前の箇条書きと同じ単位)

各ユニットには1つの出力しかありませんが、出力と次のレイヤーの間の各リンクには重みが付けられます。したがって、出力は同じですが、リンクの重みが異なる場合、受信側では各ユニットが異なる値を受け取ります。 O_hは常に、最後の反復でのこのニューロンの値を参照します。定義上、入力自体には「エラー」がないため、エラーは入力レイヤーには適用されません。

レイヤーNを計算するにはレイヤーN + 1のエラー値が必要なので、エラーは出力側からレイヤーごとに計算する必要があります。そうです、バックプロパゲーションでは入力と出力の間に直接的な関係はありません。

直感に反するのであれば、方程式は正しいと思います。おそらく紛らわしいのは、各ユニットの順方向伝搬では、ユニットの左側にあるすべてのユニットとリンク(入力値)を考慮する必要がありますが、エラー伝搬(逆方向伝搬)の場合は、右側のユニット(出力)を考慮する必要があることです。処理中のユニットの値)。

3
cjcela