def __init__(self, input_dim, feature_dim=None, mean_fn=None, embed_fn=None): super(DMEGP, self).__init__() # store params self.input_dim = input_dim self.feature_dim = feature_dim # define mean function and embedding function self.mean_fn = mean_fn self.embed_fn = embed_fn # define kernel function if embed_fn == None: feature_dim = input_dim kernel = RBF(feature_dim, lengthscale=torch.ones(feature_dim)) else: kernel = RBF(feature_dim, lengthscale=torch.ones(feature_dim)) kernel = Warping(kernel, iwarping_fn=self.embed_fn) if mean_fn != None: self.mean_fn = Warping_mean(self.mean_fn, self.embed_fn) # define gaussian process regression model self.gp_model = GPRegression( X=torch.ones(1, feature_dim), # dummy y=None, kernel=kernel, mean_function=self.mean_fn)
def __init__(self, X_curr, u_curr, X_next, option='GP', inducing_size=100, name='GP_DYNAMICS'): """ :param X_curr: 2 dim tensor array, state at the current time stamp, H by n :param u_curr: 2 dim tensor array, control signal at the current time stamp, H by m :param X_next: 2 dim tensor array, state at the next time stamp, H by n :param option: use full GP or sparse GP :param inducing_size: the number of inducing points if using sparse GP :param name: """ super(GP_DYNAMICS).__init__(name) if option not in ['SSGP', 'GP']: raise ValueError('undefined regression option for gp model!') assert(X_curr.dim() == 2 and u_curr.dim() == 2 and X_next.dim() == 2), "all data inputs can only have 2 dimensions! X_curr: {}, u_curr: {}, X_next: {}".format(X_curr.dim(), u_curr.dim(), X_next.dim()) assert(X_curr.size()[1] == u_curr.size()[1] and u_curr.size()[1] == X_next.size()[1]), "all data inputs need to have the same length! X_curr: {}, " \ "u_curr: {}, X_next: {}".format(X_curr.size(), u_curr.size(), X_next.size()) self.X_hat = torch.cat((X_curr, u_curr)) self.dX = X_next - X_curr self.GP_dyn = [] if option == 'SSGP': for i in range(self.dX.size()[1]): kernel = RBF(input_dim=self.X_hat.size()[1], lengthscale=torch.ones(self.X_hat.size()[1]) * 10., variance=torch.tensor(5.0),name="GPs_dim" + str(i) + "_RBF") range_lis = range(0, self.X_hat.size()[0]) random.shuffle(range_lis) Xu = self.X_hat[range_lis[0:inducing_size], :] # need to set the name for different model, otherwise pyro will clear the parameter storage ssgpmodel = SparseGPRegression(self.X_hat, self.dX[:, i], kernel, Xu, name="SSGPs_model_dim" + str(i), jitter=1e-5) self.GP_dyn.append(ssgpmodel) else: for i in range(self.dX.size()[1]): kernel = RBF(input_dim=self.X_hat.size()[1], lengthscale=torch.ones(self.X_hat.size()[1]) * 10., variance=torch.tensor(5.0), name="GPs_dim" + str(i) + "_RBF") gpmodel = GPRegression(self.X_hat, self.dX[:, i], kernel, name="GPs_model_dim" + str(i), jitter=1e-5) self.GP_dyn.append(gpmodel) self.option = option print("for the dynamics model, input dim {} and output dim {}".format(self.X_hat.size()[1], self.dX.size()[1])) self.Kff_inv = torch.zeros((self.dX.size()[1], self.X_hat.size()[0], self.X_hat.size()[0])) self.K_var = torch.zeros(self.dX.size()[1], 1) self.Beta = torch.zeros((self.dX.size()[1], self.X_hat.size()[0])) self.lengthscale = torch.zeros((self.dX.size()[1], self.X_hat.size()[1])) self.noise = torch.zeros((self.dX.size()[1], 1)) if self.option == 'SSGP': self.Xu = torch.zeros((self.dX.size()[1], inducing_size))
def test_inference_deepGP(): gp1 = GPRegression( X, None, RBF(input_dim=3, variance=torch.tensor(3.), lengthscale=torch.tensor(2.))) Z, _ = gp1.model() gp2 = VariationalSparseGP(Z, y2D, Matern32(input_dim=3), Z.clone(), Gaussian(torch.tensor(1e-6))) class DeepGP(torch.nn.Module): def __init__(self, gp1, gp2): super(DeepGP, self).__init__() self.gp1 = gp1 self.gp2 = gp2 def model(self): Z, _ = self.gp1.model() self.gp2.set_data(Z, y2D) self.gp2.model() def guide(self): self.gp1.guide() self.gp2.guide() deepgp = DeepGP(gp1, gp2) train(deepgp, num_steps=1)
def define_new_GP(self): # define kernel function if self.embed_fn == None: feature_dim = self.input_dim kernel = RBF(feature_dim, lengthscale=torch.ones(feature_dim)) else: feature_dim = self.feature_dim embed_fn = copy.deepcopy(self.embed_fn) kernel = RBF(feature_dim, lengthscale=torch.ones(feature_dim)) kernel = Warping(kernel, iwarping_fn=embed_fn) if self.mean_fn != None: mean_fn = copy.deepcopy(self.mean_fn) # define gaussian process regression model gp_model = GPRegression( X=torch.ones(1, feature_dim), # dummy y=None, kernel=kernel, mean_function=mean_fn) return gp_model
def test_inference(model_class, X, y, kernel, likelihood): # skip variational GP models because variance/lengthscale highly # depend on variational parameters if model_class is VariationalGP or model_class is VariationalSparseGP: return elif model_class is GPRegression: gp = model_class(X, y, RBF(input_dim=3), likelihood) else: # model_class is SparseGPRegression gp = model_class(X, y, RBF(input_dim=3), X, likelihood) # fix inducing points because variance/lengthscale highly depend on it gp.Xu.requires_grad_(False) generator = dist.MultivariateNormal(torch.zeros(X.shape[0]), kernel(X)) target_y = generator(sample_shape=torch.Size([1000])).detach() gp.set_data(X, target_y) train(gp) y_cov = gp.kernel(X) target_y_cov = kernel(X) assert_equal(y_cov, target_y_cov, prec=0.1)
def test_inference_whiten_vsgp(): N = 1000 X = dist.Uniform(torch.zeros(N), torch.ones(N)*5).sample() y = 0.5 * torch.sin(3*X) + dist.Normal(torch.zeros(N), torch.ones(N)*0.5).sample() kernel = RBF(input_dim=1) Xu = torch.arange(0., 5.5, 0.5) vsgp = VariationalSparseGP(X, y, kernel, Xu, Gaussian(), whiten=True) train(vsgp) Xnew = torch.arange(0., 5.05, 0.05) loc, var = vsgp(Xnew, full_cov=False) target = 0.5 * torch.sin(3*Xnew) assert_equal((loc - target).abs().mean().item(), 0, prec=0.07)
def test_inference_sgpr(): N = 1000 X = dist.Uniform(torch.zeros(N), torch.ones(N)*5).sample() y = 0.5 * torch.sin(3*X) + dist.Normal(torch.zeros(N), torch.ones(N)*0.5).sample() kernel = RBF(input_dim=1) Xu = torch.arange(0., 5.5, 0.5) sgpr = SparseGPRegression(X, y, kernel, Xu) train(sgpr) Xnew = torch.arange(0., 5.05, 0.05) loc, var = sgpr(Xnew, full_cov=False) target = 0.5 * torch.sin(3*Xnew) assert_equal((loc - target).abs().mean().item(), 0, prec=0.07)
def test_inference_vsgp(): N = 1000 X = dist.Uniform(torch.zeros(N), torch.ones(N) * 5).sample() y = 0.5 * torch.sin(3 * X) + dist.Normal(torch.zeros(N), torch.ones(N) * 0.5).sample() kernel = RBF(input_dim=1) Xu = torch.arange(0, 5.5, 0.5) vsgp = VariationalSparseGP(X, y, kernel, Xu, Gaussian()) vsgp.optimize(optim.Adam({"lr": 0.03}), num_steps=1000) Xnew = torch.arange(0, 5.05, 0.05) loc, var = vsgp(Xnew, full_cov=False) target = 0.5 * torch.sin(3 * Xnew) assert_equal((loc - target).abs().mean().item(), 0, prec=0.06)
def _kernel(): return RBF(input_dim=3, variance=torch.tensor(3.), lengthscale=torch.tensor(2.))
K_sum=27), T(Cosine(3, variance, lengthscale), X=X, Z=Z, K_sum=-0.193233), T(Linear(3, variance), X=X, Z=Z, K_sum=291), T(Exponential(3, variance, lengthscale), X=X, Z=Z, K_sum=2.685679), T(Matern32(3, variance, lengthscale), X=X, Z=Z, K_sum=3.229314), T(Matern52(3, variance, lengthscale), X=X, Z=Z, K_sum=3.391847), T(Periodic(3, variance, lengthscale, period=torch.ones(1)), X=X, Z=Z, K_sum=18), T(Polynomial(3, variance, degree=2), X=X, Z=Z, K_sum=7017), T(RationalQuadratic(3, variance, lengthscale, scale_mixture=torch.ones(1)), X=X, Z=Z, K_sum=5.684670), T(RBF(3, variance, lengthscale), X=X, Z=Z, K_sum=3.681117), T(WhiteNoise(3, variance, lengthscale), X=X, Z=Z, K_sum=0), T(WhiteNoise(3, variance, lengthscale), X=X, Z=None, K_sum=6), T( Coregionalize(3, components=torch.eye(3, 3)), X=torch.tensor([[1., 0., 0.], [0.5, 0., 0.5]]), Z=torch.tensor([[1., 0., 0.], [0., 1., 0.]]), K_sum=2.25, ), T( Coregionalize(3, rank=2), X=torch.tensor([[1., 0., 0.], [0.5, 0., 0.5]]), Z=torch.tensor([[1., 0., 0.], [0., 1., 0.]]), K_sum=None, # kernel is randomly initialized ), T(
from collections import namedtuple import pytest import torch from pyro.contrib.gp.kernels import RBF from pyro.contrib.gp.likelihoods import Binary, MultiClass, Poisson from pyro.contrib.gp.models import VariationalGP, VariationalSparseGP T = namedtuple("TestGPLikelihood", ["model_class", "X", "y", "kernel", "likelihood"]) X = torch.tensor([[1.0, 5.0, 3.0], [4.0, 3.0, 7.0], [3.0, 4.0, 6.0]]) kernel = RBF(input_dim=3, variance=torch.tensor(1.), lengthscale=torch.tensor(3.)) noise = torch.tensor(1e-6) y_binary1D = torch.tensor([0.0, 1.0, 0.0]) y_binary2D = torch.tensor([[0.0, 1.0, 1.0], [1.0, 0.0, 1.0]]) binary_likelihood = Binary() y_count1D = torch.tensor([0.0, 1.0, 4.0]) y_count2D = torch.tensor([[5.0, 9.0, 3.0], [4.0, 0.0, 1.0]]) poisson_likelihood = Poisson() y_multiclass1D = torch.tensor([2.0, 0.0, 1.0]) y_multiclass2D = torch.tensor([[2.0, 1.0, 1.0], [0.0, 2.0, 1.0]]) multiclass_likelihood = MultiClass(num_classes=3) TEST_CASES = [ T(VariationalGP, X, y_binary1D, kernel, binary_likelihood), T(VariationalGP, X, y_binary2D, kernel, binary_likelihood),
def __init__(self, X_s, y_s, X_o, y_o, option='GP', inducing_size=100, name='GP_ADF_RTSS'): """ :param X_s: training inputs for the state transition model N by D tensor :param y_s: training outputs for the state transition model N by E tensor :param X_o: training inputs for the observation model N by E tensor :param y_o: training outputs for the observation model N by F tensor :param state_dim: dimension for the state, D :param observation_dim: dimension for the output, E :param transition_kernel: kernel function for the :param observation_kernel: :param options: """ super(GP_ADF_RTSS, self).__init__(name) if option not in ['SSGP', 'GP']: raise ValueError('undefined regression option for gp model!') assert(X_s.dim() == 2 and y_s.dim() == 2 and X_o.dim() == 2 and y_o.dim() == 2), "all data inputs can only have 2 dimensions" # # use RBF kernel for state transition model and observation model # self.state_transition_kernel = RBF(input_dim=state_dim, lengthscale=torch.ones(state_dim) * 0.1) # self.observation_kernel = RBF(input_dim=observation_dim, lengthscale=torch.ones(observation_dim) * 0.1) self.X_s = X_s self.y_s = y_s self.X_o = X_o self.y_o = y_o # print(X_s.dtype) # print(y_s.dtype) # print(X_o.dtype) # print(y_o.dtype) # choose the model type and initialize based on the option self.state_transition_model_list = [] self.observation_model_list = [] if option == 'SSGP': for i in range(self.y_s.size()[1]): kernel = RBF(input_dim=self.X_s.size()[1], lengthscale=torch.ones(self.X_s.size()[1]) * 10., variance=torch.tensor(5.0),name="GPs_dim" + str(i) + "_RBF") range_lis = range(0, X_s.size()[0]) random.shuffle(range_lis) Xu = X_s[range_lis[0:inducing_size], :] # need to set the name for different model, otherwise pyro will clear the parameter storage ssgpmodel = SparseGPRegression(X_s, y_s[:, i], kernel, Xu, name="SSGPs_model_dim" + str(i), jitter=1e-5) self.state_transition_model_list.append(ssgpmodel) for i in range(self.y_o.size()[1]): kernel = RBF(input_dim=self.X_o.size()[1], lengthscale=torch.ones(self.X_o.size()[1]) * 10, variance=torch.tensor(5.0), name="GPo_dim" + str(i) + "_RBF") range_lis = range(0, y_o.size()[0]) random.shuffle(range_lis) Xu = X_o[range_lis[0:inducing_size], :] ssgpmodel = SparseGPRegression(X_o, y_o[:, i], kernel, Xu, name="SSGPo_model_dim" + str(i), noise=torch.tensor(2.)) self.state_transition_model_list.append(ssgpmodel) else: for i in range(self.y_s.size()[1]): kernel = RBF(input_dim=self.X_s.size()[1], lengthscale=torch.ones(self.X_s.size()[1]) * 10., variance=torch.tensor(5.0), name="GPs_dim" + str(i) + "_RBF") gpmodel = GPRegression(X_s, y_s[:, i], kernel, name="GPs_model_dim" + str(i), jitter=1e-5) self.state_transition_model_list.append(gpmodel) for i in range(self.y_o.size()[1]): kernel = RBF(input_dim=self.X_o.size()[1], lengthscale=torch.ones(self.X_o.size()[1]) * 10., variance=torch.tensor(5.0), name="GPo_dim" + str(i) + "_RBF") gpmodel = GPRegression(X_o, y_o[:, i], kernel, name="GPo_model_dim"+ str(i), noise=torch.tensor(2.)) self.observation_model_list.append(gpmodel) self.option = option # # if model_file: # self.load_model(model_file) self.mu_s_curr = torch.zeros(y_s.size()[1]) self.sigma_s_curr = torch.eye(y_s.size()[1]) self.mu_o_curr = torch.zeros(y_o.size()[1]) self.sigma_o_curr = torch.eye(y_s.size()[1]) self.mu_hat_s_curr = torch.zeros(y_s.size()[1]) self.sigma_hat_s_curr = torch.eye(y_s.size()[1]) self.mu_hat_s_prev = torch.zeros(y_s.size()[1]) self.sigma_hat_s_prev = torch.eye(y_s.size()[1]) # For backwards smoothing self.mu_hat_s_curr_lis = [] self.sigma_hat_s_curr_lis = [] self.mu_s_curr_lis = [] self.sigma_s_curr_lis = [] self.sigma_Xpf_Xcd_lis = [] self.Kff_s_inv = torch.zeros((y_s.size()[1], X_s.size()[0], X_s.size()[0])) self.Kff_o_inv = torch.zeros((y_o.size()[1], X_o.size()[0], X_o.size()[0])) self.K_s_var = torch.zeros(y_s.size()[1], 1) self.K_o_var = torch.zeros(y_o.size()[1], 1) self.Beta_s = torch.zeros((y_s.size()[1], X_s.size()[0])) self.Beta_o = torch.zeros((y_o.size()[1], X_o.size()[0])) self.lengthscale_s = torch.zeros((y_s.size()[1], X_s.size()[1])) self.lengthscale_o = torch.zeros((y_o.size()[1], X_o.size()[1])) self.noise_s = torch.zeros((y_s.size()[1], 1)) self.noise_o = torch.zeros((y_o.size()[1], 1)) if self.option == 'SSGP': self.Xu_s = torch.zeros((y_s.size()[1], inducing_size)) self.Xu_o = torch.zeros((y_o.size()[1], inducing_size)) self.noise_s = torch.zeros((y_s.size()[1], inducing_size)) self.noise_o = torch.zeros((y_o.size()[1], inducing_size)) print("for state transition model, input dim {} and output dim {}".format(X_s.size()[1], y_s.size()[1])) print("for observation model, input dim {} and output dim {}".format(X_o.size()[1], y_o.size()[1]))
X=X, Z=Z, K_sum=3.391847 ), T( Periodic(3, variance, lengthscale, period=torch.ones(1)), X=X, Z=Z, K_sum=18 ), T( Polynomial(3, variance, degree=2), X=X, Z=Z, K_sum=7017 ), T( RationalQuadratic(3, variance, lengthscale, scale_mixture=torch.ones(1)), X=X, Z=Z, K_sum=5.684670 ), T( RBF(3, variance, lengthscale), X=X, Z=Z, K_sum=3.681117 ), T( WhiteNoise(3, variance, lengthscale), X=X, Z=Z, K_sum=0 ), T( WhiteNoise(3, variance, lengthscale), X=X, Z=None, K_sum=6 ), T( Coregionalize(3, components=torch.eye(3, 3)), X=torch.tensor([[1., 0., 0.], [0.5, 0., 0.5]]), Z=torch.tensor([[1., 0., 0.],