Я играю в шахматы очень давно и с тех пор, как начал заниматься CS, мне всегда хотелось создать шахматного бота. Я наконец сделал это?
Вот видео, где меня (белого) раздавил мой бот (черный).
Вот его профиль на 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
для воспроизведения! Я использовал официальную базу данных Lichess, содержащую игры в стандартном формате PGN. Вот процесс очистки данных:
pgn-extract
, чтобы добавлять FEN после каждого хода. Для получения дополнительной информации посмотрите папку data_cleaning
.
Первоначально я пытался создать нейронную сеть для оценки платы в сочетании с минимаксным алгоритмом. При таком подходе было две проблемы:
Сеть оценки не оправдала моих ожиданий. Он мог обнаружить материальный дисбаланс, но не мог обнаружить простые маты.
Из-за большого пространства действий в шахматах минимаксный алгоритм работает очень медленно, даже если он оптимизирован с помощью альфа-бета-отсечения.
В совокупности эти факторы побудили меня отказаться от этой первоначальной идеи и попробовать другую.
Графический интерфейс был создан вручную с использованием модулей pygame
и python-chess
.
Эта архитектура во многом была вдохновлена этой статьей в Стэндфорде.
ИИ использует две модели. Они оба получают на вход позицию доски и выводят матрицу 8x8
вероятностей softmax. «Из модели» предсказывает квадрат, из которого нужно выйти, а «в модель» — квадрат, в который нужно переместиться.
Этот подход лучше всего иллюстрируется примером. Рассмотрим стартовую позицию на доске и ход: Nf3
. Оценка этого хода представляет собой произведение значения в квадрате g1
модели from и значения в квадрате f3
модели to.
Среди всех законных ходов наибольшим продуктом является выбранный ход.
Нейронные сети состоят из шести сверточных слоев, за которыми следуют два аффинных слоя и выходной слой. Более подробный эскиз архитектуры можно найти ниже:
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
__________________________________________________________________________________________________