Wie kann man Eingaben transformieren und nützliche Ausgaben in einem neuronalen Netzwerk extrahieren?

9

Seit ich auf Adam Geitgeys Blog über maschinelles Lernen gestoßen bin, habe ich versucht, neuronale Netze zu verstehen . Ich habe so viel wie möglich zu diesem Thema gelesen (was ich verstehen kann) und glaube, ich verstehe alle allgemeinen Konzepte und einige der Funktionen (obwohl sie in Mathematik sehr schwach sind), Neuronen, Synapsen, Gewichte, Kostenfunktionen und Backpropagation usw. Ich konnte jedoch nicht herausfinden, wie Probleme der realen Welt in eine neuronale Netzwerklösung übersetzt werden können.

In diesem Fall gibt Adam Geitgey als Beispiel ein Hauspreis-Vorhersagesystem an, bei dem ein Datensatz mit der Anzahl der Schlafzimmer , Sq. Fuß , Nachbarschaft und Verkaufspreis Sie können ein neuronales Netzwerk trainieren, um den Preis eines Hauses vorhersagen zu können. Er hört jedoch auf, eine mögliche Lösung im Code tatsächlich zu implementieren. Das nächste, was er als Beispiel bekommt, ist eine grundlegende Funktion, die zeigt, wie Sie Gewichte implementieren würden:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
  price = 0

  # a little pinch of this
  price += num_of_bedrooms * 1.0

  # and a big pinch of that
  price += sqft * 1.0

  # maybe a handful of this
  price += neighborhood * 1.0

  # and finally, just a little extra salt for good measure
  price += 1.0

  return price 

Andere Ressourcen scheinen sich stärker auf die Mathematik zu konzentrieren, und das einzige grundlegende Codebeispiel, das ich verstehen konnte (dh das ist nicht nur eine Codebasis für die Klassifizierung von Gesangs- und Tanzbildern), ist eine Implementierung, die ein neuronales Netzwerk zu einem XOR ausbildet Tor, das nur in Einsen und Nullen handelt.

Es gibt also eine Wissenslücke, die ich einfach nicht überbrücken kann. Wenn wir zum Rückhauspreis Vorhersage Problem, Hows macht man die Daten geeignet ist, in ein neuronales Netzwerk Fütterung? Zum Beispiel:

  • Anzahl der Schlafzimmer: 3
  • Sq. Fuß: 2000
  • Nachbarschaft: Normaltown
  • Verkaufspreis: 250.000 USD

Können Sie einfach 3 und 2000 direkt in das neuronale Netzwerk einspeisen, weil es sich um Zahlen handelt? Oder müssen Sie sie in etwas anderes verwandeln? Ähnlich ist es mit der Normaltown Wert? Das ist eine Zeichenfolge. Wie können Sie ihn in einen Wert übersetzen, den ein neuronales Netzwerk verstehen kann? Können Sie einfach eine Zahl wie einen Index auswählen, solange diese in allen Daten konsistent ist?

Die meisten Beispiele für neuronale Netze, die ich gesehen habe, sind entweder 0 zu 1 oder -1 zu 1. Wie wandeln Sie am Ende der Verarbeitung den Ausgabewert in etwas um, das wie 185.000 US-Dollar verwendet werden kann? ?

Ich weiß, dass das Beispiel für die Vorhersage von Immobilienpreisen wahrscheinlich kein besonders nützliches Problem ist, da es auf nur drei Datenpunkte massiv vereinfacht wurde. Aber ich habe nur das Gefühl, wenn ich diese Hürde überwinden und eine äußerst einfache App schreiben könnte, die mit Pseudo-Real-Life-Daten trainiert und eine Pseudo-Real-Life-Antwort ausspuckt, hätte ich mir den Rücken gebrochen und könnte treten weiter und vertiefen sich weiter in maschinelles Lernen.

David
quelle

Antworten:

10

Dies ist eine gute Frage, mit der ich mich beim ersten Versuch, eine ANN zu codieren, auseinandergesetzt habe.

Im Folgenden finden Sie eine gute Allzwecklösung, die ich in meinem Code implementiert habe, um zu versuchen, gut verhaltene numerische Daten vorherzusagen. Wenn sich Ihre Daten nicht gut verhalten (dh mit Ausreißern behaftet sind), müssen Sie möglicherweise mehr Arbeit leisten, um die Ein- und Ausgänge zu normalisieren. Einige der fortgeschritteneren Methoden werden beschrieben hier .

Hinweis: Ich gehe davon aus, dass Sie f (x) = tanh (x) als Aktivierungsfunktion verwenden. Wenn dies nicht der Fall ist, sollten Sie nach dem Lesen noch in der Lage sein, zu überlegen, wie Sie Ihre Daten normalisieren können.

So bereiten Sie die Eingabedaten vor:

Die Grundidee ist, dass eine signifikante Variation in jedem Eingabeparameter sich in einer signifikanten Variation in der Aktivierung des Neurons widerspiegeln soll, in das diese Eingaben eingespeist werden. Wenn Sie sich ein Diagramm der Ableitung der tanh (x) -Aktivierungsfunktion ansehen, werden Sie feststellen, dass sich der Bereich mit signifikanter Steigung in einem Abstand von eins oder zwei vom Ursprung befindet. Dies bedeutet, dass unabhängig davon, ob die Eingabe für die Aktivierungsfunktion 2000 oder 3000 beträgt (Werte von x, für die die Ableitung vernachlässigbar klein ist), die Ausgabe der Aktivierung nahezu identisch ist ... sodass der Zustand Ihres Neurons unabhängig von der Differenz zwischen ist 2000 und 3000, und Ihr Netzwerk wird niemals Vorhersagekraft aus Werten in diesem Bereich erzeugen.

Wenn Sie also die Quadratmeterzahl des Hauses in ein Neuron eingeben möchten, müssen Sie die Quadratmeterzahl normalisieren, damit das Netzwerk den Unterschied zwischen 2000 und 3000 erkennen kann Daten werden vom Neuron "bemerkt", um die Eingaben durch Z-Score-Normalisierung zu normalisieren .

  • Sammeln Sie alle Ihre Quadratmeterwerte (aus Ihrem Trainingssatz) und berechnen Sie den Mittelwert und die Standardabweichung. Speichern Sie den Mittelwert und die Standardabweichung. Diese Informationen benötigen Sie, um beim Testen neue Quadratmeterwerte zu normalisieren.

  • Normalisieren Sie den Vektor der Quadratmeterwerte, indem Sie den Mittelwert subtrahieren und dann das Ergebnis durch die Standardabweichung dividieren (natürlich alle Operationen elementweise). Durch Subtrahieren des Mittelwerts werden Ihre Daten am Ursprung zentriert, und durch Teilen durch die Standardabweichung wird sichergestellt, dass der größte Teil zwischen -1 und 1 liegt, wobei die Ausgabe des Neurons am empfindlichsten für die Eingabe ist. Dies wird als Z-Score-Normalisierung bezeichnet, da jeder Eingabewert durch seinen Z-Score ersetzt wird .

  • Führen Sie die obigen Schritte für jede Eingabevariable aus.

Wenn Sie nun jeden Eingabewert durch ein Neuron setzen, ist die Ausgabe des Neurons eine Aktivierung zwischen -1 und 1 (siehe Bild von tanh (x)). Da dies bereits im "sensitiven" Bereich der Aktivierungsfunktion liegt, müssen Sie sich keine Gedanken über die Änderung der Ausgabe der Neuronen der Eingangsschicht machen, bevor Sie sie an die erste verborgene Schicht senden. Geben Sie einfach allen Neuronen der verborgenen Ebene die Ausgaben der vorherigen Ebene direkt - sie können sie problemlos verarbeiten.

Wenn Sie die letzte Schicht (das Ausgangsneuron (die Ausgangsneuronen)) erreichen, erhalten Sie erneut eine Aktivierung zwischen -1 und 1. Sie müssen diese wieder in einen Wert für das betreffende Haus umwandeln , ob dieser Wert als verwendet wird eine Vorhersage in einem Testsatz oder zur Berechnung des Fehlers während des Trainings. Wie auch immer Sie dies tun, Sie müssen nur konsistent sein und beim Training und Testen dasselbe De-Normalisierungsverfahren anwenden. Eine Möglichkeit, darüber nachzudenken, ist: Wenn das Ausgangsneuron (die Ausgangsneuronen) 1 zurückgibt, bedeutet dies, dass das Netzwerk den maximal möglichen Hauswert als Vorhersage zurückgibt . Was sollte der höchste Wert sein, den das Netzwerk schätzen kann? Der richtige Ansatz hängt einfach von Ihrer Anwendung ab. Das habe ich getan:

  • Berechnen Sie den Mittelwert der Ausgabevariablen [die / jede] und speichern Sie sie.
  • Berechnen Sie die maximale Abweichung der Ausgangsvariablen vom Mittelwert. Python:MaxDev = max([abs(DataPoint-numpy.mean(TrainingData)) for DataPoint in TrainingData])
  • Wenn das Netzwerk Ausgaben zwischen -1 und 1 zurückgibt, multiplizieren Sie die Ausgabe mit MaxDevund addieren Sie sie zum Mittelwert.

Zwei grundlegende Schnellprüfungen, mit denen Sie feststellen können, ob Ihr Normalisierungs- / Renormierungsschema geeignet ist (dies sind notwendige, aber möglicherweise nicht ausreichende Bedingungen):

  1. Wenn alle Eingabewerte durchschnittlich sind (z. B. durchschnittliche Anzahl der Schlafzimmer, durchschnittliche Quadratmeter usw.), entspricht die Netzwerkausgabe auch dem Durchschnitt der Ausgabevariablen (z. B. Hauswert)? (Es sollte sein.)
  2. Wenn alle Eingabewerte ungewöhnlich hoch / niedrig sind, ist die Netzwerkausgabe auch ungewöhnlich hoch / niedrig? (Dies funktioniert nur, wenn alle Eingänge positiv mit dem Ausgang verbunden sind. Wenn einige davon in umgekehrter Beziehung zueinander stehen, müssen Sie etwas mehr darüber nachdenken.)

Beachten Sie, dass das hier vorgestellte Schema diese beiden Bedingungen erfüllt.

Beachten Sie, dass Ihr Netzwerk mit diesem Schema nur Hauswerte innerhalb des Bereichs der Hauswerte in Ihrem Trainingsdatensatz vorhersagen kann. Abhängig von der Anwendung kann dieses Verhalten wünschenswert oder unerwünscht sein.

Beispiel: Möglicherweise möchten Sie Ihrem Netzwerk die Vorhersage negativer Hauswerte unmöglich machen. Überlegen Sie, wie Sie dies tun würden. De-Normalisieren Sie die Ausgabe so, dass -1 auf 0 abgebildet wird.

Wenn Sie keine Begrenzung für die Werte festlegen möchten, die Ihr Netzwerk vorhersagen kann, können Sie die Netzwerkausgabe über eine Funktion ausführen, die den Bereich [-1,1] allen reellen Zahlen zuordnet ... wie arctanh (x)! Solange Sie dies während des Trainings tun, passt Ihr Netzwerk seine Gewichte an, um dies zu berücksichtigen.

Ich hoffe das war hilfreich. Lassen Sie mich wissen, wenn Sie weitere Fragen haben. Mein ANN-Modul befindet sich übrigens in Python, daher habe ich möglicherweise sprachspezifische Ratschläge.

Marko Bakić
quelle
Das war sehr nützlich! Jedes Blog / Tutorial, auf das ich stoße, scheint es zu vermeiden (fast absichtlich), diesen Prozess zu beschreiben, aber ja, das alles macht Sinn. Es wird eine Weile dauern, bis ich richtig verdaut habe, aber ich komme wieder, wenn ich weitere Fragen habe. Herzlichen Dank!
David
Also ein paar Fragen. Wenn mein Sq. Die Fußtrainingsdaten waren {2000, 800, 850, 550, 2000}, dann wären meine Z-Score-Eingaben für {1900, 1500, 600} (wenn ich richtig berechnet habe) {1,0496, 0,4134, -1,0177}. Einer dieser Werte ist also> 1 und einer <-1. Was würde ich damit machen? Geben Sie sie unabhängig davon in die Knoten der Eingabeebene ein oder runden Sie sie auf 1 & -1? Warum erzeugen 1900 und 600 diese Werte, wenn sie im Bereich von 550 bis 2000 liegen? Ist dies nur ein Trick der Daten, weil es einen so kleinen Datensatz gibt?
David
Habe ich es in Bezug auf die Renormierung der Ausgabeschicht richtig gemacht, dass Sie die Ausgabe auf die Min- und Max-Werte zeichnen würden? Also wenn der Mindestwert war0einndthemeinxichmum100 und die Ausgabe war Null (unter der Annahme von -1 zu 1), dann würde das 50 $ bedeuten?
David
Denken Sie daran, dass die Eingaben nicht unbedingt zwischen 1 und -1 liegen müssen. Für die Eingaben benötigen Sie lediglich die meisten Daten in diesem Bereich. Ein Wert größer oder kleiner als eins bedeutet, dass der Punkt mehr als eine Standardabweichung vom Mittelwert entfernt ist, sodass dieser Punkt näher am oberen Ende der Daten liegt. Es sollte etwas selten sein, dass Ihre Daten außerhalb von [-1, 1] liegen, noch seltener außerhalb von [-2, 2] und äußerst selten außerhalb von [-3, 3]. Schauen Sie sich tanh (x) an und Sie werden sehen, dass der Empfindlichkeitsbereich nicht nur streng zwischen -1 und 1 liegt, sondern etwas weiter hinausgeht.
Marko Bakić
In Bezug auf die Denormalisierung der Ausgabe habe ich diese Min-Max-Denormalisierung in meiner Implementierung durchgeführt, und Ihre Interpretation ist korrekt, aber das müssen Sie nicht unbedingt tun. Sie können es so gestalten, dass 1 dem doppelten maximalen Hauswert entspricht. Auf diese Weise kann Ihr Netzwerk Hauswerte vorhersagen, die über dem liegen, auf dem Sie es trainiert haben.
Marko Bakić