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)

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.
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)
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!