예제 #1
0
 def _init(self, n_suggestions):
   self.batch_size = n_suggestions
   n_init_points = self.config['n_init_points']
   if n_init_points == -1:
     # Special value to use the default 2*D+1 number.
     n_init_points = 2 * self.dim + 1
   self.n_init = max(self.batch_size, n_init_points)
   exp_design = self.config['experimental_design']
   if exp_design == 'latin_hypercube':
     X_init = latin_hypercube(self.n_init, self.dim)
   elif exp_design == 'halton':
     halton_sampler = sampler.Sampler(method='halton', api_config=self.api_config, n_points=self.n_init)
     X_init = halton_sampler.generate(random_state=self.sampler_seed)
     X_init = self.space_x.warp(X_init)
     X_init = to_unit_cube(X_init, self.lb, self.ub)
   elif exp_design == 'lhs_classic_ratio':
     lhs_sampler = sampler.Sampler(
       method='lhs',
       api_config=self.api_config,
       n_points=self.n_init,
       generator_kwargs={'lhs_type': 'classic', 'criterion': 'ratio'})
     X_init = lhs_sampler.generate(random_state=self.sampler_seed)
     X_init = self.space_x.warp(X_init)
     X_init = to_unit_cube(X_init, self.lb, self.ub)
   else:
     raise ValueError(f'Unknown experimental design: {exp_design}.')
   self.X_init = X_init
   if DEBUG:
     print(f'Initialized the method with {self.n_init} points by {exp_design}:')
     print(X_init)
