# Source code for GPy.models.sparse_gp_minibatch

# Copyright (c) 2012, GPy authors (see AUTHORS.txt).

from __future__ import print_function
import numpy as np
from ..core.parameterization.param import Param
from GPy.core.parameterization.variational import VariationalPosterior
from ..core.sparse_gp import SparseGP
from ..core.gp import GP
from ..inference.latent_function_inference import var_dtc
from .. import likelihoods

import logging
from ..inference.latent_function_inference.posterior import Posterior
from ..inference.optimization.stochastics import SparseGPStochastics, SparseGPMissing
logger = logging.getLogger("sparse gp")

[docs]class SparseGPMiniBatch(SparseGP): """ A general purpose Sparse GP model, allowing missing data and stochastics across dimensions. This model allows (approximate) inference using variational DTC or FITC (Gaussian likelihoods) as well as non-conjugate sparse methods based on these. :param X: inputs :type X: np.ndarray (num_data x input_dim) :param likelihood: a likelihood instance, containing the observed data :type likelihood: GPy.likelihood.(Gaussian | EP | Laplace) :param kernel: the kernel (covariance function). See link kernels :type kernel: a GPy.kern.kern instance :param X_variance: The uncertainty in the measurements of X (Gaussian variance) :type X_variance: np.ndarray (num_data x input_dim) | None :param Z: inducing inputs :type Z: np.ndarray (num_inducing x input_dim) :param num_inducing: Number of inducing points (optional, default 10. Ignored if Z is not None) :type num_inducing: int """ def __init__(self, X, Y, Z, kernel, likelihood, inference_method=None, name='sparse gp', Y_metadata=None, normalizer=False, missing_data=False, stochastic=False, batchsize=1): self._update_stochastics = False # FIXME(?): Half of this function seems to be copy-pasted from # SparseGP.__init, any particular reason why SparseGP.__init # is not called (instead of calling GP.__init__ directly)? # pick a sensible inference method if inference_method is None: if isinstance(likelihood, likelihoods.Gaussian): inference_method = var_dtc.VarDTC(limit=3 if not missing_data else Y.shape[1]) else: #inference_method = ?? raise NotImplementedError("what to do what to do?") print("defaulting to ", inference_method, "for latent function inference") self.kl_factr = 1. self.Z = Param('inducing inputs', Z) self.num_inducing = Z.shape[0] # Skip SparseGP.__init (see remark above) super(SparseGP, self).__init__(X, Y, kernel, likelihood, inference_method=inference_method, name=name, Y_metadata=Y_metadata, normalizer=normalizer) self.missing_data = missing_data if stochastic and missing_data: self.missing_data = True self.stochastics = SparseGPStochastics(self, batchsize, self.missing_data) elif stochastic and not missing_data: self.missing_data = False self.stochastics = SparseGPStochastics(self, batchsize, self.missing_data) elif missing_data: self.missing_data = True self.stochastics = SparseGPMissing(self) else: self.stochastics = False logger.info("Adding Z as parameter") self.link_parameter(self.Z, index=0) self.posterior = None
[docs] def optimize(self, optimizer=None, start=None, **kwargs): try: self._update_stochastics = True SparseGP.optimize(self, optimizer=optimizer, start=start, **kwargs) finally: self._update_stochastics = False
[docs] def has_uncertain_inputs(self): return isinstance(self.X, VariationalPosterior)