Upload 2 files
Browse files- booty.pth +3 -0
- chessboot.py +96 -0
booty.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a1245b6b4bb92461de2220d19d1cdd506626db752e3c43ee24c02da0ba691d78
|
| 3 |
+
size 2337603
|
chessboot.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import berserk
|
| 2 |
+
import torch
|
| 3 |
+
from torch import nn
|
| 4 |
+
from torch import optim
|
| 5 |
+
import chess
|
| 6 |
+
import os
|
| 7 |
+
import pandas as pd
|
| 8 |
+
|
| 9 |
+
device = torch.device("cpu")
|
| 10 |
+
|
| 11 |
+
def board_to_tensor(board):
|
| 12 |
+
piece_encoding = {
|
| 13 |
+
'P': 1, 'N': 2, 'B': 3, 'R': 4, 'Q': 5, 'K': 6,
|
| 14 |
+
'p': 7, 'n': 8, 'b': 9, 'r': 10, 'q': 11, 'k': 12
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
tensor = torch.zeros(64, dtype=torch.long)
|
| 18 |
+
for square in chess.SQUARES:
|
| 19 |
+
piece = board.piece_at(square)
|
| 20 |
+
if piece:
|
| 21 |
+
tensor[square] = piece_encoding[piece.symbol()]
|
| 22 |
+
else:
|
| 23 |
+
tensor[square] = 0
|
| 24 |
+
|
| 25 |
+
return tensor.unsqueeze(0)
|
| 26 |
+
|
| 27 |
+
class BOT(nn.Module):
|
| 28 |
+
def __init__(self):
|
| 29 |
+
super().__init__()
|
| 30 |
+
self.embedding = nn.Embedding(13,64)
|
| 31 |
+
self.attention = nn.MultiheadAttention(embed_dim=64,num_heads=16)
|
| 32 |
+
self.neurons = nn.Sequential(
|
| 33 |
+
nn.Linear(4096,128),
|
| 34 |
+
nn.ReLU(),
|
| 35 |
+
nn.Linear(128,128),
|
| 36 |
+
nn.ReLU(),
|
| 37 |
+
nn.Linear(128,128),
|
| 38 |
+
nn.ReLU(),
|
| 39 |
+
nn.Linear(128,64),
|
| 40 |
+
nn.ReLU(),
|
| 41 |
+
nn.Linear(64,1)
|
| 42 |
+
)
|
| 43 |
+
def forward(self,x):
|
| 44 |
+
x = self.embedding(x)
|
| 45 |
+
x = x.permute(1, 0, 2)
|
| 46 |
+
attn_output, _ = self.attention(x, x, x)
|
| 47 |
+
x = attn_output.permute(1, 0, 2).contiguous()
|
| 48 |
+
x = x.view(x.size(0), -1)
|
| 49 |
+
x = self.neurons(x)
|
| 50 |
+
return x
|
| 51 |
+
model = BOT().to(device)
|
| 52 |
+
model = torch.compile(model,mode="max-autotune",dynamic=False)
|
| 53 |
+
if os.path.exists("booty.pth"):
|
| 54 |
+
file = torch.load("booty.pth",map_location=device,weights_only=True)
|
| 55 |
+
model.load_state_dict(file)
|
| 56 |
+
model.train()
|
| 57 |
+
optimizer = optim.Adam(model.parameters(),lr=1e-4)
|
| 58 |
+
criterion = nn.MSELoss()
|
| 59 |
+
num_epochs = 1
|
| 60 |
+
df = pd.read_csv("lichess_db_puzzle.csv",nrows=1000)
|
| 61 |
+
df = df.sort_values(by="Rating", ascending=True)
|
| 62 |
+
t1 = torch.tensor([10.0], dtype=torch.float32, device=device)
|
| 63 |
+
t2 = torch.tensor([-10.0], dtype=torch.float32, device=device)
|
| 64 |
+
t3 = torch.tensor([0.0], dtype=torch.float32, device=device)
|
| 65 |
+
for i in range(num_epochs):
|
| 66 |
+
total_loss = 0.0
|
| 67 |
+
for puzzle in df.iloc:
|
| 68 |
+
board = chess.Board(puzzle["FEN"])
|
| 69 |
+
print(f"Rating: {puzzle['Rating']} elo.")
|
| 70 |
+
n = 0
|
| 71 |
+
for move in puzzle["Moves"].split():
|
| 72 |
+
if n % 2 == 0:
|
| 73 |
+
for movey in list(board.legal_moves):
|
| 74 |
+
if str(movey.uci()) == move:
|
| 75 |
+
b = True
|
| 76 |
+
else:
|
| 77 |
+
b = False
|
| 78 |
+
board.push(movey)
|
| 79 |
+
tensor = board_to_tensor(board).to(device)
|
| 80 |
+
evaling = model(tensor)
|
| 81 |
+
board.pop()
|
| 82 |
+
optimizer.zero_grad()
|
| 83 |
+
if b and board.turn == chess.WHITE:
|
| 84 |
+
loss = criterion(t1, evaling)
|
| 85 |
+
elif b and board.turn == chess.BLACK:
|
| 86 |
+
loss = criterion(t2, evaling)
|
| 87 |
+
else:
|
| 88 |
+
loss = criterion(t3, evaling)
|
| 89 |
+
total_loss += loss.item()
|
| 90 |
+
loss.backward()
|
| 91 |
+
optimizer.step()
|
| 92 |
+
n += 1
|
| 93 |
+
board.push_uci(move)
|
| 94 |
+
print(f"Epoch [{i+1}/{num_epochs}], Loss: {total_loss}.")
|
| 95 |
+
torch.save(model.state_dict(),"booty.pth")
|
| 96 |
+
|