Gpytorch: Error when running Exact GP regression

Created on 7 Feb 2019  路  10Comments  路  Source: cornellius-gp/gpytorch

I'm using GPyTorch 0.1.1 and PyTorch 1.0.0 on Ubuntu 16.04.

I was trying to use ExactGP to fit the data look like this (dots are training data)

data

The training code is exactly the same as one in Simple GP regression tutorial

But as the training goes, I run into this error

TypeError                                 Traceback (most recent call last)
<ipython-input-39-75020af4f8c3> in <module>()
     22     output = model(train_x)
     23     # Calc loss and backprop gradients
---> 24     loss = -mll(output, train_y)
     25     loss.backward()
     26     if not(i%500):

~/.conda/envs/pyro/lib/python3.6/site-packages/gpytorch/module.py in __call__(self, *inputs, **kwargs)
     20 
     21     def __call__(self, *inputs, **kwargs):
---> 22         outputs = self.forward(*inputs, **kwargs)
     23 
     24         if isinstance(outputs, tuple):

~/.conda/envs/pyro/lib/python3.6/site-packages/gpytorch/mlls/exact_marginal_log_likelihood.py in forward(self, output, target, *params)
     26         # Get the log prob of the marginal distribution
     27         output = self.likelihood(output, *params)
---> 28         res = output.log_prob(target)
     29 
     30         # Add terms for SGPR / when inducing points are learned

~/.conda/envs/pyro/lib/python3.6/site-packages/gpytorch/distributions/multivariate_normal.py in log_prob(self, value)
    121 
    122         # Get log determininat and first part of quadratic form
--> 123         inv_quad, log_det = covar.inv_quad_log_det(inv_quad_rhs=diff.unsqueeze(-1), log_det=True)
    124 
    125         res = -0.5 * sum([inv_quad, log_det, diff.size(-1) * math.log(2 * math.pi)])

~/.conda/envs/pyro/lib/python3.6/site-packages/gpytorch/lazy/lazy_tensor.py in inv_quad_log_det(self, inv_quad_rhs, log_det, reduce_inv_quad)
    715             preconditioner=self._preconditioner()[0],
    716             log_det_correction=self._preconditioner()[1],
--> 717         )(*args)
    718 
    719         if inv_quad_term.numel() and reduce_inv_quad:

TypeError: InvQuadLogDet.forward: expected Variable (got float) for return value 1

However, this error doesn't always happen, it only appears in 2 out of 10 runs. I haven't managed to trained it even for cases the error didn't show up (but that may be a different issue). Any ideas would be appreciated.

All 10 comments

Can you share the code for generating that training data? I think this is an issue that is fixed on master

I can share the data in .npy format (this is real measurement data)

data.zip

The inference code is exactly the same as the example, only changes is I change learning rate to a smaller value (0.05, sometimes, 0.001). But the error happens really randomly.

I updated to PyTorch 1.0.1 (installed with conda), GPyTorch 0.1.1 (installed with pip) and still see the issue just now when I write this.

So the expected Variable (got float) is a strong indication that there are NaNs popping up. Are you putting any priors on your hyperparameters? Maybe check whether they take on outrageous values (e.g. extremely small noise levels).

@thongnnguyen - can you install GPyTorch master? Right now it sounds like you've installed a stable release

pip install git+https://github.com/cornellius-gp/gpytorch.git

@thongnnguyen - in the future, it is also helpful if you can provide a complete, simple example that reproduces the problem :)

Thank you guys to respond and help,

Here is the code I use, as said, it is the code from Simple GP Regression example. I only change train_x and train_y to my data, and change the learning rate of Adam to 0.05, and the number of iterations.

x = np.load('x.npy')
y = np.load('y.npy')

train_x = torch.Tensor(x[::10])
train_y = torch.Tensor(y[::10])

class ExactGPModel(gpytorch.models.ExactGP):
    def __init__(self, train_x, train_y, likelihood):
        super(ExactGPModel, self).__init__(train_x, train_y, likelihood)
        self.mean_module = gpytorch.means.ConstantMean()
        self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernel())

    def forward(self, x):
        mean_x = self.mean_module(x)
        covar_x = self.covar_module(x)
        return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)

# initialize likelihood and model
likelihood = gpytorch.likelihoods.GaussianLikelihood()
model = ExactGPModel(train_x, train_y, likelihood)

# Find optimal model hyperparameters
model.train()
likelihood.train()

# Use the adam optimizer
optimizer = torch.optim.Adam([
    {'params': model.parameters()},  # Includes GaussianLikelihood parameters
], lr=0.05)

# "Loss" for GPs - the marginal log likelihood
mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)

