def inner_bo(self, enemy_config, kappa_val=6): """ Use BO to determine the best configuration, given the template :param enemy_config: An enemy mapping object :return: Best mapping and its corresponding result """ objective_function = ObjectiveFunction( experiment_info=self._experiment_info, log=self._log, socket_connect=self._socket) config = enemy_config # Devide the evaluations for each core init_pts = 5 if config.same_defines: iterations = self._experiment_info.tuning_max_iterations assert iterations > 0, "Bayesian optimization needs more iterations to work" objective_function.stored_mapping = config data_range = config.enemies[0].get_defines_range() bo = BayesianOptimization(objective_function.bo_call, data_range, verbose=0) bo.init(init_points=init_pts) bo.maximize(n_iter=1, kappa=kappa_val) it = 1 while it < iterations and time() < self._t_end: bo.maximize(n_iter=1, kappa=kappa_val) it += 1 for core in range(config.enemy_cores): config.enemies[core].set_defines(bo.res['max']['max_params']) else: iterations = int(self._experiment_info.tuning_max_iterations / config.enemy_cores - init_pts) assert iterations > 0, "Bayesian optimization needs more iterations to work" for core in range(config.enemy_cores): objective_function.optimized_core = core objective_function.stored_mapping = config data_range = config.enemies[core].get_defines_range() bo = BayesianOptimization(objective_function.bo_call, data_range, verbose=0) bo.init(init_points=init_pts) bo.maximize(n_iter=1, kappa=kappa_val) it = 1 while it < iterations and time() < self._t_end: bo.maximize(n_iter=1, kappa=kappa_val) it += 1 config.enemies[core].set_defines(bo.res['max']['max_params']) best_score = objective_function.best_score return config, best_score
def test_only_random(): random_state = ensure_rng(0) xs = np.linspace(-2, 10, 1000) f = np.exp(-(xs - 2)**2) + np.exp(-(xs - 6)**2 / 10) + 1 / (xs**2 + 1) bo = BayesianOptimization(f=lambda x: f[int(x)], pbounds={'x': (0, len(f) - 1)}, random_state=random_state, verbose=0) bo.init(20) res = bo.space.max_point() max_params = res['max_params'] max_val = res['max_val'] assert max_val > 1.0, 'function range is ~.2 - ~1.4, should be above 1.' assert max_val / f.max() > .8, 'should be better than 80% of max val' assert max_params['x'] > 200, 'should be in a peak area (around 300)' assert max_params['x'] < 500, 'should be in a peak area (around 300)'
def optimize_postproc_params(arch_to_paths, arches, train_data_path): def bo_best(self): return {'max_val': self.Y.max(), 'max_params': dict(zip(self.keys, self.X[self.Y.argmax()]))} preload, seeded_objective = _make_scorable_objective(arch_to_paths, arches, train_data_path) preload() # read datas into memory seeded_bounds = { 'mask_thresh': (.4, .9), 'seed_thresh': (.4, .9), 'min_seed_size': (0, 100), 'min_size': (0, 100), 'alpha': (0.0, 1.0), } seeded_bo = BayesianOptimization(seeded_objective, seeded_bounds) cand_params = [ {'mask_thresh': 0.9000, 'min_seed_size': 100.0000, 'min_size': 100.0000, 'seed_thresh': 0.4000}, {'mask_thresh': 0.8367, 'seed_thresh': 0.4549, 'min_seed_size': 97, 'min_size': 33}, # 'max_val': 0.8708 {'mask_thresh': 0.8367, 'min_seed_size': 97.0000, 'min_size': 33.0000, 'seed_thresh': 0.4549}, # max_val': 0.8991 {'mask_thresh': 0.7664, 'min_seed_size': 48.5327, 'min_size': 61.8757, 'seed_thresh': 0.4090}, # 'max_val': 0.9091} {'mask_thresh': 0.6666, 'min_seed_size': 81.5941, 'min_size': 13.2919, 'seed_thresh': 0.4241}, # full dataset 'max_val': 0.9142} # {'mask_thresh': 0.8, 'seed_thresh': 0.5, 'min_seed_size': 20, 'min_size': 0}, # {'mask_thresh': 0.5, 'seed_thresh': 0.8, 'min_seed_size': 20, 'min_size': 0}, # {'mask_thresh': 0.8338, 'min_seed_size': 25.7651, 'min_size': 38.6179, 'seed_thresh': 0.6573}, # {'mask_thresh': 0.6225, 'min_seed_size': 93.2705, 'min_size': 5, 'seed_thresh': 0.4401}, # {'mask_thresh': 0.7870, 'min_seed_size': 85.1641, 'min_size': 64.0634, 'seed_thresh': 0.4320}, ] for p in cand_params: p['alpha'] = .88 n_init = 2 if DEBUG else 40 seeded_bo.explore(pd.DataFrame(cand_params).to_dict(orient='list')) # Basically just using this package for random search. # The BO doesnt seem to help much seeded_bo.plog.print_header(initialization=True) seeded_bo.init(n_init) print('seeded ' + ub.repr2(bo_best(seeded_bo), nl=0, precision=4)) gp_params = {"alpha": 1e-5, "n_restarts_optimizer": 2} n_iter = 2 if DEBUG else 10 for kappa in [10, 5, 1]: seeded_bo.maximize(n_iter=n_iter, acq='ucb', kappa=kappa, **gp_params) best_res = bo_best(seeded_bo) print('seeded ' + ub.repr2(best_res, nl=0, precision=4)) max_params = best_res['max_params'] max_value = best_res['max_val'] # search for a good alpha # TODO: improve bayes_opt package to handle this for alpha in tqdm.tqdm(np.linspace(0, 1, 50), desc='opt alpha'): params = max_params.copy() params['alpha'] = alpha val = seeded_objective(**params) if val > max_value: max_value = val max_params = params return max_value, max_params
def hypersearch_probs(): prob_paths = paths['probs'] prob1_paths = paths['probs1'] # https://github.com/fmfn/BayesianOptimization # https://github.com/fmfn/BayesianOptimization/blob/master/examples/usage.py # https://github.com/fmfn/BayesianOptimization/blob/master/examples/exploitation%20vs%20exploration.ipynb # subx = [0, 1, 2, 3, 4, 5] subx = [2, 4, 5, 9, 10, 14, 17, 18, 20, 30, 33, 39, 61, 71, 72, 73, 75, 81, 84] from bayes_opt import BayesianOptimization def best(self): return {'max_val': self.Y.max(), 'max_params': dict(zip(self.keys, self.X[self.Y.argmax()]))} def seeded_objective(**params): seed_thresh, mask_thresh, min_seed_size, min_size = ub.take( params, 'seed_thresh, mask_thresh, min_seed_size, min_size'.split(', ')) fscores = [] for path, path1 in zip(ub.take(prob_paths, subx), ub.take(prob1_paths, subx)): gti, uncertain, dsm, bgr = gt_info_from_path(path) probs = np.load(path)['arr_0'] seed_probs = probs[:, :, task.classname_to_id['inner_building']] seed = (seed_probs > seed_thresh).astype(np.uint8) probs1 = np.load(path1)['arr_0'] mask_probs = probs1[:, :, 1] mask = (mask_probs > mask_thresh).astype(np.uint8) pred = seeded_instance_label(seed, mask, min_seed_size=min_seed_size, min_size=min_size) scores = instance_fscore(gti, uncertain, dsm, pred) fscore = scores[0] fscores.append(fscore) mean_fscore = np.mean(fscores) return mean_fscore seeded_bounds = { 'mask_thresh': (.4, .9), 'seed_thresh': (.4, .9), 'min_seed_size': (0, 100), 'min_size': (0, 100), } n_init = 50 seeded_bo = BayesianOptimization(seeded_objective, seeded_bounds) seeded_bo.explore(pd.DataFrame([ {'mask_thresh': 0.9000, 'min_seed_size': 100.0000, 'min_size': 100.0000, 'seed_thresh': 0.4000}, {'mask_thresh': 0.8, 'seed_thresh': 0.5, 'min_seed_size': 20, 'min_size': 0}, {'mask_thresh': 0.5, 'seed_thresh': 0.8, 'min_seed_size': 20, 'min_size': 0}, {'mask_thresh': 0.8338, 'min_seed_size': 25.7651, 'min_size': 38.6179, 'seed_thresh': 0.6573}, {'mask_thresh': 0.6225, 'min_seed_size': 93.2705, 'min_size': 5, 'seed_thresh': 0.4401}, {'mask_thresh': 0.7870, 'min_seed_size': 85.1641, 'min_size': 64.0634, 'seed_thresh': 0.4320}, {'mask_thresh': 0.8367, 'seed_thresh': 0.4549, 'min_seed_size': 97, 'min_size': 33}, # 'max_val': 0.8708 {'mask_thresh': 0.7664, 'min_seed_size': 48.5327, 'min_size': 61.8757, 'seed_thresh': 0.4090}, # 'max_val': 0.9091} {'mask_thresh': 0.8367, 'min_seed_size': 97.0000, 'min_size': 33.0000, 'seed_thresh': 0.4549}, # max_val': 0.8991 ]).to_dict(orient='list')) seeded_bo.plog.print_header(initialization=True) seeded_bo.init(n_init) print(ub.repr2(best(seeded_bo), nl=0, precision=4)) print('seeded ' + ub.repr2(best(seeded_bo), nl=0, precision=4)) print('inner ' + ub.repr2(best(inner_bo), nl=0, precision=4)) print('outer ' + ub.repr2(best(outer_bo), nl=0, precision=4)) # {'max_params': {'thresh': 0.8000, 'min_size': 0.0000}, 'max_val': 0.6445} gp_params = {"alpha": 1e-5, "n_restarts_optimizer": 2} n_iter = n_init // 2 for kappa in [10, 5, 1]: seeded_bo.maximize(n_iter=n_iter, acq='ucb', kappa=kappa, **gp_params) inner_bo.maximize(n_iter=n_iter, acq='ucb', kappa=kappa, **gp_params) outer_bo.maximize(n_iter=n_iter, acq='ucb', kappa=kappa, **gp_params) print('seeded ' + ub.repr2(best(seeded_bo), nl=0, precision=4)) print('inner ' + ub.repr2(best(inner_bo), nl=0, precision=4)) print('outer ' + ub.repr2(best(outer_bo), nl=0, precision=4)) print(arch)
class LearningGUI: def __init__(self, learning_client): self.learning_client = learning_client self.parent = tk.Tk() self.parent.resizable(0, 0) self.parent.minsize(500, 500) self.parent.maxsize(1000, 1000) self.parent.title('Parameters Learning GUI') self.parent.bind('<Control-c>', lambda e: self.parent.destroy()) self.task_ctr_frame = tk.LabelFrame(self.parent, font=title_font, text="Task Settings") self.lrning_frame = tk.LabelFrame( self.parent, font=title_font, text="Bayesian Optimization Settings and Info") self.dyn_config_frame = tk.LabelFrame( self.parent, height=400, font=title_font, text="Dynamic Reconfigure Settings") self.lrning_frame.grid(row=0, column=1, sticky='wens', padx=2, pady=2) self.task_ctr_frame.grid(row=0, column=0, sticky='wns', padx=2, pady=2) self.dyn_config_frame.grid(row=1, column=0, columnspan=2, sticky='ns', padx=2, pady=2) self.parent.rowconfigure(1, minsize=400) self.parent.columnconfigure(1, weight=1) # --------- Task Control Frame --------- # self.task_ctr = dict() self.task_ctr['start'] = tk.Button(self.task_ctr_frame, width=10, font=normal_font, text='Start Task', command=self.start_task_once) self.task_ctr['fail'] = tk.Button( self.task_ctr_frame, width=10, font=normal_font, text='FAILURE', command=self.learning_client.cancel_task, fg='red') task_type_frame = tk.Frame(self.task_ctr_frame) v = tk.IntVar(task_type_frame) v.set(0) self.learning_client.set_action_settings(atype=0) self.task_ctr['circle'] = tk.Radiobutton( task_type_frame, text="Circle", variable=v, value=0, command=lambda: self.learning_client.set_action_settings(atype=0)) self.task_ctr['square'] = tk.Radiobutton( task_type_frame, text="Square", variable=v, value=1, command=lambda: self.learning_client.set_action_settings(atype=1)) self.task_ctr['circle'].pack(side='left', anchor='center') self.task_ctr['square'].pack(side='left', anchor='center') self.task_ctr['depth'] = tk.Scale( self.task_ctr_frame, from_=0.0, to=1.0, resolution=0.01, orient='horizontal', font=small_font, tickinterval=1, length=250, command=lambda x: self.learning_client.set_action_settings( depth=float(x))) self.task_ctr['radius'] = tk.Scale( self.task_ctr_frame, from_=0.1, to=1.5, resolution=0.1, orient='horizontal', font=small_font, tickinterval=1.4, length=250, command=lambda x: self.learning_client.set_action_settings( radius=float(x))) self.task_ctr['speed'] = tk.Scale( self.task_ctr_frame, from_=0.1, to=5.0, resolution=0.1, orient='horizontal', font=small_font, tickinterval=4.9, length=250, command=lambda x: self.learning_client.set_action_settings( speed=float(x))) self.task_ctr['depth'].set(0.05) self.task_ctr['radius'].set(1) self.task_ctr['speed'].set(0.2) self.task_ctr['start'].grid(columnspan=2, sticky='we', padx=2, pady=2) self.task_ctr['fail'].grid(row=0, column=2, columnspan=2, sticky='we', padx=2, pady=2) self.create_labels(self.task_ctr_frame, 1, 0, 0, 'Type', 'Depth', 'Radius', 'Speed') task_type_frame.grid(row=1, column=1, columnspan=3, sticky='we', padx=2, pady=2) self.task_ctr['depth'].grid(row=2, column=1, columnspan=3, sticky='we', padx=2, pady=2) self.task_ctr['radius'].grid(row=3, column=1, columnspan=3, sticky='we', padx=2, pady=2) self.task_ctr['speed'].grid(row=4, column=1, columnspan=3, sticky='we', padx=2, pady=2) # --------- Bayesian Optimization and Info Frame --------- # self.lrning_ctr = dict() self.lrning_ctr['init'] = tk.Button(self.lrning_frame, text='Add Initial Point', font=normal_font, command=self.add_last_init_pt) self.lrning_ctr['raninit'] = tk.Button( self.lrning_frame, text='Add Random Initial Points', font=normal_font, command=self.add_rand_init_pt) self.lrning_ctr['points'] = tk.Scale(self.lrning_frame, from_=1, to=10, orient='horizontal', font=small_font, tickinterval=9, length=150) self.lrning_ctr['start'] = tk.Button(self.lrning_frame, text='Start Learning', font=normal_font, command=self.learn) self.lrning_ctr['iter'] = tk.Scale(self.lrning_frame, from_=1, to=40, orient='horizontal', font=small_font, tickinterval=39, length=150) self.lrning_ctr['cancel'] = tk.Button(self.lrning_frame, text='Cancel Learning', width=12, font=normal_font, command=self.reset_learning, fg='red') self.lrning_ctr['load'] = tk.Button(self.lrning_frame, text='Automatic Load & Learn', font=normal_font, command=self.load_init_pts) self.lrning_ctr['save'] = tk.Button(self.lrning_frame, text='Save Results', font=normal_font, command=self.save_results) self.lrning_ctr['init'].grid(row=0, column=0, columnspan=2, sticky='we', padx=2, pady=2) self.lrning_ctr['raninit'].grid(row=1, column=0, columnspan=2, sticky='we', padx=2, pady=2) tk.Label(self.lrning_frame, font=small_font, anchor='e', width=8, text='Points').grid(row=2, column=0, padx=2, pady=2) self.lrning_ctr['points'].grid(row=2, column=1, sticky='we', padx=2, pady=2) self.lrning_ctr['start'].grid(row=3, column=0, columnspan=2, sticky='we', padx=2, pady=2) tk.Label(self.lrning_frame, font=small_font, anchor='e', width=8, text='Iterations').grid(row=4, column=0, padx=2, pady=2) self.lrning_ctr['iter'].grid(row=4, column=1, sticky='we', padx=2, pady=2) self.lrning_ctr['save'].grid(row=0, column=2, sticky='we', padx=2, pady=2) self.lrning_ctr['load'].grid(row=0, column=3, sticky='we', padx=2, pady=2) self.lrning_ctr['cancel'].grid(row=1, column=2, columnspan=2, sticky='we', padx=2, pady=2) self.params_frame = tk.LabelFrame(self.lrning_frame, font=title_font, text="Learning Params.") self.params_frame.grid(row=2, rowspan=3, column=2, sticky='ns', padx=2, pady=2) self.info_frame = tk.LabelFrame(self.lrning_frame, font=title_font, text="Information") self.info_frame.grid(row=2, rowspan=3, column=3, sticky='wens', padx=2, pady=2) self.lrning_frame.columnconfigure(3, weight=1) self.create_labels(self.params_frame, 0, 0, 0, 'Alpha', 'xi/kappa', 'Acq. Fun.', 'Loc. Opt.', 'd', 'logistic', anchor='e', width=8) self.lrning_param = dict() self.lrning_param['alpha'] = tk.Entry(self.params_frame, font=small_font, width=10) self.lrning_param['alpha'].insert(0, '1e-10') self.lrning_param['const'] = tk.Entry(self.params_frame, font=small_font, width=10) self.lrning_param['const'].insert(0, '0.001') self.lrning_param['var'] = tk.StringVar(self.params_frame) self.lrning_param['var'].set('poi') self.lrning_param['acq'] = tk.OptionMenu(self.params_frame, self.lrning_param['var'], 'poi', 'ei', 'ucb') self.lrning_param['acq'].config(font=small_font) self.lrning_param['locvar'] = tk.IntVar() self.lrning_param['local'] = tk.Checkbutton( self.params_frame, variable=self.lrning_param['locvar']) self.lrning_param['dist'] = tk.Entry(self.params_frame, font=small_font, width=10) self.lrning_param['dist'].insert(0, '0.1') self.lrning_param['logvar'] = tk.IntVar() self.lrning_param['logis'] = tk.Checkbutton( self.params_frame, variable=self.lrning_param['logvar']) self.lrning_param['alpha'].grid(row=0, column=1, padx=2, pady=2) self.lrning_param['const'].grid(row=1, column=1, padx=2, pady=2) self.lrning_param['acq'].grid(row=2, column=1, sticky='we', padx=2, pady=2) self.lrning_param['local'].grid(row=3, column=1, sticky='we', padx=2, pady=2) self.lrning_param['dist'].grid(row=4, column=1, padx=2, pady=2) self.lrning_param['logis'].grid(row=5, column=1, sticky='we', padx=2, pady=2) self.create_labels(self.info_frame, 0, 0, 0, 'Last Reward', 'Max Reward', 'Initial Points', 'Iterations', 'Dimensions', anchor='e', width=11) self.lrning_info = dict() self.lrning_info['last'] = tk.Label(self.info_frame, text='---', font=small_font, anchor='w', width=11, bd=2, relief='groove') self.lrning_info['max'] = tk.Label(self.info_frame, text='---', font=small_font, anchor='w', width=11, bd=2, relief='groove') self.lrning_info['init'] = tk.Label(self.info_frame, text='0', font=small_font, anchor='w', width=11, bd=2, relief='groove') self.lrning_info['itrs'] = tk.Label(self.info_frame, text='0', font=small_font, anchor='w', width=11, bd=2, relief='groove') self.lrning_info['dim'] = tk.Label(self.info_frame, text='0', font=small_font, anchor='w', width=11, bd=2, relief='groove') self.lrning_info['last'].grid(row=0, column=1, padx=2, pady=2) self.lrning_info['max'].grid(row=1, column=1, padx=2, pady=2) self.lrning_info['init'].grid(row=2, column=1, padx=2, pady=2) self.lrning_info['itrs'].grid(row=3, column=1, padx=2, pady=2) self.lrning_info['dim'].grid(row=4, column=1, padx=2, pady=2) # --------- Dynamic Reconfiguration Frame --------- # self.ctr_vars_frame = tk.LabelFrame(self.dyn_config_frame, height=400, font=title_font, text="Controlled Variables") self.fix_vars_frame = tk.LabelFrame(self.dyn_config_frame, height=400, font=title_font, text="Fixed Variables") self.link_vars_frame = tk.LabelFrame(self.dyn_config_frame, height=400, font=title_font, text="Linked Variables") self.dyn_ctr_frame = tk.Frame(self.dyn_config_frame) self.dyn_ctr_frame.pack(side='top', fill='x') self.ctr_vars_frame.pack(side='left', fill='y', padx=2, pady=2) self.fix_vars_frame.pack(side='left', fill='y', padx=2, pady=2) self.link_vars_frame.pack(side='left', fill='y', padx=2, pady=2) # --------- Dynamic Reconfiguration Control Frame --------- # self.dyn_update_button = tk.Button(self.dyn_ctr_frame, text='Send Values', width=12, font=normal_font, command=self.send_dyn_reconfig_vals) self.dyn_show_button = tk.Button( self.dyn_ctr_frame, text='Show Current', width=12, font=normal_font, command=self.show_current_dyn_reconfig) self.dyn_default_button = tk.Button( self.dyn_ctr_frame, text='Restore Default', width=12, font=normal_font, command=self.restore_dyn_reconfig_default) self.dyn_setmax_button = tk.Button(self.dyn_ctr_frame, text='Set on Max', width=12, font=normal_font, command=self.set_dyn_reconfig_max) self.dyn_update_button.pack(side='left', fill='y', padx=2, pady=2) self.dyn_show_button.pack(side='left', fill='y', padx=2, pady=2) self.dyn_default_button.pack(side='left', fill='y', padx=2, pady=2) self.dyn_setmax_button.pack(side='left', fill='y', padx=2, pady=2) # ---- Controlled Variables Frame ---- # self.create_labels(self.ctr_vars_frame, 0, 0, 1, 'Selected Variables', 'min.', 'set', 'max.') self.selected_ctr_vars = [] self.dyn_ctr_bottom = dict() self.dyn_ctr_bottom['var'] = tk.StringVar(self.ctr_vars_frame) self.dyn_ctr_bottom['opt'] = tk.OptionMenu(self.ctr_vars_frame, self.dyn_ctr_bottom['var'], 'a') self.dyn_ctr_bottom['min'] = tk.Entry(self.ctr_vars_frame, font=small_font, width=5) self.dyn_ctr_bottom['val'] = tk.Entry(self.ctr_vars_frame, font=small_font, width=5) self.dyn_ctr_bottom['max'] = tk.Entry(self.ctr_vars_frame, font=small_font, width=5) self.dyn_ctr_bottom['add'] = tk.Button(self.ctr_vars_frame, font=small_font, text='Add', command=self.add_dyn_ctr_var) # ---- Fixed Variables Frame ---- # self.create_labels(self.fix_vars_frame, 0, 0, 1, 'Selected Variables', 'set') self.selected_fix_vars = [] self.dyn_fix_bottom = dict() self.dyn_fix_bottom['var'] = tk.StringVar(self.fix_vars_frame) self.dyn_fix_bottom['opt'] = tk.OptionMenu(self.fix_vars_frame, self.dyn_fix_bottom['var'], 'a') self.dyn_fix_bottom['val'] = tk.Entry(self.fix_vars_frame, font=small_font, width=5) self.dyn_fix_bottom['add'] = tk.Button(self.fix_vars_frame, font=small_font, text='Add', command=self.add_dyn_fix_var) # ---- Linked Variables Frame ---- # self.create_labels(self.link_vars_frame, 0, 0, 1, 'Selected Variables', 'Linked') self.selected_link_vars = [] self.dyn_link_bottom = dict() self.dyn_link_bottom['var1'] = tk.StringVar(self.link_vars_frame) self.dyn_link_bottom['opt1'] = tk.OptionMenu( self.link_vars_frame, self.dyn_link_bottom['var1'], 'a') self.dyn_link_bottom['var2'] = tk.StringVar(self.link_vars_frame) self.dyn_link_bottom['opt2'] = tk.OptionMenu( self.link_vars_frame, self.dyn_link_bottom['var2'], 'a') self.dyn_link_bottom['add'] = tk.Button(self.link_vars_frame, font=small_font, text='Add', command=self.add_dyn_link_var) self.reset_learning() self.update_bottoms() tk.mainloop() def create_labels(self, parent, row, column, h, *labels, **config): for i in range(len(labels)): label = tk.Label(parent, text=labels[i], font=small_font, **config) if h: label.grid(row=row, column=column + i, padx=2, pady=2) else: label.grid(row=row + i, column=column, padx=2, pady=2) def get_float_entry(self, entry): try: return float(entry.get()) except ValueError: return None def reset_learning(self): self.learning_client.cancel_task self.bo = None # Bayesian Optimization class place holder self.learning_started = self.task_running = self.learning_initialized = False self.iters_running = 0 self.init_pts_num = 0 self.last_reward = None self.pos_error = [] self.rot_error = [] self.toggle_task_ctr() self.toggle_lrning_ctr() self.toggle_dyn_reconfig_ctr() self.update_info() def init_bo(self): if not self.bo: self.bo = BO(self.start_task, self.learning_client.controlled_vars) self.learning_started = True self.toggle_task_ctr() self.toggle_dyn_reconfig_ctr() def update_info(self): self.lrning_info['dim'].config(text=str(len(self.selected_ctr_vars))) if self.bo: self.lrning_info['init'].config(text=str(self.init_pts_num)) if self.bo.space.Y is not None: self.lrning_info['max'].config(text=str(max(self.bo.space.Y))) else: self.lrning_info['max'].config(text=str(max(self.bo.y_init))) if self.learning_initialized: self.lrning_info['itrs'].config( text=str(len(self.bo.space.Y) - self.init_pts_num)) else: self.lrning_info['itrs'].config(text='0') if self.last_reward is not None: self.lrning_info['last'].config(text=str(self.last_reward)) def toggle_task_ctr(self): self.task_ctr['start'][ 'state'] = 'disabled' if self.task_running or self.iters_running else 'normal' self.task_ctr['fail'][ 'state'] = 'normal' if self.task_running else 'disabled' for key in ['depth', 'radius', 'speed', 'circle', 'square']: if self.task_running or self.learning_started: self.task_ctr[key]['state'] = 'disabled' else: self.task_ctr[key]['state'] = 'normal' def toggle_lrning_ctr(self): for key in ['init', 'raninit', 'points']: if (not self.task_running) and len( self.selected_ctr_vars) and not self.learning_initialized: self.lrning_ctr[key]['state'] = 'normal' else: self.lrning_ctr[key]['state'] = 'disabled' for key in ['start', 'iter']: if not (self.task_running or self.iters_running) and self.init_pts_num: self.lrning_ctr[key].config(state='normal') else: self.lrning_ctr[key].config(state='disabled') self.lrning_ctr['cancel'][ 'state'] = 'normal' if self.learning_started else 'disabled' self.lrning_ctr['save']['state'] = 'normal' if self.learning_initialized and \ not (self.task_running or self.iters_running) else 'disabled' for key in ['alpha', 'const', 'acq', 'local', 'dist']: if not (self.task_running or self.iters_running) and self.init_pts_num: self.lrning_param[key].config(state='normal') else: self.lrning_param[key].config(state='disabled') self.lrning_param['logis']['state'] = 'normal' if self.learning_started and \ not (self.task_running or self.iters_running or self.learning_initialized) else 'disabled' def toggle_dyn_reconfig_ctr(self): if self.task_running or self.learning_started: self.dyn_ctr_bottom['add']['state'] = 'disabled' self.dyn_fix_bottom['add']['state'] = 'disabled' self.dyn_link_bottom['add']['state'] = 'disabled' for var, items in (self.selected_ctr_vars + self.selected_fix_vars + self.selected_link_vars): items['del']['state'] = 'disabled' for var, items in self.selected_fix_vars: items['val']['state'] = 'disabled' else: self.dyn_ctr_bottom['add']['state'] = 'normal' self.dyn_fix_bottom['add']['state'] = 'normal' self.dyn_link_bottom['add']['state'] = 'normal' for var, items in (self.selected_ctr_vars + self.selected_fix_vars + self.selected_link_vars): items['del']['state'] = 'normal' for var, items in self.selected_fix_vars: items['val']['state'] = 'normal' if self.task_running or self.iters_running: self.dyn_update_button['state'] = 'disabled' self.dyn_show_button['state'] = 'disabled' self.dyn_default_button['state'] = 'disabled' else: self.dyn_update_button['state'] = 'normal' self.dyn_show_button['state'] = 'normal' self.dyn_default_button['state'] = 'normal' if self.learning_initialized and not (self.task_running or self.iters_running): self.dyn_setmax_button['state'] = 'normal' else: self.dyn_setmax_button['state'] = 'disabled' def start_task(self, **ctr_vars): self.task_running = True self.toggle_task_ctr() self.toggle_dyn_reconfig_ctr() self.toggle_lrning_ctr() if ctr_vars: for var in ctr_vars: self.learning_client.set_dyn_reconfig_var(var, ctr_vars[var]) self.parent.after(200, self.check_new_dyn_vals) reward, self.last_pos_error, self.last_rot_error = self.learning_client.start_task( ) self.last_reward = self.convert_reward(reward) self.task_running = False if self.iters_running: self.iters_running -= 1 if not self.iters_running: self.restore_dyn_reconfig_default( ) # restore to default after finishing iterations. if not self.learning_initialized: self.init_pts_num += 1 self.pos_error.append(self.last_pos_error) self.rot_error.append(self.last_rot_error) self.toggle_task_ctr() self.toggle_dyn_reconfig_ctr() self.toggle_lrning_ctr() self.parent.after( 50, self.update_info ) # Needs to be done after a lag so that self.bo is updated after the current start_task return return self.last_reward def convert_reward(self, reward): if self.learning_initialized and self.enable_sig: reward = 1 / (1 + np.exp(-0.5 * (reward - self.sig_mid)) ) # logistic function return reward def check_new_dyn_vals(self): if self.learning_client.task_started: self.parent.after(100, self.show_current_dyn_reconfig) else: self.parent.after(200, self.check_new_dyn_vals) def start_task_once(self): self.task_thread = threading.Thread(target=self.start_task) self.task_thread.daemon = True self.task_thread.start() def add_last_init_pt(self): self.init_bo() if self.last_reward is not None: point = {'target': [self.last_reward]} for var in self.learning_client.controlled_vars: point[var] = [self.learning_client.current_config[var]] try: self.bo.initialize(point) self.init_pts_num += 1 self.pos_error.append(self.last_pos_error) self.rot_error.append(self.last_rot_error) self.toggle_lrning_ctr() self.update_info() except KeyError: print "CANNOT add the same point twice" def load_init_pts(self): def simulate(init, dim, coef, atype, speed, sig, local): with open(str(dim) + 'd' + str(init) + '.pkl', 'rb') as f: data = pickle.load(f) self.learning_client.controlled_vars = data['controlled_vars'] self.learning_client.fixed_vars = data['fixed_vars'] self.learning_client.linked_vars = data['linked_vars'] print data['controlled_vars'] print data['fixed_vars'] print data['linked_vars'] self.reset_learning() self.learning_client.set_action_settings(atype=atype) self.learning_client.set_action_settings(speed=speed) self.enable_sig = sig for i in range(data['init_pts_num']): vars = dict(zip(data['keys'], data['x'][i])) self.start_task(**vars) self.add_last_init_pt() self.initialize_learning() self.iters_running = 40 self.bo.maximize(init_points=0, n_iter=40, acq='poi', kappa=0.01, xi=0.01, local_acq_opt=local, d=0.05, alpha=1e-4) self.save_results(('square' if atype else 'circle') + str(dim) + 'd' + str(coef) + '-' + str(init) * (2 - sig) + 2 * str(init) * (not local) + '-2' + 's' + str(speed)) def sims(): simulate(1, 4, 1.16, 0, 0.5, True, False) self.task_thread = threading.Thread(target=sims) self.task_thread.daemon = True self.task_thread.start() def add_rand_init_pt(self): self.init_bo() itrs = int(self.lrning_ctr['points'].get()) self.iters_running = itrs self.task_thread = threading.Thread(target=lambda: self.bo.init(itrs)) self.task_thread.daemon = True self.task_thread.start() def initialize_learning(self): if self.init_pts_num: if not self.learning_initialized: self.learning_initialized = True if not self.bo.initialized: self.bo.init(0) self.enable_sig = self.lrning_param['logvar'].get() self.sig_mid = max(self.bo.space.Y) for i in range(len(self.bo.space.Y)): self.bo.space.Y[i] = self.convert_reward( self.bo.space.Y[i]) print self.bo.space.Y def learn(self): self.initialize_learning() if self.learning_initialized: itrs = int(self.lrning_ctr['iter'].get()) alpha = self.get_float_entry(self.lrning_param['alpha']) const = self.get_float_entry(self.lrning_param['const']) d = self.get_float_entry(self.lrning_param['dist']) acq = self.lrning_param['var'].get() local = self.lrning_param['locvar'].get() self.iters_running = itrs self.task_thread = threading.Thread( target=lambda: self.bo.maximize(init_points=0, n_iter=itrs, acq=acq, kappa=const, xi=const, local_acq_opt=local, d=d, alpha=alpha)) self.task_thread.daemon = True self.task_thread.start() def save_results(self, filename='learning_results_'): data = dict() data['x'] = self.bo.space.X data['y'] = self.bo.space.Y data['keys'] = self.bo.space.keys data['pos_error'] = np.vstack(self.pos_error) data['rot_error'] = np.vstack(self.rot_error) data['action_settings'] = self.learning_client.action_settings data['init_pts_num'] = self.init_pts_num data['learning_settings'] = { 'acq': self.lrning_param['var'].get(), 'loc': self.lrning_param['locvar'].get(), 'd': self.get_float_entry(self.lrning_param['dist']), 'alpha': self.get_float_entry(self.lrning_param['alpha']), 'const': self.get_float_entry(self.lrning_param['const']) } data['controlled_vars'] = self.learning_client.controlled_vars data['fixed_vars'] = self.learning_client.fixed_vars data['linked_vars'] = self.learning_client.linked_vars data['sig_mid'] = self.sig_mid # Modified to alleviate file overriding problem (Ramy) modFileName = filename + datetime.datetime.now().strftime( '%Y-%m-%d-%H-%M-%S') + '.pkl' with open(modFileName, 'wb') as f: pickle.dump(data, f) del data shutil.move( os.getcwd() + "/" + modFileName, rospkg.RosPack().get_path('spc_uav_comm') + "/scripts/practical/" + modFileName) print "Results Saved !" # ---------------- Dynamic Reconfigure Functions --------------- # def add_dyn_ctr_var(self): var = self.dyn_ctr_bottom['var'].get() try: min_val = float(self.dyn_ctr_bottom['min'].get()) max_val = float(self.dyn_ctr_bottom['max'].get()) if self.learning_client.add_dyn_ctr_var(var, min_val, max_val): self.learning_client.set_dyn_reconfig_var( var, self.get_float_entry(self.dyn_ctr_bottom['val'])) self.add_dyn_ctr_row(var, min_val, max_val) self.update_info() self.toggle_lrning_ctr() except ValueError: return # TODO: Warn the user for invalid input def add_dyn_fix_var(self): var = self.dyn_fix_bottom['var'].get() if self.learning_client.add_dyn_fix_var(var): self.learning_client.set_dyn_reconfig_var( var, self.get_float_entry(self.dyn_fix_bottom['val'])) self.add_dyn_fix_row(var) def add_dyn_link_var(self): var1 = self.dyn_link_bottom['var1'].get() var2 = self.dyn_link_bottom['var2'].get() if self.learning_client.add_dyn_link_var(var1, var2): self.add_dyn_link_row(var1, var2) def add_dyn_ctr_row(self, var, min_val, max_val): items = dict() items['var'] = tk.Label(self.ctr_vars_frame, font=small_font, text=var, anchor='e') items['min'] = tk.Label(self.ctr_vars_frame, font=small_font, text=min_val) items['val'] = tk.Entry(self.ctr_vars_frame, font=small_font, width=5) items['val'].insert(0, str(self.learning_client.current_config[var])) items['max'] = tk.Label(self.ctr_vars_frame, font=small_font, text=max_val) items['del'] = tk.Button(self.ctr_vars_frame, font=small_font, text='x', bd=0, relief='flat', command=lambda: self.delete_dyn_var(var)) self.selected_ctr_vars.append((var, items)) self.arrange_columns(items, 'var', 'min', 'val', 'max', 'del') self.place_dyn_row(items, len(self.selected_ctr_vars)) self.update_bottoms() def add_dyn_fix_row(self, var): items = dict() items['var'] = tk.Label(self.fix_vars_frame, font=small_font, text=var, anchor='e') items['val'] = tk.Entry(self.fix_vars_frame, font=small_font, width=5) items['val'].insert(0, str(self.learning_client.current_config[var])) items['del'] = tk.Button(self.fix_vars_frame, font=small_font, text='x', bd=0, relief='flat', command=lambda: self.delete_dyn_var(var)) self.selected_fix_vars.append((var, items)) self.arrange_columns(items, 'var', 'val', 'del') self.place_dyn_row(items, len(self.selected_fix_vars)) self.update_bottoms() def add_dyn_link_row(self, var1, var2): items = dict() items['var1'] = tk.Label(self.link_vars_frame, font=small_font, text=var1, anchor='e') items['var2'] = tk.Label(self.link_vars_frame, font=small_font, text='= ' + var2, anchor='e') items['del'] = tk.Button(self.link_vars_frame, font=small_font, text='x', bd=0, relief='flat', command=lambda: self.delete_dyn_var(var1)) self.selected_link_vars.append((var1, items)) self.arrange_columns(items, 'var1', 'var2', 'del') self.place_dyn_row(items, len(self.selected_link_vars)) self.update_bottoms() def arrange_columns(self, items, *columns): for i in range(len(columns)): config = items[columns[i]].grid_info() config['column'] = i items[columns[i]].grid(config) def place_dyn_row(self, items, row): for item in items.values(): config = item.grid_info() config['row'] = row item.grid(config) def delete_dyn_var(self, var): self.learning_client.delete_dyn_reconfig_var(var) self.update_vars_rows(self.selected_ctr_vars) self.update_vars_rows(self.selected_fix_vars) self.update_vars_rows(self.selected_link_vars) self.update_bottoms() self.update_info() self.toggle_lrning_ctr() def update_vars_rows(self, selected_vars): i = 0 while i < len(selected_vars): var, items = selected_vars[i] if var in self.learning_client.get_selectable_vars(): for item in items.values(): item.destroy() selected_vars.pop(i) else: i += 1 for i in range(len(selected_vars)): self.place_dyn_row(selected_vars[i][1], i + 1) def update_bottoms(self): self.place_dyn_ctr_bottom() self.place_dyn_fix_bottom() self.place_dyn_link_bottom() def place_dyn_ctr_bottom(self): row = len(self.selected_ctr_vars) + 1 self.dyn_ctr_bottom['opt'] = self.set_optionmenu( self.ctr_vars_frame, self.dyn_ctr_bottom['opt'], self.dyn_ctr_bottom['var'], self.learning_client.get_selectable_vars()) self.dyn_ctr_bottom['opt'].grid(row=1 + row, column=0, sticky="we", padx=2, pady=2) self.dyn_ctr_bottom['min'].grid(row=1 + row, column=1) self.dyn_ctr_bottom['val'].grid(row=1 + row, column=2) self.dyn_ctr_bottom['max'].grid(row=1 + row, column=3) self.dyn_ctr_bottom['add'].grid(row=1 + row, column=4, sticky="we", padx=2, pady=2) def place_dyn_fix_bottom(self): row = len(self.selected_fix_vars) + 1 self.dyn_fix_bottom['opt'] = self.set_optionmenu( self.fix_vars_frame, self.dyn_fix_bottom['opt'], self.dyn_fix_bottom['var'], self.learning_client.get_selectable_vars()) self.dyn_fix_bottom['opt'].grid(row=1 + row, column=0, sticky="we", padx=2, pady=2) self.dyn_fix_bottom['val'].grid(row=1 + row, column=1) self.dyn_fix_bottom['add'].grid(row=1 + row, column=2, sticky="we", padx=2, pady=2) def place_dyn_link_bottom(self): row = len(self.selected_link_vars) + 1 self.dyn_link_bottom['opt1'] = self.set_optionmenu( self.link_vars_frame, self.dyn_link_bottom['opt1'], self.dyn_link_bottom['var1'], self.learning_client.get_selectable_vars()) self.dyn_link_bottom['opt2'] = self.set_optionmenu( self.link_vars_frame, self.dyn_link_bottom['opt2'], self.dyn_link_bottom['var2'], self.learning_client.get_linkable_vars()) self.dyn_link_bottom['opt1'].grid(row=1 + row, column=0, sticky="we", padx=2, pady=2) self.dyn_link_bottom['opt2'].grid(row=1 + row, column=1, sticky="we", padx=2, pady=2) self.dyn_link_bottom['add'].grid(row=1 + row, column=2, sticky="we", padx=2, pady=2) def set_optionmenu(self, frame, optionmenu, var, options): if options: options.sort() var.set('Select Variable') optionmenu.destroy() optionmenu = tk.OptionMenu(frame, var, *options) optionmenu.config(width=11, font=small_font) else: var.set('Not Available') optionmenu.config(width=11, font=small_font, state='disabled') return optionmenu def show_current_dyn_reconfig(self): self.learning_client.refresh_current_config() for var, items in (self.selected_ctr_vars + self.selected_fix_vars): items['val'].delete(0, 'end') items['val'].insert(0, str(self.learning_client.current_config[var])) def restore_dyn_reconfig_default(self): self.learning_client.default_dyn_reconfig() self.parent.after(10, self.show_current_dyn_reconfig) def set_dyn_reconfig_max(self): if self.learning_initialized: point = self.bo.space.max_point()['max_params'] self.learning_client.send_controlled_vars(**point) self.parent.after(10, self.show_current_dyn_reconfig) def send_dyn_reconfig_vals(self): for var, items in (self.selected_ctr_vars + self.selected_fix_vars): self.learning_client.set_dyn_reconfig_var( var, self.get_float_entry(items['val'])) self.parent.after(10, self.show_current_dyn_reconfig)