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
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
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
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
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
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
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