def __init__(self, train_x, train_y, mean_module, covar_module, likelihood, dataset_type=None, dataset_params=None, value_structure_discount_factor=None): """ Initializer :param train_x: np.ndarray: training input data. Should be 2D, and interpreted as a list of points. :param train_y: np.ndarray: training output data. Should be 1D, or of shape (train_x.shape[0], 1). :param mean_module: the mean of the GP. See GPyTorch tutorial :param covar_module: the covariance of the GP. See GPyTorch tutorial :param likelihood: the likelihood of the GP. See GPyTorch tutorial :param dataset_type: Possible values: * 'timeforgetting': use a TimeForgettingDataset * 'neighborerasing': use a NeighborErasingDataset * 'downsampling': use a DownsamplingDataset * anything else: use a standard Dataset :param dataset_params: dictionary or None. The entries are passed as keyword arguments to the constructor of the chosen dataset. :param value_structure_discount_factor: None or in (0,1). If float, wraps covar_module with a ValueStructureKernel with the given discount factor. """ # The @tensorwrap decorator automatically transforms train_x and train_y into torch.Tensors. # Hence, we only deal with tensors inside the methods train_x = atleast_2d(train_x) train_y = train_y self.has_value_structure = value_structure_discount_factor is not None if dataset_type == 'timeforgetting': create_dataset = TimeForgettingDataset elif dataset_type == 'neighborerasing': create_dataset = NeighborErasingDataset elif dataset_type == 'downsampling': create_dataset = DownsamplingDataset else: dataset_params = {} create_dataset = Dataset dataset_params['has_is_terminal'] = self.has_value_structure self._dataset = create_dataset(train_x, train_y, **dataset_params) super(GP, self).__init__(train_x, train_y, likelihood) if self.has_value_structure: mean_module = ValueStructureMean( base_mean=mean_module, discount_factor=value_structure_discount_factor, dataset=self.dataset ) covar_module = ValueStructureKernel( base_kernel=covar_module, discount_factor=value_structure_discount_factor, dataset=self.dataset, ) self.mean_module = mean_module self.covar_module = covar_module self.optimizer = torch.optim.Adam self.mll = gpytorch.mlls.ExactMarginalLogLikelihood self.to(device) self.likelihood.to(device)
def append(self, append_x, append_y, **kwargs): self.train_x = torch.cat((self.train_x, atleast_2d(append_x)), dim=0) self.train_y = torch.cat((self.train_y, append_y), dim=0) if self.has_is_terminal: self.is_terminal = torch.cat(( self.is_terminal, self._get_is_terminal(kwargs, append_y.shape[0]) ))
def set_data(self, x, y): """ Sets the dataset of the GP :param x: np.ndarray: the new training input data. Subject to the same constraints as train_x in __init__ :param y: np.ndarray: the new training output data. Subject to the same constraints as train_y in __init__ """ self.train_x = atleast_2d(x) self.train_y = y self._set_gp_data_to_dataset() return self
def append_data(self, x, y, **kwargs): """ Appends data to the GP dataset :param x: np.ndarray: the additional training input data. Should be 2D, with the same number of columns than self.train_x :param y: np.ndarray: the addition training output data. Should be of shape (x.shape[0],) or (x.shape[0], 1) """ # GPyTorch provides an additional, more efficient way of adding data with the ExactGP.get_fantasy_model method, # but it seems to require that the model is called at least once before it can be used self.dataset.append(atleast_2d(x), y, **kwargs) self._set_gp_data_to_dataset() return self
def set_data(self, x, y, **kwargs): """ Sets the dataset of the GP :param x: np.ndarray: the new training input data. Subject to the same constraints as train_x in __init__ :param y: np.ndarray: the new training output data. Subject to the same constraints as train_y in __init__ """ self.train_x = atleast_2d(x) self.train_y = y if self.dataset.has_is_terminal: self.dataset.is_terminal = kwargs.get('is_terminal') self._set_gp_data_to_dataset() return self
def __init__(self, train_x, train_y, mean_module, covar_module, likelihood, dataset_type=None, dataset_params=None): """ Initializer :param train_x: np.ndarray: training input data. Should be 2D, and interpreted as a list of points. :param train_y: np.ndarray: training output data. Should be 1D, or of shape (train_x.shape[0], 1). :param mean_module: the mean of the GP. See GPyTorch tutorial :param covar_module: the covariance of the GP. See GPyTorch tutorial :param likelihood: the likelihood of the GP. See GPyTorch tutorial :param dataset_type: Possible values: * 'timeforgetting': use a TimeForgettingDataset * 'neighborerasing': use a NeighborErasingDataset * anything else: use a standard Dataset :param dataset_params: dictionary or None. The entries are passed as keyword arguments to the constructor of the chosen dataset. """ # The @tensorwrap decorator automatically transforms train_x and train_y into torch.Tensors. # Hence, we only deal with tensors inside the methods train_x = atleast_2d(train_x) train_y = train_y if dataset_type == 'timeforgetting': create_dataset = TimeForgettingDataset elif dataset_type == 'neighborerasing': create_dataset = NeighborErasingDataset else: dataset_params = {} create_dataset = Dataset self.dataset = create_dataset(train_x, train_y, **dataset_params) super(GP, self).__init__(train_x, train_y, likelihood) self.mean_module = mean_module self.covar_module = covar_module self.optimizer = torch.optim.Adam self.mll = gpytorch.mlls.ExactMarginalLogLikelihood
def __init__(self, train_x, train_y, nu=2.5, noise_prior=None, noise_constraint=(1e-3, 1e4), lengthscale_prior=None, lengthscale_constraint=None, outputscale_prior=None, outputscale_constraint=None, hyperparameters_initialization=None, dataset_type=None, dataset_params=None): """ Initializer :param train_x: training input data. Should be 2D, and interpreted as a list of points. :param train_y: np.ndarray: training output data. Should be 1D, or of shape (train_x.shape[0], 1). :param nu: the nu parameter of the Matern kernel. Depends on the desired smoothness :param noise_prior: None or (mu, sigma). If not None, the noise has a prior NormalPrior(mu, sigma) :param noise_constraint: None or (nMin, nMax). If not None, the noise is bounded between nMin and nMax :param lengthscale_prior: None or (mu, sigma) or ((mu_i, sigma_i)): * if (mu, sigma), the lengthscale has a prior NormalPrior(mu, sigma) * if ((mu_i, sigma_i)), the lengthscale has a MultivariateNormalPrior, with mean diag(mu_i) and covariance diag(sigma_i) :param lengthscale_constraint: None or (lMin, lMax). If not None, the lengthscale is bounded between lMin and lMax :param outputscale_prior: None or (mu, sigma). If not None, the outputscale has a prior NormalPrior(mu, sigma) :param outputscale_constraint: None or (oMin, oMax). If not None, the outputscale is bounded between oMin and oMax :param hyperparameters_initialization: None or dict. The hyperparameters are initialized to the values specified. The remaining ones are either initialized as their prior mean, or left uninitialized if no prior is specified. :param dataset_type: If 'timeforgetting', use a TimeForgettingDataset. Otherwise, a default Dataset is used :param dataset_params: dictionary or None. The entries are passed as keyword arguments to the constructor of the chosen dataset. """ train_x = atleast_2d(train_x) self.__structure_dict = { 'nu': nu, 'noise_prior': noise_prior, 'noise_constraint': noise_constraint, 'lengthscale_prior': lengthscale_prior, 'lengthscale_constraint': lengthscale_constraint, 'outputscale_prior': outputscale_prior, 'outputscale_constraint': outputscale_constraint, 'dataset_type': dataset_type, 'dataset_params': dataset_params, } # Using a ConstantMean here performs much worse than a ZeroMean mean_module = gpytorch.means.ZeroMean() if lengthscale_prior is not None: try: means, covars = list(zip(*lengthscale_prior)) lengthscale_prior = gpytorch.priors.MultivariateNormalPrior( torch.FloatTensor(means), torch.diag(torch.FloatTensor(covars))) except TypeError: lengthscale_prior = gpytorch.priors.NormalPrior( *lengthscale_prior) lengthscale_constraint = constraint_from_tuple(lengthscale_constraint) if outputscale_prior is not None: outputscale_prior = gpytorch.priors.NormalPrior(*outputscale_prior) outputscale_constraint = constraint_from_tuple(outputscale_constraint) ard_num_dims = train_x.shape[1] covar_module = gpytorch.kernels.ScaleKernel( gpytorch.kernels.MaternKernel( nu=nu, ard_num_dims=ard_num_dims, lengthscale_prior=lengthscale_prior, lengthscale_constraint=lengthscale_constraint), outputscale_prior=outputscale_prior, outputscale_constraint=outputscale_constraint) if noise_prior is not None: noise_prior = gpytorch.priors.NormalPrior(*noise_prior) noise_constraint = constraint_from_tuple(noise_constraint) likelihood = gpytorch.likelihoods.GaussianLikelihood( noise_prior=noise_prior, noise_constraint=noise_constraint) super(MaternGP, self).__init__(train_x, train_y, mean_module, covar_module, likelihood, dataset_type, dataset_params) initialization = {} if noise_prior is not None: initialization['likelihood.noise_covar.noise'] = noise_prior.mean if outputscale_prior is not None: initialization['covar_module.outputscale'] = outputscale_prior.mean if lengthscale_prior is not None: initialization['covar_module.base_kernel.lengthscale'] = \ lengthscale_prior.mean if hyperparameters_initialization is not None: initialization.update(hyperparameters_initialization) initialization = { k: ensure_tensor(v) for k, v in initialization.items() } self.initialize(**initialization)
def __init__(self, train_x, train_y, noise_prior=None, noise_constraint=(1e-3, 1e4), lengthscale_prior=None, lengthscale_constraint=None, outputscale_prior=None, outputscale_constraint=None, hyperparameters_initialization=None, **kwargs): train_x = atleast_2d(train_x) if train_x.shape[1] != 7: raise ValueError('SymmetricMaternCosGP can only be used on ' '7-dimensional data.') self.__structure_dict = { 'noise_prior': noise_prior, 'noise_constraint': noise_constraint, 'lengthscale_prior': lengthscale_prior, 'lengthscale_constraint': lengthscale_constraint, 'outputscale_prior': outputscale_prior, 'outputscale_constraint': outputscale_constraint, } self.__structure_dict.update(kwargs) if hyperparameters_initialization is None: hyperparameters_initialization = {} mean_module = gpytorch.means.ZeroMean() lp, lc = get_prior_and_constraint(lengthscale_prior, lengthscale_constraint) matern_0 = gpytorch.kernels.MaternKernel( nu=2.5, ard_num_dims=4, lengthscale_prior=lp, lengthscale_constraint=lc, ) l_init = get_initialization('matern_0.lengthscale', hyperparameters_initialization, lp) if l_init is not None: matern_0.lengthscale = l_init sym_matern_0 = matern_0 + ConjugateKernel(matern_0, conjugation=[1, -1, 1, -1]) cos = gpytorch.kernels.CosineKernel() cos.period_length = math.pi lp, lc = get_prior_and_constraint(lengthscale_prior, lengthscale_constraint) matern_1 = gpytorch.kernels.MaternKernel(nu=2.5, ard_num_dims=1, lengthscale_prior=lp, lengthscale_constraint=lc) l_init = get_initialization('matern_1.lengthscale', hyperparameters_initialization, lp) if l_init is not None: matern_1.lengthscale = l_init sym_matern_1 = matern_1 + ConjugateKernel(matern_1, conjugation=[-1]) lp, lc = get_prior_and_constraint(lengthscale_prior, lengthscale_constraint) action = gpytorch.kernels.MaternKernel(nu=2.5, ard_num_dims=1, lengthscale_prior=lp, lengthscale_constraint=lc) l_init = get_initialization('matern_1.lengthscale', hyperparameters_initialization, lp) if l_init is not None: action.lengthscale = l_init # action = gpytorch.kernels.IndexKernel( # num_tasks=4, # rank=2, # ) # sq2o2 = math.sqrt(2) / 2 # action.covar_factor = torch.nn.Parameter(torch.tensor([ # [0, 0], # [sq2o2, -sq2o2], # [0, 0], # [-sq2o2, sq2o2], # ]).float()) # action.var = torch.tensor([1., 0., 1., 0.]).float() # # The covariance matrix of action is now # # [[ 1, 0, 0, 0] # # [ 0, 1, 0, -1] # # [ 0, 0, 1, 0] # # [-1, 0, 0, 1]] prod_decomp = ProductDecompositionKernel( (sym_matern_0, 4), (cos, 1), (sym_matern_1, 1), (action, 1)) op, oc = get_prior_and_constraint(outputscale_prior, outputscale_constraint) covar_module = gpytorch.kernels.ScaleKernel(base_kernel=prod_decomp, outputscale_prior=op, outputscale_constraint=oc) o_init = get_initialization('outputscale', hyperparameters_initialization, op) if o_init is not None: covar_module.outputscale = o_init noise_p, nc = get_prior_and_constraint(noise_prior, noise_constraint) likelihood = gpytorch.likelihoods.GaussianLikelihood( noise_prior=noise_p, noise_constraint=nc) n_init = get_initialization('noise_covar.noise', hyperparameters_initialization, op) if n_init is not None: likelihood.noise_covar.noise = n_init super(SymmetricMaternCosGP, self).__init__(train_x, train_y, mean_module, covar_module, likelihood, **kwargs)
def append(self, append_x, append_y, **kwargs): self.train_x = torch.cat((self.train_x, atleast_2d(append_x)), dim=0) self.train_y = torch.cat((self.train_y, append_y), dim=0)