Commit 0d3e909a authored by Jakob Knollmüller's avatar Jakob Knollmüller Committed by Philipp Arras
Browse files

Add docs

parent 147c9fda
Pipeline #102662 failed with stages
in 12 seconds
...@@ -33,6 +33,14 @@ from ..sugar import domain_union, from_random, full, makeField ...@@ -33,6 +33,14 @@ from ..sugar import domain_union, from_random, full, makeField
class MeanfieldModel(): class MeanfieldModel():
'''
Collects the operators required for Gaussian mean-field variational inference.
Parameters
----------
domain: MultiDomain
The domain of the model parameters.
'''
def __init__(self, domain): def __init__(self, domain):
self.domain = MultiDomain.make(domain) self.domain = MultiDomain.make(domain)
self.Flat = Multifield2Vector(self.domain) self.Flat = Multifield2Vector(self.domain)
...@@ -43,7 +51,19 @@ class MeanfieldModel(): ...@@ -43,7 +51,19 @@ class MeanfieldModel():
self.generator = self.Flat.adjoint(self.mean + self.std * self.latent) self.generator = self.Flat.adjoint(self.mean + self.std * self.latent)
self.entropy = GaussianEntropy(self.std.target) @ self.std self.entropy = GaussianEntropy(self.std.target) @ self.std
def get_initial_pos(self, initial_mean=None,initial_sig = 1): def get_initial_pos(self, initial_mean=None, initial_sig = 1):
'''
Provides an initial position for a given mean parameter vector and an initial standard deviation.
Parameters
----------
initial_mean: MultiField
The initial mean of the variational approximation. If not None, a Gaussian sample with mean zero and standard deviation of 0.1 is used.
Default: None
initial_sig: positive float
The initial standard deviation shared by all parameters. Default: 1
'''
initial_pos = from_random(self.generator.domain).to_dict() initial_pos = from_random(self.generator.domain).to_dict()
initial_pos['latent'] = full(self.generator.domain['latent'], 0.) initial_pos['latent'] = full(self.generator.domain['latent'], 0.)
initial_pos['var'] = full(self.generator.domain['var'], initial_sig) initial_pos['var'] = full(self.generator.domain['var'], initial_sig)
...@@ -56,6 +76,14 @@ class MeanfieldModel(): ...@@ -56,6 +76,14 @@ class MeanfieldModel():
class FullCovarianceModel(): class FullCovarianceModel():
'''
Collects the operators required for Gaussian full-covariance variational inference.
Parameters
----------
domain: MultiDomain
The domain of the model parameters.
'''
def __init__(self, domain): def __init__(self, domain):
self.domain = MultiDomain.make(domain) self.domain = MultiDomain.make(domain)
self.Flat = Multifield2Vector(self.domain) self.Flat = Multifield2Vector(self.domain)
...@@ -86,6 +114,17 @@ class FullCovarianceModel(): ...@@ -86,6 +114,17 @@ class FullCovarianceModel():
self.entropy = GaussianEntropy(diag_cov.target) @ diag_cov self.entropy = GaussianEntropy(diag_cov.target) @ diag_cov
def get_initial_pos(self, initial_mean=None, initial_sig=1): def get_initial_pos(self, initial_mean=None, initial_sig=1):
'''
Provides an initial position for a given mean parameter vector and a diagonal covariance with an initial standard deviation.
Parameters
----------
initial_mean: MultiField
The initial mean of the variational approximation. If not None, a Gaussian sample with mean zero and standard deviation of 0.1 is used.
Default: None
initial_sig: positive float
The initial standard deviation shared by all parameters. Default: 1
'''
initial_pos = from_random(self.generator.domain).to_dict() initial_pos = from_random(self.generator.domain).to_dict()
initial_pos['latent'] = full(self.generator.domain['latent'], 0.) initial_pos['latent'] = full(self.generator.domain['latent'], 0.)
diag_tri = np.diag(np.full(self.flat_domain.shape[0], initial_sig))[np.tril_indices(self.flat_domain.shape[0])] diag_tri = np.diag(np.full(self.flat_domain.shape[0], initial_sig))[np.tril_indices(self.flat_domain.shape[0])]
...@@ -97,6 +136,14 @@ class FullCovarianceModel(): ...@@ -97,6 +136,14 @@ class FullCovarianceModel():
class GaussianEntropy(EnergyOperator): class GaussianEntropy(EnergyOperator):
'''
Calculates the entropy of a Gaussian distribution given the diagonal of a triangular decomposition of the covariance.
Parameters
----------
domain: Domain
The domain of the diagonal.
'''
def __init__(self, domain): def __init__(self, domain):
self._domain = domain self._domain = domain
...@@ -112,6 +159,16 @@ class GaussianEntropy(EnergyOperator): ...@@ -112,6 +159,16 @@ class GaussianEntropy(EnergyOperator):
class LowerTriangularProjector(LinearOperator): class LowerTriangularProjector(LinearOperator):
'''
Projects the DOFs of a triangular matrix into the matrix form.
Parameters
----------
domain: Domain
A one-dimensional domain containing N(N+1)/2 DOFs of a triangular matrix.
target: Domain
A two-dimensional domain with NxN entries.
'''
def __init__(self, domain, target): def __init__(self, domain, target):
self._domain = DomainTuple.make(domain) self._domain = DomainTuple.make(domain)
self._target = DomainTuple.make(target) self._target = DomainTuple.make(target)
...@@ -130,6 +187,16 @@ class LowerTriangularProjector(LinearOperator): ...@@ -130,6 +187,16 @@ class LowerTriangularProjector(LinearOperator):
class DiagonalSelector(LinearOperator): class DiagonalSelector(LinearOperator):
'''
Extracts the diagonal of a two-dimensional field.
Parameters
----------
domain: Domain
The two-dimensional domain of the input field
target: Domain
A one-dimensional domain in which the diagonal of the input field lives.
'''
def __init__(self, domain, target): def __init__(self, domain, target):
self._domain = DomainTuple.make(domain) self._domain = DomainTuple.make(domain)
self._target = DomainTuple.make(target) self._target = DomainTuple.make(target)
...@@ -144,6 +211,17 @@ class DiagonalSelector(LinearOperator): ...@@ -144,6 +211,17 @@ class DiagonalSelector(LinearOperator):
class Respacer(LinearOperator): class Respacer(LinearOperator):
'''
Re-maps a field from one domain to another one with the same amounts of DOFs. Wrapps the numpy.reshape method.
Parameters
----------
domain: Domain
The domain of the input field.
target: Domain
The domain of the output field.
'''
def __init__(self, domain, target): def __init__(self, domain, target):
self._domain = DomainTuple.make(domain) self._domain = DomainTuple.make(domain)
self._target = DomainTuple.make(target) self._target = DomainTuple.make(target)
......
...@@ -19,7 +19,26 @@ from .minimizer import Minimizer ...@@ -19,7 +19,26 @@ from .minimizer import Minimizer
class ADVIOptimizer(Minimizer): class ADVIOptimizer(Minimizer):
def __init__(self, steps, eta=1, alpha=1, tau=1, epsilon=1e-16): '''
Provides an implementation of an adaptive step-size sequence optimizer, following https://arxiv.org/abs/1603.00788.
Parameters
----------
steps: int
The number of concecutive steps during one call of the optimizer.
eta: positive float
The scale of the step-size sequence. It might have to be adapted to the application to increase performance. Default: 1.
alpha: float between 0 and 1
The fraction of how much the current gradient impacts the momentum.
tau: positive float
This quantity prevents division by zero.
epsilon: positive float
A small value guarantees Robbins and Monro conditions.
'''
def __init__(self, steps, eta=1, alpha=0.1, tau=1, epsilon=1e-16):
self.alpha = alpha self.alpha = alpha
self.eta = eta self.eta = eta
self.tau = tau self.tau = tau
...@@ -40,6 +59,15 @@ class ADVIOptimizer(Minimizer): ...@@ -40,6 +59,15 @@ class ADVIOptimizer(Minimizer):
return new_position return new_position
def __call__(self, E): def __call__(self, E):
'''
Performs the optimization.
Parameters
----------
E: EnergyOperator
The target function.
'''
from ..minimization.parametric_gaussian_kl import ParametricGaussianKL from ..minimization.parametric_gaussian_kl import ParametricGaussianKL
if self.s is None: if self.s is None:
self.s = E.gradient ** 2 self.s = E.gradient ** 2
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment