From 2d6fee8405d3b3d68abb25495fe318f3fa9be06e Mon Sep 17 00:00:00 2001 From: Chris Fonnesbeck Date: Thu, 17 Nov 2016 13:43:51 -0500 Subject: [PATCH 01/83] Added mode argument to several step methods and advi to allow mode setting (e.g. nanguardmode) for Theano functions --- pymc3/step_methods/metropolis.py | 7 +++++-- pymc3/step_methods/nuts.py | 11 ++++++++--- pymc3/variational/advi.py | 9 ++++++--- pymc3/variational/advi_minibatch.py | 7 +++++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/pymc3/step_methods/metropolis.py b/pymc3/step_methods/metropolis.py index 6775eeb2f3..3645542f48 100644 --- a/pymc3/step_methods/metropolis.py +++ b/pymc3/step_methods/metropolis.py @@ -66,7 +66,8 @@ class Metropolis(ArrayStepShared): The frequency of tuning. Defaults to 100 iterations. model : PyMC Model Optional model for sampling step. Defaults to None (taken from context). - + mode : string or `Mode` instance. + compilation mode passed to Theano functions """ default_blocked = False @@ -93,6 +94,8 @@ def __init__(self, vars=None, S=None, proposal_dist=NormalProposal, scaling=1., [[v.dtype in pm.discrete_types] * (v.dsize or 1) for v in vars]) self.any_discrete = self.discrete.any() self.all_discrete = self.discrete.all() + + self.mode = mode shared = pm.make_shared_replacements(vars, model) self.delta_logp = delta_logp(model.logpt, vars, shared) @@ -430,6 +433,6 @@ def delta_logp(logp, vars, shared): logp1 = pm.CallableTensor(logp0)(inarray1) - f = theano.function([inarray1, inarray0], logp1 - logp0) + f = theano.function([inarray1, inarray0], logp1 - logp0, mode=self.mode) f.trust_input = True return f diff --git a/pymc3/step_methods/nuts.py b/pymc3/step_methods/nuts.py index b72813156d..17404fb1e4 100644 --- a/pymc3/step_methods/nuts.py +++ b/pymc3/step_methods/nuts.py @@ -32,7 +32,8 @@ def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, state k=0.75, t0=10, model=None, - profile=False, **kwargs): + profile=False, + mode=None, **kwargs): """ Parameters ---------- @@ -57,6 +58,8 @@ def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, state model : Model profile : bool or ProfileStats sets the functions to be profiled + mode : string or `Mode` instance. + compilation mode passed to Theano functions """ model = modelcontext(model) @@ -90,6 +93,7 @@ def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, state self.Hbar = 0 self.u = log(self.step_size * 10) self.m = 1 + self.mode = mode shared = make_shared_replacements(vars, model) @@ -106,7 +110,7 @@ def create_energy_func(q): p = tt.dvector('p') p.tag.test_value = q.tag.test_value E0 = energy(self.H, q, p) - E0_func = theano.function([q, p], E0) + E0_func = theano.function([q, p], E0, mode=self.mode) E0_func.trust_input = True return E0_func @@ -227,6 +231,7 @@ def leapfrog1_dE(H, q, profile): dE = E - E0 - f = theano.function([q, p, e, E0], [q1, p1, dE], profile=profile) + f = theano.function([q, p, e, E0], [q1, p1, dE], + profile=profile, mode=self.mode) f.trust_input = True return f diff --git a/pymc3/variational/advi.py b/pymc3/variational/advi.py index 67889529b0..a89195e085 100644 --- a/pymc3/variational/advi.py +++ b/pymc3/variational/advi.py @@ -36,7 +36,8 @@ def gen_random_state(): def advi(vars=None, start=None, model=None, n=5000, accurate_elbo=False, - optimizer=None, learning_rate=.001, epsilon=.1, random_seed=None): + optimizer=None, learning_rate=.001, epsilon=.1, mode=None, + random_seed=None): """Perform automatic differentiation variational inference (ADVI). This function implements the meanfield ADVI, where the variational @@ -87,7 +88,9 @@ def advi(vars=None, start=None, model=None, n=5000, accurate_elbo=False, This parameter is ignored when optimizer is given. random_seed : int or None Seed to initialize random state. None uses current seed. - + mode : string or `Mode` instance. + Compilation mode passed to Theano functions + Returns ------- ADVIFit @@ -137,7 +140,7 @@ def advi(vars=None, start=None, model=None, n=5000, accurate_elbo=False, uw_shared = theano.shared(uw, 'uw_shared') elbo = pm.CallableTensor(elbo)(uw_shared) updates = optimizer(loss=-1 * elbo, param=[uw_shared]) - f = theano.function([], [uw_shared, elbo], updates=updates) + f = theano.function([], [uw_shared, elbo], updates=updates, mode=mode) # Optimization loop elbos = np.empty(n) diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index 79ed5a0638..097ff16825 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -207,7 +207,8 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, minibatch_RVs=None, minibatch_tensors=None, minibatches=None, local_RVs=None, observed_RVs=None, encoder_params=[], total_size=None, optimizer=None, - learning_rate=.001, epsilon=.1, random_seed=None): + learning_rate=.001, epsilon=.1, random_seed=None, + mode=None): """Perform mini-batch ADVI. This function implements a mini-batch ADVI with the meanfield @@ -297,6 +298,8 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, This parameter is ignored when an optimizer is given. random_seed : int Seed to initialize random state. + mode : string or `Mode` instance. + compilation mode passed to Theano functions Returns ------- @@ -382,7 +385,7 @@ def is_shared(t): if 0 < len(global_RVs): params += [uw_global_shared] updates = OrderedDict(optimizer(loss=-1 * elbo, param=params)) - f = theano.function(tensors, elbo, updates=updates) + f = theano.function(tensors, elbo, updates=updates, mode=mode) # Optimization loop elbos = np.empty(n) From 4e5b9c205de139c9ac6226eeb976377162414ba6 Mon Sep 17 00:00:00 2001 From: Chris Fonnesbeck Date: Thu, 17 Nov 2016 14:25:18 -0500 Subject: [PATCH 02/83] Fixed namespace bugs in mode attribute --- pymc3/step_methods/metropolis.py | 2 +- pymc3/step_methods/nuts.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pymc3/step_methods/metropolis.py b/pymc3/step_methods/metropolis.py index 3645542f48..67b7873bb5 100644 --- a/pymc3/step_methods/metropolis.py +++ b/pymc3/step_methods/metropolis.py @@ -72,7 +72,7 @@ class Metropolis(ArrayStepShared): default_blocked = False def __init__(self, vars=None, S=None, proposal_dist=NormalProposal, scaling=1., - tune=True, tune_interval=100, model=None, **kwargs): + tune=True, tune_interval=100, model=None, mode=None, **kwargs): model = pm.modelcontext(model) diff --git a/pymc3/step_methods/nuts.py b/pymc3/step_methods/nuts.py index 17404fb1e4..84bb3a90ba 100644 --- a/pymc3/step_methods/nuts.py +++ b/pymc3/step_methods/nuts.py @@ -118,7 +118,8 @@ def create_energy_func(q): self.H, q = create_hamiltonian(vars, shared, model) self.compute_energy = create_energy_func(q) - self.leapfrog1_dE = leapfrog1_dE(self.H, q, profile=profile) + self.leapfrog1_dE = leapfrog1_dE(self.H, q, profile=profile, + mode=self.mode) super(NUTS, self).__init__(vars, shared, **kwargs) @@ -204,7 +205,7 @@ def buildtree(leapfrog1_dE, q, p, u, v, j, e, Emax, E0): return -def leapfrog1_dE(H, q, profile): +def leapfrog1_dE(H, q, profile, mode): """Computes a theano function that computes one leapfrog step and the energy difference between the beginning and end of the trajectory. Parameters ---------- @@ -232,6 +233,6 @@ def leapfrog1_dE(H, q, profile): dE = E - E0 f = theano.function([q, p, e, E0], [q1, p1, dE], - profile=profile, mode=self.mode) + profile=profile, mode=mode) f.trust_input = True return f From 0ebaacdee2fe34fb6451aede880d9dd5d69f0ccc Mon Sep 17 00:00:00 2001 From: Chris Fonnesbeck Date: Thu, 17 Nov 2016 16:40:37 -0500 Subject: [PATCH 03/83] Reverted function in delta_logp to not accept mode argument --- pymc3/step_methods/metropolis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/step_methods/metropolis.py b/pymc3/step_methods/metropolis.py index 67b7873bb5..74f64a27d0 100644 --- a/pymc3/step_methods/metropolis.py +++ b/pymc3/step_methods/metropolis.py @@ -433,6 +433,6 @@ def delta_logp(logp, vars, shared): logp1 = pm.CallableTensor(logp0)(inarray1) - f = theano.function([inarray1, inarray0], logp1 - logp0, mode=self.mode) + f = theano.function([inarray1, inarray0], logp1 - logp0) f.trust_input = True return f From 55c8ce644ff762f591dd1df7b44c825005ecc066 Mon Sep 17 00:00:00 2001 From: Maxim Date: Mon, 28 Nov 2016 07:38:18 +0300 Subject: [PATCH 04/83] ENH User model (#1525) * Started to write Base class for pymc3.models * mode `add_var` to public api * Added some docstrings * Added some docstrings * added getitem and fixed a typo * added assertion check * added resolve var method * decided not to add resolve method * Added linear component * Docs fix * patsy's intercept is inited properly now * refactored code * updated docs * added possibility to init coefficients with random variables * added glm * refactored api, fixed formula init * refactored linear model, extended acceptable types * moved useful matrix and labels creation to utils file * code style * removed redundant evaluation of shape * refactored resolver for constructing matrix and labels * changed error message * changed signature of init * simplified utils any_to_tensor_and_labels code * tests for `any_to_tensor_and_labels` * added docstring for `any_to_tensor_and_labels` util * forgot to document return type in `any_to_tensor_and_labels` * refactored code for dict * dict tests fix(do not check labels there) * added access to random vars of model * added a shortcut for all variables so there is a unified way to get them * added default priors for linear model * update docs for linear * refactored UserModel api, made it more similar to pm.Model class * Lots of refactoring, tests for base class, more plain api design * deleted unused module variable * fixed some typos in docstring * Refactored pm.Model class, now it is ready for inheritance * Added documentation for Model class * Small typo in docstring * nested contains for treedict (needed for add_random_variable) * More accurate duplicate implementation of treedict/treelist * refactored treedict/treelist * changed `__imul__` of treelist * added `root` property and `isroot` indicator for base model * protect `parent` and `model` attributes from violation * travis' python2 did not fail on bad syntax(maybe it's too new), fixed * decided not to use functools wrapper Unfortunately functools wrapper fails when decorating built-in methods so I need to fix that improper behaviour. Some bad but needed tricks were implemented * Added models package to setup script * Refactor utils * Fix some typos in pm.model --- pymc3/model.py | 271 +++++++++++++++++++++++++++--- pymc3/models/__init__.py | 6 + pymc3/models/linear.py | 134 +++++++++++++++ pymc3/models/utils.py | 126 ++++++++++++++ pymc3/tests/test_model.py | 120 +++++++++++++ pymc3/tests/test_models_linear.py | 108 ++++++++++++ pymc3/tests/test_models_utils.py | 79 +++++++++ requirements.txt | 1 + setup.py | 5 +- 9 files changed, 829 insertions(+), 21 deletions(-) create mode 100644 pymc3/models/__init__.py create mode 100644 pymc3/models/linear.py create mode 100644 pymc3/models/utils.py create mode 100644 pymc3/tests/test_model.py create mode 100644 pymc3/tests/test_models_linear.py create mode 100644 pymc3/tests/test_models_utils.py diff --git a/pymc3/model.py b/pymc3/model.py index 5f079b5686..1220c5529d 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -1,3 +1,4 @@ +import six import numpy as np import theano import theano.tensor as tt @@ -168,17 +169,215 @@ def logpt(self): return tt.sum(self.logp_elemwiset) -class Model(Context, Factor): - """Encapsulates the variables and likelihood factors of a model.""" +class InitContextMeta(type): + """Metaclass that executes `__init__` of instance in it's context""" + def __call__(cls, *args, **kwargs): + instance = cls.__new__(cls, *args, **kwargs) + with instance: # appends context + instance.__init__(*args, **kwargs) + return instance + + +def withparent(meth): + """Helper wrapper that passes calls to parent's instance""" + def wrapped(self, *args, **kwargs): + res = meth(self, *args, **kwargs) + if getattr(self, 'parent', None) is not None: + getattr(self.parent, meth.__name__)(*args, **kwargs) + return res + # Unfortunately functools wrapper fails + # when decorating built-in methods so we + # need to fix that improper behaviour + wrapped.__name__ = meth.__name__ + return wrapped + + +class treelist(list): + """A list that passes mutable extending operations used in Model + to parent list instance. + Extending treelist you will also extend its parent + """ + def __init__(self, iterable=(), parent=None): + super(treelist, self).__init__(iterable) + assert isinstance(parent, list) or parent is None + self.parent = parent + if self.parent is not None: + self.parent.extend(self) + # typechecking here works bad + append = withparent(list.append) + __iadd__ = withparent(list.__iadd__) + extend = withparent(list.extend) + + def tree_contains(self, item): + if isinstance(self.parent, treedict): + return (list.__contains__(self, item) or + self.parent.tree_contains(item)) + elif isinstance(self.parent, list): + return (list.__contains__(self, item) or + self.parent.__contains__(item)) + else: + return list.__contains__(self, item) + + def __setitem__(self, key, value): + raise NotImplementedError('Method is removed as we are not' + ' able to determine ' + 'appropriate logic for it') + + def __imul__(self, other): + t0 = len(self) + list.__imul__(self, other) + if self.parent is not None: + self.parent.extend(self[t0:]) + + +class treedict(dict): + """A dict that passes mutable extending operations used in Model + to parent dict instance. + Extending treedict you will also extend its parent + """ + def __init__(self, iterable=(), parent=None, **kwargs): + super(treedict, self).__init__(iterable, **kwargs) + assert isinstance(parent, dict) or parent is None + self.parent = parent + if self.parent is not None: + self.parent.update(self) + # typechecking here works bad + __setitem__ = withparent(dict.__setitem__) + update = withparent(dict.update) + + def tree_contains(self, item): + # needed for `add_random_variable` method + if isinstance(self.parent, treedict): + return (dict.__contains__(self, item) or + self.parent.tree_contains(item)) + elif isinstance(self.parent, dict): + return (dict.__contains__(self, item) or + self.parent.__contains__(item)) + else: + return dict.__contains__(self, item) + + +class Model(six.with_metaclass(InitContextMeta, Context, Factor)): + """Encapsulates the variables and likelihood factors of a model. - def __init__(self): - self.named_vars = {} - self.free_RVs = [] - self.observed_RVs = [] - self.deterministics = [] - self.potentials = [] - self.missing_values = [] - self.model = self + Model class can be used for creating class based models. To create + a class based model you should inherit from `Model` and + override `__init__` with arbitrary definitions + (do not forget to call base class `__init__` first). + + Parameters + ---------- + name : str, default '' - name that will be used as prefix for + names of all random variables defined within model + model : Model, default None - instance of Model that is + supposed to be a parent for the new instance. If None, + context will be used. All variables defined within instance + will be passed to the parent instance. So that 'nested' model + contributes to the variables and likelihood factors of + parent model. + + Examples + -------- + # How to define a custom model + class CustomModel(Model): + # 1) override init + def __init__(self, mean=0, sd=1, name='', model=None): + # 2) call super's init first, passing model and name to it + # name will be prefix for all variables here + # if no name specified for model there will be no prefix + super(CustomModel, self).__init__(name, model) + # now you are in the context of instance, + # `modelcontext` will return self + # you can define variables in several ways + # note, that all variables will get model's name prefix + + # 3) you can create variables with Var method + self.Var('v1', Normal.dist(mu=mean, sd=sd)) + # this will create variable named like '{prefix_}v1' + # and assign attribute 'v1' to instance + # created variable can be accessed with self.v1 or self['v1'] + + # 4) this syntax will also work as we are in the context + # of instance itself, names are given as usual + Normal('v2', mu=mean, sd=sd) + + # something more complex is allowed too + Normal('v3', mu=mean, sd=HalfCauchy('sd', beta=10, testval=1.)) + + # Deterministic variables can be used in usual way + Deterministic('v3_sq', self.v3 ** 2) + # Potentials too + Potential('p1', tt.constant(1)) + + # After defining a class CustomModel you can use it in several ways + + # I: + # state the model within a context + with Model() as model: + CustomModel() + # arbitrary actions + + # II: + # use new class as entering point in context + with CustomModel() as model: + Normal('new_normal_var', mu=1, sd=0) + + # III: + # just get model instance with all that was defined in it + model = CustomModel() + + # IV: + # use many custom models within one context + with Model() as model: + CustomModel(mean=1, name='first') + CustomModel(mean=2, name='second') + """ + def __new__(cls, *args, **kwargs): + # resolves the parent instance + instance = object.__new__(cls) + if kwargs.get('model') is not None: + instance._parent = kwargs.get('model') + elif cls.get_contexts(): + instance._parent = cls.get_contexts()[-1] + else: + instance._parent = None + return instance + + def __init__(self, name='', model=None): + self.name = name + if self.parent is not None: + self.named_vars = treedict(parent=self.parent.named_vars) + self.free_RVs = treelist(parent=self.parent.free_RVs) + self.observed_RVs = treelist(parent=self.parent.observed_RVs) + self.deterministics = treelist(parent=self.parent.deterministics) + self.potentials = treelist(parent=self.parent.potentials) + self.missing_values = treelist(parent=self.parent.missing_values) + else: + self.named_vars = treedict() + self.free_RVs = treelist() + self.observed_RVs = treelist() + self.deterministics = treelist() + self.potentials = treelist() + self.missing_values = treelist() + + @property + def model(self): + return self + + @property + def parent(self): + return self._parent + + @property + def root(self): + model = self + while not model.isroot: + model = model.parent + return model + + @property + def isroot(self): + return self.parent is None @property @memoize @@ -271,6 +470,7 @@ def Var(self, name, dist, data=None): ------- FreeRV or ObservedRV """ + name = self.name_for(name) if data is None: if getattr(dist, "transform", None) is None: var = FreeRV(name=name, distribution=dist, model=self) @@ -308,15 +508,46 @@ def Var(self, name, dist, data=None): def add_random_variable(self, var): """Add a random variable to the named variables of the model.""" - if var.name in self.named_vars: + if self.named_vars.tree_contains(var.name): raise ValueError( "Variable name {} already exists.".format(var.name)) self.named_vars[var.name] = var - if not hasattr(self, var.name): - setattr(self, var.name, var) + if not hasattr(self, self.name_of(var.name)): + setattr(self, self.name_of(var.name), var) + + @property + def prefix(self): + return '%s_' % self.name if self.name else '' + + def name_for(self, name): + """Checks if name has prefix and adds if needed + """ + if self.prefix: + if not name.startswith(self.prefix): + return '{}{}'.format(self.prefix, name) + else: + return name + else: + return name + + def name_of(self, name): + """Checks if name has prefix and deletes if needed + """ + if not self.prefix or not name: + return name + elif name.startswith(self.prefix): + return name[len(self.prefix):] + else: + return name def __getitem__(self, key): - return self.named_vars[key] + try: + return self.named_vars[key] + except KeyError as e: + try: + return self.named_vars[self.name_for(key)] + except KeyError: + raise e @memoize def makefn(self, outs, mode=None, *args, **kwargs): @@ -633,9 +864,10 @@ def Deterministic(name, var, model=None): ------- n : var but with name name """ - var.name = name - modelcontext(model).deterministics.append(var) - modelcontext(model).add_random_variable(var) + model = modelcontext(model) + var.name = model.name_for(name) + model.deterministics.append(var) + model.add_random_variable(var) return var @@ -651,8 +883,9 @@ def Potential(name, var, model=None): ------- var : var, with name attribute """ - var.name = name - modelcontext(model).potentials.append(var) + model = modelcontext(model) + var.name = model.name_for(name) + model.potentials.append(var) return var diff --git a/pymc3/models/__init__.py b/pymc3/models/__init__.py new file mode 100644 index 0000000000..17e6772687 --- /dev/null +++ b/pymc3/models/__init__.py @@ -0,0 +1,6 @@ +from .linear import LinearComponent, Glm + +__all__ = [ + 'LinearComponent', + 'Glm' +] diff --git a/pymc3/models/linear.py b/pymc3/models/linear.py new file mode 100644 index 0000000000..b6a224f2b4 --- /dev/null +++ b/pymc3/models/linear.py @@ -0,0 +1,134 @@ +import theano.tensor as tt +import pandas as pd +import numpy as np +from ..distributions import Normal, Flat +from ..glm import families +from ..model import Model, Deterministic +from .utils import any_to_tensor_and_labels + +__all__ = [ + 'LinearComponent', + 'Glm' +] + + +class LinearComponent(Model): + """Creates linear component, y_est is accessible via attribute + Parameters + ---------- + name : str - name, associated with the linear component + x : pd.DataFrame or np.ndarray + y : pd.Series or np.array + intercept : bool - fit with intercept or not? + labels : list - replace variable names with these labels + priors : dict - priors for coefficients + use `Intercept` key for defining Intercept prior + defaults to Flat.dist() + use `Regressor` key for defining default prior for all regressors + defaults to Normal.dist(mu=0, tau=1.0E-6) + vars : dict - random variables instead of creating new ones + """ + default_regressor_prior = Normal.dist(mu=0, tau=1.0E-6) + default_intercept_prior = Flat.dist() + + def __init__(self, x, y, intercept=True, labels=None, + priors=None, vars=None, name='', model=None): + super(LinearComponent, self).__init__(name, model) + if priors is None: + priors = {} + if vars is None: + vars = {} + x, labels = any_to_tensor_and_labels(x, labels) + # now we have x, shape and labels + if intercept: + x = tt.concatenate( + [tt.ones((x.shape[0], 1), x.dtype), x], + axis=1 + ) + labels = ['Intercept'] + labels + coeffs = list() + for name in labels: + if name == 'Intercept': + if name in vars: + v = Deterministic(name, vars[name]) + else: + v = self.Var( + name=name, + dist=priors.get( + name, + self.default_intercept_prior + ) + ) + coeffs.append(v) + else: + if name in vars: + v = Deterministic(name, vars[name]) + else: + v = self.Var( + name=name, + dist=priors.get( + name, + priors.get( + 'Regressor', + self.default_regressor_prior + ) + ) + ) + coeffs.append(v) + self.coeffs = tt.stack(coeffs, axis=0) + self.y_est = x.dot(self.coeffs) + + @classmethod + def from_formula(cls, formula, data, priors=None, vars=None, name='', model=None): + import patsy + y, x = patsy.dmatrices(formula, data) + labels = x.design_info.column_names + return cls(np.asarray(x), np.asarray(y)[:, 0], intercept=False, labels=labels, + priors=priors, vars=vars, name=name, model=model) + + +class Glm(LinearComponent): + """Creates glm model, y_est is accessible via attribute + Parameters + ---------- + name : str - name, associated with the linear component + x : pd.DataFrame or np.ndarray + y : pd.Series or np.array + intercept : bool - fit with intercept or not? + labels : list - replace variable names with these labels + priors : dict - priors for coefficients + use `Intercept` key for defining Intercept prior + defaults to Flat.dist() + use `Regressor` key for defining default prior for all regressors + defaults to Normal.dist(mu=0, tau=1.0E-6) + init : dict - test_vals for coefficients + vars : dict - random variables instead of creating new ones + family : pymc3.glm.families object + """ + def __init__(self, x, y, intercept=True, labels=None, + priors=None, vars=None, family='normal', name='', model=None): + super(Glm, self).__init__( + x, y, intercept=intercept, labels=labels, + priors=priors, vars=vars, name=name, model=model + ) + + _families = dict( + normal=families.Normal, + student=families.StudentT, + binomial=families.Binomial, + poisson=families.Poisson + ) + if isinstance(family, str): + family = _families[family]() + self.y_est = family.create_likelihood( + name='', y_est=self.y_est, + y_data=y, model=self) + + @classmethod + def from_formula(cls, formula, data, priors=None, + vars=None, family='normal', name='', model=None): + import patsy + y, x = patsy.dmatrices(formula, data) + labels = x.design_info.column_names + return cls(np.asarray(x), np.asarray(y)[:, 0], intercept=False, labels=labels, + priors=priors, vars=vars, family=family, name=name, model=model) diff --git a/pymc3/models/utils.py b/pymc3/models/utils.py new file mode 100644 index 0000000000..ea073fcd1b --- /dev/null +++ b/pymc3/models/utils.py @@ -0,0 +1,126 @@ +import six +import pandas as pd +from pandas.core.common import PandasError +import numpy as np +import theano.tensor as tt + + +def any_to_tensor_and_labels(x, labels=None): + """Util for converting input x to tensor trying to + create labels for columns if they are not provided. + + Default names for columns are ['x0', 'x1', ...], for mappable + arrays (e.g. pd.DataFrame) their names are treated as labels. + You can override them with `labels` argument. + + If you have tensor input you should provide labels as we + cannot get their shape directly + + If you pass dict input we cannot rely on labels order thus dict + keys are treated as labels anyway + + Parameters + ---------- + x : np.ndarray | pd.DataFrame | tt.Variable | dict | list + labels : list - names for columns of output tensor + + Returns + ------- + (x, labels) - tensor and labels for its columns + """ + if isinstance(labels, six.string_types): + labels = [labels] + # pandas.DataFrame + # labels can come from here + # we can override them + if isinstance(x, pd.DataFrame): + if not labels: + labels = x.columns + x = x.as_matrix() + + # pandas.Series + # there can still be a label + # we can override labels + elif isinstance(x, pd.Series): + if not labels: + labels = [x.name] + x = x.as_matrix()[:, None] + + # dict + # labels are keys, + # cannot override them + elif isinstance(x, dict): + # try to do it via pandas + try: + x = pd.DataFrame.from_dict(x) + labels = x.columns + x = x.as_matrix() + # some types fail there + # another approach is to construct + # variable by hand + except (PandasError, TypeError): + res = [] + labels = [] + for k, v in x.items(): + res.append(v) + labels.append(k) + x = tt.stack(res, axis=1) + if x.ndim == 1: + x = x[:, None] + # case when it can appear to be some + # array like value like lists of lists + # numpy deals with it + elif not isinstance(x, tt.Variable): + x = np.asarray(x) + if x.ndim == 0: + raise ValueError('Cannot use scalars') + elif x.ndim == 1: + x = x[:, None] + # something really strange goes here, + # but user passes labels trusting seems + # to be a good option + elif labels is not None: + x = tt.as_tensor_variable(x) + if x.ndim == 0: + raise ValueError('Cannot use scalars') + elif x.ndim == 1: + x = x[:, None] + else: # trust input + pass + # we should check that we can extract labels + if labels is None and not isinstance(x, tt.Variable): + labels = ['x%d' % i for i in range(x.shape[1])] + # for theano variables we should have labels from user + elif labels is None: + raise ValueError('Please provide labels as ' + 'we cannot infer shape of input') + else: # trust labels, user knows what he is doing + pass + # it's time to check shapes if we can + if not isinstance(x, tt.Variable): + if not len(labels) == x.shape[1]: + raise ValueError( + 'Please provide full list ' + 'of labels for coefficients, ' + 'got len(labels)=%d instead of %d' + % (len(labels), x.shape[1]) + ) + else: + # trust labels, as we raised an + # error in bad case, we have labels + pass + # convert labels to list + if isinstance(labels, pd.RangeIndex): + labels = ['x%d' % i for i in labels] + # maybe it was a tuple ot whatever + elif not isinstance(labels, list): + labels = list(labels) + # as output we need tensor + if not isinstance(x, tt.Variable): + x = tt.as_tensor_variable(x) + # finally check dimensions + if x.ndim == 0: + raise ValueError('Cannot use scalars') + elif x.ndim == 1: + x = x[:, None] + return x, labels diff --git a/pymc3/tests/test_model.py b/pymc3/tests/test_model.py new file mode 100644 index 0000000000..4eb96e6789 --- /dev/null +++ b/pymc3/tests/test_model.py @@ -0,0 +1,120 @@ +import unittest +import theano.tensor as tt +import pymc3 as pm +from pymc3.distributions import HalfCauchy, Normal +from pymc3 import Potential, Deterministic + + +class NewModel(pm.Model): + def __init__(self, name='', model=None): + super(NewModel, self).__init__(name, model) + assert pm.modelcontext(None) is self + # 1) init variables with Var method + self.Var('v1', pm.Normal.dist()) + self.v2 = pm.Normal('v2', mu=0, sd=1) + # 2) Potentials and Deterministic variables with method too + # be sure that names will not overlap with other same models + pm.Deterministic('d', tt.constant(1)) + pm.Potential('p', tt.constant(1)) + + +class DocstringModel(pm.Model): + def __init__(self, mean=0, sd=1, name='', model=None): + super(DocstringModel, self).__init__(name, model) + self.Var('v1', Normal.dist(mu=mean, sd=sd)) + Normal('v2', mu=mean, sd=sd) + Normal('v3', mu=mean, sd=HalfCauchy('sd', beta=10, testval=1.)) + Deterministic('v3_sq', self.v3 ** 2) + Potential('p1', tt.constant(1)) + + +class TestBaseModel(unittest.TestCase): + def test_setattr_properly_works(self): + with pm.Model() as model: + pm.Normal('v1') + self.assertEqual(len(model.vars), 1) + with pm.Model('sub') as submodel: + submodel.Var('v1', pm.Normal.dist()) + self.assertTrue(hasattr(submodel, 'v1')) + self.assertEqual(len(submodel.vars), 1) + self.assertEqual(len(model.vars), 2) + with submodel: + submodel.Var('v2', pm.Normal.dist()) + self.assertTrue(hasattr(submodel, 'v2')) + self.assertEqual(len(submodel.vars), 2) + self.assertEqual(len(model.vars), 3) + + def test_context_passes_vars_to_parent_model(self): + with pm.Model() as model: + # a set of variables is created + NewModel() + # another set of variables are created but with prefix 'another' + usermodel2 = NewModel(name='another') + # you can enter in a context with submodel + with usermodel2: + usermodel2.Var('v3', pm.Normal.dist()) + pm.Normal('v4') + # this variable is created in parent model too + self.assertIn('another_v2', model.named_vars) + self.assertIn('another_v3', model.named_vars) + self.assertIn('another_v3', usermodel2.named_vars) + self.assertIn('another_v4', model.named_vars) + self.assertIn('another_v4', usermodel2.named_vars) + self.assertTrue(hasattr(usermodel2, 'v3')) + self.assertTrue(hasattr(usermodel2, 'v2')) + self.assertTrue(hasattr(usermodel2, 'v4')) + # When you create a class based model you should follow some rules + with model: + m = NewModel('one_more') + self.assertTrue(m.d is model['one_more_d']) + self.assertTrue(m['d'] is model['one_more_d']) + self.assertTrue(m['one_more_d'] is model['one_more_d']) + + +class TestNested(unittest.TestCase): + def test_nest_context_works(self): + with pm.Model() as m: + new = NewModel() + with new: + self.assertTrue( + pm.modelcontext(None) is new + ) + self.assertTrue( + pm.modelcontext(None) is m + ) + self.assertIn('v1', m.named_vars) + self.assertIn('v2', m.named_vars) + + def test_named_context(self): + with pm.Model() as m: + NewModel(name='new') + self.assertIn('new_v1', m.named_vars) + self.assertIn('new_v2', m.named_vars) + + def test_docstring_example1(self): + usage1 = DocstringModel() + self.assertIn('v1', usage1.named_vars) + self.assertIn('v2', usage1.named_vars) + self.assertIn('v3', usage1.named_vars) + self.assertIn('v3_sq', usage1.named_vars) + self.assertTrue(len(usage1.potentials), 1) + + def test_docstring_example2(self): + with pm.Model() as model: + DocstringModel(name='prefix') + self.assertIn('prefix_v1', model.named_vars) + self.assertIn('prefix_v2', model.named_vars) + self.assertIn('prefix_v3', model.named_vars) + self.assertIn('prefix_v3_sq', model.named_vars) + self.assertTrue(len(model.potentials), 1) + + def test_duplicates_detection(self): + with pm.Model(): + DocstringModel(name='prefix') + self.assertRaises(ValueError, DocstringModel, name='prefix') + + def test_model_root(self): + with pm.Model() as model: + self.assertTrue(model is model.root) + with pm.Model() as sub: + self.assertTrue(model is sub.root) diff --git a/pymc3/tests/test_models_linear.py b/pymc3/tests/test_models_linear.py new file mode 100644 index 0000000000..fac66fc0de --- /dev/null +++ b/pymc3/tests/test_models_linear.py @@ -0,0 +1,108 @@ +import numpy as np +from .helpers import SeededTest +from pymc3 import Model, Uniform, Normal, find_MAP, Slice, sample +from pymc3.models.linear import LinearComponent, Glm + + +# Generate data +def generate_data(intercept, slope, size=700): + x = np.linspace(-1, 1, size) + y = intercept + x * slope + return x, y + + +class TestGLM(SeededTest): + @classmethod + def setUpClass(cls): + super(TestGLM, cls).setUpClass() + cls.intercept = 1 + cls.slope = 3 + cls.sd = .05 + x_linear, cls.y_linear = generate_data(cls.intercept, cls.slope, size=1000) + cls.y_linear += np.random.normal(size=1000, scale=cls.sd) + cls.data_linear = dict(x=x_linear, y=cls.y_linear) + + x_logistic, y_logistic = generate_data(cls.intercept, cls.slope, size=3000) + y_logistic = 1 / (1 + np.exp(-y_logistic)) + bern_trials = [np.random.binomial(1, i) for i in y_logistic] + cls.data_logistic = dict(x=x_logistic, y=bern_trials) + + def test_linear_component(self): + vars_to_create = { + 'sigma_interval_', + 'y_obs', + 'lm_x0', + 'lm_Intercept' + } + with Model() as model: + lm = LinearComponent( + self.data_linear['x'], + self.data_linear['y'], + name='lm' + ) # yields lm_x0, lm_Intercept + sigma = Uniform('sigma', 0, 20) # yields sigma_interval_ + Normal('y_obs', mu=lm.y_est, sd=sigma, observed=self.y_linear) # yields y_obs + start = find_MAP(vars=[sigma]) + step = Slice(model.vars) + trace = sample(500, step, start, progressbar=False, random_seed=self.random_seed) + + self.assertAlmostEqual(np.mean(trace['lm_Intercept']), self.intercept, 1) + self.assertAlmostEqual(np.mean(trace['lm_x0']), self.slope, 1) + self.assertAlmostEqual(np.mean(trace['sigma']), self.sd, 1) + self.assertSetEqual(vars_to_create, set(model.named_vars.keys())) + + def test_linear_component_from_formula(self): + with Model() as model: + lm = LinearComponent.from_formula('y ~ x', self.data_linear) + sigma = Uniform('sigma', 0, 20) + Normal('y_obs', mu=lm.y_est, sd=sigma, observed=self.y_linear) + start = find_MAP(vars=[sigma]) + step = Slice(model.vars) + trace = sample(500, step, start, progressbar=False, random_seed=self.random_seed) + + self.assertAlmostEqual(np.mean(trace['Intercept']), self.intercept, 1) + self.assertAlmostEqual(np.mean(trace['x']), self.slope, 1) + self.assertAlmostEqual(np.mean(trace['sigma']), self.sd, 1) + + def test_glm(self): + with Model() as model: + vars_to_create = { + 'glm_sd_log_', + 'glm_y', + 'glm_x0', + 'glm_Intercept' + } + Glm( + self.data_linear['x'], + self.data_linear['y'], + name='glm' + ) + start = find_MAP() + step = Slice(model.vars) + trace = sample(500, step, start, progressbar=False, random_seed=self.random_seed) + self.assertAlmostEqual(np.mean(trace['glm_Intercept']), self.intercept, 1) + self.assertAlmostEqual(np.mean(trace['glm_x0']), self.slope, 1) + self.assertAlmostEqual(np.mean(trace['glm_sd']), self.sd, 1) + self.assertSetEqual(vars_to_create, set(model.named_vars.keys())) + + def test_glm_from_formula(self): + with Model() as model: + NAME = 'glm' + Glm.from_formula('y ~ x', self.data_linear, name=NAME) + start = find_MAP() + step = Slice(model.vars) + trace = sample(500, step, start, progressbar=False, random_seed=self.random_seed) + + self.assertAlmostEqual(np.mean(trace['%s_Intercept' % NAME]), self.intercept, 1) + self.assertAlmostEqual(np.mean(trace['%s_x' % NAME]), self.slope, 1) + self.assertAlmostEqual(np.mean(trace['%s_sd' % NAME]), self.sd, 1) + + def test_strange_types(self): + with Model(): + self.assertRaises( + ValueError, + Glm, + 1, + self.data_linear['y'], + name='lm' + ) diff --git a/pymc3/tests/test_models_utils.py b/pymc3/tests/test_models_utils.py new file mode 100644 index 0000000000..160846bcbc --- /dev/null +++ b/pymc3/tests/test_models_utils.py @@ -0,0 +1,79 @@ +import unittest +import numpy as np +import pandas as pd +import theano.tensor as tt +import pymc3.models.utils as utils + + +class TestUtils(unittest.TestCase): + def setUp(self): + self.data = pd.DataFrame(dict(a=[1, 2, 3], b=[4, 5, 6])) + + def assertMatrixLabels(self, m, l, mt=None, lt=None): + self.assertTrue( + np.all( + np.equal( + m.eval(), + mt if mt is not None else self.data.as_matrix() + ) + ) + ) + self.assertEqual(l, list(lt or self.data.columns)) + + def test_numpy_init(self): + m, l = utils.any_to_tensor_and_labels(self.data.as_matrix()) + self.assertMatrixLabels(m, l, lt=['x0', 'x1']) + m, l = utils.any_to_tensor_and_labels(self.data.as_matrix(), labels=['x2', 'x3']) + self.assertMatrixLabels(m, l, lt=['x2', 'x3']) + + def test_pandas_init(self): + m, l = utils.any_to_tensor_and_labels(self.data) + self.assertMatrixLabels(m, l) + m, l = utils.any_to_tensor_and_labels(self.data, labels=['x2', 'x3']) + self.assertMatrixLabels(m, l, lt=['x2', 'x3']) + + def test_dict_input(self): + m, l = utils.any_to_tensor_and_labels(self.data.to_dict('dict')) + self.assertMatrixLabels(m, l, mt=self.data.as_matrix(l), lt=l) + + m, l = utils.any_to_tensor_and_labels(self.data.to_dict('series')) + self.assertMatrixLabels(m, l, mt=self.data.as_matrix(l), lt=l) + + m, l = utils.any_to_tensor_and_labels(self.data.to_dict('list')) + self.assertMatrixLabels(m, l, mt=self.data.as_matrix(l), lt=l) + + inp = {k: tt.as_tensor_variable(v) for k, v in self.data.to_dict('series').items()} + m, l = utils.any_to_tensor_and_labels(inp) + self.assertMatrixLabels(m, l, mt=self.data.as_matrix(l), lt=l) + + def test_list_input(self): + m, l = utils.any_to_tensor_and_labels(self.data.as_matrix().tolist()) + self.assertMatrixLabels(m, l, lt=['x0', 'x1']) + m, l = utils.any_to_tensor_and_labels(self.data.as_matrix().tolist(), labels=['x2', 'x3']) + self.assertMatrixLabels(m, l, lt=['x2', 'x3']) + + def test_tensor_input(self): + m, l = utils.any_to_tensor_and_labels( + tt.as_tensor_variable(self.data.as_matrix().tolist()), + labels=['x0', 'x1'] + ) + self.assertMatrixLabels(m, l, lt=['x0', 'x1']) + m, l = utils.any_to_tensor_and_labels( + tt.as_tensor_variable(self.data.as_matrix().tolist()), + labels=['x2', 'x3']) + self.assertMatrixLabels(m, l, lt=['x2', 'x3']) + + def test_user_mistakes(self): + # no labels for tensor variable + self.assertRaises( + ValueError, + utils.any_to_tensor_and_labels, + tt.as_tensor_variable(self.data.as_matrix().tolist()) + ) + # len of labels is bad + self.assertRaises( + ValueError, + utils.any_to_tensor_and_labels, + self.data.as_matrix().tolist(), + labels=['x'] + ) diff --git a/requirements.txt b/requirements.txt index fc6625c5d9..2e53afc286 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ recommonmark sphinx nbsphinx numpydoc +six diff --git a/setup.py b/setup.py index 708cfb1006..017c28898a 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ DISTNAME = 'pymc3' DESCRIPTION = "PyMC3" -LONG_DESCRIPTION = """Bayesian estimation, particularly using Markov chain Monte Carlo (MCMC), is an increasingly relevant approach to statistical estimation. However, few statistical software packages implement MCMC samplers, and they are non-trivial to code by hand. ``pymc3`` is a python package that implements the Metropolis-Hastings algorithm as a python class, and is extremely flexible and applicable to a large suite of problems. ``pymc3`` includes methods for summarizing output, plotting, goodness-of-fit and convergence diagnostics.""" +LONG_DESCRIPTION = """Bayesian estimation, particularly using Markov chain Monte Carlo (MCMC), is an increasingly relevant approach to statistical estimation. However, few statistical software packages implement MCMC samplers, and they are non-trivial to code by hand. ``pymc3`` is a python package that implements the Metropolis-Hastings algorithm as a python class, and is extremely flexible and applicable to a large suite of problems. ``pymc3`` includes methods for summarizing output, plotting, goodness-of-fit and convergence diagnostics.""" MAINTAINER = 'Thomas Wiecki' MAINTAINER_EMAIL = 'thomas.wiecki@gmail.com' AUTHOR = 'John Salvatier and Christopher Fonnesbeck' @@ -50,7 +50,8 @@ packages=['pymc3', 'pymc3.distributions', 'pymc3.step_methods', 'pymc3.tuning', 'pymc3.tests', 'pymc3.glm', 'pymc3.examples', - 'pymc3.backends', 'pymc3.variational', 'docs', '.'], + 'pymc3.models', 'pymc3.backends', + 'pymc3.variational', 'docs', '.'], classifiers=classifiers, install_requires=install_reqs, tests_require=test_reqs, From 9ab04da997391bf0f3f8ce0da715572900bacb2b Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sun, 4 Dec 2016 16:58:25 +0300 Subject: [PATCH 05/83] added new elbo implementation --- pymc3/distributions/dist_math.py | 38 ++++++++++++ pymc3/theanof.py | 38 +++++++++++- pymc3/variational/elbo.py | 70 +++++++++++++++++++++ pymc3/variational/utils.py | 103 +++++++++++++++++++++++++++++++ 4 files changed, 247 insertions(+), 2 deletions(-) create mode 100644 pymc3/variational/elbo.py create mode 100644 pymc3/variational/utils.py diff --git a/pymc3/distributions/dist_math.py b/pymc3/distributions/dist_math.py index 997d00eef2..7e99bf4252 100644 --- a/pymc3/distributions/dist_math.py +++ b/pymc3/distributions/dist_math.py @@ -10,6 +10,8 @@ from .special import gammaln, multigammaln +c = - 0.5 * np.log(2 * np.pi) + def bound(logp, *conditions): """ @@ -77,3 +79,39 @@ def i1(x): x**9 / 1474560 + x**11 / 176947200 + x**13 / 29727129600, np.e**x / (2 * np.pi * x)**0.5 * (1 - 3 / (8 * x) + 15 / (128 * x**2) + 315 / (3072 * x**3) + 14175 / (98304 * x**4))) + + +def sd2rho(sd): + """sd -> rho + theano converter + mu + sd*e = mu + log(1+exp(rho))*e""" + return tt.log(tt.exp(sd) - 1) + + +def rho2sd(rho): + """rho -> sd + theano converter + mu + sd*e = mu + log(1+exp(rho))*e""" + return tt.log1p(tt.exp(rho)) + + +def kl_divergence_normal_pair(mu1, mu2, sd1, sd2): + elemwise_kl = (tt.log(sd2/sd1) + + (sd2**2 + (mu1-mu2)**2)/(2.*sd2**2) - + 0.5) + return tt.sum(elemwise_kl) + + +def kl_divergence_normal_pair3(mu1, mu2, rho1, rho2): + sd1, sd2 = rho2sd(rho1), rho2sd(rho2) + return kl_divergence_normal_pair(mu1, mu2, sd1, sd2) + + +def log_normal(x, mean, std, eps=0.0): + std += eps + return c - tt.log(tt.abs_(std)) - (x - mean) ** 2 / (2 * std ** 2) + + +def log_normal3(x, mean, rho, eps=0.0): + std = rho2sd(rho) + return log_normal(x, mean, std, eps) diff --git a/pymc3/theanof.py b/pymc3/theanof.py index 04289aabbb..c56bc5edd8 100644 --- a/pymc3/theanof.py +++ b/pymc3/theanof.py @@ -3,9 +3,19 @@ from theano.gof.graph import inputs from .memoize import memoize from .blocking import ArrayOrdering +from theano.sandbox.rng_mrg import MRG_RandomStreams -__all__ = ['gradient', 'hessian', 'hessian_diag', 'inputvars', 'cont_inputs', - 'jacobian', 'CallableTensor', 'join_nonshared_inputs', 'make_shared_replacements'] +__all__ = ['gradient', + 'hessian', + 'hessian_diag', + 'inputvars', + 'cont_inputs', + 'jacobian', + 'CallableTensor', + 'join_nonshared_inputs', + 'make_shared_replacements', + 'tt_rng', + 'set_tt_rng'] def inputvars(a): @@ -229,3 +239,27 @@ def __call__(self, input): scalar_identity = IdentityOp(scalar.upgrade_to_float, name='scalar_identity') identity = tt.Elemwise(scalar_identity, name='identity') + +_tt_rng = MRG_RandomStreams() + + +def tt_rng(): + """Get the package-level random number generator. + Returns + ------- + :class:`theano.sandbox.rng_mrg.MRG_RandomStreams` instance + The :class:`theano.sandbox.rng_mrg.MRG_RandomStreams` + instance passed to the most recent call of :func:`set_tt_rng` + """ + return _tt_rng + + +def set_tt_rng(new_rng): + """Set the package-level random number generator. + Parameters + ---------- + new_rng : :class:`theano.sandbox.rng_mrg.MRG_RandomStreams` instance + The random number generator to use. + """ + global _tt_rng + _tt_rng = new_rng diff --git a/pymc3/variational/elbo.py b/pymc3/variational/elbo.py new file mode 100644 index 0000000000..8b7c908742 --- /dev/null +++ b/pymc3/variational/elbo.py @@ -0,0 +1,70 @@ +import theano.tensor as tt +import theano +from .utils import (variational_replacements, + apply_replacements, + flatten) +from ..distributions.dist_math import log_normal3 + +__all__ = [ + 'sample_elbo' +] + + +def sample_elbo(model, population=None, samples=1, pi=1, vp=None): + """ pi*KL[q(w|mu,rho)||p(w)] + E_q[log p(D|w)] + approximated by Monte Carlo sampling + + Parameters + ---------- + model : pymc3.Model + population : dict - maps observed_RV to its population size + if not provided defaults to full population + samples : number of Monte Carlo samples used for approximation, + defaults to 1 + pi : additional coefficient for KL[q(w|mu,rho)||p(w)] as proposed in [1]_ + vp : gelato.variational.utils.VariatioanalParams + tuple, holding nodes mappings with shared params, if None - new + will be created + + Returns + ------- + (elbos, updates, VariationalParams) + sampled elbos, updates for random streams, shared dicts + + Notes + ----- + You can pass tensors for `pi` and `samples` to control them while + training + + References + ---------- + .. [1] Charles Blundell et al: "Weight Uncertainty in Neural Networks" + arXiv preprint arXiv:1505.05424 + """ + if population is None: + population = dict() + if vp is None: + vp = variational_replacements(model.root) + x = flatten(vp.mapping.values()) + mu = flatten(vp.shared.means.values()) + rho = flatten(vp.shared.rhos.values()) + + def likelihood(var): + tot = population.get(var, population.get(var.name)) + logpt = tt.sum(var.logpt) + if tot is not None: + tot = tt.as_tensor(tot) + logpt *= tot / var.shape[0] + return logpt + + log_p_D = tt.add(*map(likelihood, model.root.observed_RVs)) + log_p_W = model.root.varlogpt + tt.sum(model.root.potentials) + log_q_W = tt.sum(log_normal3(x, mu, rho)) + _elbo_ = log_p_D + pi * (log_p_W - log_q_W) + _elbo_ = apply_replacements(_elbo_, vp) + + samples = tt.as_tensor(samples) + elbos, updates = theano.scan(fn=lambda: _elbo_, + outputs_info=None, + n_steps=samples) + return elbos, updates, vp diff --git a/pymc3/variational/utils.py b/pymc3/variational/utils.py new file mode 100644 index 0000000000..8e102b286b --- /dev/null +++ b/pymc3/variational/utils.py @@ -0,0 +1,103 @@ +from collections import namedtuple, OrderedDict + +import numpy as np +import theano +import theano.tensor as tt +from ..distributions.dist_math import rho2sd +from ..theanof import tt_rng + +SharedNodes = namedtuple('SharedNodes', 'means, rhos') + + +class VariationalParams(namedtuple('VariationalParamsBase', 'mapping,shared')): + @property + def params(self): + return list(self.shared.means.values())+list(self.shared.rhos.values()) + + +def random_node(old): + """Creates random node with shared params + + Parameters + ---------- + old : pm.FreeRV + + Returns + ------- + tuple : (new node, shared mu, shared rho) + """ + if len(old.broadcastable) > 0: + rho = theano.shared( + np.ones(old.tag.test_value.shape), + name='{}_rho_shared'.format(old.name), + broadcastable=old.broadcastable) + mu = theano.shared( + old.tag.test_value, + name='{}_mu_shared'.format(old.name), + broadcastable=old.broadcastable) + e = tt.patternbroadcast( + tt_rng().normal(rho.shape), old.broadcastable) + else: + rho = theano.shared( + np.ones(old.tag.test_value.shape), + name='{}_rho_shared'.format(old.name)) + mu = theano.shared( + old.tag.test_value, + name='{}_mu_shared'.format(old.name)) + e = tt_rng().normal(rho.shape) + return mu + rho2sd(rho) * e, mu, rho + + +def variational_replacements(model): + """Util for getting variational replacements + + Parameters + ---------- + model : pymc3.Model + + Returns + ------- + VariationalParams : (mapping, SharedNodes) + + Notes + ----- + Mappings and shared vars dicts are all OrderedDicts + """ + replacements = OrderedDict() + means = OrderedDict() + rhos = OrderedDict() + for var in model.vars: + v, mu, rho = random_node(var) + replacements[var] = v + means[var.name] = mu + rhos[var.name] = rho + return VariationalParams(replacements, SharedNodes(means, rhos)) + + +def apply_replacements(out, variational_params, deterministic=False): + """ + + Parameters + ---------- + out : target node of the graph for which we apply replacements + variational_params : VariationalParams + deterministic : bool - whether do deterministic or stochastic replacements + + Returns + ------- + tt.Variable + cloned node with applied replacements + """ + if deterministic: + replacements = OrderedDict(zip( + variational_params.mapping.keys(), + variational_params.shared.means.values() + )) + else: + replacements = variational_params.mapping + return theano.clone(out, replacements, strict=False) + + +def flatten(tensors): + joined = tt.concatenate([var.ravel() for var in tensors]) + return joined From 9811220e18ccec6a3f8d825b49a1167a2aa54b7a Mon Sep 17 00:00:00 2001 From: Chris Fonnesbeck Date: Thu, 17 Nov 2016 13:43:51 -0500 Subject: [PATCH 06/83] Added mode argument to several step methods and advi to allow mode setting (e.g. nanguardmode) for Theano functions --- pymc3/step_methods/metropolis.py | 7 +++++-- pymc3/step_methods/nuts.py | 11 ++++++++--- pymc3/variational/advi.py | 9 ++++++--- pymc3/variational/advi_minibatch.py | 7 +++++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/pymc3/step_methods/metropolis.py b/pymc3/step_methods/metropolis.py index 4baa8f3827..e9afe28cd3 100644 --- a/pymc3/step_methods/metropolis.py +++ b/pymc3/step_methods/metropolis.py @@ -66,7 +66,8 @@ class Metropolis(ArrayStepShared): The frequency of tuning. Defaults to 100 iterations. model : PyMC Model Optional model for sampling step. Defaults to None (taken from context). - + mode : string or `Mode` instance. + compilation mode passed to Theano functions """ default_blocked = False @@ -93,6 +94,8 @@ def __init__(self, vars=None, S=None, proposal_dist=NormalProposal, scaling=1., [[v.dtype in pm.discrete_types] * (v.dsize or 1) for v in vars]) self.any_discrete = self.discrete.any() self.all_discrete = self.discrete.all() + + self.mode = mode shared = pm.make_shared_replacements(vars, model) self.delta_logp = delta_logp(model.logpt, vars, shared) @@ -430,6 +433,6 @@ def delta_logp(logp, vars, shared): logp1 = pm.CallableTensor(logp0)(inarray1) - f = theano.function([inarray1, inarray0], logp1 - logp0) + f = theano.function([inarray1, inarray0], logp1 - logp0, mode=self.mode) f.trust_input = True return f diff --git a/pymc3/step_methods/nuts.py b/pymc3/step_methods/nuts.py index b72813156d..17404fb1e4 100644 --- a/pymc3/step_methods/nuts.py +++ b/pymc3/step_methods/nuts.py @@ -32,7 +32,8 @@ def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, state k=0.75, t0=10, model=None, - profile=False, **kwargs): + profile=False, + mode=None, **kwargs): """ Parameters ---------- @@ -57,6 +58,8 @@ def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, state model : Model profile : bool or ProfileStats sets the functions to be profiled + mode : string or `Mode` instance. + compilation mode passed to Theano functions """ model = modelcontext(model) @@ -90,6 +93,7 @@ def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, state self.Hbar = 0 self.u = log(self.step_size * 10) self.m = 1 + self.mode = mode shared = make_shared_replacements(vars, model) @@ -106,7 +110,7 @@ def create_energy_func(q): p = tt.dvector('p') p.tag.test_value = q.tag.test_value E0 = energy(self.H, q, p) - E0_func = theano.function([q, p], E0) + E0_func = theano.function([q, p], E0, mode=self.mode) E0_func.trust_input = True return E0_func @@ -227,6 +231,7 @@ def leapfrog1_dE(H, q, profile): dE = E - E0 - f = theano.function([q, p, e, E0], [q1, p1, dE], profile=profile) + f = theano.function([q, p, e, E0], [q1, p1, dE], + profile=profile, mode=self.mode) f.trust_input = True return f diff --git a/pymc3/variational/advi.py b/pymc3/variational/advi.py index 67889529b0..a89195e085 100644 --- a/pymc3/variational/advi.py +++ b/pymc3/variational/advi.py @@ -36,7 +36,8 @@ def gen_random_state(): def advi(vars=None, start=None, model=None, n=5000, accurate_elbo=False, - optimizer=None, learning_rate=.001, epsilon=.1, random_seed=None): + optimizer=None, learning_rate=.001, epsilon=.1, mode=None, + random_seed=None): """Perform automatic differentiation variational inference (ADVI). This function implements the meanfield ADVI, where the variational @@ -87,7 +88,9 @@ def advi(vars=None, start=None, model=None, n=5000, accurate_elbo=False, This parameter is ignored when optimizer is given. random_seed : int or None Seed to initialize random state. None uses current seed. - + mode : string or `Mode` instance. + Compilation mode passed to Theano functions + Returns ------- ADVIFit @@ -137,7 +140,7 @@ def advi(vars=None, start=None, model=None, n=5000, accurate_elbo=False, uw_shared = theano.shared(uw, 'uw_shared') elbo = pm.CallableTensor(elbo)(uw_shared) updates = optimizer(loss=-1 * elbo, param=[uw_shared]) - f = theano.function([], [uw_shared, elbo], updates=updates) + f = theano.function([], [uw_shared, elbo], updates=updates, mode=mode) # Optimization loop elbos = np.empty(n) diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index 79ed5a0638..097ff16825 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -207,7 +207,8 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, minibatch_RVs=None, minibatch_tensors=None, minibatches=None, local_RVs=None, observed_RVs=None, encoder_params=[], total_size=None, optimizer=None, - learning_rate=.001, epsilon=.1, random_seed=None): + learning_rate=.001, epsilon=.1, random_seed=None, + mode=None): """Perform mini-batch ADVI. This function implements a mini-batch ADVI with the meanfield @@ -297,6 +298,8 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, This parameter is ignored when an optimizer is given. random_seed : int Seed to initialize random state. + mode : string or `Mode` instance. + compilation mode passed to Theano functions Returns ------- @@ -382,7 +385,7 @@ def is_shared(t): if 0 < len(global_RVs): params += [uw_global_shared] updates = OrderedDict(optimizer(loss=-1 * elbo, param=params)) - f = theano.function(tensors, elbo, updates=updates) + f = theano.function(tensors, elbo, updates=updates, mode=mode) # Optimization loop elbos = np.empty(n) From fbd1d5b97424470da4e939751d930dc06761b6a6 Mon Sep 17 00:00:00 2001 From: Chris Fonnesbeck Date: Thu, 17 Nov 2016 14:25:18 -0500 Subject: [PATCH 07/83] Fixed namespace bugs in mode attribute --- pymc3/step_methods/metropolis.py | 2 +- pymc3/step_methods/nuts.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pymc3/step_methods/metropolis.py b/pymc3/step_methods/metropolis.py index e9afe28cd3..4fcbdc7866 100644 --- a/pymc3/step_methods/metropolis.py +++ b/pymc3/step_methods/metropolis.py @@ -72,7 +72,7 @@ class Metropolis(ArrayStepShared): default_blocked = False def __init__(self, vars=None, S=None, proposal_dist=NormalProposal, scaling=1., - tune=True, tune_interval=100, model=None, **kwargs): + tune=True, tune_interval=100, model=None, mode=None, **kwargs): model = pm.modelcontext(model) diff --git a/pymc3/step_methods/nuts.py b/pymc3/step_methods/nuts.py index 17404fb1e4..84bb3a90ba 100644 --- a/pymc3/step_methods/nuts.py +++ b/pymc3/step_methods/nuts.py @@ -118,7 +118,8 @@ def create_energy_func(q): self.H, q = create_hamiltonian(vars, shared, model) self.compute_energy = create_energy_func(q) - self.leapfrog1_dE = leapfrog1_dE(self.H, q, profile=profile) + self.leapfrog1_dE = leapfrog1_dE(self.H, q, profile=profile, + mode=self.mode) super(NUTS, self).__init__(vars, shared, **kwargs) @@ -204,7 +205,7 @@ def buildtree(leapfrog1_dE, q, p, u, v, j, e, Emax, E0): return -def leapfrog1_dE(H, q, profile): +def leapfrog1_dE(H, q, profile, mode): """Computes a theano function that computes one leapfrog step and the energy difference between the beginning and end of the trajectory. Parameters ---------- @@ -232,6 +233,6 @@ def leapfrog1_dE(H, q, profile): dE = E - E0 f = theano.function([q, p, e, E0], [q1, p1, dE], - profile=profile, mode=self.mode) + profile=profile, mode=mode) f.trust_input = True return f From 208aa790ccff63180c751f5f287fb934979c9867 Mon Sep 17 00:00:00 2001 From: Chris Fonnesbeck Date: Thu, 17 Nov 2016 16:40:37 -0500 Subject: [PATCH 08/83] Reverted function in delta_logp to not accept mode argument --- pymc3/step_methods/metropolis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/step_methods/metropolis.py b/pymc3/step_methods/metropolis.py index 4fcbdc7866..c2ab7260ca 100644 --- a/pymc3/step_methods/metropolis.py +++ b/pymc3/step_methods/metropolis.py @@ -433,6 +433,6 @@ def delta_logp(logp, vars, shared): logp1 = pm.CallableTensor(logp0)(inarray1) - f = theano.function([inarray1, inarray0], logp1 - logp0, mode=self.mode) + f = theano.function([inarray1, inarray0], logp1 - logp0) f.trust_input = True return f From 40d014674a1772daea313a86518ba90d47249ca7 Mon Sep 17 00:00:00 2001 From: Maxim Date: Mon, 28 Nov 2016 07:38:18 +0300 Subject: [PATCH 09/83] ENH User model (#1525) * Started to write Base class for pymc3.models * mode `add_var` to public api * Added some docstrings * Added some docstrings * added getitem and fixed a typo * added assertion check * added resolve var method * decided not to add resolve method * Added linear component * Docs fix * patsy's intercept is inited properly now * refactored code * updated docs * added possibility to init coefficients with random variables * added glm * refactored api, fixed formula init * refactored linear model, extended acceptable types * moved useful matrix and labels creation to utils file * code style * removed redundant evaluation of shape * refactored resolver for constructing matrix and labels * changed error message * changed signature of init * simplified utils any_to_tensor_and_labels code * tests for `any_to_tensor_and_labels` * added docstring for `any_to_tensor_and_labels` util * forgot to document return type in `any_to_tensor_and_labels` * refactored code for dict * dict tests fix(do not check labels there) * added access to random vars of model * added a shortcut for all variables so there is a unified way to get them * added default priors for linear model * update docs for linear * refactored UserModel api, made it more similar to pm.Model class * Lots of refactoring, tests for base class, more plain api design * deleted unused module variable * fixed some typos in docstring * Refactored pm.Model class, now it is ready for inheritance * Added documentation for Model class * Small typo in docstring * nested contains for treedict (needed for add_random_variable) * More accurate duplicate implementation of treedict/treelist * refactored treedict/treelist * changed `__imul__` of treelist * added `root` property and `isroot` indicator for base model * protect `parent` and `model` attributes from violation * travis' python2 did not fail on bad syntax(maybe it's too new), fixed * decided not to use functools wrapper Unfortunately functools wrapper fails when decorating built-in methods so I need to fix that improper behaviour. Some bad but needed tricks were implemented * Added models package to setup script * Refactor utils * Fix some typos in pm.model --- pymc3/model.py | 272 +++++++++++++++++++++++++++--- pymc3/models/__init__.py | 6 + pymc3/models/linear.py | 134 +++++++++++++++ pymc3/models/utils.py | 126 ++++++++++++++ pymc3/tests/test_model.py | 120 +++++++++++++ pymc3/tests/test_models_linear.py | 108 ++++++++++++ pymc3/tests/test_models_utils.py | 79 +++++++++ requirements.txt | 1 + setup.py | 5 +- 9 files changed, 829 insertions(+), 22 deletions(-) create mode 100644 pymc3/models/__init__.py create mode 100644 pymc3/models/linear.py create mode 100644 pymc3/models/utils.py create mode 100644 pymc3/tests/test_model.py create mode 100644 pymc3/tests/test_models_linear.py create mode 100644 pymc3/tests/test_models_utils.py diff --git a/pymc3/model.py b/pymc3/model.py index d28f2340e0..ee335d7941 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -1,5 +1,5 @@ import threading - +import six import numpy as np import theano import theano.tensor as tt @@ -172,17 +172,215 @@ def logpt(self): return tt.sum(self.logp_elemwiset) -class Model(Context, Factor): - """Encapsulates the variables and likelihood factors of a model.""" +class InitContextMeta(type): + """Metaclass that executes `__init__` of instance in it's context""" + def __call__(cls, *args, **kwargs): + instance = cls.__new__(cls, *args, **kwargs) + with instance: # appends context + instance.__init__(*args, **kwargs) + return instance + + +def withparent(meth): + """Helper wrapper that passes calls to parent's instance""" + def wrapped(self, *args, **kwargs): + res = meth(self, *args, **kwargs) + if getattr(self, 'parent', None) is not None: + getattr(self.parent, meth.__name__)(*args, **kwargs) + return res + # Unfortunately functools wrapper fails + # when decorating built-in methods so we + # need to fix that improper behaviour + wrapped.__name__ = meth.__name__ + return wrapped + + +class treelist(list): + """A list that passes mutable extending operations used in Model + to parent list instance. + Extending treelist you will also extend its parent + """ + def __init__(self, iterable=(), parent=None): + super(treelist, self).__init__(iterable) + assert isinstance(parent, list) or parent is None + self.parent = parent + if self.parent is not None: + self.parent.extend(self) + # typechecking here works bad + append = withparent(list.append) + __iadd__ = withparent(list.__iadd__) + extend = withparent(list.extend) + + def tree_contains(self, item): + if isinstance(self.parent, treedict): + return (list.__contains__(self, item) or + self.parent.tree_contains(item)) + elif isinstance(self.parent, list): + return (list.__contains__(self, item) or + self.parent.__contains__(item)) + else: + return list.__contains__(self, item) + + def __setitem__(self, key, value): + raise NotImplementedError('Method is removed as we are not' + ' able to determine ' + 'appropriate logic for it') + + def __imul__(self, other): + t0 = len(self) + list.__imul__(self, other) + if self.parent is not None: + self.parent.extend(self[t0:]) + + +class treedict(dict): + """A dict that passes mutable extending operations used in Model + to parent dict instance. + Extending treedict you will also extend its parent + """ + def __init__(self, iterable=(), parent=None, **kwargs): + super(treedict, self).__init__(iterable, **kwargs) + assert isinstance(parent, dict) or parent is None + self.parent = parent + if self.parent is not None: + self.parent.update(self) + # typechecking here works bad + __setitem__ = withparent(dict.__setitem__) + update = withparent(dict.update) + + def tree_contains(self, item): + # needed for `add_random_variable` method + if isinstance(self.parent, treedict): + return (dict.__contains__(self, item) or + self.parent.tree_contains(item)) + elif isinstance(self.parent, dict): + return (dict.__contains__(self, item) or + self.parent.__contains__(item)) + else: + return dict.__contains__(self, item) + + +class Model(six.with_metaclass(InitContextMeta, Context, Factor)): + """Encapsulates the variables and likelihood factors of a model. + + Model class can be used for creating class based models. To create + a class based model you should inherit from `Model` and + override `__init__` with arbitrary definitions + (do not forget to call base class `__init__` first). + + Parameters + ---------- + name : str, default '' - name that will be used as prefix for + names of all random variables defined within model + model : Model, default None - instance of Model that is + supposed to be a parent for the new instance. If None, + context will be used. All variables defined within instance + will be passed to the parent instance. So that 'nested' model + contributes to the variables and likelihood factors of + parent model. + + Examples + -------- + # How to define a custom model + class CustomModel(Model): + # 1) override init + def __init__(self, mean=0, sd=1, name='', model=None): + # 2) call super's init first, passing model and name to it + # name will be prefix for all variables here + # if no name specified for model there will be no prefix + super(CustomModel, self).__init__(name, model) + # now you are in the context of instance, + # `modelcontext` will return self + # you can define variables in several ways + # note, that all variables will get model's name prefix + + # 3) you can create variables with Var method + self.Var('v1', Normal.dist(mu=mean, sd=sd)) + # this will create variable named like '{prefix_}v1' + # and assign attribute 'v1' to instance + # created variable can be accessed with self.v1 or self['v1'] + + # 4) this syntax will also work as we are in the context + # of instance itself, names are given as usual + Normal('v2', mu=mean, sd=sd) + + # something more complex is allowed too + Normal('v3', mu=mean, sd=HalfCauchy('sd', beta=10, testval=1.)) + + # Deterministic variables can be used in usual way + Deterministic('v3_sq', self.v3 ** 2) + # Potentials too + Potential('p1', tt.constant(1)) + + # After defining a class CustomModel you can use it in several ways + + # I: + # state the model within a context + with Model() as model: + CustomModel() + # arbitrary actions + + # II: + # use new class as entering point in context + with CustomModel() as model: + Normal('new_normal_var', mu=1, sd=0) + + # III: + # just get model instance with all that was defined in it + model = CustomModel() + + # IV: + # use many custom models within one context + with Model() as model: + CustomModel(mean=1, name='first') + CustomModel(mean=2, name='second') + """ + def __new__(cls, *args, **kwargs): + # resolves the parent instance + instance = object.__new__(cls) + if kwargs.get('model') is not None: + instance._parent = kwargs.get('model') + elif cls.get_contexts(): + instance._parent = cls.get_contexts()[-1] + else: + instance._parent = None + return instance + + def __init__(self, name='', model=None): + self.name = name + if self.parent is not None: + self.named_vars = treedict(parent=self.parent.named_vars) + self.free_RVs = treelist(parent=self.parent.free_RVs) + self.observed_RVs = treelist(parent=self.parent.observed_RVs) + self.deterministics = treelist(parent=self.parent.deterministics) + self.potentials = treelist(parent=self.parent.potentials) + self.missing_values = treelist(parent=self.parent.missing_values) + else: + self.named_vars = treedict() + self.free_RVs = treelist() + self.observed_RVs = treelist() + self.deterministics = treelist() + self.potentials = treelist() + self.missing_values = treelist() + + @property + def model(self): + return self + + @property + def parent(self): + return self._parent + + @property + def root(self): + model = self + while not model.isroot: + model = model.parent + return model - def __init__(self): - self.named_vars = {} - self.free_RVs = [] - self.observed_RVs = [] - self.deterministics = [] - self.potentials = [] - self.missing_values = [] - self.model = self + @property + def isroot(self): + return self.parent is None @property @memoize @@ -275,6 +473,7 @@ def Var(self, name, dist, data=None): ------- FreeRV or ObservedRV """ + name = self.name_for(name) if data is None: if getattr(dist, "transform", None) is None: var = FreeRV(name=name, distribution=dist, model=self) @@ -312,15 +511,46 @@ def Var(self, name, dist, data=None): def add_random_variable(self, var): """Add a random variable to the named variables of the model.""" - if var.name in self.named_vars: + if self.named_vars.tree_contains(var.name): raise ValueError( "Variable name {} already exists.".format(var.name)) self.named_vars[var.name] = var - if not hasattr(self, var.name): - setattr(self, var.name, var) + if not hasattr(self, self.name_of(var.name)): + setattr(self, self.name_of(var.name), var) + + @property + def prefix(self): + return '%s_' % self.name if self.name else '' + + def name_for(self, name): + """Checks if name has prefix and adds if needed + """ + if self.prefix: + if not name.startswith(self.prefix): + return '{}{}'.format(self.prefix, name) + else: + return name + else: + return name + + def name_of(self, name): + """Checks if name has prefix and deletes if needed + """ + if not self.prefix or not name: + return name + elif name.startswith(self.prefix): + return name[len(self.prefix):] + else: + return name def __getitem__(self, key): - return self.named_vars[key] + try: + return self.named_vars[key] + except KeyError as e: + try: + return self.named_vars[self.name_for(key)] + except KeyError: + raise e @memoize def makefn(self, outs, mode=None, *args, **kwargs): @@ -637,9 +867,10 @@ def Deterministic(name, var, model=None): ------- n : var but with name name """ - var.name = name - modelcontext(model).deterministics.append(var) - modelcontext(model).add_random_variable(var) + model = modelcontext(model) + var.name = model.name_for(name) + model.deterministics.append(var) + model.add_random_variable(var) return var @@ -655,8 +886,9 @@ def Potential(name, var, model=None): ------- var : var, with name attribute """ - var.name = name - modelcontext(model).potentials.append(var) + model = modelcontext(model) + var.name = model.name_for(name) + model.potentials.append(var) return var diff --git a/pymc3/models/__init__.py b/pymc3/models/__init__.py new file mode 100644 index 0000000000..17e6772687 --- /dev/null +++ b/pymc3/models/__init__.py @@ -0,0 +1,6 @@ +from .linear import LinearComponent, Glm + +__all__ = [ + 'LinearComponent', + 'Glm' +] diff --git a/pymc3/models/linear.py b/pymc3/models/linear.py new file mode 100644 index 0000000000..b6a224f2b4 --- /dev/null +++ b/pymc3/models/linear.py @@ -0,0 +1,134 @@ +import theano.tensor as tt +import pandas as pd +import numpy as np +from ..distributions import Normal, Flat +from ..glm import families +from ..model import Model, Deterministic +from .utils import any_to_tensor_and_labels + +__all__ = [ + 'LinearComponent', + 'Glm' +] + + +class LinearComponent(Model): + """Creates linear component, y_est is accessible via attribute + Parameters + ---------- + name : str - name, associated with the linear component + x : pd.DataFrame or np.ndarray + y : pd.Series or np.array + intercept : bool - fit with intercept or not? + labels : list - replace variable names with these labels + priors : dict - priors for coefficients + use `Intercept` key for defining Intercept prior + defaults to Flat.dist() + use `Regressor` key for defining default prior for all regressors + defaults to Normal.dist(mu=0, tau=1.0E-6) + vars : dict - random variables instead of creating new ones + """ + default_regressor_prior = Normal.dist(mu=0, tau=1.0E-6) + default_intercept_prior = Flat.dist() + + def __init__(self, x, y, intercept=True, labels=None, + priors=None, vars=None, name='', model=None): + super(LinearComponent, self).__init__(name, model) + if priors is None: + priors = {} + if vars is None: + vars = {} + x, labels = any_to_tensor_and_labels(x, labels) + # now we have x, shape and labels + if intercept: + x = tt.concatenate( + [tt.ones((x.shape[0], 1), x.dtype), x], + axis=1 + ) + labels = ['Intercept'] + labels + coeffs = list() + for name in labels: + if name == 'Intercept': + if name in vars: + v = Deterministic(name, vars[name]) + else: + v = self.Var( + name=name, + dist=priors.get( + name, + self.default_intercept_prior + ) + ) + coeffs.append(v) + else: + if name in vars: + v = Deterministic(name, vars[name]) + else: + v = self.Var( + name=name, + dist=priors.get( + name, + priors.get( + 'Regressor', + self.default_regressor_prior + ) + ) + ) + coeffs.append(v) + self.coeffs = tt.stack(coeffs, axis=0) + self.y_est = x.dot(self.coeffs) + + @classmethod + def from_formula(cls, formula, data, priors=None, vars=None, name='', model=None): + import patsy + y, x = patsy.dmatrices(formula, data) + labels = x.design_info.column_names + return cls(np.asarray(x), np.asarray(y)[:, 0], intercept=False, labels=labels, + priors=priors, vars=vars, name=name, model=model) + + +class Glm(LinearComponent): + """Creates glm model, y_est is accessible via attribute + Parameters + ---------- + name : str - name, associated with the linear component + x : pd.DataFrame or np.ndarray + y : pd.Series or np.array + intercept : bool - fit with intercept or not? + labels : list - replace variable names with these labels + priors : dict - priors for coefficients + use `Intercept` key for defining Intercept prior + defaults to Flat.dist() + use `Regressor` key for defining default prior for all regressors + defaults to Normal.dist(mu=0, tau=1.0E-6) + init : dict - test_vals for coefficients + vars : dict - random variables instead of creating new ones + family : pymc3.glm.families object + """ + def __init__(self, x, y, intercept=True, labels=None, + priors=None, vars=None, family='normal', name='', model=None): + super(Glm, self).__init__( + x, y, intercept=intercept, labels=labels, + priors=priors, vars=vars, name=name, model=model + ) + + _families = dict( + normal=families.Normal, + student=families.StudentT, + binomial=families.Binomial, + poisson=families.Poisson + ) + if isinstance(family, str): + family = _families[family]() + self.y_est = family.create_likelihood( + name='', y_est=self.y_est, + y_data=y, model=self) + + @classmethod + def from_formula(cls, formula, data, priors=None, + vars=None, family='normal', name='', model=None): + import patsy + y, x = patsy.dmatrices(formula, data) + labels = x.design_info.column_names + return cls(np.asarray(x), np.asarray(y)[:, 0], intercept=False, labels=labels, + priors=priors, vars=vars, family=family, name=name, model=model) diff --git a/pymc3/models/utils.py b/pymc3/models/utils.py new file mode 100644 index 0000000000..ea073fcd1b --- /dev/null +++ b/pymc3/models/utils.py @@ -0,0 +1,126 @@ +import six +import pandas as pd +from pandas.core.common import PandasError +import numpy as np +import theano.tensor as tt + + +def any_to_tensor_and_labels(x, labels=None): + """Util for converting input x to tensor trying to + create labels for columns if they are not provided. + + Default names for columns are ['x0', 'x1', ...], for mappable + arrays (e.g. pd.DataFrame) their names are treated as labels. + You can override them with `labels` argument. + + If you have tensor input you should provide labels as we + cannot get their shape directly + + If you pass dict input we cannot rely on labels order thus dict + keys are treated as labels anyway + + Parameters + ---------- + x : np.ndarray | pd.DataFrame | tt.Variable | dict | list + labels : list - names for columns of output tensor + + Returns + ------- + (x, labels) - tensor and labels for its columns + """ + if isinstance(labels, six.string_types): + labels = [labels] + # pandas.DataFrame + # labels can come from here + # we can override them + if isinstance(x, pd.DataFrame): + if not labels: + labels = x.columns + x = x.as_matrix() + + # pandas.Series + # there can still be a label + # we can override labels + elif isinstance(x, pd.Series): + if not labels: + labels = [x.name] + x = x.as_matrix()[:, None] + + # dict + # labels are keys, + # cannot override them + elif isinstance(x, dict): + # try to do it via pandas + try: + x = pd.DataFrame.from_dict(x) + labels = x.columns + x = x.as_matrix() + # some types fail there + # another approach is to construct + # variable by hand + except (PandasError, TypeError): + res = [] + labels = [] + for k, v in x.items(): + res.append(v) + labels.append(k) + x = tt.stack(res, axis=1) + if x.ndim == 1: + x = x[:, None] + # case when it can appear to be some + # array like value like lists of lists + # numpy deals with it + elif not isinstance(x, tt.Variable): + x = np.asarray(x) + if x.ndim == 0: + raise ValueError('Cannot use scalars') + elif x.ndim == 1: + x = x[:, None] + # something really strange goes here, + # but user passes labels trusting seems + # to be a good option + elif labels is not None: + x = tt.as_tensor_variable(x) + if x.ndim == 0: + raise ValueError('Cannot use scalars') + elif x.ndim == 1: + x = x[:, None] + else: # trust input + pass + # we should check that we can extract labels + if labels is None and not isinstance(x, tt.Variable): + labels = ['x%d' % i for i in range(x.shape[1])] + # for theano variables we should have labels from user + elif labels is None: + raise ValueError('Please provide labels as ' + 'we cannot infer shape of input') + else: # trust labels, user knows what he is doing + pass + # it's time to check shapes if we can + if not isinstance(x, tt.Variable): + if not len(labels) == x.shape[1]: + raise ValueError( + 'Please provide full list ' + 'of labels for coefficients, ' + 'got len(labels)=%d instead of %d' + % (len(labels), x.shape[1]) + ) + else: + # trust labels, as we raised an + # error in bad case, we have labels + pass + # convert labels to list + if isinstance(labels, pd.RangeIndex): + labels = ['x%d' % i for i in labels] + # maybe it was a tuple ot whatever + elif not isinstance(labels, list): + labels = list(labels) + # as output we need tensor + if not isinstance(x, tt.Variable): + x = tt.as_tensor_variable(x) + # finally check dimensions + if x.ndim == 0: + raise ValueError('Cannot use scalars') + elif x.ndim == 1: + x = x[:, None] + return x, labels diff --git a/pymc3/tests/test_model.py b/pymc3/tests/test_model.py new file mode 100644 index 0000000000..4eb96e6789 --- /dev/null +++ b/pymc3/tests/test_model.py @@ -0,0 +1,120 @@ +import unittest +import theano.tensor as tt +import pymc3 as pm +from pymc3.distributions import HalfCauchy, Normal +from pymc3 import Potential, Deterministic + + +class NewModel(pm.Model): + def __init__(self, name='', model=None): + super(NewModel, self).__init__(name, model) + assert pm.modelcontext(None) is self + # 1) init variables with Var method + self.Var('v1', pm.Normal.dist()) + self.v2 = pm.Normal('v2', mu=0, sd=1) + # 2) Potentials and Deterministic variables with method too + # be sure that names will not overlap with other same models + pm.Deterministic('d', tt.constant(1)) + pm.Potential('p', tt.constant(1)) + + +class DocstringModel(pm.Model): + def __init__(self, mean=0, sd=1, name='', model=None): + super(DocstringModel, self).__init__(name, model) + self.Var('v1', Normal.dist(mu=mean, sd=sd)) + Normal('v2', mu=mean, sd=sd) + Normal('v3', mu=mean, sd=HalfCauchy('sd', beta=10, testval=1.)) + Deterministic('v3_sq', self.v3 ** 2) + Potential('p1', tt.constant(1)) + + +class TestBaseModel(unittest.TestCase): + def test_setattr_properly_works(self): + with pm.Model() as model: + pm.Normal('v1') + self.assertEqual(len(model.vars), 1) + with pm.Model('sub') as submodel: + submodel.Var('v1', pm.Normal.dist()) + self.assertTrue(hasattr(submodel, 'v1')) + self.assertEqual(len(submodel.vars), 1) + self.assertEqual(len(model.vars), 2) + with submodel: + submodel.Var('v2', pm.Normal.dist()) + self.assertTrue(hasattr(submodel, 'v2')) + self.assertEqual(len(submodel.vars), 2) + self.assertEqual(len(model.vars), 3) + + def test_context_passes_vars_to_parent_model(self): + with pm.Model() as model: + # a set of variables is created + NewModel() + # another set of variables are created but with prefix 'another' + usermodel2 = NewModel(name='another') + # you can enter in a context with submodel + with usermodel2: + usermodel2.Var('v3', pm.Normal.dist()) + pm.Normal('v4') + # this variable is created in parent model too + self.assertIn('another_v2', model.named_vars) + self.assertIn('another_v3', model.named_vars) + self.assertIn('another_v3', usermodel2.named_vars) + self.assertIn('another_v4', model.named_vars) + self.assertIn('another_v4', usermodel2.named_vars) + self.assertTrue(hasattr(usermodel2, 'v3')) + self.assertTrue(hasattr(usermodel2, 'v2')) + self.assertTrue(hasattr(usermodel2, 'v4')) + # When you create a class based model you should follow some rules + with model: + m = NewModel('one_more') + self.assertTrue(m.d is model['one_more_d']) + self.assertTrue(m['d'] is model['one_more_d']) + self.assertTrue(m['one_more_d'] is model['one_more_d']) + + +class TestNested(unittest.TestCase): + def test_nest_context_works(self): + with pm.Model() as m: + new = NewModel() + with new: + self.assertTrue( + pm.modelcontext(None) is new + ) + self.assertTrue( + pm.modelcontext(None) is m + ) + self.assertIn('v1', m.named_vars) + self.assertIn('v2', m.named_vars) + + def test_named_context(self): + with pm.Model() as m: + NewModel(name='new') + self.assertIn('new_v1', m.named_vars) + self.assertIn('new_v2', m.named_vars) + + def test_docstring_example1(self): + usage1 = DocstringModel() + self.assertIn('v1', usage1.named_vars) + self.assertIn('v2', usage1.named_vars) + self.assertIn('v3', usage1.named_vars) + self.assertIn('v3_sq', usage1.named_vars) + self.assertTrue(len(usage1.potentials), 1) + + def test_docstring_example2(self): + with pm.Model() as model: + DocstringModel(name='prefix') + self.assertIn('prefix_v1', model.named_vars) + self.assertIn('prefix_v2', model.named_vars) + self.assertIn('prefix_v3', model.named_vars) + self.assertIn('prefix_v3_sq', model.named_vars) + self.assertTrue(len(model.potentials), 1) + + def test_duplicates_detection(self): + with pm.Model(): + DocstringModel(name='prefix') + self.assertRaises(ValueError, DocstringModel, name='prefix') + + def test_model_root(self): + with pm.Model() as model: + self.assertTrue(model is model.root) + with pm.Model() as sub: + self.assertTrue(model is sub.root) diff --git a/pymc3/tests/test_models_linear.py b/pymc3/tests/test_models_linear.py new file mode 100644 index 0000000000..fac66fc0de --- /dev/null +++ b/pymc3/tests/test_models_linear.py @@ -0,0 +1,108 @@ +import numpy as np +from .helpers import SeededTest +from pymc3 import Model, Uniform, Normal, find_MAP, Slice, sample +from pymc3.models.linear import LinearComponent, Glm + + +# Generate data +def generate_data(intercept, slope, size=700): + x = np.linspace(-1, 1, size) + y = intercept + x * slope + return x, y + + +class TestGLM(SeededTest): + @classmethod + def setUpClass(cls): + super(TestGLM, cls).setUpClass() + cls.intercept = 1 + cls.slope = 3 + cls.sd = .05 + x_linear, cls.y_linear = generate_data(cls.intercept, cls.slope, size=1000) + cls.y_linear += np.random.normal(size=1000, scale=cls.sd) + cls.data_linear = dict(x=x_linear, y=cls.y_linear) + + x_logistic, y_logistic = generate_data(cls.intercept, cls.slope, size=3000) + y_logistic = 1 / (1 + np.exp(-y_logistic)) + bern_trials = [np.random.binomial(1, i) for i in y_logistic] + cls.data_logistic = dict(x=x_logistic, y=bern_trials) + + def test_linear_component(self): + vars_to_create = { + 'sigma_interval_', + 'y_obs', + 'lm_x0', + 'lm_Intercept' + } + with Model() as model: + lm = LinearComponent( + self.data_linear['x'], + self.data_linear['y'], + name='lm' + ) # yields lm_x0, lm_Intercept + sigma = Uniform('sigma', 0, 20) # yields sigma_interval_ + Normal('y_obs', mu=lm.y_est, sd=sigma, observed=self.y_linear) # yields y_obs + start = find_MAP(vars=[sigma]) + step = Slice(model.vars) + trace = sample(500, step, start, progressbar=False, random_seed=self.random_seed) + + self.assertAlmostEqual(np.mean(trace['lm_Intercept']), self.intercept, 1) + self.assertAlmostEqual(np.mean(trace['lm_x0']), self.slope, 1) + self.assertAlmostEqual(np.mean(trace['sigma']), self.sd, 1) + self.assertSetEqual(vars_to_create, set(model.named_vars.keys())) + + def test_linear_component_from_formula(self): + with Model() as model: + lm = LinearComponent.from_formula('y ~ x', self.data_linear) + sigma = Uniform('sigma', 0, 20) + Normal('y_obs', mu=lm.y_est, sd=sigma, observed=self.y_linear) + start = find_MAP(vars=[sigma]) + step = Slice(model.vars) + trace = sample(500, step, start, progressbar=False, random_seed=self.random_seed) + + self.assertAlmostEqual(np.mean(trace['Intercept']), self.intercept, 1) + self.assertAlmostEqual(np.mean(trace['x']), self.slope, 1) + self.assertAlmostEqual(np.mean(trace['sigma']), self.sd, 1) + + def test_glm(self): + with Model() as model: + vars_to_create = { + 'glm_sd_log_', + 'glm_y', + 'glm_x0', + 'glm_Intercept' + } + Glm( + self.data_linear['x'], + self.data_linear['y'], + name='glm' + ) + start = find_MAP() + step = Slice(model.vars) + trace = sample(500, step, start, progressbar=False, random_seed=self.random_seed) + self.assertAlmostEqual(np.mean(trace['glm_Intercept']), self.intercept, 1) + self.assertAlmostEqual(np.mean(trace['glm_x0']), self.slope, 1) + self.assertAlmostEqual(np.mean(trace['glm_sd']), self.sd, 1) + self.assertSetEqual(vars_to_create, set(model.named_vars.keys())) + + def test_glm_from_formula(self): + with Model() as model: + NAME = 'glm' + Glm.from_formula('y ~ x', self.data_linear, name=NAME) + start = find_MAP() + step = Slice(model.vars) + trace = sample(500, step, start, progressbar=False, random_seed=self.random_seed) + + self.assertAlmostEqual(np.mean(trace['%s_Intercept' % NAME]), self.intercept, 1) + self.assertAlmostEqual(np.mean(trace['%s_x' % NAME]), self.slope, 1) + self.assertAlmostEqual(np.mean(trace['%s_sd' % NAME]), self.sd, 1) + + def test_strange_types(self): + with Model(): + self.assertRaises( + ValueError, + Glm, + 1, + self.data_linear['y'], + name='lm' + ) diff --git a/pymc3/tests/test_models_utils.py b/pymc3/tests/test_models_utils.py new file mode 100644 index 0000000000..160846bcbc --- /dev/null +++ b/pymc3/tests/test_models_utils.py @@ -0,0 +1,79 @@ +import unittest +import numpy as np +import pandas as pd +import theano.tensor as tt +import pymc3.models.utils as utils + + +class TestUtils(unittest.TestCase): + def setUp(self): + self.data = pd.DataFrame(dict(a=[1, 2, 3], b=[4, 5, 6])) + + def assertMatrixLabels(self, m, l, mt=None, lt=None): + self.assertTrue( + np.all( + np.equal( + m.eval(), + mt if mt is not None else self.data.as_matrix() + ) + ) + ) + self.assertEqual(l, list(lt or self.data.columns)) + + def test_numpy_init(self): + m, l = utils.any_to_tensor_and_labels(self.data.as_matrix()) + self.assertMatrixLabels(m, l, lt=['x0', 'x1']) + m, l = utils.any_to_tensor_and_labels(self.data.as_matrix(), labels=['x2', 'x3']) + self.assertMatrixLabels(m, l, lt=['x2', 'x3']) + + def test_pandas_init(self): + m, l = utils.any_to_tensor_and_labels(self.data) + self.assertMatrixLabels(m, l) + m, l = utils.any_to_tensor_and_labels(self.data, labels=['x2', 'x3']) + self.assertMatrixLabels(m, l, lt=['x2', 'x3']) + + def test_dict_input(self): + m, l = utils.any_to_tensor_and_labels(self.data.to_dict('dict')) + self.assertMatrixLabels(m, l, mt=self.data.as_matrix(l), lt=l) + + m, l = utils.any_to_tensor_and_labels(self.data.to_dict('series')) + self.assertMatrixLabels(m, l, mt=self.data.as_matrix(l), lt=l) + + m, l = utils.any_to_tensor_and_labels(self.data.to_dict('list')) + self.assertMatrixLabels(m, l, mt=self.data.as_matrix(l), lt=l) + + inp = {k: tt.as_tensor_variable(v) for k, v in self.data.to_dict('series').items()} + m, l = utils.any_to_tensor_and_labels(inp) + self.assertMatrixLabels(m, l, mt=self.data.as_matrix(l), lt=l) + + def test_list_input(self): + m, l = utils.any_to_tensor_and_labels(self.data.as_matrix().tolist()) + self.assertMatrixLabels(m, l, lt=['x0', 'x1']) + m, l = utils.any_to_tensor_and_labels(self.data.as_matrix().tolist(), labels=['x2', 'x3']) + self.assertMatrixLabels(m, l, lt=['x2', 'x3']) + + def test_tensor_input(self): + m, l = utils.any_to_tensor_and_labels( + tt.as_tensor_variable(self.data.as_matrix().tolist()), + labels=['x0', 'x1'] + ) + self.assertMatrixLabels(m, l, lt=['x0', 'x1']) + m, l = utils.any_to_tensor_and_labels( + tt.as_tensor_variable(self.data.as_matrix().tolist()), + labels=['x2', 'x3']) + self.assertMatrixLabels(m, l, lt=['x2', 'x3']) + + def test_user_mistakes(self): + # no labels for tensor variable + self.assertRaises( + ValueError, + utils.any_to_tensor_and_labels, + tt.as_tensor_variable(self.data.as_matrix().tolist()) + ) + # len of labels is bad + self.assertRaises( + ValueError, + utils.any_to_tensor_and_labels, + self.data.as_matrix().tolist(), + labels=['x'] + ) diff --git a/requirements.txt b/requirements.txt index fc6625c5d9..2e53afc286 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ recommonmark sphinx nbsphinx numpydoc +six diff --git a/setup.py b/setup.py index 4fcf5af18a..d51eb2b3a3 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ DISTNAME = 'pymc3' DESCRIPTION = "PyMC3" -LONG_DESCRIPTION = """Bayesian estimation, particularly using Markov chain Monte Carlo (MCMC), is an increasingly relevant approach to statistical estimation. However, few statistical software packages implement MCMC samplers, and they are non-trivial to code by hand. ``pymc3`` is a python package that implements the Metropolis-Hastings algorithm as a python class, and is extremely flexible and applicable to a large suite of problems. ``pymc3`` includes methods for summarizing output, plotting, goodness-of-fit and convergence diagnostics.""" +LONG_DESCRIPTION = """Bayesian estimation, particularly using Markov chain Monte Carlo (MCMC), is an increasingly relevant approach to statistical estimation. However, few statistical software packages implement MCMC samplers, and they are non-trivial to code by hand. ``pymc3`` is a python package that implements the Metropolis-Hastings algorithm as a python class, and is extremely flexible and applicable to a large suite of problems. ``pymc3`` includes methods for summarizing output, plotting, goodness-of-fit and convergence diagnostics.""" MAINTAINER = 'Thomas Wiecki' MAINTAINER_EMAIL = 'thomas.wiecki@gmail.com' AUTHOR = 'John Salvatier and Christopher Fonnesbeck' @@ -50,7 +50,8 @@ packages=['pymc3', 'pymc3.distributions', 'pymc3.step_methods', 'pymc3.tuning', 'pymc3.tests', 'pymc3.glm', 'pymc3.examples', - 'pymc3.backends', 'pymc3.variational', 'docs', '.'], + 'pymc3.models', 'pymc3.backends', + 'pymc3.variational', 'docs', '.'], classifiers=classifiers, install_requires=install_reqs, tests_require=test_reqs, From fc0673bf3ed789aa12fee1244033e5e2a8c7c576 Mon Sep 17 00:00:00 2001 From: Maxim Date: Mon, 28 Nov 2016 07:38:18 +0300 Subject: [PATCH 10/83] ENH User model (#1525) * Started to write Base class for pymc3.models * mode `add_var` to public api * Added some docstrings * Added some docstrings * added getitem and fixed a typo * added assertion check * added resolve var method * decided not to add resolve method * Added linear component * Docs fix * patsy's intercept is inited properly now * refactored code * updated docs * added possibility to init coefficients with random variables * added glm * refactored api, fixed formula init * refactored linear model, extended acceptable types * moved useful matrix and labels creation to utils file * code style * removed redundant evaluation of shape * refactored resolver for constructing matrix and labels * changed error message * changed signature of init * simplified utils any_to_tensor_and_labels code * tests for `any_to_tensor_and_labels` * added docstring for `any_to_tensor_and_labels` util * forgot to document return type in `any_to_tensor_and_labels` * refactored code for dict * dict tests fix(do not check labels there) * added access to random vars of model * added a shortcut for all variables so there is a unified way to get them * added default priors for linear model * update docs for linear * refactored UserModel api, made it more similar to pm.Model class * Lots of refactoring, tests for base class, more plain api design * deleted unused module variable * fixed some typos in docstring * Refactored pm.Model class, now it is ready for inheritance * Added documentation for Model class * Small typo in docstring * nested contains for treedict (needed for add_random_variable) * More accurate duplicate implementation of treedict/treelist * refactored treedict/treelist * changed `__imul__` of treelist * added `root` property and `isroot` indicator for base model * protect `parent` and `model` attributes from violation * travis' python2 did not fail on bad syntax(maybe it's too new), fixed * decided not to use functools wrapper Unfortunately functools wrapper fails when decorating built-in methods so I need to fix that improper behaviour. Some bad but needed tricks were implemented * Added models package to setup script * Refactor utils * Fix some typos in pm.model --- pymc3/model.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pymc3/model.py b/pymc3/model.py index ee335d7941..6017484d06 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -1,5 +1,6 @@ import threading import six + import numpy as np import theano import theano.tensor as tt From ea82ebd554c426d4af85881a39e1698805cf47c8 Mon Sep 17 00:00:00 2001 From: colin Date: Tue, 8 Nov 2016 00:29:28 -0500 Subject: [PATCH 11/83] Refactor Hamiltonian methods into single class --- pymc3/step_methods/__init__.py | 4 +- pymc3/step_methods/arraystep.py | 29 ++- pymc3/step_methods/hmc.py | 127 ---------- pymc3/step_methods/hmc/__init__.py | 2 + pymc3/step_methods/hmc/base_hmc.py | 57 +++++ pymc3/step_methods/hmc/hmc.py | 56 +++++ pymc3/step_methods/hmc/nuts.py | 132 ++++++++++ pymc3/step_methods/{ => hmc}/quadpotential.py | 0 pymc3/step_methods/hmc/trajectory.py | 184 ++++++++++++++ pymc3/step_methods/nuts.py | 238 ------------------ pymc3/tests/models.py | 2 +- pymc3/tests/test_hmc.py | 29 +-- pymc3/tests/test_step.py | 16 +- pymc3/theanof.py | 4 +- 14 files changed, 474 insertions(+), 406 deletions(-) delete mode 100644 pymc3/step_methods/hmc.py create mode 100644 pymc3/step_methods/hmc/__init__.py create mode 100644 pymc3/step_methods/hmc/base_hmc.py create mode 100644 pymc3/step_methods/hmc/hmc.py create mode 100644 pymc3/step_methods/hmc/nuts.py rename pymc3/step_methods/{ => hmc}/quadpotential.py (100%) create mode 100644 pymc3/step_methods/hmc/trajectory.py delete mode 100644 pymc3/step_methods/nuts.py diff --git a/pymc3/step_methods/__init__.py b/pymc3/step_methods/__init__.py index ccb5e22c47..07ee4a453c 100644 --- a/pymc3/step_methods/__init__.py +++ b/pymc3/step_methods/__init__.py @@ -1,6 +1,6 @@ from .compound import CompoundStep -from .hmc import HamiltonianMC +from .hmc import HamiltonianMC, NUTS from .metropolis import Metropolis from .metropolis import BinaryMetropolis @@ -15,5 +15,3 @@ from .gibbs import ElemwiseCategorical from .slicer import Slice - -from .nuts import NUTS \ No newline at end of file diff --git a/pymc3/step_methods/arraystep.py b/pymc3/step_methods/arraystep.py index c0619ae653..da83191139 100644 --- a/pymc3/step_methods/arraystep.py +++ b/pymc3/step_methods/arraystep.py @@ -4,7 +4,6 @@ from ..blocking import ArrayOrdering, DictToArrayBijection import numpy as np from numpy.random import uniform -from numpy import log, isfinite from enum import IntEnum, unique __all__ = ['ArrayStep', 'ArrayStepShared', 'metrop_select', 'SamplerHist', @@ -90,9 +89,9 @@ class ArrayStep(BlockedStep): ---------- vars : list List of variables for sampler. + fs: list of logp theano functions allvars: Boolean (default False) blocked: Boolean (default True) - fs: logp theano function """ def __init__(self, vars, fs, allvars=False, blocked=True): @@ -114,10 +113,11 @@ def step(self, point): class ArrayStepShared(BlockedStep): - """Faster version of ArrayStep that requires the substep method that does not wrap the functions the step method uses. + """Faster version of ArrayStep that requires the substep method that does not wrap + the functions the step method uses. - Works by setting shared variables before using the step. This eliminates the mapping and unmapping overhead as well - as moving fewer variables around. + Works by setting shared variables before using the step. This eliminates the mapping + and unmapping overhead as well as moving fewer variables around. """ def __init__(self, vars, shared, blocked=True): @@ -144,14 +144,25 @@ def step(self, point): def metrop_select(mr, q, q0): - # Perform rejection/acceptance step for Metropolis class samplers + """Perform rejection/acceptance step for Metropolis class samplers. + Returns the new sample q if a uniform random number is less than the + metropolis acceptance rate (`mr`), and the old sample otherwise. + + Parameters + ---------- + mr : float, Metropolis acceptance rate + q : proposed sample + q0 : current sample + + Returns + ------- + q or q0 + """ # Compare acceptance ratio to uniform random number - if isfinite(mr) and log(uniform()) < mr: - # Accept proposed value + if np.isfinite(mr) and np.log(uniform()) < mr: return q else: - # Reject proposed value return q0 diff --git a/pymc3/step_methods/hmc.py b/pymc3/step_methods/hmc.py deleted file mode 100644 index 295b6122d0..0000000000 --- a/pymc3/step_methods/hmc.py +++ /dev/null @@ -1,127 +0,0 @@ -''' -Created on Mar 7, 2011 - -@author: johnsalvatier -''' -from numpy import floor -from .quadpotential import quad_potential -from .arraystep import ArrayStep, SamplerHist, metrop_select, Competence -from ..tuning import guess_scaling -from ..model import modelcontext, Point -from ..theanof import inputvars -from ..vartypes import discrete_types - -import numpy as np -from scipy.sparse import issparse - -from collections import namedtuple - -__all__ = ['HamiltonianMC'] - -# TODO: -# add constraint handling via page 37 of Radford's -# http://www.cs.utoronto.ca/~radford/ham-mcmc.abstract.html - - -def unif(step_size, elow=.85, ehigh=1.15): - return np.random.uniform(elow, ehigh) * step_size - - -class HamiltonianMC(ArrayStep): - default_blocked = True - - def __init__(self, vars=None, scaling=None, step_scale=.25, path_length=2., is_cov=False, step_rand=unif, state=None, model=None, **kwargs): - """ - Parameters - ---------- - vars : list of theano variables - scaling : array_like, ndim = {1,2} - Scaling for momentum distribution. 1d arrays interpreted matrix diagonal. - step_scale : float, default=.25 - Size of steps to take, automatically scaled down by 1/n**(1/4) (defaults to .25) - path_length : float, default=2 - total length to travel - is_cov : bool, default=False - Treat scaling as a covariance matrix/vector if True, else treat it as a precision matrix/vector - step_rand : function float -> float, default=unif - A function which takes the step size and returns an new one used to randomize the step size at each iteration. - state - State object - model : Model - """ - model = modelcontext(model) - - if vars is None: - vars = model.cont_vars - vars = inputvars(vars) - - if scaling is None: - scaling = model.test_point - - if isinstance(scaling, dict): - scaling = guess_scaling(Point(scaling, model=model), model=model) - - n = scaling.shape[0] - - self.step_size = step_scale / n ** (1 / 4.) - - self.potential = quad_potential(scaling, is_cov, as_cov=False) - - self.path_length = path_length - self.step_rand = step_rand - - if state is None: - state = SamplerHist() - self.state = state - - super(HamiltonianMC, self).__init__( - vars, [model.fastlogp, model.fastdlogp(vars)], **kwargs) - - def astep(self, q0, logp, dlogp): - H = Hamiltonian(logp, dlogp, self.potential) - - e = self.step_rand(self.step_size) - nstep = int(self.path_length / e) - - p0 = H.pot.random() - - q, p = leapfrog(H, q0, p0, nstep, e) - p = -p - - mr = energy(H, q0, p0) - energy(H, q, p) - - self.state.metrops.append(mr) - - return metrop_select(mr, q, q0) - - @staticmethod - def competence(var): - if var.dtype in discrete_types: - return Competence.INCOMPATIBLE - return Competence.COMPATIBLE - - -def bern(p): - return np.random.uniform() < p - -Hamiltonian = namedtuple("Hamiltonian", "logp, dlogp, pot") - - -def energy(H, q, p): - return -(H.logp(q) - H.pot.energy(p)) - - -def leapfrog(H, q, p, n, e): - _, dlogp, pot = H - - p = p - (e / 2) * -dlogp(q) # half momentum update - - for i in range(n): - # alternate full variable and momentum updates - q = q + e * pot.velocity(p) - - if i != n - 1: - p = p - e * -dlogp(q) - - p = p - (e / 2) * -dlogp(q) # do a half step momentum update to finish off - return q, p diff --git a/pymc3/step_methods/hmc/__init__.py b/pymc3/step_methods/hmc/__init__.py new file mode 100644 index 0000000000..07fa92af67 --- /dev/null +++ b/pymc3/step_methods/hmc/__init__.py @@ -0,0 +1,2 @@ +from .hmc import HamiltonianMC +from .nuts import NUTS diff --git a/pymc3/step_methods/hmc/base_hmc.py b/pymc3/step_methods/hmc/base_hmc.py new file mode 100644 index 0000000000..7d87f5d3c8 --- /dev/null +++ b/pymc3/step_methods/hmc/base_hmc.py @@ -0,0 +1,57 @@ +from ..arraystep import ArrayStepShared +from .trajectory import get_theano_hamiltonian_functions + +from pymc3.tuning import guess_scaling +from pymc3.model import modelcontext, Point +from .quadpotential import quad_potential +from pymc3.theanof import inputvars, make_shared_replacements + + +class BaseHMC(ArrayStepShared): + default_blocked = True + + def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, + model=None, blocked=True, use_single_leapfrog=False, **theano_kwargs): + """ + Parameters + ---------- + vars : list of theano variables + scaling : array_like, ndim = {1,2} + Scaling for momentum distribution. 1d arrays interpreted matrix diagonal. + step_scale : float, default=0.25 + Size of steps to take, automatically scaled down by 1/n**(1/4) + is_cov : bool, default=False + Treat scaling as a covariance matrix/vector if True, else treat it as a + precision matrix/vector + state + State object + model : pymc3 Model instance. default=Context model + blocked: Boolean, default True + use_single_leapfrog: Boolean, will leapfrog steps take a single step at a time. + default False. + **theano_kwargs: passed to theano functions + """ + model = modelcontext(model) + + if vars is None: + vars = model.cont_vars + vars = inputvars(vars) + + if scaling is None: + scaling = model.test_point + + if isinstance(scaling, dict): + scaling = guess_scaling(Point(scaling, model=model), model=model, vars=vars) + + n = scaling.shape[0] + self.step_size = step_scale / (n ** 0.25) + self.potential = quad_potential(scaling, is_cov, as_cov=False) + + shared = make_shared_replacements(vars, model) + if theano_kwargs is None: + theano_kwargs = {} + + self.H, self.compute_energy, self.leapfrog, self._vars = get_theano_hamiltonian_functions( + vars, shared, model.logpt, self.potential, use_single_leapfrog, **theano_kwargs) + + super(BaseHMC, self).__init__(vars, shared, blocked=blocked) diff --git a/pymc3/step_methods/hmc/hmc.py b/pymc3/step_methods/hmc/hmc.py new file mode 100644 index 0000000000..70a042f263 --- /dev/null +++ b/pymc3/step_methods/hmc/hmc.py @@ -0,0 +1,56 @@ +''' +Created on Mar 7, 2011 + +@author: johnsalvatier +''' +from ..arraystep import metrop_select, Competence +from .base_hmc import BaseHMC +from pymc3.vartypes import discrete_types +import numpy as np + + +__all__ = ['HamiltonianMC'] + +# TODO: +# add constraint handling via page 37 of Radford's +# http://www.cs.utoronto.ca/~radford/ham-mcmc.abstract.html + + +def unif(step_size, elow=.85, ehigh=1.15): + return np.random.uniform(elow, ehigh) * step_size + + +class HamiltonianMC(BaseHMC): + default_blocked = True + + def __init__(self, vars=None, path_length=2., step_rand=unif, **kwargs): + """ + Parameters + ---------- + vars : list of theano variables + path_length : float, default=2 + total length to travel + step_rand : function float -> float, default=unif + A function which takes the step size and returns an new one used to + randomize the step size at each iteration. + **kwargs : passed to BaseHMC + """ + super(HamiltonianMC, self).__init__(vars, **kwargs) + self.path_length = path_length + self.step_rand = step_rand + + def astep(self, q0): + e = np.array(self.step_rand(self.step_size)) + n_steps = np.array(self.path_length / e, dtype='int32') + q = q0 + p = self.H.pot.random() # initialize momentum + initial_energy = self.compute_energy(q, p) + q, p, current_energy = self.leapfrog(q, p, e, n_steps) + energy_change = current_energy - initial_energy + return metrop_select(energy_change, q, q0) + + @staticmethod + def competence(var): + if var.dtype in discrete_types: + return Competence.INCOMPATIBLE + return Competence.COMPATIBLE diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py new file mode 100644 index 0000000000..e22a3cb8ec --- /dev/null +++ b/pymc3/step_methods/hmc/nuts.py @@ -0,0 +1,132 @@ +from ..arraystep import Competence +from .base_hmc import BaseHMC +from pymc3.vartypes import continuous_types + +import numpy as np +import numpy.random as nr + +__all__ = ['NUTS'] + + +def bern(p): + return np.random.uniform() < p + + +class NUTS(BaseHMC): + """ + Automatically tunes step size and adjust number of steps for good performance. + + Implements "Algorithm 6: Efficient No-U-Turn Sampler with Dual Averaging" in: + + Hoffman, Matthew D., & Gelman, Andrew. (2011). + The No-U-Turn Sampler: Adaptively Setting Path Lengths in Hamiltonian Monte Carlo. + """ + default_blocked = True + + def __init__(self, vars=None, Emax=1000, target_accept=0.8, + gamma=0.05, k=0.75, t0=10, **kwargs): + """ + Parameters + ---------- + vars : list of Theano variables, default continuous vars + Emax : float, default 1000 + maximum energy + target_accept : float (0,1) default .8 + target for avg accept probability between final branch and initial position + gamma : float, default .05 + k : float (.5,1) default .75 + scaling of speed of adaptation + t0 : int, default 10 + slows inital adapatation + kwargs: passed to BaseHMC + """ + super(NUTS, self).__init__(vars, use_single_leapfrog=True, **kwargs) + + self.Emax = Emax + + self.target_accept = target_accept + self.gamma = gamma + self.k = k + self.t0 = t0 + + self.Hbar = 0 + self.u = np.log(self.step_size * 10) + self.m = 1 + + def astep(self, q0): + Emax = self.Emax + e = self.step_size + + p0 = self.potential.random() + E0 = self.compute_energy(q0, p0) + + u = nr.uniform() + q = qn = qp = q0 + p = pn = pp = p0 + + n, s, j = 1, 1, 0 + + while s == 1: + v = bern(0.5) * 2 - 1 + + if v == -1: + qn, pn, _, _, q1, n1, s1, a, na = buildtree( + self.leapfrog, qn, pn, u, v, j, e, Emax, E0) + else: + _, _, qp, pp, q1, n1, s1, a, na = buildtree( + self.leapfrog, qp, pp, u, v, j, e, Emax, E0) + + if s1 == 1 and bern(min(1, n1 * 1. / n)): + q = q1 + + n = n + n1 + + span = qp - qn + s = s1 * (span.dot(pn) >= 0) * (span.dot(pp) >= 0) + j = j + 1 + + p = -p + + w = 1. / (self.m + self.t0) + self.Hbar = (1 - w) * self.Hbar + w * \ + (self.target_accept - a * 1. / na) + + self.step_size = np.exp(self.u - (self.m**self.k / self.gamma) * self.Hbar) + self.m += 1 + + return q + + @staticmethod + def competence(var): + if var.dtype in continuous_types: + return Competence.IDEAL + return Competence.INCOMPATIBLE + + +def buildtree(leapfrog, q, p, u, v, j, e, Emax, E0): + if j == 0: + q1, p1, E = leapfrog(q, p, np.array(v * e)) + dE = E - E0 + + n1 = int(np.log(u) + dE <= 0) + s1 = int(np.log(u) + dE < Emax) + return q1, p1, q1, p1, q1, n1, s1, min(1, np.exp(-dE)), 1 + qn, pn, qp, pp, q1, n1, s1, a1, na1 = buildtree(leapfrog, q, p, u, v, j - 1, e, Emax, E0) + if s1 == 1: + if v == -1: + qn, pn, _, _, q11, n11, s11, a11, na11 = buildtree( + leapfrog, qn, pn, u, v, j - 1, e, Emax, E0) + else: + _, _, qp, pp, q11, n11, s11, a11, na11 = buildtree( + leapfrog, qp, pp, u, v, j - 1, e, Emax, E0) + + if bern(n11 * 1. / (max(n1 + n11, 1))): + q1 = q11 + + a1 = a1 + a11 + na1 = na1 + na11 + + span = qp - qn + s1 = s11 * (span.dot(pn) >= 0) * (span.dot(pp) >= 0) + n1 = n1 + n11 + return qn, pn, qp, pp, q1, n1, s1, a1, na1 diff --git a/pymc3/step_methods/quadpotential.py b/pymc3/step_methods/hmc/quadpotential.py similarity index 100% rename from pymc3/step_methods/quadpotential.py rename to pymc3/step_methods/hmc/quadpotential.py diff --git a/pymc3/step_methods/hmc/trajectory.py b/pymc3/step_methods/hmc/trajectory.py new file mode 100644 index 0000000000..b64790a21a --- /dev/null +++ b/pymc3/step_methods/hmc/trajectory.py @@ -0,0 +1,184 @@ +from collections import namedtuple + +from pymc3.theanof import join_nonshared_inputs, gradient, CallableTensor + +import theano +import theano.tensor as tt + + +Hamiltonian = namedtuple("Hamiltonian", "logp, dlogp, pot") + + +def _theano_hamiltonian(model_vars, shared, logpt, potential): + """Creates a Hamiltonian with shared inputs. + + Parameters + ---------- + model_vars: array of variables to be sampled + shared theano tensors that are already shared + logpt: model log probability + potential: hamiltonian potential + + Returns + ------- + Hamiltonian: namedtuple with log pdf, gradient of log pdf, and potential functions + q: Starting position variable. + """ + dlogp = gradient(logpt, model_vars) + (logp, dlogp), q = join_nonshared_inputs([logpt, dlogp], model_vars, shared) + logp = CallableTensor(logp) + dlogp = CallableTensor(dlogp) + return Hamiltonian(logp, dlogp, potential), q + + +def _theano_energy_function(H, q, **theano_kwargs): + """Creates a Hamiltonian with shared inputs. + + Parameters + ---------- + H: Hamiltonian namedtuple + q: theano variable, starting position + theano_kwargs: passed to theano.function + + Returns + ------- + energy_function: theano function that computes the energy at a point (p, q) in phase space + p: Starting momentum variable. + """ + p = tt.dvector('p') + p.tag.test_value = q.tag.test_value + total_energy = H.pot.energy(p) - H.logp(q) + energy_function = theano.function(inputs=[q, p], outputs=total_energy, **theano_kwargs) + energy_function.trust_input = True + + return energy_function, p + + +def _theano_leapfrog_integrator(H, q, p, **theano_kwargs): + """Computes a theano function that computes one leapfrog step and the energy at the + end of the trajectory. + + Parameters + ---------- + H : Hamiltonian + q : theano.tensor + p : theano.tensor + theano_kwargs : passed to theano.function + + Returns + ------- + theano function which returns + q_new, p_new, energy_new + """ + epsilon = tt.dscalar('epsilon') + epsilon.tag.test_value = 1 + + n_steps = tt.iscalar('n_steps') + n_steps.tag.test_value = 2 + + q_new, p_new = leapfrog(H, q, p, epsilon, n_steps) + energy_new = energy(H, q_new, p_new) + + f = theano.function([q, p, epsilon, n_steps], [q_new, p_new, energy_new], **theano_kwargs) + f.trust_input = True + return f + + +def get_theano_hamiltonian_functions(model_vars, shared, logpt, potential, + use_single_leapfrog=False, **theano_kwargs): + """Construct theano functions for the Hamiltonian, energy, and leapfrog integrator. + + Parameters + ---------- + model_vars : array of variables to be sampled + shared theano tensors that are already shared + logpt: model log probability + potential: hamiltonian potential + theano_kwargs : dictionary of keyword arguments to pass to theano functions + use_single_leapfrog: Boolean, if only 1 integration step is done at a time (as in NUTS), + this provides a ~2x speedup + + Returns + ------- + H: Hamiltonian namedtuple + energy_function: theano function computing energy at a point in phase space + leapfrog_integrator: theano function integrating the Hamiltonian from a point in phase space + theano_variables: dictionary of variables used in the computation graph which may be useful + """ + H, q = _theano_hamiltonian(model_vars, shared, logpt, potential) + energy_function, p = _theano_energy_function(H, q, **theano_kwargs) + if use_single_leapfrog: + leapfrog_integrator = _theano_single_leapfrog(H, q, p, **theano_kwargs) + else: + leapfrog_integrator = _theano_leapfrog_integrator(H, q, p, **theano_kwargs) + return H, energy_function, leapfrog_integrator, {'q': q, 'p': p} + + +def energy(H, q, p): + """Compute the total energy for the Hamiltonian at a given position/momentum""" + return -(H.logp(q) - H.pot.energy(p)) + + +def leapfrog(H, q, p, epsilon, n_steps): + """Leapfrog integrator. + + Estimates `p(t)` and `q(t)` at time :math:`t = n \cdot e`, by integrating the + Hamiltonian equations + + .. math:: + + \frac{dq_i}{dt} = \frac{\partial H}{\partial p_i} + + \frac{dp_i}{dt} = \frac{\partial H}{\partial q_i} + + with :math:`p(0) = p`, :math:`q(0) = q` + + Parameters + ---------- + H : Hamiltonian instance. + Tuple of `logp, dlogp, potential`. + q: Theano.tensor + initial position vector + p: Theano.tensor + initial momentum vector + epsilon: float, step size + n_steps: int, number of iterations + + Returns + ------- + position: Theano.tensor + position estimate at time :math:`n \cdot e`. + momentum: Theano.tensor + momentum estimate at time :math:`n \cdot e`. + """ + def full_update(p, q): + p = p + epsilon * H.dlogp(q) + q += epsilon * H.pot.velocity(p) + return p, q + # This first line can't be +=, possibly because of theano + p = p + 0.5 * epsilon * H.dlogp(q) # half momentum update + q += epsilon * H.pot.velocity(p) # full position update + if tt.gt(n_steps, 1): + (p_seq, q_seq), _ = theano.scan(full_update, outputs_info=[p, q], n_steps=n_steps - 1) + p, q = p_seq[-1], q_seq[-1] + p += 0.5 * epsilon * H.dlogp(q) # half momentum update + return q, p + + +def _theano_single_leapfrog(H, q, p, **theano_kwargs): + """Leapfrog integrator for a single step. + + See above for documentation. This is optimized for the case where only a single step is + needed, in case of, for example, a recursive algorithm. + """ + epsilon = tt.dscalar('epsilon') + epsilon.tag.test_value = 1 + + p_new = p + 0.5 * epsilon * H.dlogp(q) # half momentum update + q_new = q + epsilon * H.pot.velocity(p_new) # full position update + p_new += 0.5 * epsilon * H.dlogp(q_new) # half momentum update + energy_new = energy(H, q_new, p_new) + + f = theano.function(inputs=[q, p, epsilon], outputs=[q_new, p_new, energy_new], **theano_kwargs) + f.trust_input = True + return f diff --git a/pymc3/step_methods/nuts.py b/pymc3/step_methods/nuts.py deleted file mode 100644 index 84bb3a90ba..0000000000 --- a/pymc3/step_methods/nuts.py +++ /dev/null @@ -1,238 +0,0 @@ -from .quadpotential import quad_potential -from .arraystep import ArrayStepShared, ArrayStep, SamplerHist, Competence -from ..model import modelcontext, Point -from ..vartypes import continuous_types -from numpy import exp, log, array -from numpy.random import uniform -from .hmc import leapfrog, Hamiltonian, bern, energy -from ..tuning import guess_scaling -import theano -from ..theanof import (make_shared_replacements, join_nonshared_inputs, CallableTensor, - gradient, inputvars) -import theano.tensor as tt - -__all__ = ['NUTS'] - - -class NUTS(ArrayStepShared): - """ - Automatically tunes step size and adjust number of steps for good performance. - - Implements "Algorithm 6: Efficient No-U-Turn Sampler with Dual Averaging" in: - - Hoffman, Matthew D., & Gelman, Andrew. (2011). - The No-U-Turn Sampler: Adaptively Setting Path Lengths in Hamiltonian Monte Carlo. - """ - default_blocked = True - - def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, state=None, - Emax=1000, - target_accept=0.8, - gamma=0.05, - k=0.75, - t0=10, - model=None, - profile=False, - mode=None, **kwargs): - """ - Parameters - ---------- - vars : list of Theano variables, default continuous vars - scaling : array_like, ndim = {1,2} or point - Scaling for momentum distribution. 1d arrays interpreted matrix diagonal. - step_scale : float, default=.25 - Size of steps to take, automatically scaled down by 1/n**(1/4) - is_cov : bool, default=False - Treat C as a covariance matrix/vector if True, else treat it as a precision matrix/vector - state - state to start from - Emax : float, default 1000 - maximum energy - target_accept : float (0,1) default .8 - target for avg accept probability between final branch and initial position - gamma : float, default .05 - k : float (.5,1) default .75 - scaling of speed of adaptation - t0 : int, default 10 - slows inital adapatation - model : Model - profile : bool or ProfileStats - sets the functions to be profiled - mode : string or `Mode` instance. - compilation mode passed to Theano functions - """ - model = modelcontext(model) - - if vars is None: - vars = model.cont_vars - vars = inputvars(vars) - - if scaling is None: - scaling = model.test_point - - if isinstance(scaling, dict): - scaling = guess_scaling( - Point(scaling, model=model), model=model, vars=vars) - - n = scaling.shape[0] - - self.step_size = step_scale / n**(1 / 4.) - - self.potential = quad_potential(scaling, is_cov, as_cov=False) - - if state is None: - state = SamplerHist() - self.state = state - self.Emax = Emax - - self.target_accept = target_accept - self.gamma = gamma - self.t0 = t0 - self.k = k - - self.Hbar = 0 - self.u = log(self.step_size * 10) - self.m = 1 - self.mode = mode - - shared = make_shared_replacements(vars, model) - - def create_hamiltonian(vars, shared, model): - dlogp = gradient(model.logpt, vars) - (logp, dlogp), q = join_nonshared_inputs( - [model.logpt, dlogp], vars, shared) - logp = CallableTensor(logp) - dlogp = CallableTensor(dlogp) - - return Hamiltonian(logp, dlogp, self.potential), q - - def create_energy_func(q): - p = tt.dvector('p') - p.tag.test_value = q.tag.test_value - E0 = energy(self.H, q, p) - E0_func = theano.function([q, p], E0, mode=self.mode) - E0_func.trust_input = True - - return E0_func - - self.H, q = create_hamiltonian(vars, shared, model) - self.compute_energy = create_energy_func(q) - - self.leapfrog1_dE = leapfrog1_dE(self.H, q, profile=profile, - mode=self.mode) - - super(NUTS, self).__init__(vars, shared, **kwargs) - - def astep(self, q0): - leapfrog = self.leapfrog1_dE - Emax = self.Emax - e = self.step_size - - p0 = self.potential.random() - E0 = self.compute_energy(q0, p0) - - u = uniform() - q = qn = qp = q0 - p = pn = pp = p0 - - n, s, j = 1, 1, 0 - - while s == 1: - v = bern(.5) * 2 - 1 - - if v == -1: - qn, pn, _, _, q1, n1, s1, a, na = buildtree( - leapfrog, qn, pn, u, v, j, e, Emax, E0) - else: - _, _, qp, pp, q1, n1, s1, a, na = buildtree( - leapfrog, qp, pp, u, v, j, e, Emax, E0) - - if s1 == 1 and bern(min(1, n1 * 1. / n)): - q = q1 - - n = n + n1 - - span = qp - qn - s = s1 * (span.dot(pn) >= 0) * (span.dot(pp) >= 0) - j = j + 1 - - p = -p - - w = 1. / (self.m + self.t0) - self.Hbar = (1 - w) * self.Hbar + w * \ - (self.target_accept - a * 1. / na) - - self.step_size = exp(self.u - (self.m**self.k / self.gamma) * self.Hbar) - self.m += 1 - - return q - - @staticmethod - def competence(var): - if var.dtype in continuous_types: - return Competence.IDEAL - return Competence.INCOMPATIBLE - - -def buildtree(leapfrog1_dE, q, p, u, v, j, e, Emax, E0): - if j == 0: - q1, p1, dE = leapfrog1_dE(q, p, array(v * e), E0) - - n1 = int(log(u) + dE <= 0) - s1 = int(log(u) + dE < Emax) - return q1, p1, q1, p1, q1, n1, s1, min(1, exp(-dE)), 1 - else: - qn, pn, qp, pp, q1, n1, s1, a1, na1 = buildtree( - leapfrog1_dE, q, p, u, v, j - 1, e, Emax, E0) - if s1 == 1: - if v == -1: - qn, pn, _, _, q11, n11, s11, a11, na11 = buildtree( - leapfrog1_dE, qn, pn, u, v, j - 1, e, Emax, E0) - else: - _, _, qp, pp, q11, n11, s11, a11, na11 = buildtree( - leapfrog1_dE, qp, pp, u, v, j - 1, e, Emax, E0) - - if bern(n11 * 1. / (max(n1 + n11, 1))): - q1 = q11 - - a1 = a1 + a11 - na1 = na1 + na11 - - span = qp - qn - s1 = s11 * (span.dot(pn) >= 0) * (span.dot(pp) >= 0) - n1 = n1 + n11 - return qn, pn, qp, pp, q1, n1, s1, a1, na1 - return - - -def leapfrog1_dE(H, q, profile, mode): - """Computes a theano function that computes one leapfrog step and the energy difference between the beginning and end of the trajectory. - Parameters - ---------- - H : Hamiltonian - q : theano.tensor - profile : Boolean - - Returns - ------- - theano function which returns - q_new, p_new, dE - """ - p = tt.dvector('p') - p.tag.test_value = q.tag.test_value - - e = tt.dscalar('e') - e.tag.test_value = 1 - - q1, p1 = leapfrog(H, q, p, 1, e) - E = energy(H, q1, p1) - - E0 = tt.dscalar('E0') - E0.tag.test_value = 1 - - dE = E - E0 - - f = theano.function([q, p, e, E0], [q1, p1, dE], - profile=profile, mode=mode) - f.trust_input = True - return f diff --git a/pymc3/tests/models.py b/pymc3/tests/models.py index d8a195fd46..9c8ad87775 100644 --- a/pymc3/tests/models.py +++ b/pymc3/tests/models.py @@ -19,7 +19,7 @@ def simple_categorical(): p = np.array([0.1, 0.2, 0.3, 0.4]) v = np.array([0.0, 1.0, 2.0, 3.0]) with Model() as model: - Categorical('x', p, shape = 3, testval = [1, 2, 3]) + Categorical('x', p, shape=3, testval=[1, 2, 3]) mu = np.dot(p, v) var = np.dot(p, (v - mu) ** 2) diff --git a/pymc3/tests/test_hmc.py b/pymc3/tests/test_hmc.py index d64d89de16..e40aa3fd11 100644 --- a/pymc3/tests/test_hmc.py +++ b/pymc3/tests/test_hmc.py @@ -1,32 +1,25 @@ -import pymc3 as pm import numpy as np + +from pymc3.blocking import DictToArrayBijection from . import models -from pymc3.step_methods.hmc import leapfrog, Hamiltonian +from pymc3.step_methods.hmc.base_hmc import BaseHMC from .checks import close_to -from ..blocking import DictToArrayBijection def test_leapfrog_reversible(): n = 3 start, model, _ = models.non_normal(n) - - with model: - h = pm.find_hessian(start, model=model) - step = pm.HamiltonianMC(model.vars, h, model=model) - + step = BaseHMC(vars=model.vars, model=model) bij = DictToArrayBijection(step.ordering, start) - - logp, dlogp = list(map(bij.mapf, step.fs)) - H = Hamiltonian(logp, dlogp, step.potential) - q0 = bij.map(start) p0 = np.ones(n) * .05 - for e in [.01, .1, 1.2]: - for L in [1, 2, 3, 4, 20]: + + for epsilon in [.01, .1, 1.2]: + for n_steps in [1, 2, 3, 4, 20]: q, p = q0, p0 - q, p = leapfrog(H, q, p, L, e) - q, p = leapfrog(H, q, -p, L, e) + q, p, _ = step.leapfrog(q, p, np.array(epsilon), np.array(n_steps, dtype='int32')) + q, p, _ = step.leapfrog(q, -p, np.array(epsilon), np.array(n_steps, dtype='int32')) - close_to(q, q0, 1e-8, str((L, e))) - close_to(-p, p0, 1e-8, str((L, e))) + close_to(q, q0, 1e-8, str((n_steps, epsilon))) + close_to(-p, p0, 1e-8, str((n_steps, epsilon))) diff --git a/pymc3/tests/test_step.py b/pymc3/tests/test_step.py index 99cb9b1dd5..924bd6ab29 100644 --- a/pymc3/tests/test_step.py +++ b/pymc3/tests/test_step.py @@ -1,6 +1,10 @@ import os import unittest +from numpy.testing import assert_array_almost_equal +import numpy as np +from tqdm import tqdm + from .checks import close_to from .models import simple_categorical, mv_simple, mv_simple_discrete, simple_2model from pymc3.sampling import assign_step_methods, sample @@ -10,10 +14,6 @@ MultivariateNormalProposal, HamiltonianMC) from pymc3.distributions import Binomial, Normal, Bernoulli, Categorical -from numpy.testing import assert_array_almost_equal -import numpy as np -from tqdm import tqdm - class TestStepMethods(object): # yield test doesn't work subclassing unittest.TestCase master_samples = { @@ -128,7 +128,7 @@ def check_trace(self, step_method): if not benchmarking: assert_array_almost_equal(trace.get_values('x'), self.master_samples[step_method]) - def check_stat(self, check, trace): + def check_stat(self, check, trace, name): for (var, stat, value, bound) in check: s = stat(trace[var][2000:], axis=0) close_to(s, value, bound) @@ -153,7 +153,7 @@ def test_step_continuous(self): ) for step in steps: trace = sample(8000, step=step, start=start, model=model, random_seed=1) - yield self.check_stat, check, trace + yield self.check_stat, check, trace, step.__class__.__name__ def test_step_discrete(self): start, model, (mu, C) = mv_simple_discrete() @@ -166,7 +166,7 @@ def test_step_discrete(self): ) for step in steps: trace = sample(20000, step=step, start=start, model=model, random_seed=1) - self.check_stat(check, trace) + yield self.check_stat, check, trace, step.__class__.__name__ def test_step_categorical(self): start, model, (mu, C) = simple_categorical() @@ -180,7 +180,7 @@ def test_step_categorical(self): ) for step in steps: trace = sample(8000, step=step, start=start, model=model, random_seed=1) - self.check_stat(check, trace) + yield self.check_stat, check, trace, step.__class__.__name__ class TestCompoundStep(unittest.TestCase): diff --git a/pymc3/theanof.py b/pymc3/theanof.py index 04289aabbb..a391b198fc 100644 --- a/pymc3/theanof.py +++ b/pymc3/theanof.py @@ -210,8 +210,8 @@ def reshape_t(x, shape): class CallableTensor(object): - """Turns a symbolic variable with one input into a function that returns symbolic arguments with the one variable replaced with the input. - + """Turns a symbolic variable with one input into a function that returns symbolic arguments + with the one variable replaced with the input. """ def __init__(self, tensor): From 140a80c8f2a6949c90ba935d0f1199afa46b1fc0 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 3 Dec 2016 13:47:31 -0500 Subject: [PATCH 12/83] Reformat docs --- pymc3/step_methods/hmc/base_hmc.py | 33 ++++++++-------- pymc3/step_methods/hmc/hmc.py | 14 +++---- pymc3/step_methods/hmc/nuts.py | 22 +++++------ pymc3/step_methods/hmc/quadpotential.py | 18 ++++----- pymc3/step_methods/hmc/trajectory.py | 52 ++++++++++++------------- 5 files changed, 70 insertions(+), 69 deletions(-) diff --git a/pymc3/step_methods/hmc/base_hmc.py b/pymc3/step_methods/hmc/base_hmc.py index 7d87f5d3c8..0c594b09e8 100644 --- a/pymc3/step_methods/hmc/base_hmc.py +++ b/pymc3/step_methods/hmc/base_hmc.py @@ -12,24 +12,25 @@ class BaseHMC(ArrayStepShared): def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, model=None, blocked=True, use_single_leapfrog=False, **theano_kwargs): - """ + """Superclass to implement Hamiltonian/hybrid monte carlo + Parameters ---------- - vars : list of theano variables - scaling : array_like, ndim = {1,2} - Scaling for momentum distribution. 1d arrays interpreted matrix diagonal. - step_scale : float, default=0.25 - Size of steps to take, automatically scaled down by 1/n**(1/4) - is_cov : bool, default=False - Treat scaling as a covariance matrix/vector if True, else treat it as a - precision matrix/vector - state - State object - model : pymc3 Model instance. default=Context model - blocked: Boolean, default True - use_single_leapfrog: Boolean, will leapfrog steps take a single step at a time. - default False. - **theano_kwargs: passed to theano functions + vars : list of theano variables + scaling : array_like, ndim = {1,2} + Scaling for momentum distribution. 1d arrays interpreted matrix diagonal. + step_scale : float, default=0.25 + Size of steps to take, automatically scaled down by 1/n**(1/4) + is_cov : bool, default=False + Treat scaling as a covariance matrix/vector if True, else treat it as a + precision matrix/vector + state + State object + model : pymc3 Model instance. default=Context model + blocked: Boolean, default True + use_single_leapfrog: Boolean, will leapfrog steps take a single step at a time. + default False. + **theano_kwargs: passed to theano functions """ model = modelcontext(model) diff --git a/pymc3/step_methods/hmc/hmc.py b/pymc3/step_methods/hmc/hmc.py index 70a042f263..1e0b2c3dd4 100644 --- a/pymc3/step_methods/hmc/hmc.py +++ b/pymc3/step_methods/hmc/hmc.py @@ -27,13 +27,13 @@ def __init__(self, vars=None, path_length=2., step_rand=unif, **kwargs): """ Parameters ---------- - vars : list of theano variables - path_length : float, default=2 - total length to travel - step_rand : function float -> float, default=unif - A function which takes the step size and returns an new one used to - randomize the step size at each iteration. - **kwargs : passed to BaseHMC + vars : list of theano variables + path_length : float, default=2 + total length to travel + step_rand : function float -> float, default=unif + A function which takes the step size and returns an new one used to + randomize the step size at each iteration. + **kwargs : passed to BaseHMC """ super(HamiltonianMC, self).__init__(vars, **kwargs) self.path_length = path_length diff --git a/pymc3/step_methods/hmc/nuts.py b/pymc3/step_methods/hmc/nuts.py index e22a3cb8ec..d171159cd9 100644 --- a/pymc3/step_methods/hmc/nuts.py +++ b/pymc3/step_methods/hmc/nuts.py @@ -28,17 +28,17 @@ def __init__(self, vars=None, Emax=1000, target_accept=0.8, """ Parameters ---------- - vars : list of Theano variables, default continuous vars - Emax : float, default 1000 - maximum energy - target_accept : float (0,1) default .8 - target for avg accept probability between final branch and initial position - gamma : float, default .05 - k : float (.5,1) default .75 - scaling of speed of adaptation - t0 : int, default 10 - slows inital adapatation - kwargs: passed to BaseHMC + vars : list of Theano variables, default continuous vars + Emax : float, default 1000 + maximum energy + target_accept : float (0,1) default .8 + target for avg accept probability between final branch and initial position + gamma : float, default .05 + k : float (.5,1) default .75 + scaling of speed of adaptation + t0 : int, default 10 + slows inital adapatation + kwargs: passed to BaseHMC """ super(NUTS, self).__init__(vars, use_single_leapfrog=True, **kwargs) diff --git a/pymc3/step_methods/hmc/quadpotential.py b/pymc3/step_methods/hmc/quadpotential.py index e12fe1dcbc..0c85d2c214 100644 --- a/pymc3/step_methods/hmc/quadpotential.py +++ b/pymc3/step_methods/hmc/quadpotential.py @@ -14,18 +14,18 @@ def quad_potential(C, is_cov, as_cov): """ Parameters ---------- - C : arraylike, 0 <= ndim <= 2 - scaling matrix for the potential - vector treated as diagonal matrix - is_cov : Boolean - whether C is provided as a covariance matrix or hessian - as_cov : Boolean - whether the random draws should come from the normal dist - using the covariance matrix above or the inverse + C : arraylike, 0 <= ndim <= 2 + scaling matrix for the potential + vector treated as diagonal matrix + is_cov : Boolean + whether C is provided as a covariance matrix or hessian + as_cov : Boolean + whether the random draws should come from the normal dist + using the covariance matrix above or the inverse Returns ------- - q : Quadpotential + q : Quadpotential """ if issparse(C) and is_cov != as_cov: diff --git a/pymc3/step_methods/hmc/trajectory.py b/pymc3/step_methods/hmc/trajectory.py index b64790a21a..ebc8c44d5c 100644 --- a/pymc3/step_methods/hmc/trajectory.py +++ b/pymc3/step_methods/hmc/trajectory.py @@ -14,15 +14,15 @@ def _theano_hamiltonian(model_vars, shared, logpt, potential): Parameters ---------- - model_vars: array of variables to be sampled - shared theano tensors that are already shared - logpt: model log probability - potential: hamiltonian potential + model_vars : array of variables to be sampled + shared : theano tensors that are already shared + logpt : model log probability + potential : hamiltonian potential Returns ------- - Hamiltonian: namedtuple with log pdf, gradient of log pdf, and potential functions - q: Starting position variable. + Hamiltonian : namedtuple with log pdf, gradient of log pdf, and potential functions + q : Starting position variable. """ dlogp = gradient(logpt, model_vars) (logp, dlogp), q = join_nonshared_inputs([logpt, dlogp], model_vars, shared) @@ -36,14 +36,14 @@ def _theano_energy_function(H, q, **theano_kwargs): Parameters ---------- - H: Hamiltonian namedtuple - q: theano variable, starting position - theano_kwargs: passed to theano.function + H : Hamiltonian namedtuple + q : theano variable, starting position + theano_kwargs : passed to theano.function Returns ------- - energy_function: theano function that computes the energy at a point (p, q) in phase space - p: Starting momentum variable. + energy_function : theano function that computes the energy at a point (p, q) in phase space + p : Starting momentum variable. """ p = tt.dvector('p') p.tag.test_value = q.tag.test_value @@ -91,19 +91,19 @@ def get_theano_hamiltonian_functions(model_vars, shared, logpt, potential, Parameters ---------- model_vars : array of variables to be sampled - shared theano tensors that are already shared - logpt: model log probability - potential: hamiltonian potential + shared : theano tensors that are already shared + logpt : model log probability + potential : Hamiltonian potential theano_kwargs : dictionary of keyword arguments to pass to theano functions - use_single_leapfrog: Boolean, if only 1 integration step is done at a time (as in NUTS), - this provides a ~2x speedup + use_single_leapfrog : Boolean, if only 1 integration step is done at a time (as in NUTS), + this provides a ~2x speedup Returns ------- - H: Hamiltonian namedtuple - energy_function: theano function computing energy at a point in phase space - leapfrog_integrator: theano function integrating the Hamiltonian from a point in phase space - theano_variables: dictionary of variables used in the computation graph which may be useful + H : Hamiltonian namedtuple + energy_function : theano function computing energy at a point in phase space + leapfrog_integrator : theano function integrating the Hamiltonian from a point in phase space + theano_variables : dictionary of variables used in the computation graph which may be useful """ H, q = _theano_hamiltonian(model_vars, shared, logpt, potential) energy_function, p = _theano_energy_function(H, q, **theano_kwargs) @@ -137,18 +137,18 @@ def leapfrog(H, q, p, epsilon, n_steps): ---------- H : Hamiltonian instance. Tuple of `logp, dlogp, potential`. - q: Theano.tensor + q : Theano.tensor initial position vector - p: Theano.tensor + p : Theano.tensor initial momentum vector - epsilon: float, step size - n_steps: int, number of iterations + epsilon : float, step size + n_steps : int, number of iterations Returns ------- - position: Theano.tensor + position : Theano.tensor position estimate at time :math:`n \cdot e`. - momentum: Theano.tensor + momentum : Theano.tensor momentum estimate at time :math:`n \cdot e`. """ def full_update(p, q): From 168b1131c3d87d0a50f57a72f9c6a4426fb79ebf Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 9 Dec 2016 04:00:35 +0300 Subject: [PATCH 13/83] added replacements class and mean field approximation --- pymc3/variational/replacements.py | 184 ++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 pymc3/variational/replacements.py diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py new file mode 100644 index 0000000000..a97ab41e41 --- /dev/null +++ b/pymc3/variational/replacements.py @@ -0,0 +1,184 @@ +import collections +import theano.tensor as tt +import theano +from ..theanof import tt_rng +from ..distributions.dist_math import rho2sd, log_normal3 +import numpy as np + + +def flatten(tensors): + joined = tt.concatenate([var.ravel() for var in tensors]) + return joined + + +class Replacement(object): + def __init__(self, model, local=None, population=None): + if local is None: + local = dict() + if population is None: + population = dict() + self.population = population + self.model = model + self.local_x = [] + self._prepare_local_dict() + self.stochastic_replacements, \ + self.global_dict = \ + self.create_mapping(model, local) + + def _prepare_local_dict(self): + self.local_dict = collections.OrderedDict() + self.local_dict['means'] = collections.OrderedDict() + self.local_dict['rhos'] = collections.OrderedDict() + + def known_node(self, _for_, mu, rho): + e = tt_rng().normal(rho.shape) + v = mu + rho2sd(rho) * e + self.local_dict['means'][_for_.name] = mu + self.local_dict['rhos'][_for_.name] = rho + self.local_x.append(v) + return v + + def names2nodes(self, names): + return [self.model[n] for n in names] + + def create_mapping(self, model, local): + # returns tuple(mapping, dict with shared trainable params) + raise NotImplementedError + + @property + def deterministic_replacements(self): + """Method specific deterministic replacements + """ + raise NotImplementedError + + @property + def params(self): + """Method specific parametrization + """ + raise NotImplementedError + + @property + def log_q_W_local(self): + x = flatten(self.local_x) + mu = flatten(self.local_dict['means'].values()) + rho = flatten(self.local_dict['rhos'].values()) + _log_q_W_local_ = tt.sum(log_normal3(x, mu, rho)) + return self.apply_replacements(_log_q_W_local_) + + @property + def log_q_W_global(self): + """Method specific log_q_W_global + """ + raise NotImplementedError + + @property + def log_q_W(self): + return self.log_q_W_global + self.log_q_W_local + + @property + def log_p_D(self): + _log_p_D_ = tt.add( + *map(self.weighted_likelihood, self.model.observed_RVs) + ) + return self.apply_replacements(_log_p_D_) + + @property + def log_p_W(self): + _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) + return self.apply_replacements(_log_p_W_) + + def apply_replacements(self, node, deterministic=False): + if deterministic: + return theano.clone( + node, self.deterministic_replacements, strict=False) + else: + return theano.clone( + node, self.stochastic_replacements, strict=False) + + def weighted_likelihood(self, var): + tot = self.population.get( + var, self.population.get(var.name)) + logpt = tt.sum(var.logpt) + if tot is not None: + tot = tt.as_tensor(tot) + logpt *= tot + if var.ndim >= 1: + logpt /= var.shape[0] + return logpt + + def sample_elbo(self, samples=1, pi=1): + samples = tt.as_tensor(samples) + pi = tt.as_tensor(pi) + _elbo_ = self.log_p_D + pi * (self.log_p_W - self.log_q_W) + elbos, updates = theano.scan(fn=lambda: _elbo_, + outputs_info=None, + n_steps=samples) + return elbos, updates + + +class MeanField(Replacement): + @staticmethod + def random_node(old): + """Creates random node with shared params + + Parameters + ---------- + old : pm.FreeRV + + Returns + ------- + tuple : (new node, shared mu, shared rho) + """ + if len(old.broadcastable) > 0: + rho = theano.shared( + np.ones(old.tag.test_value.shape), + name='{}_rho_shared'.format(old.name), + broadcastable=old.broadcastable) + mu = theano.shared( + old.tag.test_value, + name='{}_mu_shared'.format(old.name), + broadcastable=old.broadcastable) + e = tt.patternbroadcast( + tt_rng().normal(rho.shape), old.broadcastable) + else: + rho = theano.shared( + np.ones(old.tag.test_value.shape), + name='{}_rho_shared'.format(old.name)) + mu = theano.shared( + old.tag.test_value, + name='{}_mu_shared'.format(old.name)) + e = tt_rng().normal(rho.shape) + return mu + rho2sd(rho) * e, mu, rho + + def create_mapping(self, model, local): + replacements = collections.OrderedDict() + global_means = collections.OrderedDict() + global_rhos = collections.OrderedDict() + for var in model.vars: + if var in local: + v = self.known_node(var, *local[var]) + else: + v, mu, rho = self.random_node(var) + global_means[var.name] = mu + global_rhos[var.name] = rho + replacements[var] = v + return (replacements, + dict(means=global_means, rhos=global_rhos)) + + @property + def log_q_W_global(self): + x = flatten(self.names2nodes(self.global_dict['means'].keys())) + mu = flatten(self.global_dict['means'].values()) + rho = flatten(self.global_dict['rhos'].values()) + _log_q_W_global_ = tt.sum(log_normal3(x, mu, rho)) + return self.apply_replacements(_log_q_W_global_) + + @property + def params(self): + return (list(self.global_dict['means'].values()) + + list(self.global_dict['rhos'].values())) + + def deterministic_replacements(self): + return collections.OrderedDict( + [(self.model[k], v for k, v in self.global_dict.items())] + ) From c1211a6a9f37bcb26cfdf4751e4328cea20dbfd9 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 9 Dec 2016 04:02:05 +0300 Subject: [PATCH 14/83] moved local to local constructor --- pymc3/variational/replacements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index a97ab41e41..369b0e9404 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -19,13 +19,13 @@ def __init__(self, model, local=None, population=None): population = dict() self.population = population self.model = model - self.local_x = [] self._prepare_local_dict() self.stochastic_replacements, \ self.global_dict = \ self.create_mapping(model, local) def _prepare_local_dict(self): + self.local_x = [] self.local_dict = collections.OrderedDict() self.local_dict['means'] = collections.OrderedDict() self.local_dict['rhos'] = collections.OrderedDict() From 96905626906234fef8bb442771f4ea3638f25661 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 9 Dec 2016 04:09:28 +0300 Subject: [PATCH 15/83] property for deterministic replacements --- pymc3/variational/replacements.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 369b0e9404..cf60332fc7 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -178,6 +178,7 @@ def params(self): return (list(self.global_dict['means'].values()) + list(self.global_dict['rhos'].values())) + @property def deterministic_replacements(self): return collections.OrderedDict( [(self.model[k], v for k, v in self.global_dict.items())] From 34da7c85ac44a24cdc53581f8a425cb41fe321fd Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 9 Dec 2016 15:16:36 +0300 Subject: [PATCH 16/83] refactored replacements to make them more unitary --- pymc3/variational/replacements.py | 95 ++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index cf60332fc7..dd7c76603f 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -12,37 +12,55 @@ def flatten(tensors): class Replacement(object): - def __init__(self, model, local=None, population=None): + def __init__(self, model, population=None, local=None): if local is None: local = dict() if population is None: population = dict() self.population = population self.model = model - self._prepare_local_dict() - self.stochastic_replacements, \ - self.global_dict = \ - self.create_mapping(model, local) - - def _prepare_local_dict(self): - self.local_x = [] - self.local_dict = collections.OrderedDict() - self.local_dict['means'] = collections.OrderedDict() - self.local_dict['rhos'] = collections.OrderedDict() - - def known_node(self, _for_, mu, rho): + s, g, l = self.create_mapping(model, local) + self.stochastic_replacements = s + self.global_dict = g + self.local_dict = l + + @staticmethod + def new_local_dict(): + local_dict = dict( + means=collections.OrderedDict(), + rhos=collections.OrderedDict(), + x=list() + ) + return local_dict + + @staticmethod + def new_global_dict(): + raise NotImplementedError + + @staticmethod + def known_node(local_dict, node, mu, rho): e = tt_rng().normal(rho.shape) v = mu + rho2sd(rho) * e - self.local_dict['means'][_for_.name] = mu - self.local_dict['rhos'][_for_.name] = rho - self.local_x.append(v) + local_dict['means'][node.name] = mu + local_dict['rhos'][node.name] = rho + local_dict['x'].append(v) return v def names2nodes(self, names): return [self.model[n] for n in names] def create_mapping(self, model, local): - # returns tuple(mapping, dict with shared trainable params) + """ + + Parameters + ---------- + model - pm.Model + local - local_RV + + Returns + ------- + replacements, global_dict, local_dict + """ raise NotImplementedError @property @@ -59,7 +77,7 @@ def params(self): @property def log_q_W_local(self): - x = flatten(self.local_x) + x = flatten(self.local_dict['x']) mu = flatten(self.local_dict['means'].values()) rho = flatten(self.local_dict['rhos'].values()) _log_q_W_local_ = tt.sum(log_normal3(x, mu, rho)) @@ -102,8 +120,7 @@ def weighted_likelihood(self, var): if tot is not None: tot = tt.as_tensor(tot) logpt *= tot - if var.ndim >= 1: - logpt /= var.shape[0] + logpt /= var.size return logpt def sample_elbo(self, samples=1, pi=1): @@ -118,16 +135,18 @@ def sample_elbo(self, samples=1, pi=1): class MeanField(Replacement): @staticmethod - def random_node(old): - """Creates random node with shared params + def random_node(global_dict, old): + """Creates random node with shared params and + places shared parameters to global dict Parameters ---------- + global_dict : dict - placeholder for parameters old : pm.FreeRV Returns ------- - tuple : (new node, shared mu, shared rho) + tt.Variable : new node """ if len(old.broadcastable) > 0: rho = theano.shared( @@ -148,26 +167,36 @@ def random_node(old): old.tag.test_value, name='{}_mu_shared'.format(old.name)) e = tt_rng().normal(rho.shape) - return mu + rho2sd(rho) * e, mu, rho + v = mu + rho2sd(rho) * e + global_dict['means'][old.name] = mu + global_dict['rhos'][old.name] = rho + global_dict['x'].append(v) + return v + + @staticmethod + def new_global_dict(): + global_dict = dict( + x=list(), + means=collections.OrderedDict(), + rhos=collections.OrderedDict() + ) + return global_dict def create_mapping(self, model, local): + local_dict = self.new_local_dict() + global_dict = self.new_global_dict() replacements = collections.OrderedDict() - global_means = collections.OrderedDict() - global_rhos = collections.OrderedDict() for var in model.vars: if var in local: - v = self.known_node(var, *local[var]) + v = self.known_node(local_dict, var, *local[var]) else: - v, mu, rho = self.random_node(var) - global_means[var.name] = mu - global_rhos[var.name] = rho + v = self.random_node(global_dict, var) replacements[var] = v - return (replacements, - dict(means=global_means, rhos=global_rhos)) + return replacements, global_dict, local_dict @property def log_q_W_global(self): - x = flatten(self.names2nodes(self.global_dict['means'].keys())) + x = flatten(self.global_dict['x']) mu = flatten(self.global_dict['means'].values()) rho = flatten(self.global_dict['rhos'].values()) _log_q_W_global_ = tt.sum(log_normal3(x, mu, rho)) From 07a248a037dd9c489249469ab94ff247b33fcb8f Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 9 Dec 2016 00:32:40 +0300 Subject: [PATCH 17/83] shape problem when sampling --- pymc3/tests/test_distributions_random.py | 30 ++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/pymc3/tests/test_distributions_random.py b/pymc3/tests/test_distributions_random.py index 20da35fae3..3904fa1fa6 100644 --- a/pymc3/tests/test_distributions_random.py +++ b/pymc3/tests/test_distributions_random.py @@ -96,20 +96,22 @@ def __init__(self, *args, **kwargs): super(BaseTestCases.BaseTestCase, self).__init__(*args, **kwargs) self.model = pm.Model() - def get_random_variable(self, shape, with_vector_params=False): + def get_random_variable(self, shape, with_vector_params=False, name=None): if with_vector_params: params = {key: value * np.ones(self.shape, dtype=np.dtype(type(value))) for key, value in self.params.items()} else: params = self.params - name = self.distribution.__name__ + if name is None: + name = self.distribution.__name__ with self.model: if shape is None: return self.distribution(name, transform=None, **params) else: return self.distribution(name, shape=shape, transform=None, **params) - def sample_random_variable(self, random_variable, size): + @staticmethod + def sample_random_variable(random_variable, size): try: return random_variable.random(size=size) except AttributeError: @@ -145,7 +147,7 @@ def test_parameters_1d_shape(self): else: expected = np.atleast_1d(size).tolist() expected.append(self.shape) - actual = np.atleast_1d(self.sample_random_variable(rv, size)).shape + actual = self.sample_random_variable(rv, size).shape self.assertSequenceEqual(expected, actual) def test_broadcast_shape(self): @@ -160,6 +162,26 @@ def test_broadcast_shape(self): actual = np.atleast_1d(self.sample_random_variable(rv, size)).shape self.assertSequenceEqual(expected, actual) + def test_different_shapes_and_sample_sizes(self): + shapes = [(), (1,), (1, 1), (1, 2), (10, 10, 1), (10, 10, 2)] + prefix = self.distribution.__name__ + expected = [] + actual = [] + for shape in shapes: + rv = self.get_random_variable(shape, name='%s_%s' % (prefix, shape)) + for size in (None, 1, 5, (4, 5)): + if size is None: + s = [] + else: + try: + s = list(size) + except TypeError: + s = [size] + s.extend(shape) + expected.append(tuple(s)) + actual.append(self.sample_random_variable(rv, size).shape) + self.assertSequenceEqual(expected, actual) + class TestNormal(BaseTestCases.BaseTestCase): distribution = pm.Normal From 889b50e63aaf77b2b7317b13143b6cd8b4b39c0f Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sat, 10 Dec 2016 02:17:54 +0300 Subject: [PATCH 18/83] tests passed --- pymc3/distributions/discrete.py | 14 +++++++---- pymc3/distributions/distribution.py | 31 +++++++++++++++--------- pymc3/tests/test_distributions_random.py | 10 +++++--- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/pymc3/distributions/discrete.py b/pymc3/distributions/discrete.py index 8b1d0d988f..e92be57e60 100644 --- a/pymc3/distributions/discrete.py +++ b/pymc3/distributions/discrete.py @@ -6,7 +6,7 @@ from scipy import stats from .dist_math import bound, factln, binomln, betaln, logpow -from .distribution import Discrete, draw_values, generate_samples +from .distribution import Discrete, draw_values, generate_samples, reshape_sampled __all__ = ['Binomial', 'BetaBinomial', 'Bernoulli', 'Poisson', 'NegativeBinomial', 'ConstantDist', 'Constant', 'ZeroInflatedPoisson', @@ -250,7 +250,7 @@ def random(self, point=None, size=None, repeat=None): dist_shape=self.shape, size=size) g[g == 0] = np.finfo(float).eps # Just in case - return stats.poisson.rvs(g) + return reshape_sampled(stats.poisson.rvs(g), size, self.shape) def logp(self, value): mu = self.mu @@ -441,9 +441,11 @@ def logp(self, value): c = self.c return bound(0, tt.eq(value, c)) + def ConstantDist(*args, **kwargs): + import warnings warnings.warn("ConstantDist has been deprecated. In future, use Constant instead.", - DeprecationWarning) + DeprecationWarning) return Constant(*args, **kwargs) @@ -489,7 +491,8 @@ def random(self, point=None, size=None, repeat=None): g = generate_samples(stats.poisson.rvs, theta, dist_shape=self.shape, size=size) - return g * (np.random.random(np.squeeze(g.shape)) < psi) + sampled = g * (np.random.random(np.squeeze(g.shape)) < psi) + return reshape_sampled(sampled, size, self.shape) def logp(self, value): return tt.switch(value > 0, @@ -543,7 +546,8 @@ def random(self, point=None, size=None, repeat=None): dist_shape=self.shape, size=size) g[g == 0] = np.finfo(float).eps # Just in case - return stats.poisson.rvs(g) * (np.random.random(np.squeeze(g.shape)) < psi) + sampled = stats.poisson.rvs(g) * (np.random.random(np.squeeze(g.shape)) < psi) + return reshape_sampled(sampled, size, self.shape) def logp(self, value): return tt.switch(value > 0, diff --git a/pymc3/distributions/distribution.py b/pymc3/distributions/distribution.py index 61570ceaa3..f5bdb0cf15 100644 --- a/pymc3/distributions/distribution.py +++ b/pymc3/distributions/distribution.py @@ -10,9 +10,11 @@ __all__ = ['DensityDist', 'Distribution', 'Continuous', 'Discrete', 'NoDistribution', 'TensorType', 'draw_values'] + class _Unpickling(object): pass + class Distribution(object): """Statistical distribution""" def __new__(cls, name, *args, **kwargs): @@ -129,12 +131,10 @@ def __init__(self, logp, shape=(), dtype='float64', testval=0, *args, **kwargs): class MultivariateContinuous(Continuous): - pass class MultivariateDiscrete(Discrete): - pass @@ -265,6 +265,22 @@ def broadcast_shapes(*args): return tuple(x) +def infer_shape(shape): + try: + shape = tuple(shape or ()) + except TypeError: # If size is an int + shape = tuple((shape,)) + except ValueError: # If size is np.array + shape = tuple(shape) + return shape + + +def reshape_sampled(sampled, size, dist_shape): + dist_shape = infer_shape(dist_shape) + repeat_shape = infer_shape(size) + return np.reshape(sampled, repeat_shape + dist_shape) + + def replicate_samples(generator, size, repeats, *args, **kwargs): n = int(np.prod(repeats)) if n == 1: @@ -326,10 +342,7 @@ def generate_samples(generator, *args, **kwargs): else: prefix_shape = tuple(dist_shape) - try: - repeat_shape = tuple(size or ()) - except TypeError: # If size is an int - repeat_shape = tuple((size,)) + repeat_shape = infer_shape(size) if broadcast_shape == (1,) and prefix_shape == (): if size is not None: @@ -342,13 +355,9 @@ def generate_samples(generator, *args, **kwargs): broadcast_shape, repeat_shape + prefix_shape, *args, **kwargs) - if broadcast_shape == (1,) and not prefix_shape == (): - samples = np.reshape(samples, repeat_shape + prefix_shape) else: samples = replicate_samples(generator, broadcast_shape, prefix_shape, *args, **kwargs) - if broadcast_shape == (1,): - samples = np.reshape(samples, prefix_shape) - return samples + return reshape_sampled(samples, size, dist_shape) diff --git a/pymc3/tests/test_distributions_random.py b/pymc3/tests/test_distributions_random.py index 3904fa1fa6..f3500c1a01 100644 --- a/pymc3/tests/test_distributions_random.py +++ b/pymc3/tests/test_distributions_random.py @@ -178,8 +178,10 @@ def test_different_shapes_and_sample_sizes(self): except TypeError: s = [size] s.extend(shape) - expected.append(tuple(s)) - actual.append(self.sample_random_variable(rv, size).shape) + e = tuple(s) + a = self.sample_random_variable(rv, size).shape + expected.append(e) + actual.append(a) self.assertSequenceEqual(expected, actual) @@ -332,8 +334,8 @@ class TestCategorical(BaseTestCases.BaseTestCase): distribution = pm.Categorical params = {'p': np.ones(BaseTestCases.BaseTestCase.shape)} - def get_random_variable(self, shape, with_vector_params=False): # don't transform categories - return super(TestCategorical, self).get_random_variable(shape, with_vector_params=False) + def get_random_variable(self, shape, with_vector_params=False, **kwargs): # don't transform categories + return super(TestCategorical, self).get_random_variable(shape, with_vector_params=False, **kwargs) @attr('scalar_parameter_samples') From 0d486fb806e726deda5fc115425e0a434af133e3 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 13 Dec 2016 19:41:07 +0300 Subject: [PATCH 19/83] deleted unused modules --- pymc3/math.py | 9 ++- pymc3/variational/elbo.py | 70 -------------------- pymc3/variational/replacements.py | 6 +- pymc3/variational/utils.py | 103 ------------------------------ 4 files changed, 9 insertions(+), 179 deletions(-) delete mode 100644 pymc3/variational/elbo.py delete mode 100644 pymc3/variational/utils.py diff --git a/pymc3/math.py b/pymc3/math.py index 97c6d92b50..551a7ec9c9 100644 --- a/pymc3/math.py +++ b/pymc3/math.py @@ -2,7 +2,7 @@ import sys import theano import theano.tensor as tt -from theano.tensor import (constant, flatten, zeros_like, ones_like, stack, concatenate, sum, prod, +from theano.tensor import (constant, flatten as _flatten, zeros_like, ones_like, stack, concatenate, sum, prod, lt, gt, le, ge, eq, neq, switch, clip, where, and_, or_, abs_, exp, log, cos, sin, tan, cosh, sinh, tanh, sqr, sqrt, erf, erfinv, dot, maximum, minimum, sgn, ceil, floor) @@ -22,3 +22,10 @@ def invlogit(x, eps=sys.float_info.epsilon): def logit(p): return tt.log(p / (1 - p)) + + +def flatten(tensors, outdim=1): + if not isinstance(tensors, list): + return _flatten(tensors, outdim) + else: + return tt.concatenate([var.ravel() for var in tensors]) diff --git a/pymc3/variational/elbo.py b/pymc3/variational/elbo.py deleted file mode 100644 index 8b7c908742..0000000000 --- a/pymc3/variational/elbo.py +++ /dev/null @@ -1,70 +0,0 @@ -import theano.tensor as tt -import theano -from .utils import (variational_replacements, - apply_replacements, - flatten) -from ..distributions.dist_math import log_normal3 - -__all__ = [ - 'sample_elbo' -] - - -def sample_elbo(model, population=None, samples=1, pi=1, vp=None): - """ pi*KL[q(w|mu,rho)||p(w)] + E_q[log p(D|w)] - approximated by Monte Carlo sampling - - Parameters - ---------- - model : pymc3.Model - population : dict - maps observed_RV to its population size - if not provided defaults to full population - samples : number of Monte Carlo samples used for approximation, - defaults to 1 - pi : additional coefficient for KL[q(w|mu,rho)||p(w)] as proposed in [1]_ - vp : gelato.variational.utils.VariatioanalParams - tuple, holding nodes mappings with shared params, if None - new - will be created - - Returns - ------- - (elbos, updates, VariationalParams) - sampled elbos, updates for random streams, shared dicts - - Notes - ----- - You can pass tensors for `pi` and `samples` to control them while - training - - References - ---------- - .. [1] Charles Blundell et al: "Weight Uncertainty in Neural Networks" - arXiv preprint arXiv:1505.05424 - """ - if population is None: - population = dict() - if vp is None: - vp = variational_replacements(model.root) - x = flatten(vp.mapping.values()) - mu = flatten(vp.shared.means.values()) - rho = flatten(vp.shared.rhos.values()) - - def likelihood(var): - tot = population.get(var, population.get(var.name)) - logpt = tt.sum(var.logpt) - if tot is not None: - tot = tt.as_tensor(tot) - logpt *= tot / var.shape[0] - return logpt - - log_p_D = tt.add(*map(likelihood, model.root.observed_RVs)) - log_p_W = model.root.varlogpt + tt.sum(model.root.potentials) - log_q_W = tt.sum(log_normal3(x, mu, rho)) - _elbo_ = log_p_D + pi * (log_p_W - log_q_W) - _elbo_ = apply_replacements(_elbo_, vp) - - samples = tt.as_tensor(samples) - elbos, updates = theano.scan(fn=lambda: _elbo_, - outputs_info=None, - n_steps=samples) - return elbos, updates, vp diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index dd7c76603f..c379b44d8d 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -3,14 +3,10 @@ import theano from ..theanof import tt_rng from ..distributions.dist_math import rho2sd, log_normal3 +from ..math import flatten import numpy as np -def flatten(tensors): - joined = tt.concatenate([var.ravel() for var in tensors]) - return joined - - class Replacement(object): def __init__(self, model, population=None, local=None): if local is None: diff --git a/pymc3/variational/utils.py b/pymc3/variational/utils.py deleted file mode 100644 index 8e102b286b..0000000000 --- a/pymc3/variational/utils.py +++ /dev/null @@ -1,103 +0,0 @@ -from collections import namedtuple, OrderedDict - -import numpy as np -import theano -import theano.tensor as tt -from ..distributions.dist_math import rho2sd -from ..theanof import tt_rng - -SharedNodes = namedtuple('SharedNodes', 'means, rhos') - - -class VariationalParams(namedtuple('VariationalParamsBase', 'mapping,shared')): - @property - def params(self): - return list(self.shared.means.values())+list(self.shared.rhos.values()) - - -def random_node(old): - """Creates random node with shared params - - Parameters - ---------- - old : pm.FreeRV - - Returns - ------- - tuple : (new node, shared mu, shared rho) - """ - if len(old.broadcastable) > 0: - rho = theano.shared( - np.ones(old.tag.test_value.shape), - name='{}_rho_shared'.format(old.name), - broadcastable=old.broadcastable) - mu = theano.shared( - old.tag.test_value, - name='{}_mu_shared'.format(old.name), - broadcastable=old.broadcastable) - e = tt.patternbroadcast( - tt_rng().normal(rho.shape), old.broadcastable) - else: - rho = theano.shared( - np.ones(old.tag.test_value.shape), - name='{}_rho_shared'.format(old.name)) - mu = theano.shared( - old.tag.test_value, - name='{}_mu_shared'.format(old.name)) - e = tt_rng().normal(rho.shape) - return mu + rho2sd(rho) * e, mu, rho - - -def variational_replacements(model): - """Util for getting variational replacements - - Parameters - ---------- - model : pymc3.Model - - Returns - ------- - VariationalParams : (mapping, SharedNodes) - - Notes - ----- - Mappings and shared vars dicts are all OrderedDicts - """ - replacements = OrderedDict() - means = OrderedDict() - rhos = OrderedDict() - for var in model.vars: - v, mu, rho = random_node(var) - replacements[var] = v - means[var.name] = mu - rhos[var.name] = rho - return VariationalParams(replacements, SharedNodes(means, rhos)) - - -def apply_replacements(out, variational_params, deterministic=False): - """ - - Parameters - ---------- - out : target node of the graph for which we apply replacements - variational_params : VariationalParams - deterministic : bool - whether do deterministic or stochastic replacements - - Returns - ------- - tt.Variable - cloned node with applied replacements - """ - if deterministic: - replacements = OrderedDict(zip( - variational_params.mapping.keys(), - variational_params.shared.means.values() - )) - else: - replacements = variational_params.mapping - return theano.clone(out, replacements, strict=False) - - -def flatten(tensors): - joined = tt.concatenate([var.ravel() for var in tensors]) - return joined From 125f6adbf44efa8eb1f7dca67b40c165f7cb557b Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 13 Dec 2016 19:47:38 +0300 Subject: [PATCH 20/83] added replacement names for global/local dict --- pymc3/variational/replacements.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index c379b44d8d..4581f90ee5 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -20,17 +20,16 @@ def __init__(self, model, population=None, local=None): self.global_dict = g self.local_dict = l - @staticmethod - def new_local_dict(): + def new_local_dict(self): local_dict = dict( means=collections.OrderedDict(), rhos=collections.OrderedDict(), - x=list() + x=list(), + replacement=self.__class__.__name__ ) return local_dict - @staticmethod - def new_global_dict(): + def new_global_dict(self): raise NotImplementedError @staticmethod @@ -169,12 +168,12 @@ def random_node(global_dict, old): global_dict['x'].append(v) return v - @staticmethod - def new_global_dict(): + def new_global_dict(self): global_dict = dict( x=list(), means=collections.OrderedDict(), - rhos=collections.OrderedDict() + rhos=collections.OrderedDict(), + replacement=self.__class__.__name__ ) return global_dict From 69f07a159550de08685f907cbcb4b82aa61aceed Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Thu, 15 Dec 2016 20:20:14 +0300 Subject: [PATCH 21/83] refactored replacements --- pymc3/variational/replacements.py | 132 ++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 35 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 4581f90ee5..65cb876276 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -1,4 +1,5 @@ import collections +import functools import theano.tensor as tt import theano from ..theanof import tt_rng @@ -7,20 +8,38 @@ import numpy as np -class Replacement(object): - def __init__(self, model, population=None, local=None): - if local is None: - local = dict() +def replace_out(func): + @functools.wraps(func) + def wrapped(self, *args, **kwargs): + out = func(self, *args, **kwargs) + return self.apply_replacements(out) + return wrapped + + +class BaseReplacement(object): + def __init__(self, model, population=None, known=None): + if known is None: + known = dict() if population is None: population = dict() self.population = population self.model = model - s, g, l = self.create_mapping(model, local) + self.known = known + s, g, l = self.create_mapping() self.stochastic_replacements = s self.global_dict = g self.local_dict = l + def new_global_dict(self): + """ + :return: dict + """ + raise NotImplementedError + def new_local_dict(self): + """ + :return: dict + """ local_dict = dict( means=collections.OrderedDict(), rhos=collections.OrderedDict(), @@ -29,11 +48,21 @@ def new_local_dict(self): ) return local_dict - def new_global_dict(self): - raise NotImplementedError + def new_rep_glob_loc(self): + """ + :return: empty_replacements, new_global_dict, new_local_dict + """ + return collections.OrderedDict(), self.new_global_dict(), self.new_local_dict() @staticmethod - def known_node(local_dict, node, mu, rho): + def known_node(local_dict, node, *args): + """ + :param local_dict: placeholder for local params + :param node: node to be replaced + :param args: mu, rho + :return: replacement for given node + """ + mu, rho = args e = tt_rng().normal(rho.shape) v = mu + rho2sd(rho) * e local_dict['means'][node.name] = mu @@ -42,16 +71,14 @@ def known_node(local_dict, node, mu, rho): return v def names2nodes(self, names): - return [self.model[n] for n in names] - - def create_mapping(self, model, local): + """Create a list of nodes with names order + :param names: list + :return: list - ordered list of variables """ + return [self.model[n] for n in names] - Parameters - ---------- - model - pm.Model - local - local_RV - + def create_mapping(self): + """Implements creation of new replacements and parameters Returns ------- replacements, global_dict, local_dict @@ -60,28 +87,62 @@ def create_mapping(self, model, local): @property def deterministic_replacements(self): - """Method specific deterministic replacements + """ + :return: dict + """ + replacements = collections.OrderedDict() + replacements.update(self.deterministic_replacements_global) + replacements.update(self.deterministic_replacements_local) + return replacements + + @property + def deterministic_replacements_local(self): + """ + :return: dict + """ + return collections.OrderedDict( + [(self.model[k], v) for k, v in self.local_dict['means'].items()] + ) + + @property + def deterministic_replacements_global(self): + """ + :return: dict """ raise NotImplementedError @property def params(self): - """Method specific parametrization + """ + :return: list - shared params to fit + """ + return self.params_local + self.params_global + + @property + def params_local(self): + """ + :return: list - shared params for local replacements + """ + return [] + + @property + def params_global(self): + """ + :return: list - shared params for global replacements """ raise NotImplementedError @property + @replace_out def log_q_W_local(self): x = flatten(self.local_dict['x']) mu = flatten(self.local_dict['means'].values()) rho = flatten(self.local_dict['rhos'].values()) _log_q_W_local_ = tt.sum(log_normal3(x, mu, rho)) - return self.apply_replacements(_log_q_W_local_) + return _log_q_W_local_ @property def log_q_W_global(self): - """Method specific log_q_W_global - """ raise NotImplementedError @property @@ -89,16 +150,18 @@ def log_q_W(self): return self.log_q_W_global + self.log_q_W_local @property + @replace_out def log_p_D(self): _log_p_D_ = tt.add( *map(self.weighted_likelihood, self.model.observed_RVs) ) - return self.apply_replacements(_log_p_D_) + return _log_p_D_ @property + @replace_out def log_p_W(self): _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) - return self.apply_replacements(_log_p_W_) + return _log_p_W_ def apply_replacements(self, node, deterministic=False): if deterministic: @@ -128,7 +191,7 @@ def sample_elbo(self, samples=1, pi=1): return elbos, updates -class MeanField(Replacement): +class MeanField(BaseReplacement): @staticmethod def random_node(global_dict, old): """Creates random node with shared params and @@ -177,33 +240,32 @@ def new_global_dict(self): ) return global_dict - def create_mapping(self, model, local): - local_dict = self.new_local_dict() - global_dict = self.new_global_dict() - replacements = collections.OrderedDict() - for var in model.vars: - if var in local: - v = self.known_node(local_dict, var, *local[var]) + def create_mapping(self): + replacements, global_dict, local_dict = self.new_rep_glob_loc() + for var in self.model.vars: + if var in self.known: + v = self.known_node(local_dict, var, *self.known[var]) else: v = self.random_node(global_dict, var) replacements[var] = v return replacements, global_dict, local_dict @property + @replace_out def log_q_W_global(self): x = flatten(self.global_dict['x']) mu = flatten(self.global_dict['means'].values()) rho = flatten(self.global_dict['rhos'].values()) _log_q_W_global_ = tt.sum(log_normal3(x, mu, rho)) - return self.apply_replacements(_log_q_W_global_) + return _log_q_W_global_ @property - def params(self): + def params_global(self): return (list(self.global_dict['means'].values()) + list(self.global_dict['rhos'].values())) @property - def deterministic_replacements(self): + def deterministic_replacements_global(self): return collections.OrderedDict( - [(self.model[k], v for k, v in self.global_dict.items())] + [(self.model[k], v) for k, v in self.global_dict['means'].items()] ) From 9614bf9c69bdf6ca93d84bb12019e07dd4641e39 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Thu, 15 Dec 2016 21:40:53 +0300 Subject: [PATCH 22/83] refactored replacements --- pymc3/variational/replacements.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 65cb876276..0ff0f75b43 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -70,13 +70,6 @@ def known_node(local_dict, node, *args): local_dict['x'].append(v) return v - def names2nodes(self, names): - """Create a list of nodes with names order - :param names: list - :return: list - ordered list of variables - """ - return [self.model[n] for n in names] - def create_mapping(self): """Implements creation of new replacements and parameters Returns From 32a2eb7e3711b2e8de22ad76cc4532b03cd6af55 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 16 Dec 2016 01:40:04 +0300 Subject: [PATCH 23/83] refactored GARCH and added Mv(Gaussian/StudentT)RandomWalk (#1603) * refactored GARCH and added Mv(Gaussian/StudentT)RandomWalk * refactored garch logp * added docs * fix typo * even more typos * better description for tau --- pymc3/distributions/timeseries.py | 96 +++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/pymc3/distributions/timeseries.py b/pymc3/distributions/timeseries.py index 8dd2e282fb..fd418f603e 100644 --- a/pymc3/distributions/timeseries.py +++ b/pymc3/distributions/timeseries.py @@ -1,10 +1,18 @@ import theano.tensor as tt from theano import scan +from .multivariate import get_tau_cov, MvNormal, MvStudentT from .continuous import Normal, Flat from .distribution import Continuous -__all__ = ['AR1', 'GaussianRandomWalk', 'GARCH11', 'EulerMaruyama'] +__all__ = [ + 'AR1', + 'GaussianRandomWalk', + 'GARCH11', + 'EulerMaruyama', + 'MvGaussianRandomWalk', + 'MvStudentTRandomWalk' +] class AR1(Continuous): @@ -108,7 +116,8 @@ def __init__(self, omega=None, alpha_1=None, beta_1=None, self.initial_vol = initial_vol self.mean = 0 - def _get_volatility(self, x): + def get_volatility(self, x): + x = x[:-1] def volatility_update(x, vol, w, a, b): return tt.sqrt(w + a * tt.square(x) + b * tt.square(vol)) @@ -118,12 +127,11 @@ def volatility_update(x, vol, w, a, b): outputs_info=[self.initial_vol], non_sequences=[self.omega, self.alpha_1, self.beta_1]) - return vol + return tt.concatenate(self.initial_vol, vol) def logp(self, x): - vol = self._get_volatility(x[:-1]) - return (Normal.dist(0., sd=self.initial_vol).logp(x[0]) + - tt.sum(Normal.dist(0, sd=vol).logp(x[1:]))) + vol = self.get_volatility(x) + return tt.sum(Normal.dist(0, sd=vol).logp(x)) class EulerMaruyama(Continuous): @@ -151,3 +159,79 @@ def logp(self, x): mu = xt + self.dt * f sd = tt.sqrt(self.dt) * g return tt.sum(Normal.dist(mu=mu, sd=sd).logp(x[1:])) + + +class MvGaussianRandomWalk(Continuous): + """ + Multivariate Random Walk with Normal innovations + + Parameters + ---------- + mu : tensor + innovation drift, defaults to 0.0 + cov : tensor + pos def matrix, innovation covariance matrix + tau : tensor + pos def matrix, innovation precision (alternative to specifying cov) + init : distribution + distribution for initial value (Defaults to Flat()) + """ + def __init__(self, mu=0., cov=None, tau=None, init=Flat.dist(), + *args, **kwargs): + super(MvGaussianRandomWalk, self).__init__(*args, **kwargs) + tau, cov = get_tau_cov(mu, tau=tau, cov=cov) + self.tau = tau + self.cov = cov + self.mu = mu + self.init = init + self.mean = 0. + + def logp(self, x): + tau = self.tau + mu = self.mu + init = self.init + + x_im1 = x[:-1] + x_i = x[1:] + + innov_like = MvNormal.dist(mu=x_im1 + mu, tau=tau).logp(x_i) + return init.logp(x[0]) + tt.sum(innov_like) + + +class MvStudentTRandomWalk(Continuous): + """ + Multivariate Random Walk with StudentT innovations + + Parameters + ---------- + nu : degrees of freedom + mu : tensor + innovation drift, defaults to 0.0 + cov : tensor + pos def matrix, innovation covariance matrix + tau : tensor + pos def matrix, innovation precision (alternative to specifying cov) + init : distribution + distribution for initial value (Defaults to Flat()) + """ + def __init__(self, nu, mu=0., cov=None, tau=None, init=Flat.dist(), + *args, **kwargs): + super(MvStudentTRandomWalk, self).__init__(*args, **kwargs) + tau, cov = get_tau_cov(mu, tau=tau, cov=cov) + self.tau = tau + self.cov = cov + self.mu = mu + self.nu = nu + self.init = init + self.mean = 0. + + def logp(self, x): + cov = self.cov + mu = self.mu + nu = self.nu + init = self.init + + x_im1 = x[:-1] + x_i = x[1:] + innov_like = MvStudentT.dist(nu, cov, mu=x_im1 + mu).logp(x_i) + return init.logp(x[0]) + tt.sum(innov_like) From 0f2c38fced4d6f8a8372bd3fcb5bcf31f5b662f4 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 16 Dec 2016 02:18:09 +0300 Subject: [PATCH 24/83] added flatten_list --- pymc3/math.py | 9 +++------ pymc3/variational/replacements.py | 14 +++++++------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/pymc3/math.py b/pymc3/math.py index 551a7ec9c9..adb34bef7a 100644 --- a/pymc3/math.py +++ b/pymc3/math.py @@ -2,7 +2,7 @@ import sys import theano import theano.tensor as tt -from theano.tensor import (constant, flatten as _flatten, zeros_like, ones_like, stack, concatenate, sum, prod, +from theano.tensor import (constant, flatten, zeros_like, ones_like, stack, concatenate, sum, prod, lt, gt, le, ge, eq, neq, switch, clip, where, and_, or_, abs_, exp, log, cos, sin, tan, cosh, sinh, tanh, sqr, sqrt, erf, erfinv, dot, maximum, minimum, sgn, ceil, floor) @@ -24,8 +24,5 @@ def logit(p): return tt.log(p / (1 - p)) -def flatten(tensors, outdim=1): - if not isinstance(tensors, list): - return _flatten(tensors, outdim) - else: - return tt.concatenate([var.ravel() for var in tensors]) +def flatten_list(tensors): + return tt.concatenate([var.ravel() for var in tensors]) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 0ff0f75b43..000dc8b527 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -4,7 +4,7 @@ import theano from ..theanof import tt_rng from ..distributions.dist_math import rho2sd, log_normal3 -from ..math import flatten +from ..math import flatten_list import numpy as np @@ -128,9 +128,9 @@ def params_global(self): @property @replace_out def log_q_W_local(self): - x = flatten(self.local_dict['x']) - mu = flatten(self.local_dict['means'].values()) - rho = flatten(self.local_dict['rhos'].values()) + x = flatten_list(self.local_dict['x']) + mu = flatten_list(self.local_dict['means'].values()) + rho = flatten_list(self.local_dict['rhos'].values()) _log_q_W_local_ = tt.sum(log_normal3(x, mu, rho)) return _log_q_W_local_ @@ -246,9 +246,9 @@ def create_mapping(self): @property @replace_out def log_q_W_global(self): - x = flatten(self.global_dict['x']) - mu = flatten(self.global_dict['means'].values()) - rho = flatten(self.global_dict['rhos'].values()) + x = flatten_list(self.global_dict['x']) + mu = flatten_list(self.global_dict['means'].values()) + rho = flatten_list(self.global_dict['rhos'].values()) _log_q_W_global_ = tt.sum(log_normal3(x, mu, rho)) return _log_q_W_global_ From 63e57d7fae66c7a3597e4f2e0eab4056d354fc6a Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 16 Dec 2016 03:20:42 +0300 Subject: [PATCH 25/83] added tests --- pymc3/tests/test_replacements_mean_field.py | 39 ++++++++++++++ pymc3/theanof.py | 29 ++++++++++ pymc3/variational/replacements.py | 59 ++++++++++++--------- 3 files changed, 101 insertions(+), 26 deletions(-) create mode 100644 pymc3/tests/test_replacements_mean_field.py diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py new file mode 100644 index 0000000000..d9e8e3b9d9 --- /dev/null +++ b/pymc3/tests/test_replacements_mean_field.py @@ -0,0 +1,39 @@ +import unittest +import numpy as np +import theano +from pymc3 import Model, Normal +from pymc3.variational.replacements import MeanField + + +class TestMeanField(unittest.TestCase): + def test_elbo(self): + mu0 = 1.5 + sigma = 1.0 + y_obs = np.array([1.6, 1.4]) + + post_mu = 1.88 + post_sd = 1 + # Create a model for test + with Model() as model: + mu = Normal('mu', mu=mu0, sd=sigma) + Normal('y', mu=mu, sd=1, observed=y_obs) + + # Create variational gradient tensor + mean_field = MeanField(model) + elbos, updates = mean_field.sample_elbo(samples=10000) + + mean_field.global_dict['means']['mu'].set_value(post_mu) + mean_field.global_dict['rhos']['mu'].set_value(np.log(np.exp(post_sd) - 1)) + + f = theano.function([], elbos, updates=updates) + elbo_mc = f() + + # Exact value + elbo_true = (-0.5 * ( + 3 + 3 * post_mu**2 - 2 * (y_obs[0] + y_obs[1] + mu0) * post_mu + + y_obs[0]**2 + y_obs[1]**2 + mu0**2 + 3 * np.log(2 * np.pi)) + + 0.5 * (np.log(2 * np.pi) + 1)) + np.testing.assert_allclose(elbo_mc.mean(), elbo_true, rtol=0, atol=1e-1) + +if __name__ == '__main__': + unittest.main() diff --git a/pymc3/theanof.py b/pymc3/theanof.py index 569f91eb27..48649052ce 100644 --- a/pymc3/theanof.py +++ b/pymc3/theanof.py @@ -1,10 +1,13 @@ +import contextlib from .vartypes import typefilter, continuous_types from theano import theano, scalar, tensor as tt from theano.gof.graph import inputs +from theano.configparser import change_flags from .memoize import memoize from .blocking import ArrayOrdering from theano.sandbox.rng_mrg import MRG_RandomStreams + __all__ = ['gradient', 'hessian', 'hessian_diag', @@ -18,6 +21,17 @@ 'set_tt_rng'] +@contextlib.contextmanager +def no_test_val(): + """ + for functions use theano.configparser.change_flags + :return: + """ + theano.config.compute_test_value = 'off' + yield + theano.config.compute_test_value = 'raise' + + def inputvars(a): """ Get the inputs into a theano variables @@ -240,7 +254,19 @@ def __call__(self, input): scalar_identity = IdentityOp(scalar.upgrade_to_float, name='scalar_identity') identity = tt.Elemwise(scalar_identity, name='identity') + +@change_flags(compute_test_value='off') +def launch_rng(rng): + """or else test value is not available + :param rng: MRG_RandomStreams + :return: + """ + state = rng.rstate + rng.inc_rstate() + rng.set_rstate(state) + _tt_rng = MRG_RandomStreams() +launch_rng(_tt_rng) def tt_rng(): @@ -263,3 +289,6 @@ def set_tt_rng(new_rng): """ global _tt_rng _tt_rng = new_rng + launch_rng(_tt_rng) + + diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 000dc8b527..2ed4751f1c 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -12,6 +12,7 @@ def replace_out(func): @functools.wraps(func) def wrapped(self, *args, **kwargs): out = func(self, *args, **kwargs) + out = tt.as_tensor(out) return self.apply_replacements(out) return wrapped @@ -128,11 +129,14 @@ def params_global(self): @property @replace_out def log_q_W_local(self): - x = flatten_list(self.local_dict['x']) - mu = flatten_list(self.local_dict['means'].values()) - rho = flatten_list(self.local_dict['rhos'].values()) - _log_q_W_local_ = tt.sum(log_normal3(x, mu, rho)) - return _log_q_W_local_ + if self.local_dict['x']: + x = flatten_list(self.local_dict['x']) + mu = flatten_list(self.local_dict['means'].values()) + rho = flatten_list(self.local_dict['rhos'].values()) + _log_q_W_local_ = tt.sum(log_normal3(x, mu, rho)) + return _log_q_W_local_ + else: + return 0 @property def log_q_W_global(self): @@ -186,41 +190,41 @@ def sample_elbo(self, samples=1, pi=1): class MeanField(BaseReplacement): @staticmethod - def random_node(global_dict, old): + def random_node(global_dict, node): """Creates random node with shared params and places shared parameters to global dict Parameters ---------- global_dict : dict - placeholder for parameters - old : pm.FreeRV + node : pm.FreeRV Returns ------- tt.Variable : new node """ - if len(old.broadcastable) > 0: + if len(node.broadcastable) > 0: rho = theano.shared( - np.ones(old.tag.test_value.shape), - name='{}_rho_shared'.format(old.name), - broadcastable=old.broadcastable) + np.ones(node.tag.test_value.shape), + name='{}_rho_shared'.format(node.name), + broadcastable=node.broadcastable) mu = theano.shared( - old.tag.test_value, - name='{}_mu_shared'.format(old.name), - broadcastable=old.broadcastable) + node.tag.test_value, + name='{}_mu_shared'.format(node.name), + broadcastable=node.broadcastable) e = tt.patternbroadcast( - tt_rng().normal(rho.shape), old.broadcastable) + tt_rng().normal(rho.shape), node.broadcastable) else: rho = theano.shared( - np.ones(old.tag.test_value.shape), - name='{}_rho_shared'.format(old.name)) + np.ones(node.tag.test_value.shape), + name='{}_rho_shared'.format(node.name)) mu = theano.shared( - old.tag.test_value, - name='{}_mu_shared'.format(old.name)) + node.tag.test_value, + name='{}_mu_shared'.format(node.name)) e = tt_rng().normal(rho.shape) v = mu + rho2sd(rho) * e - global_dict['means'][old.name] = mu - global_dict['rhos'][old.name] = rho + global_dict['means'][node.name] = mu + global_dict['rhos'][node.name] = rho global_dict['x'].append(v) return v @@ -246,11 +250,14 @@ def create_mapping(self): @property @replace_out def log_q_W_global(self): - x = flatten_list(self.global_dict['x']) - mu = flatten_list(self.global_dict['means'].values()) - rho = flatten_list(self.global_dict['rhos'].values()) - _log_q_W_global_ = tt.sum(log_normal3(x, mu, rho)) - return _log_q_W_global_ + if self.global_dict['x']: + x = flatten_list(self.global_dict['x']) + mu = flatten_list(self.global_dict['means'].values()) + rho = flatten_list(self.global_dict['rhos'].values()) + _log_q_W_global_ = tt.sum(log_normal3(x, mu, rho)) + return _log_q_W_global_ + else: + return 0 @property def params_global(self): From 4d4cb8235ec254a476573185eacfb852176f7dec Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 16 Dec 2016 03:33:37 +0300 Subject: [PATCH 26/83] refactored local/global dicts --- pymc3/variational/replacements.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 2ed4751f1c..e98fb4d440 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -27,6 +27,9 @@ def __init__(self, model, population=None, known=None): self.model = model self.known = known s, g, l = self.create_mapping() + # add a name of replacement in case of some generic interface + g['__type__'] = self.__class__.__name__ + l['__type__'] = self.__class__.__name__ self.stochastic_replacements = s self.global_dict = g self.local_dict = l @@ -45,7 +48,6 @@ def new_local_dict(self): means=collections.OrderedDict(), rhos=collections.OrderedDict(), x=list(), - replacement=self.__class__.__name__ ) return local_dict @@ -73,6 +75,9 @@ def known_node(local_dict, node, *args): def create_mapping(self): """Implements creation of new replacements and parameters + starting poing is always the following: + >>> replacements, global_dict, local_dict = self.new_rep_glob_loc() + Just for not having any side effect Returns ------- replacements, global_dict, local_dict @@ -232,8 +237,7 @@ def new_global_dict(self): global_dict = dict( x=list(), means=collections.OrderedDict(), - rhos=collections.OrderedDict(), - replacement=self.__class__.__name__ + rhos=collections.OrderedDict() ) return global_dict From 82c7996dd17d203a68dba9a68d22f94cf7d1a15e Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 16 Dec 2016 03:37:24 +0300 Subject: [PATCH 27/83] moved __type__ assignment to better place --- pymc3/variational/replacements.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index e98fb4d440..3a8ae98223 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -27,9 +27,6 @@ def __init__(self, model, population=None, known=None): self.model = model self.known = known s, g, l = self.create_mapping() - # add a name of replacement in case of some generic interface - g['__type__'] = self.__class__.__name__ - l['__type__'] = self.__class__.__name__ self.stochastic_replacements = s self.global_dict = g self.local_dict = l @@ -55,7 +52,11 @@ def new_rep_glob_loc(self): """ :return: empty_replacements, new_global_dict, new_local_dict """ - return collections.OrderedDict(), self.new_global_dict(), self.new_local_dict() + g, l = self.new_global_dict(), self.new_local_dict() + # specify type for some probable generic purposes + g['__type__'] = self.__class__.__name__ + l['__type__'] = self.__class__.__name__ + return collections.OrderedDict(), g, l @staticmethod def known_node(local_dict, node, *args): From 2cd6bc5f3b9a84f47ddbdaa2c2dac84a023e91b5 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 16 Dec 2016 03:48:34 +0300 Subject: [PATCH 28/83] Don't do replacements too early or else it will be not possible to track mean elbo likelihood and others --- pymc3/variational/replacements.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 3a8ae98223..27d0dbfd1f 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -1,5 +1,4 @@ import collections -import functools import theano.tensor as tt import theano from ..theanof import tt_rng @@ -8,15 +7,6 @@ import numpy as np -def replace_out(func): - @functools.wraps(func) - def wrapped(self, *args, **kwargs): - out = func(self, *args, **kwargs) - out = tt.as_tensor(out) - return self.apply_replacements(out) - return wrapped - - class BaseReplacement(object): def __init__(self, model, population=None, known=None): if known is None: @@ -133,7 +123,6 @@ def params_global(self): raise NotImplementedError @property - @replace_out def log_q_W_local(self): if self.local_dict['x']: x = flatten_list(self.local_dict['x']) @@ -153,7 +142,6 @@ def log_q_W(self): return self.log_q_W_global + self.log_q_W_local @property - @replace_out def log_p_D(self): _log_p_D_ = tt.add( *map(self.weighted_likelihood, self.model.observed_RVs) @@ -161,7 +149,6 @@ def log_p_D(self): return _log_p_D_ @property - @replace_out def log_p_W(self): _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) return _log_p_W_ @@ -188,6 +175,7 @@ def sample_elbo(self, samples=1, pi=1): samples = tt.as_tensor(samples) pi = tt.as_tensor(pi) _elbo_ = self.log_p_D + pi * (self.log_p_W - self.log_q_W) + _elbo_ = self.apply_replacements(_elbo_) elbos, updates = theano.scan(fn=lambda: _elbo_, outputs_info=None, n_steps=samples) @@ -253,7 +241,6 @@ def create_mapping(self): return replacements, global_dict, local_dict @property - @replace_out def log_q_W_global(self): if self.global_dict['x']: x = flatten_list(self.global_dict['x']) From 4d810f20b4b44e8a2b6713f83d9d94db244e0990 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 16 Dec 2016 04:06:47 +0300 Subject: [PATCH 29/83] refactored docs --- pymc3/variational/replacements.py | 74 ++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 27d0dbfd1f..e09b536213 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -21,16 +21,12 @@ def __init__(self, model, population=None, known=None): self.global_dict = g self.local_dict = l - def new_global_dict(self): - """ - :return: dict - """ + @staticmethod + def new_global_dict(): raise NotImplementedError - def new_local_dict(self): - """ - :return: dict - """ + @staticmethod + def new_local_dict(): local_dict = dict( means=collections.OrderedDict(), rhos=collections.OrderedDict(), @@ -40,7 +36,9 @@ def new_local_dict(self): def new_rep_glob_loc(self): """ - :return: empty_replacements, new_global_dict, new_local_dict + Returns + ------- + empty_replacements, new_global_dict, new_local_dict """ g, l = self.new_global_dict(), self.new_local_dict() # specify type for some probable generic purposes @@ -51,10 +49,15 @@ def new_rep_glob_loc(self): @staticmethod def known_node(local_dict, node, *args): """ - :param local_dict: placeholder for local params - :param node: node to be replaced - :param args: mu, rho - :return: replacement for given node + Parameters + ---------- + local_dict: placeholder for local params + node : node to be replaced + args : mu, rho + + Returns + ------- + replacement for given node """ mu, rho = args e = tt_rng().normal(rho.shape) @@ -69,6 +72,7 @@ def create_mapping(self): starting poing is always the following: >>> replacements, global_dict, local_dict = self.new_rep_glob_loc() Just for not having any side effect + Returns ------- replacements, global_dict, local_dict @@ -77,9 +81,6 @@ def create_mapping(self): @property def deterministic_replacements(self): - """ - :return: dict - """ replacements = collections.OrderedDict() replacements.update(self.deterministic_replacements_global) replacements.update(self.deterministic_replacements_local) @@ -87,38 +88,38 @@ def deterministic_replacements(self): @property def deterministic_replacements_local(self): - """ - :return: dict - """ return collections.OrderedDict( [(self.model[k], v) for k, v in self.local_dict['means'].items()] ) @property def deterministic_replacements_global(self): - """ - :return: dict - """ raise NotImplementedError @property def params(self): """ - :return: list - shared params to fit + Returns + ------- + list - shared params to fit """ return self.params_local + self.params_global @property def params_local(self): """ - :return: list - shared params for local replacements + Returns + ------- + list - shared params for local replacements """ return [] @property def params_global(self): """ - :return: list - shared params for global replacements + Returns + ------- + list - shared params for global replacements """ raise NotImplementedError @@ -153,6 +154,10 @@ def log_p_W(self): _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) return _log_p_W_ + @property + def elbo(self): + return self.log_p_D + self.log_p_W - self.log_q_W + def apply_replacements(self, node, deterministic=False): if deterministic: return theano.clone( @@ -172,6 +177,22 @@ def weighted_likelihood(self, var): return logpt def sample_elbo(self, samples=1, pi=1): + """Output of this function should be used for fitting a model + + Parameters + ---------- + samples : Tensor - number of samples + pi : Tensor - weight of variational part + + + Notes + ----- + In case of samples == 1 updates are empty and can be ignored + + Returns + ------- + elbos, updates + """ samples = tt.as_tensor(samples) pi = tt.as_tensor(pi) _elbo_ = self.log_p_D + pi * (self.log_p_W - self.log_q_W) @@ -222,7 +243,8 @@ def random_node(global_dict, node): global_dict['x'].append(v) return v - def new_global_dict(self): + @staticmethod + def new_global_dict(): global_dict = dict( x=list(), means=collections.OrderedDict(), From 16a226b882af173497d9da5396a4b86b0567ff88 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sun, 18 Dec 2016 21:26:52 +0300 Subject: [PATCH 30/83] fixed memory consumption during test --- pymc3/tests/test_replacements_mean_field.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index d9e8e3b9d9..97e0d7a8f5 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -25,7 +25,7 @@ def test_elbo(self): mean_field.global_dict['means']['mu'].set_value(post_mu) mean_field.global_dict['rhos']['mu'].set_value(np.log(np.exp(post_sd) - 1)) - f = theano.function([], elbos, updates=updates) + f = theano.function([], elbos.mean(), updates=updates) elbo_mc = f() # Exact value @@ -33,7 +33,7 @@ def test_elbo(self): 3 + 3 * post_mu**2 - 2 * (y_obs[0] + y_obs[1] + mu0) * post_mu + y_obs[0]**2 + y_obs[1]**2 + mu0**2 + 3 * np.log(2 * np.pi)) + 0.5 * (np.log(2 * np.pi) + 1)) - np.testing.assert_allclose(elbo_mc.mean(), elbo_true, rtol=0, atol=1e-1) + np.testing.assert_allclose(elbo_mc, elbo_true, rtol=0, atol=1e-1) if __name__ == '__main__': unittest.main() From d8e98862e1975cba73165adea2a987bd18a4d51e Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Mon, 19 Dec 2016 00:55:55 +0300 Subject: [PATCH 31/83] set nmc samples to 1000 in test --- pymc3/tests/test_replacements_mean_field.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index 97e0d7a8f5..455a23fd21 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -20,7 +20,7 @@ def test_elbo(self): # Create variational gradient tensor mean_field = MeanField(model) - elbos, updates = mean_field.sample_elbo(samples=10000) + elbos, updates = mean_field.sample_elbo(samples=1000) mean_field.global_dict['means']['mu'].set_value(post_mu) mean_field.global_dict['rhos']['mu'].set_value(np.log(np.exp(post_sd) - 1)) From 1bb349ee8375087632787dae78090cc163d14143 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Mon, 19 Dec 2016 22:14:55 +0300 Subject: [PATCH 32/83] optimized code a lot --- pymc3/tests/test_replacements_mean_field.py | 12 +- pymc3/variational/replacements.py | 331 ++++++++------------ 2 files changed, 141 insertions(+), 202 deletions(-) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index 455a23fd21..64c4f66339 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -11,8 +11,8 @@ def test_elbo(self): sigma = 1.0 y_obs = np.array([1.6, 1.4]) - post_mu = 1.88 - post_sd = 1 + post_mu = np.array([1.88]) + post_sd = np.array([1]) # Create a model for test with Model() as model: mu = Normal('mu', mu=mu0, sd=sigma) @@ -20,12 +20,12 @@ def test_elbo(self): # Create variational gradient tensor mean_field = MeanField(model) - elbos, updates = mean_field.sample_elbo(samples=1000) + elbo = mean_field.sample_elbo(samples=10000) - mean_field.global_dict['means']['mu'].set_value(post_mu) - mean_field.global_dict['rhos']['mu'].set_value(np.log(np.exp(post_sd) - 1)) + mean_field.shared_params['mu'].set_value(post_mu) + mean_field.shared_params['rho'].set_value(np.log(np.exp(post_sd) - 1)) - f = theano.function([], elbos.mean(), updates=updates) + f = theano.function([], elbo) elbo_mc = f() # Exact value diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index e09b536213..15e467a209 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -2,11 +2,15 @@ import theano.tensor as tt import theano from ..theanof import tt_rng +from ..blocking import ArrayOrdering from ..distributions.dist_math import rho2sd, log_normal3 from ..math import flatten_list import numpy as np +FlatView = collections.namedtuple('FlatView', 'input, replacements') + + class BaseReplacement(object): def __init__(self, model, population=None, known=None): if known is None: @@ -16,155 +20,138 @@ def __init__(self, model, population=None, known=None): self.population = population self.model = model self.known = known - s, g, l = self.create_mapping() - self.stochastic_replacements = s - self.global_dict = g - self.local_dict = l + self.local_vars = [v for v in model.vars if v in known] + self.global_vars = [v for v in model.vars if v not in known] + self.order = ArrayOrdering(self.local_vars + self.global_vars) + inputvar = tt.vector('flat_view') + inputvar.tag.test_value = flatten_list(self.local_vars + self.global_vars).tag.test_value + replacements = {self.model.named_vars[name]: inputvar[slc].reshape(shape).astype(dtype) + for name, slc, shape, dtype in self.order.vmap} + self.flat_view = FlatView(inputvar, replacements) + self.view = {vm.var: vm for vm in self.order.vmap} + self.shared_params = self.create_shared_params() - @staticmethod - def new_global_dict(): - raise NotImplementedError - - @staticmethod - def new_local_dict(): - local_dict = dict( - means=collections.OrderedDict(), - rhos=collections.OrderedDict(), - x=list(), - ) - return local_dict + @property + def input(self): + return self.flat_view.input - def new_rep_glob_loc(self): - """ + def create_shared_params(self): + """Any stuff you need will be here Returns ------- - empty_replacements, new_global_dict, new_local_dict + dict : shared params """ - g, l = self.new_global_dict(), self.new_local_dict() - # specify type for some probable generic purposes - g['__type__'] = self.__class__.__name__ - l['__type__'] = self.__class__.__name__ - return collections.OrderedDict(), g, l - - @staticmethod - def known_node(local_dict, node, *args): + raise NotImplementedError + + def initial(self, samples=1, zeros=False): """ Parameters ---------- - local_dict: placeholder for local params - node : node to be replaced - args : mu, rho + samples : int - number of samples + zeros : bool - return zeros if True Returns ------- - replacement for given node + matrix/vector + sampled latent space """ - mu, rho = args - e = tt_rng().normal(rho.shape) - v = mu + rho2sd(rho) * e - local_dict['means'][node.name] = mu - local_dict['rhos'][node.name] = rho - local_dict['x'].append(v) - return v - - def create_mapping(self): - """Implements creation of new replacements and parameters - starting poing is always the following: - >>> replacements, global_dict, local_dict = self.new_rep_glob_loc() - Just for not having any side effect + if not zeros: + return tt_rng().normal((samples, self.total_size)) + else: + return tt.zeros((samples, self.total_size)) - Returns - ------- - replacements, global_dict, local_dict - """ + def view_from(self, space, name, subset='all'): + assert subset in {'all', 'local', 'global'} + if subset in {'all', 'local'}: + slc = self.view[name].slc + else: + s = self.view[name].slc.start + e = self.view[name].slc.stop + slc = slice(s - self.global_size, e - self.global_size) + return space[:, slc] + + def posterior(self, initial): + return tt.concatenate([ + self.posterior_local(initial[:, self.local_slc]), + self.posterior_global(initial[:, self.global_slc]) + ], axis=1) + + def posterior_global(self, initial): raise NotImplementedError + def __local_mu_rho(self): + mu = [] + rho = [] + for var in self.local_vars: + mu.append(self.known[var][0].ravel()) + rho.append(self.known[var][1].ravel()) + mu = tt.concatenate(mu) + rho = tt.concatenate(rho) + return mu, rho + + def posterior_local(self, initial): + if not self.known: + return initial + mu, rho = self.__local_mu_rho() + x = initial * rho2sd(rho) + mu + return x + + def to_flat_input(self, node): + return theano.clone(node, self.flat_view.replacements, strict=False) + @property - def deterministic_replacements(self): - replacements = collections.OrderedDict() - replacements.update(self.deterministic_replacements_global) - replacements.update(self.deterministic_replacements_local) - return replacements + def local_vmap(self): + return self.order.vmap[:len(self.local_vars)] @property - def deterministic_replacements_local(self): - return collections.OrderedDict( - [(self.model[k], v) for k, v in self.local_dict['means'].items()] - ) + def global_vmap(self): + return self.order.vmap[len(self.local_vars):] @property - def deterministic_replacements_global(self): - raise NotImplementedError + def local_size(self): + size = sum([0] + [v.size for v in self.local_vars]) + return size @property - def params(self): - """ - Returns - ------- - list - shared params to fit - """ - return self.params_local + self.params_global + def global_size(self): + return self.total_size - self.local_size @property - def params_local(self): - """ - Returns - ------- - list - shared params for local replacements - """ - return [] + def total_size(self): + return self.order.dimensions @property - def params_global(self): - """ - Returns - ------- - list - shared params for global replacements - """ - raise NotImplementedError + def local_slc(self): + return slice(0, self.local_size) @property - def log_q_W_local(self): - if self.local_dict['x']: - x = flatten_list(self.local_dict['x']) - mu = flatten_list(self.local_dict['means'].values()) - rho = flatten_list(self.local_dict['rhos'].values()) - _log_q_W_local_ = tt.sum(log_normal3(x, mu, rho)) - return _log_q_W_local_ - else: + def global_slc(self): + return slice(self.local_size, self.total_size) + + def log_q_W_local(self, posterior): + if not self.known: return 0 + mu, rho = self.__local_mu_rho() + logp = tt.sum(log_normal3(posterior, mu, rho), axis=1).mean(axis=0) + return logp - @property - def log_q_W_global(self): + def log_q_W_global(self, posterior): raise NotImplementedError - @property - def log_q_W(self): - return self.log_q_W_global + self.log_q_W_local + def log_q_W(self, posterior): + return self.log_q_W_global(posterior) + self.log_q_W_local(posterior) - @property - def log_p_D(self): + def log_p_D(self, posterior): _log_p_D_ = tt.add( *map(self.weighted_likelihood, self.model.observed_RVs) ) - return _log_p_D_ + _log_p_D_ = self.to_flat_input(_log_p_D_) - @property - def log_p_W(self): - _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) - return _log_p_W_ + def replace_log_p_D(post): + return theano.clone(_log_p_D_, {self.input: post}) - @property - def elbo(self): - return self.log_p_D + self.log_p_W - self.log_q_W - - def apply_replacements(self, node, deterministic=False): - if deterministic: - return theano.clone( - node, self.deterministic_replacements, strict=False) - else: - return theano.clone( - node, self.stochastic_replacements, strict=False) + results, _ = theano.map(replace_log_p_D, posterior) + return results.mean() def weighted_likelihood(self, var): tot = self.population.get( @@ -176,6 +163,25 @@ def weighted_likelihood(self, var): logpt /= var.size return logpt + def log_p_W(self, posterior): + _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) + _log_p_W_ = self.to_flat_input(_log_p_W_) + + def replace_log_p_W(post): + return theano.clone(_log_p_W_, {self.input: post}) + + results, _ = theano.map(replace_log_p_W, posterior) + return results.mean() + + def elbo(self, posterior): + return self.log_p_D(posterior) + self.log_p_W(posterior) - self.log_q_W(posterior) + + def apply_replacements(self, node, deterministic=False): + node = self.to_flat_input(node) + initial = self.initial(zeros=deterministic) + posterior = self.posterior(initial)[0] + return theano.clone(node, {self.input: posterior}) + def sample_elbo(self, samples=1, pi=1): """Output of this function should be used for fitting a model @@ -195,91 +201,24 @@ def sample_elbo(self, samples=1, pi=1): """ samples = tt.as_tensor(samples) pi = tt.as_tensor(pi) - _elbo_ = self.log_p_D + pi * (self.log_p_W - self.log_q_W) - _elbo_ = self.apply_replacements(_elbo_) - elbos, updates = theano.scan(fn=lambda: _elbo_, - outputs_info=None, - n_steps=samples) - return elbos, updates + posterior = self.posterior(self.initial(samples)) + elbo = (self.log_p_D(posterior) + + pi * (self.log_p_W(posterior) - self.log_q_W(posterior))) + return elbo class MeanField(BaseReplacement): - @staticmethod - def random_node(global_dict, node): - """Creates random node with shared params and - places shared parameters to global dict - - Parameters - ---------- - global_dict : dict - placeholder for parameters - node : pm.FreeRV - - Returns - ------- - tt.Variable : new node - """ - if len(node.broadcastable) > 0: - rho = theano.shared( - np.ones(node.tag.test_value.shape), - name='{}_rho_shared'.format(node.name), - broadcastable=node.broadcastable) - mu = theano.shared( - node.tag.test_value, - name='{}_mu_shared'.format(node.name), - broadcastable=node.broadcastable) - e = tt.patternbroadcast( - tt_rng().normal(rho.shape), node.broadcastable) - else: - rho = theano.shared( - np.ones(node.tag.test_value.shape), - name='{}_rho_shared'.format(node.name)) - mu = theano.shared( - node.tag.test_value, - name='{}_mu_shared'.format(node.name)) - e = tt_rng().normal(rho.shape) - v = mu + rho2sd(rho) * e - global_dict['means'][node.name] = mu - global_dict['rhos'][node.name] = rho - global_dict['x'].append(v) - return v - - @staticmethod - def new_global_dict(): - global_dict = dict( - x=list(), - means=collections.OrderedDict(), - rhos=collections.OrderedDict() - ) - return global_dict - - def create_mapping(self): - replacements, global_dict, local_dict = self.new_rep_glob_loc() - for var in self.model.vars: - if var in self.known: - v = self.known_node(local_dict, var, *self.known[var]) - else: - v = self.random_node(global_dict, var) - replacements[var] = v - return replacements, global_dict, local_dict - - @property - def log_q_W_global(self): - if self.global_dict['x']: - x = flatten_list(self.global_dict['x']) - mu = flatten_list(self.global_dict['means'].values()) - rho = flatten_list(self.global_dict['rhos'].values()) - _log_q_W_global_ = tt.sum(log_normal3(x, mu, rho)) - return _log_q_W_global_ - else: - return 0 - - @property - def params_global(self): - return (list(self.global_dict['means'].values()) + - list(self.global_dict['rhos'].values())) - - @property - def deterministic_replacements_global(self): - return collections.OrderedDict( - [(self.model[k], v) for k, v in self.global_dict['means'].items()] - ) + def create_shared_params(self): + return {'mu': theano.shared(self.input.tag.test_value[self.global_slc]), + 'rho': theano.shared(np.ones((self.global_size,)))} + + def posterior_global(self, initial): + sd = rho2sd(self.shared_params['rho']) + mu = self.shared_params['mu'] + return sd * initial + mu + + def log_q_W_global(self, posterior): + mu = self.shared_params['mu'] + rho = self.shared_params['rho'] + logp = tt.sum(log_normal3(posterior, mu, rho), axis=1).mean(axis=0) + return logp From 87e7e2dac24fd79c218ad0ba9d36004beb58bbcd Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Mon, 19 Dec 2016 23:50:44 +0300 Subject: [PATCH 33/83] changed expectations to sampling, added docs --- pymc3/tests/test_replacements_mean_field.py | 4 +- pymc3/variational/replacements.py | 192 +++++++++++++------- 2 files changed, 132 insertions(+), 64 deletions(-) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index 64c4f66339..eac2eee9fc 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -20,12 +20,12 @@ def test_elbo(self): # Create variational gradient tensor mean_field = MeanField(model) - elbo = mean_field.sample_elbo(samples=10000) + elbo = mean_field.elbo(samples=10000) mean_field.shared_params['mu'].set_value(post_mu) mean_field.shared_params['rho'].set_value(np.log(np.exp(post_sd) - 1)) - f = theano.function([], elbo) + f = theano.function([], elbo.mean()) elbo_mc = f() # Exact value diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 15e467a209..6bcf5d3ca3 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -33,6 +33,8 @@ def __init__(self, model, population=None, known=None): @property def input(self): + """Shortcut to flattened input + """ return self.flat_view.input def create_shared_params(self): @@ -52,15 +54,43 @@ def initial(self, samples=1, zeros=False): Returns ------- - matrix/vector - sampled latent space + matrix + sampled latent space shape(samples, size) """ if not zeros: return tt_rng().normal((samples, self.total_size)) else: return tt.zeros((samples, self.total_size)) + def sample_over_space(self, space, node): + """ + Parameters + ---------- + space : space to sample over + node : node that has flattened input + + Returns + ------- + samples + """ + def replace_node(post): + return theano.clone(node, {self.input: post}) + samples, _ = theano.map(replace_node, space) + return samples + def view_from(self, space, name, subset='all'): + """ + Parameters + ---------- + space : space to take view of variable from + name : name of variable + subset : determines what space is used can be {all|local|global} + + Returns + ------- + variable + shape == (samples,) + variable.shape + """ assert subset in {'all', 'local', 'global'} if subset in {'all', 'local'}: slc = self.view[name].slc @@ -68,15 +98,36 @@ def view_from(self, space, name, subset='all'): s = self.view[name].slc.start e = self.view[name].slc.stop slc = slice(s - self.global_size, e - self.global_size) - return space[:, slc] + _, _, shape, dtype = self.view[name] + return space[:, slc].reshape((space.shape[0],) + shape).astype(dtype) def posterior(self, initial): + """Transforms initial latent space to posterior distribution + + Parameters + ---------- + initial : initial latent space shape(samples, size) + + Returns + ------- + posterior space + """ return tt.concatenate([ self.posterior_local(initial[:, self.local_slc]), self.posterior_global(initial[:, self.global_slc]) ], axis=1) def posterior_global(self, initial): + """Implements posterior distribution from initial latent space + + Parameters + ---------- + initial : initial latent space shape(samples, size) + + Returns + ------- + global posterior space + """ raise NotImplementedError def __local_mu_rho(self): @@ -90,70 +141,54 @@ def __local_mu_rho(self): return mu, rho def posterior_local(self, initial): - if not self.known: + """Implements posterior distribution from initial latent space + + Parameters + ---------- + initial : initial latent space shape(samples, size) + + Returns + ------- + local posterior space + """ + if not self.local_vars: return initial mu, rho = self.__local_mu_rho() x = initial * rho2sd(rho) + mu return x def to_flat_input(self, node): + """Replaces vars with flattened view stored in self.input + """ return theano.clone(node, self.flat_view.replacements, strict=False) - @property - def local_vmap(self): - return self.order.vmap[:len(self.local_vars)] - - @property - def global_vmap(self): - return self.order.vmap[len(self.local_vars):] - - @property - def local_size(self): - size = sum([0] + [v.size for v in self.local_vars]) - return size - - @property - def global_size(self): - return self.total_size - self.local_size - - @property - def total_size(self): - return self.order.dimensions - - @property - def local_slc(self): - return slice(0, self.local_size) - - @property - def global_slc(self): - return slice(self.local_size, self.total_size) - def log_q_W_local(self, posterior): - if not self.known: + """log_q_W samples over q for local vars""" + if not self.local_vars: return 0 mu, rho = self.__local_mu_rho() - logp = tt.sum(log_normal3(posterior, mu, rho), axis=1).mean(axis=0) - return logp + samples = tt.sum(log_normal3(posterior, mu, rho), axis=1) + return samples def log_q_W_global(self, posterior): + """log_q_W samples over q for global vars""" raise NotImplementedError def log_q_W(self, posterior): + """log_q_W samples over q""" return self.log_q_W_global(posterior) + self.log_q_W_local(posterior) def log_p_D(self, posterior): + """log_p_D samples over q""" _log_p_D_ = tt.add( *map(self.weighted_likelihood, self.model.observed_RVs) ) _log_p_D_ = self.to_flat_input(_log_p_D_) - - def replace_log_p_D(post): - return theano.clone(_log_p_D_, {self.input: post}) - - results, _ = theano.map(replace_log_p_D, posterior) - return results.mean() + samples = self.sample_over_space(posterior, _log_p_D_) + return samples def weighted_likelihood(self, var): + """Weight likelihood according to given population size""" tot = self.population.get( var, self.population.get(var.name)) logpt = tt.sum(var.logpt) @@ -163,26 +198,36 @@ def weighted_likelihood(self, var): logpt /= var.size return logpt + def KL_q_p_W(self, posterior): + """KL(q||p) samples over q""" + return self.log_q_W(posterior) - self.log_p_W(posterior) + def log_p_W(self, posterior): + """log_p_W samples over q""" _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) _log_p_W_ = self.to_flat_input(_log_p_W_) + samples = self.sample_over_space(posterior, _log_p_W_) + return samples - def replace_log_p_W(post): - return theano.clone(_log_p_W_, {self.input: post}) - - results, _ = theano.map(replace_log_p_W, posterior) - return results.mean() + def apply_replacements(self, node, deterministic=False): + """Replace variables in graph with variational approximation - def elbo(self, posterior): - return self.log_p_D(posterior) + self.log_p_W(posterior) - self.log_q_W(posterior) + Parameters + ---------- + node : node for replacements + deterministic : whether to use zeros as initial distribution + if True - median point will be sampled - def apply_replacements(self, node, deterministic=False): - node = self.to_flat_input(node) + Returns + ------- + node with replacements + """ initial = self.initial(zeros=deterministic) posterior = self.posterior(initial)[0] + node = self.to_flat_input(node) return theano.clone(node, {self.input: posterior}) - def sample_elbo(self, samples=1, pi=1): + def elbo(self, samples=1, pi=1): """Output of this function should be used for fitting a model Parameters @@ -190,22 +235,45 @@ def sample_elbo(self, samples=1, pi=1): samples : Tensor - number of samples pi : Tensor - weight of variational part - - Notes - ----- - In case of samples == 1 updates are empty and can be ignored - Returns ------- - elbos, updates + ELBO samples """ samples = tt.as_tensor(samples) pi = tt.as_tensor(pi) posterior = self.posterior(self.initial(samples)) - elbo = (self.log_p_D(posterior) + - pi * (self.log_p_W(posterior) - self.log_q_W(posterior))) + elbo = self.log_p_D(posterior) - pi * (self.KL_q_p_W(posterior)) return elbo + @property + def local_vmap(self): + return self.order.vmap[:len(self.local_vars)] + + @property + def global_vmap(self): + return self.order.vmap[len(self.local_vars):] + + @property + def local_size(self): + size = sum([0] + [v.size for v in self.local_vars]) + return size + + @property + def global_size(self): + return self.total_size - self.local_size + + @property + def total_size(self): + return self.order.dimensions + + @property + def local_slc(self): + return slice(0, self.local_size) + + @property + def global_slc(self): + return slice(self.local_size, self.total_size) + class MeanField(BaseReplacement): def create_shared_params(self): @@ -220,5 +288,5 @@ def posterior_global(self, initial): def log_q_W_global(self, posterior): mu = self.shared_params['mu'] rho = self.shared_params['rho'] - logp = tt.sum(log_normal3(posterior, mu, rho), axis=1).mean(axis=0) - return logp + samples = tt.sum(log_normal3(posterior, mu, rho), axis=1) + return samples From 9eb79a007449872c68cc48cac5374c9768a7b22e Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 20 Dec 2016 00:15:32 +0300 Subject: [PATCH 34/83] code style --- pymc3/theanof.py | 30 +++++++++++++++++++----------- pymc3/variational/replacements.py | 23 +++++++++++++++-------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/pymc3/theanof.py b/pymc3/theanof.py index 48649052ce..e220412635 100644 --- a/pymc3/theanof.py +++ b/pymc3/theanof.py @@ -18,14 +18,19 @@ 'join_nonshared_inputs', 'make_shared_replacements', 'tt_rng', - 'set_tt_rng'] + 'set_tt_rng', + 'no_test_val', + 'change_flags'] @contextlib.contextmanager def no_test_val(): - """ - for functions use theano.configparser.change_flags - :return: + """for functions use theano.configparser.change_flags + + Usage + ----- + >>> with no_test_val(): + ... """ theano.config.compute_test_value = 'off' yield @@ -257,9 +262,12 @@ def __call__(self, input): @change_flags(compute_test_value='off') def launch_rng(rng): - """or else test value is not available - :param rng: MRG_RandomStreams - :return: + """Helper function for safe launch of rng. + If not launched, there will be problems with test_value + + Parameters + ---------- + rng : theano.sandbox.rng_mrg.MRG_RandomStreams` instance """ state = rng.rstate rng.inc_rstate() @@ -273,9 +281,9 @@ def tt_rng(): """Get the package-level random number generator. Returns ------- - :class:`theano.sandbox.rng_mrg.MRG_RandomStreams` instance - The :class:`theano.sandbox.rng_mrg.MRG_RandomStreams` - instance passed to the most recent call of :func:`set_tt_rng` + `theano.sandbox.rng_mrg.MRG_RandomStreams` instance + `theano.sandbox.rng_mrg.MRG_RandomStreams` + instance passed to the most recent call of `set_tt_rng` """ return _tt_rng @@ -284,7 +292,7 @@ def set_tt_rng(new_rng): """Set the package-level random number generator. Parameters ---------- - new_rng : :class:`theano.sandbox.rng_mrg.MRG_RandomStreams` instance + new_rng : `theano.sandbox.rng_mrg.MRG_RandomStreams` instance The random number generator to use. """ global _tt_rng diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 6bcf5d3ca3..54f1422145 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -163,7 +163,8 @@ def to_flat_input(self, node): return theano.clone(node, self.flat_view.replacements, strict=False) def log_q_W_local(self, posterior): - """log_q_W samples over q for local vars""" + """log_q_W samples over q for local vars + """ if not self.local_vars: return 0 mu, rho = self.__local_mu_rho() @@ -171,15 +172,18 @@ def log_q_W_local(self, posterior): return samples def log_q_W_global(self, posterior): - """log_q_W samples over q for global vars""" + """log_q_W samples over q for global vars + """ raise NotImplementedError def log_q_W(self, posterior): - """log_q_W samples over q""" + """log_q_W samples over q + """ return self.log_q_W_global(posterior) + self.log_q_W_local(posterior) def log_p_D(self, posterior): - """log_p_D samples over q""" + """log_p_D samples over q + """ _log_p_D_ = tt.add( *map(self.weighted_likelihood, self.model.observed_RVs) ) @@ -188,7 +192,8 @@ def log_p_D(self, posterior): return samples def weighted_likelihood(self, var): - """Weight likelihood according to given population size""" + """Weight likelihood according to given population size + """ tot = self.population.get( var, self.population.get(var.name)) logpt = tt.sum(var.logpt) @@ -199,11 +204,13 @@ def weighted_likelihood(self, var): return logpt def KL_q_p_W(self, posterior): - """KL(q||p) samples over q""" + """KL(q||p) samples over q + """ return self.log_q_W(posterior) - self.log_p_W(posterior) def log_p_W(self, posterior): - """log_p_W samples over q""" + """log_p_W samples over q + """ _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) _log_p_W_ = self.to_flat_input(_log_p_W_) samples = self.sample_over_space(posterior, _log_p_W_) @@ -242,7 +249,7 @@ def elbo(self, samples=1, pi=1): samples = tt.as_tensor(samples) pi = tt.as_tensor(pi) posterior = self.posterior(self.initial(samples)) - elbo = self.log_p_D(posterior) - pi * (self.KL_q_p_W(posterior)) + elbo = self.log_p_D(posterior) - pi * self.KL_q_p_W(posterior) return elbo @property From be1ca80e2f4fca527530211e0e3c48fefa4358e1 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 20 Dec 2016 00:24:07 +0300 Subject: [PATCH 35/83] validate model --- pymc3/variational/replacements.py | 39 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 54f1422145..8303820744 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -1,10 +1,12 @@ import collections import theano.tensor as tt import theano +import pymc3 as pm from ..theanof import tt_rng from ..blocking import ArrayOrdering from ..distributions.dist_math import rho2sd, log_normal3 from ..math import flatten_list +from ..model import modelcontext import numpy as np @@ -12,7 +14,9 @@ class BaseReplacement(object): - def __init__(self, model, population=None, known=None): + def __init__(self, model=None, population=None, known=None): + model = modelcontext(model) + self.check_model(model) if known is None: known = dict() if population is None: @@ -31,6 +35,14 @@ def __init__(self, model, population=None, known=None): self.view = {vm.var: vm for vm in self.order.vmap} self.shared_params = self.create_shared_params() + @staticmethod + def check_model(model): + """Checks that model is valid for variational inference + """ + vars_ = [var for var in model.vars if not isinstance(var, pm.model.ObservedRV)] + if any([var.dtype in pm.discrete_types for var in vars_]): + raise ValueError('Model should not include discrete RVs') + @property def input(self): """Shortcut to flattened input @@ -54,7 +66,7 @@ def initial(self, samples=1, zeros=False): Returns ------- - matrix + Tensor sampled latent space shape(samples, size) """ if not zeros: @@ -110,7 +122,8 @@ def posterior(self, initial): Returns ------- - posterior space + Tensor + posterior space """ return tt.concatenate([ self.posterior_local(initial[:, self.local_slc]), @@ -130,16 +143,6 @@ def posterior_global(self, initial): """ raise NotImplementedError - def __local_mu_rho(self): - mu = [] - rho = [] - for var in self.local_vars: - mu.append(self.known[var][0].ravel()) - rho.append(self.known[var][1].ravel()) - mu = tt.concatenate(mu) - rho = tt.concatenate(rho) - return mu, rho - def posterior_local(self, initial): """Implements posterior distribution from initial latent space @@ -157,6 +160,16 @@ def posterior_local(self, initial): x = initial * rho2sd(rho) + mu return x + def __local_mu_rho(self): + mu = [] + rho = [] + for var in self.local_vars: + mu.append(self.known[var][0].ravel()) + rho.append(self.known[var][1].ravel()) + mu = tt.concatenate(mu) + rho = tt.concatenate(rho) + return mu, rho + def to_flat_input(self, node): """Replaces vars with flattened view stored in self.input """ From e8f6644a01ec0671c99982b4bdb62e6c6d2f6b43 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 20 Dec 2016 00:55:19 +0300 Subject: [PATCH 36/83] added tests for dynamic number of samples --- pymc3/tests/test_replacements_mean_field.py | 21 +++++++++++++++++++++ pymc3/variational/replacements.py | 9 +++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index eac2eee9fc..ed425f1980 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -1,8 +1,10 @@ import unittest import numpy as np import theano +import theano.tensor as tt from pymc3 import Model, Normal from pymc3.variational.replacements import MeanField +from . import models class TestMeanField(unittest.TestCase): @@ -35,5 +37,24 @@ def test_elbo(self): 0.5 * (np.log(2 * np.pi) + 1)) np.testing.assert_allclose(elbo_mc, elbo_true, rtol=0, atol=1e-1) + def test_vary_samples(self): + _, model, _ = models.simple_model() + i = tt.iscalar('i') + i.tag.test_value = 1 + with model: + mf = MeanField() + elbo = mf.elbo(i) + elbos = theano.function([i], elbo) + self.assertEqual(elbos(1).shape[0], 1) + self.assertEqual(elbos(10).shape[0], 10) + + def test_vars_view(self): + _, model, _ = models.multidimensional_model() + with model: + mf = MeanField() + posterior = mf.posterior(mf.initial(10)) + x_sampled = mf.view_from(posterior, 'x').eval() + self.assertEqual(x_sampled.shape, (10,) + model['x'].dshape) + if __name__ == '__main__': unittest.main() diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 8303820744..235067c8f0 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -69,10 +69,11 @@ def initial(self, samples=1, zeros=False): Tensor sampled latent space shape(samples, size) """ + shape = tt.stack([tt.as_tensor(samples), tt.as_tensor(self.total_size)]) if not zeros: - return tt_rng().normal((samples, self.total_size)) + return tt_rng().normal(shape) else: - return tt.zeros((samples, self.total_size)) + return tt.zeros(shape) def sample_over_space(self, space, node): """ @@ -197,8 +198,8 @@ def log_q_W(self, posterior): def log_p_D(self, posterior): """log_p_D samples over q """ - _log_p_D_ = tt.add( - *map(self.weighted_likelihood, self.model.observed_RVs) + _log_p_D_ = tt.sum( + list(map(self.weighted_likelihood, self.model.observed_RVs)) ) _log_p_D_ = self.to_flat_input(_log_p_D_) samples = self.sample_over_space(posterior, _log_p_D_) From 4add3bcbcc951ef2bf0391b758af16ca3bd5b829 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 20 Dec 2016 01:03:45 +0300 Subject: [PATCH 37/83] added `set_params` method --- pymc3/variational/replacements.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 235067c8f0..366dac9732 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -35,6 +35,9 @@ def __init__(self, model=None, population=None, known=None): self.view = {vm.var: vm for vm in self.order.vmap} self.shared_params = self.create_shared_params() + def set_params(self, params): + self.shared_params.update(params) + @staticmethod def check_model(model): """Checks that model is valid for variational inference From 43a86385686eb5680545502af719331efd7356b7 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 20 Dec 2016 01:05:22 +0300 Subject: [PATCH 38/83] added `params` property --- pymc3/variational/replacements.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 366dac9732..9d2d1a98cd 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -38,6 +38,10 @@ def __init__(self, model=None, population=None, known=None): def set_params(self, params): self.shared_params.update(params) + @property + def params(self): + return list(self.shared_params.values()) + @staticmethod def check_model(model): """Checks that model is valid for variational inference @@ -54,6 +58,7 @@ def input(self): def create_shared_params(self): """Any stuff you need will be here + Returns ------- dict : shared params From 6a88fdefdfe80f0c63ac02c6af2414c7891c44bb Mon Sep 17 00:00:00 2001 From: taku-y Date: Fri, 25 Nov 2016 00:10:07 +0900 Subject: [PATCH 39/83] ENH KL-weighting --- pymc3/variational/advi_minibatch.py | 286 ++++++++++++++++++++-------- 1 file changed, 210 insertions(+), 76 deletions(-) diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index 097ff16825..3d89b62b70 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -66,7 +66,8 @@ def _get_rvss( return local_RVs, observed_RVs -def _init_uw_global_shared(start, global_RVs, global_order): +def _init_uw_global_shared(start, global_RVs): + global_order = pm.ArrayOrdering([v for v in global_RVs]) start = {v.name: start[v.name] for v in global_RVs} bij = pm.DictToArrayBijection(global_order, start) u_start = bij.map(start) @@ -82,6 +83,7 @@ def _join_global_RVs(global_RVs, global_order): inarray_global = None uw_global = None replace_global = {} + c_g = 0 else: joined_global = tt.concatenate([v.ravel() for v in global_RVs]) uw_global = tt.vector('uw_global') @@ -98,7 +100,11 @@ def _join_global_RVs(global_RVs, global_order): for var, slc, shp, dtyp in global_order.vmap } - return inarray_global, uw_global, replace_global + cs = [c for _, c in global_RVs.items()] + shps = [shp for _, _, shp, _ in global_order.vmap] + c_g = [c * tt.ones(np.prod(shp)) for c, shp in zip(cs, shps)] + + return inarray_global, uw_global, replace_global, c_g def _join_local_RVs(local_RVs, local_order): @@ -106,6 +112,7 @@ def _join_local_RVs(local_RVs, local_order): inarray_local = None uw_local = None replace_local = {} + c_l = 0 else: joined_local = tt.concatenate([v.ravel() for v in local_RVs]) uw_local = tt.vector('uw_local') @@ -121,23 +128,29 @@ def _join_local_RVs(local_RVs, local_order): for var, slc, shp, dtyp in local_order.vmap } - return inarray_local, uw_local, replace_local + cs = [c for _, (_, c) in local_RVs.items()] + shps = [shp for _, _, shp, _ in local_order.vmap] + c_l = [c * tt.ones(np.prod(shp)) for c, shp in zip(cs, shps)] + return inarray_local, uw_local, replace_local, c_l -def _make_logpt(global_RVs, local_RVs, observed_RVs, model): + +def _make_logpt(global_RVs, local_RVs, observed_RVs, potentials): """Return expression of log probability. """ # Scale log probability for mini-batches - factors = [s * v.logpt for v, s in observed_RVs.items()] + \ - [v.logpt for v in global_RVs] + model.potentials - if local_RVs is not None: - factors += [s * v.logpt for v, (_, s) in local_RVs.items()] + factors = [c * v.logpt for v, c in observed_RVs.items()] + \ + [c * v.logpt for v, c in global_RVs.items()] + \ + [c * v.logpt for v, (_, c) in local_RVs.items()] + \ + potentials logpt = tt.add(*map(tt.sum, factors)) return logpt -def _elbo_t(logp, uw_g, uw_l, inarray_g, inarray_l, n_mcsamples, random_seed): +def _elbo_t( + logp, uw_g, uw_l, inarray_g, inarray_l, c_g, c_l, n_mcsamples, + random_seed): """Return expression of approximate ELBO based on Monte Carlo sampling. """ if random_seed is None: @@ -152,24 +165,22 @@ def _elbo_t(logp, uw_g, uw_l, inarray_g, inarray_l, n_mcsamples, random_seed): # Sampling local variational parameters if uw_l is not None: l_l = (uw_l.size / 2).astype('int64') - l_l_ = (uw_l.size / 2).astype(floatX_str) u_l = uw_l[:l_l] w_l = uw_l[l_l:] ns_l = r.normal(size=(n_mcsamples, inarray_l.tag.test_value.shape[0])) zs_l = ns_l * tt.exp(w_l) + u_l - elbo += tt.sum(w_l) + 0.5 * l_l_ * normal_const + elbo += tt.sum(c_l * (w_l + 0.5 * normal_const)) else: zs_l = None # Sampling global variational parameters if uw_g is not None: l_g = (uw_g.size / 2).astype('int64') - l_g_ = (uw_g.size / 2).astype(floatX_str) u_g = uw_g[:l_g] w_g = uw_g[l_g:] ns_g = r.normal(size=(n_mcsamples, inarray_g.tag.test_value.shape[0])) zs_g = ns_g * tt.exp(w_g) + u_g - elbo += tt.sum(w_g) + 0.5 * l_g_ * normal_const + elbo += tt.sum(c_g * (w_g + 0.5 * normal_const)) else: zs_g = None @@ -203,53 +214,159 @@ def logp_(z_g): return elbo -def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, - minibatch_RVs=None, minibatch_tensors=None, - minibatches=None, local_RVs=None, observed_RVs=None, - encoder_params=[], total_size=None, optimizer=None, - learning_rate=.001, epsilon=.1, random_seed=None, - mode=None): - """Perform mini-batch ADVI. - - This function implements a mini-batch ADVI with the meanfield - approximation. Autoencoding variational inference is also supported. - - The log probability terms for mini-batches, corresponding to RVs in - minibatch_RVs, are scaled to (total_size) / (the number of samples in each - mini-batch), where total_size is an argument for the total data size. - - minibatch_tensors is a list of tensors (can be shared variables) to which - mini-batch samples are set during the optimization. In most cases, these - tensors are observations for RVs in the model. +def _make_elbo_t( + observed_RVs, global_RVs, local_RVs, potentials, n_mcsamples, random_seed): + global_order = pm.ArrayOrdering([v for v in global_RVs]) + local_order = pm.ArrayOrdering([v for v in local_RVs]) - local_RVs and observed_RVs are used for autoencoding variational Bayes. - Both of these RVs are associated with each of given samples. - The difference is that local_RVs are unkown and their posterior - distributions are approximated. + inarray_g, uw_g, replace_g, c_g = _join_global_RVs(global_RVs, global_order) + inarray_l, uw_l, replace_l, c_l = _join_local_RVs(local_RVs, local_order) - local_RVs are Ordered dict, whose keys and values are RVs and a tuple of - two objects. The first is the theano expression of variational parameters - (mean and log of std) of the approximate posterior, which are encoded from - given samples by an arbitrary deterministic function, e.g., MLP. The other - one is a scaling constant to be multiplied to the log probability term - corresponding to the RV. + logpt = _make_logpt(global_RVs, local_RVs, observed_RVs, potentials) + replace = replace_g + replace.update(replace_l) + logpt = theano.clone(logpt, replace, strict=False) - observed_RVs are also Ordered dict with RVs as the keys, but whose values - are only the scaling constant as in local_RVs. In this case, total_size is - ignored. + elbo = _elbo_t(logpt, uw_g, uw_l, inarray_g, inarray_l, c_g, c_l, + n_mcsamples, random_seed) - If local_RVs is None (thus not using autoencoder), the following two - settings are equivalent: + return elbo, uw_l, uw_g - - observed_RVs=OrderedDict([(rv, total_size / minibatch_size)]) - - minibatch_RVs=[rv], total_size=total_size - where minibatch_size is minibatch_tensors[0].shape[0]. +def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, + minibatch_RVs=None, minibatch_tensors=None, + minibatches=None, global_RVs=None, local_RVs=None, + observed_RVs=None, encoder_params=[], total_size=None, + optimizer=None, learning_rate=.001, epsilon=.1, + random_seed=None, mode=None): + """Perform mini-batch ADVI. - The variational parameters and the parameters of the autoencoder are - simultaneously optimized with given optimizer, which is a function that - returns a dictionary of parameter updates as provided to Theano function. - See the docstring of pymc3.variational.advi(). + This function implements a mini-batch automatic differentiation variational + inference (ADVI; Kucukelbir et al., 2015) with the meanfield + approximation. Autoencoding variational Bayes (AEVB; Kingma and Welling, + 2014) is also supported. + + For explanation, we classify random variables in probabilistic models into + three types. Observed random variables + :math:`{\cal Y}=\{\mathbf{y}_{i}\}_{i=1}^{N}` are :math:`N` observations. + Each :math:`\mathbf{y}_{i}` can be a set of observed random variables, + i.e., :math:`\mathbf{y}_{i}=\{\mathbf{y}_{i}^{k}\}_{k=1}^{V_{o}}`, where + :math:`V_{k}` is the number of the types of observed random variables + in the model. + + The next ones are global random variables + :math:`\Theta=\{\\theta^{k}\}_{k=1}^{V_{g}}`, which are used to calculate + the probabilities for all observed samples. + + The last ones are local random variables + :math:`{\cal Z}=\{\mathbf{z}_{i}\}_{i=1}^{N}`, where + :math:`\mathbf{z}_{i}=\{\mathbf{z}_{i}^{k}\}_{k=1}^{V_{l}}`. + These RVs are used only in AEVB. + + The goal of ADVI is to approximate the posterior distribution + :math:`p(\Theta,{\cal Z}|{\cal Y})` by variational posterior + :math:`q(\Theta)\prod_{i=1}^{N}q(\mathbf{z}_{i})`. All of these terms + are normal distributions (mean-field approximation). + + :math:`q(\Theta)` is parametrized with its means and standard deviations. + These parameters are denoted as :math:`\gamma`. While :math:`\gamma` is + a constant, the parameters of :math:`q(\mathbf{z}_{i})` are dependent on + each observation. Therefore these parameters are denoted as + :math:`\\xi(\mathbf{y}_{i}; \\nu)`, where :math:`\\nu` is the parameters + of :math:`\\xi(\cdot)`. For example, :math:`\\xi(\cdot)` can be a + multilayer perceptron or convolutional neural network. + + In addition to :math:`\\xi(\cdot)`, we can also include deterministic + mappings for the likelihood of observations. We denote the parameters of + the deterministic mappings as :math:`\eta`. An example of such mappings is + the deconvolutional neural network used in the convolutional VAE example + in the PyMC3 notebook directory. + + This function maximizes the evidence lower bound (ELBO) + :math:`{\cal L}(\gamma, \\nu, \eta)` defined as follows: + + .. math:: + + {\cal L}(\gamma,\\nu,\eta) & = + \mathbf{c}_{o}\mathbb{E}_{q(\Theta)}\left[ + \sum_{i=1}^{N}\mathbb{E}_{q(\mathbf{z}_{i})}\left[ + \log p(\mathbf{y}_{i}|\mathbf{z}_{i},\Theta,\eta) + \\right]\\right] \\\\ & + - \mathbf{c}_{g}KL\left[q(\Theta)||p(\Theta)\\right] + - \mathbf{c}_{l}\sum_{i=1}^{N} + KL\left[q(\mathbf{z}_{i})||p(\mathbf{z}_{i})\\right], + + where :math:`KL[q(v)||p(v)]` is the Kullback-Leibler divergence + + .. math:: + + KL[q(v)||p(v)] = \int q(v)\log\\frac{q(v)}{p(v)}dv, + + :math:`\mathbf{c}_{o/g/l}` are vectors for weighting each term of ELBO. + More precisely, we can write each of the terms in ELBO as follows: + + .. math:: + + \mathbf{c}_{o}\log p(\mathbf{y}_{i}|\mathbf{z}_{i},\Theta,\eta) & = & + \sum_{k=1}^{V_{o}}c_{o}^{k} + \log p(\mathbf{y}_{i}^{k}| + {\\rm pa}(\mathbf{y}_{i}^{k},\Theta,\eta)) \\\\ + \mathbf{c}_{g}KL\left[q(\Theta)||p(\Theta)\\right] & = & + \sum_{k=1}^{V_{g}}c_{g}^{k}KL\left[ + q(\\theta^{k})||p(\\theta^{k}|{\\rm pa(\\theta^{k})})\\right] \\\\ + \mathbf{c}_{l}KL\left[q(\mathbf{z}_{i}||p(\mathbf{z}_{i})\\right] & = & + \sum_{k=1}^{V_{l}}c_{l}^{k}KL\left[ + q(\mathbf{z}_{i}^{k})|| + p(\mathbf{z}_{i}^{k}|{\\rm pa}(\mathbf{z}_{i}^{k}))\\right], + + where :math:`{\\rm pa}(v)` denotes the set of parent variables of :math:`v` + in the directed acyclic graph of the model. + + When using mini-batches, :math:`c_{o}^{k}` and :math:`c_{l}^{k}` should be + set to :math:`N/M`, where :math:`M` is the number of observations in each + mini-batch. Other weighting scheme were proposed in (Blundell et al., 2015) + for accelarating model fitting. + + For working with ADVI, we need to give the probabilistic model + (:code:`model`), the three types of RVs (:code:`observed_RVs`, + :code:`global_RVs` and :code:`local_RVs`), the tensors to which + mini-bathced samples are supplied (:code:`minibatches`) and + parameters of deterministic mappings :math:`\\xi` and :math:`\eta` + (:code:`encoder_params`) as input arguments. + + :code:`observed_RVs` is a :code:`OrderedDict` of the form + :code:`{y_k: c_k}`, where :code:`y_k` is a random variable defined in the + PyMC3 model. :code:`c_k` is a scalar (:math:`c_{o}^{k}`) and it can be a + shared variable. + + :code:`global_RVs` is a :code:`OrderedDict` of the form + :code:`{t_k: c_k}`, where :code:`t_k` is a random variable defined in the + PyMC3 model. :code:`c_k` is a scalar (:math:`c_{g}^{k}`) and it can be a + shared variable. + + :code:`local_RVs` is a :code:`OrderedDict` of the form + :code:`{z_k: ((m_k, s_k), c_k)}`, where :code:`z_k` is a random variable + defined in the PyMC3 model. :code:`c_k` is a scalar (:math:`c_{l}^{k}`) + and it can be a shared variable. :code:`(m_k, s_k)` is a pair of tensors + of means and log standard deviations of the variational distribution; + samples drawn from the variational distribution replaces :code:`z_k`. + It should be noted that if :code:`z_k` has a transformation that changes + the dimension (e.g., StickBreakingTransform), the variational distribution + must have the same dimension. For example, if :code:`z_k` is distributed + with Dirichlet distribution with :code:`p` choices, :math:`m_k` and + :code:`s_k` has the shape :code:`(n_samples_in_minibatch, p - 1)`. + + :code:`minibatch_tensors` is a list of tensors (can be shared variables) + to which mini-batch samples are set during the optimization. + These tensors are observations (:code:`obs=`) in :code:`observed_RVs`. + + :code:`minibatches` is a generator of a list of :code:`numpy.ndarray`. + Each item of the list will be set to tensors in :code:`minibatch_tensors`. + + :code:`encoder_params` is a list of shared variables of the parameters + :math:`\\nu` and :math:`\eta`. We do not need to include the variational + parameters of the global variables, :math:`\gamma`, because these are + automatically created and updated in this function. Parameters ---------- @@ -277,12 +394,17 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, total_size : int Total size of training samples. This is used to appropriately scale the log likelihood terms corresponding to mini-batches in ELBO. - local_RVs : Ordered dict - Include encoded variational parameters and a scaling constant for - the corresponding RV. See the above description. observed_RVs : Ordered dict Include a scaling constant for the corresponding RV. See the above - description + description. + global_RVs : Ordered dict or None + Include a scaling constant for the corresponding RV. See the above + description. If :code:`None`, it is set to + :code:`{v: 1 for v in grvs}`, where :code:`grvs` is + :code:`list(set(vars) - set(list(local_RVs) + list(observed_RVs)))`. + local_RVs : Ordered dict or None + Include encoded variational parameters and a scaling constant for + the corresponding RV. See the above description. encoder_params : list of theano shared variables Parameters of encoder. optimizer : (loss, list of shared variables) -> dict or OrderedDict @@ -291,11 +413,11 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, Adagrad optimizer is used with parameters :code:`learning_rate` and :code:`epsilon` below. learning_rate: float - Base learning rate for adagrad. This parameter is ignored when - an optimizer is given. + Base learning rate for adagrad. + This parameter is ignored when :code:`optimizer` is set. epsilon : float Offset in denominator of the scale of learning rate in Adagrad. - This parameter is ignored when an optimizer is given. + This parameter is ignored when :code:`optimizer` is set. random_seed : int Seed to initialize random state. mode : string or `Mode` instance. @@ -305,6 +427,17 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, ------- ADVIFit Named tuple, which includes 'means', 'stds', and 'elbo_vals'. + + References + ---------- + - Kingma, D. P., & Welling, M. (2014). + Auto-Encoding Variational Bayes. stat, 1050, 1. + - Kucukelbir, A., Ranganath, R., Gelman, A., & Blei, D. (2015). + Automatic variational inference in Stan. In Advances in neural + information processing systems (pp. 568-576). + - Blundell, C., Cornebise, J., Kavukcuoglu, K., & Wierstra, D. (2015). + Weight Uncertainty in Neural Network. In Proceedings of the 32nd + International Conference on Machine Learning (ICML-15) (pp. 1613-1622). """ theano.config.compute_test_value = 'ignore' @@ -334,30 +467,31 @@ def get_transformed(v): ) # Get global variables - global_RVs = list(set(vars) - set(list(local_RVs) + list(observed_RVs))) - - # Ordering for concatenation of random variables - global_order = pm.ArrayOrdering([v for v in global_RVs]) - local_order = pm.ArrayOrdering([v for v in local_RVs]) + grvs = list(set(vars) - set(list(local_RVs) + list(observed_RVs))) + if global_RVs is None: + global_RVs = OrderedDict({v: 1 for v in grvs}) + else: + assert(len(grvs) == len(global_RVs)) # ELBO wrt variational parameters - inarray_g, uw_g, replace_g = _join_global_RVs(global_RVs, global_order) - inarray_l, uw_l, replace_l = _join_local_RVs(local_RVs, local_order) - logpt = _make_logpt(global_RVs, local_RVs, observed_RVs, model) - replace = replace_g - replace.update(replace_l) - logp = theano.clone(logpt, replace, strict=False) - elbo = _elbo_t(logp, uw_g, uw_l, inarray_g, inarray_l, - n_mcsamples, random_seed) - del logpt + # inarray_g, uw_g, replace_g, c_g = _join_global_RVs(global_RVs, global_order) + # inarray_l, uw_l, replace_l, c_l = _join_local_RVs(local_RVs, local_order) + # logpt = _make_logpt(global_RVs, local_RVs, observed_RVs, model.potentials) + # replace = replace_g + # replace.update(replace_l) + # logp = theano.clone(logpt, replace, strict=False) + # elbo = _elbo_t(logp, uw_g, uw_l, inarray_g, inarray_l, + # n_mcsamples, random_seed) + # del logpt + elbo, uw_l, uw_g = _make_elbo_t(observed_RVs, global_RVs, local_RVs, + model.potentials, n_mcsamples, random_seed) # Replacements tensors of variational parameters in the graph replaces = dict() # Variational parameters for global RVs if 0 < len(global_RVs): - uw_global_shared, bij = _init_uw_global_shared(start, global_RVs, - global_order) + uw_global_shared, bij = _init_uw_global_shared(start, global_RVs) replaces.update({uw_g: uw_global_shared}) # Variational parameters for local RVs, encoded from samples in From a3bad35d5e7c29e2de37fce857902623b666bbbf Mon Sep 17 00:00:00 2001 From: taku-y Date: Sat, 26 Nov 2016 11:14:11 +0900 Subject: [PATCH 40/83] Fix bugs --- pymc3/variational/advi_minibatch.py | 42 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index 3d89b62b70..7da81cb991 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -94,15 +94,16 @@ def _join_global_RVs(global_RVs, global_order): inarray_global = joined_global.type('inarray_global') inarray_global.tag.test_value = joined_global.tag.test_value - get_var = {var.name: var for var in global_RVs} - replace_global = { - get_var[var]: reshape_t(inarray_global[slc], shp).astype(dtyp) - for var, slc, shp, dtyp in global_order.vmap - } + # Replace RVs with reshaped subvectors of the joined vector + # The order of global_order is the same with that of global_RVs + subvecs = [reshape_t(inarray_global[slc], shp).astype(dtyp) + for _, slc, shp, dtyp in global_order.vmap] + replace_global = {v: subvec for v, subvec in zip(global_RVs, subvecs)} + # Weight vector cs = [c for _, c in global_RVs.items()] - shps = [shp for _, _, shp, _ in global_order.vmap] - c_g = [c * tt.ones(np.prod(shp)) for c, shp in zip(cs, shps)] + oness = [tt.ones(v.ravel().tag.test_value.shape) for v in global_RVs] + c_g = tt.concatenate([c * ones for c, ones in zip(cs, oness)]) return inarray_global, uw_global, replace_global, c_g @@ -128,9 +129,15 @@ def _join_local_RVs(local_RVs, local_order): for var, slc, shp, dtyp in local_order.vmap } + # Weight vector cs = [c for _, (_, c) in local_RVs.items()] - shps = [shp for _, _, shp, _ in local_order.vmap] - c_l = [c * tt.ones(np.prod(shp)) for c, shp in zip(cs, shps)] + oness = [tt.ones(v.ravel().tag.test_value.shape) for v in local_RVs] + c_l = tt.concatenate([c * ones for c, ones in zip(cs, oness)]) + + # shps = [shp for _, _, shp, _ in local_order.vmap] + # c_l = tt.concatenate( + # [c * tt.ones(np.prod(shp)) for c, shp in zip(cs, shps)] + # ) return inarray_local, uw_local, replace_local, c_l @@ -368,6 +375,14 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, parameters of the global variables, :math:`\gamma`, because these are automatically created and updated in this function. + The following is a list of example notebooks using advi_minibatch: + + - docs/source/notebooks/GLM-hierarchical-advi-minibatch.ipynb + - docs/source/notebooks/bayesian_neural_network_advi.ipynb + - docs/source/notebooks/convolutional_vae_keras_advi.ipynb + - docs/source/notebooks/gaussian-mixture-model-advi.ipynb + - docs/source/notebooks/lda-advi-aevb.ipynb + Parameters ---------- vars : object @@ -474,15 +489,6 @@ def get_transformed(v): assert(len(grvs) == len(global_RVs)) # ELBO wrt variational parameters - # inarray_g, uw_g, replace_g, c_g = _join_global_RVs(global_RVs, global_order) - # inarray_l, uw_l, replace_l, c_l = _join_local_RVs(local_RVs, local_order) - # logpt = _make_logpt(global_RVs, local_RVs, observed_RVs, model.potentials) - # replace = replace_g - # replace.update(replace_l) - # logp = theano.clone(logpt, replace, strict=False) - # elbo = _elbo_t(logp, uw_g, uw_l, inarray_g, inarray_l, - # n_mcsamples, random_seed) - # del logpt elbo, uw_l, uw_g = _make_elbo_t(observed_RVs, global_RVs, local_RVs, model.potentials, n_mcsamples, random_seed) From 7ed2cb5128928dcdf498efe3cf7886d9179f353a Mon Sep 17 00:00:00 2001 From: taku-y Date: Mon, 28 Nov 2016 23:01:34 +0900 Subject: [PATCH 41/83] Remove unnecessary comments --- pymc3/variational/advi_minibatch.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index 7da81cb991..f08c2ff60b 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -134,11 +134,6 @@ def _join_local_RVs(local_RVs, local_order): oness = [tt.ones(v.ravel().tag.test_value.shape) for v in local_RVs] c_l = tt.concatenate([c * ones for c, ones in zip(cs, oness)]) - # shps = [shp for _, _, shp, _ in local_order.vmap] - # c_l = tt.concatenate( - # [c * tt.ones(np.prod(shp)) for c, shp in zip(cs, shps)] - # ) - return inarray_local, uw_local, replace_local, c_l From 163b1be140886dfd158a9f93d06a5b359d7eaf48 Mon Sep 17 00:00:00 2001 From: taku-y Date: Mon, 5 Dec 2016 22:58:09 +0900 Subject: [PATCH 42/83] Fix typo --- pymc3/variational/advi_minibatch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index f08c2ff60b..77dfc8f08b 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -326,8 +326,8 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, When using mini-batches, :math:`c_{o}^{k}` and :math:`c_{l}^{k}` should be set to :math:`N/M`, where :math:`M` is the number of observations in each - mini-batch. Other weighting scheme were proposed in (Blundell et al., 2015) - for accelarating model fitting. + mini-batch. Another weighting scheme was proposed in + (Blundell et al., 2015) for accelarating model fitting. For working with ADVI, we need to give the probabilistic model (:code:`model`), the three types of RVs (:code:`observed_RVs`, From fad94106aff7f0559534d524cb74e611dcc4c769 Mon Sep 17 00:00:00 2001 From: taku-y Date: Thu, 8 Dec 2016 00:58:59 +0900 Subject: [PATCH 43/83] Minor fixes --- pymc3/tests/test_advi.py | 15 +++++++++++++++ pymc3/variational/advi.py | 21 +++++++++++++++------ pymc3/variational/advi_minibatch.py | 17 +++++++++++++---- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/pymc3/tests/test_advi.py b/pymc3/tests/test_advi.py index e9bb4e0815..3c48d72f72 100644 --- a/pymc3/tests/test_advi.py +++ b/pymc3/tests/test_advi.py @@ -119,6 +119,12 @@ def test_advi(self): np.testing.assert_allclose(np.mean(trace['mu']), mu_post, rtol=0.4) np.testing.assert_allclose(np.std(trace['mu']), np.sqrt(1. / d), rtol=0.4) + # Test for n < 10 + with Model(): + mu_ = Normal('mu', mu=mu0, sd=sd0, testval=0) + Normal('x', mu=mu_, sd=sd, observed=data) + advi_fit = advi(n=5, accurate_elbo=False, learning_rate=1e-1) + def test_advi_optimizer(self): n = 1000 sd0 = 2. @@ -178,6 +184,15 @@ def create_minibatch(data): np.testing.assert_allclose(np.mean(trace['mu']), mu_post, rtol=0.4) np.testing.assert_allclose(np.std(trace['mu']), np.sqrt(1. / d), rtol=0.4) + # Test for n < 10 + with Model(): + mu_ = Normal('mu', mu=mu0, sd=sd0, testval=0) + x = Normal('x', mu=mu_, sd=sd, observed=data_t) + advi_fit = advi_minibatch( + n=5, minibatch_tensors=[data_t], + minibatch_RVs=[x], minibatches=minibatches, + total_size=n, learning_rate=1e-1) + def test_advi_minibatch_shared(self): n = 1000 sd0 = 2. diff --git a/pymc3/variational/advi.py b/pymc3/variational/advi.py index a89195e085..60cebbc0b2 100644 --- a/pymc3/variational/advi.py +++ b/pymc3/variational/advi.py @@ -149,17 +149,26 @@ def advi(vars=None, start=None, model=None, n=5000, accurate_elbo=False, for i in progress: uw_i, e = f() elbos[i] = e - if i % (n // 10) == 0 and i > 0: + if n < 10: + progress.set_description('ELBO = {:,.5g}'.format(elbos[i])) + elif i % (n // 10) == 0 and i > 0: avg_elbo = elbos[i - n // 10:i].mean() progress.set_description('Average ELBO = {:,.5g}'.format(avg_elbo)) except KeyboardInterrupt: elbos = elbos[:i] - avg_elbo = elbos[i - n // 10:].mean() - pm._log.info('Interrupted at {:,d} [{:.0f}%]: Average ELBO = {:,.5g}'.format( - i, 100 * i // n, avg_elbo)) + if n < 10: + pm._log.info('Interrupted at {:,d} [{:.0f}%]: ELBO = {:,.5g}'.format( + i, 100 * i // n, elbos[i])) + else: + avg_elbo = elbos[i - n // 10:].mean() + pm._log.info('Interrupted at {:,d} [{:.0f}%]: Average ELBO = {:,.5g}'.format( + i, 100 * i // n, avg_elbo)) else: - avg_elbo = elbos[-n // 10:].mean() - pm._log.info('Finished [100%]: Average ELBO = {:,.5g}'.format(avg_elbo)) + if n < 10: + pm._log.info('Finished [100%]: ELBO = {:,.5g}'.format(elbos[-1])) + else: + avg_elbo = elbos[-n // 10:].mean() + pm._log.info('Finished [100%]: Average ELBO = {:,.5g}'.format(avg_elbo)) # Estimated parameters l = int(uw_i.size / 2) diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index 77dfc8f08b..e9e8ba6ffe 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -238,7 +238,7 @@ def _make_elbo_t( def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, minibatch_RVs=None, minibatch_tensors=None, minibatches=None, global_RVs=None, local_RVs=None, - observed_RVs=None, encoder_params=[], total_size=None, + observed_RVs=None, encoder_params=None, total_size=None, optimizer=None, learning_rate=.001, epsilon=.1, random_seed=None, mode=None): """Perform mini-batch ADVI. @@ -451,6 +451,9 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, """ theano.config.compute_test_value = 'ignore' + if encoder_params is None: + encoder_params = [] + model = pm.modelcontext(model) vars = inputvars(vars if vars is not None else model.vars) start = start if start is not None else model.test_point @@ -480,8 +483,12 @@ def get_transformed(v): grvs = list(set(vars) - set(list(local_RVs) + list(observed_RVs))) if global_RVs is None: global_RVs = OrderedDict({v: 1 for v in grvs}) - else: - assert(len(grvs) == len(global_RVs)) + elif len(grvs) != len(global_RVs): + _value_error( + 'global_RVs ({}) must have all global RVs: {}'.format( + [v for v in global_RVs], grvs + ) + ) # ELBO wrt variational parameters elbo, uw_l, uw_g = _make_elbo_t(observed_RVs, global_RVs, local_RVs, @@ -528,7 +535,9 @@ def is_shared(t): for i in progress: e = f(*next(minibatches)) elbos[i] = e - if i % (n // 10) == 0 and i > 0: + if n < 10: + progress.set_description('ELBO = {:,.2f}'.format(elbos[i])) + elif i % (n // 10) == 0 and i > 0: avg_elbo = elbos[i - n // 10:i].mean() progress.set_description('Average ELBO = {:,.2f}'.format(avg_elbo)) From e1a88e0a83fa03f33f8e5e38fd5ad291f4bb8b00 Mon Sep 17 00:00:00 2001 From: taku-y Date: Thu, 8 Dec 2016 23:25:34 +0900 Subject: [PATCH 44/83] Check transformed RVs using hasattr --- pymc3/variational/advi_minibatch.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index e9e8ba6ffe..01da56794d 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -469,10 +469,8 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, minibatch_tensors, total_size) # Replace local_RVs with transformed variables - ds = model.deterministics - def get_transformed(v): - if v in ds: + if hasattr(v, 'transformed'): return v.transformed return v local_RVs = OrderedDict( From ae349e9275e715a10e92233123aaee0586253d65 Mon Sep 17 00:00:00 2001 From: taku-y Date: Thu, 15 Dec 2016 12:33:39 +0900 Subject: [PATCH 45/83] Update conv-vae notebook --- .../convolutional_vae_keras_advi.ipynb | 121 ++++++++---------- pymc3/variational/advi_minibatch.py | 4 +- 2 files changed, 58 insertions(+), 67 deletions(-) diff --git a/docs/source/notebooks/convolutional_vae_keras_advi.ipynb b/docs/source/notebooks/convolutional_vae_keras_advi.ipynb index 93f82c20ff..0178f86e72 100644 --- a/docs/source/notebooks/convolutional_vae_keras_advi.ipynb +++ b/docs/source/notebooks/convolutional_vae_keras_advi.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "collapsed": true }, @@ -44,7 +44,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": { "collapsed": false }, @@ -110,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": { "collapsed": false }, @@ -119,7 +119,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "dict_keys(['data', 'COL_NAMES', 'DESCR', 'target'])\n" + "dict_keys(['COL_NAMES', 'target', 'DESCR', 'data'])\n" ] } ], @@ -145,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": { "collapsed": false }, @@ -198,7 +198,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": { "collapsed": true }, @@ -244,7 +244,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": { "collapsed": false }, @@ -322,7 +322,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": { "collapsed": true }, @@ -362,7 +362,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": { "collapsed": true }, @@ -418,14 +418,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Constants\n", - "minibatch_size = 100\n", + "minibatch_size = 200\n", "dim_hidden = 2" ] }, @@ -438,7 +438,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": { "collapsed": false }, @@ -450,21 +450,21 @@ "____________________________________________________________________________________________________\n", "Layer (type) Output Shape Param # Connected to \n", "====================================================================================================\n", - "input_1 (InputLayer) (100, 1, 28, 28) 0 \n", + "input_1 (InputLayer) (200, 1, 28, 28) 0 \n", "____________________________________________________________________________________________________\n", - "convolution2d_1 (Convolution2D) (100, 1, 28, 28) 5 input_1[0][0] \n", + "convolution2d_1 (Convolution2D) (200, 1, 28, 28) 5 input_1[0][0] \n", "____________________________________________________________________________________________________\n", - "convolution2d_2 (Convolution2D) (100, 64, 14, 14) 320 convolution2d_1[0][0] \n", + "convolution2d_2 (Convolution2D) (200, 64, 14, 14) 320 convolution2d_1[0][0] \n", "____________________________________________________________________________________________________\n", - "convolution2d_3 (Convolution2D) (100, 64, 14, 14) 36928 convolution2d_2[0][0] \n", + "convolution2d_3 (Convolution2D) (200, 64, 14, 14) 36928 convolution2d_2[0][0] \n", "____________________________________________________________________________________________________\n", - "convolution2d_4 (Convolution2D) (100, 64, 14, 14) 36928 convolution2d_3[0][0] \n", + "convolution2d_4 (Convolution2D) (200, 64, 14, 14) 36928 convolution2d_3[0][0] \n", "____________________________________________________________________________________________________\n", - "flatten_1 (Flatten) (100, 12544) 0 convolution2d_4[0][0] \n", + "flatten_1 (Flatten) (200, 12544) 0 convolution2d_4[0][0] \n", "____________________________________________________________________________________________________\n", - "dense_1 (Dense) (100, 128) 1605760 flatten_1[0][0] \n", + "dense_1 (Dense) (200, 128) 1605760 flatten_1[0][0] \n", "____________________________________________________________________________________________________\n", - "dense_2 (Dense) (100, 4) 516 dense_1[0][0] \n", + "dense_2 (Dense) (200, 4) 516 dense_1[0][0] \n", "====================================================================================================\n", "Total params: 1680457\n", "____________________________________________________________________________________________________\n" @@ -489,9 +489,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ @@ -503,7 +503,7 @@ " dec = Decoder(zs, net=cnn_dec)\n", " \n", " # Observation model\n", - " xs_ = pm.Normal('xs_', mu=dec.out.ravel(), sd=1, observed=xs_t.ravel(), dtype='float32')" + " xs_ = pm.Normal('xs_', mu=dec.out.ravel(), sd=0.1, observed=xs_t.ravel(), dtype='float32')" ] }, { @@ -515,7 +515,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": { "collapsed": true }, @@ -535,7 +535,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": { "collapsed": false }, @@ -553,7 +553,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": { "collapsed": false }, @@ -565,21 +565,21 @@ "____________________________________________________________________________________________________\n", "Layer (type) Output Shape Param # Connected to \n", "====================================================================================================\n", - "input_2 (InputLayer) (100, 2) 0 \n", + "input_2 (InputLayer) (200, 2) 0 \n", "____________________________________________________________________________________________________\n", - "dense_3 (Dense) (100, 100) 300 input_2[0][0] \n", + "dense_3 (Dense) (200, 100) 300 input_2[0][0] \n", "____________________________________________________________________________________________________\n", - "dense_4 (Dense) (100, 12544) 1266944 dense_3[0][0] \n", + "dense_4 (Dense) (200, 12544) 1266944 dense_3[0][0] \n", "____________________________________________________________________________________________________\n", - "reshape_1 (Reshape) (100, 64, 14, 14) 0 dense_4[0][0] \n", + "reshape_1 (Reshape) (200, 64, 14, 14) 0 dense_4[0][0] \n", "____________________________________________________________________________________________________\n", - "deconvolution2d_1 (Deconvolution2(100, 64, 14, 14) 36928 reshape_1[0][0] \n", + "deconvolution2d_1 (Deconvolution2(200, 64, 14, 14) 36928 reshape_1[0][0] \n", "____________________________________________________________________________________________________\n", - "deconvolution2d_2 (Deconvolution2(100, 64, 14, 14) 36928 deconvolution2d_1[0][0] \n", + "deconvolution2d_2 (Deconvolution2(200, 64, 14, 14) 36928 deconvolution2d_1[0][0] \n", "____________________________________________________________________________________________________\n", - "deconvolution2d_3 (Deconvolution2(100, 64, 28, 28) 16448 deconvolution2d_2[0][0] \n", + "deconvolution2d_3 (Deconvolution2(200, 64, 29, 29) 16448 deconvolution2d_2[0][0] \n", "____________________________________________________________________________________________________\n", - "convolution2d_5 (Convolution2D) (100, 1, 27, 27) 257 deconvolution2d_3[0][0] \n", + "convolution2d_5 (Convolution2D) (200, 1, 28, 28) 257 deconvolution2d_3[0][0] \n", "====================================================================================================\n", "Total params: 1357805\n", "____________________________________________________________________________________________________\n" @@ -606,7 +606,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": { "collapsed": true }, @@ -623,8 +623,8 @@ "\n", "minibatches = zip(create_minibatch(data, minibatch_size))\n", "\n", - "def adam(loss, param):\n", - " adam_ = keras.optimizers.Adam()\n", + "def rmsprop(loss, param):\n", + " adam_ = keras.optimizers.RMSprop()\n", " return adam_.get_updates(param, [], loss)" ] }, @@ -637,37 +637,27 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "Iteration 0 [0%]: ELBO = -56970296.0\n", - "Iteration 50 [10%]: Average ELBO = -53106500.16\n", - "Iteration 100 [20%]: Average ELBO = -52194973.92\n", - "Iteration 150 [30%]: Average ELBO = -52064982.24\n", - "Iteration 200 [40%]: Average ELBO = -51975449.2\n", - "Iteration 250 [50%]: Average ELBO = -51931158.48\n", - "Iteration 300 [60%]: Average ELBO = -51887135.28\n", - "Iteration 350 [70%]: Average ELBO = -51885579.92\n", - "Iteration 400 [80%]: Average ELBO = -51846011.28\n", - "Iteration 450 [90%]: Average ELBO = -51832335.44\n", - "Finished [100%]: ELBO = -51903096.0\n" + "Average ELBO = -41,015,059.05: 100%|██████████| 1000/1000 [36:47<00:00, 2.19s/it]\n" ] } ], "source": [ "with model:\n", " v_params = pm.variational.advi_minibatch(\n", - " n=500, minibatch_tensors=[xs_t], minibatches=minibatches,\n", + " n=1000, minibatch_tensors=[xs_t], minibatches=minibatches,\n", " local_RVs=local_RVs, observed_RVs=observed_RVs, \n", " encoder_params=(enc.params + dec.params), \n", - " optimizer=adam\n", + " optimizer=rmsprop\n", " )" ] }, @@ -687,7 +677,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": { "collapsed": false }, @@ -695,18 +685,18 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\nROTD/j9rP7zVXF4pbgAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -726,7 +716,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": { "collapsed": false }, @@ -734,18 +724,18 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\nPgXKrYu8UjwAAAAASUVORK5CYII=\n", + "image/png": "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\nO2uEj8f8cAAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -754,11 +744,12 @@ ], "source": [ "zs = np.array([(z1, z2) \n", - " for z1 in np.arange(-1, 1, 0.2) \n", - " for z2 in np.arange(-1, 1, 0.2)]).astype('float32')\n", + " for z1 in np.arange(-2, 2, 0.2) \n", + " for z2 in np.arange(-2, 2, 0.2)]).astype('float32')\n", "xs = dec.decode(zs)[:, 0, :, :]\n", - "xs = np.bmat([[xs[i + j * 10] for i in range(10)] for j in range(10)])\n", + "xs = np.bmat([[xs[i + j * 20] for i in range(20)] for j in range(20)])\n", "matplotlib.rc('axes', **{'grid': False})\n", + "plt.figure(figsize=(10, 10))\n", "plt.imshow(xs, interpolation='none', cmap='gray')" ] }, diff --git a/pymc3/variational/advi_minibatch.py b/pymc3/variational/advi_minibatch.py index 01da56794d..69a142447b 100644 --- a/pymc3/variational/advi_minibatch.py +++ b/pymc3/variational/advi_minibatch.py @@ -4,6 +4,7 @@ import theano import theano.tensor as tt from theano.sandbox.rng_mrg import MRG_RandomStreams +from theano.configparser import change_flags import tqdm import pymc3 as pm @@ -235,6 +236,7 @@ def _make_elbo_t( return elbo, uw_l, uw_g +@change_flags(compute_test_value='ignore') def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, minibatch_RVs=None, minibatch_tensors=None, minibatches=None, global_RVs=None, local_RVs=None, @@ -449,8 +451,6 @@ def advi_minibatch(vars=None, start=None, model=None, n=5000, n_mcsamples=1, Weight Uncertainty in Neural Network. In Proceedings of the 32nd International Conference on Machine Learning (ICML-15) (pp. 1613-1622). """ - theano.config.compute_test_value = 'ignore' - if encoder_params is None: encoder_params = [] From 9e237efba75b6d697d906975e558b6221285c39c Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 21 Dec 2016 02:14:58 +0300 Subject: [PATCH 46/83] Implementation of path derivative gradient estimator (NIPS 2016) #1615 --- pymc3/theanof.py | 2 -- pymc3/variational/replacements.py | 12 ++++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pymc3/theanof.py b/pymc3/theanof.py index e220412635..ab7750dff3 100644 --- a/pymc3/theanof.py +++ b/pymc3/theanof.py @@ -298,5 +298,3 @@ def set_tt_rng(new_rng): global _tt_rng _tt_rng = new_rng launch_rng(_tt_rng) - - diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 9d2d1a98cd..f82c1a41f3 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -35,6 +35,14 @@ def __init__(self, model=None, population=None, known=None): self.view = {vm.var: vm for vm in self.order.vmap} self.shared_params = self.create_shared_params() + @property + def constant_shared_params(self): + """Constant view on shared params + """ + return collections.OrderedDict( + [(name, theano.gradient.zero_grad(shared)) + for name, shared in self.shared_params.items()]) + def set_params(self, params): self.shared_params.update(params) @@ -315,7 +323,7 @@ def posterior_global(self, initial): return sd * initial + mu def log_q_W_global(self, posterior): - mu = self.shared_params['mu'] - rho = self.shared_params['rho'] + mu = self.constant_shared_params['mu'] + rho = self.constant_shared_params['rho'] samples = tt.sum(log_normal3(posterior, mu, rho), axis=1) return samples From 63c128564a7a7d739eb0ef59b68f358cf4a439fe Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 21 Dec 2016 02:32:55 +0300 Subject: [PATCH 47/83] local vars nee this path trick too --- pymc3/variational/replacements.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index f82c1a41f3..966cdda266 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -187,6 +187,10 @@ def __local_mu_rho(self): rho = tt.concatenate(rho) return mu, rho + def __constant_local_mu_rho(self): + mu, rho = self.__local_mu_rho() + return theano.gradient.zero_grad(mu), theano.gradient.zero_grad(rho) + def to_flat_input(self, node): """Replaces vars with flattened view stored in self.input """ @@ -197,7 +201,7 @@ def log_q_W_local(self, posterior): """ if not self.local_vars: return 0 - mu, rho = self.__local_mu_rho() + mu, rho = self.__constant_local_mu_rho() samples = tt.sum(log_normal3(posterior, mu, rho), axis=1) return samples From 02f5fa6e9c809b66d2268d1fc75530cd168f3580 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 21 Dec 2016 09:25:08 +0300 Subject: [PATCH 48/83] bug in local size calculation --- pymc3/variational/replacements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 966cdda266..6d3a279951 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -296,7 +296,7 @@ def global_vmap(self): @property def local_size(self): - size = sum([0] + [v.size for v in self.local_vars]) + size = sum([0] + [v.dsize for v in self.local_vars]) return size @property From 8cc955817401ee34eacfc67e5a1d014f30c27e81 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 21 Dec 2016 09:35:37 +0300 Subject: [PATCH 49/83] bug in global subset view --- pymc3/variational/replacements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 6d3a279951..0c003c6c11 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -126,7 +126,7 @@ def view_from(self, space, name, subset='all'): else: s = self.view[name].slc.start e = self.view[name].slc.stop - slc = slice(s - self.global_size, e - self.global_size) + slc = slice(s - self.local_size, e - self.local_size) _, _, shape, dtype = self.view[name] return space[:, slc].reshape((space.shape[0],) + shape).astype(dtype) From 4e302e6a655c0ac2e36f75fa941eebda38e1d4a0 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Thu, 22 Dec 2016 02:35:53 +0300 Subject: [PATCH 50/83] improved performance --- pymc3/variational/replacements.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 0c003c6c11..8c94b39898 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -104,7 +104,7 @@ def sample_over_space(self, space, node): """ def replace_node(post): return theano.clone(node, {self.input: post}) - samples, _ = theano.map(replace_node, space) + samples, _ = theano.scan(replace_node, space, n_steps=space.shape[0]) return samples def view_from(self, space, name, subset='all'): @@ -142,10 +142,13 @@ def posterior(self, initial): Tensor posterior space """ - return tt.concatenate([ - self.posterior_local(initial[:, self.local_slc]), - self.posterior_global(initial[:, self.global_slc]) - ], axis=1) + if self.local_vars: + return tt.concatenate([ + self.posterior_local(initial[:, self.local_slc]), + self.posterior_global(initial[:, self.global_slc]) + ], axis=1) + else: + return self.posterior_global(initial) def posterior_global(self, initial): """Implements posterior distribution from initial latent space From e5df6eee7410e8baa0ea3f685353137f57dc5e36 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Thu, 22 Dec 2016 04:36:06 +0300 Subject: [PATCH 51/83] changed the way for calling posterior --- pymc3/tests/test_replacements_mean_field.py | 2 +- pymc3/variational/replacements.py | 62 ++++++++++++--------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index ed425f1980..42d44a5b77 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -52,7 +52,7 @@ def test_vars_view(self): _, model, _ = models.multidimensional_model() with model: mf = MeanField() - posterior = mf.posterior(mf.initial(10)) + posterior = mf.posterior(10) x_sampled = mf.view_from(posterior, 'x').eval() self.assertEqual(x_sampled.shape, (10,) + model['x'].dshape) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 8c94b39898..9900914666 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -73,11 +73,12 @@ def create_shared_params(self): """ raise NotImplementedError - def initial(self, samples=1, zeros=False): + def initial(self, samples, subset, zeros=False): """ Parameters ---------- samples : int - number of samples + subset : determines what space is used can be {all|local|global} zeros : bool - return zeros if True Returns @@ -85,12 +86,44 @@ def initial(self, samples=1, zeros=False): Tensor sampled latent space shape(samples, size) """ - shape = tt.stack([tt.as_tensor(samples), tt.as_tensor(self.total_size)]) + assert subset in {'all', 'local', 'global'} + if subset == 'all': + size = self.total_size + elif subset == 'global': + size = self.global_size + else: + size = self.local_size + shape = tt.stack([tt.as_tensor(samples), tt.as_tensor(size)]) if not zeros: return tt_rng().normal(shape) else: return tt.zeros(shape) + def posterior(self, samples=1, zeros=False): + """Transforms initial latent space to posterior distribution + + Parameters + ---------- + samples : number of samples + zeros : set initial distribution to zeros + + Returns + ------- + Tensor + posterior space + """ + if self.local_vars and self.global_vars: + return tt.concatenate([ + self.posterior_local(self.initial(samples, 'local', zeros)), + self.posterior_global(self.initial(samples, 'global', zeros)) + ], axis=1) + elif self.local_vars: + return self.posterior_local(self.initial(samples, 'local', zeros)) + elif self.global_vars: + return self.posterior_global(self.initial(samples, 'global', zeros)) + else: + raise ValueError('No FreeVARs in model') + def sample_over_space(self, space, node): """ Parameters @@ -130,26 +163,6 @@ def view_from(self, space, name, subset='all'): _, _, shape, dtype = self.view[name] return space[:, slc].reshape((space.shape[0],) + shape).astype(dtype) - def posterior(self, initial): - """Transforms initial latent space to posterior distribution - - Parameters - ---------- - initial : initial latent space shape(samples, size) - - Returns - ------- - Tensor - posterior space - """ - if self.local_vars: - return tt.concatenate([ - self.posterior_local(initial[:, self.local_slc]), - self.posterior_global(initial[:, self.global_slc]) - ], axis=1) - else: - return self.posterior_global(initial) - def posterior_global(self, initial): """Implements posterior distribution from initial latent space @@ -266,8 +279,7 @@ def apply_replacements(self, node, deterministic=False): ------- node with replacements """ - initial = self.initial(zeros=deterministic) - posterior = self.posterior(initial)[0] + posterior = self.posterior(zeros=deterministic)[0] node = self.to_flat_input(node) return theano.clone(node, {self.input: posterior}) @@ -285,7 +297,7 @@ def elbo(self, samples=1, pi=1): """ samples = tt.as_tensor(samples) pi = tt.as_tensor(pi) - posterior = self.posterior(self.initial(samples)) + posterior = self.posterior(samples) elbo = self.log_p_D(posterior) - pi * self.KL_q_p_W(posterior) return elbo From 23ed1755f552c69e991c0bb0d1a4eb30bf4b98df Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Thu, 22 Dec 2016 22:22:32 +0300 Subject: [PATCH 52/83] deleted accidental added nuts file --- pymc3/step_methods/nuts.py | 238 ------------------------------------- 1 file changed, 238 deletions(-) delete mode 100644 pymc3/step_methods/nuts.py diff --git a/pymc3/step_methods/nuts.py b/pymc3/step_methods/nuts.py deleted file mode 100644 index 84bb3a90ba..0000000000 --- a/pymc3/step_methods/nuts.py +++ /dev/null @@ -1,238 +0,0 @@ -from .quadpotential import quad_potential -from .arraystep import ArrayStepShared, ArrayStep, SamplerHist, Competence -from ..model import modelcontext, Point -from ..vartypes import continuous_types -from numpy import exp, log, array -from numpy.random import uniform -from .hmc import leapfrog, Hamiltonian, bern, energy -from ..tuning import guess_scaling -import theano -from ..theanof import (make_shared_replacements, join_nonshared_inputs, CallableTensor, - gradient, inputvars) -import theano.tensor as tt - -__all__ = ['NUTS'] - - -class NUTS(ArrayStepShared): - """ - Automatically tunes step size and adjust number of steps for good performance. - - Implements "Algorithm 6: Efficient No-U-Turn Sampler with Dual Averaging" in: - - Hoffman, Matthew D., & Gelman, Andrew. (2011). - The No-U-Turn Sampler: Adaptively Setting Path Lengths in Hamiltonian Monte Carlo. - """ - default_blocked = True - - def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, state=None, - Emax=1000, - target_accept=0.8, - gamma=0.05, - k=0.75, - t0=10, - model=None, - profile=False, - mode=None, **kwargs): - """ - Parameters - ---------- - vars : list of Theano variables, default continuous vars - scaling : array_like, ndim = {1,2} or point - Scaling for momentum distribution. 1d arrays interpreted matrix diagonal. - step_scale : float, default=.25 - Size of steps to take, automatically scaled down by 1/n**(1/4) - is_cov : bool, default=False - Treat C as a covariance matrix/vector if True, else treat it as a precision matrix/vector - state - state to start from - Emax : float, default 1000 - maximum energy - target_accept : float (0,1) default .8 - target for avg accept probability between final branch and initial position - gamma : float, default .05 - k : float (.5,1) default .75 - scaling of speed of adaptation - t0 : int, default 10 - slows inital adapatation - model : Model - profile : bool or ProfileStats - sets the functions to be profiled - mode : string or `Mode` instance. - compilation mode passed to Theano functions - """ - model = modelcontext(model) - - if vars is None: - vars = model.cont_vars - vars = inputvars(vars) - - if scaling is None: - scaling = model.test_point - - if isinstance(scaling, dict): - scaling = guess_scaling( - Point(scaling, model=model), model=model, vars=vars) - - n = scaling.shape[0] - - self.step_size = step_scale / n**(1 / 4.) - - self.potential = quad_potential(scaling, is_cov, as_cov=False) - - if state is None: - state = SamplerHist() - self.state = state - self.Emax = Emax - - self.target_accept = target_accept - self.gamma = gamma - self.t0 = t0 - self.k = k - - self.Hbar = 0 - self.u = log(self.step_size * 10) - self.m = 1 - self.mode = mode - - shared = make_shared_replacements(vars, model) - - def create_hamiltonian(vars, shared, model): - dlogp = gradient(model.logpt, vars) - (logp, dlogp), q = join_nonshared_inputs( - [model.logpt, dlogp], vars, shared) - logp = CallableTensor(logp) - dlogp = CallableTensor(dlogp) - - return Hamiltonian(logp, dlogp, self.potential), q - - def create_energy_func(q): - p = tt.dvector('p') - p.tag.test_value = q.tag.test_value - E0 = energy(self.H, q, p) - E0_func = theano.function([q, p], E0, mode=self.mode) - E0_func.trust_input = True - - return E0_func - - self.H, q = create_hamiltonian(vars, shared, model) - self.compute_energy = create_energy_func(q) - - self.leapfrog1_dE = leapfrog1_dE(self.H, q, profile=profile, - mode=self.mode) - - super(NUTS, self).__init__(vars, shared, **kwargs) - - def astep(self, q0): - leapfrog = self.leapfrog1_dE - Emax = self.Emax - e = self.step_size - - p0 = self.potential.random() - E0 = self.compute_energy(q0, p0) - - u = uniform() - q = qn = qp = q0 - p = pn = pp = p0 - - n, s, j = 1, 1, 0 - - while s == 1: - v = bern(.5) * 2 - 1 - - if v == -1: - qn, pn, _, _, q1, n1, s1, a, na = buildtree( - leapfrog, qn, pn, u, v, j, e, Emax, E0) - else: - _, _, qp, pp, q1, n1, s1, a, na = buildtree( - leapfrog, qp, pp, u, v, j, e, Emax, E0) - - if s1 == 1 and bern(min(1, n1 * 1. / n)): - q = q1 - - n = n + n1 - - span = qp - qn - s = s1 * (span.dot(pn) >= 0) * (span.dot(pp) >= 0) - j = j + 1 - - p = -p - - w = 1. / (self.m + self.t0) - self.Hbar = (1 - w) * self.Hbar + w * \ - (self.target_accept - a * 1. / na) - - self.step_size = exp(self.u - (self.m**self.k / self.gamma) * self.Hbar) - self.m += 1 - - return q - - @staticmethod - def competence(var): - if var.dtype in continuous_types: - return Competence.IDEAL - return Competence.INCOMPATIBLE - - -def buildtree(leapfrog1_dE, q, p, u, v, j, e, Emax, E0): - if j == 0: - q1, p1, dE = leapfrog1_dE(q, p, array(v * e), E0) - - n1 = int(log(u) + dE <= 0) - s1 = int(log(u) + dE < Emax) - return q1, p1, q1, p1, q1, n1, s1, min(1, exp(-dE)), 1 - else: - qn, pn, qp, pp, q1, n1, s1, a1, na1 = buildtree( - leapfrog1_dE, q, p, u, v, j - 1, e, Emax, E0) - if s1 == 1: - if v == -1: - qn, pn, _, _, q11, n11, s11, a11, na11 = buildtree( - leapfrog1_dE, qn, pn, u, v, j - 1, e, Emax, E0) - else: - _, _, qp, pp, q11, n11, s11, a11, na11 = buildtree( - leapfrog1_dE, qp, pp, u, v, j - 1, e, Emax, E0) - - if bern(n11 * 1. / (max(n1 + n11, 1))): - q1 = q11 - - a1 = a1 + a11 - na1 = na1 + na11 - - span = qp - qn - s1 = s11 * (span.dot(pn) >= 0) * (span.dot(pp) >= 0) - n1 = n1 + n11 - return qn, pn, qp, pp, q1, n1, s1, a1, na1 - return - - -def leapfrog1_dE(H, q, profile, mode): - """Computes a theano function that computes one leapfrog step and the energy difference between the beginning and end of the trajectory. - Parameters - ---------- - H : Hamiltonian - q : theano.tensor - profile : Boolean - - Returns - ------- - theano function which returns - q_new, p_new, dE - """ - p = tt.dvector('p') - p.tag.test_value = q.tag.test_value - - e = tt.dscalar('e') - e.tag.test_value = 1 - - q1, p1 = leapfrog(H, q, p, 1, e) - E = energy(H, q1, p1) - - E0 = tt.dscalar('E0') - E0.tag.test_value = 1 - - dE = E - E0 - - f = theano.function([q, p, e, E0], [q1, p1, dE], - profile=profile, mode=mode) - f.trust_input = True - return f From ac949d28d68bb31a4badcd07afe91183c19a175e Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 23 Dec 2016 02:59:07 +0300 Subject: [PATCH 53/83] changed zero grad usage --- pymc3/variational/replacements.py | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 9900914666..960fecddef 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -9,8 +9,10 @@ from ..model import modelcontext import numpy as np - +# helper class FlatView = collections.namedtuple('FlatView', 'input, replacements') +# shortcut for zero grad +Z = theano.gradient.zero_grad class BaseReplacement(object): @@ -35,14 +37,6 @@ def __init__(self, model=None, population=None, known=None): self.view = {vm.var: vm for vm in self.order.vmap} self.shared_params = self.create_shared_params() - @property - def constant_shared_params(self): - """Constant view on shared params - """ - return collections.OrderedDict( - [(name, theano.gradient.zero_grad(shared)) - for name, shared in self.shared_params.items()]) - def set_params(self, params): self.shared_params.update(params) @@ -203,10 +197,6 @@ def __local_mu_rho(self): rho = tt.concatenate(rho) return mu, rho - def __constant_local_mu_rho(self): - mu, rho = self.__local_mu_rho() - return theano.gradient.zero_grad(mu), theano.gradient.zero_grad(rho) - def to_flat_input(self, node): """Replaces vars with flattened view stored in self.input """ @@ -214,11 +204,14 @@ def to_flat_input(self, node): def log_q_W_local(self, posterior): """log_q_W samples over q for local vars + + Gradient wrt mu, rho in density parametrization + is set to zero to lower variance of ELBO """ if not self.local_vars: return 0 - mu, rho = self.__constant_local_mu_rho() - samples = tt.sum(log_normal3(posterior, mu, rho), axis=1) + mu, rho = self.__local_mu_rho() + samples = tt.sum(log_normal3(posterior, Z(mu), Z(rho)), axis=1) return samples def log_q_W_global(self, posterior): @@ -342,7 +335,9 @@ def posterior_global(self, initial): return sd * initial + mu def log_q_W_global(self, posterior): - mu = self.constant_shared_params['mu'] - rho = self.constant_shared_params['rho'] - samples = tt.sum(log_normal3(posterior, mu, rho), axis=1) + """Gradient wrt mu, rho in density parametrization + is set to zero to lower variance of ELBO""" + mu = self.shared_params['mu'] + rho = self.shared_params['rho'] + samples = tt.sum(log_normal3(posterior, Z(mu), Z(rho)), axis=1) return samples From 26adf3b60a2035974d8f65d2d31fef49a0ad3758 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Fri, 23 Dec 2016 03:09:01 +0300 Subject: [PATCH 54/83] refactor apply replacements --- pymc3/variational/replacements.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 960fecddef..8a1d27911b 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -259,21 +259,33 @@ def log_p_W(self, posterior): samples = self.sample_over_space(posterior, _log_p_W_) return samples - def apply_replacements(self, node, deterministic=False): - """Replace variables in graph with variational approximation + def apply_replacements(self, node, deterministic=False, include=None, exclude=None): + """Replace variables in graph with variational approximation. By default, replaces all variables Parameters ---------- node : node for replacements deterministic : whether to use zeros as initial distribution - if True - median point will be sampled + if True - zero initial point will produce constant latent variables + include : list - latent variables to be replaced + exclude : list - latent variables to be excluded for replacements Returns ------- node with replacements """ + if include is not None and exclude is not None: + raise ValueError('Only one parameter is supported {include|exclude}, got two') + if include is not None: + replacements = {k: v for k, v + in self.flat_view.replacements.items() if k in include} + elif exclude is not None: + replacements = {k: v for k, v + in self.flat_view.replacements.items() if k not in exclude} + else: + replacements = self.flat_view.replacements + node = theano.clone(node, replacements, strict=False) posterior = self.posterior(zeros=deterministic)[0] - node = self.to_flat_input(node) return theano.clone(node, {self.input: posterior}) def elbo(self, samples=1, pi=1): From 63000fb0cdd9823e4774179e21b04a77d9e4a043 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sat, 24 Dec 2016 03:07:02 +0300 Subject: [PATCH 55/83] added useful functions to replacements --- pymc3/tests/test_replacements_mean_field.py | 147 +++++++++++++------- pymc3/variational/replacements.py | 75 +++++++++- 2 files changed, 169 insertions(+), 53 deletions(-) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index 42d44a5b77..676ec27314 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -2,59 +2,110 @@ import numpy as np import theano import theano.tensor as tt +import pymc3 as pm from pymc3 import Model, Normal from pymc3.variational.replacements import MeanField from . import models -class TestMeanField(unittest.TestCase): - def test_elbo(self): - mu0 = 1.5 - sigma = 1.0 - y_obs = np.array([1.6, 1.4]) - - post_mu = np.array([1.88]) - post_sd = np.array([1]) - # Create a model for test - with Model() as model: - mu = Normal('mu', mu=mu0, sd=sigma) - Normal('y', mu=mu, sd=1, observed=y_obs) - - # Create variational gradient tensor - mean_field = MeanField(model) - elbo = mean_field.elbo(samples=10000) - - mean_field.shared_params['mu'].set_value(post_mu) - mean_field.shared_params['rho'].set_value(np.log(np.exp(post_sd) - 1)) - - f = theano.function([], elbo.mean()) - elbo_mc = f() - - # Exact value - elbo_true = (-0.5 * ( - 3 + 3 * post_mu**2 - 2 * (y_obs[0] + y_obs[1] + mu0) * post_mu + - y_obs[0]**2 + y_obs[1]**2 + mu0**2 + 3 * np.log(2 * np.pi)) + - 0.5 * (np.log(2 * np.pi) + 1)) - np.testing.assert_allclose(elbo_mc, elbo_true, rtol=0, atol=1e-1) - - def test_vary_samples(self): - _, model, _ = models.simple_model() - i = tt.iscalar('i') - i.tag.test_value = 1 - with model: - mf = MeanField() - elbo = mf.elbo(i) - elbos = theano.function([i], elbo) - self.assertEqual(elbos(1).shape[0], 1) - self.assertEqual(elbos(10).shape[0], 10) - - def test_vars_view(self): - _, model, _ = models.multidimensional_model() - with model: - mf = MeanField() - posterior = mf.posterior(10) - x_sampled = mf.view_from(posterior, 'x').eval() - self.assertEqual(x_sampled.shape, (10,) + model['x'].dshape) +class TestApproximates: + class Base(unittest.TestCase): + approx = None + + def test_elbo(self): + if self.approx is not MeanField: + raise unittest.SkipTest + mu0 = 1.5 + sigma = 1.0 + y_obs = np.array([1.6, 1.4]) + + post_mu = np.array([1.88]) + post_sd = np.array([1]) + # Create a model for test + with Model() as model: + mu = Normal('mu', mu=mu0, sd=sigma) + Normal('y', mu=mu, sd=1, observed=y_obs) + + # Create variational gradient tensor + mean_field = self.approx(model) + elbo = mean_field.elbo(samples=10000) + + mean_field.shared_params['mu'].set_value(post_mu) + mean_field.shared_params['rho'].set_value(np.log(np.exp(post_sd) - 1)) + + f = theano.function([], elbo.mean()) + elbo_mc = f() + + # Exact value + elbo_true = (-0.5 * ( + 3 + 3 * post_mu**2 - 2 * (y_obs[0] + y_obs[1] + mu0) * post_mu + + y_obs[0]**2 + y_obs[1]**2 + mu0**2 + 3 * np.log(2 * np.pi)) + + 0.5 * (np.log(2 * np.pi) + 1)) + np.testing.assert_allclose(elbo_mc, elbo_true, rtol=0, atol=1e-1) + + def test_vary_samples(self): + _, model, _ = models.simple_model() + i = tt.iscalar('i') + i.tag.test_value = 1 + with model: + mf = self.approx() + elbo = mf.elbo(i) + elbos = theano.function([i], elbo) + self.assertEqual(elbos(1).shape[0], 1) + self.assertEqual(elbos(10).shape[0], 10) + + def test_vars_view(self): + _, model, _ = models.multidimensional_model() + with model: + mf = self.approx() + posterior = mf.posterior(10) + x_sampled = mf.view_from(posterior, 'x').eval() + self.assertEqual(x_sampled.shape, (10,) + model['x'].dshape) + + def test_sample_vp(self): + n_samples = 100 + xs = np.random.binomial(n=1, p=0.2, size=n_samples) + with pm.Model(): + p = pm.Beta('p', alpha=1, beta=1) + pm.Binomial('xs', n=1, p=p, observed=xs) + mf = self.approx() + trace = mf.sample_vp(draws=1, hide_transformed=True) + self.assertListEqual(trace.varnames, ['p']) + trace = mf.sample_vp(draws=1, hide_transformed=False) + self.assertListEqual(sorted(trace.varnames), ['p', 'p_logodds_']) + + def test_advi_optimizer(self): + from pymc3.variational.advi import adagrad_optimizer + n = 1000 + sd0 = 2. + mu0 = 4. + sd = 3. + mu = -5. + + data = sd * np.random.randn(n) + mu + + d = n / sd ** 2 + 1 / sd0 ** 2 + mu_post = (n * np.mean(data) / sd ** 2 + mu0 / sd0 ** 2) / d + + with Model(): + mu_ = Normal('mu', mu=mu0, sd=sd0, testval=0) + Normal('x', mu=mu_, sd=sd, observed=data) + optimizer = adagrad_optimizer(learning_rate=0.1, epsilon=0.1) + mf = self.approx() + elbo = mf.elbo().mean() + upd = optimizer(-elbo, mf.params) + step = theano.function([], elbo, updates=upd) + for _ in range(1000): + step() + trace = mf.sample_vp(10000) + + np.testing.assert_allclose(np.mean(trace['mu']), mu_post, rtol=0.1) + np.testing.assert_allclose(np.std(trace['mu']), np.sqrt(1. / d), rtol=0.4) + np.testing.assert_allclose(mf.median['mu'], mu_post, rtol=0.1) + + +class TestMeanField(TestApproximates.Base): + approx = MeanField if __name__ == '__main__': unittest.main() diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 8a1d27911b..581c4dc657 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -1,8 +1,9 @@ import collections import theano.tensor as tt +from theano.ifelse import ifelse import theano import pymc3 as pm -from ..theanof import tt_rng +from ..theanof import tt_rng, memoize, change_flags from ..blocking import ArrayOrdering from ..distributions.dist_math import rho2sd, log_normal3 from ..math import flatten_list @@ -88,10 +89,13 @@ def initial(self, samples, subset, zeros=False): else: size = self.local_size shape = tt.stack([tt.as_tensor(samples), tt.as_tensor(size)]) - if not zeros: - return tt_rng().normal(shape) - else: - return tt.zeros(shape) + if isinstance(zeros, bool): + zeros = int(zeros) + zeros = tt.as_tensor(zeros) + space = ifelse(zeros, + tt.zeros(shape), + tt_rng().normal(shape)) + return space def posterior(self, samples=1, zeros=False): """Transforms initial latent space to posterior distribution @@ -306,6 +310,67 @@ def elbo(self, samples=1, pi=1): elbo = self.log_p_D(posterior) - pi * self.KL_q_p_W(posterior) return elbo + @property + @memoize + @change_flags(compute_test_value='off') + def posterior_fn(self): + In = theano.In + samples = tt.iscalar('n_samples') + zeros = tt.bscalar('zeros') + posterior = self.posterior(samples, zeros) + fn = theano.function([In(samples, 'samples', 1, allow_downcast=True), + In(zeros, 'zeros', 0, allow_downcast=True)], + posterior) + + def inner(samples=1, zeros=False): + return fn(samples, int(zeros)) + return inner + + def sample_vp(self, draws=1, zeros=False, hide_transformed=False): + if hide_transformed: + vars_sampled = [v_ for v_ in self.model.unobserved_RVs + if not str(v_).endswith('_')] + else: + vars_sampled = [v_ for v_ in self.model.unobserved_RVs] + posterior = self.posterior_fn(draws, zeros) + names = [var.name for var in self.local_vars + self.global_vars] + samples = {name: self.view_from(posterior, name) + for name in names} + + def points(): + for i in range(draws): + yield {name: samples[name][i] + for name in names} + + trace = pm.sampling.NDArray(model=self.model, vars=vars_sampled) + trace.setup(draws=draws, chain=0) + for point in points(): + trace.record(point) + return pm.sampling.MultiTrace([trace]) + + @property + @memoize + def posterior_to_point_fn(self): + names = [var.name for var in self.local_vars + self.global_vars] + point_fn = self.model.fastfn(self.local_vars + self.global_vars) + + def inner(posterior): + if posterior.shape[0] > 1: + raise ValueError('Posterior should have one sample') + point = {name: self.view_from(posterior, name)[0] + for name in names} + return dict(zip(names, point_fn(point))) + return inner + + @property + def median(self): + posterior = self.posterior_fn(samples=1, zeros=True) + return self.posterior_to_point_fn(posterior) + + def random(self): + posterior = self.posterior_fn(samples=1, zeros=False) + return self.posterior_to_point_fn(posterior) + @property def local_vmap(self): return self.order.vmap[:len(self.local_vars)] From 52402609d7d0f705e3eb2f068dd8f23ee622d3a5 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sat, 24 Dec 2016 03:52:44 +0300 Subject: [PATCH 56/83] added `approximate` function --- pymc3/tests/test_replacements_mean_field.py | 13 +++-- pymc3/variational/inference.py | 60 +++++++++++++++++++++ 2 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 pymc3/variational/inference.py diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index 676ec27314..b68ad97f25 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -2,15 +2,20 @@ import numpy as np import theano import theano.tensor as tt +from theano.sandbox.rng_mrg import MRG_RandomStreams import pymc3 as pm from pymc3 import Model, Normal from pymc3.variational.replacements import MeanField +from pymc3.variational.inference import approximate +from ..theanof import set_tt_rng from . import models +set_tt_rng(MRG_RandomStreams(42)) class TestApproximates: class Base(unittest.TestCase): approx = None + NITER = 30000 def test_elbo(self): if self.approx is not MeanField: @@ -75,7 +80,6 @@ def test_sample_vp(self): self.assertListEqual(sorted(trace.varnames), ['p', 'p_logodds_']) def test_advi_optimizer(self): - from pymc3.variational.advi import adagrad_optimizer n = 1000 sd0 = 2. mu0 = 4. @@ -90,13 +94,8 @@ def test_advi_optimizer(self): with Model(): mu_ = Normal('mu', mu=mu0, sd=sd0, testval=0) Normal('x', mu=mu_, sd=sd, observed=data) - optimizer = adagrad_optimizer(learning_rate=0.1, epsilon=0.1) mf = self.approx() - elbo = mf.elbo().mean() - upd = optimizer(-elbo, mf.params) - step = theano.function([], elbo, updates=upd) - for _ in range(1000): - step() + approximate(self.NITER, method=mf) trace = mf.sample_vp(10000) np.testing.assert_allclose(np.mean(trace['mu']), mu_post, rtol=0.1) diff --git a/pymc3/variational/inference.py b/pymc3/variational/inference.py new file mode 100644 index 0000000000..d82f83d5a9 --- /dev/null +++ b/pymc3/variational/inference.py @@ -0,0 +1,60 @@ +import numpy as np +import theano +import pymc3 as pm +from .replacements import MeanField, BaseReplacement +from .advi import adagrad_optimizer +from tqdm import trange + + +APPROXIMATIONS = { + 'advi': MeanField, + 'meanfield': MeanField +} + + +def approximate(n=10000, population=None, local_vars=None, + optimizer=None, method='advi', samples=1, callbacks=None, + learning_rate=.001, epsilon=.1, + *args, **kwargs): + if isinstance(method, BaseReplacement): + approx = method + else: + approx = APPROXIMATIONS[method](known=local_vars, population=population, + *args, **kwargs) + if callbacks is None: + callbacks = [] + if optimizer is None: + optimizer = adagrad_optimizer(learning_rate, epsilon) + elbo = approx.elbo(samples).mean() + updates = optimizer(-elbo, approx.params) + step = theano.function([], elbo, updates=updates) + i = 0 + elbos = np.empty(n) + try: + progress = trange(n) + for i in progress: + e = step() + elbos[i] = e + for callback in callbacks: + callback(approx, e, i) + if n < 10: + progress.set_description('ELBO = {:,.5g}'.format(elbos[i])) + elif i % (n // 10) == 0 and i > 0: + avg_elbo = elbos[i - n // 10:i].mean() + progress.set_description('Average ELBO = {:,.5g}'.format(avg_elbo)) + except KeyboardInterrupt: + elbos = elbos[:i] + if n < 10: + pm._log.info('Interrupted at {:,d} [{:.0f}%]: ELBO = {:,.5g}'.format( + i, 100 * i // n, elbos[i])) + else: + avg_elbo = elbos[i - n // 10:].mean() + pm._log.info('Interrupted at {:,d} [{:.0f}%]: Average ELBO = {:,.5g}'.format( + i, 100 * i // n, avg_elbo)) + else: + if n < 10: + pm._log.info('Finished [100%]: ELBO = {:,.5g}'.format(elbos[-1])) + else: + avg_elbo = elbos[-n // 10:].mean() + pm._log.info('Finished [100%]: Average ELBO = {:,.5g}'.format(avg_elbo)) + return approx, elbos \ No newline at end of file From 7802a7897cb249a4ec92098a470f0f4f7396dff0 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sun, 25 Dec 2016 14:04:07 +0300 Subject: [PATCH 57/83] changed name MeanFieald to Advi --- pymc3/tests/test_replacements_mean_field.py | 6 +++--- pymc3/variational/inference.py | 5 ++--- pymc3/variational/replacements.py | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_replacements_mean_field.py index b68ad97f25..2e79ab5aef 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_replacements_mean_field.py @@ -5,7 +5,7 @@ from theano.sandbox.rng_mrg import MRG_RandomStreams import pymc3 as pm from pymc3 import Model, Normal -from pymc3.variational.replacements import MeanField +from pymc3.variational.replacements import Advi from pymc3.variational.inference import approximate from ..theanof import set_tt_rng from . import models @@ -18,7 +18,7 @@ class Base(unittest.TestCase): NITER = 30000 def test_elbo(self): - if self.approx is not MeanField: + if self.approx is not Advi: raise unittest.SkipTest mu0 = 1.5 sigma = 1.0 @@ -104,7 +104,7 @@ def test_advi_optimizer(self): class TestMeanField(TestApproximates.Base): - approx = MeanField + approx = Advi if __name__ == '__main__': unittest.main() diff --git a/pymc3/variational/inference.py b/pymc3/variational/inference.py index d82f83d5a9..b58bb8c12b 100644 --- a/pymc3/variational/inference.py +++ b/pymc3/variational/inference.py @@ -1,14 +1,13 @@ import numpy as np import theano import pymc3 as pm -from .replacements import MeanField, BaseReplacement +from .replacements import Advi, BaseReplacement from .advi import adagrad_optimizer from tqdm import trange APPROXIMATIONS = { - 'advi': MeanField, - 'meanfield': MeanField + 'advi': Advi, } diff --git a/pymc3/variational/replacements.py b/pymc3/variational/replacements.py index 581c4dc657..2b1b8e2237 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/replacements.py @@ -401,7 +401,7 @@ def global_slc(self): return slice(self.local_size, self.total_size) -class MeanField(BaseReplacement): +class Advi(BaseReplacement): def create_shared_params(self): return {'mu': theano.shared(self.input.tag.test_value[self.global_slc]), 'rho': theano.shared(np.ones((self.global_size,)))} From 2407d78dd5d3b6d50efc8ba04f96abb058d40170 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Mon, 26 Dec 2016 02:01:10 +0300 Subject: [PATCH 58/83] added docs, renamed classes --- ...field.py => test_variational_inference.py} | 2 +- .../{replacements.py => approximations.py} | 17 +++- pymc3/variational/inference.py | 96 +++++++++++++++++-- 3 files changed, 103 insertions(+), 12 deletions(-) rename pymc3/tests/{test_replacements_mean_field.py => test_variational_inference.py} (98%) rename pymc3/variational/{replacements.py => approximations.py} (95%) diff --git a/pymc3/tests/test_replacements_mean_field.py b/pymc3/tests/test_variational_inference.py similarity index 98% rename from pymc3/tests/test_replacements_mean_field.py rename to pymc3/tests/test_variational_inference.py index 2e79ab5aef..3607c6afe1 100644 --- a/pymc3/tests/test_replacements_mean_field.py +++ b/pymc3/tests/test_variational_inference.py @@ -5,7 +5,7 @@ from theano.sandbox.rng_mrg import MRG_RandomStreams import pymc3 as pm from pymc3 import Model, Normal -from pymc3.variational.replacements import Advi +from pymc3.variational.approximations import Advi from pymc3.variational.inference import approximate from ..theanof import set_tt_rng from . import models diff --git a/pymc3/variational/replacements.py b/pymc3/variational/approximations.py similarity index 95% rename from pymc3/variational/replacements.py rename to pymc3/variational/approximations.py index 2b1b8e2237..5b6dfe0d7b 100644 --- a/pymc3/variational/replacements.py +++ b/pymc3/variational/approximations.py @@ -16,7 +16,18 @@ Z = theano.gradient.zero_grad -class BaseReplacement(object): +class BaseApproximation(object): + """Base class for variational methods + It uses the idea that we can map standard normal distribution + to the approximate posterior distribution. Thus there are three blank + places in the implementation: + 1) creating shared parameters `create_shared_params()` + 2) mapping initial distribution to posterior `posterior{_{global|local}}(initial)` + 3) calculating log_q_W for approximation `log_q_W{_{global|local}}(posterior)` + + Then ELBO can be calculated for given approximation + log_p_D(posterior) - KL_q_p_W(posterior) + """ def __init__(self, model=None, population=None, known=None): model = modelcontext(model) self.check_model(model) @@ -401,10 +412,10 @@ def global_slc(self): return slice(self.local_size, self.total_size) -class Advi(BaseReplacement): +class Advi(BaseApproximation): def create_shared_params(self): return {'mu': theano.shared(self.input.tag.test_value[self.global_slc]), - 'rho': theano.shared(np.ones((self.global_size,)))} + 'rho': theano.shared(np.zeros((self.global_size,)))} def posterior_global(self, initial): sd = rho2sd(self.shared_params['rho']) diff --git a/pymc3/variational/inference.py b/pymc3/variational/inference.py index b58bb8c12b..9e00d51d5e 100644 --- a/pymc3/variational/inference.py +++ b/pymc3/variational/inference.py @@ -1,7 +1,7 @@ import numpy as np import theano import pymc3 as pm -from .replacements import Advi, BaseReplacement +from .approximations import Advi, BaseApproximation from .advi import adagrad_optimizer from tqdm import trange @@ -12,20 +12,100 @@ def approximate(n=10000, population=None, local_vars=None, - optimizer=None, method='advi', samples=1, callbacks=None, - learning_rate=.001, epsilon=.1, + optimizer=None, method='advi', samples=1, pi=1, + callbacks=None, learning_rate=.001, epsilon=.1, + model=None, more_params=None, more_updates=None, *args, **kwargs): - if isinstance(method, BaseReplacement): + """Interface for efficient variational inference with gradient + variance reduction described in [4]_ + + + PyMC3 supports the following variational inference methods: + 1) Automatic differentiation variational inference (ADVI) [2]_ + + Parameters + ---------- + n : int + number of training iterations + population : dict + maps observed_RV to its population size + if not provided defaults to full population + Note: population size is not `shape[0]` but `size` attr + local_vars : dict[Variable->(mu, rho)] + maps random variable to mu and rho + for posterior parametrization it is used for Autoencoding Variational Bayes + (AEVB; Kingma and Welling, 2014)[1]_ + optimizer : callable + optional custom optimizer to be called in the following way: + :code:`updates = optimizer(-elbo, list_of_params)` + method : str|Approximation + string description of approximation to be used or + Approximation instance used to calculate elbo and provide for shared params + samples : int|Tensor + number of Monte Carlo samples used for approximation, + defaults to 1 + pi : float|Tensor + pi in [0;1] reweighting constant for KL divergence + this trick was described in [3]_ for fine-tuning minibatch ADVI + callbacks : list[callable] + callables that will be called in the following way + :code:`callback(Approximation, elbo_history, i)` + learning_rate : float + learning rate for adagrad optimizer, + it will be ignored if optimizer is passed + epsilon : float - epsilon for adagrad optimizer, + it will be ignored if optimizer is passed + model : Model + Probabilistic model if function is called out of context + more_params : list + optional more parameters for computing gradients + more_updates : dict + more updates are included in step function + args : additional args that will be passed to Approximation + kwargs : additional kwargs that will be passed to Approximation + + Returns + ------- + (Approximation, elbo_history) + + Notes + ----- + Remember that you can manipulate with pi and samples with callbacks + + References + ---------- + .. [1] Kingma, D. P., & Welling, M. (2014). + Auto-Encoding Variational Bayes. stat, 1050, 1. + + .. [2] Kucukelbir, A., Ranganath, R., Gelman, A., & Blei, D. (2015). + Automatic variational inference in Stan. In Advances in neural + information processing systems (pp. 568-576). + + .. [3] Blundell, C., Cornebise, J., Kavukcuoglu, K., & Wierstra, D. (2015). + Weight Uncertainty in Neural Network. In Proceedings of the 32nd + International Conference on Machine Learning (ICML-15) (pp. 1613-1622). + + .. [4] Geoffrey, R., Yuhuai, W., David, D. (2016) + Sticking the Landing: A Simple Reduced-Variance Gradient for ADVI. + NIPS Workshop + """ + if isinstance(method, BaseApproximation): approx = method else: approx = APPROXIMATIONS[method](known=local_vars, population=population, - *args, **kwargs) + model=model, *args, **kwargs) if callbacks is None: callbacks = [] if optimizer is None: optimizer = adagrad_optimizer(learning_rate, epsilon) - elbo = approx.elbo(samples).mean() - updates = optimizer(-elbo, approx.params) + elbo = approx.elbo(samples=samples, pi=pi).mean() + params = approx.params + if more_params is not None: + params += more_params + updates = optimizer(-elbo, params) + if more_updates is not None: + more_updates.update(updates) + updates = more_updates step = theano.function([], elbo, updates=updates) i = 0 elbos = np.empty(n) @@ -35,7 +115,7 @@ def approximate(n=10000, population=None, local_vars=None, e = step() elbos[i] = e for callback in callbacks: - callback(approx, e, i) + callback(approx, elbos[:i+1], i) if n < 10: progress.set_description('ELBO = {:,.5g}'.format(elbos[i])) elif i % (n // 10) == 0 and i > 0: From fbf26d45526a770f9f09d92df23a2d1fcccaac30 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Mon, 26 Dec 2016 02:43:15 +0300 Subject: [PATCH 59/83] add deterministics to posterior to point function --- pymc3/tests/test_variational_inference.py | 2 ++ pymc3/variational/approximations.py | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pymc3/tests/test_variational_inference.py b/pymc3/tests/test_variational_inference.py index 3607c6afe1..ac8d124ec7 100644 --- a/pymc3/tests/test_variational_inference.py +++ b/pymc3/tests/test_variational_inference.py @@ -94,6 +94,7 @@ def test_advi_optimizer(self): with Model(): mu_ = Normal('mu', mu=mu0, sd=sd0, testval=0) Normal('x', mu=mu_, sd=sd, observed=data) + pm.Deterministic('mu_sq', mu_**2) mf = self.approx() approximate(self.NITER, method=mf) trace = mf.sample_vp(10000) @@ -101,6 +102,7 @@ def test_advi_optimizer(self): np.testing.assert_allclose(np.mean(trace['mu']), mu_post, rtol=0.1) np.testing.assert_allclose(np.std(trace['mu']), np.sqrt(1. / d), rtol=0.4) np.testing.assert_allclose(mf.median['mu'], mu_post, rtol=0.1) + np.testing.assert_allclose(mf.median['mu_sq'], mu_post**2, rtol=0.1) class TestMeanField(TestApproximates.Base): diff --git a/pymc3/variational/approximations.py b/pymc3/variational/approximations.py index 5b6dfe0d7b..1cf00b5a4b 100644 --- a/pymc3/variational/approximations.py +++ b/pymc3/variational/approximations.py @@ -362,15 +362,16 @@ def points(): @property @memoize def posterior_to_point_fn(self): - names = [var.name for var in self.local_vars + self.global_vars] - point_fn = self.model.fastfn(self.local_vars + self.global_vars) + names_vars = [var.name for var in self.local_vars + self.global_vars] + names_point = names_vars + [var.name for var in self.model.deterministics] + point_fn = self.model.fastfn(self.local_vars + self.global_vars + self.model.deterministics) def inner(posterior): if posterior.shape[0] > 1: raise ValueError('Posterior should have one sample') point = {name: self.view_from(posterior, name)[0] - for name in names} - return dict(zip(names, point_fn(point))) + for name in names_vars} + return dict(zip(names_point, point_fn(point))) return inner @property From c394d5ebb9d0464a2d27fa6c795bed5cd55dd366 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Mon, 26 Dec 2016 22:08:50 +0300 Subject: [PATCH 60/83] trying to fix reweighting --- pymc3/variational/approximations.py | 34 +++++++++++++++++------------ pymc3/variational/inference.py | 8 +++---- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/pymc3/variational/approximations.py b/pymc3/variational/approximations.py index 1cf00b5a4b..ba0fa8a8f9 100644 --- a/pymc3/variational/approximations.py +++ b/pymc3/variational/approximations.py @@ -198,11 +198,11 @@ def posterior_local(self, initial): """ if not self.local_vars: return initial - mu, rho = self.__local_mu_rho() + mu, rho = self._local_mu_rho() x = initial * rho2sd(rho) + mu return x - def __local_mu_rho(self): + def _local_mu_rho(self): mu = [] rho = [] for var in self.local_vars: @@ -225,8 +225,13 @@ def log_q_W_local(self, posterior): """ if not self.local_vars: return 0 - mu, rho = self.__local_mu_rho() - samples = tt.sum(log_normal3(posterior, Z(mu), Z(rho)), axis=1) + logp = [] + for var in self.local_vars: + mu = self.known[var][0].ravel() + rho = self.known[var][1].ravel() + q = log_normal3(self.view_from(posterior, var.name, 'local'), Z(mu), Z(rho)) + logp.append(self.weighted_logp(var, q)) + samples = tt.sum(tt.concatenate(logp, axis=1), axis=1) return samples def log_q_W_global(self, posterior): @@ -243,23 +248,22 @@ def log_p_D(self, posterior): """log_p_D samples over q """ _log_p_D_ = tt.sum( - list(map(self.weighted_likelihood, self.model.observed_RVs)) + list(map(self.weighted_logp, self.model.observed_RVs)) ) _log_p_D_ = self.to_flat_input(_log_p_D_) samples = self.sample_over_space(posterior, _log_p_D_) return samples - def weighted_likelihood(self, var): - """Weight likelihood according to given population size + def weighted_logp(self, var, logp=None): + """Weight logp according to given population size """ - tot = self.population.get( - var, self.population.get(var.name)) - logpt = tt.sum(var.logpt) + tot = self.population.get(var) + if logp is None: + logp = tt.sum(var.logpt) if tot is not None: tot = tt.as_tensor(tot) - logpt *= tot - logpt /= var.size - return logpt + logp *= tot / var.shape[0] + return logp def KL_q_p_W(self, posterior): """KL(q||p) samples over q @@ -424,7 +428,9 @@ def posterior_global(self, initial): return sd * initial + mu def log_q_W_global(self, posterior): - """Gradient wrt mu, rho in density parametrization + """log_q_W samples over q for global vars + + Gradient wrt mu, rho in density parametrization is set to zero to lower variance of ELBO""" mu = self.shared_params['mu'] rho = self.shared_params['rho'] diff --git a/pymc3/variational/inference.py b/pymc3/variational/inference.py index 9e00d51d5e..3fce1cc21b 100644 --- a/pymc3/variational/inference.py +++ b/pymc3/variational/inference.py @@ -17,7 +17,7 @@ def approximate(n=10000, population=None, local_vars=None, model=None, more_params=None, more_updates=None, *args, **kwargs): """Interface for efficient variational inference with gradient - variance reduction described in [4]_ + variance reduction as described in [4]_ PyMC3 supports the following variational inference methods: @@ -27,10 +27,10 @@ def approximate(n=10000, population=None, local_vars=None, ---------- n : int number of training iterations - population : dict + population : dict[Variable->int] maps observed_RV to its population size if not provided defaults to full population - Note: population size is not `shape[0]` but `size` attr + Note: population size is `shape[0]` of the whole data local_vars : dict[Variable->(mu, rho)] maps random variable to mu and rho for posterior parametrization it is used for Autoencoding Variational Bayes @@ -70,7 +70,7 @@ def approximate(n=10000, population=None, local_vars=None, Notes ----- - Remember that you can manipulate with pi and samples with callbacks + Remember that you can manipulate pi and number of samples with callbacks References ---------- From 2162d4c0861894efd3b42f9dbf8d8ebe61fb2d57 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Mon, 26 Dec 2016 22:27:38 +0300 Subject: [PATCH 61/83] weight log_p_W{local|global} correctly --- pymc3/variational/approximations.py | 42 ++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/pymc3/variational/approximations.py b/pymc3/variational/approximations.py index ba0fa8a8f9..040a6219dc 100644 --- a/pymc3/variational/approximations.py +++ b/pymc3/variational/approximations.py @@ -270,10 +270,41 @@ def KL_q_p_W(self, posterior): """ return self.log_q_W(posterior) - self.log_p_W(posterior) - def log_p_W(self, posterior): + def log_p_W_local(self, posterior): + if not self.local_vars: + return 0 + _log_p_W_local_ = tt.sum( + list(map(self.weighted_logp, self.local_vars)) + ) + _log_p_W_local_ = self.to_flat_input(_log_p_W_local_) + samples = self.sample_over_space(posterior, _log_p_W_local_) + return samples + + def log_p_W_global(self, posterior): """log_p_W samples over q """ - _log_p_W_ = self.model.varlogpt + tt.sum(self.model.potentials) + def logp(var): + return var.logpt + _log_p_W_global_ = tt.sum( + list(map(logp, self.global_vars)) + ) + _log_p_W_global_ = self.to_flat_input(_log_p_W_global_) + samples = self.sample_over_space(posterior, _log_p_W_global_) + return samples + + def log_p_W(self, posterior): + def logp(var): + return var.logpt + if self.local_vars: + _log_p_W_local_ = tt.sum( + list(map(self.weighted_logp, self.local_vars)) + ) + else: + _log_p_W_local_ = 0 + _log_p_W_global_ = tt.sum( + list(map(logp, self.global_vars)) + ) + _log_p_W_ = _log_p_W_global_ + _log_p_W_local_ _log_p_W_ = self.to_flat_input(_log_p_W_) samples = self.sample_over_space(posterior, _log_p_W_) return samples @@ -322,7 +353,12 @@ def elbo(self, samples=1, pi=1): samples = tt.as_tensor(samples) pi = tt.as_tensor(pi) posterior = self.posterior(samples) - elbo = self.log_p_D(posterior) - pi * self.KL_q_p_W(posterior) + elbo = (self.log_p_D(posterior) + - self.log_q_W_local(posterior) + - pi * self.log_q_W_global(posterior) + + self.log_p_W_local(posterior) + + pi * self.log_p_W_global(posterior)) + return elbo @property From 7609f7200100038177a21a97ef6048f70b5b2a00 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 27 Dec 2016 23:35:27 +0300 Subject: [PATCH 62/83] local and global weighting --- pymc3/variational/approximations.py | 19 ++++++++++--------- pymc3/variational/inference.py | 14 ++++++++++---- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/pymc3/variational/approximations.py b/pymc3/variational/approximations.py index 040a6219dc..723061dda7 100644 --- a/pymc3/variational/approximations.py +++ b/pymc3/variational/approximations.py @@ -262,7 +262,7 @@ def weighted_logp(self, var, logp=None): logp = tt.sum(var.logpt) if tot is not None: tot = tt.as_tensor(tot) - logp *= tot / var.shape[0] + logp = logp * tot / var.shape[0] return logp def KL_q_p_W(self, posterior): @@ -338,27 +338,28 @@ def apply_replacements(self, node, deterministic=False, include=None, exclude=No posterior = self.posterior(zeros=deterministic)[0] return theano.clone(node, {self.input: posterior}) - def elbo(self, samples=1, pi=1): + def elbo(self, samples=1, pi_local=1, pi_global=1): """Output of this function should be used for fitting a model Parameters ---------- samples : Tensor - number of samples - pi : Tensor - weight of variational part + pi_local : Tensor - weight of local variational part + pi_global : Tensor - weight of global variational part Returns ------- ELBO samples """ samples = tt.as_tensor(samples) - pi = tt.as_tensor(pi) + pi_local = tt.as_tensor(pi_local) + pi_global = tt.as_tensor(pi_global) posterior = self.posterior(samples) elbo = (self.log_p_D(posterior) - - self.log_q_W_local(posterior) - - pi * self.log_q_W_global(posterior) - + self.log_p_W_local(posterior) - + pi * self.log_p_W_global(posterior)) - + - pi_local * self.log_q_W_local(posterior) + - pi_global * self.log_q_W_global(posterior) + + pi_local * self.log_p_W_local(posterior) + + pi_global * self.log_p_W_global(posterior)) return elbo @property diff --git a/pymc3/variational/inference.py b/pymc3/variational/inference.py index 3fce1cc21b..48e79937c2 100644 --- a/pymc3/variational/inference.py +++ b/pymc3/variational/inference.py @@ -12,7 +12,8 @@ def approximate(n=10000, population=None, local_vars=None, - optimizer=None, method='advi', samples=1, pi=1, + optimizer=None, method='advi', + samples=1, pi_local=1, pi_global=1, callbacks=None, learning_rate=.001, epsilon=.1, model=None, more_params=None, more_updates=None, *args, **kwargs): @@ -44,8 +45,11 @@ def approximate(n=10000, population=None, local_vars=None, samples : int|Tensor number of Monte Carlo samples used for approximation, defaults to 1 - pi : float|Tensor - pi in [0;1] reweighting constant for KL divergence + pi_local : float|Tensor + pi_local in [0;1] reweighting constant for local KL divergence + this trick was described in [3]_ for fine-tuning minibatch ADVI + pi_global : float|Tensor + pi_global in [0;1] reweighting constant for global KL divergence this trick was described in [3]_ for fine-tuning minibatch ADVI callbacks : list[callable] callables that will be called in the following way @@ -98,7 +102,9 @@ def approximate(n=10000, population=None, local_vars=None, callbacks = [] if optimizer is None: optimizer = adagrad_optimizer(learning_rate, epsilon) - elbo = approx.elbo(samples=samples, pi=pi).mean() + elbo = approx.elbo(samples=samples, + pi_local=pi_local, + pi_global=pi_global).mean() params = approx.params if more_params is not None: params += more_params From d55d258523895b30fd5d897b95c53ead09a91771 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 27 Dec 2016 23:51:56 +0300 Subject: [PATCH 63/83] added docs --- pymc3/variational/approximations.py | 38 ++++++++++++++++++++++++++++- pymc3/variational/inference.py | 7 +++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/pymc3/variational/approximations.py b/pymc3/variational/approximations.py index 723061dda7..39adc2bf5e 100644 --- a/pymc3/variational/approximations.py +++ b/pymc3/variational/approximations.py @@ -28,7 +28,7 @@ class BaseApproximation(object): Then ELBO can be calculated for given approximation log_p_D(posterior) - KL_q_p_W(posterior) """ - def __init__(self, model=None, population=None, known=None): + def __init__(self, population=None, known=None, model=None): model = modelcontext(model) self.check_model(model) if known is None: @@ -455,6 +455,42 @@ def global_slc(self): class Advi(BaseApproximation): + """ADVI algorithm as discribed in Kucukelbir[1]_ with + variance reduction [3]_. ADVI also supports Auto-Encoding + Variational Bayes described in [2]_ and minibatch training. + + The main goal of advi is fast variational inference algorithm + that can be scaled on large problems. The limitation of this + approximation is that latent variables are assumed to be independent + and approximated with normal distribution. These assumptions don't hold + in regular practical task. + + Parameters + ---------- + population : dict[Variable->int] + maps observed_RV to its population size + if not provided defaults to full population + Note: population size is `shape[0]` of the whole data + known : dict[Variable->(mu, rho)] + maps local random variable to mu and rho for posterior parametrization + it is used for Autoencoding Variational Bayes + (AEVB; Kingma and Welling, 2014)[1]_ + model : Model + PyMC3 model that's posterior is going to be approximated + + References + ---------- + .. [1] Kingma, D. P., & Welling, M. (2014). + Auto-Encoding Variational Bayes. stat, 1050, 1. + + .. [2] Kucukelbir, A., Ranganath, R., Gelman, A., & Blei, D. (2015). + Automatic variational inference in Stan. In Advances in neural + information processing systems (pp. 568-576). + + .. [3] Geoffrey, R., Yuhuai, W., David, D. (2016) + Sticking the Landing: A Simple Reduced-Variance Gradient for ADVI. + NIPS Workshop + """ def create_shared_params(self): return {'mu': theano.shared(self.input.tag.test_value[self.global_slc]), 'rho': theano.shared(np.zeros((self.global_size,)))} diff --git a/pymc3/variational/inference.py b/pymc3/variational/inference.py index 48e79937c2..9827e29fbe 100644 --- a/pymc3/variational/inference.py +++ b/pymc3/variational/inference.py @@ -33,15 +33,16 @@ def approximate(n=10000, population=None, local_vars=None, if not provided defaults to full population Note: population size is `shape[0]` of the whole data local_vars : dict[Variable->(mu, rho)] - maps random variable to mu and rho - for posterior parametrization it is used for Autoencoding Variational Bayes + maps local random variable to mu and rho for posterior + parametrization, it is used for Autoencoding Variational Bayes (AEVB; Kingma and Welling, 2014)[1]_ optimizer : callable optional custom optimizer to be called in the following way: :code:`updates = optimizer(-elbo, list_of_params)` method : str|Approximation string description of approximation to be used or - Approximation instance used to calculate elbo and provide for shared params + Approximation instance used to calculate elbo and provide + for shared params samples : int|Tensor number of Monte Carlo samples used for approximation, defaults to 1 From dca919c2f87d7a4b03950ba7ddf7a8a8d6dc9de8 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 28 Dec 2016 02:40:08 +0300 Subject: [PATCH 64/83] preparing mnist vae, fixed bugs --- pymc3/tests/test_variational_inference.py | 2 +- pymc3/variational/approximations.py | 41 ++++++++++++++++------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/pymc3/tests/test_variational_inference.py b/pymc3/tests/test_variational_inference.py index ac8d124ec7..bdf39d60f4 100644 --- a/pymc3/tests/test_variational_inference.py +++ b/pymc3/tests/test_variational_inference.py @@ -32,7 +32,7 @@ def test_elbo(self): Normal('y', mu=mu, sd=1, observed=y_obs) # Create variational gradient tensor - mean_field = self.approx(model) + mean_field = self.approx(model=model) elbo = mean_field.elbo(samples=10000) mean_field.shared_params['mu'].set_value(post_mu) diff --git a/pymc3/variational/approximations.py b/pymc3/variational/approximations.py index 39adc2bf5e..efcb45f4c8 100644 --- a/pymc3/variational/approximations.py +++ b/pymc3/variational/approximations.py @@ -37,11 +37,17 @@ def __init__(self, population=None, known=None, model=None): population = dict() self.population = population self.model = model + + def get_transformed(v): + if hasattr(v, 'transformed'): + return v.transformed + return v + known = {get_transformed(k): v for k, v in known.items()} self.known = known - self.local_vars = [v for v in model.vars if v in known] - self.global_vars = [v for v in model.vars if v not in known] + self.local_vars = [v for v in model.free_RVs if v in known] + self.global_vars = [v for v in model.free_RVs if v not in known] self.order = ArrayOrdering(self.local_vars + self.global_vars) - inputvar = tt.vector('flat_view') + inputvar = tt.vector('flat_view', dtype=theano.config.floatX) inputvar.tag.test_value = flatten_list(self.local_vars + self.global_vars).tag.test_value replacements = {self.model.named_vars[name]: inputvar[slc].reshape(shape).astype(dtype) for name, slc, shape, dtype in self.order.vmap} @@ -149,14 +155,17 @@ def replace_node(post): samples, _ = theano.scan(replace_node, space, n_steps=space.shape[0]) return samples - def view_from(self, space, name, subset='all'): + def view_from(self, space, name, subset='all', reshape=True): """ Parameters ---------- space : space to take view of variable from - name : name of variable - subset : determines what space is used can be {all|local|global} - + name : str + name of variable + subset : str + determines what space is used can be {all|local|global} + reshape : bool + whether to reshape variable form vectorized view Returns ------- variable @@ -170,7 +179,10 @@ def view_from(self, space, name, subset='all'): e = self.view[name].slc.stop slc = slice(s - self.local_size, e - self.local_size) _, _, shape, dtype = self.view[name] - return space[:, slc].reshape((space.shape[0],) + shape).astype(dtype) + view = space[:, slc] + if reshape: + view = view.reshape((space.shape[0],) + shape) + return view.astype(dtype) def posterior_global(self, initial): """Implements posterior distribution from initial latent space @@ -229,7 +241,8 @@ def log_q_W_local(self, posterior): for var in self.local_vars: mu = self.known[var][0].ravel() rho = self.known[var][1].ravel() - q = log_normal3(self.view_from(posterior, var.name, 'local'), Z(mu), Z(rho)) + x = self.view_from(posterior, var.name, 'all', reshape=False) + q = log_normal3(x, Z(mu), Z(rho)) logp.append(self.weighted_logp(var, q)) samples = tt.sum(tt.concatenate(logp, axis=1), axis=1) return samples @@ -259,7 +272,7 @@ def weighted_logp(self, var, logp=None): """ tot = self.population.get(var) if logp is None: - logp = tt.sum(var.logpt) + logp = var.logpt if tot is not None: tot = tt.as_tensor(tot) logp = logp * tot / var.shape[0] @@ -492,8 +505,10 @@ class Advi(BaseApproximation): NIPS Workshop """ def create_shared_params(self): - return {'mu': theano.shared(self.input.tag.test_value[self.global_slc]), - 'rho': theano.shared(np.zeros((self.global_size,)))} + return {'mu': theano.shared( + self.input.tag.test_value[self.global_slc]), + 'rho': theano.shared( + np.zeros((self.global_size,), dtype=theano.config.floatX))} def posterior_global(self, initial): sd = rho2sd(self.shared_params['rho']) @@ -507,5 +522,5 @@ def log_q_W_global(self, posterior): is set to zero to lower variance of ELBO""" mu = self.shared_params['mu'] rho = self.shared_params['rho'] - samples = tt.sum(log_normal3(posterior, Z(mu), Z(rho)), axis=1) + samples = tt.sum(log_normal3(posterior[:, self.global_slc], Z(mu), Z(rho)), axis=1) return samples From cb2e21951fbe63d99bca86a755c6aa09f4629be3 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sat, 31 Dec 2016 02:25:39 +0300 Subject: [PATCH 65/83] Took in account suggestions for refactoring --- pymc3/distributions/dist_math.py | 71 ++++++++--- pymc3/tests/test_variational_inference.py | 6 +- pymc3/variational/approximations.py | 137 ++++++++++++++++------ pymc3/variational/inference.py | 9 +- 4 files changed, 165 insertions(+), 58 deletions(-) diff --git a/pymc3/distributions/dist_math.py b/pymc3/distributions/dist_math.py index 7e99bf4252..f0bccce68c 100644 --- a/pymc3/distributions/dist_math.py +++ b/pymc3/distributions/dist_math.py @@ -82,36 +82,71 @@ def i1(x): def sd2rho(sd): - """sd -> rho - theano converter - mu + sd*e = mu + log(1+exp(rho))*e""" + """ + `sd -> rho` theano converter + + :math:`mu + sd*e = mu + log(1+exp(rho))*e`""" return tt.log(tt.exp(sd) - 1) def rho2sd(rho): - """rho -> sd - theano converter - mu + sd*e = mu + log(1+exp(rho))*e""" - return tt.log1p(tt.exp(rho)) - - -def kl_divergence_normal_pair(mu1, mu2, sd1, sd2): - elemwise_kl = (tt.log(sd2/sd1) + - (sd2**2 + (mu1-mu2)**2)/(2.*sd2**2) - - 0.5) - return tt.sum(elemwise_kl) - + """ + `rho -> sd` theano converter -def kl_divergence_normal_pair3(mu1, mu2, rho1, rho2): - sd1, sd2 = rho2sd(rho1), rho2sd(rho2) - return kl_divergence_normal_pair(mu1, mu2, sd1, sd2) + :math:`mu + sd*e = mu + log(1+exp(rho))*e`""" + return tt.log1p(tt.exp(rho)) def log_normal(x, mean, std, eps=0.0): + """ + Calculate logarithm of normal distribution at point `x` + with given `mean` and `std` + + Notes + ----- + There are three variants for density evaluation function. + They use: + 1) standard normal distribution - `std` (:code:`log_normal`) + 2) `w`, logarithm of `std` :math:`w = log(std)` (:code:`log_normal2`) + 3) `rho` that follows this equation :math:`rho = log(exp(std) - 1)` (:code:`log_normal3`) + ---- + """ std += eps return c - tt.log(tt.abs_(std)) - (x - mean) ** 2 / (2 * std ** 2) +def log_normal2(x, mean, w, eps=0.0): + """ + Calculate logarithm of normal distribution at point `x` + with given `mean` and `w` + + Notes + ----- + There are three variants for density evaluation function. + They use: + 1) standard normal distribution - `std` (:code:`log_normal`) + 2) `w`, logarithm of `std` :math:`w = log(std)` (:code:`log_normal2`) + 3) `rho` that follows this equation :math:`rho = log(exp(std) - 1)` (:code:`log_normal3`) + ---- + """ + std = tt.exp(w) + return log_normal(x, mean, std, eps) + + def log_normal3(x, mean, rho, eps=0.0): + """ + Calculate logarithm of normal distribution at point `x` + with given `mean` and `rho` + + Notes + ----- + There are three variants for density evaluation function. + They use: + 1) standard normal distribution - `std` (:code:`log_normal`) + 2) `w`, logarithm of `std` :math:`w = log(std)` (:code:`log_normal2`) + 3) `rho` that follows this equation :math:`rho = log(exp(std) - 1)` (:code:`log_normal3`) + ---- + """ std = rho2sd(rho) return log_normal(x, mean, std, eps) + diff --git a/pymc3/tests/test_variational_inference.py b/pymc3/tests/test_variational_inference.py index bdf39d60f4..0b75a69b6a 100644 --- a/pymc3/tests/test_variational_inference.py +++ b/pymc3/tests/test_variational_inference.py @@ -5,7 +5,7 @@ from theano.sandbox.rng_mrg import MRG_RandomStreams import pymc3 as pm from pymc3 import Model, Normal -from pymc3.variational.approximations import Advi +from pymc3.variational.approximations import ADVI from pymc3.variational.inference import approximate from ..theanof import set_tt_rng from . import models @@ -18,7 +18,7 @@ class Base(unittest.TestCase): NITER = 30000 def test_elbo(self): - if self.approx is not Advi: + if self.approx is not ADVI: raise unittest.SkipTest mu0 = 1.5 sigma = 1.0 @@ -106,7 +106,7 @@ def test_advi_optimizer(self): class TestMeanField(TestApproximates.Base): - approx = Advi + approx = ADVI if __name__ == '__main__': unittest.main() diff --git a/pymc3/variational/approximations.py b/pymc3/variational/approximations.py index efcb45f4c8..f28ef61d0b 100644 --- a/pymc3/variational/approximations.py +++ b/pymc3/variational/approximations.py @@ -17,16 +17,37 @@ class BaseApproximation(object): - """Base class for variational methods - It uses the idea that we can map standard normal distribution - to the approximate posterior distribution. Thus there are three blank - places in the implementation: + """ + Base class for variational methods + + It uses the idea that we can map initial standard normal + distribution to the approximate posterior distribution. + + Three methods are required for implementation: 1) creating shared parameters `create_shared_params()` 2) mapping initial distribution to posterior `posterior{_{global|local}}(initial)` 3) calculating log_q_W for approximation `log_q_W{_{global|local}}(posterior)` Then ELBO can be calculated for given approximation - log_p_D(posterior) - KL_q_p_W(posterior) + `log_p_D(posterior) - KL_q_p_W(posterior)` + + Parameters + ---------- + population : dict[Variable->int] + maps observed_RV to its population size + if not provided defaults to full population + Note: population size is `shape[0]` of the whole data + known : dict[Variable->(mu, rho)] + maps local random variable to mu and rho for posterior parametrization + it is used for Autoencoding Variational Bayes + (AEVB; Kingma and Welling, 2014)[1]_ + model : Model + PyMC3 model which posterior is going to be approximated + + References + ---------- + .. [1] Kingma, D. P., & Welling, M. (2014). + Auto-Encoding Variational Bayes. stat, 1050, 1. """ def __init__(self, population=None, known=None, model=None): model = modelcontext(model) @@ -64,7 +85,8 @@ def params(self): @staticmethod def check_model(model): - """Checks that model is valid for variational inference + """ + Checks that model is valid for variational inference """ vars_ = [var for var in model.vars if not isinstance(var, pm.model.ObservedRV)] if any([var.dtype in pm.discrete_types for var in vars_]): @@ -72,12 +94,14 @@ def check_model(model): @property def input(self): - """Shortcut to flattened input + """ + Shortcut to flattened input """ return self.flat_view.input def create_shared_params(self): - """Any stuff you need will be here + """ + Any stuff you need will be here Returns ------- @@ -85,8 +109,10 @@ def create_shared_params(self): """ raise NotImplementedError - def initial(self, samples, subset, zeros=False): + def initial(self, samples, subset='all', zeros=False): """ + Initial distribution for constructing posterior + Parameters ---------- samples : int - number of samples @@ -115,7 +141,8 @@ def initial(self, samples, subset, zeros=False): return space def posterior(self, samples=1, zeros=False): - """Transforms initial latent space to posterior distribution + """ + Transforms initial latent space to posterior distribution Parameters ---------- @@ -141,6 +168,8 @@ def posterior(self, samples=1, zeros=False): def sample_over_space(self, space, node): """ + Take samples of node using `space` as distribution of random variables + Parameters ---------- space : space to sample over @@ -157,6 +186,8 @@ def replace_node(post): def view_from(self, space, name, subset='all', reshape=True): """ + Construct view on a variable from flattened `space` + Parameters ---------- space : space to take view of variable from @@ -165,7 +196,7 @@ def view_from(self, space, name, subset='all', reshape=True): subset : str determines what space is used can be {all|local|global} reshape : bool - whether to reshape variable form vectorized view + whether to reshape variable from vectorized view Returns ------- variable @@ -185,7 +216,8 @@ def view_from(self, space, name, subset='all', reshape=True): return view.astype(dtype) def posterior_global(self, initial): - """Implements posterior distribution from initial latent space + """ + Implements posterior distribution from initial latent space Parameters ---------- @@ -198,7 +230,8 @@ def posterior_global(self, initial): raise NotImplementedError def posterior_local(self, initial): - """Implements posterior distribution from initial latent space + """ + Implements posterior distribution from initial latent space Parameters ---------- @@ -225,12 +258,14 @@ def _local_mu_rho(self): return mu, rho def to_flat_input(self, node): - """Replaces vars with flattened view stored in self.input + """ + Replaces vars with flattened view stored in self.input """ return theano.clone(node, self.flat_view.replacements, strict=False) def log_q_W_local(self, posterior): - """log_q_W samples over q for local vars + """ + log_q_W samples over q for local vars Gradient wrt mu, rho in density parametrization is set to zero to lower variance of ELBO @@ -248,17 +283,20 @@ def log_q_W_local(self, posterior): return samples def log_q_W_global(self, posterior): - """log_q_W samples over q for global vars + """ + log_q_W samples over q for global vars """ raise NotImplementedError def log_q_W(self, posterior): - """log_q_W samples over q + """ + log_q_W samples over q """ return self.log_q_W_global(posterior) + self.log_q_W_local(posterior) def log_p_D(self, posterior): - """log_p_D samples over q + """ + log_p_D samples over q """ _log_p_D_ = tt.sum( list(map(self.weighted_logp, self.model.observed_RVs)) @@ -268,7 +306,18 @@ def log_p_D(self, posterior): return samples def weighted_logp(self, var, logp=None): - """Weight logp according to given population size + """ + Weight logp according to given population size + + Parameters + ---------- + var : Random Variable + logp : None or given density for variable + + Returns + ------- + Tensor + weighted logp """ tot = self.population.get(var) if logp is None: @@ -279,11 +328,15 @@ def weighted_logp(self, var, logp=None): return logp def KL_q_p_W(self, posterior): - """KL(q||p) samples over q + """ + KL(q||p) samples over q """ return self.log_q_W(posterior) - self.log_p_W(posterior) def log_p_W_local(self, posterior): + """ + log_p_W_local samples over q + """ if not self.local_vars: return 0 _log_p_W_local_ = tt.sum( @@ -294,7 +347,8 @@ def log_p_W_local(self, posterior): return samples def log_p_W_global(self, posterior): - """log_p_W samples over q + """ + log_p_W_global samples over q """ def logp(var): return var.logpt @@ -306,6 +360,9 @@ def logp(var): return samples def log_p_W(self, posterior): + """ + log_p_W samples over q + """ def logp(var): return var.logpt if self.local_vars: @@ -323,15 +380,20 @@ def logp(var): return samples def apply_replacements(self, node, deterministic=False, include=None, exclude=None): - """Replace variables in graph with variational approximation. By default, replaces all variables + """ + Replace variables in graph with variational approximation. By default, replaces all variables Parameters ---------- - node : node for replacements - deterministic : whether to use zeros as initial distribution + node : Variable + node for replacements + deterministic : bool + whether to use zeros as initial distribution if True - zero initial point will produce constant latent variables - include : list - latent variables to be replaced - exclude : list - latent variables to be excluded for replacements + include : list + latent variables to be replaced + exclude : list + latent variables to be excluded for replacements Returns ------- @@ -352,13 +414,20 @@ def apply_replacements(self, node, deterministic=False, include=None, exclude=No return theano.clone(node, {self.input: posterior}) def elbo(self, samples=1, pi_local=1, pi_global=1): - """Output of this function should be used for fitting a model + """ + Evidence Lower Bound - ELBO + + To fit variational posterior we need to maximize ELBO + wrt parameters Parameters ---------- - samples : Tensor - number of samples - pi_local : Tensor - weight of local variational part - pi_global : Tensor - weight of global variational part + samples : Tensor + number of samples + pi_local : Tensor + weight of local variational part + pi_global : Tensor + weight of global variational part Returns ------- @@ -467,7 +536,7 @@ def global_slc(self): return slice(self.local_size, self.total_size) -class Advi(BaseApproximation): +class ADVI(BaseApproximation): """ADVI algorithm as discribed in Kucukelbir[1]_ with variance reduction [3]_. ADVI also supports Auto-Encoding Variational Bayes described in [2]_ and minibatch training. @@ -516,10 +585,12 @@ def posterior_global(self, initial): return sd * initial + mu def log_q_W_global(self, posterior): - """log_q_W samples over q for global vars + """ + log_q_W samples over q for global vars Gradient wrt mu, rho in density parametrization - is set to zero to lower variance of ELBO""" + is set to zero to lower variance of ELBO + """ mu = self.shared_params['mu'] rho = self.shared_params['rho'] samples = tt.sum(log_normal3(posterior[:, self.global_slc], Z(mu), Z(rho)), axis=1) diff --git a/pymc3/variational/inference.py b/pymc3/variational/inference.py index 9827e29fbe..48bbb8b41c 100644 --- a/pymc3/variational/inference.py +++ b/pymc3/variational/inference.py @@ -1,13 +1,13 @@ import numpy as np import theano import pymc3 as pm -from .approximations import Advi, BaseApproximation +from .approximations import ADVI, BaseApproximation from .advi import adagrad_optimizer from tqdm import trange APPROXIMATIONS = { - 'advi': Advi, + 'advi': ADVI, } @@ -17,7 +17,8 @@ def approximate(n=10000, population=None, local_vars=None, callbacks=None, learning_rate=.001, epsilon=.1, model=None, more_params=None, more_updates=None, *args, **kwargs): - """Interface for efficient variational inference with gradient + """ + Interface for efficient variational inference with gradient variance reduction as described in [4]_ @@ -143,4 +144,4 @@ def approximate(n=10000, population=None, local_vars=None, else: avg_elbo = elbos[-n // 10:].mean() pm._log.info('Finished [100%]: Average ELBO = {:,.5g}'.format(avg_elbo)) - return approx, elbos \ No newline at end of file + return approx, elbos From d94e7e752c302ac9e1e310bd2a9442b5b593643d Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Tue, 3 Jan 2017 18:48:50 +0300 Subject: [PATCH 66/83] refactored dist math --- pymc3/distributions/dist_math.py | 76 +++++++++++++---------------- pymc3/variational/approximations.py | 6 +-- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/pymc3/distributions/dist_math.py b/pymc3/distributions/dist_math.py index f0bccce68c..7fccbc15fc 100644 --- a/pymc3/distributions/dist_math.py +++ b/pymc3/distributions/dist_math.py @@ -97,56 +97,46 @@ def rho2sd(rho): return tt.log1p(tt.exp(rho)) -def log_normal(x, mean, std, eps=0.0): +def log_normal(x, mean, **kwargs): """ Calculate logarithm of normal distribution at point `x` with given `mean` and `std` + Parameters + ---------- + x : Tensor + point of evaluation + mean : Tensor + mean of normal distribution + kwargs : one of parameters `{sd, tau, w, rho}` + Notes ----- - There are three variants for density evaluation function. - They use: - 1) standard normal distribution - `std` (:code:`log_normal`) - 2) `w`, logarithm of `std` :math:`w = log(std)` (:code:`log_normal2`) - 3) `rho` that follows this equation :math:`rho = log(exp(std) - 1)` (:code:`log_normal3`) + There are four variants for density parametrization. + They are: + 1) standard deviation - `std` + 2) `w`, logarithm of `std` :math:`w = log(std)` + 3) `rho` that follows this equation :math:`rho = log(exp(std) - 1)` + 4) `tau` that follows this equation :math:`tau = std^{-1}` ---- """ + sd = kwargs.get('sd') + w = kwargs.get('w') + rho = kwargs.get('rho') + tau = kwargs.get('tau') + eps = kwargs.get('eps', 0.0) + check = sum(map(lambda a: a is not None, [sd, w, rho, tau])) + if check > 1: + raise ValueError('more than one required kwarg is passed') + if check == 0: + raise ValueError('none of required kwarg is passed') + if sd is not None: + std = sd + elif w is not None: + std = tt.exp(w) + elif rho is not None: + std = rho2sd(rho) + else: + std = tau**(-1) std += eps return c - tt.log(tt.abs_(std)) - (x - mean) ** 2 / (2 * std ** 2) - - -def log_normal2(x, mean, w, eps=0.0): - """ - Calculate logarithm of normal distribution at point `x` - with given `mean` and `w` - - Notes - ----- - There are three variants for density evaluation function. - They use: - 1) standard normal distribution - `std` (:code:`log_normal`) - 2) `w`, logarithm of `std` :math:`w = log(std)` (:code:`log_normal2`) - 3) `rho` that follows this equation :math:`rho = log(exp(std) - 1)` (:code:`log_normal3`) - ---- - """ - std = tt.exp(w) - return log_normal(x, mean, std, eps) - - -def log_normal3(x, mean, rho, eps=0.0): - """ - Calculate logarithm of normal distribution at point `x` - with given `mean` and `rho` - - Notes - ----- - There are three variants for density evaluation function. - They use: - 1) standard normal distribution - `std` (:code:`log_normal`) - 2) `w`, logarithm of `std` :math:`w = log(std)` (:code:`log_normal2`) - 3) `rho` that follows this equation :math:`rho = log(exp(std) - 1)` (:code:`log_normal3`) - ---- - """ - std = rho2sd(rho) - return log_normal(x, mean, std, eps) - diff --git a/pymc3/variational/approximations.py b/pymc3/variational/approximations.py index f28ef61d0b..42caf4bd72 100644 --- a/pymc3/variational/approximations.py +++ b/pymc3/variational/approximations.py @@ -5,7 +5,7 @@ import pymc3 as pm from ..theanof import tt_rng, memoize, change_flags from ..blocking import ArrayOrdering -from ..distributions.dist_math import rho2sd, log_normal3 +from ..distributions.dist_math import rho2sd, log_normal from ..math import flatten_list from ..model import modelcontext import numpy as np @@ -277,7 +277,7 @@ def log_q_W_local(self, posterior): mu = self.known[var][0].ravel() rho = self.known[var][1].ravel() x = self.view_from(posterior, var.name, 'all', reshape=False) - q = log_normal3(x, Z(mu), Z(rho)) + q = log_normal(x, Z(mu), rho=Z(rho)) logp.append(self.weighted_logp(var, q)) samples = tt.sum(tt.concatenate(logp, axis=1), axis=1) return samples @@ -593,5 +593,5 @@ def log_q_W_global(self, posterior): """ mu = self.shared_params['mu'] rho = self.shared_params['rho'] - samples = tt.sum(log_normal3(posterior[:, self.global_slc], Z(mu), Z(rho)), axis=1) + samples = tt.sum(log_normal(posterior[:, self.global_slc], Z(mu), rho=Z(rho)), axis=1) return samples From 8d1f088ac6d995eac5de8adefa5bd0bf7a76fc24 Mon Sep 17 00:00:00 2001 From: Chris Fonnesbeck Date: Thu, 17 Nov 2016 13:43:51 -0500 Subject: [PATCH 67/83] Added mode argument to several step methods and advi to allow mode setting (e.g. nanguardmode) for Theano functions --- pymc3/step_methods/metropolis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/step_methods/metropolis.py b/pymc3/step_methods/metropolis.py index c2ab7260ca..4fcbdc7866 100644 --- a/pymc3/step_methods/metropolis.py +++ b/pymc3/step_methods/metropolis.py @@ -433,6 +433,6 @@ def delta_logp(logp, vars, shared): logp1 = pm.CallableTensor(logp0)(inarray1) - f = theano.function([inarray1, inarray0], logp1 - logp0) + f = theano.function([inarray1, inarray0], logp1 - logp0, mode=self.mode) f.trust_input = True return f From 37843af0de8998e27f47846df2591fc68d568fcf Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 19:21:20 +0300 Subject: [PATCH 68/83] Created Generator Op with simple Test --- pymc3/data.py | 34 +++++++++++++++++++++++++++++++++- pymc3/tests/test_theanof.py | 18 ++++++++++++++++++ pymc3/theanof.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 pymc3/tests/test_theanof.py diff --git a/pymc3/data.py b/pymc3/data.py index 944ce55458..bd0a6e5735 100644 --- a/pymc3/data.py +++ b/pymc3/data.py @@ -1,7 +1,10 @@ +import itertools import pkgutil import io -__all__ = ['get_data_file'] +import theano.tensor as tt + +__all__ = ['get_data_file', 'DataGenerator'] def get_data_file(pkg, path): @@ -19,3 +22,32 @@ def get_data_file(pkg, path): """ return io.BytesIO(pkgutil.get_data(pkg, path)) + + +class DataGenerator(object): + """ + Helper class that helps to infer data type of generator with looking + at the first item, preserving the order of the resulting generator + """ + def __init__(self, iterable): + if hasattr(iterable, '__len__'): + generator = itertools.cycle(iterable) + else: + generator = iter(iterable) + self.test_value = next(generator) + self.gen = itertools.chain([self.test_value], generator) + self.tensortype = tt.TensorType( + self.test_value.dtype, + ((False, ) * self.test_value.ndim)) + + def __next__(self): + return next(self.gen) + + def __iter__(self): + return self + + def __eq__(self, other): + return id(self) == id(other) + + def __hash__(self): + return hash(id(self)) diff --git a/pymc3/tests/test_theanof.py b/pymc3/tests/test_theanof.py new file mode 100644 index 0000000000..c7fa50ab3e --- /dev/null +++ b/pymc3/tests/test_theanof.py @@ -0,0 +1,18 @@ +import unittest +import numpy as np +import theano +from ..theanof import DataGenerator, GeneratorOp + + +class TestGenerator(unittest.TestCase): + def test_basic(self): + def integers(): + i = 0 + while True: + yield np.float32(i) + i += 1 + generator = DataGenerator(integers()) + gop = GeneratorOp(generator)() + f = theano.function([], gop) + self.assertEqual(f(), np.float32(0)) + self.assertEqual(f(), np.float32(1)) diff --git a/pymc3/theanof.py b/pymc3/theanof.py index 56bad3fb0e..8e8d4c6af8 100644 --- a/pymc3/theanof.py +++ b/pymc3/theanof.py @@ -3,8 +3,12 @@ from .vartypes import typefilter, continuous_types from theano import theano, scalar, tensor as tt from theano.gof.graph import inputs +from theano.tensor import TensorVariable +from theano.gof import Op, Apply +from theano.configparser import change_flags from .memoize import memoize from .blocking import ArrayOrdering +from .data import DataGenerator __all__ = ['gradient', 'hessian', 'hessian_diag', 'inputvars', 'cont_inputs', 'floatX', 'jacobian', @@ -242,3 +246,31 @@ def __call__(self, input): scalar_identity = IdentityOp(scalar.upgrade_to_float, name='scalar_identity') identity = tt.Elemwise(scalar_identity, name='identity') + + +class GeneratorOp(Op): + __props__ = ('generator',) + + def __init__(self, generator): + if not isinstance(generator, DataGenerator): + raise ValueError('pymc3 requires special DataGenerator for consistency, ' + 'wrap your generator with it') + super(GeneratorOp, self).__init__() + self.generator = generator + self.itypes = [] + self.otypes = [self.generator.tensortype] + + def perform(self, node, inputs, output_storage, params=None): + output_storage[0][0] = self.generator.__next__() + + def do_constant_folding(self, node): + return False + + @change_flags(compute_test_value='off') + def __call__(self, *args, **kwargs): + rval = super(GeneratorOp, self).__call__(*args, **kwargs) + rval.tag.test_value = self.generator.test_value + return rval + + + From 3dc6f1bcbc59d6f75aabadf1adc6a7916346a736 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 19:37:25 +0300 Subject: [PATCH 69/83] added ndim test --- pymc3/tests/test_theanof.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pymc3/tests/test_theanof.py b/pymc3/tests/test_theanof.py index c7fa50ab3e..31a66a943c 100644 --- a/pymc3/tests/test_theanof.py +++ b/pymc3/tests/test_theanof.py @@ -1,3 +1,4 @@ +import itertools import unittest import numpy as np import theano @@ -16,3 +17,18 @@ def integers(): f = theano.function([], gop) self.assertEqual(f(), np.float32(0)) self.assertEqual(f(), np.float32(1)) + + def test_ndim(self): + for ndim in range(10): + def integers(): + i = 0 + while True: + yield np.ones((2,) * ndim) * i + i += 1 + res = list(itertools.islice(integers(), 0, 2)) + generator = DataGenerator(integers()) + gop = GeneratorOp(generator)() + f = theano.function([], gop) + self.assertEqual(ndim, res[0].ndim) + np.testing.assert_equal(f(), res[0]) + np.testing.assert_equal(f(), res[1]) From a16512e56a04d6be42cffa2460102cd561416752 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 19:39:13 +0300 Subject: [PATCH 70/83] updated test --- pymc3/tests/test_theanof.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pymc3/tests/test_theanof.py b/pymc3/tests/test_theanof.py index 31a66a943c..758b5a3173 100644 --- a/pymc3/tests/test_theanof.py +++ b/pymc3/tests/test_theanof.py @@ -17,6 +17,9 @@ def integers(): f = theano.function([], gop) self.assertEqual(f(), np.float32(0)) self.assertEqual(f(), np.float32(1)) + for i in range(2, 100): + f() + self.assertEqual(f(), np.float32(100)) def test_ndim(self): for ndim in range(10): From 7127c23d446144051b87732860b0dee71c919ee2 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 19:43:11 +0300 Subject: [PATCH 71/83] updated test, added test value check --- pymc3/tests/test_theanof.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pymc3/tests/test_theanof.py b/pymc3/tests/test_theanof.py index 758b5a3173..86c32416a7 100644 --- a/pymc3/tests/test_theanof.py +++ b/pymc3/tests/test_theanof.py @@ -14,6 +14,7 @@ def integers(): i += 1 generator = DataGenerator(integers()) gop = GeneratorOp(generator)() + self.assertEqual(gop.tag.test_value, np.float32(0)) f = theano.function([], gop) self.assertEqual(f(), np.float32(0)) self.assertEqual(f(), np.float32(1)) From 23b14ff735d45fdeb4f0b206fd100e66ec62bc72 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 19:49:26 +0300 Subject: [PATCH 72/83] added test for replacing generator with shared variable --- pymc3/tests/test_theanof.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/pymc3/tests/test_theanof.py b/pymc3/tests/test_theanof.py index 86c32416a7..7907b98da6 100644 --- a/pymc3/tests/test_theanof.py +++ b/pymc3/tests/test_theanof.py @@ -5,13 +5,22 @@ from ..theanof import DataGenerator, GeneratorOp +def integers(): + i = 0 + while True: + yield np.float32(i) + i += 1 + + +def integers_ndim(ndim): + i = 0 + while True: + yield np.ones((2,) * ndim) * i + i += 1 + + class TestGenerator(unittest.TestCase): def test_basic(self): - def integers(): - i = 0 - while True: - yield np.float32(i) - i += 1 generator = DataGenerator(integers()) gop = GeneratorOp(generator)() self.assertEqual(gop.tag.test_value, np.float32(0)) @@ -24,15 +33,19 @@ def integers(): def test_ndim(self): for ndim in range(10): - def integers(): - i = 0 - while True: - yield np.ones((2,) * ndim) * i - i += 1 - res = list(itertools.islice(integers(), 0, 2)) - generator = DataGenerator(integers()) + res = list(itertools.islice(integers_ndim(ndim), 0, 2)) + generator = DataGenerator(integers_ndim(ndim)) gop = GeneratorOp(generator)() f = theano.function([], gop) self.assertEqual(ndim, res[0].ndim) np.testing.assert_equal(f(), res[0]) np.testing.assert_equal(f(), res[1]) + + def test_cloning_available(self): + generator = DataGenerator(integers()) + gop = GeneratorOp(generator)() + res = gop ** 2 + shared = theano.shared(np.float32(10)) + res1 = theano.clone(res, {gop: shared}) + f = theano.function([], res1) + self.assertEqual(f(), np.float32(100)) From 96cd5bbdb9efb9c29580bf5197805976f33f76ed Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 20:01:17 +0300 Subject: [PATCH 73/83] added shortcut for generator op --- pymc3/theanof.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pymc3/theanof.py b/pymc3/theanof.py index 8e8d4c6af8..666d66220c 100644 --- a/pymc3/theanof.py +++ b/pymc3/theanof.py @@ -4,7 +4,7 @@ from theano import theano, scalar, tensor as tt from theano.gof.graph import inputs from theano.tensor import TensorVariable -from theano.gof import Op, Apply +from theano.gof import Op from theano.configparser import change_flags from .memoize import memoize from .blocking import ArrayOrdering @@ -13,7 +13,7 @@ __all__ = ['gradient', 'hessian', 'hessian_diag', 'inputvars', 'cont_inputs', 'floatX', 'jacobian', 'CallableTensor', 'join_nonshared_inputs', - 'make_shared_replacements'] + 'make_shared_replacements', 'generator'] def inputvars(a): @@ -251,17 +251,19 @@ def __call__(self, input): class GeneratorOp(Op): __props__ = ('generator',) - def __init__(self, generator): - if not isinstance(generator, DataGenerator): - raise ValueError('pymc3 requires special DataGenerator for consistency, ' - 'wrap your generator with it') + def __init__(self, gen): + if not isinstance(gen, DataGenerator): + gen = DataGenerator(gen) super(GeneratorOp, self).__init__() - self.generator = generator + self.generator = gen self.itypes = [] self.otypes = [self.generator.tensortype] def perform(self, node, inputs, output_storage, params=None): - output_storage[0][0] = self.generator.__next__() + try: + output_storage[0][0] = self.generator.__next__() + except StopIteration: + output_storage[0][0] = np.nan def do_constant_folding(self, node): return False @@ -273,4 +275,5 @@ def __call__(self, *args, **kwargs): return rval - +def generator(gen): + return GeneratorOp(gen)() From 633e4e9369566f8cb0d47e54898bcd11ad38c601 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 20:07:49 +0300 Subject: [PATCH 74/83] refactored test --- pymc3/tests/test_theanof.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pymc3/tests/test_theanof.py b/pymc3/tests/test_theanof.py index 7907b98da6..ebc7308781 100644 --- a/pymc3/tests/test_theanof.py +++ b/pymc3/tests/test_theanof.py @@ -2,7 +2,7 @@ import unittest import numpy as np import theano -from ..theanof import DataGenerator, GeneratorOp +from ..theanof import DataGenerator, GeneratorOp, generator def integers(): @@ -42,8 +42,7 @@ def test_ndim(self): np.testing.assert_equal(f(), res[1]) def test_cloning_available(self): - generator = DataGenerator(integers()) - gop = GeneratorOp(generator)() + gop = generator(integers()) res = gop ** 2 shared = theano.shared(np.float32(10)) res1 = theano.clone(res, {gop: shared}) From 0629adc03403dcdbef29a12c6f7ec7b4c70c112d Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 20:27:55 +0300 Subject: [PATCH 75/83] added population kwarg (no tests yet) --- pymc3/data.py | 6 +----- pymc3/distributions/distribution.py | 3 ++- pymc3/model.py | 29 +++++++++++++++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/pymc3/data.py b/pymc3/data.py index bd0a6e5735..fcac737719 100644 --- a/pymc3/data.py +++ b/pymc3/data.py @@ -29,11 +29,7 @@ class DataGenerator(object): Helper class that helps to infer data type of generator with looking at the first item, preserving the order of the resulting generator """ - def __init__(self, iterable): - if hasattr(iterable, '__len__'): - generator = itertools.cycle(iterable) - else: - generator = iter(iterable) + def __init__(self, generator): self.test_value = next(generator) self.gen = itertools.chain([self.test_value], generator) self.tensortype = tt.TensorType( diff --git a/pymc3/distributions/distribution.py b/pymc3/distributions/distribution.py index 2ad2243f74..d6ab06d683 100644 --- a/pymc3/distributions/distribution.py +++ b/pymc3/distributions/distribution.py @@ -30,8 +30,9 @@ def __new__(cls, name, *args, **kwargs): if isinstance(name, string_types): data = kwargs.pop('observed', None) + population = kwargs.pop('population', None) dist = cls.dist(*args, **kwargs) - return model.Var(name, dist, data) + return model.Var(name, dist, data, population) else: raise TypeError("Name needs to be a string but got: %s" % name) diff --git a/pymc3/model.py b/pymc3/model.py index 6017484d06..7c34f6047e 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -8,7 +8,7 @@ import pymc3 as pm from .memoize import memoize -from .theanof import gradient, hessian, inputvars +from .theanof import gradient, hessian, inputvars, generator from .vartypes import typefilter, discrete_types, continuous_types from .blocking import DictToArrayBijection, ArrayOrdering @@ -458,7 +458,7 @@ def cont_vars(self): """All the continuous variables in the model""" return list(typefilter(self.vars, continuous_types)) - def Var(self, name, dist, data=None): + def Var(self, name, dist, data=None, population=None): """Create and add (un)observed random variable to the model with an appropriate prior distribution. @@ -491,7 +491,7 @@ def Var(self, name, dist, data=None): return var elif isinstance(data, dict): var = MultiObservedRV(name=name, data=data, distribution=dist, - model=self) + model=self, population=population) self.observed_RVs.append(var) if var.missing_values: self.free_RVs += var.missing_values @@ -500,7 +500,8 @@ def Var(self, name, dist, data=None): self.named_vars[v.name] = v else: var = ObservedRV(name=name, data=data, - distribution=dist, model=self) + distribution=dist, model=self, + population=population) self.observed_RVs.append(var) if var.missing_values: self.free_RVs.append(var.missing_values) @@ -780,6 +781,8 @@ def as_tensor(data, name, model, distribution): constant[data.mask.nonzero()], missing_values) dataTensor.missing_values = missing_values return dataTensor + elif hasattr(data, '__next__'): + return generator(data) else: data = tt.as_tensor_variable(data, name=name) data.missing_values = None @@ -792,7 +795,7 @@ class ObservedRV(Factor, TensorVariable): """ def __init__(self, type=None, owner=None, index=None, name=None, data=None, - distribution=None, model=None): + distribution=None, model=None, population=None): """ Parameters ---------- @@ -814,7 +817,12 @@ def __init__(self, type=None, owner=None, index=None, name=None, data=None, data = as_tensor(data, name, model, distribution) self.missing_values = data.missing_values - self.logp_elemwiset = distribution.logp(data) + logp_elemwiset = distribution.logp(data) + if population is None: + coef = tt.as_tensor(1) + else: + coef = tt.as_tensor(population) / logp_elemwiset.shape[0] + self.logp_elemwiset = logp_elemwiset * coef self.model = model self.distribution = distribution @@ -835,7 +843,7 @@ class MultiObservedRV(Factor): Potentially partially observed. """ - def __init__(self, name, data, distribution, model): + def __init__(self, name, data, distribution, model, population=None): """ Parameters ---------- @@ -851,7 +859,12 @@ def __init__(self, name, data, distribution, model): self.missing_values = [datum.missing_values for datum in self.data.values() if datum.missing_values is not None] - self.logp_elemwiset = distribution.logp(**self.data) + logp_elemwiset = distribution.logp(**self.data) + if population is None: + coef = tt.as_tensor(1) + else: + coef = tt.as_tensor(population) / logp_elemwiset.shape[0] + self.logp_elemwiset = logp_elemwiset * coef self.model = model self.distribution = distribution From 06099a205f823bb1e84f4ddd9e1cc4664c92dcac Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 11 Jan 2017 21:20:23 +0300 Subject: [PATCH 76/83] added population kwarg for free var(autoencoder case) --- pymc3/model.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/pymc3/model.py b/pymc3/model.py index 7c34f6047e..c437c55e75 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -477,11 +477,13 @@ def Var(self, name, dist, data=None, population=None): name = self.name_for(name) if data is None: if getattr(dist, "transform", None) is None: - var = FreeRV(name=name, distribution=dist, model=self) + var = FreeRV(name=name, distribution=dist, model=self, + population=population) self.free_RVs.append(var) else: var = TransformedRV(name=name, distribution=dist, model=self, - transform=dist.transform) + transform=dist.transform, + population=population) pm._log.debug('Applied {transform}-transform to {name}' ' and added transformed {orig_name} to model.'.format( transform=dist.transform.name, @@ -718,7 +720,7 @@ class FreeRV(Factor, TensorVariable): """Unobserved random variable that a model is specified in terms of.""" def __init__(self, type=None, owner=None, index=None, name=None, - distribution=None, model=None): + distribution=None, model=None, population=None): """ Parameters ---------- @@ -737,7 +739,12 @@ def __init__(self, type=None, owner=None, index=None, name=None, self.distribution = distribution self.tag.test_value = np.ones( distribution.shape, distribution.dtype) * distribution.default() - self.logp_elemwiset = distribution.logp(self) + logp_elemwiset = distribution.logp(self) + if population is None: + coef = tt.as_tensor(1) + else: + coef = tt.as_tensor(population) / logp_elemwiset.shape[0] + self.logp_elemwiset = logp_elemwiset * coef self.model = model incorporate_methods(source=distribution, destination=self, @@ -909,7 +916,8 @@ def Potential(name, var, model=None): class TransformedRV(TensorVariable): def __init__(self, type=None, owner=None, index=None, name=None, - distribution=None, model=None, transform=None): + distribution=None, model=None, transform=None, + population=None): """ Parameters ---------- @@ -929,7 +937,7 @@ def __init__(self, type=None, owner=None, index=None, name=None, transformed_name = "{}_{}_".format(name, transform.name) self.transformed = model.Var( - transformed_name, transform.apply(distribution)) + transformed_name, transform.apply(distribution), population=population) normalRV = transform.backward(self.transformed) From 75a48495178c6a01c3fe27982e2eb535a0fdef9f Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Thu, 12 Jan 2017 13:16:28 +0300 Subject: [PATCH 77/83] Revert "Added mode argument to several step methods and advi to allow mode setting (e.g. nanguardmode) for Theano functions" This reverts commit 6bdb53a069c6d569fadcbc36a93489c0ddb334a3. --- pymc3/step_methods/metropolis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymc3/step_methods/metropolis.py b/pymc3/step_methods/metropolis.py index 4fcbdc7866..c2ab7260ca 100644 --- a/pymc3/step_methods/metropolis.py +++ b/pymc3/step_methods/metropolis.py @@ -433,6 +433,6 @@ def delta_logp(logp, vars, shared): logp1 = pm.CallableTensor(logp0)(inarray1) - f = theano.function([inarray1, inarray0], logp1 - logp0, mode=self.mode) + f = theano.function([inarray1, inarray0], logp1 - logp0) f.trust_input = True return f From ff325d8970fea1306ade442c85e688a9f5a4df93 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sat, 14 Jan 2017 13:25:48 +0300 Subject: [PATCH 78/83] add docstring to generator Op --- pymc3/theanof.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pymc3/theanof.py b/pymc3/theanof.py index 666d66220c..eeddacf5ce 100644 --- a/pymc3/theanof.py +++ b/pymc3/theanof.py @@ -249,6 +249,17 @@ def __call__(self, input): class GeneratorOp(Op): + """ + Generaror Op is designed for storing python generators + inside theano graph. The main limitation is generator itself. + + There are some important cases when generator becomes exhausted + - not endless generator is passed + - exception is raised while `generator.__next__` is performed + Note: it is dangerous in simple python generators, but ok in + custom class based generators with explicit state + - data type on each iteration should be the same + """ __props__ = ('generator',) def __init__(self, gen): @@ -276,4 +287,5 @@ def __call__(self, *args, **kwargs): def generator(gen): + """shortcut for `GeneratorOp`""" return GeneratorOp(gen)() From 79ac934df3c9355824ea8455076323131df3eb12 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sat, 14 Jan 2017 13:27:54 +0300 Subject: [PATCH 79/83] rename population -> total_size --- pymc3/distributions/distribution.py | 4 ++-- pymc3/model.py | 32 ++++++++++++++--------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/pymc3/distributions/distribution.py b/pymc3/distributions/distribution.py index d6ab06d683..cae9740740 100644 --- a/pymc3/distributions/distribution.py +++ b/pymc3/distributions/distribution.py @@ -30,9 +30,9 @@ def __new__(cls, name, *args, **kwargs): if isinstance(name, string_types): data = kwargs.pop('observed', None) - population = kwargs.pop('population', None) + total_size = kwargs.pop('total_size', None) dist = cls.dist(*args, **kwargs) - return model.Var(name, dist, data, population) + return model.Var(name, dist, data, total_size) else: raise TypeError("Name needs to be a string but got: %s" % name) diff --git a/pymc3/model.py b/pymc3/model.py index c437c55e75..46ce029b61 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -458,7 +458,7 @@ def cont_vars(self): """All the continuous variables in the model""" return list(typefilter(self.vars, continuous_types)) - def Var(self, name, dist, data=None, population=None): + def Var(self, name, dist, data=None, total_size=None): """Create and add (un)observed random variable to the model with an appropriate prior distribution. @@ -478,12 +478,12 @@ def Var(self, name, dist, data=None, population=None): if data is None: if getattr(dist, "transform", None) is None: var = FreeRV(name=name, distribution=dist, model=self, - population=population) + total_size=total_size) self.free_RVs.append(var) else: var = TransformedRV(name=name, distribution=dist, model=self, transform=dist.transform, - population=population) + total_size=total_size) pm._log.debug('Applied {transform}-transform to {name}' ' and added transformed {orig_name} to model.'.format( transform=dist.transform.name, @@ -493,7 +493,7 @@ def Var(self, name, dist, data=None, population=None): return var elif isinstance(data, dict): var = MultiObservedRV(name=name, data=data, distribution=dist, - model=self, population=population) + model=self, total_size=total_size) self.observed_RVs.append(var) if var.missing_values: self.free_RVs += var.missing_values @@ -503,7 +503,7 @@ def Var(self, name, dist, data=None, population=None): else: var = ObservedRV(name=name, data=data, distribution=dist, model=self, - population=population) + total_size=total_size) self.observed_RVs.append(var) if var.missing_values: self.free_RVs.append(var.missing_values) @@ -720,7 +720,7 @@ class FreeRV(Factor, TensorVariable): """Unobserved random variable that a model is specified in terms of.""" def __init__(self, type=None, owner=None, index=None, name=None, - distribution=None, model=None, population=None): + distribution=None, model=None, total_size=None): """ Parameters ---------- @@ -740,10 +740,10 @@ def __init__(self, type=None, owner=None, index=None, name=None, self.tag.test_value = np.ones( distribution.shape, distribution.dtype) * distribution.default() logp_elemwiset = distribution.logp(self) - if population is None: + if total_size is None: coef = tt.as_tensor(1) else: - coef = tt.as_tensor(population) / logp_elemwiset.shape[0] + coef = tt.as_tensor(total_size) / logp_elemwiset.shape[0] self.logp_elemwiset = logp_elemwiset * coef self.model = model @@ -802,7 +802,7 @@ class ObservedRV(Factor, TensorVariable): """ def __init__(self, type=None, owner=None, index=None, name=None, data=None, - distribution=None, model=None, population=None): + distribution=None, model=None, total_size=None): """ Parameters ---------- @@ -825,10 +825,10 @@ def __init__(self, type=None, owner=None, index=None, name=None, data=None, self.missing_values = data.missing_values logp_elemwiset = distribution.logp(data) - if population is None: + if total_size is None: coef = tt.as_tensor(1) else: - coef = tt.as_tensor(population) / logp_elemwiset.shape[0] + coef = tt.as_tensor(total_size) / logp_elemwiset.shape[0] self.logp_elemwiset = logp_elemwiset * coef self.model = model self.distribution = distribution @@ -850,7 +850,7 @@ class MultiObservedRV(Factor): Potentially partially observed. """ - def __init__(self, name, data, distribution, model, population=None): + def __init__(self, name, data, distribution, model, total_size=None): """ Parameters ---------- @@ -867,10 +867,10 @@ def __init__(self, name, data, distribution, model, population=None): self.missing_values = [datum.missing_values for datum in self.data.values() if datum.missing_values is not None] logp_elemwiset = distribution.logp(**self.data) - if population is None: + if total_size is None: coef = tt.as_tensor(1) else: - coef = tt.as_tensor(population) / logp_elemwiset.shape[0] + coef = tt.as_tensor(total_size) / logp_elemwiset.shape[0] self.logp_elemwiset = logp_elemwiset * coef self.model = model self.distribution = distribution @@ -917,7 +917,7 @@ class TransformedRV(TensorVariable): def __init__(self, type=None, owner=None, index=None, name=None, distribution=None, model=None, transform=None, - population=None): + total_size=None): """ Parameters ---------- @@ -937,7 +937,7 @@ def __init__(self, type=None, owner=None, index=None, name=None, transformed_name = "{}_{}_".format(name, transform.name) self.transformed = model.Var( - transformed_name, transform.apply(distribution), population=population) + transformed_name, transform.apply(distribution), total_size=total_size) normalRV = transform.backward(self.transformed) From 57dbe47b4c420d11588ebbbb91ee5ac45ecb75f6 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sat, 14 Jan 2017 13:40:53 +0300 Subject: [PATCH 80/83] update docstrings in model --- pymc3/model.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/pymc3/model.py b/pymc3/model.py index 46ce029b61..bdfaaf0c15 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -469,6 +469,8 @@ def Var(self, name, dist, data=None, total_size=None): data : array_like (optional) If data is provided, the variable is observed. If None, the variable is unobserved. + total_size : scalar + upscales logp of variable with :math:`coef = total_size/var.shape[0]` Returns ------- @@ -728,7 +730,10 @@ def __init__(self, type=None, owner=None, index=None, name=None, owner : theano owner (optional) name : str distribution : Distribution - model : Model""" + model : Model + total_size : scalar Tensor (optional) + needed for upscaling logp + """ if type is None: type = distribution.type super(FreeRV, self).__init__(type, owner, index, name) @@ -811,6 +816,8 @@ def __init__(self, type=None, owner=None, index=None, name=None, data=None, name : str distribution : Distribution model : Model + total_size : scalar Tensor (optional) + needed for upscaling logp """ from .distributions import TensorType if type is None: @@ -859,6 +866,8 @@ def __init__(self, name, data, distribution, model, total_size=None): name : str distribution : Distribution model : Model + total_size : scalar Tensor (optional) + needed for upscaling logp """ self.name = name self.data = {name: as_tensor(data, name, model, distribution) @@ -924,10 +933,12 @@ def __init__(self, type=None, owner=None, index=None, name=None, type : theano type (optional) owner : theano owner (optional) - name : str distribution : Distribution - model : Model""" + model : Model + total_size : scalar Tensor (optional) + needed for upscaling logp + """ if type is None: type = distribution.type super(TransformedRV, self).__init__(type, owner, index, name) From f8bce58790050fc757784017cf317d5dcbc562f4 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Sat, 14 Jan 2017 13:41:18 +0300 Subject: [PATCH 81/83] fix typo in `as_tensor` function --- pymc3/model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymc3/model.py b/pymc3/model.py index bdfaaf0c15..56241971fe 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -772,6 +772,8 @@ def pandas_to_array(data): return data elif isinstance(data, theano.gof.graph.Variable): return data + elif hasattr(data, '__next__'): + return generator(data) else: return np.asarray(data) @@ -793,8 +795,6 @@ def as_tensor(data, name, model, distribution): constant[data.mask.nonzero()], missing_values) dataTensor.missing_values = missing_values return dataTensor - elif hasattr(data, '__next__'): - return generator(data) else: data = tt.as_tensor_variable(data, name=name) data.missing_values = None From 8d91fee84989b6d3fc4297b795caacbd3b59bf53 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 18 Jan 2017 01:34:14 +0300 Subject: [PATCH 82/83] add simple test for density scaling via `total_size` --- pymc3/tests/test_model.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pymc3/tests/test_model.py b/pymc3/tests/test_model.py index 4eb96e6789..0b9696a4ae 100644 --- a/pymc3/tests/test_model.py +++ b/pymc3/tests/test_model.py @@ -1,5 +1,5 @@ import unittest -import theano.tensor as tt +from theano import theano, tensor as tt import pymc3 as pm from pymc3.distributions import HalfCauchy, Normal from pymc3 import Potential, Deterministic @@ -118,3 +118,12 @@ def test_model_root(self): self.assertTrue(model is model.root) with pm.Model() as sub: self.assertTrue(model is sub.root) + + def test_density_scaling(self): + with pm.Model() as model1: + Normal('n', observed=[[1]], total_size=1) + p1 = theano.function([], model1.logpt) + with pm.Model() as model2: + Normal('n', observed=[[1]], total_size=2) + p2 = theano.function([], model2.logpt) + self.assertEqual(p1() * 2, p2()) From 1a9fa3de201c22c8a89502844bd245bb31633b67 Mon Sep 17 00:00:00 2001 From: Maxim Kochurov Date: Wed, 18 Jan 2017 02:05:46 +0300 Subject: [PATCH 83/83] raise an error when density scaling is done on scalar --- pymc3/model.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pymc3/model.py b/pymc3/model.py index 56241971fe..8c480c87e0 100644 --- a/pymc3/model.py +++ b/pymc3/model.py @@ -748,6 +748,8 @@ def __init__(self, type=None, owner=None, index=None, name=None, if total_size is None: coef = tt.as_tensor(1) else: + assert logp_elemwiset.ndim >= 1, ('Variable with scaled density ' + 'needs to be at least 1 dimensional') coef = tt.as_tensor(total_size) / logp_elemwiset.shape[0] self.logp_elemwiset = logp_elemwiset * coef self.model = model @@ -835,6 +837,8 @@ def __init__(self, type=None, owner=None, index=None, name=None, data=None, if total_size is None: coef = tt.as_tensor(1) else: + assert logp_elemwiset.ndim >= 1, ('Variable with scaled density ' + 'needs to be at least 1 dimensional') coef = tt.as_tensor(total_size) / logp_elemwiset.shape[0] self.logp_elemwiset = logp_elemwiset * coef self.model = model @@ -879,6 +883,8 @@ def __init__(self, name, data, distribution, model, total_size=None): if total_size is None: coef = tt.as_tensor(1) else: + assert logp_elemwiset.ndim >= 1, ('Variable with scaled density ' + 'needs to be at least 1 dimensional') coef = tt.as_tensor(total_size) / logp_elemwiset.shape[0] self.logp_elemwiset = logp_elemwiset * coef self.model = model