def create_data_set(data_set_file, pgn_dir): """ creates the data set from all games in the pgn folder the data set is in hdf5 format and compressed because most of the matrices are sparse :param data_set_file: path of the hdf5 file to create :return: """ # check if the file already exists if os.path.exists(data_set_file): logger.debug("data set file {} already exists".format(data_set_file)) return # create a new data file (compression level needs to be between 0 and 9, 0 is no compression and the fastest) # 6 seemed to be the best time / size trade off. at least 1 is necessary otherwise the file size will explode # the zlib algorithm is lossless compression_filter = tables.Filters(complib='zlib', complevel=1) file = tables.open_file(data_set_file, mode='w', filters=compression_filter) atom = tables.Float64Atom() array_c = file.create_earray(file.root, 'data', atom, (0, full_example_size)) # load all pgn files and add the games to the data set path_list = os.listdir(pgn_dir) game_count = 0 for pgn_file_name in path_list: pgn_file_path = pgn_dir + "/" + pgn_file_name pgn_file = open(pgn_file_path) logger.info("start to process file {}".format(pgn_file_name)) # read out all games in the pgn file game = chess.pgn.read_game( pgn_file) # read out the next game from the pgn while game is not None: board = chess.Board() # create a new board # get the value of the game result = value_from_result(game.headers["Result"]) if result is None: game = chess.pgn.read_game( pgn_file) # read out the next game from the pgn continue # go through all moves and append the data to the data file for move in game.mainline_moves(): try: network_input = board_representation.board_to_matrix(board) network_input = network_input.flatten() move_idx = np.array( [board_representation.move_to_index(move, board.turn)]) # policy = board_representation.move_to_policy(move, board.turn) value = np.array([ result ]) if board.turn == chess.WHITE else np.array([-result]) training_example = np.concatenate( (network_input, move_idx, value)) training_example = np.expand_dims(training_example, axis=0) array_c.append(training_example) # make the move to get the next board position board.push(move) except Exception as e: # ignore the rest of the game if an error occurs logging.error("error in the current game: ", exc_info=True) continue game = chess.pgn.read_game( pgn_file) # read out the next game from the pgn game_count += 1 if game_count % 5000 == 0: logger.debug("processed {} games".format(game_count)) pgn_file.close() logger.info("total number of games processed: {}".format(game_count)) file.close()
def white_perspective(self): player = CONST.WHITE if self.chess_board.turn == chess.WHITE else CONST.BLACK return board_representation.board_to_matrix(self.chess_board), player
def create_averaged_data_set(db_file, data_set_file): """ creates the averaged hdf5 file with all positions :param db_file: the file path of the db file :param data_set_file: the file path of the hdf5 file to create :return: """ # check if the file already exists if os.path.exists(data_set_file): logger.debug("data set file {} already exists".format(data_set_file)) return # create a new data file (compression level needs to be between 0 and 9, 0 is no compression and the fastest) # 6 seemed to be the best time / size trade off. at least 1 is necessary otherwise the file size will explode # the zlib algorithm is lossless compression_filter = tables.Filters(complib='zlib', complevel=1) file = tables.open_file(data_set_file, mode='w', filters=compression_filter) atom = tables.Float64Atom() array_c = file.create_earray(file.root, 'data', atom, (0, avg_example_size)) # open a connection to the db file connection = sqlite3.connect(db_file) cursor = connection.cursor() # query all positions cursor.execute("SELECT * FROM position;") row = cursor.fetchone() position_count = 0 while row is not None: try: # create the board from the fen string fen = row[1] board = chess.Board(fen=fen) # create the neural network input of the state network_input = board_representation.board_to_matrix(board) network_input = network_input.flatten() # create the policy policy = np.zeros(board_representation.LABEL_COUNT) move_indices = row[2].strip('_').split("_") for move_idx in move_indices: policy[int(move_idx)] += 1 # normalize the policy policy /= row[4] # calculate the value from the networks perspective value = row[3] / row[4] value = np.array( [value]) if board.turn == chess.WHITE else np.array([-value]) # add the training example to the hdf5 file training_example = np.concatenate((network_input, policy, value)) training_example = np.expand_dims(training_example, axis=0) array_c.append(training_example) # log the progress position_count += 1 if position_count % 150000 == 0: logger.debug("processed {} positions".format(position_count)) # fetch the next fow row = cursor.fetchone() except Exception as e: # ignore the current row if an error occurred logging.error("error processing the current row: ", exc_info=True) continue logger.info( "total number of processed positions: {}".format(position_count)) file.close()
def mainTrain(): # The logger utils.init_logger(logging.DEBUG, file_name="../log/chess_sl.log") logger = logging.getLogger('Chess_SL') # set the random seed # set the random seed random.seed(a=None, version=2) np.random.seed(seed=None) logger.debug("start the main test program") # test the rise network network = networks.RiseNet(Config.learning_rate, Config.n_blocks, Config.n_se_blocks, Config.n_filters, Config.se_ratio, Config.n_mobile_filters, Config.n_filter_inc, Config.weight_decay) network = data_storage.net_to_device(network, Config.training_device) board = chess.Board() input = board_representation.board_to_matrix(board) input = torch.tensor(input) input = input.to(Config.training_device, dtype=torch.float) input = input.unsqueeze(0) res = network(input) board = chess.Board() board.push_san("g4") board.push_san("e5") board.push_san("f4") board.push_uci("d8h4") # board.push_san("Qh4") print(board.turn == chess.WHITE) list = [1, 2, 3, 4] list.remove(2) print(list) test_str = "_5_6" print(test_str.split("_")) # get the fen string of a board board = chess.Board() board.push_san("e4") board.push_san("e5") board.push_san("Nf3") board.push_san("Nc6") board.push_san("Bc4") board.push_san("Bc5") board.push_san("Qe2") board.push_san("d6") board.push_san("Nc3") board.push_san("Bd7") board.push_san("b3") board.push_san("Qe7") fen_string = board.fen() print(fen_string) print("n-bytes: ", len(fen_string.encode('utf-8'))) filter = data_processing.get_compression_filter() data_file = tables.open_file("../king-base-light-avg.h5", mode='r', filters=filter) print(data_file.root.data.shape[0]) state = data_file.root.data[2, 0:CONST.STATE_SIZE] policy_idx = int(data_file.root.data[2, -2]) value = data_file.root.data[100, -1] state = state.reshape(CONST.INPUT_CHANNELS, CONST.BOARD_HEIGHT, CONST.BOARD_WIDTH) policy = np.zeros(board_representation.LABEL_COUNT) policy[policy_idx] = 1 pgn_file = open("../pgns/KingBaseLite2019-B00-B19.pgn") game = chess.pgn.read_game(pgn_file) # read out the next game from the pgn while game is not None: result = data_processing.value_from_result(game.headers["Result"]) if result is None: print(game) game = chess.pgn.read_game( pgn_file) # read out the next game from the pgn for move in game.mainline_moves(): if move.uci() == "0000": print(game) print(move)
def mainTrain(): # The logger utils.init_logger(logging.DEBUG, file_name="log/chess_sl.log.log") logger = logging.getLogger('Sup Learning') np.set_printoptions(suppress=True, precision=6) # set the random seed random.seed(a=None, version=2) np.random.seed(seed=None) # parameters network_dir = "networks" network_file = network_dir + "/" + "network_batch_158436.pt" training_progress_dir = "training_progress" # count the games in the database dict_file = "elo_dict.pkl" if not Path(dict_file).is_file(): elo_dict = data_processing.create_elo_dict("pgns") with open(dict_file, 'wb') as f: pickle.dump(elo_dict, f, pickle.HIGHEST_PROTOCOL) with open(dict_file, 'rb') as f: elo_dict = pickle.load(f) elo = [] count = [] tot_count = 0 for key in sorted(elo_dict): elo.append(int(key)) value = elo_dict[key] tot_count += value count.append(tot_count) # plot the training policy loss fig1 = plt.figure(1) plt.plot(elo, count) axes = plt.gca() axes.grid(True, color=(0.9, 0.9, 0.9)) plt.title("Dataset Statistics") plt.xlabel("Minimal ELO") plt.ylabel("Total Number of Games") fig1.show() plt.show() # load the network logger.info("load the neural network: " + network_file) net = torch.load(network_file, map_location='cpu') board = chess.Board() board.push_san("e4") board.push_san("e5") board.push_san("Nf3") bit_board = board_representation.board_to_matrix(board) policy, value = net(torch.Tensor(bit_board).unsqueeze(0)) print(policy) print(value) print("move: ", board_representation.policy_to_move(policy.detach().numpy(), board.turn)) print(board.legal_moves) # plot the learning progress value_loss = np.load(training_progress_dir + "/value_loss.npy") policy_loss = np.load(training_progress_dir + "/policy_loss.npy") batches = np.load(training_progress_dir + "/batches.npy") # plot the loss versus the number of seen batches # plot the value training loss fig2 = plt.figure(2) plt.plot(batches, value_loss) axes = plt.gca() axes.grid(True, color=(0.9, 0.9, 0.9)) plt.title("Average Value Training Loss") plt.xlabel("Training Samples") plt.ylabel("Value Loss") fig2.show() # plot the training policy loss fig3 = plt.figure(3) plt.plot(batches, policy_loss) axes = plt.gca() axes.grid(True, color=(0.9, 0.9, 0.9)) plt.title("Average Policy Training Loss") plt.xlabel("Training Samples") plt.ylabel("Policy Loss") fig3.show() plt.show()
def mainTrain(): # The logger utils.init_logger(logging.DEBUG, file_name="log/chess_sl.log.log") logger = logging.getLogger('MCTS') np.set_printoptions(suppress=True, precision=6) # set the random seed random.seed(a=None, version=2) np.random.seed(seed=None) # parameters network_dir = "networks" network_file = network_dir + "/" + "network_batch_158436.pt" training_progress_dir = "training_progress" # load the network logger.info("load the neural network: " + network_file) net = torch.load(network_file, map_location='cuda') board = chess.Board() board.push_san("e4") board.push_san("e5") board.push_san("Nf3") bit_board = board_representation.board_to_matrix(board) policy, value = net(torch.Tensor(bit_board).unsqueeze(0).cuda()) print(policy) print(value) print( "move: ", board_representation.policy_to_move(policy.detach().cpu().numpy(), board.turn)) print(board.legal_moves) # find the policy with the help of mcts board = chess.Board() board.push_san("g4") board.push_san("e5") board.push_san("f4") chess_board = game.ChessBoard() chess_board.chess_board = board policy = mcts.mcts_policy(chess_board, 200, net, 1, 0) print( "fastest mate move: ", board_representation.policy_to_move(policy, chess_board.chess_board.turn)) board = chess.Board() board.push_san("e4") board.push_san("e5") board.push_san("Nf3") chess_board = game.ChessBoard() chess_board.chess_board = board start_time = time.time() policy = mcts.mcts_policy(chess_board, 800, net, 1, 0) elapsed_time = time.time() - start_time print("time needed for mtcs: ", elapsed_time) print( "suggested move after e4, e5, Nf3: ", board_representation.policy_to_move(policy, chess_board.chess_board.turn))
logger.info("start the board representation tests") board = chess.Board() board.push_san("e4") board.push_san("e5") board.push_san("Nf3") board.push_san("Nc6") board.push_san("Bc4") board.push_san("Bc5") board.push_san("Qe2") board.push_san("d6") board.push_san("Nc3") board.push_san("Bd7") board.push_san("b3") board.push_san("Qe7") bit_board = board_representation.board_to_matrix(board) ################################# white pieces # white pawn on b3 if bit_board[PlaneIndex.white_pawns][5][1] < 0.9: logger.error("white pawn is not on b3") # white knight on c3 if bit_board[PlaneIndex.white_knights][5][2] < 0.9: logger.error("white knight is not on c3") # white bishop on c1 if bit_board[PlaneIndex.white_bishops][7][2] < 0.9: logger.error("white bishop is not on c1") # white rook on a1