Ich trainiere ein neuronales Netzwerk (Details nicht wichtig), bei dem die Zieldaten ein Winkelvektor sind (zwischen 0 und 2 * pi). Ich suche Rat, wie ich diese Daten verschlüsseln kann. Folgendes versuche ich derzeit (mit begrenztem Erfolg):
1) 1-von-C-Codierung: Ich bin die eingestellten möglichen Winkel in etwa 1000 diskrete Winkel und gebe dann einen bestimmten Winkel an, indem ich eine 1 an den entsprechenden Index stelle. Das Problem dabei ist, dass das Netzwerk einfach lernt, alle Nullen auszugeben (da dies fast genau richtig ist).
2) Einfache Skalierung: Ich habe den Ausgangsbereich des Netzwerks ([0,1]) auf [0,2 * pi] skaliert. Das Problem hierbei ist, dass Winkel naturgemäß eine kreisförmige Topologie haben (dh 0,0001 und 2 * pi liegen tatsächlich direkt nebeneinander). Bei dieser Art der Codierung gehen diese Informationen verloren.
Anregungen wäre dankbar!
quelle
Antworten:
Einführung
Ich finde diese Frage wirklich interessant, ich gehe davon aus, dass jemand eine Zeitung darüber herausgebracht hat, aber es ist mein freier Tag, also möchte ich nicht nach Referenzen suchen.
Wir könnten es also als Repräsentation / Codierung der Ausgabe betrachten, was ich in dieser Antwort tue. Ich denke immer noch, dass es einen besseren Weg gibt, wo man einfach eine etwas andere Verlustfunktion verwenden kann. (Vielleicht Summe der quadratischen Differenzen mit Subtraktionsmodulo 2 ).π
Aber weiter mit der eigentlichen Antwort.
Methode
Ich schlage vor, dass ein Winkel als ein Wertepaar dargestellt wird, sein Sinus und sein Cosinus.θ
Die Codierungsfunktion lautet also: und die Decodierungsfunktion lautet: Für arctan2 sind die inversen Tangenten, wobei die Richtung in allen Quadranten beibehalten wird.θ ↦ ( sin( θ ) , cos( θ ) )
( y1, y2) ↦ arctan2 ( y1, y2)
Theoretisch könnten Sie auch direkt mit den Winkeln arbeiten, wenn Ihr Werkzeug
atan2
als Layer-Funktion unterstützt wird (genau 2 Eingaben nehmen und 1 Ausgabe erzeugen). TensorFlow macht dies jetzt und unterstützt den Gradientenabstieg , obwohl es nicht für diese Verwendung vorgesehen ist. Ich habeout = atan2(sigmoid(ylogit), sigmoid(xlogit))
mit einer Verlustfunktion nachgeforschtmin((pred - out)^2, (pred - out - 2pi)^2)
. Ich fand, dass es viel schlimmer trainierte alsouts = tanh(ylogit), outc = tanh(xlogit))
mit einer Verlustfunktion0.5((sin(pred) - outs)^2 + (cos(pred) - outc)^2
. Was meiner Meinung nach darauf zurückzuführen ist, dass der Gradient für unterbrochen istatan2
Mein Test hier führt es als Vorverarbeitungsfunktion aus
Um dies auszuwerten, habe ich eine Aufgabe definiert:
Ich habe eine Funktion implementiert, mit der diese Bilder zufällig mit Linien in zufälligen Winkeln erzeugt werden (Hinweis: In früheren Versionen dieses Beitrags wurden eher zufällige Neigungen als zufällige Winkel verwendet. Dank an @Ari Herman für den Hinweis. Es ist jetzt behoben). Ich habe mehrere neuronale Netze aufgebaut, um die Leistung für die Aufgabe zu bewerten. Die vollständigen Details der Implementierung finden Sie in diesem Jupyter-Notizbuch . Der Code ist alles in Julia und ich benutze die Mocha- Bibliothek für neuronale Netze.
Zum Vergleich stelle ich es den alternativen Skalierungsmethoden von 0,1 gegenüber. und in 500 Behälter zu setzen und Soft-Label-Softmax zu verwenden. Ich bin mit dem letzten nicht besonders glücklich und denke, ich muss es optimieren. Aus diesem Grund probiere ich es im Gegensatz zu den anderen nur für 1.000 Iterationen aus, im Gegensatz zu den beiden anderen, die für 1.000 und für 10.000 ausgeführt wurden
Versuchsaufbau
Die Bilder hatten eine Pixel, wobei die Linie in der Mitte beginnt und bis zum Rand reicht. Das Bild enthielt kein Rauschen usw., nur eine "schwarze" Linie auf weißem Hintergrund.101 × 101
Für jeden Trail wurden 1.000 Trainings- und 1.000 Testbilder zufällig generiert.
Das Bewertungsnetzwerk hatte eine einzige verborgene Schicht mit einer Breite von 500. Sigmoidneuronen wurden in der verborgenen Schicht verwendet.
Es wurde von Stochastic Gradient Decent mit einer festen Lernrate von 0,01 und einem festen Impuls von 0,9 trainiert.
Es wurde keine Regularisierung oder Dropout verwendet. Es gab auch keine Art von Faltung usw. Ein einfaches Netzwerk, von dem ich hoffe, dass sich diese Ergebnisse verallgemeinern lassen
Es ist sehr einfach , diese Parameter in dem zwicken Test - Code , und ich ermutige die Menschen , dies zu tun. (und suchen Sie nach Fehlern im Test).
Ergebnisse
Meine Ergebnisse sind wie folgt:
Wo ich mich auf Fehler beziehe, ist dies der absolute Wert der Differenz zwischen dem vom neuronalen Netz ausgegebenen Winkel und dem wahren Winkel. So ist der mittlere Fehler (zum Beispiel) der Durchschnitt über die 1.000 Testfälle dieses Unterschieds usw. Ich bin nicht sicher, ob ich ihn nicht neu skalieren sollte, indem ich einen Fehler von say gleich mache auf einen Fehler von ). π7 π4 π4
Ich präsentiere auch die Genauigkeit auf verschiedenen Ebenen der Granularität. Die Genauigkeit ist der Teil der Testfälle, die korreliert wurden. Das
accuracy_to_point01
bedeutet, dass es als korrekt gezählt wurde, wenn die Ausgabe innerhalb von 0,01 des wahren Winkels lag. Keine der Darstellungen lieferte perfekte Ergebnisse, aber das ist angesichts der Funktionsweise der Gleitkomma-Mathematik keineswegs überraschend.Wenn Sie sich den Verlauf dieses Beitrags ansehen, werden Sie feststellen, dass die Ergebnisse ein wenig verrauscht sind und sich jedes Mal geringfügig unterscheiden, wenn ich ihn erneut ausführe. Die allgemeine Reihenfolge und Skala der Werte bleibt jedoch gleich. So können wir einige Schlussfolgerungen ziehen.
Diskussion
Binning mit Softmax funktioniert bei weitem am schlechtesten, da ich nicht sicher bin, ob ich bei der Implementierung etwas falsch gemacht habe. Die Leistung liegt jedoch geringfügig über der Rate. Wenn wir nur raten würden, bekämen wir einen mittleren Fehler vonπ
Die Sin / Cos-Codierung ist wesentlich leistungsfähiger als die skalierte 0-1-Codierung. Die Verbesserung besteht darin, dass sin / cos bei 1.000 Trainingsiterationen bei den meisten Metriken etwa dreimal so gut abschneidet wie bei 10.000 Iterationen.
Ich denke, dies hängt zum Teil mit der Verbesserung der Verallgemeinerung zusammen, da beide einen relativ ähnlichen mittleren quadratischen Fehler im Trainingssatz aufwiesen und mindestens einmal 10.000 Iterationen ausgeführt wurden.
Es gibt sicherlich eine Obergrenze für die bestmögliche Leistung bei dieser Aufgabe, da der Winkel mehr oder weniger eine reelle Zahl sein kann, aber nicht alle derartigen Winkel erzeugen unterschiedliche Linien bei einer Auflösung von × Pixeln. Da zum Beispiel die Winkel 45.0 und 45.0000001 bei dieser Auflösung beide an dasselbe Bild gebunden sind, wird keine Methode jemals beide perfekt korrigieren.101 × 101
Es scheint auch wahrscheinlich, dass auf einer absoluten Skala, um über diese Leistung hinauszugehen, ein besseres neuronales Netzwerk benötigt wird. Anstatt der sehr einfachen, die oben im Versuchsaufbau beschrieben wurde.
Fazit.
Es scheint, dass die Sin / Cos-Darstellung bei weitem die beste der Darstellungen ist, die ich hier untersucht habe. Dies ist sinnvoll, da es einen glatten Wert hat, wenn Sie sich im Kreis bewegen. Ich mag es auch, dass das Umkehren mit arctan2 gemacht werden kann , was elegant ist.
Ich glaube, dass die vorgelegte Aufgabe ausreicht, um eine angemessene Herausforderung für das Netzwerk darzustellen. Obwohl ich wirklich denke, dass es nur darum geht, die Kurvenanpassung für es vielleicht zu einfach. Und vielleicht noch schlimmer, es könnte die gepaarte Darstellung begünstigen. Ich glaube nicht, dass es so ist, aber es wird spät hier, also habe ich vielleicht etwas verpasst, das ich Sie noch einmal einlade, meinen Code durchzusehen . Schlagen Sie Verbesserungen oder alternative Aufgaben vor.f( x ) = y1y2x
quelle
tan(angle)
Hier ist eine weitere Python-Implementierung, die Lyndon Whites vorgeschlagene Codierung mit einem Binned-Ansatz vergleicht. Der folgende Code erzeugte die folgende Ausgabe:
quelle
Hier ist meine Python-Version Ihres Experiments. Ich habe viele Details Ihrer Implementierung gleich gehalten, insbesondere die gleiche Bildgröße, Netzwerkebenengröße, Lernrate, Dynamik und Erfolgsmetrik.
Jedes getestete Netzwerk verfügt über eine verborgene Schicht (Größe = 500) mit logistischen Neuronen. Die Ausgangsneuronen sind, wie angegeben, entweder linear oder softmax. Ich habe 1.000 Trainingsbilder und 1.000 Testbilder verwendet, die unabhängig voneinander zufällig generiert wurden (daher kann es zu Wiederholungen kommen). Das Training bestand aus 50 Iterationen durch den Trainingssatz.
Mit Binning und "Gauß" -Codierung (ein Name, den ich mir ausgedacht habe; ähnlich wie Binning, außer dass der Zielausgabevektor die Form exp (-pi * ([1,2,3, ... , 500] - idx) ** 2) wobei idx der Index ist, der dem korrekten Winkel entspricht). Der Code ist unten; Hier sind meine Ergebnisse:
Testfehler für (cos, sin) Kodierung:
1.000 Trainingsbilder, 1.000 Testbilder, 50 Iterationen, lineare Ausgabe
Mittelwert: 0,0911558142071
Median: 0,0429723541743
Minimum: 2.77769843793e-06
Maximum: 6.2608513539
Genauigkeit auf 0,1: 85,2%
Genauigkeit auf 0,01: 11,6%
Genauigkeit bis 0,001: 1,0%
Testfehler für [-1,1] -Codierung:
1.000 Trainingsbilder, 1.000 Testbilder, 50 Iterationen, lineare Ausgabe
Mittelwert: 0,234181700523
Median: 0,17460197307
Minimum: 0,000473665840258
Maximum: 6.00637777237
Genauigkeit auf 0,1: 29,9%
Genauigkeit auf 0,01: 3,3%
Genauigkeit bis 0,001: 0,1%
Testfehler bei 1-von-500-Codierung:
1.000 Trainingsbilder, 1.000 Testbilder, 50 Iterationen, Softmax-Ausgabe
Mittelwert: 0,0298767021922
Median: 0,00388858079174
Minimum: 4.08712407829e-06
Maximum: 6.2784479965
Genauigkeit auf 0,1: 99,6%
Genauigkeit auf 0,01: 88,9%
Genauigkeit bis 0,001: 13,5%
Testfehler für Gaußsche Codierung:
1.000 Trainingsbilder, 1.000 Testbilder, 50 Iterationen, Softmax-Ausgabe
Ich kann nicht verstehen, warum unsere Ergebnisse im Widerspruch zueinander zu stehen scheinen, aber es scheint eine weitere Untersuchung wert zu sein.
quelle
Eine andere Möglichkeit, den Winkel zu codieren, besteht darin, zwei Werte festzulegen:
Dies hätte das ähnliche Problem wie arctan2, da der Gradient bei Theta = 0 undefiniert ist. Ich habe nicht die Zeit, ein Netzwerk zu trainieren und mit den anderen Codierungen zu vergleichen, aber in diesem Artikel schien die Technik einigermaßen erfolgreich zu sein.
quelle