def get_init_and_post_gp(fidel_dim, domain_dim, num_data, kernel_scale, dim_bw_power=0.5): """ Generates a GP and data, constructs posterior and returns everything. """ # pylint: disable=too-many-locals kernel_bw_scaling = float(fidel_dim + domain_dim) ** dim_bw_power fidel_kernel = kernel.SEKernel(fidel_dim, 1, (1 + np.random.random(fidel_dim)) * kernel_bw_scaling) domain_kernel = kernel.SEKernel(domain_dim, 1, (0.1 + 0.2*np.random.random(domain_dim)) * kernel_bw_scaling) mean_func_const_val = (2 + np.random.random()) * (1 + np.random.random()) mean_func = lambda x: np.array([mean_func_const_val] * len(x)) noise_var = 0.05 * np.random.random() Z_init = np.zeros((0, fidel_dim)) X_init = np.zeros((0, domain_dim)) Y_init = np.zeros((0)) init_gp = mf_gp.get_mfgp_from_fidel_domain(Z_init, X_init, Y_init, kernel_scale, fidel_kernel, domain_kernel, mean_func, noise_var) # Now construct the data post_gp = deepcopy(init_gp) Z_data = np.random.random((num_data, fidel_dim)) X_data = np.random.random((num_data, domain_dim)) Y_wo_noise = post_gp.draw_mf_samples(1, Z_data, X_data).ravel() Y_data = Y_wo_noise + np.random.normal(0, np.sqrt(noise_var), Y_wo_noise.shape) post_gp.add_mf_data(Z_data, X_data, Y_data) # Put everything in a namespace ret = Namespace(init_gp=init_gp, post_gp=post_gp, Z_data=Z_data, X_data=X_data, Y_data=Y_data, fidel_kernel=fidel_kernel, domain_kernel=domain_kernel, mean_func=mean_func, noise_var=noise_var, kernel_scale=kernel_scale, fidel_dim=fidel_dim, domain_dim=domain_dim, num_data=num_data) return ret
def gen_mf_gp_test_data(): """ Generates test data. """ # pylint: disable=too-many-locals # dataset 1 fzx = lambda z, x: (x**2).sum(axis=1) + (z**2).sum(axis=1) dim_z = 2 dim_x = 3 N = 20 Z_tr, X_tr, Y_tr, ZX_tr, Z_te, X_te, Y_te, ZX_te = _gen_datasets_from_func( fzx, N, dim_z, dim_x) fidel_kernel = kernel.SEKernel(dim=dim_z, scale=1, dim_bandwidths=0.5) domain_kernel = kernel.SEKernel(dim=dim_x, scale=1, dim_bandwidths=0.5) kernel_scale = 2 tune_noise = True dataset_1 = Namespace(Z_tr=Z_tr, X_tr=X_tr, Y_tr=Y_tr, ZX_tr=ZX_tr, Z_te=Z_te, X_te=X_te, Y_te=Y_te, ZX_te=ZX_te, fidel_kernel=fidel_kernel, domain_kernel=domain_kernel, kernel_scale=kernel_scale, tune_noise=tune_noise) # dataset 2 fx = lambda x: -70 * (x + 0.01) * (x - 0.31) * (x + 0.51) * (x - 0.71) * (x - 0.98) fzx = lambda z, x: (np.exp((z - 0.8)**2) * fx(x)).sum(axis=1) N = 100 Z_tr, X_tr, Y_tr, ZX_tr, Z_te, X_te, Y_te, ZX_te = _gen_datasets_from_func(fzx, N, 1, 1) fidel_kernel = kernel.SEKernel(dim=1, scale=1, dim_bandwidths=1.0) domain_kernel = kernel.SEKernel(dim=1, scale=1, dim_bandwidths=0.25) kernel_scale = 2 tune_noise = True dataset_2 = Namespace(Z_tr=Z_tr, X_tr=X_tr, Y_tr=Y_tr, ZX_tr=ZX_tr, Z_te=Z_te, X_te=X_te, Y_te=Y_te, ZX_te=ZX_te, fidel_kernel=fidel_kernel, domain_kernel=domain_kernel, kernel_scale=kernel_scale, tune_noise=tune_noise) # return all datasets return [dataset_1, dataset_2]
def test_effective_length_se(self): """ Tests for the effective length in the SE kernel. """ # pylint: disable=too-many-locals self.report('Tests for the effective length in the SE kernel.') data_1 = np.array([1, 2]) data_2 = np.array([[0, 1, 2], [1, 1, 0.5]]) bws_1 = [0.1, 1] bws_2 = [0.5, 1, 2] res_l2_1 = np.sqrt(104) res_l2_2 = np.array([np.sqrt(2), np.sqrt(5.0625)]) res_l1_1 = 12 res_l1_2 = np.array([2, 3.25]) dim_1 = 2 dim_2 = 3 all_data = [(data_1, bws_1, dim_1, res_l2_1, res_l1_1), (data_2, bws_2, dim_2, res_l2_2, res_l1_2)] for data in all_data: kern = kernel.SEKernel(data[2], 1, data[1]) eff_l1_norms = kern.get_effective_norm(data[0], order=1, is_single=len( data[0].shape) == 1) eff_l2_norms = kern.get_effective_norm(data[0], order=2, is_single=len( data[0].shape) == 1) assert np.linalg.norm(eff_l2_norms - data[3]) < 1e-5 assert np.linalg.norm(eff_l1_norms - data[4]) < 1e-5
def gen_gp_test_data(): """ This function generates a bunch of test data. """ # pylint: disable=too-many-locals # Dataset 1 f1 = lambda x: (x**2).sum(axis=1) N1 = 5 X1_tr = np.array(range(N1)).astype(float).reshape( (N1, 1)) / N1 + 1 / (2 * N1) Y1_tr = f1(X1_tr) X1_te = np.random.random((50, 1)) Y1_te = f1(X1_te) kernel1 = kernel.SEKernel(1, 1, 0.5) # Dataset 2 N2 = 100 D2 = 10 f2 = lambda x: ((x**2) * range(1, D2 + 1) / D2).sum(axis=1) X2_tr = np.random.random((N2, D2)) Y2_tr = f2(X2_tr) X2_te = np.random.random((N2, D2)) Y2_te = f2(X2_te) kernel2 = kernel.SEKernel(D2, 10, 0.2 * np.sqrt(D2)) # Dataset 3 N3 = 200 D3 = 6 f3 = lambda x: ( (x**3 + 2 * x**2 - x + 2) * range(1, D3 + 1) / D3).sum(axis=1) X3_tr = np.random.random((N3, D3)) Y3_tr = f3(X3_tr) X3_te = np.random.random((N3, D3)) Y3_te = f3(X3_te) kernel3 = kernel.SEKernel(D3, 10, 0.2 * np.sqrt(D3)) # Dataset 4 N4 = 400 D4 = 8 f4 = lambda x: ((np.sin(x**2) + 2 * np.cos(x**2) - x + 2) * range( 1, D4 + 1) / D4).sum(axis=1) X4_tr = np.random.random((N4, D4)) Y4_tr = f4(X4_tr) X4_te = np.random.random((N4, D4)) Y4_te = f4(X4_te) kernel4 = kernel.SEKernel(D4, 10, 0.2 * np.sqrt(D4)) # put all datasets into a list. return [(X1_tr, Y1_tr, kernel1, X1_te, Y1_te), (X2_tr, Y2_tr, kernel2, X2_te, Y2_te), (X3_tr, Y3_tr, kernel3, X3_te, Y3_te), (X4_tr, Y4_tr, kernel4, X4_te, Y4_te)]
def test_se_kernel(self): """ Tests for the SE kernel. """ self.report('Tests for the SE kernel.') kern = kernel.SEKernel(self.data_1.shape[1], self.se_scale, self.se_dim_bandwidths) K11 = kern(self.data_1) K22 = kern(self.data_2) K12 = kern(self.data_1, self.data_2) assert np.linalg.norm(self.true_se_vals_11 - K11) < 1e-10 assert np.linalg.norm(self.true_se_vals_22 - K22) < 1e-10 assert np.linalg.norm(self.true_se_vals_12 - K12) < 1e-10
def __init__(self, X, Y, ke_scale, ke_dim_bandwidths, mean_func, noise_var, *args, **kwargs): """ Constructor. ke_scale and ke_dim_bandwidths are the kernel hyper-parameters. ke_dim_bandwidths can be a vector of length dim or a scalar (in which case we will use the same bandwidth for all dimensions). """ X = np.array(X) se_kernel = kernel.SEKernel(dim=X.shape[1], scale=ke_scale, dim_bandwidths=ke_dim_bandwidths) super(SEGP, self).__init__(X, Y, se_kernel, mean_func, noise_var, *args, **kwargs)
def test_comb_kernel(self): """ Tests for the combined kernel. """ self.report('Tests for the Combined kernel.') kern_se = kernel.SEKernel(self.data_1.shape[1], self.se_scale, self.se_dim_bandwidths) kern_upo = kernel.UnscaledPolyKernel(self.data_1.shape[1], self.poly_order, self.unscaled_dim_scalings) kern = kernel.CoordinateProductKernel(self.data_1.shape[0], self.com_scale, [kern_se, kern_upo], [[0, 1], [0, 1]]) K11 = kern(self.data_1) K22 = kern(self.data_2) K12 = kern(self.data_1, self.data_2) assert np.linalg.norm(self.true_comb_11 - K11) < 1e-10 assert np.linalg.norm(self.true_comb_22 - K22) < 1e-10 assert np.linalg.norm(self.true_comb_12 - K12) < 1e-10
def test_compute_std_slack_se(self): """ Tests for the effective length in the SE kernel. """ self.report('Tests for std slack in the SE kernel.') # The data here are in the order [dim, scale, num_data] prob_params = [[2, 1, 10], [3, 2, 0], [10, 6, 13]] n = 5 for prob in prob_params: dim_bws = list(np.random.random(prob[0]) * 0.3 + 0.5) kern = kernel.SEKernel(prob[0], prob[1], dim_bws) X_1 = np.random.random((n, prob[0])) X_2 = np.random.random((n, prob[0])) X_tr = np.random.random((prob[2], prob[0])) _, std_1 = self._compute_post_covar(kern, X_tr, X_1) _, std_2 = self._compute_post_covar(kern, X_tr, X_2) std_diff = np.abs(std_1 - std_2) std_slack = kern.compute_std_slack(X_1, X_2) diff_12_scaled = kern.get_effective_norm(X_1 - X_2, order=2, is_single=False) kern_diff_12_scaled = kern.hyperparams['scale'] * diff_12_scaled assert np.all(std_diff <= std_slack) assert np.all(std_slack <= kern_diff_12_scaled)
def _get_kernel_from_type(cls, kernel_type, kernel_hyperparams): """ Get different euclidean kernels based on kernel_type""" if kernel_type in ['se']: return gp_kernel.SEKernel(kernel_hyperparams['dim'], kernel_hyperparams['scale'], kernel_hyperparams['dim_bandwidths']) elif kernel_type in ['poly']: return gp_kernel.PolyKernel(kernel_hyperparams['dim'], kernel_hyperparams['order'], kernel_hyperparams['scale'], kernel_hyperparams['dim_scalings']) elif kernel_type in ['matern']: return gp_kernel.MaternKernel(kernel_hyperparams['dim'], kernel_hyperparams['nu'], kernel_hyperparams['scale'], kernel_hyperparams['dim_bandwidths']) elif kernel_type in ['esp']: return gp_kernel.ESPKernelSE(kernel_hyperparams['dim'], kernel_hyperparams['scale'], kernel_hyperparams['order'], kernel_hyperparams['dim_bandwidths']) else: raise ValueError('Cannot construct kernel from kernel_type %s.' % (kernel_type))
def get_euclidean_integral_gp_kernel_with_scale(kernel_type, scale, kernel_hyperparams, gp_cts_hps, gp_dscr_hps, use_same_bandwidth, add_gp_groupings=None, esp_kernel_type=None): """ A method to parse the GP kernel from hyper-parameters. Assumes the scale is not part of the hyper-parameters but given as an argument. """ # pylint: disable=too-many-branches # pylint: disable=too-many-statements dim = kernel_hyperparams['dim'] # For the additive ones --------------------- esp_order = None if kernel_type == 'esp': if 'esp_order' in kernel_hyperparams: esp_order = kernel_hyperparams['esp_order'] else: esp_order = gp_dscr_hps[-1] gp_dscr_hps = gp_dscr_hps[:-1] is_additive = False if add_gp_groupings is None: add_gp_groupings = [list(range(dim))] grp_scale = scale elif esp_order is None: is_additive = True grp_scale = 1.0 # Extract features and create a placeholder for the kernel constructors. # Some common functionality for the se, matern and poly kernels. if kernel_type in ['se', 'matern', 'poly']: if use_same_bandwidth: ke_dim_bandwidths = [np.exp(gp_cts_hps[0])] * dim gp_cts_hps = gp_cts_hps[1:] else: ke_dim_bandwidths = np.exp(gp_cts_hps[0:dim]) gp_cts_hps = gp_cts_hps[dim:] elif kernel_type in ['esp']: if use_same_bandwidth: esp_dim_bandwidths = np.exp(gp_cts_hps[0:dim]) gp_cts_hps = gp_cts_hps[dim:] else: esp_dim_bandwidths = np.exp(gp_cts_hps[0:dim * dim]) gp_cts_hps = gp_cts_hps[dim * dim:] # Now iterate through the kernels for the rest of the parameters. if kernel_type == 'se': grp_kernels = [gp_kernel.SEKernel(dim=len(grp), scale=grp_scale, \ dim_bandwidths=get_sublist_from_indices(ke_dim_bandwidths, grp)) for grp in add_gp_groupings] elif kernel_type == 'matern': if 'nu' not in kernel_hyperparams or kernel_hyperparams['nu'] < 0: matern_nu = gp_dscr_hps[0] gp_dscr_hps = gp_dscr_hps[1:] else: matern_nu = kernel_hyperparams['nu'] grp_kernels = [gp_kernel.MaternKernel(dim=len(grp), nu=matern_nu, scale=grp_scale, \ dim_bandwidths=get_sublist_from_indices(ke_dim_bandwidths, grp)) for grp in add_gp_groupings] elif kernel_type == 'poly': if 'order' not in kernel_hyperparams or kernel_hyperparams['order'] < 0: poly_order = gp_dscr_hps[0] gp_dscr_hps = gp_dscr_hps[1:] else: poly_order = kernel_hyperparams['order'] grp_kernels = [gp_kernel.PolyKernel(dim=len(grp), order=poly_order, scale=grp_scale, \ dim_scalings=get_sublist_from_indices(ke_dim_bandwidths, grp)) for grp in add_gp_groupings] elif kernel_type == 'expdecay': exp_decay_offset = np.exp(gp_cts_hps[0]) exp_decay_powers = np.exp(gp_cts_hps[1:dim + 1]) gp_cts_hps = gp_cts_hps[dim + 1:] grp_kernels = [gp_kernel.ExpDecayKernel(dim=len(grp), scale=grp_scale, \ offset=exp_decay_offset, powers=exp_decay_powers) for grp in add_gp_groupings] elif kernel_type == 'esp': if not np.isscalar(esp_order): esp_order = np.asscalar(esp_order) if esp_kernel_type == 'se': grp_kernels = [ gp_kernel.ESPKernelSE(dim=dim, scale=scale, order=int(esp_order), dim_bandwidths=esp_dim_bandwidths) ] elif esp_kernel_type == 'matern': if 'esp_matern_nu' not in kernel_hyperparams: matern_nu = [gp_dscr_hps[0]] * dim gp_dscr_hps = gp_dscr_hps[1:] else: matern_nu = [kernel_hyperparams['esp_matern_nu']] * dim grp_kernels = [ gp_kernel.ESPKernelMatern(dim=dim, nu=matern_nu, scale=scale, order=int(esp_order), dim_bandwidths=esp_dim_bandwidths) ] else: raise Exception('Unknown kernel type %s!' % (kernel_type)) if is_additive: euc_kernel = gp_kernel.AdditiveKernel(scale=scale, kernel_list=grp_kernels, groupings=add_gp_groupings) else: euc_kernel = grp_kernels[0] return euc_kernel, gp_cts_hps, gp_dscr_hps