-
Notifications
You must be signed in to change notification settings - Fork 15
feature/laplace dynamic delta #566
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 all commits
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 |
|---|---|---|
|
|
@@ -16,11 +16,12 @@ class AbstractFactorOptimiser(ABC): | |
| """ | ||
| logger = logger.debug | ||
|
|
||
| def __init__(self, initial_values=None, deltas=None, inplace=False, delta=1): | ||
| def __init__(self, initial_values=None, deltas=None, inplace=False, delta=1, dynamic_delta=False): | ||
| self.initial_values = initial_values or {} | ||
| self.inplace = inplace | ||
| self.delta = delta | ||
| self.deltas = deltas or {} | ||
| self.dynamic_delta = dynamic_delta | ||
|
|
||
| def update_model_approx( | ||
|
Collaborator
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. Suggest deleting this method and merging functionality into EPOptimiser class |
||
| self, | ||
|
|
@@ -30,14 +31,26 @@ def update_model_approx( | |
| status: Optional[Status] = Status(), | ||
| delta: Optional[float] = None, | ||
| ) -> Tuple[EPMeanField, Status]: | ||
| delta = delta or self.deltas.get(factor_approx.factor) or self.delta | ||
| new_approx, status = model_approx.project_mean_field( | ||
|
|
||
| variable_message_count = model_approx.variable_message_count | ||
| min_value = min(variable_message_count.values()) | ||
|
|
||
| delta = delta or self.delta | ||
|
|
||
| if factor_approx.factor in self.deltas: | ||
| delta = self.deltas[factor_approx.factor] | ||
| elif self.dynamic_delta: | ||
| delta = MeanField({ | ||
| variable: self.delta * (min_value / message_count) | ||
| for variable, message_count in variable_message_count.items() | ||
| }) | ||
|
|
||
| return model_approx.project_mean_field( | ||
| new_model_dist, | ||
| factor_approx, | ||
| delta=delta, | ||
| status=status, | ||
| ) | ||
| return new_approx, status | ||
|
|
||
| @abstractmethod | ||
| def optimise( | ||
|
Collaborator
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. This method should have signature, |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -101,7 +101,7 @@ def __init__( | |
| session | ||
| An SQLAlchemy session instance so the results of the model-fit are written to an SQLite database. | ||
| """ | ||
| super().__init__(delta=kwargs.get("delta", 1.0)) | ||
| super().__init__(delta=kwargs.get("delta", 1.0), dynamic_delta=kwargs.get("dynamic_delta", True)) | ||
|
|
||
| from autofit.non_linear.paths.database import DatabasePaths | ||
|
|
||
|
|
@@ -204,15 +204,13 @@ def __init__( | |
|
|
||
| self.optimisation_counter = Counter() | ||
|
|
||
| self.dynamic_delta = kwargs.get("dynamic_delta", True) | ||
|
|
||
| __identifier_fields__ = tuple() | ||
|
|
||
| def optimise( | ||
| self, | ||
| factor: Factor, | ||
| model_approx: EPMeanField, | ||
| status: Optional[Status] = None | ||
| status: Status = Status(), | ||
| ) -> Tuple[EPMeanField, Status]: | ||
| """ | ||
| Perform optimisation for expectation propagation. Currently only | ||
|
|
@@ -289,25 +287,12 @@ def optimise( | |
| result.projected_model.priors | ||
| ) | ||
|
|
||
| variable_message_count = model_approx.variable_message_count | ||
| min_value = min(variable_message_count.values()) | ||
|
|
||
| if self.dynamic_delta: | ||
| delta = MeanField({ | ||
| variable: self.delta * (min_value / message_count) | ||
| for variable, message_count in variable_message_count.items() | ||
| }) | ||
| else: | ||
| delta = self.delta | ||
|
|
||
| projection, status = factor_approx.project( | ||
|
Collaborator
Author
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. This projection step does not occur anymore. @matthewghgriffiths is this correct? |
||
| new_model_dist, | ||
| delta=delta | ||
| model_approx, status = self.update_model_approx( | ||
| new_model_dist, factor_approx, model_approx, status | ||
| ) | ||
|
|
||
| status.result = result | ||
|
|
||
| return model_approx.project(projection, status) | ||
| return model_approx, status | ||
|
|
||
| @property | ||
| def name(self): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently the default optimiser would need to be passed with dynamic_delta=True explicitly. I'm tempted to make the default dynamic_delta=True
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once I test this feature set properly I suspect we'll end up making it True by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah makes sense. I also need to look at incorporating it into the Laplace optimiser
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait that's what this PR does lol