Bevor ich mit der Implementierung des Agenten selbst begann, musste ich mich mit der Umgebung, die ich verwenden werde, vertraut machen und darüber einen benutzerdefinierten Wrapper erstellen, damit er während des Trainings mit dem Agenten interagieren kann.
Ich habe die Schachumgebung aus der Bibliothek kaggle_environments verwendet.
from kaggle_environments import make env = make("chess", debug=True)
Ich habe auch Chessnut verwendet, eine leichte Python-Bibliothek, die beim Analysieren und Validieren von Schachpartien hilft.
from Chessnut import Game initial_fen = env.state[0]['observation']['board'] game=Game(env.state[0]['observation']['board'])
Es bietet eine kompakte Möglichkeit, alle Figuren auf dem Brett und den aktuell aktiven Spieler darzustellen. Da ich jedoch vorhatte, die Eingabe einem neuronalen Netzwerk zuzuführen, musste ich die Darstellung des Zustands ändern.
Da es 12 verschiedene Arten von Teilen auf einem Brett gibt, habe ich 12 Kanäle mit 8x8-Rastern erstellt, um den Zustand jedes dieser Arten auf dem Brett darzustellen.
class EnvCust: def __init__(self): self.env = make("chess", debug=True) self.game=Game(env.state[0]['observation']['board']) print(self.env.state[0]['observation']['board']) self.action_space=game.get_moves(); self.obs_space=(self.env.state[0]['observation']['board']) def get_action(self): return Game(self.env.state[0]['observation']['board']).get_moves(); def get_obs_space(self): return fen_to_board(self.env.state[0]['observation']['board']) def step(self,action): reward=0 g=Game(self.env.state[0]['observation']['board']); if(g.board.get_piece(Game.xy2i(action[2:4]))=='q'): reward=7 elif g.board.get_piece(Game.xy2i(action[2:4]))=='n' or g.board.get_piece(Game.xy2i(action[2:4]))=='b' or g.board.get_piece(Game.xy2i(action[2:4]))=='r': reward=4 elif g.board.get_piece(Game.xy2i(action[2:4]))=='P': reward=2 g=Game(self.env.state[0]['observation']['board']); g.apply_move(action) done=False if(g.status==2): done=True reward=10 elif g.status == 1: done = True reward = -5 self.env.step([action,'None']) self.action_space=list(self.get_action()) if(self.action_space==[]): done=True else: self.env.step(['None',random.choice(self.action_space)]) g=Game(self.env.state[0]['observation']['board']); if g.status==2: reward=-10 done=True self.action_space=list(self.get_action()) return self.env.state[0]['observation']['board'],reward,done
Der Zweck dieses Wrappers bestand darin, eine Belohnungsrichtlinie für den Agenten und eine Schrittfunktion bereitzustellen, die zur Interaktion mit der Umgebung während des Trainings verwendet wird.
Chessnut war nützlich, um Informationen zu erhalten, wie z. B. die legalen Züge, die zum aktuellen Stand des Bretts möglich sind, und um Schachmatts während des Spiels zu erkennen.
Ich habe versucht, eine Belohnungsrichtlinie zu erstellen, um positive Punkte für Schachmatt und das Ausschalten gegnerischer Figuren zu vergeben, während negative Punkte für das Verlieren des Spiels vergeben werden.
Wiederholungspuffer wird während des Trainingszeitraums verwendet, um die Ausgabe (Zustand, Aktion, Belohnung, nächster Zustand) des Q-Netzwerks zu speichern und später zufällig für die Backpropagation des Zielnetzwerks zu verwenden
Chessnut gibt rechtliche Schritte im UCI-Format zurück, das wie „a2a3“ aussieht. Um jedoch mit dem neuronalen Netzwerk zu interagieren, habe ich jede Aktion mithilfe eines Grundmusters in einen eigenen Index umgewandelt. Es gibt insgesamt 64 Quadrate, daher habe ich beschlossen, für jede Bewegung 64*64 eindeutige Indizes zu verwenden.
Ich weiß, dass nicht alle 64*64-Züge legal wären, aber mit Chessnut konnte ich mit der Legalität umgehen und das Muster war einfach genug.
from kaggle_environments import make env = make("chess", debug=True)
Dieses neuronale Netzwerk verwendet die Faltungsschichten, um die 12-Kanal-Eingabe aufzunehmen, und verwendet außerdem die gültigen Aktionsindizes, um die Belohnungsausgabevorhersage herauszufiltern.
from Chessnut import Game initial_fen = env.state[0]['observation']['board'] game=Game(env.state[0]['observation']['board'])
Dies war offensichtlich ein sehr einfaches Modell, das keine Chance hatte, tatsächlich eine gute Leistung zu erbringen (und das tat es auch nicht), aber es hat mir geholfen, die Funktionsweise von DQNs etwas besser zu verstehen.
Das obige ist der detaillierte Inhalt vonErstellen eines Schachagenten mit DQN. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!