Beispiel #1
0
	def test_save_and_load(self):
		torch.manual_seed(42)

		config = ModelConfig()
		model = Model.create(config, logger=NullLogger())
		model_dir = "local_tests/local_model_test"
		model.save(model_dir)
		assert os.path.exists(f"{model_dir}/config.json")
		assert os.path.exists(f"{model_dir}/model.pt")

		model = Model.load(model_dir).to(gpu)
		assert next(model.parameters()).device.type == gpu.type
Beispiel #2
0
	def from_saved(cls, loc: str, use_best: bool, epsilon: float, workers: int, depth: int):
		net = Model.load(loc, load_best=use_best).to(gpu)
		return cls(net, epsilon=epsilon, workers=workers, depth=depth)
Beispiel #3
0
	def from_saved(cls, loc: str, use_best: bool, c: float, search_graph: bool):
		net = Model.load(loc, load_best=use_best)
		net.to(gpu)
		return cls(net, c=c, search_graph=search_graph)
Beispiel #4
0
	def from_saved(cls, loc: str, use_best: bool):
		net = Model.load(loc, load_best=use_best)
		net.to(gpu)
		return cls(net)
Beispiel #5
0
	def from_saved(cls, loc: str, use_best: bool, lambda_: float, expansions: int) -> DeepAgent:
		net = Model.load(loc, load_best=use_best).to(gpu)
		return cls(net, lambda_=lambda_, expansions=expansions)
Beispiel #6
0
	def from_saved(cls, loc: str, use_best: bool, sample_policy=False):
		net = Model.load(loc, load_best=use_best)
		net.to(gpu)
		return cls(net, sample_policy)
Beispiel #7
0
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)
Beispiel #8
0
import matplotlib.pyplot as plt
import numpy as np
import torch

from librubiks import gpu, no_grad
from librubiks import cube
from librubiks.model import Model
from librubiks.utils import TickTock, Logger

tt = TickTock()
log = Logger("data/local_analyses/net.log", "Analyzing MCTS")
net = Model.load("data/local_method_comparison/asgerfix").eval().to(gpu)


def _get_adi_ff_slices(b, n):
	slice_size = n // b + 1
	# Final slice may have overflow, however this is simply ignored when indexing
	slices = [slice(i * slice_size, (i + 1) * slice_size) for i in range(b)]
	return slices

def _ff(oh_states, value=True, policy=True):
	batches = 1
	while True:
		try:
			value_parts = [net(oh_states[slice_], policy=policy, value=value).squeeze() for slice_ in
						   _get_adi_ff_slices(batches, len(oh_states))]
			values = torch.cat(value_parts).cpu()
			break
		except RuntimeError as e:  # Usually caused by running out of vram. If not, the error is still raised, else batch size is reduced
			if "alloc" not in str(e):
				raise e
Beispiel #9
0
import matplotlib.pyplot as plt

import numpy as np

from librubiks import gpu, cube, rc_params
from librubiks.model import Model
from librubiks.solving.agents import MCTS
from librubiks.utils import set_seeds, Logger, TickTock, TimeUnit

np.set_printoptions(precision=4, threshold=np.inf)
plt.rcParams.update(rc_params)

tt = TickTock()
log = Logger("data/local_analyses/mcts.log", "Analyzing MCTS")
net = Model.load("local_net").eval().to(gpu)


def solve(depth: int, c: float, time_limit: float):
    state, f, d = cube.scramble(depth, True)
    searcher = MCTS(net, c=c, search_graph=False)
    is_solved = searcher.search(state, time_limit)
    assert is_solved == (cube.get_solved().tostring() in searcher.indices)
    return is_solved, len(searcher.indices)


def analyze_var(var: str, values: np.ndarray, other_vars: dict):
    x = values
    y = []
    tree_sizes = []
    log.section(
        f"Optimizing {var}\nExpected runtime: {len(x)*time_limit*n:.2f} s\nGames per evaluation: {n}"