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=1): X_suggestions = np.zeros((n_suggestions, self.dim)) # Initialize the design if it is the first call if self.X_init is None: self._init(n_suggestions) if self.init_batches: print('REUSING INITIALIZATION:') for X, Y in self.init_batches: print('Re-observing a batch!') self.observe(X, Y) self.X_init = [] # Pick from the experimental design n_init = min(len(self.X_init), n_suggestions) if n_init > 0: X_suggestions[:n_init] = self.X_init[:n_init] self.X_init = self.X_init[n_init:] self.is_init_batch = True else: self.is_init_batch = False # Pick from the model based on the already received observations n_suggest = n_suggestions - n_init if n_suggest > 0: X_cand = self._suggest(n_suggest) X_suggestions[-n_suggest:] = X_cand # Map into the continuous space with the api bounds and unwarp the suggestions X_min_bound = 0.0 X_max_bound = 1.0 X_suggestions_min = X_suggestions.min() X_suggestions_max = X_suggestions.max() if X_suggestions_min < X_min_bound or X_suggestions_max > X_max_bound: print( f'Some suggestions are out of the bounds in suggest(): {X_suggestions_min}, {X_suggestions_max}' ) print('Clipping everything...') X_suggestions = np.clip(X_suggestions, X_min_bound, X_max_bound) X_suggestions = from_unit_cube(X_suggestions, self.lb, self.ub) X_suggestions = self.space_x.unwarp(X_suggestions) return X_suggestions
def restart(self): self.turbo._restart() self.turbo._X = np.zeros((0, self.turbo.dim)) self.turbo._fX = np.zeros((0, 1)) X_init = latin_hypercube(self.turbo.n_init, self.dim) self.X_init = from_unit_cube(X_init, self.lb, self.ub)