Advertisement
alkkofficial

Untitled

Apr 4th, 2023
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.57 KB | None | 0 0
  1. # sorry for the undocumented, unexplained sphaghetti code, this is a really early version of my code
  2. import numpy as np
  3. import torch
  4. import matplotlib.pyplot as plt
  5. import copy
  6. import tqdm
  7. import torch.nn as nn
  8. import torch.optim as optim
  9. from sklearn.model_selection import train_test_split
  10. import chess
  11.  
  12. # puzzle presets
  13. board = chess.Board()
  14. files = ["./ww.pgn", "./bw.pgn", "./drew.pgn"]
  15.  
  16.  
  17. def board_data(board):
  18. board_array = np.zeros((8, 8, 13), dtype=np.int8)
  19. for i in range(64):
  20. piece = board.piece_at(i)
  21. if piece is not None:
  22. color = int(piece.color)
  23. piece_type = piece.piece_type - 1
  24. board_array[i // 8][i % 8][piece_type + 6 * color] = 1
  25. else:
  26. board_array[i // 8][i % 8][-1] = 1
  27. board_array = board_array.flatten()
  28. # board_array.shape = 832 (1D)
  29. return board_array
  30.  
  31.  
  32. def process_output(y_pred, is_eval_output=True):
  33. score = np.mean(np.array(y_pred), axis=1, keepdims=False, dtype=np.float32)
  34. median = np.median(np.array(y_pred))
  35. temp = np.array(list(map(int, str(int(median)) * 832)))
  36. temp = np.split(temp, 832)
  37. temp = np.array(list(map(float, ["".join(map(str, x)) for x in temp])))
  38. temp = np.where(temp > 1, 1, temp)
  39. temp = np.where(temp < -1, -1, temp)
  40. temp = np.where((-1 <= temp) & (temp <= 1), temp, np.where(temp < -1, -1, 1))
  41. temp = np.array(list(map(float, temp)))
  42. temp = np.array(list(map(int, temp)))
  43. temp = [y for y in temp]
  44. big_l = [temp]
  45. if not is_eval_output:
  46. return big_l
  47. return score
  48.  
  49.  
  50. # load the numpy arrays (if any), these arrays are generated once and saved locally so that time is not wasted reloading every single time
  51. # the files are only there because during development of the code a lot of the time will be lost through loading games afresh
  52. # getting the number of games needed to analyse
  53. # set up training data
  54. train_data = np.empty(
  55. (0, 832)
  56. ) # 832 is the size of the flattened board in one hot encoding
  57. train_target = []
  58. for file in files:
  59. with open(file, "r") as f:
  60. contents = f.read()
  61. contents = contents.split(" \n")
  62. for game in tqdm.tqdm(contents, desc="each game"):
  63. game = game.split(" \n")
  64. g = "".join(game)
  65. game = g.split(" ")
  66. game = [x for x in game if x] # remove empty strings
  67. MAX_MOMENTS = min(20, len(game))
  68. unsampled_idx = [x for x in range(1, len(game))]
  69. for move in range(MAX_MOMENTS - 1):
  70. board = chess.Board()
  71. up_to = np.random.choice(unsampled_idx)
  72. unsampled_idx.remove(up_to)
  73. moment = game[:up_to]
  74. counter = 0
  75. for move in moment:
  76. board.push(chess.Move.from_uci(move))
  77. counter += 1
  78. matrix_game = np.array([board_data(board)]) # game after one hot encoding
  79. train_data = np.append(train_data, matrix_game, axis=0)
  80. status = 0
  81. move_turn = counter % 2
  82. if (move_turn == 0 and file == "./ww.pgn") or (
  83. move_turn == 1 and file == "./bw.pgn"
  84. ):
  85. status = 1
  86. elif (move_turn == 0 and file == "./bw.pgn") or (
  87. move_turn == 1 and file == "./ww.pgn"
  88. ):
  89. status = -1
  90. elif file == "./drew.pgn":
  91. status = 0
  92. train_target.append(status)
  93. train_target = np.array(train_target, dtype=np.float32).reshape(-1, 1)
  94.  
  95.  
  96. # save np arrays (if needed to reuse/redo training)
  97. np.save("train_target.pckl", train_target)
  98. np.save("train_data.pckl", train_data)
  99.  
  100. # convert all to pytorch tensor
  101.  
  102.  
  103. X_train, X_val, y_train, y_val = train_test_split(
  104. train_data, train_target, test_size=0.1, shuffle=True
  105. )
  106.  
  107.  
  108. X_train = torch.tensor(X_train, dtype=torch.float32) #
  109. y_train = torch.tensor(y_train, dtype=torch.float32)
  110. X_val = torch.tensor(X_val, dtype=torch.float32)
  111. y_val = torch.tensor(y_val, dtype=torch.float32)
  112.  
  113.  
  114. # NON_LAST_LAYERS = 2
  115. # model = nn.Sequential(
  116. # nn.Linear(832, 1),
  117. # )
  118.  
  119.  
  120. # Define the model architecture
  121. model = nn.Sequential(
  122. nn.Linear(832, 256),
  123. nn.ReLU(),
  124. nn.Dropout(p=0.1),
  125. nn.Linear(256, 128),
  126. nn.ReLU(),
  127. nn.Dropout(p=0.1),
  128. nn.Linear(128, 64),
  129. nn.ReLU(),
  130. nn.Dropout(p=0.1),
  131. nn.Linear(64, 32),
  132. nn.ReLU(),
  133. nn.Dropout(p=0.1),
  134. nn.Linear(32, 1),
  135. nn.Tanh()
  136. )
  137.  
  138. # for i in range(NON_LAST_LAYERS):
  139. # model.add_module(f"linear_{i}", nn.Linear(832, 832))
  140. # model.add_module(f"linear_{NON_LAST_LAYERS}", nn.Tanh())
  141. try:
  142. model.eval()
  143. weights_path = "./ai_zan1ling4_mini_eval.pt"
  144. state_dict = torch.load(weights_path)
  145. model.load_state_dict(state_dict)
  146. except FileNotFoundError:
  147. model.train()
  148.  
  149. # loss function and optimizer
  150. loss_fn = nn.MSELoss() # mean square error
  151. optimizer = optim.AdamW(
  152. model.parameters(),
  153. lr=0.001,
  154. betas=(0.999, 0.999),
  155. eps=1e-08,
  156. weight_decay=0,
  157. amsgrad=False,
  158. )
  159.  
  160. n_epochs = 100 # number of epochs to run optimal = 40, 220
  161. batch_size = 300 # size of each batch
  162. batch_start = torch.arange(0, len(X_train), batch_size)
  163.  
  164. # Hold the best model
  165. best_mse = np.inf # initialise value as infinite
  166. best_weights = None
  167. history = []
  168.  
  169. for epoch in tqdm.tqdm(range(n_epochs), desc="Epochs"):
  170. model.train()
  171. epoch_loss = 0.0
  172. for batch_idx in batch_start:
  173. batch_X, batch_y = (
  174. X_train[batch_idx : batch_idx + batch_size],
  175. y_train[batch_idx : batch_idx + batch_size],
  176. )
  177. optimizer.zero_grad()
  178. y_pred = model(batch_X)
  179. loss = loss_fn(y_pred, batch_y.view(-1, 1))
  180. loss.backward()
  181. optimizer.step()
  182. epoch_loss += loss.item() * batch_X.shape[0]
  183. epoch_loss /= len(X_train)
  184. history.append(epoch_loss)
  185. if epoch_loss < best_mse:
  186. best_mse = epoch_loss
  187. best_weights = copy.deepcopy(model.state_dict())
  188.  
  189. # load the best weights into the model
  190. model.load_state_dict(best_weights)
  191.  
  192. print("MSE: %.2f" % best_mse)
  193. print("RMSE: %.2f" % np.sqrt(best_mse))
  194. plt.plot(history)
  195. plt.title("Epoch loss for ZL")
  196. plt.xlabel("Number of Epochs")
  197. plt.ylabel("Epoch Loss")
  198. plt.draw()
  199. plt.savefig("ai-eval-losses.jpg")
  200. model.eval()
  201. with torch.no_grad():
  202. # Test out inference with 5 samples
  203. q = 0
  204. for i in range(5):
  205. X_sample = X_val[i : i + 1]
  206. X_sample = X_sample.clone().detach()
  207. y_pred = model(X_sample)
  208. print(y_pred)
  209. counter = 0
  210. torch.save(best_weights, "zl.pt")
  211.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement