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])
         ))
Exemple #3
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
Exemple #4
0
 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
Exemple #6
0
    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
Exemple #7
0
    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)
Exemple #9
0
 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)