mirror of
https://github.com/wassname/pyrobolearn.git
synced 2026-09-10 12:21:16 +08:00
add gplvm
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env python
|
||||
"""Provide the Gaussian Process Latent Variable Model (GPLVM)
|
||||
|
||||
This file provides the GPLVM and shared GPLVM.
|
||||
"""
|
||||
|
||||
import torch
|
||||
import gpytorch
|
||||
|
||||
from pyrobolearn.models.gp.gp import GPR
|
||||
|
||||
|
||||
__author__ = "Brian Delhaisse"
|
||||
__copyright__ = "Copyright 2018, PyRoboLearn"
|
||||
__credits__ = ["Brian Delhaisse"]
|
||||
__license__ = "MIT"
|
||||
__version__ = "1.0.0"
|
||||
__maintainer__ = "Brian Delhaisse"
|
||||
__email__ = "briandelhaisse@gmail.com"
|
||||
__status__ = "Development"
|
||||
|
||||
|
||||
class GPLVM(GPR):
|
||||
r"""Gaussian Process Latent Variable Model (GPLVM)
|
||||
|
||||
The GPLVM is a non-linear, probabilistic model which reduces the dimensional of the original observational space
|
||||
by projecting it to a latent space. This can be seen as one of the non-linear version of probabilistic PCA.
|
||||
|
||||
The optimization carried out by the GPLVM is similar to the one undertaken by the GP regression, instead that, in
|
||||
addition to optimize the kernel hyperparameters, we also optimize the latent variables. This is mathematically
|
||||
formulated by:
|
||||
|
||||
.. math::
|
||||
|
||||
{X^*, \Phi^*} = \arg \max_{X, \Phi} p(Y|X; \Phi)
|
||||
|
||||
where :math:`X` are the latent variables, :math:`\Phi` are the kernel hyperparameters, :math:`Y` are the
|
||||
variables that are observed, and :math:`p(Y|X; \Phi)` is the marginal likelihood.
|
||||
Note that the initialization of the latent space of the GP-LVM can have drastic consequences on the results;
|
||||
which can be good or bad depending on the initialization scheme. Different initialization schemes can be used
|
||||
such as random, or PCA.
|
||||
|
||||
A GPLVM provides a smooth mapping from the latent space to the observational space, however the converse is not
|
||||
true. In order to preserve local distances and have a smooth mapping from the observational space to the latent
|
||||
space, back constraints are often used, which is given by:
|
||||
|
||||
.. math::
|
||||
|
||||
{W^*, \Phi^*} = \arg \max_{W, \Phi} p(Y|X; \Phi)
|
||||
|
||||
where :math:`X = g(Y; W)` with :math:`g` is the back-constraint function parametrized by the weights :math:`W`,
|
||||
which are learned during the optimization process. This often has the effect of constraining the latent space (and
|
||||
thus the latent parameters) making it more robust to overfitting.
|
||||
|
||||
References:
|
||||
[1] "Gaussian Process Latent Variable Models for Visualisation of High Dimensional Data", Lawrence, 2004
|
||||
[2] "Probabilistic Non-linear Principal Component Analysis with Gaussian Process Latent Variable Models",
|
||||
Lawrence, 2005
|
||||
[3] "Local distance preservation in the GP-LVM through back constraints", Lawrence et al., 2006
|
||||
"""
|
||||
|
||||
def __init__(self, latent_dim, mean=None, kernel=None, model=None, likelihood=None):
|
||||
"""
|
||||
Initialize the GPLVM.
|
||||
|
||||
Args:
|
||||
latent_dim (int): latent dimensionality.
|
||||
mean (None, gpytorch.means.Mean): mean prior. If None, it will be set to `gpytorch.means.ConstantMean()`.
|
||||
kernel (None, gpytorch.kernels.Kernel): kernel prior. If None it will be set to
|
||||
`gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernel() + gpytorch.kernels.WhiteNoiseKernel())`
|
||||
model (None, gpytorch.module.Module): the prior GP model. If None, it will create `ExactGPModel()`, a GP
|
||||
model using the provided mean, kernel, and likelihood.
|
||||
likelihood (None, gpytorch.likelihoods.Likelihood): the likelihood pdf. If None, it will use the
|
||||
`gpytorch.likelihoods.GaussianLikelihood()`
|
||||
"""
|
||||
super(GPLVM, self).__init__(mean=mean, kernel=kernel, model=model, likelihood=likelihood)
|
||||
self.X = None
|
||||
latent_dim = int(latent_dim)
|
||||
if latent_dim <= 0:
|
||||
raise ValueError("Expecting the latent dimension to be bigger than 0, instead got: {}".format(latent_dim))
|
||||
self.latent_dim = latent_dim
|
||||
|
||||
@property
|
||||
def is_latent(self):
|
||||
"""The GPLVM is a latent model."""
|
||||
return True
|
||||
|
||||
# TODO: improve the below function
|
||||
def fit_latent(self, Y, init='pca', num_iters=100, tolerance=1e-5, optimizer=None, verbose=False):
|
||||
"""Fit the given data by maximizing the marginal likelihood.
|
||||
|
||||
Args:
|
||||
Y (torch.Tensor, np.array): observational data.
|
||||
init (str, torch.nn.Module): initialization scheme or back-constraint function. If a string, it is the
|
||||
initialization scheme. Currently, you can choose between 'pca' and 'random'. If torch.nn.Module, it
|
||||
is the back-constraint function which has some parameters to optimize.
|
||||
num_iters (int): number of iterations to optimize the marginal likelihood.
|
||||
tolerance (float): termination tolerance on function value/parameter changes (default: 1e-5).
|
||||
optimizer (None, torch.optim.Optimizer): optimizer to use to optimize the marginal likelihood. By default,
|
||||
it will use L-BFGS.
|
||||
verbose (bool): if True, it will print information during the optimization.
|
||||
"""
|
||||
# convert observation data to torch.tensor
|
||||
Y = self._convert_to_torch(Y)
|
||||
|
||||
# initialize the latent space
|
||||
if isinstance(init, torch.nn.Module): # back-constraint function
|
||||
raise NotImplementedError
|
||||
elif isinstance(init, str):
|
||||
init = init.lower()
|
||||
if init == 'random':
|
||||
X = torch.rand(Y.shape[0], self.latent_dim)
|
||||
elif init == 'pca':
|
||||
X = Y - torch.mean(Y, dim=0).expand_as(Y)
|
||||
U, S, V = torch.svd(X)
|
||||
X = torch.mm(X, V[:, :self.latent_dim])
|
||||
else:
|
||||
raise NotImplementedError("Currently, only the 'random' or 'pca' initialization schemes have been "
|
||||
"implemented")
|
||||
X.requires_grad = True
|
||||
X = torch.nn.Parameter(X)
|
||||
|
||||
self.X = X
|
||||
|
||||
# fit the data
|
||||
self.fit(X, Y, num_iters=num_iters, tolerance=tolerance, optimizer=optimizer, verbose=verbose)
|
||||
|
||||
|
||||
class SGPLVM(GPLVM):
|
||||
r"""Shared Gaussian Process Latent Variable Model (SGPLVM)
|
||||
|
||||
With :math:`k` observational spaces sharing the same latent latent space, the following marginal likelihood to
|
||||
maximize is then given by:
|
||||
|
||||
.. math::
|
||||
|
||||
{X^*, {\Phi^*_i}_{i=1}^k} = \arg \max_{X, {\Phi_i}_{i=1}^k} p({Y_i}_{i=1}^k | X; {\Phi_i}_{i=1}^k)
|
||||
|
||||
Back-constraints can be applied on one of the observational space :math:`Y_i`, such that:
|
||||
|
||||
.. math::
|
||||
|
||||
{W^*, {\Phi^*_i}_{i=1}^k} = \arg \max_{W, {\Phi_i}_{i=1}^k} p({Y_i}_{i=1}^k | X; {\Phi_i}_{i=1}^k)
|
||||
|
||||
where :math:`X = g(Y_i, W)` with :math:`g` is the back-constraint function parametrized by the weights :math:`W`.
|
||||
|
||||
References:
|
||||
[1] "Shared gaussian process latent variables models" (PhD thesis), Ek, 2009
|
||||
"""
|
||||
|
||||
def __init__(self, latent_dim, mean=None, kernel=None, model=None, likelihood=None):
|
||||
"""
|
||||
Initialize the shared GPLVM.
|
||||
|
||||
Args:
|
||||
latent_dim (int): latent dimensionality.
|
||||
mean (None, gpytorch.means.Mean): mean prior. If None, it will be set to `gpytorch.means.ConstantMean()`.
|
||||
kernel (None, gpytorch.kernels.Kernel): kernel prior. If None it will be set to
|
||||
`gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernel() + gpytorch.kernels.WhiteNoiseKernel())`
|
||||
model (None, gpytorch.module.Module): the prior GP model. If None, it will create `ExactGPModel()`, a GP
|
||||
model using the provided mean, kernel, and likelihood.
|
||||
likelihood (None, gpytorch.likelihoods.Likelihood): the likelihood pdf. If None, it will use the
|
||||
`gpytorch.likelihoods.GaussianLikelihood()`
|
||||
"""
|
||||
super(SGPLVM, self).__init__(latent_dim=latent_dim, mean=mean, kernel=kernel, model=model,
|
||||
likelihood=likelihood)
|
||||
|
||||
|
||||
class HGPLVM(GPLVM):
|
||||
r"""Hierarchical Gaussian Process Latent Variable Model.
|
||||
|
||||
References:
|
||||
[1] "Hierarchical Gaussian Process Latent Variable Models", Lawrence et al., 2007
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
r"""Provide Bayesian Neural Networks.
|
||||
|
||||
This file provides Bayesian neural networks which add uncertainty to the the prediction of NNs. In a bayesian neural
|
||||
network, the weights and biases have a prior probability distribution attached to them. The posterior distribution on
|
||||
these parameters is computed after training the model on some data.
|
||||
|
||||
Several approaches to learning Bayesian neural networks have been proposed in the literature:
|
||||
- Laplace approximation [5,4]
|
||||
- Monte Carlo
|
||||
- MC Dropout [8,9]
|
||||
- Variational Inference (Bayes by Backprop [7,10])
|
||||
|
||||
References:
|
||||
[1] "Deep Learning" (http://www.deeplearningbook.org/), Goodfellow et al., 2016
|
||||
[2] PyTorch: https://pytorch.org/
|
||||
[3] Pyro: https://pyro.ai/
|
||||
[4] "Pattern Recognition and Machine Learning" (section 5.7), Bishop, 2006
|
||||
[5] "Practical Bayesian Framework for Backpropagation Networks", MacKay, 1992
|
||||
(https://authors.library.caltech.edu/13793/1/MACnc92b.pdf)
|
||||
[6] "Bayesian Learning for Neural Networks" (PhD thesis), Neal, 1995
|
||||
(http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.446.9306&rep=rep1&type=pdf)
|
||||
[7] "Weight Uncertainty in Neural Networks", Blundell et al., 2015 (https://arxiv.org/abs/1505.05424)
|
||||
[8] "Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning", Gal et al., 2015
|
||||
(https://arxiv.org/abs/1506.02142 and appendix: https://arxiv.org/abs/1506.02157)
|
||||
[9] "Uncertainty in Deep Learning" (PhD thesis), Gal, 2016
|
||||
[10] "A Comprehensive guide to Bayesian Convolutional Neural Network with Variational Inference", Shridhar et al.,
|
||||
2019 (https://arxiv.org/pdf/1901.02731.pdf)
|
||||
[11] Blog post: "Making your Neural Network Say 'I Don't Know' - Bayesian NNs using Pyro and PyTorch":
|
||||
https://towardsdatascience.com/making-your-neural-network-say-i-dont-know-bayesian-nns-using-pyro-and-pytorch\
|
||||
-b1c24e6ab8cd
|
||||
|
||||
Interesting implementations:
|
||||
- https://github.com/kumar-shridhar/PyTorch-BayesianCNN
|
||||
- https://github.com/anassinator/bnn
|
||||
- https://github.com/paraschopra/bayesian-neural-network-mnist
|
||||
"""
|
||||
|
||||
import torch
|
||||
|
||||
from pyrobolearn.models.nn.dnn import NN
|
||||
|
||||
__author__ = "Brian Delhaisse"
|
||||
__copyright__ = "Copyright 2018, PyRoboLearn"
|
||||
__credits__ = ["Brian Delhaisse"]
|
||||
__license__ = "MIT"
|
||||
__version__ = "1.0.0"
|
||||
__maintainer__ = "Brian Delhaisse"
|
||||
__email__ = "briandelhaisse@gmail.com"
|
||||
__status__ = "Development"
|
||||
|
||||
|
||||
# TODO: implement
|
||||
class BNN(NN):
|
||||
r"""Bayesian Neural Networks"""
|
||||
pass
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
r"""Provide Capsule networks.
|
||||
|
||||
References:
|
||||
[1] "Deep Learning" (http://www.deeplearningbook.org/), Goodfellow et al., 2016
|
||||
[2] PyTorch: https://pytorch.org/
|
||||
[3] "Dynamic Routing Between Capsules", Sabour et al., 2017 (https://arxiv.org/abs/1710.09829)
|
||||
[4] Medium blog post: "Introducing awesome-capsule-networks"
|
||||
https://medium.com/@sekwiatkowski/introducing-awesome-capsule-networks-897f1b81d1e3
|
||||
|
||||
Interesting implementations:
|
||||
- https://github.com/gram-ai/capsule-networks
|
||||
- https://github.com/danielhavir/capsule-network
|
||||
- https://github.com/higgsfield/Capsule-Network-Tutorial
|
||||
"""
|
||||
|
||||
import torch
|
||||
|
||||
from pyrobolearn.models.nn.dnn import NN
|
||||
|
||||
__author__ = "Brian Delhaisse"
|
||||
__copyright__ = "Copyright 2018, PyRoboLearn"
|
||||
__credits__ = ["Brian Delhaisse"]
|
||||
__license__ = "MIT"
|
||||
__version__ = "1.0.0"
|
||||
__maintainer__ = "Brian Delhaisse"
|
||||
__email__ = "briandelhaisse@gmail.com"
|
||||
__status__ = "Development"
|
||||
|
||||
|
||||
# TODO: implement
|
||||
class CapsuleNN(NN):
|
||||
r"""Capsule Neural Networks"""
|
||||
pass
|
||||
Reference in New Issue
Block a user