Ändern Sie das neuronale Netz, um ein einzelnes Beispiel zu klassifizieren

8

Dies ist meine benutzerdefinierte Erweiterung eines neuronalen Netzwerks von Andrew NG aus dem Deep Learning-Kurs, wo ich statt 0 oder 1 für die binäre Klassifizierung zu produzieren versuche um mehrere Beispiele zu klassifizieren.

Sowohl die Eingänge als auch die Ausgänge sind hot-codiert.

Mit wenig Training erhalte ich eine Genauigkeit von 'train accuracy: 67.51658067499625 %'

Wie kann ich ein einzelnes Trainingsbeispiel klassifizieren, anstatt alle Trainingsbeispiele zu klassifizieren?

Ich glaube, dass ein Fehler in meiner Implementierung existiert, da ein Problem mit diesem Netzwerk Trainingsbeispiele (train_set_x) und Ausgabewerte (train_set_y) beide müssen dieselben Dimensionen haben oder ein Fehler in Bezug auf die Dimensionalität von Matrizen erhalten wird. Zum Beispiel mit:

%Vor%

gibt Fehler zurück:

%Vor%

ValueError: Operanden konnten nicht zusammen mit shapes (3,3) (1,4)

gesendet werden

Netzwerkcode:

%Vor%

Update: In dieser Implementierung gibt es einen Fehler, da die Trainingsbeispiel-Paare (train_set_x , train_set_y) dieselben Dimensionen enthalten müssen. Kann in Richtung zeigen, wie lineare Algebra modifiziert werden sollte?

Update 2:

Ich habe die @Paul-Panzer-Antwort so modifiziert, dass die Lernrate 0,001 beträgt und train_set_x, train_set_y-Paare eindeutig sind:

%Vor%

Dieses Update erzeugt folgende Ausgabe:

%Vor%

Soll print(sigmoid(dw @ [0,0,1,1,0] + db)) einen Vektor erzeugen, der einmal abgerundet wurde train_set_y korrespondierender Wert: [0,1,0] ?

Ändern, um einen Vektor mit (% [0,0,1,1,0] zu numpy array zu addieren und Transponieren) zu erzeugen:

%Vor%

gibt zurück:

%Vor%

Auch wenn diese Werte auf die nächste ganze Zahl gerundet werden, wird der Vektor [1,0,1] erzeugt, wenn [0,1,0] erwartet wird.

Dies sind falsche Operationen, um eine Vorhersage für ein einzelnes Trainingsbeispiel zu erstellen?

    
blue-sky 15.11.2017, 13:04
quelle

3 Antworten

5

Ihre Schwierigkeiten kommen von nicht übereinstimmenden Dimensionen, also lassen Sie uns das Problem durchgehen und versuchen, sie zu verstehen.

Ihr Netzwerk hat eine Anzahl von Eingängen, die Funktionen, nennen wir ihre Nummer N_in ( numberOfFeatures in Ihrem Code). Und es hat eine Anzahl von Ausgaben, die verschiedenen Klassen entsprechen, nennen wir ihre Nummer N_out . Ein- und Ausgänge sind mit den Gewichten w verbunden.

Jetzt ist hier das Problem. Die Verbindungen sind all-to-all, also benötigen wir eine Gewichtung für jedes N_out x N_in Paar von Ausgängen und Eingängen. Daher muss in Ihrem Code die Form von w in (N_out, N_in) geändert werden. Sie möchten wahrscheinlich auch einen Offset b für jede Ausgabe, also sollte b ein Vektor der Größe (N_out,) oder eher (N_out, 1) sein, damit er gut mit den 2d Termen spielt.

Ich habe das im unten stehenden modifizierten Code behoben und ich habe versucht, es sehr explizit zu machen. Ich habe auch einen Pseudo-Daten-Schöpfer in den Handel geworfen.

