def setup_class(cls): os.makedirs("local_tests", exist_ok = True) set_seeds() repo_path = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ) if 'PYTHONPATH' not in os.environ: os.environ['PYTHONPATH'] = '' if repo_path not in os.environ['PYTHONPATH']: os.environ['PYTHONPATH'] += f':{repo_path}'
'choices': [True, False], }, } if __name__ == "__main__": description = r""" ___________________________________________________________________ /_/_/_/\ ______ _ ______ _ _______ _____ _ __ _____ /_/_/_/\/\ | ___ \ | | ___ \ | | | ___ \_ _| | / // ___| /_/_/_/\/\/\| |_/ / | | |_/ / | | | |_/ / | | | |/ / \ `--. \_\_\_\/\/\/| /| | | /| | | | ___ \ | | | \ `--. \ \_\_\_\/\/ | |\ \| |____ | |\ \| |_| | |_/ /_| |_| |\ \/\__/ / \_\_\_\/ \_| \_\_____/ \_| \_|\___/\____/ \___/\_| \_/\____/ __________________________________________________________________ Start one or more Reinforcement Learning training session(s) on the Rubik's Cube using config or CLI arguments. """ set_seeds() parser = Parser(options, description=description, name='train', description_last=True) parsley = parser.parse() TrainJob.clean_dir(parser.save_location) jobs = [TrainJob(**settings) for settings in parsley] for job in jobs: job.execute()
def agent_optimize(): """ Main way to run optimization. Hard coded to run optimization at 1 sec per game, but other behaviour can be set with CLI arguments seen by running `python librubiks/solving/hyper_optim.py --help`. Does not support config arguments. NB: The path here is different to the one in runeval and runtrain: It needs to be to folder containing model.pt! It doesen't work with parent folder. Can work with runeval through ``` python librubiks/solving/hyper_optim.py --location example/net1/ python runeval.py --location example/ --optimized_params True ``` """ set_seeds() #Lot of overhead just for default argument niceness: latest model is latest from runeval import train_folders model_path = '' if train_folders: for folder in [train_folders[-1]] + glob(f"{train_folders[-1]}/*/"): if os.path.isfile(os.path.join(folder, 'model.pt')): model_path = os.path.join(folder) break parser = argparse.ArgumentParser(description='Optimize Monte Carlo Tree Search for one model') parser.add_argument('--location', help='Folder which includes model.pt. Results will also be saved here', type=str, default=model_path) parser.add_argument('--iterations', help='Number of iterations of Bayesian Optimization', type=int, default=125) parser.add_argument('--agent', help='Name of agent corresponding to agent class in librubiks.solving.agents', type=str, default='AStar', choices = ['AStar', 'MCTS', 'EGVM']) parser.add_argument('--depth', help='Single number corresponding to the depth at which to test. If 0: run this at deep', type=int, default=0) parser.add_argument('--eval_games', help='Number of games to evaluate at depth', type = int, default='100') parser.add_argument('--save_optimal', help='If Tue, saves a JSON of optimal hyperparameters usable for runeval', type=literal_eval, default=True, choices = [True, False]) parser.add_argument('--use_best', help="Set to True to use model-best.pt instead of model.pt.", type=literal_eval, default=True, choices = [True, False]) parser.add_argument('--optim_lengths', help="Set to true to optimize against sol percentage / solution length. Else, simply use sol %", type=literal_eval, default=True, choices = [True, False]) parser.add_argument('--optimizer', help="Either BO or grid", type=str, default="grid", choices = ("grid", "BO")) args = parser.parse_args() agent_name = args.agent if agent_name == 'MCTS': params = { 'c': (0.1, 100), } def prepper(params): return params persistent_params = { 'net': Model.load(args.location, load_best=args.use_best), 'search_graph': True, } elif agent_name == 'AStar': params = { 'lambda_': (0, 0.4), 'expansions': (1, 1000), } def prepper(params): params['expansions'] = int(params['expansions']) return params persistent_params = { 'net': Model.load(args.location, load_best=args.use_best), } elif agent_name == 'EGVM': params = { 'epsilon': (0, 0.5), 'workers': (1, 500), 'depth': (1, 250), } def prepper(params): params['workers'] = int(params['workers']) params['depth'] = int(params['depth']) return params persistent_params = { 'net': Model.load(args.location, load_best=args.use_best), } else: raise NameError(f"{agent_name} does not correspond to a known agent, please pick either AStar, MCTS or EGVM") logger = Logger(os.path.join(args.location, f'{agent_name}_optimization.log'), 'Optimization') logger.log(f"{agent_name} optimization. Using network from {model_path}.") logger.log(f"Received arguments: {vars(args)}") agent = getattr(agents, agent_name) evaluator = Evaluator(n_games=args.eval_games, max_time=5, scrambling_depths=range(0) if args.depth == 0 else [args.depth]) assert args.optimizer in ["BO", "grid"], f"Optimizer should be 'BO' or 'grid', not '{args.optimizer}'" if args.optimizer == "BO": optimizer = BayesianOptimizer(target_function=None, parameters=params, logger=logger) else: optimizer = GridSearch(target_function=None, parameters=params, logger=logger) optimizer.objective_from_evaluator(evaluator, agent, persistent_params, param_prepper=prepper, optim_lengths=args.optim_lengths) optimizer.optimize(args.iterations) if args.save_optimal: with open(os.path.join(args.location, f'{agent_name}_params.json'), 'w') as outfile: json.dump(prepper(copy(optimizer.optimal)), outfile)