def test_matern52_encoding(): kernel = Matern52(dimension=2, ARD=True) assert isinstance(kernel.encoding, LogarithmScalarEncoding) assert isinstance(kernel.squared_distance.encoding, LogarithmScalarEncoding) assert kernel.encoding.dimension == 1 assert kernel.squared_distance.encoding.dimension == 2 kernel = Matern52(dimension=2, ARD=True, encoding_type="positive") assert isinstance(kernel.encoding, PositiveScalarEncoding) assert isinstance(kernel.squared_distance.encoding, PositiveScalarEncoding) assert kernel.encoding.dimension == 1 assert kernel.squared_distance.encoding.dimension == 2
def test_gp_regression_with_noise(): def f(x): return anp.sin(x)/x anp.random.seed(7) x_train = anp.arange(-5, 5, 0.2)# [-5, -4.8, -4.6,..., 4.8] x_test = anp.arange(-4.9, 5, 0.2)# [-4.9, -4.7, -4.5,..., 4.9], note that train and test points do not overlap y_train = f(x_train) y_test = f(x_test) std_noise = 0.01 noise_train = anp.random.normal(0.0, std_noise,size=y_train.shape) # to anp.ndarray y_train_np_ndarray = anp.array(y_train) noise_train_np_ndarray = anp.array(noise_train) x_train_np_ndarray = anp.array(x_train) x_test_np_ndarray = anp.array(x_test) model = GaussianProcessRegression(kernel=Matern52(dimension=1)) model.fit(x_train_np_ndarray, y_train_np_ndarray + noise_train_np_ndarray) # Check that the value of the residual noise variance learned by empirical Bayes is in the same order as std_noise^2 noise_variance = model.likelihood.get_noise_variance() numpy.testing.assert_almost_equal(noise_variance, std_noise**2, decimal=4) mu_train, _ = model.predict(x_train_np_ndarray)[0] mu_test, _ = model.predict(x_test_np_ndarray)[0] numpy.testing.assert_almost_equal(mu_train, y_train, decimal=2) numpy.testing.assert_almost_equal(mu_test, y_test, decimal=2)
def test_gp_regression_no_noise(): def f(x): return anp.sin(x)/x x_train = anp.arange(-5, 5, 0.2)# [-5,-4.8,-4.6,...,4.8] x_test = anp.arange(-4.9, 5, 0.2)# [-4.9, -4.7, -4.5,...,4.9], note that train and test points do not overlap y_train = f(x_train) y_test = f(x_test) # to np.ndarray y_train_np_ndarray = anp.array(y_train) x_train_np_ndarray = anp.array(x_train) x_test_np_ndarray = anp.array(x_test) model = GaussianProcessRegression(kernel=Matern52(dimension=1)) model.fit(x_train_np_ndarray, y_train_np_ndarray) # Check that the value of the residual noise variance learned by empirical Bayes is in the same order # as the smallest allowed value (since there is no noise) noise_variance = model.likelihood.get_noise_variance() numpy.testing.assert_almost_equal(noise_variance, NOISE_VARIANCE_LOWER_BOUND) mu_train, var_train = model.predict(x_train_np_ndarray)[0] mu_test, var_test = model.predict(x_test_np_ndarray)[0] numpy.testing.assert_almost_equal(mu_train, y_train, decimal=4) numpy.testing.assert_almost_equal(var_train, [0.0] * len(var_train), decimal=4) # Fewer decimals imposed for the test points numpy.testing.assert_almost_equal(mu_test, y_test, decimal=3)
def test_likelihood_encoding(): mean = ScalarMeanFunction() kernel = Matern52(dimension=1) likelihood = MarginalLikelihood(mean=mean, kernel=kernel) assert isinstance(likelihood.encoding, LogarithmScalarEncoding) likelihood = MarginalLikelihood(mean=mean, kernel=kernel, encoding_type="positive") assert isinstance(likelihood.encoding, PositiveScalarEncoding)
def test_autograd_backprop(n, d, print_results): """ Compare the gradients of the negative_log_posterior computed via the method of finite difference and AutoGrad. The gradients are with respect to the internal parameters. """ X = anp.random.normal(size=(n, d)) y = anp.random.normal(size=(n, 1)) kernel = Matern52(dimension=d) mean = ScalarMeanFunction() initial_noise_variance = None likelihood = MarginalLikelihood( kernel=kernel, mean=mean, initial_noise_variance=initial_noise_variance) likelihood.initialize(force_reinit=True) params = {} params_ordict = likelihood.collect_params().values() for param in params_ordict: params[param.name] = param def negative_log_posterior_forward(param_dict, likelihood, X, y): for k in params.keys(): params[k].set_data(param_dict[k]) return negative_log_posterior(likelihood, X, y) params_custom = {} for key in params.keys(): params_custom[key] = anp.array([anp.random.uniform() + 0.3]) params_custom_copy = _deep_copy_params(params_custom) likelihood_value = negative_log_posterior_forward(params_custom, likelihood, X, y) finite_diff_grad_vec = [] for key in params.keys(): N = negative_log_posterior_forward(params_custom, likelihood, X, y) params_custom_plus = params_custom.copy() params_custom_plus[key] *= (1 + slack_constant) N_plus = negative_log_posterior_forward(params_custom_plus, likelihood, X, y) finite_diff_grad_vec.append( (N_plus - N) / (params_custom[key] * slack_constant)) negative_log_posterior_gradient = grad(negative_log_posterior_forward) grad_vec = negative_log_posterior_gradient(params_custom_copy, likelihood, X, y) autograd_grad_vec = list(grad_vec.values()) if print_results: print('Parameter dictionary:') pprint.pprint(params) print('\nLikelihood value: {}'.format(likelihood_value)) print('\nGradients through finite difference:\n{}'.format( finite_diff_grad_vec)) print('\nGradients through AutoGrad:\n{}\n'.format(autograd_grad_vec)) numpy.testing.assert_almost_equal(finite_diff_grad_vec, autograd_grad_vec, decimal=3)
def test_matern52_unit_scale(): X = anp.array([[1, 0], [0, 1]], dtype=DATA_TYPE) kernel = Matern52(dimension=2) assert kernel.ARD == False kernel.collect_params().initialize() K = kernel(X,X) expected_K = anp.array([[mater52(0.0), mater52(2.0)], [mater52(2.0), mater52(0.0)]]) numpy.testing.assert_almost_equal(expected_K, K)
def test_matern52_wrongshape(): kernel = Matern52(dimension=3) kernel.collect_params().initialize() X1 = anp.random.normal(0.0, 1.0, (5, 2)) try: kmat = kernel(X1, X1) except Exception as e: print(e) try: kdiag = kernel.diagonal(X1) except Exception as e: print(e) X2 = anp.random.normal(0.0, 1.0, (3, 3)) try: kmat = kernel(X2, X1) except Exception as e: print(e)
def test_matern52_ard(): X = anp.array([[2., 1.], [1., 2.], [0., 1.]], dtype=DATA_TYPE) kernel = Matern52(dimension=2, ARD=True) kernel.collect_params().initialize() sqd = kernel.squared_distance assert kernel.ARD == True assert sqd.ARD == True sqd.encoding.set(sqd.inverse_bandwidths_internal, [1. / anp.sqrt(2.), 1.]) K = kernel(X,X) # expected_D is taken from previous test about squared distances expected_D = anp.array([[0., 3. / 2., 2.], [3. / 2., 0., 3. / 2.], [2.0, 3. / 2., 0.]]) expected_K = mater52(expected_D) numpy.testing.assert_almost_equal(expected_K, K)
def test_product_wrongshape(): kernel1 = Matern52(dimension=2) kernel1.collect_params().initialize() kernels = [Matern52(dimension=1), FabolasKernelFunction()] for kernel2 in kernels: kernel2.collect_params().initialize() kernel = ProductKernelFunction(kernel1, kernel2) X1 = anp.random.normal(0.0, 1.0, (5, 4)) try: kmat = kernel(X1, X1) except Exception as e: print(e) try: kdiag = kernel.diagonal(X1) except Exception as e: print(e) X2 = anp.random.normal(0.0, 1.0, (3, 3)) try: kmat = kernel(X2, X1) except Exception as e: print(e) X1 = anp.random.normal(0.0, 1.0, (5, 2)) try: kmat = kernel(X1, X1) except Exception as e: print(e)
def test_gp_regression_2d_with_ard(): def f(x): # Only dependent on the first column of x return anp.sin(x[:,0])/x[:,0] anp.random.seed(7) dimension = 3 # 30 train and test points in R^3 x_train = anp.random.uniform(-5, 5, size=(30,dimension)) x_test = anp.random.uniform(-5, 5, size=(30,dimension)) y_train = f(x_train) y_test = f(x_test) # to np.ndarray y_train_np_ndarray = anp.array(y_train) x_train_np_ndarray = anp.array(x_train) x_test_np_ndarray = anp.array(x_test) model = GaussianProcessRegression(kernel=Matern52(dimension=dimension, ARD=True)) model.fit(x_train_np_ndarray, y_train_np_ndarray) # Check that the value of the residual noise variance learned by empirical Bayes is in the same order as the smallest allowed value (since there is no noise) noise_variance = model.likelihood.get_noise_variance() numpy.testing.assert_almost_equal(noise_variance, NOISE_VARIANCE_LOWER_BOUND) # Check that the bandwidths learned by empirical Bayes reflect the fact that only the first column is useful # In particular, for the useless dimensions indexed by {1,2}, the inverse bandwidths should be close to INVERSE_BANDWIDTHS_LOWER_BOUND # (or conversely, bandwidths should be close to their highest allowed values) sqd = model.likelihood.kernel.squared_distance inverse_bandwidths = sqd.encoding.get(sqd.inverse_bandwidths_internal.data()) assert inverse_bandwidths[0] > inverse_bandwidths[1] and inverse_bandwidths[0] > inverse_bandwidths[2] numpy.testing.assert_almost_equal(inverse_bandwidths[1], INVERSE_BANDWIDTHS_LOWER_BOUND) numpy.testing.assert_almost_equal(inverse_bandwidths[2], INVERSE_BANDWIDTHS_LOWER_BOUND) mu_train, _ = model.predict(x_train_np_ndarray)[0] mu_test, _ = model.predict(x_test_np_ndarray)[0] numpy.testing.assert_almost_equal(mu_train, y_train, decimal=2) # Fewer decimals imposed for the test points numpy.testing.assert_almost_equal(mu_test, y_test, decimal=1)
def fit_predict_ours(data: dict, random_seed: int, optimization_config: OptimizationConfig, test_intermediates: Optional[dict] = None) -> dict: # Create surrogate model num_dims = len(data['ss_limits']) _gpmodel = GaussianProcessRegression( kernel=Matern52(num_dims, ARD=True), mean=ZeroMeanFunction(), # Instead of ScalarMeanFunction optimization_config=optimization_config, random_seed=random_seed, test_intermediates=test_intermediates) model = GaussProcSurrogateModel(data['state'], DEFAULT_METRIC, random_seed, _gpmodel, fit_parameters=True, num_fantasy_samples=20) model_params = model.get_params() print('Hyperparameters: {}'.format(model_params)) # Prediction predictions = model.predict(data['test_inputs'])[0] return {'means': predictions['mean'], 'stddevs': predictions['std']}
def test_incremental_update(): def f(x): return anp.sin(x) / x numpy.random.seed(298424) std_noise = 0.01 # Sample data features_list = [] targets_list = [] num_incr_list = [] for rep in range(10): num_train = anp.random.randint(low=5, high=15) num_incr = anp.random.randint(low=1, high=7) num_incr_list.append(num_incr) sizes = [num_train, num_incr] features = [] targets = [] for sz in sizes: feats = anp.random.uniform(low=-1.0, high=1.0, size=sz).reshape( (-1, 1)) features.append(feats) targs = f(feats) targs += anp.random.normal(0.0, std_noise, size=targs.shape) targets.append(targs) features_list.append(features) targets_list.append(targets) for rep in range(10): model = GaussianProcessRegression(kernel=Matern52(dimension=1)) features = features_list[rep] targets = targets_list[rep] # Posterior state by incremental updating train_features = features[0] train_targets = targets[0] model.fit(train_features, train_targets) noise_variance_1 = model.likelihood.get_noise_variance() state_incr = IncrementalUpdateGPPosteriorState( features=train_features, targets=train_targets, mean=model.likelihood.mean, kernel=model.likelihood.kernel, noise_variance=model.likelihood.get_noise_variance( as_ndarray=True)) num_incr = num_incr_list[rep] for i in range(num_incr): state_incr = state_incr.update(features[1][i].reshape((1, -1)), targets[1][i].reshape((1, -1))) noise_variance_2 = state_incr.noise_variance[0] # Posterior state by direct computation state_comp = GaussProcPosteriorState( features=anp.concatenate(features, axis=0), targets=anp.concatenate(targets, axis=0), mean=model.likelihood.mean, kernel=model.likelihood.kernel, noise_variance=state_incr.noise_variance) # Compare them assert noise_variance_1 == noise_variance_2, "noise_variance_1 = {} != {} = noise_variance_2".format( noise_variance_1, noise_variance_2) chol_fact_incr = state_incr.chol_fact chol_fact_comp = state_comp.chol_fact numpy.testing.assert_almost_equal(chol_fact_incr, chol_fact_comp, decimal=2) pred_mat_incr = state_incr.pred_mat pred_mat_comp = state_comp.pred_mat numpy.testing.assert_almost_equal(pred_mat_incr, pred_mat_comp, decimal=2)