Bei der einheiß codierten kategorischen Ausgabe bin ich kein Experte für neuronale Netzwerke, aber ich denke, die meisten Leute verstehen es so, dass Klassen sich gegenseitig ausschließen, also sollte jedes Sample in Ihrer Pseudoausgabe eins und den Rest haben Nullen.

Seitliche Anmerkung:

An einer Stelle riet Ihnen eine konkurrierende Antwort, die 1-... -Begriffe in der Kostenfunktion loszuwerden. Das sieht nach einer interessanten Idee für mich aus ( Bearbeiten Jetzt bestätigt mit gradientenfreiem Minimierer; benutze activation="hybrid" im folgenden Code. Solver maximiert einfach all Ausgaben, die in mindestens einem Trainingsbeispiel aktiv sind.) Es wird nicht einfach so funktionieren, weil die Kosten dann falsche Positive nicht bestrafen (siehe unten für eine detaillierte Erklärung). Damit es funktioniert, müssen Sie eine Art Regularisierung hinzufügen. Eine Methode, die scheinbar funktioniert, ist die Verwendung von softmax anstelle von sigmoid . Das softmax ist zu eins-heiß was das sigmoid zu binär ist. Es stellt sicher, dass der Ausgang "unscharf ein-heiß" ist.

Deshalb ist meine Empfehlung:

  • Wenn Sie bei sigmoid bleiben und keine One-Hot-Vorhersagen explizit erzwingen möchten. Behalten Sie den 1-... -Begriff bei.
  • Wenn Sie die Funktion für kürzere Kosten verwenden möchten. Erzwinge One-Hot-Vorhersagen. Zum Beispiel mit softmax anstelle von sigmoid .

Ich habe einen activation="sigmoid"|"softmax"|"hybrid" -Parameter zu dem Code hinzugefügt, der zwischen den Modellen wechselt. Ich habe auch den scipy Allzweck-Minimizer verfügbar gemacht, der nützlich sein kann, wenn der Gradient der Kosten nicht zur Hand ist.

Wiederholen Sie die Funktionsweise der Kostenfunktion:

Die Kosten sind eine Summe über alle Klassen und alle Trainingsbeispiele des Begriffs

%Vor%

wobei y die erwartete Antwort ist, d. h. diejenige, die durch den Trainingsprobe "y" für die Eingabe (die "x" Trainingsprobe) gegeben ist. y 'ist die Vorhersage, die Antwort, die das Netzwerk mit seinen aktuellen Gewichten und Verzerrungen erzeugt. Da die erwartete Antwort entweder 0 oder 1 ist, können die Kosten für eine einzelne Kategorie und ein einzelnes Trainingssample geschrieben werden

%Vor%

weil im ersten Fall (1-y) Null ist, so verschwindet der zweite Term und im zweiten Fall ist y Null, so dass der erste Term verschwindet. Man kann sich jetzt davon überzeugen, dass die Kosten hoch sind, wenn

  • die erwartete Antwort y ist 1 und die Netzwerkvorhersage y 'ist nahe bei Null
  • die erwartete Antwort y ist 0 und die Netzwerkvorhersage y 'ist nahe bei 1

