def test_normalizer_inverse_transform(self): np.random.seed(42) normalizer = Normalizer(-2 * np.ones(3), 4 * np.ones(3)) ref_inputs = np.array([-1, 0, 1]) inputs = normalizer.inverse_transform(ref_inputs) true_unnorm = np.array([-2, 1, 4]) np.testing.assert_array_equal(true_unnorm, inputs)
def test_normalizer_fit_transform(self): np.random.seed(42) normalizer = Normalizer(-2 * np.ones(3), 4 * np.ones(3)) inputs = np.random.uniform(-2, 4, 12).reshape(4, 3) ref_inputs = normalizer.fit_transform(inputs) true_norm = np.array([[-0.25091976, 0.90142861, 0.46398788], [0.19731697, -0.68796272, -0.68801096], [-0.88383278, 0.73235229, 0.20223002], [0.41614516, -0.95883101, 0.9398197]]) np.testing.assert_array_almost_equal(true_norm, ref_inputs)
def sample_in_out(input_dim, n_samples): #input ranges lb = np.array(-3 * np.ones(input_dim)) ub = np.array(3 * np.ones(input_dim)) #input normalization XX = np.random.uniform(lb, ub, (n_samples, input_dim)) nor = Normalizer(lb, ub) x = nor.fit_transform(XX) #output values (f) and gradients (df) func = partial(radial, normalizer=nor, generatrix=lambda x: np.cos(x)) f = func(x) df = egrad(func)(x) return x, f, df
def output(x, normalizer, r): return r(np.linalg.norm(normalizer.inverse_transform(x)**2, axis=1)**2) def profile(active, ss, f_out, N=10): return (1 / N) * np.sum(np.array( [f_out(ss.inverse_transform(active)[0]) for i in range(N)]), axis=0) # Generate and normalize inputs X = inputs_uniform(n_samples, input_dim, lb, ub) #X = inputs_gaussian(M, mean, cov) nor = Normalizer(lb, ub) x = nor.fit_transform(X) # Define the output of interest and compute the gradients func = partial(output, normalizer=nor, r=generatrix) f = func(x) df = egrad(func)(x) # Compute the active subspace asub = ActiveSubspaces(dim=1) asub.fit(gradients=df) M_test = 50 X_test = inputs_uniform(M_test, input_dim, lb, ub) nor = Normalizer(lb, ub) x_test = nor.fit_transform(X_test)
def plot_results( optimizer: Optimizer, result_object: OptimizeResult, plot_path: str, parameter_names: Sequence[str], ) -> None: """Plot the current results of the optimizer. Parameters ---------- optimizer : bask.Optimizer Fitted Optimizer object. result_object : scipy.optimize.OptimizeResult Result object containing the data and the last fitted model. plot_path : str Path to the directory to which the plots should be saved. parameter_names : Sequence of str Names of the parameters to use for plotting. """ logger = logging.getLogger(LOGGER) if optimizer.space.n_dims == 1: logger.warning("Plotting for only 1 parameter is not supported yet.") return plt.rcdefaults() logger.debug("Starting to compute the next partial dependence plot.") plt.style.use("dark_background") fig, ax = plt.subplots( nrows=optimizer.space.n_dims, ncols=optimizer.space.n_dims, figsize=(3 * optimizer.space.n_dims, 3 * optimizer.space.n_dims), ) fig.patch.set_facecolor("#36393f") for i in range(optimizer.space.n_dims): for j in range(optimizer.space.n_dims): ax[i, j].set_facecolor("#36393f") timestr = time.strftime("%Y%m%d-%H%M%S") plot_objective( result_object, dimensions=parameter_names, plot_standard_deviation=False, fig=fig, ax=ax, ) plotpath = pathlib.Path(plot_path) plotpath.mkdir(parents=True, exist_ok=True) full_plotpath = plotpath / f"{timestr}-{len(optimizer.Xi)}-partial_dependence.png" plt.savefig( full_plotpath, dpi=300, facecolor="#36393f", ) logger.info(f"Saving a partial dependence plot to {full_plotpath}.") plt.close(fig) logger.debug("Starting to compute the next standard deviation plot.") plt.style.use("dark_background") standard_deviation_figure, standard_deviation_axes = plt.subplots( nrows=optimizer.space.n_dims, ncols=optimizer.space.n_dims, figsize=(3 * optimizer.space.n_dims, 3 * optimizer.space.n_dims), ) standard_deviation_figure.patch.set_facecolor("#36393f") for i in range(optimizer.space.n_dims): for j in range(optimizer.space.n_dims): standard_deviation_axes[i, j].set_facecolor("#36393f") timestr = time.strftime("%Y%m%d-%H%M%S") plot_objective( result_object, dimensions=parameter_names, plot_standard_deviation=True, fig=standard_deviation_figure, ax=standard_deviation_axes, ) standard_deviation_full_plotpath = ( plotpath / f"{timestr}-{len(optimizer.Xi)}-standard_deviation.png" ) plt.savefig( standard_deviation_full_plotpath, dpi=300, facecolor="#36393f", ) logger.info( f"Saving a standard deviation plot to {standard_deviation_full_plotpath}." ) plt.close(standard_deviation_figure) plt.rcdefaults() number_of_random_active_subspace_samples = 10000 - len(result_object.x_iters) number_of_input_dimensions = optimizer.space.n_dims active_subspace_samples_gradient = [] active_subspace_samples_y = [] # Uniformly distributed inputs lb = 0 * np.ones(number_of_input_dimensions) # lower bounds ub = 1 * np.ones(number_of_input_dimensions) # upper bounds active_subspace_samples_x_raw = inputs_uniform( number_of_random_active_subspace_samples, lb, ub ) active_subspace_samples_x_raw = np.append( active_subspace_samples_x_raw, optimizer.space.transform(np.asarray(result_object.x_iters)), axis=0, ) active_subspaces_input_normalizer = Normalizer(lb, ub) active_subspace_samples_normalized_x = active_subspaces_input_normalizer.fit_transform( active_subspace_samples_x_raw ) if optimizer.gp.kernel.k1.k2.nu >= 1.5: for x_row in active_subspace_samples_x_raw: y_row, grad_row = optimizer.gp.predict( np.reshape(x_row, (1, -1)), return_mean_grad=True ) if active_subspace_samples_gradient == []: active_subspace_samples_gradient = grad_row active_subspace_samples_y = y_row else: active_subspace_samples_gradient = np.vstack( [active_subspace_samples_gradient, grad_row] ) active_subspace_samples_y = np.vstack( [active_subspace_samples_y, y_row] ) active_subspaces_object = ActiveSubspaces(dim=2, method="exact", n_boot=1000) active_subspaces_object.fit(gradients=active_subspace_samples_gradient) else: for x_row in active_subspace_samples_x_raw: y_row = optimizer.gp.predict(np.reshape(x_row, (1, -1))) if active_subspace_samples_y == []: active_subspace_samples_y = y_row else: active_subspace_samples_y = np.vstack( [active_subspace_samples_y, y_row] ) active_subspaces_object = ActiveSubspaces(dim=2, method="local", n_boot=1000) active_subspaces_object.fit( inputs=active_subspace_samples_normalized_x, outputs=active_subspace_samples_y, ) plt.style.use("default") timestr = time.strftime("%Y%m%d-%H%M%S") active_subspace_figure = plt.figure( constrained_layout=True, figsize=(20, 18 + active_subspaces_object.evects.shape[1] * 6), ) active_subspace_subfigures = active_subspace_figure.subfigures( nrows=3, ncols=1, wspace=0.07, height_ratios=[1, active_subspaces_object.evects.shape[1], 3], ) #active_subspace_figure.tight_layout() #active_subspace_figure.patch.set_facecolor("#36393f") active_subspace_eigenvalues_axes = active_subspace_subfigures[0].subplots(1, 1) active_subspace_eigenvalues_axes = plot_activesubspace_eigenvalues( active_subspaces_object, active_subspace_figure=active_subspace_figure, active_subspace_eigenvalues_axes=active_subspace_eigenvalues_axes, #figsize=(6, 4), ) logger.debug( f"Active subspace eigenvalues: {np.squeeze(active_subspaces_object.evals)}" ) active_subspace_eigenvectors_axes = active_subspace_subfigures[1].subplots( active_subspaces_object.evects.shape[1], 1 ) active_subspace_eigenvectors_axes = plot_activesubspace_eigenvectors( active_subspaces_object, active_subspace_figure=active_subspace_figure, active_subspace_eigenvectors_axes=active_subspace_eigenvectors_axes, #n_evects=number_of_input_dimensions, n_evects=active_subspaces_object.evects.shape[1], labels=parameter_names, #figsize=(6, 4), ) activity_scores_table = PrettyTable() activity_scores_table.add_column("Parameter", parameter_names) activity_scores_table.add_column( "Activity score", np.squeeze(active_subspaces_object.activity_scores) ) activity_scores_table.sortby = "Activity score" activity_scores_table.reversesort = True logger.debug(f"Active subspace activity scores:\n{activity_scores_table}") #logger.debug(f"Active subspace activity scores: {np.squeeze(active_subspaces_object.activity_scores)}") active_subspace_sufficient_summary_axes = active_subspace_subfigures[2].subplots( 1, 1 ) active_subspace_sufficient_summary_axes = plot_activesubspace_sufficient_summary( active_subspaces_object, active_subspace_samples_normalized_x, active_subspace_samples_y, result_object, active_subspace_figure=active_subspace_figure, active_subspace_sufficient_summary_axes=active_subspace_sufficient_summary_axes, #figsize=(6, 4), ) active_subspace_figure.suptitle("Active subspace") #plt.show() active_subspace_full_plotpath = ( plotpath / f"{timestr}-{len(optimizer.Xi)}-active_subspace.png" ) active_subspace_figure.savefig( active_subspace_full_plotpath, dpi=300, facecolor="#36393f", ) logger.info(f"Saving an active subspace plot to {active_subspace_full_plotpath}.") plt.close(active_subspace_figure) plt.rcdefaults()
def test_normalizer_init_ub(self): normalizer = Normalizer(np.arange(5), np.arange(2, 7)) np.testing.assert_array_equal(normalizer.ub, np.arange(2, 7))