Fehlerbehebung bei der Implementierung eines neuronalen Netzwerks

7

Ich habe den Standford / Coursera-Kurs für maschinelles Lernen durchlaufen . und es ist ziemlich gut gelaufen. Ich interessiere mich wirklich mehr für das Verständnis des Themas als für das Erhalten der Note aus dem Kurs und als solches versuche ich, den gesamten Code in einer Programmiersprache zu schreiben, die ich fließender beherrsche (etwas, in das ich mich leicht einarbeiten kann Wurzeln von).

Die Art und Weise, wie ich am besten lerne, ist das Durcharbeiten von Problemen. Ich habe also ein neuronales Netzwerk implementiert und es funktioniert nicht. Ich scheine unabhängig vom Testbeispiel die gleiche Wahrscheinlichkeit für jede Klasse zu erhalten (zum Beispiel 0,45 von Klasse 0, 0,55 von Klasse 1, unabhängig von den Eingabewerten). Seltsamerweise ist dies nicht der Fall, wenn ich alle versteckten Ebenen entferne.

Hier ist ein kurzer Überblick über meine Arbeit.

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

Das ist wahrscheinlich nicht viel zu tun. Wenn mir jemand sagen kann, ob es einen größeren Fehler in meinem Code gibt, der fantastisch wäre, wäre eine großartige Vorstellung davon, wo ich falsch liegen könnte / wie man so etwas debuggt, ebenfalls großartig.

BEARBEITEN:

Hier ist ein kurzes Bild des Netzwerks (einschließlich eines Testfalls mit Eingaben und Antworten) (dies erfolgt nach 1 Million Iterationen des Gradientenabfalls).

Geben Sie hier die Bildbeschreibung ein

Der Datensatz, den ich verwendet habe, besteht aus zwei Prüfungsergebnissen als x und dem Erfolg / Misserfolg einer Universität als y. Offensichtlich würden zwei Testergebnisse von 0 bedeuten, dass der Zugang zur Universität fehlgeschlagen ist. Das Netzwerk schlägt jedoch eine 56% ige Chance vor, diese mit 0 als Eingabe zu erhalten.

Bearbeiten # 2;

Ich habe einen Gradientenprüfungsalgorithmus mit den folgenden Ergebnissen ausgeführt.

Numerische Berechnung: -0.0074962585205895493 Wert aus der Ausbreitung: 0.62021047431540277

Numerische Berechnung: 0,0032635827218463476 Wert aus der Ausbreitung: -0,39564819922432665

usw. Hier stimmt eindeutig etwas nicht; Ich werde es durcharbeiten.

FraserOfSmeg
quelle
1
Wie initialisieren Sie die Gewichte? Haben Sie versucht, die von Ihrem Backprop-Algorithmus erzeugten Gradienten zu überprüfen (dazu muss das Feed-Forward-Netzwerk viele Male ausgeführt werden, wobei jedes Gewicht geringfügig variiert und die Differenz am Ausgang gemessen wird)?
Neil Slater
@NeilSlater Ich initialisiere die Gewichte wie folgt: rnd () × 2 × e -e [wählt im Grunde eine kleine Zahl zwischen -e und e aus, wobei e nur ein Wert nahe Null ist]. Ich habe noch keine Gradientenprüfung durchgeführt, ich bin mir noch nicht 100% klar über diesen Prozess. Ich zeichne J (Theta) und J (Theta) 1-J (Theta) 0 [aktuelles J (Theta) - letztes].
FraserOfSmeg
Soweit ich sehe, gibt es keinen größeren Fehler in Ihrem Code. Viele kleine Dinge können jedoch schief gehen. Ich schlage vor, dass Sie zuerst versuchen, den Code mithilfe der bereitgestellten Skelettcodes zu implementieren, z. B. ex4.m usw. Insbesondere die Verwendung von sigmoidGradient.m kann Ihnen dabei helfen, zu überprüfen, ob Ihre Gradientenberechnung korrekt ist.
Yuqian

Antworten:

1

Sind Ihre Eingaben skaliert ? Andernfalls können die Gewichte sofort explodieren.

Es ist üblich, die Eingabe so zu verarbeiten, dass sie zwischen -1 und 1 liegt oder zumindest in diesem Bereich liegt. Andernfalls besteht die Gefahr, dass Ihre Farbverläufe explodieren oder verschwinden (siehe hier ).

jamesmf
quelle
Vielen Dank für die Eingabe (Wortspiel beabsichtigt), aber da beide Eingaben Punkte von 100 sind, haben beide Features dieselbe Skalierung, sodass keine Feature-Skalierung erforderlich ist (zumindest verstehe ich das?). Trotzdem habe ich auch daran gedacht und es mit jedem Wert versucht, der auf 0 bis 1 (Punktzahl / 100) skaliert ist, aber die gleichen Probleme traten auf.
FraserOfSmeg
Haben Sie sich die Aktivierungen jeder Ebene für einige Iterationen angesehen?
Jamesmf