Skip to content

Commit d87b0b9

Browse files
committed
Transformation warning using a class variable; docstring links
1 parent 7bfacff commit d87b0b9

File tree

3 files changed

+39
-24
lines changed

3 files changed

+39
-24
lines changed

bayesflow/approximators/point_approximator.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ class PointApproximator(ContinuousApproximator):
1414
"""
1515
A workflow for fast amortized point estimation of a conditional distribution.
1616
17-
The distribution is approximated by point estimators, parameterized by a feed-forward `PointInferenceNetwork`.
18-
Conditions can be compressed by an optional `SummaryNetwork` or used directly as input to the inference network.
17+
The distribution is approximated by point estimators, parameterized by a feed-forward
18+
:class:`bayesflow.networks.PointInferenceNetwork`. Conditions can be compressed by an optional summary network
19+
(inheriting from :class:`bayesflow.networks.SummaryNetwork`) or used directly as input to the inference network.
1920
"""
2021

2122
def estimate(
@@ -89,7 +90,7 @@ def sample(
8990
for the sampling process.
9091
split : bool, optional
9192
If True, the sampled arrays are split along the last axis, by default False.
92-
Currently not supported for `PointApproximator`.
93+
Currently not supported for :class:`PointApproximator` .
9394
**kwargs
9495
Additional keyword arguments passed to underlying processing functions.
9596
@@ -135,15 +136,14 @@ def log_prob(
135136
Returns
136137
-------
137138
log_prob : np.ndarray or dict[str, np.ndarray]
138-
Log-probabilities of the distribution `p(inference_variables | inference_conditions, h(summary_conditions))`
139-
for all parametric scoring rules.
139+
Log-probabilities of the distribution
140+
`p(inference_variables | inference_conditions, h(summary_conditions))` for all parametric scoring rules.
140141
141142
If only one parametric score is available, output is an array of log-probabilities.
142143
143144
Output is a dictionary if multiple parametric scores are available.
144145
Then, each key is the name of a score and values are corresponding log-probabilities.
145146
146-
147147
Log-probabilities have shape (num_datasets,).
148148
"""
149149
log_prob = super().log_prob(data=data, **kwargs)
@@ -167,7 +167,7 @@ def _apply_inverse_adapter_to_estimates(
167167
for score_key, score_val in estimates.items():
168168
processed[score_key] = {}
169169
for head_key, estimate in score_val.items():
170-
if head_key in self.inference_network.scores[score_key].not_transforming_like_vector_warning:
170+
if head_key in self.inference_network.scores[score_key].NOT_TRANSFORMING_LIKE_VECTOR_WARNING:
171171
logging.warning(
172172
f"Estimate '{score_key}.{head_key}' is marked to not transform like a vector. "
173173
f"It was treated like a vector by the adapter. Handle '{head_key}' estimates with care."

bayesflow/scores/multivariate_normal_score.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,22 @@ class MultivariateNormalScore(ParametricDistributionScore):
1616
Scores a predicted mean and covariance matrix with the log-score of the probability of the materialized value.
1717
"""
1818

19+
NOT_TRANSFORMING_LIKE_VECTOR_WARNING = ("covariance",)
20+
"""
21+
Marks head for covariance matrix as an exception for adapter transformations.
22+
23+
This variable contains names of prediction heads that should lead to a warning when the adapter is applied
24+
in inverse direction to them.
25+
26+
For more information see :class:`ScoringRule`.
27+
"""
28+
1929
def __init__(self, dim: int = None, links: dict = None, **kwargs):
2030
super().__init__(links=links, **kwargs)
2131

2232
self.dim = dim
2333
self.links = links or {"covariance": PositiveDefinite()}
2434

25-
# mark head for covariance matrix as an exception for adapter transformations
26-
self.not_transforming_like_vector = ["covariance"]
27-
2835
self.config = {"dim": dim}
2936

3037
def get_config(self):

bayesflow/scores/scoring_rule.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,27 @@ class ScoringRule:
1515
when sampling from the true distribution. By minimizing an expected score, estimates with
1616
different properties can be obtained.
1717
18-
To define a custom ``ScoringRule``, inherit from this class and overwrite the score method.
18+
To define a custom :class:`ScoringRule`, inherit from this class and overwrite the score method.
1919
For proper serialization, any new constructor arguments must be taken care of in a `get_config` method.
2020
2121
Estimates are typically parameterized by projection heads consisting of a neural network component
2222
and a link to project into the correct output space.
2323
24-
`ScoringRule`s can score estimates consisting of multiple parts. See `MultivariateNormalScore` for an example
25-
of a `ParametricDistributionScore`. The score evaluates an estimated mean and covariance simultaneously.
24+
A :class:`ScoringRule` can score estimates consisting of multiple parts. See :class:`MultivariateNormalScore`
25+
for an example of a :class:`ParametricDistributionScore`. That score evaluates an estimated mean
26+
and covariance simultaneously.
27+
"""
28+
29+
NOT_TRANSFORMING_LIKE_VECTOR_WARNING = tuple()
30+
"""
31+
This variable contains names of prediction heads that should lead to a warning when the adapter is applied
32+
in inverse direction to them.
33+
34+
Prediction heads can output estimates in spaces other than the target distribution space.
35+
To such estimates the adapter cannot be straightforwardly applied in inverse direction,
36+
because the adapter is built to map vectors from the inference variable space. When subclassing
37+
:class:`ScoringRule`, add the names of such heads to the following list to warn users about difficulties
38+
with a type of estimate whenever the adapter is applied to them in inverse direction.
2639
"""
2740

2841
def __init__(
@@ -35,13 +48,6 @@ def __init__(
3548
self.subnets_kwargs = subnets_kwargs or {}
3649
self.links = links or {}
3750

38-
# Prediction heads can output estimates in spaces other than the target distribution space.
39-
# To such estimates the adapter cannot be straightforwardly applied in inverse direction,
40-
# because the adapter is built to map vectors. When subclassing `ScoringRule`, add the names
41-
# of such heads to the following list to warn users about difficulties with a type of estimate
42-
# whenever the adapter is applied to them in inverse direction.
43-
self.not_transforming_like_vector_warning = []
44-
4551
self.config = {"subnets_kwargs": self.subnets_kwargs}
4652

4753
def get_config(self):
@@ -117,10 +123,12 @@ def get_head(self, key: str, output_shape: Shape) -> keras.Sequential:
117123
"""For a specified head key and output shape, request corresponding head network.
118124
119125
A head network has the following components that are called sequentially:
126+
120127
1. subnet: A keras.Layer.
121128
2. dense: A trainable linear projection with as many units as are required by the next component.
122129
3. reshape: Changes shape of output of projection to match requirements of next component.
123130
4. link: Transforms unconstrained values into a constrained space for the final estimator.
131+
See :mod:`bayesflow.links` for examples.
124132
125133
This method initializes the components in reverse order to meet all requirements and returns them.
126134
@@ -130,7 +138,7 @@ def get_head(self, key: str, output_shape: Shape) -> keras.Sequential:
130138
Name of head for which to request a link.
131139
output_shape: Shape
132140
The necessary shape of estimated values for the given key as returned by
133-
`scoring_rule.get_head_shapes_from_target_shape()`.
141+
:func:`get_head_shapes_from_target_shape()`.
134142
135143
Returns
136144
-------
@@ -173,11 +181,11 @@ def score(self, estimates: dict[str, Tensor], targets: Tensor, weights: Tensor)
173181
174182
Examples
175183
--------
176-
The following shows how to score estimates with a ``MeanScore``. All ``ScoringRule`` s follow this pattern,
177-
only differing in the structure of the estimates dictionary.
184+
The following shows how to score estimates with a :class:`MeanScore`. All :class:`ScoringRule` s
185+
follow this pattern, only differing in the structure of the estimates dictionary.
178186
179187
>>> import keras
180-
... from bayesflow.scores import MeanScore
188+
>>> from bayesflow.scores import MeanScore
181189
>>>
182190
>>> # batch of samples from a normal distribution
183191
>>> samples = keras.random.normal(shape=(100,))

0 commit comments

Comments
 (0)