エージェント自体の実装を開始する前に、使用する環境を理解し、その上にカスタム ラッパーを作成して、トレーニング中にエージェントと対話できるようにする必要がありました。
kaggle_environments ライブラリのチェス環境を使用しました。
from kaggle_environments import make env = make("chess", debug=True)
チェス ゲームの解析と検証に役立つ軽量の Python ライブラリである Chessnut も使用しました。
from Chessnut import Game initial_fen = env.state[0]['observation']['board'] game=Game(env.state[0]['observation']['board'])
ボード上のすべての駒と現在アクティブなプレイヤーを表すコンパクトな方法を提供します。ただし、入力をニューラル ネットワークにフィードする予定だったので、状態の表現を変更する必要がありました。
ボード上には 12 の異なるタイプの駒があるため、ボード上の各タイプの状態を表す 8x8 グリッドの 12 チャネルを作成しました。
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
このラッパーのポイントは、エージェントに対する報酬ポリシーと、トレーニング中に環境と対話するために使用されるステップ関数を提供することでした。
チェスナットは、ボードの現在の状態で可能な合法的な動きなどの情報を取得したり、ゲーム中にチェックメイトを認識したりするのに役立ちました。
チェックメイトと敵の駒を取り除くとプラスのポイントを与え、ゲームに負けるとマイナスのポイントを与える報酬ポリシーを作成しようとしました。
リプレイ バッファは、Q ネットワークによって出力された (状態、アクション、報酬、次の状態) を保存するためにトレーニング期間中に使用され、後でターゲット ネットワークのバックプロパゲーションにランダムに使用されます
Chessnut は、「a2a3」のような UCI 形式で法的アクションを返しますが、ニューラル ネットワークと対話するために、基本パターンを使用して各アクションを個別のインデックスに変換しました。合計 64 個の正方形があるため、各手に対して 64*64 の一意のインデックスを持つことにしました。
64*64 のすべての手が合法であるわけではないことはわかっていますが、チェスナットを使用して合法性を処理でき、パターンも十分に単純でした。
from kaggle_environments import make env = make("chess", debug=True)
このニューラル ネットワークは、畳み込み層を使用して 12 チャネル入力を取り込み、有効なアクション インデックスを使用して報酬出力予測をフィルターで除外します。
from Chessnut import Game initial_fen = env.state[0]['observation']['board'] game=Game(env.state[0]['observation']['board'])
これは明らかに非常に基本的なモデルで、実際にうまく機能する可能性はありませんでした (実際にはうまく機能しませんでした)。しかし、DQN がどのように機能するかを少し理解するのに役立ちました。
以上がDQN を使用したチェス エージェントの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。