Closed DanielH1994 closed 3 years ago
Hi, assigning the constraint over the inducing points on the module level is the correct thing to do here. Here's a working example:
from gpytorch.constraints import Interval
from gpytorch.kernels import InducingPointKernel
class ConstrainedInducingPointKernel(InducingPointKernel):
def __init__(self, base_kernel, inducing_points, likelihood, constraint, active_dims=None):
super().__init__(
base_kernel=base_kernel,
inducing_points=inducing_points,
likelihood=likelihood,
active_dims=None,
)
# define the raw inducing points in the kernel initialization method
del self.inducing_points # not sure if this is strictly necessary but probably good for book-keeping
self.register_parameter(name="raw_inducing_points", parameter=torch.nn.Parameter(inducing_points))
self.register_constraint("raw_inducing_points", constraint)
@property
def inducing_points(self):
return self.raw_inducing_points_constraint.transform(
self.raw_inducing_points
)
# now the model looks something like this
class SGPRModel(gpytorch.models.ExactGP):
def __init__(self, train_x, train_y, likelihood) -> None:
super(SGPRModel, self).__init__(train_x, train_y, likelihood)
self.mean_module = gpytorch.means.ConstantMean()
self.base_covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.MaternKernel(nu=1.5))
# only change is we swapped out the kernel class and put in a constraint over the inducing pts
self.covar_module = ConstrainedInducingPointKernel(
base_kernel=self.base_covar_module, likelihood=likelihood,
inducing_points=ind_ini, constraint=Interval(0.0, 2.0),
)
def forward(self, x):
mean_x = self.mean_module(x)
covar_x = self.covar_module(x)
return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)
likelihood = gpytorch.likelihoods.GaussianLikelihood(noise_constraint=gpytorch.constraints.Positive())
model = SGPRModel(train_x, train_y, likelihood)
With this model and the rest of your code, I'm able to get something like this:
It works very well! Thank you very much!
Hi,
I am using a simple example to implement the SGPR model. I find that the selected inducing points located sometimes outside the input domain. It is unacceptable in my case. In fact, in my application, the point has physical meanings and can not be negative.
I want to set the interval constraints to the inducing points by the following command
lower_bound, upper_bound = torch.zeros_like(ind_ini).reshape(-1,1), 2.0*torch.ones_like(ind_ini).reshape(-1,1) constrained_tensor = gpytorch.constraints.Interval(lower_bound=lower_bound, upper_bound=upper_bound) model.covar_module.register_constraint("inducing_points", constrained_tensor)
but it can not work.Then I try to register the raw parameters for the inducing_points by
model.covar_module.register_parameter(name="raw_inducing_points", parameter=torch.nn.Parameter(ind_ini.reshape(-1,1)))
it fails again.I find that, by registering the raw parameters, those raw parameters
raw_inducing_points
will have the same value as the original parameterinducing_point
but some of them will still locate outside the constraint interval. Could you please help me for how to set the constraint for theinducing_points
? Here are the result figure I get and the code snippet.