Je joue aux échecs depuis très longtemps et depuis que j'ai commencé CS, j'ai toujours voulu créer un robot d'échecs. Je l'ai enfin fait ?.
Voici une vidéo où je (blanc) me fais écraser par mon bot (noir).
Voici son profil chess.com : https://www.chess.com/member/chessables_with_chat_gpt.
git clone https://github.com/samliu21/chess-ai
. Naviguez dans le répertoire avec cd chess-ai
.python -m venv .
et activez-le avec source bin/activate
.python -m pip install -r requirements.txt
.cd gui
et appelez python main.py
pour jouer ! J'ai utilisé la base de données officielle Lichess, qui contenait des jeux au format PGN standard. Voici le processus de nettoyage des données :
pgn-extract
pour ajouter des FEN après chaque mouvement Pour plus d'informations, consultez le dossier data_cleaning
.
Au départ, j'ai essayé de créer un réseau neuronal d'évaluation de carte à associer à un algorithme minimax. Cette approche présentait deux problèmes :
Le réseau d'évaluation n'a pas répondu à mes attentes. Il pouvait détecter des déséquilibres matériels mais ne pouvait pas détecter de simples échecs et mats.
En raison du grand espace d'action aux échecs, l'algorithme minimax est très lent, même lorsqu'il est optimisé avec l'élagage alpha-bêta.
Ensemble, ces facteurs m’ont incité à abandonner cette idée initiale et à en essayer une autre.
L'interface graphique a été réalisée à la main à l'aide des modules pygame
et python-chess
.
Cette architecture a été largement inspirée de cet article de Standford.
L'IA utilise deux modèles. Ils reçoivent tous deux une position sur le tableau en entrée et génèrent une matrice 8x8
de probabilités softmax. Le « à partir du modèle » prédit le carré à partir duquel il sera déplacé et le « à modéliser » prédit le carré dans lequel il sera déplacé.
Cette approche est mieux illustrée par un exemple. Considérez la position de départ sur le plateau et le coup : Nf3
. L'évaluation de ce mouvement est le produit de la valeur au carré g1
du modèle from et de la valeur au carré f3
du modèle to.
Parmi tous les coups légaux, le produit le plus important est le coup sélectionné.
Les réseaux de neurones sont constitués de six couches convolutives, suivies de deux couches affines et d'une couche de sortie. Un croquis plus détaillé de l’architecture peut être trouvé ci-dessous :
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
__________________________________________________________________________________________________