Пример #1
0
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()
Пример #2
0
 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
Пример #3
0
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()
Пример #4
0
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)
Пример #5
0
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()
Пример #6
0
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))
Пример #7
0
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