私は長い間チェスをプレイしており、CS を始めた頃からずっとチェス bot を作りたいと思っていました。ついにやりました?。
これは私(白人)が私のボット(黒人)に押しつぶされるビデオです。
chess.com のプロフィールは次のとおりです: https://www.chess.com/member/chessables_with_chat_gpt。
git clone https://github.com/samliu21/chess-ai
実行します。 cd chess-ai
を使用してディレクトリに移動します。python -m venv .
そして、 source bin/activate
でアクティブ化します。python -m pip install -r requirements.txt
を使用して、必要な依存関係をインストールします。cd gui
使用して正しいディレクトリに移動し、 python main.py
呼び出して再生します。 標準の PGN 形式でゲームが含まれている公式 Lichess データベースを使用しました。データクリーニングプロセスは次のとおりです。
pgn-extract
使用して各移動後に FEN を追加します詳細については、 data_cleaning
フォルダーを参照してください。
最初に、ミニマックス アルゴリズムと組み合わせる基板評価ニューラル ネットワークを作成しようとしました。このアプローチには 2 つの問題がありました。
評価ネットワークは私の期待どおりには機能しませんでした。材料の不均衡は検出できましたが、単純なチェックメイトは検出できませんでした。
チェスではアクション スペースが大きいため、アルファ ベータ プルーニングで最適化した場合でも、ミニマックス アルゴリズムは非常に遅くなります。
これらの要因が重なって、私はこの最初のアイデアを破棄し、別のアイデアを試してみることにしました。
GUI は、 pygame
モジュールとpython-chess
モジュールを使用して手作りされました。
このアーキテクチャは主にこのスタンフォード論文からインスピレーションを受けています。
AI は 2 つのモデルを使用します。どちらもボードの位置を入力として受け取り、ソフトマックス確率の8x8
行列を出力します。 「from モデル」は移動元の正方形を予測し、「to モデル」は移動先の正方形を予測します。
このアプローチは、例で最もよく説明されています。開始ボードの位置と移動: Nf3
考えてみましょう。この動きの評価は、from モデルのg1
平方の値と to モデルのf3
平方の値の積です。
すべての合法的な手の中で、最大の成果は選択された手です。
ニューラル ネットワークは 6 つの畳み込み層、その後に 2 つのアフィン層と 1 つの出力層で構成されます。アーキテクチャのより詳細なスケッチは以下にあります。
Model: "model"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 8, 8, 12)] 0 []
conv2d (Conv2D) (None, 8, 8, 32) 3488 ['input_1[0][0]']
batch_normalization (BatchNorm (None, 8, 8, 32) 128 ['conv2d[0][0]']
alization)
activation (Activation) (None, 8, 8, 32) 0 ['batch_normalization[0][0]']
conv2d_1 (Conv2D) (None, 8, 8, 64) 18496 ['activation[0][0]']
batch_normalization_1 (BatchNo (None, 8, 8, 64) 256 ['conv2d_1[0][0]']
rmalization)
activation_1 (Activation) (None, 8, 8, 64) 0 ['batch_normalization_1[0][0]']
conv2d_2 (Conv2D) (None, 8, 8, 256) 147712 ['activation_1[0][0]']
batch_normalization_2 (BatchNo (None, 8, 8, 256) 1024 ['conv2d_2[0][0]']
rmalization)
activation_2 (Activation) (None, 8, 8, 256) 0 ['batch_normalization_2[0][0]']
concatenate (Concatenate) (None, 8, 8, 512) 0 ['activation_2[0][0]',
'activation_2[0][0]']
conv2d_3 (Conv2D) (None, 8, 8, 256) 1179904 ['concatenate[0][0]']
batch_normalization_3 (BatchNo (None, 8, 8, 256) 1024 ['conv2d_3[0][0]']
rmalization)
activation_3 (Activation) (None, 8, 8, 256) 0 ['batch_normalization_3[0][0]']
concatenate_1 (Concatenate) (None, 8, 8, 320) 0 ['activation_3[0][0]',
'activation_1[0][0]']
conv2d_4 (Conv2D) (None, 8, 8, 256) 737536 ['concatenate_1[0][0]']
batch_normalization_4 (BatchNo (None, 8, 8, 256) 1024 ['conv2d_4[0][0]']
rmalization)
activation_4 (Activation) (None, 8, 8, 256) 0 ['batch_normalization_4[0][0]']
concatenate_2 (Concatenate) (None, 8, 8, 288) 0 ['activation_4[0][0]',
'activation[0][0]']
conv2d_5 (Conv2D) (None, 8, 8, 256) 663808 ['concatenate_2[0][0]']
batch_normalization_5 (BatchNo (None, 8, 8, 256) 1024 ['conv2d_5[0][0]']
rmalization)
activation_5 (Activation) (None, 8, 8, 256) 0 ['batch_normalization_5[0][0]']
dense (Dense) (None, 8, 8, 256) 65792 ['activation_5[0][0]']
batch_normalization_6 (BatchNo (None, 8, 8, 256) 1024 ['dense[0][0]']
rmalization)
dense_1 (Dense) (None, 8, 8, 64) 16448 ['batch_normalization_6[0][0]']
batch_normalization_7 (BatchNo (None, 8, 8, 64) 256 ['dense_1[0][0]']
rmalization)
dense_2 (Dense) (None, 8, 8, 1) 65 ['batch_normalization_7[0][0]']
batch_normalization_8 (BatchNo (None, 8, 8, 1) 4 ['dense_2[0][0]']
rmalization)
softmax (Softmax) (None, 8, 8, 1) 0 ['batch_normalization_8[0][0]']
==================================================================================================
Total params: 2,839,013
Trainable params: 2,836,131
Non-trainable params: 2,882
__________________________________________________________________________________________________