training_iter = 5000
for i in range(training_iter):
    # Zero gradients from previous iteration
    optimizer.zero_grad()
    # Output from model
    output = model(train_x)
    # Calc loss and backprop gradients
    loss = -mll(output, train_y)
    loss.backward()
    print('Iter %d/%d - Loss: %.3f   log_lengthscale: %.3f   log_noise: %.3f' % (
        i + 1, training_iter, loss.item(),
        model.covar_module.base_kernel.log_lengthscale.item(),
        model.likelihood.log_noise.item()
    ))
    optimizer.step()

I'll install GPyTorch master and test it out.

Update: I pip uninstall gpytorch then pip install git+https://github.com/cornellius-gp/gpytorch.git, but still see gpytorch-0.1.1. Looks like nothing changed.

You're running a ton of iterations to fit the model - my guess is that there is very little noise in the data and the inferred noise level eventually gets so small that you run into numerical errors. At what iteration do you start to see this fail?

@Balandat It happens randomly, I didn't pay much attention.

I think pip install git+https://github.com/cornellius-gp/gpytorch.git works. I'm on master now (because
the attribute model.covar_module.base_kernel.log_lengthscale and model.likelihood.log_noise is not there anymore, I can only print model.covar_module.base_kernel.lengthscale and model.likelihood.noise)

Now I don't see the error anymore (as @jacobrgardner said, it was fixed on master), and @Balandat is right, I print

print('Iter %d/%d - Loss: %.3f   lengthscale: %.3f   noise: %.3f' % (
            i + 1, training_iter, loss.item(),
            model.covar_module.base_kernel.lengthscale.item(),
            model.likelihood.noise.item()
        ))

And see the noise goes to zero

Iter 1/500 - Loss: 1.124   lengthscale: 0.693   noise: 0.693
Iter 11/500 - Loss: 0.832   lengthscale: 0.969   noise: 0.473
Iter 21/500 - Loss: 0.563   lengthscale: 1.264   noise: 0.309
Iter 31/500 - Loss: 0.305   lengthscale: 1.535   noise: 0.193
Iter 41/500 - Loss: 0.055   lengthscale: 1.772   noise: 0.117
Iter 51/500 - Loss: -0.194   lengthscale: 1.970   noise: 0.069
Iter 61/500 - Loss: -0.430   lengthscale: 2.121   noise: 0.041
Iter 71/500 - Loss: -0.639   lengthscale: 2.245   noise: 0.024
Iter 81/500 - Loss: -0.808   lengthscale: 2.304   noise: 0.015
Iter 91/500 - Loss: -0.939   lengthscale: 2.265   noise: 0.009
Iter 101/500 - Loss: -1.049   lengthscale: 2.109   noise: 0.006
Iter 111/500 - Loss: -1.171   lengthscale: 1.777   noise: 0.004
Iter 121/500 - Loss: -1.287   lengthscale: 1.438   noise: 0.003
Iter 131/500 - Loss: -1.377   lengthscale: 1.335   noise: 0.002
Iter 141/500 - Loss: -1.487   lengthscale: 1.362   noise: 0.001
Iter 151/500 - Loss: -1.568   lengthscale: 1.243   noise: 0.001
Iter 161/500 - Loss: -1.624   lengthscale: 1.205   noise: 0.001
Iter 171/500 - Loss: -1.733   lengthscale: 1.216   noise: 0.000
Iter 181/500 - Loss: -1.733   lengthscale: 1.152   noise: 0.000
Iter 191/500 - Loss: -1.913   lengthscale: 1.262   noise: 0.000
Iter 201/500 - Loss: -1.813   lengthscale: 1.286   noise: 0.000
Iter 211/500 - Loss: -1.925   lengthscale: 1.270   noise: 0.000
Iter 221/500 - Loss: -2.019   lengthscale: 1.258   noise: 0.000

So if it's because the data is almost noiseless, how do I train a noiseless GP with GPyTorch? I searched the documentation but couldn't find any topic about this. (I can do this easily with sklearn.GPR).

Thanks

I would recommend fixing the noise to something really small, or set a prior on the noise parameter. @Balandat is also working on bounds for the parameters, which might help.

I'd like to echo thongnnguyen's point about coming over from sklearn. Can you expand on "fixing the noise to something really small" and "set a prior on the noise parameter" ? I don't see examples where either of these are done. One stab is changing the likelihood line from thongnnguyen's code to something like this:

likelihood = gpytorch.likelihoods.GaussianLikelihood(noise_prior=gpytorch.priors.GammaPrior(0.01,10.0))

But this does not result in (or even initialize to) a low-noise fit. Not sure what I'm doing wrong. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ankushaggarwal picture ankushaggarwal  路  6Comments

Galto2000 picture Galto2000  路  6Comments

ptonner picture ptonner  路  6Comments

pinle-go picture pinle-go  路  4Comments

mshvartsman picture mshvartsman  路  5Comments