[PYTHON] Schreiben Sie Reversi AI mit Keras + DQN

Kostenloses Studium der Winterferien Es gibt auch Demo

Motivation

Wir streben eine rein starke KI an, anstatt die Regeln der Umkehrung zu lernen. Repository

Themen vor DQN

Brettoberfläche

Das Board ist 6x6. Ursprünglich habe ich es mit 8x8 gemacht, aber da sowohl das Modell als auch die Trainingsdaten eine vernünftige Größe haben, war ungefähr 6x6 genau richtig für den Test. ~~ Oder besser gesagt, es ging gut mit 6x6 und ich habe es verstanden ~~

Bereite AI vor

Ich möchte eine große Menge Musik zum Lernen erzeugen, also werde ich eine geeignete KI erstellen. Heute werden wir eine völlig zufällige und Monte-Carlo-Baumerkundung durchführen. Das Ergebnis ist hier. Dieser Artikel zeigt die KI der Monte-Carlo-Baumerkundung mit n Playouts in MTS (n).

Generation des Schachs

[Hier](http://qiita.com/Ugo-Nama/items/08c6a5f6a571335972d5#%E9%96%A2%E6%95%B0%E8%BF%91%E4%BC%BC%E3%81%AB % E3% 83% 8B% E3% 83% A5% E3% 83% BC% E3% 83% A9% E3% 83% AB% E3% 83% 8D% E3% 83% 83% E3% 83% 88% E3 % 83% AF% E3% 83% BC% E3% 82% AF% E3% 82% 92% E4% BD% BF% E3% 81% 86) Lernen Sie mit so etwas wie Neural Fitted Q Iteration Also werde ich eine Punktzahl machen. Wir haben das Board und den Fortschritt der Runde auf der Partitur aufgezeichnet und vorerst etwa 200.000 Stationen vorbereitet. Mit DQN müssen Sie kein gutes Ergebnis vorbereiten, es ist also sehr einfach. Sie können dies tun, indem Sie es einige Minuten lang ganz zufällig drehen.

DQN-Thema

Die Grundlagen finden Sie in diesem Artikel.

Eingang

DQN nimmt den Zustand "s" und die Aktion "a" als Eingabe. Diesmal ist der Staat das Brett, der Zug und das Brett, nachdem er Maßnahmen ergriffen hat. In Atari-Spielen, die in DQN üblich sind, wirken sich andere Faktoren als Aktionen (wie die Bewegung von Feinden) auf den nächsten Status aus, sodass Aktionen nur durch Tasteneingabe ausgeführt werden können. Andererseits bestimmen meine Aktionen in Reversi den nächsten Zustand vollständig, also habe ich dies versucht.

Belohnung und Ausgabe

DQN legt für jede Aktion eine Belohnung "r" fest. Diesmal war es das Endergebnis der Aktion, +1 für das Gewinnen, -1 für das Verlieren und 0 für das Unentschieden und vor dem Finale. Dies stellt sicher, dass die Zwischenbewertung immer innerhalb von [-1, 1] liegt und die Ausgabe "tanh" sein kann. Unter der Annahme eines Nullsummenspiels wird außerdem "schwarze Punktzahl = weiße Punktzahl" festgelegt und "R" später beschrieben Es wird möglich sein, es zur Berechnung des geschätzten Wertes von zu verwenden. Übrigens ist auch die Ausbreitung des Q-Wertes leicht zu erkennen.

R Schätzwertberechnung

Verwenden Sie r, um die Gesamtbelohnung R zu berechnen, die das Lehrersignal ist (Referenz 82% 83% E3% 81% AA% E3% 81% 84q-networkq% E5% AD% A6% E7% BF% 92 -% E9% 96% A2% E6% 95% B0% E8% BF% 91% E4% BC% BC)).

Q_\theta(s, a) = r + \gamma*\max_{a'}Q_\theta(s',a')

Dies ist die Formel für das Lehrersignal, aber im Fall von Umkehrung wechseln sich Schwarz und Weiß ab. Der gewünschte Wert ist also der gewünschte Wert, indem Sie einfach diese Formel kopieren, da die Drehung von "s" und die Drehung von "s" unterschiedlich sind. Wird nicht herauskommen. Schreiben Sie hier unter Verwendung der oben erwähnten Nullsummenannahme wie folgt um.

Q_\theta(s, a) = \left\{
\begin{array}{ll}
 r + \gamma*\max_{a'}Q_\theta(s',a') & (s und s'Und die Wende ist die gleiche)\\
 r - \gamma*\max_{a'}Q_\theta(s',a') & (s und s'Die Wende ist anders)
\end{array}
\right.

Wenn die Runde anders ist, ist die Code-Umkehrung der Punktzahl des Gegners die eigene Punktzahl aus der Annahme einer Nullsumme, daher wird diese Formel verwendet. Die Minimax-Methode macht das Gleiche, also habe ich sie mir natürlich ausgedacht, aber ich weiß nicht, ob sie passt. Da davon ausgegangen wird, dass die Plattenoberfläche von Reversi dieselbe diagonale zweiachsige und um 180 Grad gedrehte Plattenoberfläche aufweist, wurde auch die Idee eingeführt, die Ausbreitungsgeschwindigkeit zu erhöhen, indem unter diesen vier Typen "max" genommen wird.

Der Code lautet this, jedoch zur Beschleunigung max Die "Vorhersage" für die Berechnung erfolgt auf einmal, und der ε-gierige Code wird eingemischt, was das Lesen fürchterlich erschwert. (Nachtrag 2017/1/1: Ich habe festgestellt, dass 8 Straßenbetten in Betracht gezogen wurden, aber NFQ scheint kein ε-gieriges zu brauchen.)

Modell-

Ich nutzte Keras und machte das folgende Modell.

def create_model6():

    board_input = Input(shape=[6, 6])
    action_input = Input(shape=[6, 6])
    color_input = Input(shape=[1])

    model_v = Sequential([
        InputLayer([6, 6]),
        Reshape([6, 6, 1]),
        Conv2D(64, 6, 1), # 1x6
        ELU(),
        Conv2D(64, 1, 1),
        ELU(),
        Flatten()
    ])

    model_h = Sequential([
        InputLayer([6, 6]),
        Reshape([6, 6, 1]),
        Conv2D(64, 1, 6), # 6x1
        ELU(),
        Conv2D(64, 1, 1),
        ELU(),
        Flatten()
    ])

    model_dr = Sequential([
        InputLayer([6, 6]),
        Reshape([6*6, 1]),
        ZeroPadding1D(3),
        Reshape([6, 7, 1]),
        LocallyConnected2D(64, 6, 1),
        ELU(),
        LocallyConnected2D(64, 1, 1),
        ELU(),
        Flatten()
    ])

    model_dl = Sequential([
        InputLayer([6, 6]),
        Reshape([6*6, 1]),
        ZeroPadding1D(2),
        Reshape([8, 5, 1]),
        LocallyConnected2D(64, 8, 1),
        ELU(),
        LocallyConnected2D(64, 1, 1),
        ELU(),
        Flatten()
    ])

    color_model = Sequential([
        InputLayer([1]),
        Dense(256),
        ELU(),
        Dense(1024),
        ELU()
    ])

    merge_layer = merge([
        model_v(board_input),
        model_h(board_input),
        model_dl(board_input),
        model_dr(board_input),
        color_model(color_input),
        model_v(action_input),
        model_h(action_input),
        model_dl(action_input),
        model_dr(action_input),
    ], mode="concat", concat_axis=-1) 

    x = Dense(2048)(merge_layer)
    x = BatchNormalization()(x)
    x = ELU()(x)
    x = Dense(512)(x)
    x = BatchNormalization()(x)
    x = ELU()(x)
    x = Dense(128)(x)
    x = BatchNormalization()(x)
    x = ELU()(x)
    output = Dense(1, activation="tanh")(x)

    model = Model(input=[board_input, color_input, action_input], output=[output])

    adam = Adam(lr=1e-4)
    model.compile(optimizer=adam, loss="mse")

    return model

Zuallererst gibt es zwei Boards, Present und Post-Action, die in vier Arten von Weight-Sharing-Netzwerken eingegeben werden. model_v und model_h werden nach 6x1, 1x6 Faltung um 1x1 gefaltet. Auf diese Weise können Sie berechnen, indem Sie nur eine vertikale und eine horizontale Reihe betrachten. Die verbleibenden model_dl und model_dr sind diagonale Spaltenberechnungen. Verwenden Sie zuerst "ZeroPadding" und "Reshape", um die diagonalen Spalten in einer vertikalen Spalte auszurichten und sie auf das 6x1 "Local Connected 2D" anzuwenden. In model_dr werden beispielsweise diagonale Spalten wie in der folgenden Abbildung gezeigt ausgerichtet. スクリーンショット 2016-12-27 15.46.43.png Ich verwende LocallyConnected2D, weil diese Spalten verschiedene Dinge zeigen. Ich möchte es wirklich trennen, aber ich habe es übersprungen. Danach wird auch die Drehung entsprechend erhöht und es wird eine vollständig verbundene Schicht, nachdem alle Ausgänge verbunden wurden.

Keras hat einen hohen Freiheitsgrad im Modelldesign, aber ich bin ziemlich ratlos, weil es den Anschein haben mag, dass "Modell, Sequenz" und "Ebene" ohne Unterschied verwendet werden können. Der Bereich um die letzte vollständig verbundene Schicht ist das Produkt dieses Leidens. Außerdem habe ich in diesem Artikel etwas über "InputLayer" gelernt und Fortschritte gemacht, sodass ich hoffe, dass es mehr gefällt.

Bestätigung des Lernfortschritts

Ich habe zwei Methoden verwendet, um den Fortschritt zu überprüfen.

Lass uns tatsächlich kämpfen

Ich habe Hunderte von Schlachten mit zufälliger KI für jede geeignete Anzahl von Iterationen durchgeführt und gesehen, wie hoch die Gewinnrate war. Tatsächlich war die Implementierung am Anfang fehlerhaft, und als ich sie bemerkte und reparierte und die Fortsetzung startete, lag die Gewinnrate zu diesem Zeitpunkt bei über 99%, daher ist sie nicht sehr hilfreich. Ich habe es verwendet, um das Modell mit der besten Gewinnrate im Lernprozess zu belassen.

Geben Sie die Daten des Spiels in die Nähe der besten

Mal sehen, welche Art von Wert erhalten wird, indem die Eingabe der Schachpartitur zwischen MTS (5000) angegeben wird. DQN schätzt die Punktzahl, wenn Sie immer auf den besten Zug zeigen. Daher besteht die Idee darin, eine Punktzahl anzugeben, die bei MTS mit einer großen Anzahl von Playouts immer auf den besten Zug zeigt. Die Ausgabe am Ende des Lernens war wie folgt.

 0: B: [-0.02196666 -0.02230018 -0.0303785  -0.03168077]
 1: W: [-0.09994178 -0.10080269 -0.09473281 -0.09523395]
 2: B: [-0.05049421 -0.0613905  -0.05865757 -0.0515893 ]
 3: W: [-0.10307723 -0.11034401 -0.1078812  -0.11545543]
 4: B: [-0.02195507 -0.01722838 -0.00687013 -0.00869585]
 5: W: [-0.128447   -0.12213746 -0.14925914 -0.14207964]
 6: B: [-0.22107203 -0.21318831 -0.1865633  -0.18185341]
 7: W: [ 0.06178221  0.08316899  0.05964577  0.03900897]
 8: B: [-0.22808655 -0.20577276 -0.16608836 -0.18835764]
 9: W: [ 0.0713096   0.08927093  0.05861793  0.0417437 ]
10: B: [-0.25330806 -0.2539109  -0.22571792 -0.20664638]
11: W: [ 0.05460038  0.07116394  0.07360842  0.01370821]
12: B: [-0.24553944 -0.22967289 -0.22448763 -0.2255006 ]
13: W: [ 0.08806669  0.11078909  0.11152182  0.0635582 ]
14: B: [-0.45493153 -0.45988095 -0.46441916 -0.41323128]
15: W: [ 0.37723741  0.37333494  0.36738792  0.32914931]
16: B: [-0.46461144 -0.44231483 -0.42101949 -0.38848421]
17: W: [ 0.17253573  0.21936594  0.20173906  0.16213408]
18: B: [-0.50654161 -0.52144158 -0.50978303 -0.51221204]
19: W: [ 0.42853072  0.47864962  0.42829457  0.39107552]
20: B: [-0.68370593 -0.69842124 -0.69973147 -0.70182347]
21: W: [ 0.39964256  0.50497115  0.51084852  0.49810672]
22: B: [-0.71973562 -0.70337516 -0.62852156 -0.67204589]
23: W: [ 0.37252051  0.49400631  0.34360072  0.35528785]
24: B: [-0.81641883 -0.84098679 -0.79452062 -0.82713711]
25: W: [ 0.80729294  0.81642532  0.79480326  0.78571904]
26: B: [-0.916417   -0.9247427  -0.90268892 -0.89786631]
27: W: [ 0.93264407  0.93837488  0.93335259  0.9382773 ]
28: W: [ 0.93243909  0.93243909  0.9183923   0.9183923 ]

Die Punktzahlen des ersten Zuges, des zweiten Zuges usw. von oben sind in horizontaler Richtung gleich, die diagonale Achse der Aktion ist umgekehrt und die Drehung beträgt 180 Grad. Es kann gelesen werden, dass die Punktzahl am Ende des Spiels hoch ist und dass das Vorzeichen aufgrund der Änderung der Runde umgekehrt ist. Die Tatsache, dass die Werte in horizontaler Richtung ungefähr gleich sind, scheint auf ihre Gleichheit hinzuweisen. Wird der Q-Wert nicht in den frühen Stadien propagiert oder befindet er sich überhaupt in einem unbestimmten Zustand? Es scheint, dass der Abzinsungssatz γ nicht sehr effektiv ist ...

Lernergebnis

Ich drehte es für ungefähr 3 Tage mit dem obigen Gefühl. Als ich ein neues Buch von Made in Abyss kaufte und zurückkam, waren alle Ausgaben "nan" und ich war kalt und verschwitzt. Ich möchte vor allem, dass Sie voller Dinge sind. Glücklicherweise habe ich versucht, die Gewinnrate anhand des verbleibenden Modells zu bewerten.

--995 / 1000 mit einem zufälligen Gegner

Hmm subtil? Zufällige Gegner sollten gewinnen können, wenn sie nur in der Taktik der zweiten Hälfte gut sind. Daher dachte ich, dass es einfacher wäre, die Gewinnrate mit DQN zu erhöhen, das sich ab der zweiten Hälfte ausbreitet, aber es war ein bisschen, dass ich gegen MTS-Gegner gewinnen konnte, die in der zweiten Hälfte stärker sein sollten Ich war überrascht. Haben Sie in der mittleren Phase die Oberhand gewonnen? Ohne Nan habe ich das Gefühl, ich kann noch weiter gehen und stärker werden.

Demo

Ich wollte schon immer GCP verwenden, also habe ich versucht, den freien Frame zu verwenden. Wenn es nicht fällt, wird es meiner Meinung nach während der Jahresend- und Neujahrsferien funktionieren. http://104.155.201.107:8888/ Wählen Sie DQN im Auswahlfeld unten aus, um DQN zu erhalten.

Erwägung

Über das Modell

Da es reversibel ist, habe ich ein Modell entworfen, das vertikal, horizontal und diagonal berücksichtigen kann. Ich weiß nicht, ob ich die Regeln für das Sandwiching gelernt habe, aber kann ich den Grad der Offenheit erkennen? Tatsächlich scheint der Wert der Aktion erst von der Kammer nach der Aktion verstanden zu werden, so dass ich der Meinung bin, dass es nicht notwendig war, die Kammer in den Staat aufzunehmen. Wenn das Ergebnis der Aktion in einem beliebigen Status dasselbe ist, sollten diese Ergebnisse gleich sein. Ich habe das Gefühl, dass das Modell, das ich richtig gemacht habe, gut funktioniert hat, also habe ich nicht genug darüber nachgedacht. Es ist jedoch ziemlich schwierig, für jede Studie mehrere Tage in Anspruch zu nehmen.

Über die Partitur

Die Punktzahl gegen Ende wurde für jede Runde umgekehrt, so dass das Lernen anscheinend Fortschritte machte. Andererseits sollte der absolute Wert der Punktzahl in Form von "γ ^ n" vorliegen, aber es schien weit davon entfernt zu sein. Was wird überhaupt mit dem wahren Wert von "R" geschehen ... Es scheint, dass letzteres vorteilhaft ist, also wird Schwarz vom ersten Zug an minus und Weiß plus sein?

TODO

That's it folks!

Recommended Posts

Schreiben Sie Reversi AI mit Keras + DQN
Schreiben Sie DCGAN mit Keras
Bilderkennung mit Keras
3. 3. KI-Programmierung mit Python
Spiel mit Othello (Reversi)
Visualisieren Sie Ansprüche mit AI
Erstellen Sie die Keras AI Prediction Engine in 1 Stunde mit GCP
CIFAR-10-Tutorial mit Keras
Multivariates LSTM mit Keras
Keras-Installation (von Anaconda verwendet)
Multiple Regressionsanalyse mit Keras
AutoEncodder-Notizen mit Keras
Schreiben Sie einfach if-elif mit Lambda
Word2vec mit Theano + Keras implementiert
Satzerzeugung mit GRU (Keras)
Optimieren von Keras-Parametern mit Keras Tuner
Erstelle Puyopuyo AI mit Python
Schreiben wir Python mitinema4d.
Erstellen Sie einfach CNNs mit Keras
Effizientes GAN mit Keras implementiert
Schreiben Sie einen flexiblen Unit-Test mit PyHamcrest!
Bilderkennung mit Keras + OpenCV