Skip to content

Instantly share code, notes, and snippets.

@Joshuaalbert
Created January 19, 2018 08:56
Show Gist options
  • Save Joshuaalbert/431e084cb2cd47da723a4436bc7fceb9 to your computer and use it in GitHub Desktop.
Save Joshuaalbert/431e084cb2cd47da723a4436bc7fceb9 to your computer and use it in GitHub Desktop.
import numpy as np
import tensorflow as tf
from gpflow.likelihoods import Likelihood
from gpflow import densities
from gpflow.decors import params_as_tensors
from gpflow.params import Parameter
from gpflow.transforms import Transform, positive, Chain
from gpflow import settings
class RelativeUncertainties(Transform):
"""
The transform that will enable vector observational uncertainty
by forcing the likelihood variance parameter to a vector with
values proportional to these given relative errors.
Note: this is used for incorperating vector uncertainties in likelihoods
by placing this transform on the variance parameter.
Essentially, this is a vector rescaling function.
"""
def __init__(self, relative_errors = 1.):
self.relative_errors = np.atleast_1d(relative_errors)
def forward_tensor(self, x):
return x * self.relative_errors
def forward(self, x):
return x * self.relative_errors
def backward_tensor(self, y):
return y / self.relative_errors
def backward(self, y):
return y / self.relative_errors
def log_jacobian_tensor(self, x):
errors = tf.cast(self.relative_errors, dtype=settings.float_type)
log_errors = tf.log(errors)
return tf.reduce_sum(log_errors)
def __str__(self):
return "{}*".format(self.relative_errors)
class Gaussian1(Likelihood):
def __init__(self, var=1.0):
super().__init__()
###
# must leave name of param unchanged for trainable param to work
self.variance = Parameter(
1.0, transform=positive, trainable=True, dtype=settings.float_type)
self.relative_errors = Parameter(
var, transform=positive, trainable=False, dtype=settings.float_type)
@params_as_tensors
def logp(self, F, Y):
return densities.gaussian(F, Y, self.relative_errors*self.variance)
@params_as_tensors
def conditional_mean(self, F): # pylint: disable=R0201
return tf.identity(F)
@params_as_tensors
def conditional_variance(self, F):
return tf.fill(tf.shape(F), tf.squeeze((self.relative_errors)*self.variance))
@params_as_tensors
def predict_mean_and_var(self, Fmu, Fvar):
return tf.identity(Fmu), Fvar + (self.relative_errors)*self.variance
@params_as_tensors
def predict_density(self, Fmu, Fvar, Y):
return densities.gaussian(Fmu, Y, Fvar + (self.relative_errors)*self.variance)
@params_as_tensors
def variational_expectations(self, Fmu, Fvar, Y):
return -0.5 * np.log(2 * np.pi) - 0.5 * tf.log((self.relative_errors)*self.variance) \
- 0.5 * (tf.square(Y - Fmu) + Fvar) / ((self.relative_errors)*self.variance)
class Gaussian2(Likelihood):
def __init__(self, var=1.0):
super().__init__()
if isinstance(var, (tuple, list, np.ndarray)):
self.variance = Parameter(
1., transform = Chain(positive, RelativeUncertainties(var)), dtype=settings.float_type)
else:
self.variance = Parameter(
var, transform=positive, dtype=settings.float_type)
@params_as_tensors
def logp(self, F, Y):
return densities.gaussian(F, Y, self.variance)
@params_as_tensors
def conditional_mean(self, F): # pylint: disable=R0201
return tf.identity(F)
@params_as_tensors
def conditional_variance(self, F):
return tf.fill(tf.shape(F), tf.squeeze(self.variance))
@params_as_tensors
def predict_mean_and_var(self, Fmu, Fvar):
return tf.identity(Fmu), Fvar + self.variance
@params_as_tensors
def predict_density(self, Fmu, Fvar, Y):
return densities.gaussian(Fmu, Y, Fvar + self.variance)
@params_as_tensors
def variational_expectations(self, Fmu, Fvar, Y):
return -0.5 * np.log(2 * np.pi) - 0.5 * tf.log(self.variance) \
- 0.5 * (tf.square(Y - Fmu) + Fvar) / self.variance
import gpflow as gp
import pylab as plt
plt.style.use("ggplot")
X = np.linspace(0,1,100)[:,None]
sigma_y = np.random.uniform(size=100)
Y = np.sin(10*X) + sigma_y*np.random.normal(size=X.shape)
plt.plot(X[:,0],Y[:,0])
plt.fill_between(X[:,0],Y[:,0] + sigma_y, Y[:,0] - sigma_y, alpha = 0.2)
plt.show()
o = gp.train.ScipyOptimizer(method='BFGS')
print("Gaussian1: Testing with scalar measurement variance")
with gp.defer_build():
k = gp.kernels.RBF(1,lengthscales=[0.05])
kern = k
mean = gp.mean_functions.Zero()
l = Gaussian1(var=1.0)
m = gp.models.GPR(X, Y, kern, mean_function=mean, var=1.0)
#m.likelihood = Gaussian1(var=1.0)
m.compile()
print(o.minimize(m,maxiter=1000))
print(m)
y,var = m.predict_y(X)
plt.plot(X[:,0],y[:,0])
plt.fill_between(X[:,0],y[:,0] + np.sqrt(var[:,0]),y[:,0] - np.sqrt(var[:,0]), alpha = 0.2)
plt.show()
print("Gaussian1: Testing with vector measurement variance (two separate params - leaving variance param)")
with gp.defer_build():
k = gp.kernels.RBF(1,lengthscales=[0.05])
kern = k
mean = gp.mean_functions.Zero()
m = gp.models.GPR(X, Y, kern, mean_function=mean, var=(sigma_y)**2)
m.likelihood = Gaussian1(var=sigma_y**2)
m.compile()
print(o.minimize(m,maxiter=1000))
print(m)
y,var = m.predict_y(X)
plt.plot(X[:,0],y[:,0])
plt.fill_between(X[:,0],y[:,0] + np.sqrt(var[:,0]),y[:,0] - np.sqrt(var[:,0]), alpha = 0.2)
plt.show()
print("Gaussian2: Testing with vector measurement variance (attempting to use transform)")
with gp.defer_build():
k = gp.kernels.RBF(1,lengthscales=[0.05])
kern = k
mean = gp.mean_functions.Zero()
m = gp.models.GPR(X, Y, kern, mean_function=mean, var=(sigma_y)**2)
m.likelihood = Gaussian2(var=sigma_y**2)
m.compile()
print(o.minimize(m,maxiter=1000))
print(m)
y,var = m.predict_y(X)
plt.plot(X[:,0],y[:,0])
plt.fill_between(X[:,0],y[:,0] + np.sqrt(var[:,0]),y[:,0] - np.sqrt(var[:,0]), alpha = 0.2)
plt.show()
@koneshgit
Copy link

from gpflow import densities _ImportError: cannot import name 'densities'_

Is it something wrong with my GPFlow Version?
gpflow 1.3.0 py36_0 conda-forge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment