Ich habe ein Problem, bei dem ich versuche, ein neuronales Netz für Tic-Tac-Toe zu erstellen. Aus irgendeinem Grund führt das Training des neuronalen Netzwerks jedoch dazu, dass es für jede beliebige Eingabe fast die gleiche Ausgabe erzeugt.
Ich habe einen Blick darauf geworfen Künstliche neuronale Netze Benchmark aber meine Netzimplementierung ist für Neuronen mit der gleichen Aktivierungsfunktion für jedes Neuron gebaut, d.h. keine konstanten Neuronen.
Um sicherzugehen, dass das Problem nicht nur auf meine Wahl des Trainingssatzes (1218 Brettzustände und Züge, die von einem genetischen Algorithmus generiert wurden) zurückzuführen ist, habe ich versucht, das Netz so zu trainieren, dass es XOR reproduziert. Dabei wurde die logistische Aktivierungsfunktion verwendet. Anstatt die Ableitung zu verwenden, habe ich den Fehler multipliziert mit output*(1-output)
da in einigen Quellen behauptet wurde, dies sei gleichbedeutend mit der Verwendung des Derivats. Ich kann den Haskell-Quelltext auf HPaste stellen, aber es ist ein wenig peinlich, ihn anzusehen. Das Netzwerk hat 3 Schichten: die erste Schicht hat 2 Eingänge und 4 Ausgänge, die zweite hat 4 Eingänge und 1 Ausgang, und die dritte hat 1 Ausgang. Die Erhöhung auf 4 Neuronen in der zweiten Schicht hat nicht geholfen, und auch nicht die Erhöhung auf 8 Ausgänge in der ersten Schicht.
Anschließend berechnete ich die Fehler, die Netzwerkausgabe, die Bias-Aktualisierungen und die Gewichtungsaktualisierungen von Hand auf der Grundlage von http://hebb.mit.edu/courses/9.641/2002/lectures/lecture04.pdf um sicherzustellen, dass in diesen Teilen des Codes kein Fehler aufgetreten ist (das war nicht der Fall, aber ich werde es wahrscheinlich noch einmal tun, nur um sicherzugehen). Da ich Batch-Training verwende, habe ich nicht mit x
in Gleichung (4). Ich füge jedoch die Gewichtsänderung hinzu http://www.faqs.org/faqs/ai-faq/neural-nets/part2/section-2.html schlägt vor, sie stattdessen zu subtrahieren.
Das Problem blieb auch in diesem vereinfachten Netz bestehen. Dies sind zum Beispiel die Ergebnisse nach 500 Epochen Batch-Training und inkrementellem Training.
Input |Target|Output (Batch) |Output(Incremental)
[1.0,1.0]|[0.0] |[0.5003781562785173]|[0.5009731800870864]
[1.0,0.0]|[1.0] |[0.5003740346965251]|[0.5006347214672715]
[0.0,1.0]|[1.0] |[0.5003734471544522]|[0.500589332376345]
[0.0,0.0]|[0.0] |[0.5003674110937019]|[0.500095157458231]
Wenn man subtrahiert statt addiert, hat man das gleiche Problem, nur dass alles 0,99 irgendwas statt 0,50 irgendwas ist. 5000 Epochen führen zum gleichen Ergebnis, außer dass das im Stapelverfahren trainierte Netzwerk in jedem Fall genau 0,5 liefert. (Sogar 10.000 Epochen haben beim Batch-Training nicht funktioniert.)
Gibt es irgendetwas, das dieses Verhalten hervorrufen könnte?
Außerdem habe ich mir die Zwischenfehler für das inkrementelle Training angesehen, und obwohl die Eingaben der versteckten/eingehenden Schichten variierten, war der Fehler für das Ausgangsneuron immer +/-0,12. Beim Stapeltraining stiegen die Fehler zwar an, aber extrem langsam, und die Fehler waren alle extrem klein (x10^-7). Unterschiedliche anfängliche Zufallsgewichte und Verzerrungen machten ebenfalls keinen Unterschied.
Beachten Sie, dass es sich um ein Schulprojekt handelt, daher wären Hinweise/Anleitungen hilfreicher. Obwohl es eine schreckliche Idee war, das Rad neu zu erfinden und mein eigenes Netzwerk zu erstellen (in einer Sprache, die ich nicht gut kenne!), hielt ich es für ein Schulprojekt für angemessener (damit ich weiß, was vor sich geht... zumindest in der Theorie. An meiner Schule scheint es keinen Informatiklehrer zu geben).
EDIT: Zwei Schichten, eine Eingabeschicht mit 2 Eingängen zu 8 Ausgängen und eine Ausgabeschicht mit 8 Eingängen zu 1 Ausgang, führen zu fast den gleichen Ergebnissen: 0,5+/-0,2 (oder so) für jeden Trainingsfall. Ich spiele auch mit pyBrain herum, um zu sehen, ob irgendeine Netzwerkstruktur dort funktionieren wird.
Edit 2: Ich verwende eine Lernrate von 0,1. Tut mir leid, dass ich das vergessen habe.
Edit 3: Pybrains "trainUntilConvergence" bringt mir auch kein vollständig trainiertes Netzwerk, aber 20000 Epochen schon, mit 16 Neuronen in der versteckten Schicht. 10000 Epochen und 4 Neuronen, nicht so viel, aber nahe dran. In Haskell, mit der Eingabeschicht mit 2 Eingängen und 2 Ausgängen, der versteckten Schicht mit 2 Eingängen und 8 Ausgängen und der Ausgabeschicht mit 8 Eingängen und 1 Ausgang... habe ich das gleiche Problem mit 10000 Epochen. Und mit 20000 Epochen.
Edit 4: Ich habe das Netzwerk auf der Grundlage des obigen MIT-PDFs noch einmal von Hand durchgespielt, und die Werte stimmen überein, so dass der Code korrekt sein sollte, es sei denn, ich habe die Gleichungen falsch verstanden.
Ein Teil meines Quellcodes ist unter http://hpaste.org/42453/neural_network__not_working Ich arbeite daran, meinen Code etwas aufzuräumen und ihn in ein Github-Repository (statt in ein privates Bitbucket-Repository) zu stellen.
Der gesamte relevante Quellcode ist jetzt unter https://github.com/l33tnerd/hsann .