Mit anderen Worten, die Kosten machen ihren Job, falsche Vorhersagen zu bestrafen. Wenn wir jetzt den zweiten Term (1-y) log (1-y') fallen lassen, ist die Hälfte dieses Mechanismus weg. Wenn die erwartete Antwort 1 ist, verursacht eine niedrige Vorhersage immer noch Kosten, aber wenn die erwartete Antwort 0 ist, sind die Kosten gleich Null, unabhängig von der Vorhersage, insbesondere einer hohen Vorhersage (oder falsch positiv ) wird ungestraft bleiben.

Jetzt, da die Gesamtkosten eine Summe über alle Trainingsbeispiele sind, gibt es drei Möglichkeiten.

  • Alle Trainingsbeispiele schreiben vor, dass die Klasse null ist:  dann sind die Kosten völlig unabhängig von den Vorhersagen für diese Klasse und es kann kein Lernen stattfinden

  • einige Trainingsbeispiele setzen die Klasse auf Null, einige auf eins:  dann, weil "falsch negative" oder "misses" immer noch bestraft werden, aber falsch positive sind nicht das Netz wird den einfachsten Weg finden, um die Kosten zu minimieren, die die Vorhersage der Klasse für alle Proben unterschiedslos erhöhen soll

  • Alle Trainingsbeispiele schreiben vor, dass die Klasse eins sein soll:  im Wesentlichen das gleiche wie im zweiten Szenario, nur hier ist es kein Problem, denn das ist das richtige Verhalten

Und schließlich, warum funktioniert es, wenn wir softmax anstelle von sigmoid verwenden? Falsche Positive sind immer noch unsichtbar. Jetzt ist es leicht zu sehen, dass die Summe über alle Klassen des Softmax eins ist. Daher kann ich die Vorhersage für eine Klasse nur erhöhen, wenn mindestens eine andere Klasse reduziert wird, um sie zu kompensieren. Insbesondere kann es keine Falsch-Positiven ohne ein Falsches Negatives geben, und das Falsche-Negative werden die Kosten erkennen.

So erhalten Sie eine binäre Vorhersage:

Bei binär erwarteten Antworten ist das Runden in der Tat das geeignete Verfahren. Für einen heißen würde ich lieber den größten Wert finden, diesen auf einen und alle anderen auf Null setzen. Ich habe eine Komfortfunktion, predict , hinzugefügt, die das implementiert.

%Vor%     
Paul Panzer 18.11.2017, 18:48
quelle
3

Sowohl die Idee, wie man den Fehler beheben kann, als auch wie man die Implementierung erweitern kann, um zwischen mehreren Klassen zu klassifizieren, kann mit einer Dimensionalitätsanalyse gelöst werden.

Ich gehe davon aus, dass Sie bei der Klassifizierung mehrerer Beispiele mehrere Klassen und nicht mehrere Stichproben verwenden, da wir mehrere Stichproben benötigen, um auch für zwei Klassen zu trainieren.

Wo N = Anzahl der Proben, D = Anzahl der Merkmale, K = Anzahl der Kategorien (wobei K=2 ein Sonderfall ist, in dem man dies auf eine Dimension reduzieren kann, zB K=1 mit y=0 bedeutet eine Klasse und y=1 die andere). Die Daten sollten folgende Dimensionen haben:

%Vor%

Die Reihenfolge der Dimensionen kann umgestellt werden, solange die Punktprodukte korrekt sind.

  • Erste Behandlung Ihres Fehlers: Sie initialisieren W als N * K anstelle von D * K ie. im binären Fall:

    %Vor%

    Das bedeutet, dass Sie W nur dann initialisieren, wenn Sie die Dimensionen korrigieren möchten, wenn y und X (zufälligerweise) dieselben Dimensionen haben.

    Dies wird auch mit Ihren Dot-Produkten zu tun haben:

    %Vor%

    und

    %Vor%

    Stellen Sie außerdem sicher, dass die Kostenfunktion eine Zahl zurückgibt (dh kein Array).

  • Als nächstes geht es weiter mit K>2 Sie müssen einige Änderungen vornehmen. b ist nicht länger eine einzelne Zahl, sondern ein Vektor (1D-Array). y und W werden vom 1D-Array zum 2D-Array. Um Verwechslungen und schwer zu findende Fehler zu vermeiden, kann es sinnvoll sein, K , N und D auf unterschiedliche Werte zu setzen

M.T 18.11.2017 19:05
quelle
-1

Die Form von A ist (1,4), während die Form von train_set_y (3,3) ist.

Sie können zwei Matrizen, die keine gemeinsame Form auf einer Achse haben, nicht elementweise multiplizieren.

Versuchen Sie, train_set_y so zu gestalten, dass es der Form von A entspricht. Zum Beispiel:

%Vor%     
dportman 15.11.2017 13:13
quelle