ニューラルネットワーク実装のトラブルシューティング


7

私はStandford / Coursera Machine Learningコースを受講しました。そしてそれはかなり順調に進んでいます。コースから成績を取得するよりも、トピックの理解に本当に興味があるので、私はすべてのコードをより流暢なプログラミング言語で書き込もうとしています(簡単に掘り下げることができるもの)のルーツ)。

私が最もよく学ぶ方法は、問題に取り組むことです。そのため、ニューラルネットワークを実装しましたが、機能しません。テストの例に関係なく、各クラスの確率は同じになるようです(たとえば、入力値に関係なく、クラス0の0.45、クラス1の0.55)。奇妙なことに、すべての非表示のレイヤーを削除した場合、これは当てはまりません。

ここに私がすることの簡単な概要があります。

Set all Theta's (weights) to a small random number

for each training example

set activation 0 on layer 0 as 1 (bias)
set layer 1 activations = inputs

forward propagate;
 Z(j+1) = Theta(j) x activation(j)  [matrix operations]
 activation(j+1) = Sigmoid function (Z(j+1)) [element wise sigmoid]

Set Hx = final layer activations

Set bias of each layer (activation 0,0) = 1

[back propagate]
calculate delta;
delta(last layer) = activation(last layer) - Y  [Y is the expected answer from training set]

delta(j) = transpose(Theta(j)) x delta(j+1) .* (activation(j) .*(Ones - activation(j))

[where ones is a matrix of 1's in every cell; and .* is the element wise multiplication]
[Don't calculate delta(0) since there ins't one for input layer]


DeltaCap(j) = DeltaCap(j) + delta(j+1) x transpose(activation(j))

Next [End for]

Calculate D;

D(j) = 1/#Training * DeltaCap(j) (for j = 0)

D(j) = 1/#Training * DeltaCap(j) + Lambda/#Training * Theta(j) (for j = 0)


[calculate cost function]

J(theta) = -1/#training * Y*Log(Hx) + (1-Y)*log(1-Hx) + lambda/ (2 * #training) * theta^2

Recalculate Theta

Theta = Theta - alpha * D

おそらく、それはそれほど大きなことではありません。私のコードに素晴らしいと思われる大きな欠陥があるかどうか誰かが私に言うことができるなら、そうでなければ私がどこで間違っているのか、そのようなものをデバッグする方法のいくつかの一般的な考えも素晴らしいでしょう。

編集:

これは、ネットワークの簡単な画像です(入力と応答のテストケースを含む)(これは、勾配降下の100万回の反復後)。

ここに画像の説明を入力してください

私が使用したデータセットは、xとしての2つの試験のスコアと、yとしての大学入学の成功/失敗です。明らかに2つのテストスコアが0の場合、大学に入学できなかったことを意味しますが、ネットワークでは、0を入力として取得する確率が56%であることを示唆しています。

編集#2;

勾配チェックアルゴリズムを実行して、次のような結果が得られました。

数値計算:-0.0074962585205895493伝播の値:0.62021047431540277

数値計算:0.0032635827218463476伝播の値:-0.39564819922432665

など明らかにここに何か問題があります。私はそれを処理するつもりです。


1
重みをどのように初期化しますか?バックプロップアルゴリズムによって生成された勾配をチェックしてみましたか(これには、フィードフォワードネットワークを何回も実行し、各重みにわずかなばらつきを付けて、出力での差を測定することを含みます)?
Neil Slater

@NeilSlater重みを次のように初期化します:rnd()×2×e -e [基本的に-eとeの間の小さな数を選択します。私はまだ勾配チェックを行っていません。そのプロセスはまだ100%明確ではありません。J(シータ)とJ(シータ)1-J(シータ)0をプロットします[現在のJ(シータ)-最後]。
FraserOfSmeg


私の知る限り、コードに大きな欠陥はありません。ただし、多くの小さなことがうまくいかない場合があります。まず、ex4.mなどの提供されたスケルトンコードを使用してコードを実装することをお勧めします。特に、sigmoidGradient.mを使用すると、勾配計算が正しいかどうかを確認できます。
玉泉2015

回答:


1

入力はスケーリングされていますか?そうしないと、ウェイトがすぐに膨らむ可能性があります。

入力を-1から1の間、または少なくともその範囲になるように前処理するのが一般的な方法です。そうしないと、グラデーションが爆発または消失するリスクがあります(ここで説明します)。


入力をありがとう(しゃれが意図されています)ですが、両方の入力は100のうちのスコアなので、両方の機能は同じスケールであるため、機能のスケーリングは必要ありません(少なくともそれは私の理解ですか?)。それでも私はこれについても考え、各値を0〜1(スコア/ 100)にスケーリングして試してみましたが、同じ問題が発生しました。
FraserOfSmeg

数回の反復で各レイヤーのアクティブ化を確認しましたか?
jamesmf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.