예제 #2
0
    def turbo_suggest(self, n_suggestions=1):
        if self.turbo_batch_size is None:  # Remember the batch size on the first call to suggest
            self.turbo_batch_size = n_suggestions
            self.turbo.batch_size = n_suggestions
            self.turbo.failtol = np.ceil(np.max([4.0 / self.turbo_batch_size, self.dim / self.turbo_batch_size]))
            self.turbo.n_init = max([self.turbo.n_init, self.turbo_batch_size])
            self.restart()

        X_next = np.zeros((n_suggestions, self.dim))

        # Pick from the initial points
        n_init = min(len(self.X_init), n_suggestions)
        if n_init > 0:
            X_next[:n_init] = deepcopy(self.X_init[:n_init, :])
            self.X_init = self.X_init[n_init:, :]  # Remove these pending points

        # Get remaining points from TuRBO
        n_adapt = n_suggestions - n_init
        if n_adapt > 0:
            if len(self.turbo._X) > 0:  # Use random points if we can't fit a GP
                X = to_unit_cube(deepcopy(self.turbo._X), self.lb, self.ub)
                fX = copula_standardize(deepcopy(self.turbo._fX).ravel())  # Use Copula
                X_cand, y_cand, _ = self.turbo._create_candidates(
                    X, fX, length=self.turbo.length, n_training_steps=100, hypers={}
                )
                X_next[-n_adapt:, :] = self.turbo._select_candidates(X_cand, y_cand)[:n_adapt, :]
                X_next[-n_adapt:, :] = from_unit_cube(X_next[-n_adapt:, :], self.lb, self.ub)
        # Unwarp the suggestions
        suggestions = self.space_x.unwarp(X_next)
        suggestions[-1] = self.meta_init[2]
        return suggestions
    def _suggest(self, n_suggestions):
        X = to_unit_cube(deepcopy(self.X), self.lb, self.ub)
        y = deepcopy(self.y)
        if not self.node:
            self.split_used = 0
            self.node = self._build_tree(X, y)
            used_budget = len(y)
            idx = (self._get_in_node_region(X, self.node) == 1)
            X = X[idx]
            y = y[idx]
            print(f'Rebuilt the tree of depth {len(self.node)}')
            model_config = self.config['turbo']
            #print('CONFIG!!!!!', model_config)
            self.turbo = Turbo1(
                f=None,
                lb=self.bounds[:, 0],
                ub=self.bounds[:, 1],
                n_init=len(X),
                max_evals=np.iinfo(np.int32).max,
                batch_size=self.batch_size,
                verbose=False,
                use_cylinder=model_config['use_cylinder'],
                budget=model_config['budget'],
                use_decay=model_config['use_decay'],
                decay_threshold=model_config['decay_threshold'],
                decay_alpha=model_config['decay_alpha'],
                use_pull=model_config['use_pull'],
                use_lcb=model_config['use_lcb'],
                kappa=model_config['kappa'],
                length_min=model_config['length_min'],
                length_max=model_config['length_max'],
                length_init=model_config['length_init'],
                length_multiplier=model_config['length_multiplier'],
                used_budget=used_budget)
            self.turbo._X = np.array(X, copy=True)
            self.turbo._fX = np.array(y, copy=True)
            self.turbo.X = np.array(X, copy=True)
            self.turbo.fX = np.array(y, copy=True)
            print('Initialized TURBO')
        else:
            idx = (self._get_in_node_region(X, self.node) == 1)
            X = X[idx]
            y = y[idx]
        self.split_used += 1

        length_init_method = self.config['turbo_length_init_method']
        if length_init_method == 'default':
            length = self.turbo.length
        elif length_init_method == 'length_init':
            length = self.turbo.length_init
        elif length_init_method == 'length_max':
            length = self.turbo.length_max
        elif length_init_method == 'infinity':
            length = np.iinfo(np.int32).max
        else:
            raise ValueError(
                f'Unknown init method for turbo\'s length: {length_init_method}.'
            )
        length_reties = self.config['turbo_length_retries']
        for retry in range(length_reties):
            XX = X
            yy = copula_standardize(y.ravel())
            X_cand, y_cand, _ = self.turbo._create_candidates(
                XX,
                yy,
                length=length,
                n_training_steps=self.config['turbo_training_steps'],
                hypers={})
            in_region_predictions = self._get_in_node_region(X_cand, self.node)
            in_region_idx = in_region_predictions == 1
            if DEBUG:
                print(
                    f'In region: {np.sum(in_region_idx)} out of {len(X_cand)}')
            if np.sum(in_region_idx) >= n_suggestions:
                X_cand, y_cand = X_cand[in_region_idx], y_cand[in_region_idx]
                self.turbo.f_var = self.turbo.f_var[in_region_idx]
                if DEBUG:
                    print('Found a suitable set of candidates.')
                break
            else:
                length /= 2
                if DEBUG:
                    print(f'Retrying {retry + 1}/{length_reties} time')

        X_cand = self.turbo._select_candidates(X_cand,
                                               y_cand)[:n_suggestions, :]
        if DEBUG:
            if X.shape[1] == 3:
                tx = np.arange(0.0, 1.0 + 1e-6, 0.1)
                ty = np.arange(0.0, 1.0 + 1e-6, 0.1)
                tz = np.arange(0.0, 1.0 + 1e-6, 0.1)
                p = np.array([[x, y, z] for x in tx for y in ty for z in tz])
            elif X.shape[1] == 2:
                tx = np.arange(0.0, 1.0 + 1e-6, 0.1)
                ty = np.arange(0.0, 1.0 + 1e-6, 0.1)
                p = np.array([[x, y] for x in tx for y in ty])
            else:
                raise ValueError(
                    'The points for the DEBUG should either be 2D or 3D.')
            p_predictions = self._get_in_node_region(p, self.node)
            in_turbo_bounds = np.logical_and(
                np.all(self.turbo.cand_lb <= p, axis=1),
                np.all(p <= self.turbo.cand_ub, axis=1))
            pcds = []
            _add_pcd(pcds, p[p_predictions == 0], (1.0, 0.0, 0.0))
            _add_pcd(
                pcds, p[np.logical_and(p_predictions == 1,
                                       np.logical_not(in_turbo_bounds))],
                (0.0, 1.0, 0.0))
            _add_pcd(pcds, p[np.logical_and(p_predictions == 1,
                                            in_turbo_bounds)], (0.0, 0.5, 0.0))
            _add_pcd(pcds, X_cand, (0.0, 0.0, 0.0))
            open3d.visualization.draw_geometries(pcds)
        return X_cand