Advertisement
alkkofficial

Untitled

Mar 31st, 2023 (edited)
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.32 KB | None | 0 0
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import pandas as pd
  4. import torch
  5. import torch.nn as nn
  6. import torch.optim as optim
  7. import tqdm
  8. from sklearn.model_selection import train_test_split
  9. import chess
  10.  
  11. # puzzle presets
  12. MAX_MOMENTS = 10
  13. TOTAL_GAMES = 4
  14. board = chess.Board()
  15. files = ["./a.txt","./ab.txt", "./ac.txt"]
  16.  
  17. # pre-training loop
  18.  
  19. final_df = pd.DataFrame()
  20.  
  21. # set up training data
  22.  
  23. for file in files:
  24. with open(file, "r") as f:
  25. contents = f.read()
  26.  
  27. contents = contents.split(" \n")
  28. df_add = pd.DataFrame(columns=["moves", "status"])
  29.  
  30. for game in contents:
  31. if file == "./a.txt": # NOTE: change the filename
  32. d = {"moves": game, "status": "won"}
  33. df_add.loc[len(df_add)] = d
  34. elif file == "./ab.txt":
  35. d = {"moves": game, "status": "lost"}
  36. df_add.loc[len(df_add)] = d
  37. elif file == "./ac.txt":
  38. d = {"moves": game, "status": "drew"}
  39. df_add.loc[len(df_add)] = d
  40. final_df = pd.concat([final_df, df_add], ignore_index=True)
  41. # define function that takes chess board and turns into AI-understandable matrix
  42.  
  43.  
  44. def board_data(board):
  45. board_array = np.zeros((8, 8, 13), dtype=np.int8)
  46. for i in range(64):
  47. piece = board.piece_at(i)
  48. if piece is not None:
  49. color = int(piece.color)
  50. piece_type = piece.piece_type - 1
  51. board_array[i // 8][i % 8][piece_type + 6 * color] = 1
  52. else:
  53. board_array[i // 8][i % 8][-1] = 1
  54. board_array = board_array.flatten()
  55. return board_array
  56.  
  57.  
  58. game = 0
  59. train_df = pd.DataFrame(
  60. columns=[
  61. "board_data",
  62. "status",
  63. ]
  64. )
  65.  
  66. for index, row in final_df.iterrows():
  67. moves = row["moves"].split(" ")
  68. status = row["status"]
  69. moves = [x for x in moves if x] # removes empty strings in list
  70. if len(moves) <= MAX_MOMENTS:
  71. MAX_MOMENTS = len(moves)
  72. unsampled_idx = [x for x in range(len(moves))]
  73. unsampled_idx.pop(0)
  74. for _ in range(MAX_MOMENTS - 1):
  75. board = chess.Board()
  76. up_to = np.random.choice(unsampled_idx)
  77. unsampled_idx.remove(up_to)
  78. moment = moves[:up_to]
  79. df_add = pd.DataFrame(
  80. columns=[
  81. "board_data",
  82. "status",
  83. ]
  84. )
  85. for move in moment:
  86. board.push(chess.Move.from_uci(move))
  87. ai_moves = board_data(board)
  88.  
  89. counter = 0
  90. d = {
  91. "board_data": ai_moves,
  92. "status": status,
  93. }
  94. df_add.loc[len(df_add)] = d
  95. train_df = pd.concat([train_df, df_add], ignore_index=True)
  96. game += 1
  97.  
  98. # preprocessing data
  99.  
  100. train_df["status"] = train_df["status"].map(
  101. {"won": 1.0, "lost": -1.0, "drew": 0.0}
  102. ) # target
  103. X = np.array([x for x in train_df["board_data"]])
  104. y = np.array([x for x in train_df["status"]])
  105. # train-test split for model evaluation
  106. X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, shuffle=True)
  107. # Convert to 2D PyTorch tensors
  108. X_train = torch.tensor(X_train, dtype=torch.float32)
  109. y_train = torch.tensor(y_train, dtype=torch.float32).reshape(-1, 1)
  110. X_test = torch.tensor(X_test, dtype=torch.float32)
  111. y_test = torch.tensor(y_test, dtype=torch.float32).reshape(-1, 1)
  112.  
  113.  
  114. class EvalNN(nn.Module):
  115. def __init__(self):
  116. super().__init__()
  117. self.fc1 = nn.Linear(832, 832)
  118. self.hidden_layers = nn.ModuleList()
  119. for _ in range(100):
  120. self.hidden_layers.append(nn.Linear(832, 832))
  121. self.fc_out = nn.Tanh()
  122. self.optimizer = optim.AdamW(self.parameters(), lr=1e-3)
  123. self.scheduler = optim.lr_scheduler.StepLR(
  124. self.optimizer, step_size=10, gamma=0.5
  125. )
  126. self.loss = nn.MSELoss()
  127.  
  128. def forward(self, x):
  129. x = torch.relu(self.fc1(x))
  130. for layer in self.hidden_layers:
  131. x = torch.relu(layer(x))
  132. x = self.fc_out(x)
  133. return x
  134.  
  135. def load_weights(self, path):
  136. self.load_state_dict(torch.load(path))
  137.  
  138.  
  139. model = EvalNN()
  140. train_losses = []
  141. test_losses = []
  142. num_epochs = 5
  143.  
  144. for epoch in range(num_epochs):
  145. # Training
  146. model.train()
  147. train_loss = 0.0
  148. for i in tqdm.tqdm(range(X_train.shape[0])):
  149. inputs = X_train[i]
  150. targets = y_train[i]
  151. model.optimizer.zero_grad()
  152. outputs = model(inputs)
  153. loss = model.loss(outputs, targets)
  154. loss.backward()
  155. model.optimizer.step()
  156. train_loss += loss.item()
  157. train_loss /= X_train.shape[0]
  158. train_losses.append(train_loss)
  159.  
  160. # Validation
  161. model.eval()
  162. test_loss = 0.0
  163. with torch.no_grad():
  164. for i in range(X_test.shape[0]):
  165. inputs = X_test[i]
  166. targets = y_test[i]
  167. outputs = model(inputs)
  168. loss = model.loss(outputs, targets)
  169. test_loss += loss.item()
  170. test_loss /= X_test.shape[0]
  171. test_losses.append(test_loss)
  172.  
  173. # Learning rate scheduling
  174. model.scheduler.step()
  175.  
  176. print(
  177. f"Epoch {epoch+1}/{num_epochs}: Train Loss = {train_loss:.6f}, Test Loss = {test_loss:.6f}"
  178. )
  179. plt.plot(train_losses, label="Train Loss")
  180. plt.plot(test_losses, label="Test Loss")
  181. plt.legend()
  182. plt.show()
  183. plt.savefig('ai-eval-losses.png')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement