def load_model(self):
        """
        Loads the next generation model from the appropriate directory. If not found, loads
        the best known model.
        """
        model = ChessModel(self.config)
        rc = self.config.resource

        dirs = get_next_generation_model_dirs(rc)
        if not dirs:
            logger.debug("loading best model")
            if self.config.opts.new and not load_best_model_weight(model):
                model.build()
                save_as_best_model(model)
            elif not load_best_model_weight(model):
                raise RuntimeError("Best model can not loaded!")
        else:
            latest_dir = dirs[-1]
            logger.debug("loading latest model")
            config_path = os.path.join(
                latest_dir, rc.next_generation_model_config_filename)
            weight_path = os.path.join(
                latest_dir, rc.next_generation_model_weight_filename)
            model.load(config_path, weight_path)
        return model
예제 #2
0
 def load_next_generation_model(self):
     """
     Loads the next generation model from the standard directory
     :return (ChessModel, file): the model and the directory that it was in
     """
     rc = self.config.resource
     while True:
         dirs = get_next_generation_model_dirs(self.config.resource)
         if dirs:
             break
         logger.info("There is no next generation model to evaluate")
         sleep(60)
     model_dir = dirs[
         -1] if self.config.eval.evaluate_latest_first else dirs[0]
     i = -1
     while model_dir in self.evaluated_model_name:
         #while Counter(self.evaluated_model_name)[model_dir] >= 2:   # evaluate a model only once
         i -= 1
         model_dir = dirs[i]
     config_path = os.path.join(model_dir,
                                rc.next_generation_model_config_filename)
     weight_path = os.path.join(model_dir,
                                rc.next_generation_model_weight_filename)
     model = ChessModel(self.config)
     model.load(config_path, weight_path)
     self.evaluated_model_name.append(model_dir)
     return model, model_dir
예제 #3
0
 def load_next_generation_model(self):
     rc = self.config.resource
     while True:
         dirs = get_next_generation_model_dirs(self.config.resource)
         if dirs:
             break
         logger.info(f"There is no next generation model to evaluate")
         sleep(60)
     model_dir = dirs[-1] if self.config.eval.evaluate_latest_first else dirs[0]
     config_path = os.path.join(model_dir, rc.next_generation_model_config_filename)
     weight_path = os.path.join(model_dir, rc.next_generation_model_weight_filename)
     model = ChessModel(self.config)
     model.load(config_path, weight_path)
     return model, model_dir
예제 #4
0
    def load_model(self):
        from chess_zero.agent.model_chess import ChessModel
        model = ChessModel(self.config)
        rc = self.config.resource

        dirs = get_next_generation_model_dirs(rc)
        if not dirs:
            logger.debug(f"loading best model")
            if not load_best_model_weight(model):
                raise RuntimeError(f"Best model can not loaded!")
        else:
            latest_dir = dirs[-1]
            logger.debug(f"loading latest model")
            config_path = os.path.join(latest_dir, rc.next_generation_model_config_filename)
            weight_path = os.path.join(latest_dir, rc.next_generation_model_weight_filename)
            model.load(config_path, weight_path)
        return model
예제 #5
0
 def load_next_generation_model(self):
     """
     Loads the next generation model from the standard directory
     :return (ChessModel, file): the model and the directory that it was in
     """
     rc = self.config.resource
     while True:
         dirs = get_next_generation_model_dirs(self.config.resource)
         if dirs:
             break
         logger.info("There is no next generation model to evaluate")
         sleep(60)
     model_dir = dirs[-1] if self.config.eval.evaluate_latest_first else dirs[0]
     config_path = os.path.join(model_dir, rc.next_generation_model_config_filename)
     weight_path = os.path.join(model_dir, rc.next_generation_model_weight_filename)
     model = ChessModel(self.config)
     model.load(config_path, weight_path)
     return model, model_dir
예제 #6
0
    def load_model(self):
        """
        Loads the next generation model from the appropriate directory. If not found, loads
        the best known model.
        """
        model = ChessModel(self.config)
        rc = self.config.resource

        dirs = get_next_generation_model_dirs(rc)
        if not dirs:
            logger.debug("loading best model")
            if not load_best_model_weight(model):
                raise RuntimeError("Best model can not loaded!")
        else:
            latest_dir = dirs[-1]
            logger.debug("loading latest model")
            config_path = os.path.join(latest_dir, rc.next_generation_model_config_filename)
            weight_path = os.path.join(latest_dir, rc.next_generation_model_weight_filename)
            model.load(config_path, weight_path)
        return model
예제 #7
0
class EvaluateWorker:
    def __init__(self, config: Config):
        """
        :param config:
        """
        self.config = config
        self.play_config = config.eval.play_config
        self.current_model = self.load_current_model()
        self.ng_model = ChessModel(self.config)
        self.m = Manager()
        self.cur_pipes = self.m.list([
            self.current_model.get_pipes(self.play_config.search_threads)
            for _ in range(self.play_config.max_processes)
        ])
        self.ng_pipes = self.m.list([
            self.ng_model.get_pipes(self.play_config.search_threads)
            for _ in range(self.play_config.max_processes)
        ])
        self.model_list = []
        self.history_list = []

    def start(self):
        while True:
            model_dir, config_path, weight_path = self.load_next_generation_model(
            )
            logger.debug("start evaluate model %s" % (model_dir))
            ng_is_great = self.evaluate_model()
            if ng_is_great:
                logger.debug("New Model become best model: %s" % (model_dir))
                save_as_best_model(self.ng_model)
                self.current_model.load(config_path, weight_path)
            else:
                logger.debug("No need to renew the Model.")
            # self.move_model(model_dir)

    def evaluate_model(self):

        futures = deque()
        with ProcessPoolExecutor(
                max_workers=self.play_config.max_processes) as executor:
            for game_idx in range(self.config.eval.game_num):
                fut = executor.submit(play_game,
                                      self.config,
                                      cur=self.cur_pipes,
                                      ng=self.ng_pipes,
                                      current_white=(game_idx % 2 == 0))
                futures.append(fut)

            results = []
            for game_idx in range(self.config.eval.game_num):
                # ng_score := if ng_model win -> 1, lose -> 0, draw -> 0.5
                fut = futures.popleft()
                ng_score, env, current_white = fut.result()
                results.append(ng_score)
                win_rate = sum(results) / len(results)
                game_idx = len(results)

                if (current_white):
                    player = 'red'
                else:
                    player = 'black'
                if (env.resigned):
                    resigned = 'by resign '
                else:
                    resigned = '          '

                logger.debug("game %3d: ng_score=%.1f as %s "
                             "%s"
                             "%5.2f\n"
                             "%s" % (game_idx, ng_score, player, resigned,
                                     win_rate, env.board.fen().split(' ')[0]))

                # colors = ("current_model", "ng_model")
                # if not current_white:
                #     colors = reversed(colors)
                # pretty_print(env, colors)

                if len(results) - sum(results) >= self.config.eval.game_num * (
                        1 - self.config.eval.replace_rate):
                    logger.debug("lose count reach %d so give up challenge" %
                                 (results.count(0)))
                    return False
                if sum(
                        results
                ) >= self.config.eval.game_num * self.config.eval.replace_rate:
                    logger.debug("win count reach %d so change best model" %
                                 (results.count(1)))
                    return True

        win_rate = sum(results) / len(results)
        logger.debug("winning rate %.1f" % win_rate * 100)
        return win_rate >= self.config.eval.replace_rate

    def move_model(self, model_dir):
        rc = self.config.resource
        new_dir = os.path.join(rc.next_generation_model_dir, "copies",
                               model_dir)
        os.rename(model_dir, new_dir)

    def load_current_model(self):
        model = ChessModel(self.config)
        load_best_model_weight(model)
        return model

    def load_next_generation_model(self):
        rc = self.config.resource
        while True:
            dirs = get_next_generation_model_dirs(self.config.resource)

            i = -1
            if dirs is not None:
                i = len(dirs) - 1
            while i >= 0:
                if dirs[i] in self.history_list:
                    break
                i = i - 1
            if (dirs is not None) and (len(dirs) > i + 1):
                self.model_list.extend(dirs[i + 1:])
                self.history_list.extend(dirs[i + 1:])
            if len(self.model_list) > 0:
                break
            logger.info(
                "There is no next generation model to evaluate, waiting for 600s"
            )
            sleep(600)
        model_dir = self.model_list.pop()

        print('========================================================')
        print('eval against %s' % (model_dir))
        print('========================================================')

        config_path = os.path.join(model_dir,
                                   rc.next_generation_model_config_filename)
        weight_path = os.path.join(model_dir,
                                   rc.next_generation_model_weight_filename)
        self.ng_model.load(config_path, weight_path)
        return model_dir, config_path, weight_path