-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Add an option to stop PyroModules from sharing parameters #3149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
06a9122
fb5d282
ac21b8d
c789c3e
9835ee9
2cb054c
755ae4a
5f7cd94
c2eb114
a3a848c
81b1191
2c03fa0
401e9c6
446e8a5
84e3cde
d7c4777
8a42dbf
41a157c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,13 +5,26 @@ | |
| import warnings | ||
| from abc import ABCMeta, abstractmethod | ||
|
|
||
| import torch | ||
|
|
||
| import pyro | ||
| import pyro.poutine as poutine | ||
| from pyro.infer.util import is_validation_enabled | ||
| from pyro.poutine.util import prune_subsample_sites | ||
| from pyro.util import check_site_shape | ||
|
|
||
|
|
||
| class _ELBOModule(torch.nn.Module): | ||
| def __init__(self, model: torch.nn.Module, guide: torch.nn.Module, elbo: "ELBO"): | ||
| super().__init__() | ||
| self.model = model | ||
| self.guide = guide | ||
| self.elbo = elbo | ||
|
|
||
| def forward(self, *args, **kwargs): | ||
| return self.elbo.differentiable_loss(self.model, self.guide, *args, **kwargs) | ||
|
eb8680 marked this conversation as resolved.
|
||
|
|
||
|
|
||
| class ELBO(object, metaclass=ABCMeta): | ||
| """ | ||
| :class:`ELBO` is the top-level interface for stochastic variational | ||
|
|
@@ -23,6 +36,40 @@ class ELBO(object, metaclass=ABCMeta): | |
| :class:`~pyro.infer.tracegraph_elbo.TraceGraph_ELBO`, or | ||
| :class:`~pyro.infer.traceenum_elbo.TraceEnum_ELBO`. | ||
|
|
||
| .. note:: Derived classes now provide a more idiomatic PyTorch interface via | ||
| :meth:`__call__` for (model, guide) pairs that are :class:`~torch.nn.Module` s, | ||
| which is useful for integrating Pyro's variational inference tooling with | ||
| standard PyTorch interfaces like :class:`~torch.optim.Optimizer` s | ||
| and the large ecosystem of libraries like PyTorch Lightning | ||
| and the PyTorch JIT that work with these interfaces:: | ||
|
|
||
| model = Model() | ||
| guide = pyro.infer.autoguide.AutoNormal(model) | ||
|
|
||
| elbo_ = pyro.infer.Trace_ELBO(num_particles=10) | ||
|
|
||
| # Fix the model/guide pair | ||
| elbo = elbo_(model, guide) | ||
|
|
||
| # perform any data-dependent initialization | ||
| elbo(data) | ||
|
|
||
| optim = torch.optim.Adam(elbo.parameters(), lr=0.001) | ||
|
|
||
| for _ in range(100): | ||
| optim.zero_grad() | ||
| loss = elbo(data) | ||
| loss.backward() | ||
| optim.step() | ||
|
|
||
| Note that Pyro's global parameter store may cause this new interface to | ||
| behave unexpectedly relative to standard PyTorch when working with | ||
| :class:`~pyro.nn.PyroModule` s. | ||
|
|
||
| Users are therefore strongly encouraged to use this interface in conjunction | ||
| with :func:`~pyro.enable_module_local_param` which will override the default | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: override -> disable or avoid? |
||
| implicit sharing of parameters across :class:`~pyro.nn.PyroModule` instances. | ||
|
|
||
| :param num_particles: The number of particles/samples used to form the ELBO | ||
| (gradient) estimators. | ||
| :param int max_plate_nesting: Optional bound on max number of nested | ||
|
|
@@ -86,6 +133,15 @@ def __init__( | |
| self.jit_options = jit_options | ||
| self.tail_adaptive_beta = tail_adaptive_beta | ||
|
|
||
| def __call__( | ||
| self, model: torch.nn.Module, guide: torch.nn.Module | ||
| ) -> torch.nn.Module: | ||
|
eb8680 marked this conversation as resolved.
Outdated
|
||
| """ | ||
| Given a model and guide, returns a :class:`~torch.nn.Module` which | ||
| computes the ELBO loss when called with arguments to the model and guide. | ||
| """ | ||
| return _ELBOModule(model, guide, self) | ||
|
|
||
| def _guess_max_plate_nesting(self, model, guide, args, kwargs): | ||
| """ | ||
| Guesses max_plate_nesting by running the (model,guide) pair once | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -562,3 +562,35 @@ def validation_enabled(is_validate=True): | |
| dist.enable_validation(distribution_validation_status) | ||
| infer.enable_validation(infer_validation_status) | ||
| poutine.enable_validation(poutine_validation_status) | ||
|
|
||
|
|
||
| def enable_module_local_param(is_enabled: bool = False) -> None: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to make it super clear that users can now decide between (i) a global param store or (ii) local nn.Module style parameters. Like maybe with pyro.param_storage("local"): ...
with pyro.param_storage("global"): ...or |
||
| """ | ||
| Toggles the behavior of :class:`~pyro.nn.module.PyroModule` to use | ||
| local parameters instead of global parameters. | ||
|
|
||
| When this feature is enabled, :class:`~pyro.nn.module.PyroModule` | ||
| instances will not share parameters with other instances of the same | ||
| class through Pyro's global parameter store. Instead, each instance | ||
| will have its own local parameters, just like a standard :class:`torch.nn.Module`. | ||
|
|
||
| .. note:: This feature is disabled by default to ensure backwards compatibility | ||
| of :class:`~pyro.nn.module.PyroModule` with existing Pyro code. | ||
|
|
||
| :param bool is_enabled: (optional; defaults to False) whether to | ||
| enable local parameters. | ||
| """ | ||
| poutine.runtime._PYRO_MODULE_LOCAL_PARAM = is_enabled | ||
|
|
||
|
|
||
| @contextmanager | ||
| def module_local_param_enabled(is_enabled=False): | ||
| """ | ||
| Context manager to temporarily toggle local parameter stores in PyroModules. | ||
| """ | ||
| old_flag = poutine.runtime._PYRO_MODULE_LOCAL_PARAM | ||
| poutine.runtime._PYRO_MODULE_LOCAL_PARAM = is_enabled | ||
| try: | ||
| yield | ||
| finally: | ||
| poutine.runtime._PYRO_MODULE_LOCAL_PARAM = old_flag | ||
Uh oh!
There was an error while loading. Please reload this page.