Advertisement
alkkofficial

Untitled

Mar 31st, 2023 (edited)
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.13 KB | None | 0 0
  1. # 真零 eval engine with NN
  2. # zan1ling4 | 真零 | (pronounced Jun Ling)
  3. # imports
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. import pandas as pd
  7. import torch
  8. import torch.nn as nn
  9. import torch.optim as optim
  10. import copy
  11. import tqdm
  12. from sklearn.model_selection import train_test_split
  13. import chess
  14.  
  15. # puzzle presets
  16. MAX_MOMENTS = 10
  17. board = chess.Board()
  18. files = ["./won.txt", "./lost.txt", "./drew.txt"]
  19.  
  20. # pre-training loop
  21.  
  22. final_df = pd.DataFrame()
  23.  
  24. # set up training data
  25.  
  26. for file in files:
  27. with open(file, "r") as f:
  28. contents = f.read()
  29.  
  30. contents = contents.split(" \n")
  31. df_add = pd.DataFrame(columns=["moves", "status"])
  32.  
  33. for game in contents:
  34. if file == "./won.txt" or file == "./a.txt": # NOTE: change the filename
  35. d = {"moves": game, "status": "won"}
  36. df_add.loc[len(df_add)] = d
  37. elif file == "./lost.txt" or file == "./ab.txt":
  38. d = {"moves": game, "status": "lost"}
  39. df_add.loc[len(df_add)] = d
  40. elif file == "./drew.txt" or file == ".ac.txt":
  41. d = {"moves": game, "status": "drew"}
  42. df_add.loc[len(df_add)] = d
  43. final_df = pd.concat([final_df, df_add], ignore_index=True)
  44.  
  45. print("ALL GAMES LOADED")
  46.  
  47. # define function that takes chess board and turns into AI-understandable matrix
  48.  
  49.  
  50. def process_output(y_pred, is_eval_output=True):
  51. total_sum = 0
  52. big_l = []
  53. c = 0
  54. small_l = []
  55. for x in y_pred:
  56. for y in x:
  57. total_sum += y
  58. small_l.append(y)
  59. c +=1
  60. median = 0
  61. if len(small_l) % 2 == 0:
  62. median = small_l[int(len(small_l)/2)]
  63. else:
  64. median = small_l[int((len(small_l)+1)/2)]
  65. avg = total_sum/c
  66. score = (float(median) + float(avg))/2
  67. print("scores",score)
  68. temp = ""
  69. big_l = []
  70. temp = (str(int(median)) + "2") * 832
  71. temp = temp.split("2")
  72. tt = []
  73. temp = list(filter(None, temp))
  74. for y in temp:
  75. tt.append(y)
  76. temp = [float(y) for y in tt]
  77. for y in temp:
  78. if y > 1:
  79. y = min(y, 1)
  80. elif y < -1:
  81. y = max(y, -1)
  82. temp = [y if -1 <= y <= 1 else max(-1, min(y, 1)) for y in temp]
  83. temp = [float(int(y)) for y in temp]
  84. big_l.append(temp)
  85. if is_eval_output == False:
  86. return big_l
  87. return score
  88.  
  89.  
  90. def board_data(board):
  91. board_array = np.zeros((8, 8, 13), dtype=np.int8)
  92. for i in range(64):
  93. piece = board.piece_at(i)
  94. if piece is not None:
  95. color = int(piece.color)
  96. piece_type = piece.piece_type - 1
  97. board_array[i // 8][i % 8][piece_type + 6 * color] = 1
  98. else:
  99. board_array[i // 8][i % 8][-1] = 1
  100. board_array = board_array.flatten()
  101. return board_array
  102.  
  103.  
  104. game = 0
  105. train_df = pd.DataFrame(
  106. columns=[
  107. "board_data",
  108. "status",
  109. ]
  110. )
  111.  
  112. for index, row in final_df.iterrows():
  113. moves = row["moves"].split(" ")
  114. status = row["status"]
  115. moves = [x for x in moves if x] # removes empty strings in list
  116. if len(moves) <= MAX_MOMENTS:
  117. MAX_MOMENTS = len(moves)
  118. unsampled_idx = [x for x in range(len(moves))]
  119. unsampled_idx.pop(0)
  120. for _ in range(MAX_MOMENTS - 1):
  121. board = chess.Board()
  122. up_to = np.random.choice(unsampled_idx)
  123. unsampled_idx.remove(up_to)
  124. moment = moves[:up_to]
  125. df_add = pd.DataFrame(
  126. columns=[
  127. "board_data",
  128. "status",
  129. ]
  130. )
  131. for move in moment:
  132. board.push(chess.Move.from_uci(move))
  133. ai_moves = board_data(board)
  134.  
  135. counter = 0
  136. d = {
  137. "board_data": ai_moves,
  138. "status": status,
  139. }
  140. df_add.loc[len(df_add)] = d
  141. train_df = pd.concat([train_df, df_add], ignore_index=True)
  142. game += 1
  143.  
  144. # preprocessing data
  145.  
  146. train_df["status"] = train_df["status"].map(
  147. {"won": 1.0, "lost": -1.0, "drew": 0.0}
  148. ) # target
  149. X = np.array([x for x in train_df["board_data"]])
  150. temp = ""
  151. big_l = []
  152. for x in train_df["status"]:
  153. temp = (str(x) + "2") * 832
  154. temp = temp.split("2")
  155. tt = []
  156. for y in temp:
  157. if y != "":
  158. tt.append(y)
  159. temp = [float(y) for y in tt]
  160. big_l.append(temp)
  161.  
  162. train_df["status"] = big_l
  163.  
  164.  
  165. y = np.array([x for x in train_df["status"]])
  166. # train-test split for model evaluation
  167. X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, shuffle=True)
  168.  
  169. X_train = torch.tensor(X_train, dtype=torch.float32)
  170. y_train = torch.tensor(y_train, dtype=torch.float32)
  171. X_test = torch.tensor(X_test, dtype=torch.float32)
  172. y_test = torch.tensor(y_test, dtype=torch.float32)
  173. NON_LAST_LAYERS = 2
  174. model = nn.Sequential(
  175. nn.Linear(832, 832),
  176. )
  177. for i in range(NON_LAST_LAYERS):
  178. model.add_module(f"linear_{i}", nn.ReLU())
  179. model.add_module(f"linear_{i}", nn.Linear(832, 832))
  180.  
  181. model.add_module(f"linear_{NON_LAST_LAYERS}", nn.Tanh())
  182. try:
  183. model.eval()
  184. weights_path = "./ai_zan1ling4_mini_eval.pt"
  185. state_dict = torch.load(weights_path)
  186. model.load_state_dict(state_dict)
  187. except FileNotFoundError:
  188. model.train()
  189.  
  190. # loss function and optimizer
  191. loss_fn = nn.MSELoss() # mean square error
  192. optimizer = optim.AdamW(model.parameters(), lr=0.0001)
  193.  
  194. n_epochs = 40 # number of epochs to run optimal = 40, 220
  195. batch_size = 512 # size of each batch
  196. batch_start = torch.arange(0, len(X_train), batch_size)
  197.  
  198. # Hold the best model
  199. best_mse = np.inf # initialise value as infinite
  200. best_weights = None
  201. history = []
  202.  
  203. for epoch in tqdm.tqdm(range(n_epochs), desc="Epochs"):
  204. model.train()
  205. epoch_loss = 0.0
  206. for batch_idx in batch_start:
  207. batch_X, batch_y = (
  208. X_train[batch_idx : batch_idx + batch_size],
  209. y_train[batch_idx : batch_idx + batch_size],
  210. )
  211. optimizer.zero_grad()
  212. y_pred = model(batch_X)
  213. loss = loss_fn(y_pred, batch_y)
  214. loss.backward()
  215. optimizer.step()
  216. epoch_loss += loss.item() * batch_X.shape[0]
  217. epoch_loss /= len(X_train)
  218. history.append(epoch_loss)
  219. if epoch_loss < best_mse:
  220. best_mse = epoch_loss
  221. best_weights = copy.deepcopy(model.state_dict())
  222.  
  223. # load the best weights into the model
  224. model.load_state_dict(best_weights)
  225.  
  226. print("MSE: %.2f" % best_mse)
  227. print("RMSE: %.2f" % np.sqrt(best_mse))
  228. plt.plot(history)
  229. plt.title("Epoch loss for ZL")
  230. plt.xlabel("Number of Epochs")
  231. plt.ylabel("Epoch Loss")
  232. plt.draw()
  233. plt.savefig("ai-eval-losses.jpg")
  234. model.eval()
  235. with torch.no_grad():
  236. # Test out inference with 5 samples
  237. q = 0
  238. for i in range(5):
  239. X_sample = X_test[i : i + 1]
  240. X_sample = X_sample.clone().detach()
  241. print(X_sample.shape)
  242. y_pred = model(X_sample)
  243. print("Y PRED", y_pred)
  244. print(y_pred.shape)
  245. y_pred = process_output(y_pred, False)
  246. y_pred = torch.tensor(big_l)
  247. counter = 0
  248. torch.save(best_weights, "ai_zan1ling4_eval.pt")
  249.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement