From 909011257f4b7bc6e8ee46fbb578dcb15c95de0f Mon Sep 17 00:00:00 2001 From: stefanradev93 Date: Thu, 28 Nov 2024 11:10:22 -0500 Subject: [PATCH 01/38] Splines draft --- .../transforms/spline_transform.py | 112 ++++++++++++++++-- bayesflow/utils/__init__.py | 1 + bayesflow/utils/tensor_utils.py | 20 ++++ 3 files changed, 121 insertions(+), 12 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 3fef3abc5..d7321df28 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -3,7 +3,9 @@ from keras import ops from keras.saving import register_keras_serializable as serializable +from bayesflow.utils import searchsorted from bayesflow.types import Tensor + from .transform import Transform @@ -32,15 +34,9 @@ def __init__(self, bins=16, default_domain=(-5.0, 5.0, -5.0, 5.0), **kwargs): self.softplus_shift = math.log(math.e - 1.0) def split_parameters(self, parameters: Tensor) -> dict[str, Tensor]: - # Ensure spline works for 2D (batch_size, dim) and 3D (batch_size, num_reps, dim) + # Ensure spline works for N-D, e.g., 2D (batch_size, dim) and 3D (batch_size, num_reps, dim) shape = ops.shape(parameters) - rank = len(shape) - if rank == 2: - new_shape = (shape[0], -1, self._params_per_dim) - elif rank == 3: - new_shape = (shape[0], shape[1], -1, self._params_per_dim) - else: - raise NotImplementedError("Spline flows can currently only operate on 2D and 3D inputs!") + new_shape = shape[:-1] + (-1, self._params_per_dim) # Arrange spline parameters into a dictionary parameters = ops.reshape(parameters, new_shape) @@ -77,8 +73,100 @@ def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tenso parameters["derivatives"] = ops.concatenate([scale, parameters["derivatives"], scale], axis=-1) return parameters - def forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): - raise NotImplementedError + def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): + return self._calculate_spline(x, parameters, inverse=False) + + def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): + return self._calculate_spline(z, parameters, inverse=True) + + @staticmethod + def _calculate_spline(x: Tensor, p: dict[str, Tensor], inverse: bool = False) -> (Tensor, Tensor): + """Helper function to calculate RQ spline.""" + + result = ops.zeros_like(x) + log_jac = ops.zeros_like(x) + + total_width = ops.sum(p["widths"], axis=-1, keepdims=True) + total_height = ops.sum(p["heights"], axis=-1, keepdims=True) + + knots_x = ops.concatenate([p["left_edge"], p["left_edge"] + ops.cumsum(p["widths"], axis=-1)], axis=-1) + knots_y = ops.concatenate([p["bottom_edge"], p["bottom_edge"] + ops.cumsum(p["heights"], axis=-1)], axis=-1) + + if not inverse: + target_in_domain = ops.logical_and(knots_x[..., 0] < x, x <= knots_x[..., -1]) + higher_indices = searchsorted(knots_x, x[..., None]) + else: + target_in_domain = ops.logical_and(knots_y[..., 0] < x, x <= knots_y[..., -1]) + higher_indices = searchsorted(knots_y, x[..., None]) + + target_in = x[target_in_domain] + target_in_idx = ops.stack(ops.where(target_in_domain), axis=-1) + target_out = x[~target_in_domain] + target_out_idx = ops.stack(ops.where(~target_in_domain), axis=-1) + + # In-domain computation + if ops.size(target_in_idx) > 0: + # Index crunching + higher_indices = ops.take_along_axis(higher_indices, target_in_idx) + lower_indices = higher_indices - 1 + lower_idx_tuples = ops.concatenate([target_in_idx, lower_indices], axis=-1) + higher_idx_tuples = ops.concatenate([target_in_idx, higher_indices], axis=-1) + + # Spline computation + dk = ops.take_along_axis(p["derivatives"], lower_idx_tuples) + dkp = ops.take_along_axis(p["derivatives"], higher_idx_tuples) + xk = ops.take_along_axis(knots_x, lower_idx_tuples) + xkp = ops.take_along_axis(knots_x, higher_idx_tuples) + yk = ops.take_along_axis(knots_y, lower_idx_tuples) + ykp = ops.take_along_axis(knots_y, higher_idx_tuples) + x = target_in + dx = xkp - xk + dy = ykp - yk + sk = dy / dx + xi = (x - xk) / dx + + # Forward pass + if not inverse: + numerator = dy * (sk * xi**2 + dk * xi * (1 - xi)) + denominator = sk + (dkp + dk - 2 * sk) * xi * (1 - xi) + result_in = yk + numerator / denominator + + # Log Jacobian for in-domain + numerator = sk**2 * (dkp * xi**2 + 2 * sk * xi * (1 - xi) + dk * (1 - xi) ** 2) + denominator = (sk + (dkp + dk - 2 * sk) * xi * (1 - xi)) ** 2 + log_jac_in = ops.log(numerator + 1e-10) - ops.log(denominator + 1e-10) + log_jac = ops.slice_update(log_jac, target_in_idx, log_jac_in) + + # Inverse pass + else: + y = x + a = dy * (sk - dk) + (y - yk) * (dkp + dk - 2 * sk) + b = dy * dk - (y - yk) * (dkp + dk - 2 * sk) + c = -sk * (y - yk) + discriminant = ops.maximum(b**2 - 4 * a * c, 0.0) + xi = 2 * c / (-b - ops.sqrt(discriminant)) + result_in = xi * dx + xk + + result = ops.slice_update(result, target_in_idx, result_in) + + # Out-of-domain + if ops.size(target_out_idx) > 1: + scale = total_height / total_width + shift = p["bottom_edge"] - scale * p["left_edge"] + scale_out = ops.take_along_axis(scale, target_out_idx) + shift_out = ops.take_along_axis(shift, target_out_idx) + + if not inverse: + result_out = scale_out * target_out[..., None] + shift_out + # Log Jacobian for out-of-domain points + log_jac_out = ops.log(scale_out + 1e-10) + log_jac_out = ops.squeeze(log_jac_out, axis=-1) + log_jac = ops.slice_update(log_jac, target_out_idx, log_jac_out) + else: + result_out = (target_out[..., None] - shift_out) / scale_out + + result_out = ops.squeeze(result_out, axis=-1) + result = ops.slice_update(result, target_out_idx, result_out) - def inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): - raise NotImplementedError + log_det = ops.sum(log_jac, axis=-1) + return result, log_det diff --git a/bayesflow/utils/__init__.py b/bayesflow/utils/__init__.py index 669ad33de..5c6bf0634 100644 --- a/bayesflow/utils/__init__.py +++ b/bayesflow/utils/__init__.py @@ -40,6 +40,7 @@ tree_concatenate, concatenate, tree_stack, + searchsorted, ) from .validators import check_lengths_same from .comp_utils import expected_calibration_error diff --git a/bayesflow/utils/tensor_utils.py b/bayesflow/utils/tensor_utils.py index 219f4404d..aef87a69d 100644 --- a/bayesflow/utils/tensor_utils.py +++ b/bayesflow/utils/tensor_utils.py @@ -140,3 +140,23 @@ def stack(*items): return keras.ops.stack(items, axis=axis) return keras.tree.map_structure(stack, *structures) + + +def searchsorted(sorted_sequence: Tensor, values: Tensor) -> Tensor: + """Compute the dot product between the Jacobian of the given function at the point given by + the input (primals) and vectors in tangents.""" + + match keras.backend.backend(): + case "torch": + import torch + + return torch.searchsorted(sorted_sequence, values) + case "tensorflow": + import tensorflow as tf + + return tf.searchsorted(sorted_sequence, values) + case "jax": + raise NotImplementedError("N-D searchsorted not implemented for JAX") + + case _: + raise NotImplementedError(f"JVP not implemented for backend {keras.backend.backend()}") From 38501d509cb085e3a167bf2f40f2ee8efbe9d504 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Mon, 13 Jan 2025 15:02:36 +0100 Subject: [PATCH 02/38] update keras requirement --- environment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yaml b/environment.yaml index 0264442a3..842b4c748 100644 --- a/environment.yaml +++ b/environment.yaml @@ -4,7 +4,7 @@ channels: dependencies: - jupyter - jupyterlab - - keras ~= 3.4.0 + - keras >= 3.5.0 - numpy ~= 1.26 - matplotlib - pre-commit From afb7f375e89fa7bcdc05afe82bba804c108c5006 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Mon, 13 Jan 2025 15:02:58 +0100 Subject: [PATCH 03/38] small improvements to error messages --- bayesflow/utils/jvp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bayesflow/utils/jvp.py b/bayesflow/utils/jvp.py index d086cfdc1..fbc670082 100644 --- a/bayesflow/utils/jvp.py +++ b/bayesflow/utils/jvp.py @@ -27,5 +27,5 @@ def jvp(fn: callable, primals: tuple[Tensor] | Tensor, tangents: tuple[Tensor] | tangents, ) case _: - raise NotImplementedError(f"JVP not implemented for backend {keras.backend.backend()}") + raise NotImplementedError(f"JVP not implemented for backend {keras.backend.backend()!r}") return fn_output, _jvp From 95a85286b70c835843afb49dac0e28989a34d6b2 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Mon, 13 Jan 2025 15:05:42 +0100 Subject: [PATCH 04/38] add rq spline function --- .../transforms/_rational_quadratic.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py diff --git a/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py b/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py new file mode 100644 index 000000000..dffbe9a61 --- /dev/null +++ b/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py @@ -0,0 +1,75 @@ +import keras +from typing import TypedDict + +from bayesflow.types import Tensor + + +class Edges(TypedDict): + left: Tensor + right: Tensor + bottom: Tensor + top: Tensor + + +class Derivatives(TypedDict): + left: Tensor + right: Tensor + + +def _rational_quadratic_spline( + x: Tensor, edges: Edges, derivatives: Derivatives, inverse: bool = False +) -> (Tensor, Tensor): + # rename variables to match the paper: + + # $x^{(k)}$ + xk = edges["left"] + + # $x^{(k+1)}$ + xkp = edges["right"] + + # $y^{(k)}$ + yk = edges["bottom"] + + # $y^{(k+1)}$ + ykp = edges["top"] + + # $delta^{(k)}$ + dk = derivatives["left"] + + # $delta^{(k+1)}$ + dkp = derivatives["right"] + + # commonly used values + dx = xkp - xk + dy = ykp - yk + sk = dy / dx + + if not inverse: + xi = (x - xk) / dx + + # Eq. 4 in the paper + numerator = dy * (sk * xi**2 + dk * xi * (1 - xi)) + denominator = sk + (dkp + dk - 2 * sk) * xi * (1 - xi) + out = yk + numerator / denominator + else: + y = x + # Eq. 6-8 in the paper + a = dy * (sk - dk) + (y - yk) * (dkp + dk - 2 * sk) + b = dy * dk - (y - yk) * (dkp + dk - 2 * sk) + c = -sk * (y - yk) + + # Eq. 29 in the appendix of the paper + discriminant = b**2 - 4 * a * c + if not keras.ops.all(discriminant >= 0): + raise ValueError("Discriminant must be non-negative.") + + xi = 2 * c / (-b - keras.ops.sqrt(discriminant)) + + out = xi * dx + xk + + # Eq 5 in the paper + numerator = sk**2 * (dkp * xi**2 + 2 * sk * xi * (1 - xi) + dk * (1 - xi) ** 2) + denominator = (sk + (dkp + dk - 2 * sk) * xi * (1 - xi)) ** 2 + log_jac = keras.ops.log(numerator) - keras.ops.log(denominator) + + return out, log_jac From ffd1dd180aceeb6eef585f6b85e21bb6ef59fb21 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Mon, 13 Jan 2025 15:06:00 +0100 Subject: [PATCH 05/38] add spline transform --- .../transforms/spline_transform.py | 277 ++++++++---------- 1 file changed, 130 insertions(+), 147 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index d7321df28..356dbf674 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -1,172 +1,155 @@ -import math +import keras +from keras.saving import ( + register_keras_serializable as serializable, +) -from keras import ops -from keras.saving import register_keras_serializable as serializable - -from bayesflow.utils import searchsorted from bayesflow.types import Tensor +from bayesflow.utils import searchsorted +from bayesflow.utils.keras_utils import shifted_softplus from .transform import Transform +from ._rational_quadratic import _rational_quadratic_spline @serializable(package="networks.coupling_flow") class SplineTransform(Transform): - def __init__(self, bins=16, default_domain=(-5.0, 5.0, -5.0, 5.0), **kwargs): - super().__init__(**kwargs) - + def __init__( + self, + bins: int = 16, + default_domain: (float, float, float, float) = (-5.0, 5.0, -5.0, 5.0), + method: str = "rational_quadratic", + ): + super().__init__() self.bins = bins - self.default_domain = default_domain - self.spline_params_counts = { + self.method = method + + if self.method != "rational_quadratic": + raise NotImplementedError("Currently, only 'rational_quadratic' spline method is supported.") + + self.parameter_sizes = { "left_edge": 1, "bottom_edge": 1, - "widths": self.bins, - "heights": self.bins, + "bin_widths": self.bins, + "bin_heights": self.bins, "derivatives": self.bins - 1, } - self.split_idx = ops.cumsum(list(self.spline_params_counts.values()))[:-1] - self._params_per_dim = sum(self.spline_params_counts.values()) - # Pre-compute defaults and softplus shifts - default_width = (self.default_domain[1] - self.default_domain[0]) / self.bins - default_height = (self.default_domain[3] - self.default_domain[2]) / self.bins - self.xshift = math.log(math.exp(default_width) - 1) - self.yshift = math.log(math.exp(default_height) - 1) - self.softplus_shift = math.log(math.e - 1.0) + if default_domain[1] <= default_domain[0] or default_domain[3] <= default_domain[2]: + raise ValueError("Invalid default domain. Must be (left, right, bottom, top).") - def split_parameters(self, parameters: Tensor) -> dict[str, Tensor]: - # Ensure spline works for N-D, e.g., 2D (batch_size, dim) and 3D (batch_size, num_reps, dim) - shape = ops.shape(parameters) - new_shape = shape[:-1] + (-1, self._params_per_dim) - - # Arrange spline parameters into a dictionary - parameters = ops.reshape(parameters, new_shape) - parameters = ops.split(parameters, self.split_idx, axis=-1) - parameters = dict( - left_edge=parameters[0], - bottom_edge=parameters[1], - widths=parameters[2], - heights=parameters[3], - derivatives=parameters[4], - ) - return parameters + self.default_left = default_domain[0] + self.default_bottom = default_domain[2] + self.default_bin_width = (default_domain[1] - default_domain[0]) / self.bins + self.default_bin_height = (default_domain[3] - default_domain[2]) / self.bins @property - def params_per_dim(self): - return self._params_per_dim + def params_per_dim(self) -> int: + return sum(self.parameter_sizes.values()) - def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tensor]: - # Set lower corners of domain relative to default domain - parameters["left_edge"] = parameters["left_edge"] + self.default_domain[0] - parameters["bottom_edge"] = parameters["bottom_edge"] + self.default_domain[2] + def split_parameters(self, parameters: Tensor) -> dict[str, Tensor]: + p = {} + + start = 0 + for key, value in self.parameter_sizes.items(): + stop = start + value + p[key] = keras.ops.take(parameters, indices=list(range(start, stop)), axis=-1) + start = stop - # Constrain widths and heights to be positive - parameters["widths"] = ops.softplus(parameters["widths"] + self.xshift) - parameters["heights"] = ops.softplus(parameters["heights"] + self.yshift) + return p - # Compute spline derivatives - parameters["derivatives"] = ops.softplus(parameters["derivatives"] + self.softplus_shift) + def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tensor]: + left_edge = parameters["left_edge"] + self.default_left + bottom_edge = parameters["bottom_edge"] + self.default_bottom + bin_widths = self.default_bin_width * shifted_softplus(parameters["bin_widths"]) + bin_heights = self.default_bin_height * shifted_softplus(parameters["bin_heights"]) + + affine_scale = keras.ops.sum(bin_widths, axis=-1, keepdims=True) + affine_shift = bottom_edge - affine_scale * left_edge + + horizontal_edges = left_edge + keras.ops.cumsum(bin_widths, axis=-1) + vertical_edges = bottom_edge + keras.ops.cumsum(bin_heights, axis=-1) + + derivatives = shifted_softplus(parameters["derivatives"]) + # derivatives = pad(derivatives, 0.0, 1, axis=-1) + derivatives = keras.ops.concatenate([affine_scale, derivatives, affine_scale], axis=-1) + + constrained_parameters = { + "horizontal_edges": horizontal_edges, + "vertical_edges": vertical_edges, + "derivatives": derivatives, + "affine_scale": affine_scale, + "affine_shift": affine_shift, + } - # Add in edge derivatives - total_width = ops.sum(parameters["widths"], axis=-1, keepdims=True) - total_height = ops.sum(parameters["heights"], axis=-1, keepdims=True) - scale = total_height / total_width - parameters["derivatives"] = ops.concatenate([scale, parameters["derivatives"], scale], axis=-1) - return parameters + return constrained_parameters def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): - return self._calculate_spline(x, parameters, inverse=False) + # x.shape == ([B, ...], D) + # parameters.shape == ([B, ...], bins) + bins = searchsorted(parameters["horizontal_edges"], x) + + inside = (bins > 0) & (bins <= self.bins) + inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) + + # first compute affine transform on everything + scale = parameters["affine_scale"] + shift = parameters["affine_shift"] + z = scale * x + shift + log_jac = keras.ops.broadcast_to(keras.ops.log(scale), keras.ops.shape(z)) + + # overwrite inside part with spline + upper = bins[inside] + lower = upper - 1 + + edges = { + "left": keras.ops.take_along_axis(parameters["horizontal_edges"], lower, axis=None), + "right": keras.ops.take_along_axis(parameters["horizontal_edges"], upper, axis=None), + "bottom": keras.ops.take_along_axis(parameters["vertical_edges"], lower, axis=None), + "top": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=None), + } + derivatives = { + "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=None), + "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=None), + } + spline, jac = _rational_quadratic_spline(x[inside], edges=edges, derivatives=derivatives) + z = keras.ops.scatter_update(z, inside_indices, spline) + log_jac = keras.ops.scatter_update(log_jac, inside_indices, jac) + + log_det = keras.ops.sum(log_jac, axis=-1) + + return z, log_det def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): - return self._calculate_spline(z, parameters, inverse=True) - - @staticmethod - def _calculate_spline(x: Tensor, p: dict[str, Tensor], inverse: bool = False) -> (Tensor, Tensor): - """Helper function to calculate RQ spline.""" - - result = ops.zeros_like(x) - log_jac = ops.zeros_like(x) - - total_width = ops.sum(p["widths"], axis=-1, keepdims=True) - total_height = ops.sum(p["heights"], axis=-1, keepdims=True) - - knots_x = ops.concatenate([p["left_edge"], p["left_edge"] + ops.cumsum(p["widths"], axis=-1)], axis=-1) - knots_y = ops.concatenate([p["bottom_edge"], p["bottom_edge"] + ops.cumsum(p["heights"], axis=-1)], axis=-1) - - if not inverse: - target_in_domain = ops.logical_and(knots_x[..., 0] < x, x <= knots_x[..., -1]) - higher_indices = searchsorted(knots_x, x[..., None]) - else: - target_in_domain = ops.logical_and(knots_y[..., 0] < x, x <= knots_y[..., -1]) - higher_indices = searchsorted(knots_y, x[..., None]) - - target_in = x[target_in_domain] - target_in_idx = ops.stack(ops.where(target_in_domain), axis=-1) - target_out = x[~target_in_domain] - target_out_idx = ops.stack(ops.where(~target_in_domain), axis=-1) - - # In-domain computation - if ops.size(target_in_idx) > 0: - # Index crunching - higher_indices = ops.take_along_axis(higher_indices, target_in_idx) - lower_indices = higher_indices - 1 - lower_idx_tuples = ops.concatenate([target_in_idx, lower_indices], axis=-1) - higher_idx_tuples = ops.concatenate([target_in_idx, higher_indices], axis=-1) - - # Spline computation - dk = ops.take_along_axis(p["derivatives"], lower_idx_tuples) - dkp = ops.take_along_axis(p["derivatives"], higher_idx_tuples) - xk = ops.take_along_axis(knots_x, lower_idx_tuples) - xkp = ops.take_along_axis(knots_x, higher_idx_tuples) - yk = ops.take_along_axis(knots_y, lower_idx_tuples) - ykp = ops.take_along_axis(knots_y, higher_idx_tuples) - x = target_in - dx = xkp - xk - dy = ykp - yk - sk = dy / dx - xi = (x - xk) / dx - - # Forward pass - if not inverse: - numerator = dy * (sk * xi**2 + dk * xi * (1 - xi)) - denominator = sk + (dkp + dk - 2 * sk) * xi * (1 - xi) - result_in = yk + numerator / denominator - - # Log Jacobian for in-domain - numerator = sk**2 * (dkp * xi**2 + 2 * sk * xi * (1 - xi) + dk * (1 - xi) ** 2) - denominator = (sk + (dkp + dk - 2 * sk) * xi * (1 - xi)) ** 2 - log_jac_in = ops.log(numerator + 1e-10) - ops.log(denominator + 1e-10) - log_jac = ops.slice_update(log_jac, target_in_idx, log_jac_in) - - # Inverse pass - else: - y = x - a = dy * (sk - dk) + (y - yk) * (dkp + dk - 2 * sk) - b = dy * dk - (y - yk) * (dkp + dk - 2 * sk) - c = -sk * (y - yk) - discriminant = ops.maximum(b**2 - 4 * a * c, 0.0) - xi = 2 * c / (-b - ops.sqrt(discriminant)) - result_in = xi * dx + xk - - result = ops.slice_update(result, target_in_idx, result_in) - - # Out-of-domain - if ops.size(target_out_idx) > 1: - scale = total_height / total_width - shift = p["bottom_edge"] - scale * p["left_edge"] - scale_out = ops.take_along_axis(scale, target_out_idx) - shift_out = ops.take_along_axis(shift, target_out_idx) - - if not inverse: - result_out = scale_out * target_out[..., None] + shift_out - # Log Jacobian for out-of-domain points - log_jac_out = ops.log(scale_out + 1e-10) - log_jac_out = ops.squeeze(log_jac_out, axis=-1) - log_jac = ops.slice_update(log_jac, target_out_idx, log_jac_out) - else: - result_out = (target_out[..., None] - shift_out) / scale_out - - result_out = ops.squeeze(result_out, axis=-1) - result = ops.slice_update(result, target_out_idx, result_out) - - log_det = ops.sum(log_jac, axis=-1) - return result, log_det + bins = searchsorted(parameters["vertical_edges"], z) + + inside = (bins > 0) & (bins <= self.bins) + inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) + + # first compute affine transform on everything + scale = parameters["affine_scale"] + shift = parameters["affine_shift"] + x = (z - shift) / scale + log_jac = keras.ops.broadcast_to(-keras.ops.log(scale), keras.ops.shape(x)) + + # overwrite inside part with spline + + upper = bins[inside] + lower = upper - 1 + + edges = { + "left": keras.ops.take_along_axis(parameters["vertical_edges"], lower, axis=None), + "right": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=None), + "bottom": keras.ops.take_along_axis(parameters["horizontal_edges"], lower, axis=None), + "top": keras.ops.take_along_axis(parameters["horizontal_edges"], upper, axis=None), + } + derivatives = { + "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=None), + "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=None), + } + spline, jac = _rational_quadratic_spline(z[inside], edges=edges, derivatives=derivatives, inverse=True) + x = keras.ops.scatter_update(x, inside_indices, spline) + log_jac = keras.ops.scatter_update(log_jac, inside_indices, jac) + + log_det = keras.ops.sum(log_jac, axis=-1) + + return x, log_det From 2a8a3ea9db6e66b6f0b1075340472aad127c2d40 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Mon, 13 Jan 2025 15:06:37 +0100 Subject: [PATCH 06/38] update searchsorted utils for jax also add padd util --- bayesflow/utils/__init__.py | 3 +- bayesflow/utils/tensor_utils.py | 61 +++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/bayesflow/utils/__init__.py b/bayesflow/utils/__init__.py index 5c6bf0634..67ce8e635 100644 --- a/bayesflow/utils/__init__.py +++ b/bayesflow/utils/__init__.py @@ -28,6 +28,7 @@ from .jvp import jvp from .optimal_transport import optimal_transport from .tensor_utils import ( + concatenate, expand_left, expand_left_as, expand_left_to, @@ -38,8 +39,8 @@ size_of, tile_axis, tree_concatenate, - concatenate, tree_stack, + pad, searchsorted, ) from .validators import check_lengths_same diff --git a/bayesflow/utils/tensor_utils.py b/bayesflow/utils/tensor_utils.py index aef87a69d..6cea1f43d 100644 --- a/bayesflow/utils/tensor_utils.py +++ b/bayesflow/utils/tensor_utils.py @@ -5,6 +5,7 @@ import numpy as np from bayesflow.types import Tensor +from . import logging T = TypeVar("T") @@ -57,6 +58,16 @@ def expand_tile(x: Tensor, n: int, axis: int) -> Tensor: return tile_axis(x, n, axis=axis) +def pad(x: Tensor, value: float, n: int, axis: int) -> Tensor: + """Pad x with n values along axis""" + shape = list(keras.ops.shape(x)) + shape[axis] = n + p = keras.ops.full(shape, value, dtype=keras.ops.dtype(x)) + xp = keras.ops.concatenate([p, x, p], axis=axis) + + return xp + + def size_of(x) -> int: """ :param x: A nested structure of tensors. @@ -142,21 +153,51 @@ def stack(*items): return keras.tree.map_structure(stack, *structures) -def searchsorted(sorted_sequence: Tensor, values: Tensor) -> Tensor: - """Compute the dot product between the Jacobian of the given function at the point given by - the input (primals) and vectors in tangents.""" +def searchsorted(sorted_sequence: Tensor, values: Tensor, side: str = "left") -> Tensor: + """ + Find indices where elements should be inserted to maintain order. + """ match keras.backend.backend(): - case "torch": - import torch + case "jax": + import jax + import jax.numpy as jnp + + logging.warning("JAX searchsorted is not yet optimized.") + + # do not vmap over the side argument (we have to pass it as a positional argument) + in_axes = [0, 0, None] + + # vmap over the batch dimension + vss = jax.vmap(jnp.searchsorted, in_axes=in_axes) - return torch.searchsorted(sorted_sequence, values) + # flatten all batch dimensions + ss = sorted_sequence.reshape((-1,) + sorted_sequence.shape[-1:]) + v = values.reshape((-1,) + values.shape[-1:]) + + # noinspection PyTypeChecker + indices = vss(ss, v, side) + + # restore the batch dimensions + indices = indices.reshape(values.shape) + + # noinspection PyTypeChecker + return indices case "tensorflow": import tensorflow as tf - return tf.searchsorted(sorted_sequence, values) - case "jax": - raise NotImplementedError("N-D searchsorted not implemented for JAX") + out_type = "int32" if len(sorted_sequence) <= np.iinfo(np.int32).max else "int64" + + indices = tf.searchsorted(sorted_sequence, values, side=side, out_type=out_type) + + return indices + case "torch": + import torch + + out_int32 = len(sorted_sequence) <= np.iinfo(np.int32).max + + indices = torch.searchsorted(sorted_sequence, values, side=side, out_int32=out_int32) + return indices case _: - raise NotImplementedError(f"JVP not implemented for backend {keras.backend.backend()}") + raise NotImplementedError(f"Searchsorted not implemented for backend {keras.backend.backend()!r}") From 601b0c51cf354992f09af0d46f4b1fa63874c49b Mon Sep 17 00:00:00 2001 From: LarsKue Date: Mon, 13 Jan 2025 15:07:27 +0100 Subject: [PATCH 07/38] update tests --- tests/test_networks/test_coupling_flow/conftest.py | 2 +- .../test_coupling_flow/test_invertible_layers.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_networks/test_coupling_flow/conftest.py b/tests/test_networks/test_coupling_flow/conftest.py index 5aca010bf..2b59fde89 100644 --- a/tests/test_networks/test_coupling_flow/conftest.py +++ b/tests/test_networks/test_coupling_flow/conftest.py @@ -12,7 +12,7 @@ def actnorm(): def dual_coupling(): from bayesflow.networks.coupling_flow.couplings import DualCoupling - return DualCoupling() + return DualCoupling(transform="spline") @pytest.fixture(params=["actnorm", "dual_coupling"]) diff --git a/tests/test_networks/test_coupling_flow/test_invertible_layers.py b/tests/test_networks/test_coupling_flow/test_invertible_layers.py index 9b52376f1..2c422964c 100644 --- a/tests/test_networks/test_coupling_flow/test_invertible_layers.py +++ b/tests/test_networks/test_coupling_flow/test_invertible_layers.py @@ -4,7 +4,7 @@ import numpy as np import pytest -from tests.utils import allclose +from tests.utils import allclose, assert_allclose def test_build(invertible_layer, random_samples, random_conditions): @@ -57,8 +57,8 @@ def test_cycle_consistency(invertible_layer, random_samples, random_conditions): forward_output, forward_log_det = invertible_layer(random_samples) inverse_output, inverse_log_det = invertible_layer(forward_output, inverse=True) - assert allclose(random_samples, inverse_output) - assert allclose(forward_log_det, -inverse_log_det) + assert_allclose(random_samples, inverse_output, atol=1e-6, msg="Samples are not cycle consistent") + assert_allclose(forward_log_det, -inverse_log_det, atol=1e-6, msg="Log Determinants are not cycle consistent") @pytest.mark.torch From 9974a711e665f1010ad6afd24c11090a5ed23034 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Mon, 13 Jan 2025 15:07:44 +0100 Subject: [PATCH 08/38] add assert_allclose util for improved messages --- tests/utils/ops.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/utils/ops.py b/tests/utils/ops.py index f46320a06..80841fba7 100644 --- a/tests/utils/ops.py +++ b/tests/utils/ops.py @@ -9,6 +9,11 @@ def allclose(x1, x2, rtol=1e-5, atol=1e-8): return keras.ops.all(isclose(x1, x2, rtol, atol)) +def assert_allclose(x1, x2, rtol=1e-5, atol=1e-8, msg=""): + mse = keras.ops.mean(keras.ops.square(x1 - x2)) + assert allclose(x1, x2, rtol, atol), f"{msg} - mse={mse}" + + def max_mean_discrepancy(x, y): # Computes the Max Mean Discrepancy between samples of two distributions xx = keras.ops.matmul(x, keras.ops.transpose(x)) From b1e52c269fa6e9744717bd7b9a32f864ef509589 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Mon, 13 Jan 2025 16:18:53 +0100 Subject: [PATCH 09/38] parametrize transform for flow tests --- .../test_networks/test_coupling_flow/conftest.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test_networks/test_coupling_flow/conftest.py b/tests/test_networks/test_coupling_flow/conftest.py index 2b59fde89..e9f7d63b4 100644 --- a/tests/test_networks/test_coupling_flow/conftest.py +++ b/tests/test_networks/test_coupling_flow/conftest.py @@ -9,19 +9,24 @@ def actnorm(): @pytest.fixture() -def dual_coupling(): +def dual_coupling(request, transform): from bayesflow.networks.coupling_flow.couplings import DualCoupling - return DualCoupling(transform="spline") + return DualCoupling(transform=transform) @pytest.fixture(params=["actnorm", "dual_coupling"]) -def invertible_layer(request): +def invertible_layer(request, transform): return request.getfixturevalue(request.param) @pytest.fixture() -def single_coupling(): +def single_coupling(request, transform): from bayesflow.networks.coupling_flow.couplings import SingleCoupling - return SingleCoupling() + return SingleCoupling(transform=transform) + + +@pytest.fixture(params=["affine", "spline"]) +def transform(request): + return request.param From f688454812d0f304159323be85baf27c40dac897 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Tue, 14 Jan 2025 14:49:11 +0100 Subject: [PATCH 10/38] update jacobian, jacobian trace, vjp, jvp, and corresponding usages and tests --- .../continuous_consistency_model.py | 2 +- .../flow_matching/integrators/euler.py | 2 +- .../flow_matching/integrators/runge_kutta.py | 2 +- .../integrators/runge_kutta_4.py | 2 +- bayesflow/utils/__init__.py | 8 +- bayesflow/utils/jacobian/__init__.py | 4 + bayesflow/utils/jacobian/jacobian.py | 60 +++++++++++++++ bayesflow/utils/jacobian/jacobian_trace.py | 76 +++++++++++++++++++ bayesflow/utils/jacobian/jvp.py | 43 +++++++++++ .../_vjp.py => jacobian/vjp.py} | 9 ++- bayesflow/utils/jacobian_trace/__init__.py | 1 - .../jacobian_trace/compute_jacobian_trace.py | 38 ---------- .../jacobian_trace/estimate_jacobian_trace.py | 37 --------- .../utils/jacobian_trace/jacobian_trace.py | 38 ---------- bayesflow/utils/jvp.py | 31 -------- .../test_invertible_layers.py | 35 +++------ 16 files changed, 209 insertions(+), 179 deletions(-) create mode 100644 bayesflow/utils/jacobian/__init__.py create mode 100644 bayesflow/utils/jacobian/jacobian.py create mode 100644 bayesflow/utils/jacobian/jacobian_trace.py create mode 100644 bayesflow/utils/jacobian/jvp.py rename bayesflow/utils/{jacobian_trace/_vjp.py => jacobian/vjp.py} (79%) delete mode 100644 bayesflow/utils/jacobian_trace/__init__.py delete mode 100644 bayesflow/utils/jacobian_trace/compute_jacobian_trace.py delete mode 100644 bayesflow/utils/jacobian_trace/estimate_jacobian_trace.py delete mode 100644 bayesflow/utils/jacobian_trace/jacobian_trace.py delete mode 100644 bayesflow/utils/jvp.py diff --git a/bayesflow/networks/consistency_models/continuous_consistency_model.py b/bayesflow/networks/consistency_models/continuous_consistency_model.py index 2dc319782..3436f1200 100644 --- a/bayesflow/networks/consistency_models/continuous_consistency_model.py +++ b/bayesflow/networks/consistency_models/continuous_consistency_model.py @@ -224,7 +224,7 @@ def f_teacher(x, t): ops.cos(t) * ops.sin(t) * self.sigma_data, ) - teacher_output, cos_sin_dFdt = jvp(f_teacher, primals, tangents) + teacher_output, cos_sin_dFdt = jvp(f_teacher, primals, tangents, return_output=True) teacher_output = ops.stop_gradient(teacher_output) cos_sin_dFdt = ops.stop_gradient(cos_sin_dFdt) diff --git a/bayesflow/networks/flow_matching/integrators/euler.py b/bayesflow/networks/flow_matching/integrators/euler.py index c4a3e806f..424d725ab 100644 --- a/bayesflow/networks/flow_matching/integrators/euler.py +++ b/bayesflow/networks/flow_matching/integrators/euler.py @@ -65,7 +65,7 @@ def f(arg): if density: trace = keras.ops.zeros(keras.ops.shape(x)[:-1], dtype=x.dtype) for _ in range(steps): - v, tr = jacobian_trace(f, z, kwargs.get("trace_steps", 5)) + v, tr = jacobian_trace(f, z, max_steps=kwargs.get("trace_steps", 5), return_output=True) z += dt * v trace += dt * tr t += dt diff --git a/bayesflow/networks/flow_matching/integrators/runge_kutta.py b/bayesflow/networks/flow_matching/integrators/runge_kutta.py index dc1f2e1fe..1264e5d0c 100644 --- a/bayesflow/networks/flow_matching/integrators/runge_kutta.py +++ b/bayesflow/networks/flow_matching/integrators/runge_kutta.py @@ -67,7 +67,7 @@ def f(arg): if density: trace = keras.ops.zeros(keras.ops.shape(x)[:-1], dtype=x.dtype) for _ in range(steps): - k2, tr = jacobian_trace(f, z, kwargs.get("trace_steps", 5)) + k2, tr = jacobian_trace(f, z, max_steps=kwargs.get("trace_steps", 5), return_output=True) z += dt * k2 trace += dt * tr t += dt diff --git a/bayesflow/networks/flow_matching/integrators/runge_kutta_4.py b/bayesflow/networks/flow_matching/integrators/runge_kutta_4.py index 5e88d1ad7..98ea9ee07 100644 --- a/bayesflow/networks/flow_matching/integrators/runge_kutta_4.py +++ b/bayesflow/networks/flow_matching/integrators/runge_kutta_4.py @@ -69,7 +69,7 @@ def f(arg): if density: trace = keras.ops.zeros(keras.ops.shape(x)[:-1], dtype=x.dtype) for _ in range(steps): - v4, tr = jacobian_trace(f, z, kwargs.get("trace_steps", 5)) + v4, tr = jacobian_trace(f, z, max_steps=kwargs.get("trace_steps", 5), return_output=True) z += dt * v4 trace += dt * tr t += dt diff --git a/bayesflow/utils/__init__.py b/bayesflow/utils/__init__.py index 67ce8e635..3eed7ad91 100644 --- a/bayesflow/utils/__init__.py +++ b/bayesflow/utils/__init__.py @@ -24,8 +24,12 @@ format_bytes, parse_bytes, ) -from .jacobian_trace import jacobian_trace -from .jvp import jvp +from .jacobian import ( + jacobian, + jacobian_trace, + jvp, + vjp, +) from .optimal_transport import optimal_transport from .tensor_utils import ( concatenate, diff --git a/bayesflow/utils/jacobian/__init__.py b/bayesflow/utils/jacobian/__init__.py new file mode 100644 index 000000000..54b3a8ebc --- /dev/null +++ b/bayesflow/utils/jacobian/__init__.py @@ -0,0 +1,4 @@ +from .jacobian import jacobian +from .jacobian_trace import jacobian_trace +from .jvp import jvp +from .vjp import vjp diff --git a/bayesflow/utils/jacobian/jacobian.py b/bayesflow/utils/jacobian/jacobian.py new file mode 100644 index 000000000..b11fe7a05 --- /dev/null +++ b/bayesflow/utils/jacobian/jacobian.py @@ -0,0 +1,60 @@ +from collections.abc import Callable + +import keras +import numpy as np + +from bayesflow.types import Tensor + +from .vjp import vjp + + +def jacobian(f: Callable[[Tensor], Tensor], x: Tensor, return_output: bool = False): + """ + Compute the Jacobian matrix of f with respect to x. + + :param f: The function to be differentiated. + + :param x: Tensor of shape (..., D_in) + The input tensor to f. + + :param return_output: bool + Whether to return the output of f(x) along with the Jacobian matrix. + Default: False + + :return: Tensor of shape (..., D_out, D_in) + The Jacobian matrix of f with respect to x. + + :return: 2-tuple of tensors: + 1. The output of f(x) (if return_output is True) + 2. Tensor of shape (..., D_out, D_in) + The Jacobian matrix of f with respect to x. + + """ + fx, vjp_fn = vjp(f, x, return_output=True) + + batch_shape = keras.ops.shape(x)[:-1] + batch_size = np.prod(batch_shape) + + rows = keras.ops.shape(fx)[-1] + cols = keras.ops.shape(x)[-1] + + jac = keras.ops.zeros((*batch_shape, rows, cols)) + + for col in range(cols): + projector = np.zeros(keras.ops.shape(x), dtype=keras.ops.dtype(x)) + projector[..., col] = 1.0 + projector = keras.ops.convert_to_tensor(projector) + + # jac[..., col] = vjp_fn(projector) + indices = np.stack(list(np.ndindex(batch_shape + (rows,)))) + indices = np.concatenate([indices, np.full((batch_size * rows, 1), col)], axis=1) + indices = keras.ops.convert_to_tensor(indices) + + updates = vjp_fn(projector) + updates = keras.ops.reshape(updates, (-1,)) + jac = keras.ops.scatter_update(jac, indices, updates) + + if return_output: + return fx, jac + + return jac diff --git a/bayesflow/utils/jacobian/jacobian_trace.py b/bayesflow/utils/jacobian/jacobian_trace.py new file mode 100644 index 000000000..bafffb016 --- /dev/null +++ b/bayesflow/utils/jacobian/jacobian_trace.py @@ -0,0 +1,76 @@ +from collections.abc import Callable +import keras + +from bayesflow.types import Tensor + +from .jacobian import jacobian +from .vjp import vjp + + +def jacobian_trace(f: Callable[[Tensor], Tensor], x: Tensor, max_steps: int = None, return_output: bool = False): + """Compute or estimate the trace of the Jacobian matrix of f. + + :param f: The function to be differentiated. + + :param x: Tensor of shape (n, ..., d) + The input tensor to f. + + :param max_steps: The maximum number of steps to use for the estimate. + If this does not exceed the dimensionality of f(x), use Hutchinson's algorithm to + return an unbiased estimate of the Jacobian trace. + Otherwise, perform an exact computation. + Default: None + + :param return_output: bool + Whether to return the output of f(x) along with the trace of the Jacobian. + Default: False + + :return: 2-tuple of tensors: + 1. The output of f(x) (if return_output is True) + 2. Tensor of shape (n,) + An unbiased estimate or the exact trace of the Jacobian of f. + """ + dims = keras.ops.shape(x)[-1] + + if max_steps is None or dims <= max_steps: + fx, jac = jacobian(f, x, return_output=True) + trace = keras.ops.trace(jac, axis1=-2, axis2=-1) + else: + fx, trace = _hutchinson(f, x, steps=max_steps, return_output=True) + + if return_output: + return fx, trace + + return trace + + +def _hutchinson(f: callable, x: Tensor, steps: int = 1, return_output: bool = False): + """Estimate the trace of the Jacobian matrix of f using Hutchinson's algorithm. + + :param f: The function to be differentiated. + + :param x: Tensor of shape (n,..., d) + The input tensor to f. + + :param steps: The number of steps to use for the estimate. + Higher values yield better precision. + Default: 1 + + :return: 2-tuple of tensors: + 1. The output of f(x) + 2. Tensor of shape (n,) + An unbiased estimate of the trace of the Jacobian matrix of f. + """ + shape = keras.ops.shape(x) + trace = keras.ops.zeros(shape[:-1]) + + fx, vjp_fn = vjp(f, x, return_output=True) + + for _ in range(steps): + projector = keras.random.normal(shape) + trace += keras.ops.sum(vjp_fn(projector) * projector, axis=-1) + + if return_output: + return fx, trace + + return trace diff --git a/bayesflow/utils/jacobian/jvp.py b/bayesflow/utils/jacobian/jvp.py new file mode 100644 index 000000000..dcaf08ef7 --- /dev/null +++ b/bayesflow/utils/jacobian/jvp.py @@ -0,0 +1,43 @@ +from collections.abc import Callable +import keras + +from bayesflow.types import Tensor + + +def jvp( + f: Callable, x: Tensor | tuple[Tensor, ...], tangents: Tensor | tuple[Tensor, ...], return_output: bool = False +): + """Compute the Jacobian-vector product of f at x with tangents.""" + if keras.ops.is_tensor(x): + x = (x,) + + if keras.ops.is_tensor(tangents): + tangents = (tangents,) + + match keras.backend.backend(): + case "torch": + import torch + + fx, _jvp = torch.autograd.functional.jvp(f, x, tangents) + case "tensorflow": + import tensorflow as tf + + with tf.autodiff.ForwardAccumulator(primals=x, tangents=tangents) as acc: + fx = f(*x) + + _jvp = acc.jvp(fx) + case "jax": + import jax + + fx, _jvp = jax.jvp( + f, + x, + tangents, + ) + case _: + raise NotImplementedError(f"JVP not implemented for backend {keras.backend.backend()!r}") + + if return_output: + return fx, _jvp + + return _jvp diff --git a/bayesflow/utils/jacobian_trace/_vjp.py b/bayesflow/utils/jacobian/vjp.py similarity index 79% rename from bayesflow/utils/jacobian_trace/_vjp.py rename to bayesflow/utils/jacobian/vjp.py index b7e71e494..3ae063035 100644 --- a/bayesflow/utils/jacobian_trace/_vjp.py +++ b/bayesflow/utils/jacobian/vjp.py @@ -1,9 +1,11 @@ +from collections.abc import Callable import keras from bayesflow.types import Tensor -def _make_vjp_fn(f: callable, x: Tensor) -> (Tensor, callable): +def vjp(f: Callable[[Tensor], Tensor], x: Tensor, return_output: bool = False): + """Compute the vector-Jacobian product of f at x.""" match keras.backend.backend(): case "jax": import jax @@ -35,4 +37,7 @@ def vjp_fn(projector): case other: raise NotImplementedError(f"Cannot build a vjp function for backend '{other}'.") - return fx, vjp_fn + if return_output: + return fx, vjp_fn + + return vjp_fn diff --git a/bayesflow/utils/jacobian_trace/__init__.py b/bayesflow/utils/jacobian_trace/__init__.py deleted file mode 100644 index d24dfe2a6..000000000 --- a/bayesflow/utils/jacobian_trace/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .jacobian_trace import jacobian_trace diff --git a/bayesflow/utils/jacobian_trace/compute_jacobian_trace.py b/bayesflow/utils/jacobian_trace/compute_jacobian_trace.py deleted file mode 100644 index de03baa0a..000000000 --- a/bayesflow/utils/jacobian_trace/compute_jacobian_trace.py +++ /dev/null @@ -1,38 +0,0 @@ -from collections.abc import Callable -import keras -import numpy as np - -from bayesflow.types import Tensor - - -from ._vjp import _make_vjp_fn - - -def compute_jacobian_trace(f: Callable[[Tensor], Tensor], x: Tensor) -> (Tensor, Tensor): - """Compute the exact trace of the Jacobian matrix of f by projection on each axis. - - :param f: The function to be differentiated. - - :param x: Tensor of shape (n, ..., d) - The input tensor to f. - - :return: 2-tuple of tensors: - 1. The output of f(x) - 2. Tensor of shape (n,) - The exact trace of the Jacobian matrix of f. - """ - shape = keras.ops.shape(x) - trace = keras.ops.zeros(shape[:-1]) - - fx, vjp_fn = _make_vjp_fn(f, x) - - for dim in range(shape[-1]): - projector = np.zeros(shape, dtype="float32") - projector[..., dim] = 1.0 - projector = keras.ops.convert_to_tensor(projector) - - vjp = vjp_fn(projector) - - trace += vjp[..., dim] - - return fx, trace diff --git a/bayesflow/utils/jacobian_trace/estimate_jacobian_trace.py b/bayesflow/utils/jacobian_trace/estimate_jacobian_trace.py deleted file mode 100644 index c0a867d19..000000000 --- a/bayesflow/utils/jacobian_trace/estimate_jacobian_trace.py +++ /dev/null @@ -1,37 +0,0 @@ -import keras - -from bayesflow.types import Tensor - -from ._vjp import _make_vjp_fn - - -def estimate_jacobian_trace(f: callable, x: Tensor, steps: int = 1) -> (Tensor, Tensor): - """Estimate the trace of the Jacobian matrix of f using Hutchinson's algorithm. - - :param f: The function to be differentiated. - - :param x: Tensor of shape (n,..., d) - The input tensor to f. - - :param steps: The number of steps to use for the estimate. - Higher values yield better precision. - Default: 1 - - :return: 2-tuple of tensors: - 1. The output of f(x) - 2. Tensor of shape (n,) - An unbiased estimate of the trace of the Jacobian matrix of f. - """ - shape = keras.ops.shape(x) - trace = keras.ops.zeros(shape[:-1]) - - fx, vjp_fn = _make_vjp_fn(f, x) - - for _ in range(steps): - projector = keras.random.normal(shape) - - vjp = vjp_fn(projector) - - trace += keras.ops.sum(vjp * projector, axis=-1) - - return fx, trace diff --git a/bayesflow/utils/jacobian_trace/jacobian_trace.py b/bayesflow/utils/jacobian_trace/jacobian_trace.py deleted file mode 100644 index ae699bcce..000000000 --- a/bayesflow/utils/jacobian_trace/jacobian_trace.py +++ /dev/null @@ -1,38 +0,0 @@ -from collections.abc import Callable -import keras - -from bayesflow.types import Tensor - -from .compute_jacobian_trace import compute_jacobian_trace -from .estimate_jacobian_trace import estimate_jacobian_trace - - -def jacobian_trace(f: Callable[[Tensor], Tensor], x: Tensor, max_steps: int = 1) -> (Tensor, Tensor): - """Compute or estimate the trace of the Jacobian matrix of f. - - :param f: The function to be differentiated. - - :param x: Tensor of shape (n, ..., d) - The input tensor to f. - - :param max_steps: The maximum number of steps to use for the estimate. - If this does not exceed the dimensionality of f(x), use Hutchinson's algorithm to - return an unbiased estimate of the Jacobian trace. - Otherwise, perform an exact computation. - Default: 1 - - :return: 2-tuple of tensors: - 1. The output of f(x) - 2. Tensor of shape (n,) - An unbiased estimate or the exact trace of the Jacobian of f. - """ - dims = keras.ops.shape(x)[-1] - - if max_steps is None or dims <= max_steps: - # use the exact version - fx, trace = compute_jacobian_trace(f, x) - else: - # use an estimate with the maximum number of steps - fx, trace = estimate_jacobian_trace(f, x, max_steps) - - return fx, trace diff --git a/bayesflow/utils/jvp.py b/bayesflow/utils/jvp.py deleted file mode 100644 index fbc670082..000000000 --- a/bayesflow/utils/jvp.py +++ /dev/null @@ -1,31 +0,0 @@ -import keras - -from bayesflow.types import Tensor - - -def jvp(fn: callable, primals: tuple[Tensor] | Tensor, tangents: tuple[Tensor] | Tensor): - """Compute the dot product between the Jacobian of the given function at the point given by - the input (primals) and vectors in tangents.""" - - match keras.backend.backend(): - case "torch": - import torch - - fn_output, _jvp = torch.autograd.functional.jvp(fn, primals, tangents) - case "tensorflow": - import tensorflow as tf - - with tf.autodiff.ForwardAccumulator(primals=primals, tangents=tangents) as acc: - fn_output = fn(*primals) - _jvp = acc.jvp(fn_output) - case "jax": - import jax - - fn_output, _jvp = jax.jvp( - fn, - primals, - tangents, - ) - case _: - raise NotImplementedError(f"JVP not implemented for backend {keras.backend.backend()!r}") - return fn_output, _jvp diff --git a/tests/test_networks/test_coupling_flow/test_invertible_layers.py b/tests/test_networks/test_coupling_flow/test_invertible_layers.py index 2c422964c..2d7f04cdd 100644 --- a/tests/test_networks/test_coupling_flow/test_invertible_layers.py +++ b/tests/test_networks/test_coupling_flow/test_invertible_layers.py @@ -1,10 +1,7 @@ -import functools - import keras import numpy as np -import pytest -from tests.utils import allclose, assert_allclose +from tests.utils import assert_allclose def test_build(invertible_layer, random_samples, random_conditions): @@ -61,35 +58,21 @@ def test_cycle_consistency(invertible_layer, random_samples, random_conditions): assert_allclose(forward_log_det, -inverse_log_det, atol=1e-6, msg="Log Determinants are not cycle consistent") -@pytest.mark.torch def test_jacobian_numerically(invertible_layer, random_samples, random_conditions): - import torch + from bayesflow.utils import jacobian forward_output, forward_log_det = invertible_layer(random_samples) - numerical_forward_jacobian, *_ = torch.autograd.functional.jacobian( - invertible_layer, random_samples, vectorize=True - ) - # TODO: torch is somehow permuted wrt keras - numerical_forward_log_det = [ - keras.ops.log(keras.ops.abs(keras.ops.det(numerical_forward_jacobian[i, :, i, :]))) - for i in range(keras.ops.shape(random_samples)[0]) - ] - numerical_forward_log_det = keras.ops.stack(numerical_forward_log_det, axis=0) + numerical_forward_jacobian = jacobian(lambda x: invertible_layer(x)[0], random_samples) + + numerical_forward_log_det = keras.ops.logdet(numerical_forward_jacobian) - assert allclose(forward_log_det, numerical_forward_log_det, rtol=1e-4, atol=1e-5) + assert_allclose(forward_log_det, numerical_forward_log_det, rtol=1e-4, atol=1e-5) inverse_output, inverse_log_det = invertible_layer(random_samples, inverse=True) - numerical_inverse_jacobian, *_ = torch.autograd.functional.jacobian( - functools.partial(invertible_layer, inverse=True), random_samples, vectorize=True - ) + numerical_inverse_jacobian = jacobian(lambda z: invertible_layer(z, inverse=True)[0], random_samples) - # TODO: torch is somehow permuted wrt keras - numerical_inverse_log_det = [ - keras.ops.log(keras.ops.abs(keras.ops.det(numerical_inverse_jacobian[i, :, i, :]))) - for i in range(keras.ops.shape(random_samples)[0]) - ] - numerical_inverse_log_det = keras.ops.stack(numerical_inverse_log_det, axis=0) + numerical_inverse_log_det = keras.ops.logdet(numerical_inverse_jacobian) - assert allclose(inverse_log_det, numerical_inverse_log_det, rtol=1e-4, atol=1e-5) + assert_allclose(inverse_log_det, numerical_inverse_log_det, rtol=1e-4, atol=1e-5) From 91ad5317d438d212956cd52f847c666f32860f62 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Tue, 14 Jan 2025 15:15:10 +0100 Subject: [PATCH 11/38] fix imports, remove old jacobian and jvp, fix application in free form flow --- .../networks/free_form_flow/free_form_flow.py | 23 ++-- bayesflow/utils/jacobian.py | 129 ------------------ bayesflow/utils/vjp.py | 42 ------ 3 files changed, 10 insertions(+), 184 deletions(-) delete mode 100644 bayesflow/utils/jacobian.py delete mode 100644 bayesflow/utils/vjp.py diff --git a/bayesflow/networks/free_form_flow/free_form_flow.py b/bayesflow/networks/free_form_flow/free_form_flow.py index 23c375c1f..ed44bb8a6 100644 --- a/bayesflow/networks/free_form_flow/free_form_flow.py +++ b/bayesflow/networks/free_form_flow/free_form_flow.py @@ -7,7 +7,7 @@ find_network, keras_kwargs, concatenate, - log_jacobian_determinant, + jacobian, jvp, vjp, serialize_value_or_type, @@ -119,12 +119,10 @@ def _forward( self, x: Tensor, conditions: Tensor = None, density: bool = False, training: bool = False, **kwargs ) -> Tensor | tuple[Tensor, Tensor]: if density: - if conditions is None: - # None cannot be batched, so supply as keyword argument - z, log_det = log_jacobian_determinant(x, self.encode, conditions=None, training=training, **kwargs) - else: - # conditions should be batched, supply as positional argument - z, log_det = log_jacobian_determinant(x, self.encode, conditions, training=training, **kwargs) + z, jac = jacobian( + lambda inp: self.encode(inp, conditions=conditions, training=training, **kwargs), x, return_output=True + ) + log_det = keras.ops.log(keras.ops.abs(keras.ops.det(jac))) log_density = self.base_distribution.log_prob(z) + log_det return z, log_density @@ -136,12 +134,11 @@ def _inverse( self, z: Tensor, conditions: Tensor = None, density: bool = False, training: bool = False, **kwargs ) -> Tensor | tuple[Tensor, Tensor]: if density: - if conditions is None: - # None cannot be batched, so supply as keyword argument - x, log_det = log_jacobian_determinant(z, self.decode, conditions=None, training=training, **kwargs) - else: - # conditions should be batched, supply as positional argument - x, log_det = log_jacobian_determinant(z, self.decode, conditions, training=training, **kwargs) + x, jac = jacobian( + lambda inp: self.decode(inp, conditions=conditions, training=training, **kwargs), z, return_output=True + ) + log_det = keras.ops.log(keras.ops.abs(keras.ops.det(jac))) + log_density = self.base_distribution.log_prob(z) - log_det return x, log_density diff --git a/bayesflow/utils/jacobian.py b/bayesflow/utils/jacobian.py deleted file mode 100644 index 830ef6e01..000000000 --- a/bayesflow/utils/jacobian.py +++ /dev/null @@ -1,129 +0,0 @@ -from collections.abc import Callable -import keras -from keras import ops -from bayesflow.types import Tensor - -from functools import partial, wraps - - -def compute_jacobian( - x_in: Tensor, - fn: Callable, - *func_args: any, - grad_type: str = "backward", - **func_kwargs: any, -) -> tuple[Tensor, Tensor]: - """Computes the Jacobian of a function with respect to its input. - - :param x_in: The input tensor to compute the jacobian at. - Shape: (batch_size, in_dim). - :param fn: The function to compute the jacobian of, which transforms - `x` to `fn(x)` of shape (batch_size, out_dim). - :param func_args: The positional arguments to pass to the function. - func_args are batched over the first dimension. - :param grad_type: The type of gradient to use. Either 'backward' or - 'forward'. - :param func_kwargs: The keyword arguments to pass to the function. - func_kwargs are not batched. - :return: The output of the function `fn(x)` and the jacobian - of the function with respect to its input `x` of shape - (batch_size, out_dim, in_dim).""" - - def batch_wrap(fn: Callable) -> Callable: - """Add a batch dimension to each tensor argument. - - :param fn: - :return: wrapped function""" - - def deep_unsqueeze(arg): - if ops.is_tensor(arg): - return arg[None, ...] - elif isinstance(arg, dict): - return {key: deep_unsqueeze(value) for key, value in arg.items()} - elif isinstance(arg, (list, tuple)): - return [deep_unsqueeze(value) for value in arg] - raise ValueError(f"Argument cannot be batched: {arg}") - - @wraps(fn) - def wrapper(*args, **kwargs): - args = deep_unsqueeze(args) - return fn(*args, **kwargs)[0] - - return wrapper - - def double_output(fn): - @wraps(fn) - def wrapper(*args, **kwargs): - out = fn(*args, **kwargs) - return out, out - - return wrapper - - match keras.backend.backend(): - case "torch": - import torch - from torch.func import jacrev, jacfwd, vmap - - jacfn = jacrev if grad_type == "backward" else jacfwd - with torch.inference_mode(False): - with torch.no_grad(): - fn_kwargs_prefilled = partial(fn, **func_kwargs) - fn_batch_expanded = batch_wrap(fn_kwargs_prefilled) - fn_return_val = double_output(fn_batch_expanded) - fn_jac_batched = vmap(jacfn(fn_return_val, has_aux=True)) - jac, x_out = fn_jac_batched(x_in, *func_args) - case "jax": - from jax import jacrev, jacfwd, vmap - - jacfn = jacrev if grad_type == "backward" else jacfwd - fn_kwargs_prefilled = partial(fn, **func_kwargs) - fn_batch_expanded = batch_wrap(fn_kwargs_prefilled) - fn_return_val = double_output(fn_batch_expanded) - fn_jac_batched = vmap(jacfn(fn_return_val, has_aux=True)) - jac, x_out = fn_jac_batched(x_in, *func_args) - case "tensorflow": - if grad_type == "forward": - raise NotImplementedError("For TensorFlow, only backward mode Jacobian computation is available.") - import tensorflow as tf - - with tf.GradientTape() as tape: - tape.watch(x_in) - x_out = fn(x_in, *func_args, **func_kwargs) - jac = tape.batch_jacobian(x_out, x_in) - - case _: - raise NotImplementedError(f"compute_jacobian not implemented for {keras.backend.backend()}.") - return x_out, jac - - -def log_jacobian_determinant( - x_in: Tensor, - fn: Callable, - *func_args: any, - grad_type: str = "backward", - **func_kwargs: any, -) -> tuple[Tensor, Tensor]: - """Computes the log Jacobian determinant of a function - with respect to its input. - - :param x_in: The input tensor to compute the jacobian at. - Shape: (batch_size, in_dim). - :param fn: The function to compute the jacobian of, which transforms - `x` to `fn(x)` of shape (batch_size, out_dim). - :param func_args: The positional arguments to pass to the function. - func_args are batched over the first dimension. - :param grad_type: The type of gradient to use. Either 'backward' or - 'forward'. - :param func_kwargs: The keyword arguments to pass to the function. - func_kwargs are not batched. - :return: The output of the function `fn(x)` and the log jacobian determinant - of the function with respect to its input `x` of shape - (batch_size, out_dim, in_dim).""" - - x_out, jac = compute_jacobian(x_in, fn, *func_args, grad_type=grad_type, **func_kwargs) - jac = ops.reshape( - jac, (ops.shape(x_in)[0], ops.prod(list(ops.shape(x_out)[1:])), ops.prod(list(ops.shape(x_in)[1:]))) - ) - log_det = ops.slogdet(jac)[1] - - return x_out, log_det diff --git a/bayesflow/utils/vjp.py b/bayesflow/utils/vjp.py deleted file mode 100644 index 435c46334..000000000 --- a/bayesflow/utils/vjp.py +++ /dev/null @@ -1,42 +0,0 @@ -from collections.abc import Callable -import keras -from functools import partial - -from bayesflow.types import Tensor - - -def vjp(fn: Callable, *primals: Tensor) -> (any, Callable[[Tensor], tuple[Tensor, ...]]): - """ - Backend-agnostic version of the vector-Jacobian product (vjp). - Computes the vector-Jacobian product of the given function at the point given by the input (primals). - - :param fn: The function to differentiate. - Signature and return value must be compatible with the vjp method of the backend in use. - - :param primals: Input tensors to `fn`. - - :return: The output of `fn(*primals)` and a vjp function. - The vjp function takes a single tensor argument, and returns the vector-Jacobian product of this argument with - `fn` as evaluated at `primals`. - """ - match keras.backend.backend(): - case "jax": - import jax - - fx, vjp_fn = jax.vjp(fn, *primals) - case "torch": - import torch - - fx, vjp_fn = torch.func.vjp(fn, *primals) - case "tensorflow": - import tensorflow as tf - - with tf.GradientTape(persistent=True) as tape: - for p in primals: - tape.watch(p) - fx = fn(*primals) - vjp_fn = partial(tape.gradient, fx, primals) - case _: - raise NotImplementedError(f"VJP not implemented for backend {keras.backend.backend()}") - - return fx, vjp_fn From 47e28aac15f30c0a934f2acba51f4c77e4e47275 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Tue, 14 Jan 2025 16:34:21 +0100 Subject: [PATCH 12/38] improve logdet computation in free form flows --- bayesflow/networks/free_form_flow/free_form_flow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bayesflow/networks/free_form_flow/free_form_flow.py b/bayesflow/networks/free_form_flow/free_form_flow.py index ed44bb8a6..fd5ca180a 100644 --- a/bayesflow/networks/free_form_flow/free_form_flow.py +++ b/bayesflow/networks/free_form_flow/free_form_flow.py @@ -122,7 +122,7 @@ def _forward( z, jac = jacobian( lambda inp: self.encode(inp, conditions=conditions, training=training, **kwargs), x, return_output=True ) - log_det = keras.ops.log(keras.ops.abs(keras.ops.det(jac))) + log_det = keras.ops.logdet(jac) log_density = self.base_distribution.log_prob(z) + log_det return z, log_density @@ -137,7 +137,7 @@ def _inverse( x, jac = jacobian( lambda inp: self.decode(inp, conditions=conditions, training=training, **kwargs), z, return_output=True ) - log_det = keras.ops.log(keras.ops.abs(keras.ops.det(jac))) + log_det = keras.ops.logdet(jac) log_density = self.base_distribution.log_prob(z) - log_det return x, log_density From c3e72d9ad66321cfe0bd20fe51607ad56da8ee51 Mon Sep 17 00:00:00 2001 From: stefanradev93 Date: Fri, 17 Jan 2025 19:50:14 -0500 Subject: [PATCH 13/38] Fix comparison for symbolic tensors under tf --- bayesflow/utils/tensor_utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bayesflow/utils/tensor_utils.py b/bayesflow/utils/tensor_utils.py index 6cea1f43d..80b10a32f 100644 --- a/bayesflow/utils/tensor_utils.py +++ b/bayesflow/utils/tensor_utils.py @@ -186,9 +186,8 @@ def searchsorted(sorted_sequence: Tensor, values: Tensor, side: str = "left") -> case "tensorflow": import tensorflow as tf - out_type = "int32" if len(sorted_sequence) <= np.iinfo(np.int32).max else "int64" - - indices = tf.searchsorted(sorted_sequence, values, side=side, out_type=out_type) + # always use int64 to avoid complicated graph code + indices = tf.searchsorted(sorted_sequence, values, side=side, out_type="int64") return indices case "torch": From f4d41a9fc1108ea4f722ab541108bef932245be6 Mon Sep 17 00:00:00 2001 From: stefanradev93 Date: Fri, 17 Jan 2025 20:01:50 -0500 Subject: [PATCH 14/38] Add splines to twomoons notebook --- .../transforms/spline_transform.py | 1 - examples/TwoMoons_StarterNotebook.ipynb | 65 ++++++++++++++++++- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 356dbf674..077f5a55a 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -70,7 +70,6 @@ def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tenso vertical_edges = bottom_edge + keras.ops.cumsum(bin_heights, axis=-1) derivatives = shifted_softplus(parameters["derivatives"]) - # derivatives = pad(derivatives, 0.0, 1, axis=-1) derivatives = keras.ops.concatenate([affine_scale, derivatives, affine_scale], axis=-1) constrained_parameters = { diff --git a/examples/TwoMoons_StarterNotebook.ipynb b/examples/TwoMoons_StarterNotebook.ipynb index d9b1b653f..ae41b77b4 100644 --- a/examples/TwoMoons_StarterNotebook.ipynb +++ b/examples/TwoMoons_StarterNotebook.ipynb @@ -382,7 +382,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 11, "id": "09206e6f", "metadata": { "ExecuteTime": { @@ -868,6 +868,65 @@ ")" ] }, + { + "cell_type": "markdown", + "id": "056d3cf2", + "metadata": {}, + "source": [ + "## Going Splines" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "6ae7ba3b", + "metadata": {}, + "outputs": [], + "source": [ + "inference_network = bf.networks.CouplingFlow(\n", + " subnet=\"mlp\", \n", + " coupling_kwargs={\"subnet_kwargs\": {\"dropout\": 0.0}},\n", + " transform=\"spline\"\n", + ")\n", + "\n", + "spline_approximator = bf.ContinuousApproximator(inference_network=inference_network, adapter=adapter)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "174d8e65", + "metadata": {}, + "outputs": [], + "source": [ + "initial_learning_rate = 5e-4\n", + "scheduled_lr = keras.optimizers.schedules.CosineDecay(\n", + " initial_learning_rate=initial_learning_rate,\n", + " decay_steps=total_steps,\n", + " alpha=1e-8\n", + ")\n", + "\n", + "optimizer = keras.optimizers.AdamW(learning_rate=scheduled_lr, clipnorm=1.0)\n", + "\n", + "\n", + "spline_approximator.compile(optimizer=optimizer)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "318b8420", + "metadata": {}, + "outputs": [], + "source": [ + "# DOES NOT CURRENTLY WORK\n", + "spline_history = spline_approximator.fit(\n", + " epochs=epochs,\n", + " dataset=training_dataset,\n", + " validation_data=validation_dataset,\n", + ")" + ] + }, { "cell_type": "markdown", "id": "f6ffbb96", @@ -964,7 +1023,7 @@ ], "metadata": { "kernelspec": { - "display_name": "bf2", + "display_name": "bf", "language": "python", "name": "python3" }, @@ -978,7 +1037,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.11.5" }, "toc": { "base_numbering": 1, From 12a80f8fc99ef802797629fc7ecf1a8fbd58c7db Mon Sep 17 00:00:00 2001 From: larskue Date: Mon, 20 Jan 2025 12:15:42 +0100 Subject: [PATCH 15/38] improve pad utility --- bayesflow/utils/tensor_utils.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/bayesflow/utils/tensor_utils.py b/bayesflow/utils/tensor_utils.py index 80b10a32f..563b6fcbb 100644 --- a/bayesflow/utils/tensor_utils.py +++ b/bayesflow/utils/tensor_utils.py @@ -58,14 +58,29 @@ def expand_tile(x: Tensor, n: int, axis: int) -> Tensor: return tile_axis(x, n, axis=axis) -def pad(x: Tensor, value: float, n: int, axis: int) -> Tensor: - """Pad x with n values along axis""" +def pad(x: Tensor, value: float | Tensor, n: int, axis: int, side: str = "both") -> Tensor: + """ + Pad x with n values along axis on the given side. + The pad value must broadcast against the shape of x, except for the pad axis, where it must broadcast against n. + """ + if not keras.ops.is_tensor(value): + value = keras.ops.full((), value, dtype=keras.ops.dtype(x)) + shape = list(keras.ops.shape(x)) shape[axis] = n - p = keras.ops.full(shape, value, dtype=keras.ops.dtype(x)) - xp = keras.ops.concatenate([p, x, p], axis=axis) - return xp + p = keras.ops.broadcast_to(value, shape) + match side: + case "left": + return keras.ops.concatenate([p, x], axis=axis) + case "right": + return keras.ops.concatenate([x, p], axis=axis) + case "both": + return keras.ops.concatenate([p, x, p], axis=axis) + case str() as name: + raise ValueError(f"Invalid side {name!r}. Must be 'left', 'right', or 'both'.") + case _: + raise TypeError(f"Invalid side type {type(side)!r}. Must be str.") def size_of(x) -> int: From 4861dfa1dea2569f940496fc1f6a871376a99e81 Mon Sep 17 00:00:00 2001 From: larskue Date: Mon, 20 Jan 2025 12:16:08 +0100 Subject: [PATCH 16/38] fix missing left edge in spline --- .../transforms/spline_transform.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 077f5a55a..cb9d8ce66 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -4,11 +4,10 @@ ) from bayesflow.types import Tensor -from bayesflow.utils import searchsorted +from bayesflow.utils import pad, searchsorted from bayesflow.utils.keras_utils import shifted_softplus - -from .transform import Transform from ._rational_quadratic import _rational_quadratic_spline +from .transform import Transform @serializable(package="networks.coupling_flow") @@ -63,14 +62,22 @@ def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tenso bin_widths = self.default_bin_width * shifted_softplus(parameters["bin_widths"]) bin_heights = self.default_bin_height * shifted_softplus(parameters["bin_heights"]) - affine_scale = keras.ops.sum(bin_widths, axis=-1, keepdims=True) + total_width = keras.ops.sum(bin_widths, axis=-1, keepdims=True) + total_height = keras.ops.sum(bin_heights, axis=-1, keepdims=True) + + affine_scale = total_height / total_width affine_shift = bottom_edge - affine_scale * left_edge - horizontal_edges = left_edge + keras.ops.cumsum(bin_widths, axis=-1) - vertical_edges = bottom_edge + keras.ops.cumsum(bin_heights, axis=-1) + horizontal_edges = keras.ops.cumsum(bin_widths, axis=-1) + horizontal_edges = pad(horizontal_edges, 0.0, 1, axis=-1, side="left") + horizontal_edges = left_edge + horizontal_edges + + vertical_edges = keras.ops.cumsum(bin_heights, axis=-1) + vertical_edges = pad(vertical_edges, 0.0, 1, axis=-1, side="left") + vertical_edges = bottom_edge + vertical_edges derivatives = shifted_softplus(parameters["derivatives"]) - derivatives = keras.ops.concatenate([affine_scale, derivatives, affine_scale], axis=-1) + derivatives = pad(derivatives, affine_scale, 1, axis=-1, side="both") constrained_parameters = { "horizontal_edges": horizontal_edges, From e59055a3a901b314f7625b86c4a4214afc0c2e8b Mon Sep 17 00:00:00 2001 From: larskue Date: Mon, 20 Jan 2025 17:33:01 +0100 Subject: [PATCH 17/38] fix inside mask edge case --- .../networks/coupling_flow/transforms/spline_transform.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index cb9d8ce66..5d7a44762 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -94,7 +94,7 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) # parameters.shape == ([B, ...], bins) bins = searchsorted(parameters["horizontal_edges"], x) - inside = (bins > 0) & (bins <= self.bins) + inside = (bins > 0) & (bins < self.bins) inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) # first compute affine transform on everything @@ -128,7 +128,7 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): bins = searchsorted(parameters["vertical_edges"], z) - inside = (bins > 0) & (bins <= self.bins) + inside = (bins > 0) & (bins < self.bins) inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) # first compute affine transform on everything @@ -138,7 +138,6 @@ def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) log_jac = keras.ops.broadcast_to(-keras.ops.log(scale), keras.ops.shape(x)) # overwrite inside part with spline - upper = bins[inside] lower = upper - 1 From 8a4c2dddd9976b2e352bf4c949b08f0568ac1948 Mon Sep 17 00:00:00 2001 From: larskue Date: Tue, 21 Jan 2025 13:56:41 +0100 Subject: [PATCH 18/38] explicitly set bias initializer --- bayesflow/networks/coupling_flow/couplings/single_coupling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bayesflow/networks/coupling_flow/couplings/single_coupling.py b/bayesflow/networks/coupling_flow/couplings/single_coupling.py index f4fba7cb1..eb7f65659 100644 --- a/bayesflow/networks/coupling_flow/couplings/single_coupling.py +++ b/bayesflow/networks/coupling_flow/couplings/single_coupling.py @@ -1,5 +1,4 @@ import keras - from keras.saving import register_keras_serializable as serializable from bayesflow.types import Tensor @@ -24,6 +23,7 @@ def __init__(self, subnet: str | type = "mlp", transform: str = "affine", **kwar output_projector_kwargs = kwargs.get("output_projector_kwargs", {}) output_projector_kwargs.setdefault("kernel_initializer", "zeros") + output_projector_kwargs.setdefault("bias_initializer", "zeros") self.output_projector = keras.layers.Dense(units=None, **output_projector_kwargs) # serialization: store all parameters necessary to call __init__ From a1ce42e6161aace206b5db83a3e3cc21eaeed6fb Mon Sep 17 00:00:00 2001 From: larskue Date: Tue, 21 Jan 2025 14:01:42 +0100 Subject: [PATCH 19/38] add better expand utility --- bayesflow/utils/__init__.py | 25 ++++++++++++++----------- bayesflow/utils/tensor_utils.py | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/bayesflow/utils/__init__.py b/bayesflow/utils/__init__.py index b2dc5dc50..d86827899 100644 --- a/bayesflow/utils/__init__.py +++ b/bayesflow/utils/__init__.py @@ -3,6 +3,8 @@ logging, numpy_utils, ) +from .callbacks import detailed_loss_callback +from .comp_utils import expected_calibration_error from .dict_utils import ( convert_args, convert_kwargs, @@ -31,10 +33,21 @@ jvp, vjp, ) -from .serialization import serialize_value_or_type, deserialize_value_or_type from .optimal_transport import optimal_transport +from .plot_utils import ( + check_posterior_prior_shapes, + prepare_plot_data, + add_titles_and_labels, + prettify_subplots, + make_quadratic, + add_metric, +) +from .serialization import serialize_value_or_type, deserialize_value_or_type from .tensor_utils import ( concatenate, + expand, + expand_as, + expand_to, expand_left, expand_left_as, expand_left_to, @@ -50,14 +63,4 @@ searchsorted, ) from .validators import check_lengths_same -from .comp_utils import expected_calibration_error -from .plot_utils import ( - check_posterior_prior_shapes, - prepare_plot_data, - add_titles_and_labels, - prettify_subplots, - make_quadratic, - add_metric, -) -from .callbacks import detailed_loss_callback from .workflow_utils import find_inference_network, find_summary_network diff --git a/bayesflow/utils/tensor_utils.py b/bayesflow/utils/tensor_utils.py index 563b6fcbb..597c08650 100644 --- a/bayesflow/utils/tensor_utils.py +++ b/bayesflow/utils/tensor_utils.py @@ -10,6 +10,31 @@ T = TypeVar("T") +def expand(x: Tensor, n: int, side: str): + if n < 0: + raise ValueError(f"Cannot expand {n} times.") + + match side: + case "left": + idx = [None] * n + [...] + case "right": + idx = [...] + [None] * n + case str() as name: + raise ValueError(f"Invalid side {name!r}. Must be 'left' or 'right'.") + case other: + raise TypeError(f"Invalid side type {type(other)!r}. Must be str.") + + return x[tuple(idx)] + + +def expand_as(x: Tensor, y: Tensor, side: str): + return expand_to(x, keras.ops.ndim(y), side) + + +def expand_to(x: Tensor, dim: int, side: str): + return expand(x, dim - keras.ops.ndim(x), side) + + def expand_left(x: Tensor, n: int) -> Tensor: """Expand x to the left n times""" if n < 0: From 6861cdbd0f0014708699d0e3904725066dc34bbf Mon Sep 17 00:00:00 2001 From: larskue Date: Tue, 21 Jan 2025 14:02:00 +0100 Subject: [PATCH 20/38] small clean up, renaming --- .../coupling_flow/transforms/_rational_quadratic.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py b/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py index dffbe9a61..980afb88f 100644 --- a/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py +++ b/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py @@ -1,6 +1,7 @@ -import keras from typing import TypedDict +import keras + from bayesflow.types import Tensor @@ -50,9 +51,11 @@ def _rational_quadratic_spline( # Eq. 4 in the paper numerator = dy * (sk * xi**2 + dk * xi * (1 - xi)) denominator = sk + (dkp + dk - 2 * sk) * xi * (1 - xi) - out = yk + numerator / denominator + result = yk + numerator / denominator else: + # rename for clarity y = x + # Eq. 6-8 in the paper a = dy * (sk - dk) + (y - yk) * (dkp + dk - 2 * sk) b = dy * dk - (y - yk) * (dkp + dk - 2 * sk) @@ -64,12 +67,11 @@ def _rational_quadratic_spline( raise ValueError("Discriminant must be non-negative.") xi = 2 * c / (-b - keras.ops.sqrt(discriminant)) - - out = xi * dx + xk + result = xi * dx + xk # Eq 5 in the paper numerator = sk**2 * (dkp * xi**2 + 2 * sk * xi * (1 - xi) + dk * (1 - xi) ** 2) denominator = (sk + (dkp + dk - 2 * sk) * xi * (1 - xi)) ** 2 log_jac = keras.ops.log(numerator) - keras.ops.log(denominator) - return out, log_jac + return result, log_jac From 577a44ef13b793b2eaf9ce3c453e9f31b3a66060 Mon Sep 17 00:00:00 2001 From: larskue Date: Tue, 21 Jan 2025 14:02:57 +0100 Subject: [PATCH 21/38] fix indexing, fix inside check --- .../transforms/spline_transform.py | 106 ++++++++++++++---- 1 file changed, 84 insertions(+), 22 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 5d7a44762..b07ab1f8f 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -1,10 +1,11 @@ import keras +import numpy as np from keras.saving import ( register_keras_serializable as serializable, ) from bayesflow.types import Tensor -from bayesflow.utils import pad, searchsorted +from bayesflow.utils import expand_as, pad, searchsorted from bayesflow.utils.keras_utils import shifted_softplus from ._rational_quadratic import _rational_quadratic_spline from .transform import Transform @@ -15,19 +16,31 @@ class SplineTransform(Transform): def __init__( self, bins: int = 16, - default_domain: (float, float, float, float) = (-5.0, 5.0, -5.0, 5.0), + default_domain: (float, float, float, float) = (-3.0, 3.0, -3.0, 3.0), + min_width: float = 1.0, + min_height: float = 1.0, + min_bin_width: float = 0.1, + min_bin_height: float = 0.1, method: str = "rational_quadratic", ): super().__init__() self.bins = bins + self.min_width = max(min_width, bins * min_bin_width) + self.min_height = max(min_height, bins * min_bin_height) + self.min_bin_width = min_bin_width + self.min_bin_height = min_bin_height self.method = method if self.method != "rational_quadratic": raise NotImplementedError("Currently, only 'rational_quadratic' spline method is supported.") + # we slightly over-parametrize to allow for better constraints + # this may also improve convergence due to redundancy self.parameter_sizes = { "left_edge": 1, "bottom_edge": 1, + "total_width": 1, + "total_height": 1, "bin_widths": self.bins, "bin_heights": self.bins, "derivatives": self.bins - 1, @@ -38,8 +51,16 @@ def __init__( self.default_left = default_domain[0] self.default_bottom = default_domain[2] - self.default_bin_width = (default_domain[1] - default_domain[0]) / self.bins - self.default_bin_height = (default_domain[3] - default_domain[2]) / self.bins + self.default_width = default_domain[1] - default_domain[0] + self.default_height = default_domain[3] - default_domain[2] + + if self.default_width < self.min_width: + raise ValueError(f"Default width must be greater than minimum width ({self.min_width}).") + + if self.default_height < self.min_height: + raise ValueError(f"Default height must be greater than minimum height ({self.min_height}).") + + self._shift = np.sinh(1.0) * np.log(np.e - 1.0) @property def params_per_dim(self) -> int: @@ -59,13 +80,26 @@ def split_parameters(self, parameters: Tensor) -> dict[str, Tensor]: def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tensor]: left_edge = parameters["left_edge"] + self.default_left bottom_edge = parameters["bottom_edge"] + self.default_bottom - bin_widths = self.default_bin_width * shifted_softplus(parameters["bin_widths"]) - bin_heights = self.default_bin_height * shifted_softplus(parameters["bin_heights"]) - total_width = keras.ops.sum(bin_widths, axis=-1, keepdims=True) - total_height = keras.ops.sum(bin_heights, axis=-1, keepdims=True) + # strictly positive (softplus) + # scales logarithmically to infinity (arcsinh) + # 1 when network outputs 0 (shift) + total_width = keras.ops.arcsinh(keras.ops.softplus(parameters["total_width"] + self._shift)) + total_width = (self.default_width - self.min_width) * total_width + self.min_width + total_height = keras.ops.arcsinh(keras.ops.softplus(parameters["total_height"] + self._shift)) + total_height = (self.default_height - self.min_height) * total_height + self.min_height + + bin_widths = (total_width - self.bins * self.min_bin_width) * keras.ops.softmax( + parameters["bin_widths"], axis=-1 + ) + self.min_bin_width + bin_heights = (total_height - self.bins * self.min_bin_height) * keras.ops.softmax( + parameters["bin_heights"], axis=-1 + ) + self.min_bin_height + + # dy / dx affine_scale = total_height / total_width + # y = a * x + b -> b = y - a * x affine_shift = bottom_edge - affine_scale * left_edge horizontal_edges = keras.ops.cumsum(bin_widths, axis=-1) @@ -94,7 +128,9 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) # parameters.shape == ([B, ...], bins) bins = searchsorted(parameters["horizontal_edges"], x) - inside = (bins > 0) & (bins < self.bins) + # inside check is right-inclusive because searchsorted is right-inclusive + inside = (bins > 0) & (bins <= self.bins) + # inside_indices.shape == (n_inside, ndim(x)) inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) # first compute affine transform on everything @@ -105,18 +141,29 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) # overwrite inside part with spline upper = bins[inside] + upper = expand_as(upper, parameters["horizontal_edges"], side="right") + lower = upper - 1 + # select batch elements that are inside + parameters_inside = {key: value[inside_indices[:, :-1]] for key, value in parameters.items()} + parameters_inside = {key: keras.ops.squeeze(value, axis=1) for key, value in parameters_inside.items()} + + # select bin parameters for inside elements edges = { - "left": keras.ops.take_along_axis(parameters["horizontal_edges"], lower, axis=None), - "right": keras.ops.take_along_axis(parameters["horizontal_edges"], upper, axis=None), - "bottom": keras.ops.take_along_axis(parameters["vertical_edges"], lower, axis=None), - "top": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=None), + "left": keras.ops.take_along_axis(parameters_inside["horizontal_edges"], lower, axis=-1), + "right": keras.ops.take_along_axis(parameters_inside["horizontal_edges"], upper, axis=-1), + "bottom": keras.ops.take_along_axis(parameters_inside["vertical_edges"], lower, axis=-1), + "top": keras.ops.take_along_axis(parameters_inside["vertical_edges"], upper, axis=-1), } + edges = {key: keras.ops.squeeze(value, axis=-1) for key, value in edges.items()} derivatives = { - "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=None), - "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=None), + "left": keras.ops.take_along_axis(parameters_inside["derivatives"], lower, axis=-1), + "right": keras.ops.take_along_axis(parameters_inside["derivatives"], upper, axis=-1), } + derivatives = {key: keras.ops.squeeze(value, axis=-1) for key, value in derivatives.items()} + + # compute spline and jacobian spline, jac = _rational_quadratic_spline(x[inside], edges=edges, derivatives=derivatives) z = keras.ops.scatter_update(z, inside_indices, spline) log_jac = keras.ops.scatter_update(log_jac, inside_indices, jac) @@ -126,9 +173,13 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) return z, log_det def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): + # z.shape == ([B, ...], D) + # parameters.shape == ([B, ...], bins) bins = searchsorted(parameters["vertical_edges"], z) - inside = (bins > 0) & (bins < self.bins) + # inside check is right-inclusive because searchsorted is right-inclusive + inside = (bins > 0) & (bins <= self.bins) + # inside_indices.shape == (n_inside, ndim(x)) inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) # first compute affine transform on everything @@ -139,18 +190,29 @@ def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) # overwrite inside part with spline upper = bins[inside] + upper = expand_as(upper, parameters["horizontal_edges"], side="right") + lower = upper - 1 + # select batch elements that are inside + parameters_inside = {key: value[inside_indices[:, :-1]] for key, value in parameters.items()} + parameters_inside = {key: keras.ops.squeeze(value, axis=1) for key, value in parameters_inside.items()} + + # select bin parameters for inside elements edges = { - "left": keras.ops.take_along_axis(parameters["vertical_edges"], lower, axis=None), - "right": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=None), - "bottom": keras.ops.take_along_axis(parameters["horizontal_edges"], lower, axis=None), - "top": keras.ops.take_along_axis(parameters["horizontal_edges"], upper, axis=None), + "left": keras.ops.take_along_axis(parameters_inside["horizontal_edges"], lower, axis=-1), + "right": keras.ops.take_along_axis(parameters_inside["horizontal_edges"], upper, axis=-1), + "bottom": keras.ops.take_along_axis(parameters_inside["vertical_edges"], lower, axis=-1), + "top": keras.ops.take_along_axis(parameters_inside["vertical_edges"], upper, axis=-1), } + edges = {key: keras.ops.squeeze(value, axis=-1) for key, value in edges.items()} derivatives = { - "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=None), - "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=None), + "left": keras.ops.take_along_axis(parameters_inside["derivatives"], lower, axis=-1), + "right": keras.ops.take_along_axis(parameters_inside["derivatives"], upper, axis=-1), } + derivatives = {key: keras.ops.squeeze(value, axis=-1) for key, value in derivatives.items()} + + # compute spline and jacobian spline, jac = _rational_quadratic_spline(z[inside], edges=edges, derivatives=derivatives, inverse=True) x = keras.ops.scatter_update(x, inside_indices, spline) log_jac = keras.ops.scatter_update(log_jac, inside_indices, jac) From 543281cf471c0c2d7b33fbd6c35cce02aa353d8e Mon Sep 17 00:00:00 2001 From: larskue Date: Thu, 23 Jan 2025 10:39:47 +0100 Subject: [PATCH 22/38] dump --- .../transforms/spline_transform.py | 134 +++++++++--------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index b07ab1f8f..edef81833 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -34,6 +34,8 @@ def __init__( if self.method != "rational_quadratic": raise NotImplementedError("Currently, only 'rational_quadratic' spline method is supported.") + self.method_fn = _rational_quadratic_spline + # we slightly over-parametrize to allow for better constraints # this may also improve convergence due to redundancy self.parameter_sizes = { @@ -67,15 +69,17 @@ def params_per_dim(self) -> int: return sum(self.parameter_sizes.values()) def split_parameters(self, parameters: Tensor) -> dict[str, Tensor]: - p = {} + shape = keras.ops.shape(parameters) + + if shape[-1] % self.params_per_dim != 0: + raise ValueError(f"Invalid number of parameters. Must be divisible by {self.params_per_dim}.") - start = 0 - for key, value in self.parameter_sizes.items(): - stop = start + value - p[key] = keras.ops.take(parameters, indices=list(range(start, stop)), axis=-1) - start = stop + dims = shape[-1] // self.params_per_dim + indices = dims * keras.ops.convert_to_tensor(list(self.parameter_sizes.values())) + parameters = keras.ops.split(parameters, indices, axis=-1) + parameters = dict(zip(self.parameter_sizes.keys(), parameters)) - return p + return parameters def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tensor]: left_edge = parameters["left_edge"] + self.default_left @@ -124,99 +128,99 @@ def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tenso return constrained_parameters def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): - # x.shape == ([B, ...], D) - # parameters.shape == ([B, ...], bins) - bins = searchsorted(parameters["horizontal_edges"], x) + # avoid side effects for mutable args + parameters = parameters.copy() - # inside check is right-inclusive because searchsorted is right-inclusive + # first compute affine transform on everything + scale = parameters.pop("affine_scale") + shift = parameters.pop("affine_shift") + affine = scale * x + shift + affine_log_jac = keras.ops.broadcast_to(keras.ops.log(scale), keras.ops.shape(affine)) + + # compute spline and overwrite inside part + bins = searchsorted(parameters["horizontal_edges"], x) inside = (bins > 0) & (bins <= self.bins) - # inside_indices.shape == (n_inside, ndim(x)) inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) - # first compute affine transform on everything - scale = parameters["affine_scale"] - shift = parameters["affine_shift"] - z = scale * x + shift - log_jac = keras.ops.broadcast_to(keras.ops.log(scale), keras.ops.shape(z)) + # select parameters for inside elements + parameters = {key: value[keras.ops.any(inside, axis=-1)] for key, value in parameters.items()} - # overwrite inside part with spline - upper = bins[inside] + # select parameters for the bins + # TODO: need a generic way to do this for arbitrary spline methods + upper = bins[keras.ops.any(inside, axis=-1)] upper = expand_as(upper, parameters["horizontal_edges"], side="right") - lower = upper - 1 - # select batch elements that are inside - parameters_inside = {key: value[inside_indices[:, :-1]] for key, value in parameters.items()} - parameters_inside = {key: keras.ops.squeeze(value, axis=1) for key, value in parameters_inside.items()} - - # select bin parameters for inside elements edges = { - "left": keras.ops.take_along_axis(parameters_inside["horizontal_edges"], lower, axis=-1), - "right": keras.ops.take_along_axis(parameters_inside["horizontal_edges"], upper, axis=-1), - "bottom": keras.ops.take_along_axis(parameters_inside["vertical_edges"], lower, axis=-1), - "top": keras.ops.take_along_axis(parameters_inside["vertical_edges"], upper, axis=-1), + "left": keras.ops.take_along_axis(parameters["horizontal_edges"], lower, axis=-1), + "right": keras.ops.take_along_axis(parameters["horizontal_edges"], upper, axis=-1), + "bottom": keras.ops.take_along_axis(parameters["vertical_edges"], lower, axis=-1), + "top": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=-1), } - edges = {key: keras.ops.squeeze(value, axis=-1) for key, value in edges.items()} derivatives = { - "left": keras.ops.take_along_axis(parameters_inside["derivatives"], lower, axis=-1), - "right": keras.ops.take_along_axis(parameters_inside["derivatives"], upper, axis=-1), + "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=-1), + "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=-1), } - derivatives = {key: keras.ops.squeeze(value, axis=-1) for key, value in derivatives.items()} - # compute spline and jacobian - spline, jac = _rational_quadratic_spline(x[inside], edges=edges, derivatives=derivatives) - z = keras.ops.scatter_update(z, inside_indices, spline) - log_jac = keras.ops.scatter_update(log_jac, inside_indices, jac) + parameters = {"edges": edges, "derivatives": derivatives} + + # compute the spline and jacobian + spline, spline_log_jac = self.method_fn(x[inside], **parameters) + + # overwrite inside part with spline + z = keras.ops.scatter_update(affine, inside_indices, spline) + log_jac = keras.ops.scatter_update(affine_log_jac, inside_indices, spline_log_jac) log_det = keras.ops.sum(log_jac, axis=-1) return z, log_det def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor): - # z.shape == ([B, ...], D) - # parameters.shape == ([B, ...], bins) - bins = searchsorted(parameters["vertical_edges"], z) + # avoid side effects for mutable args + parameters = parameters.copy() - # inside check is right-inclusive because searchsorted is right-inclusive + # first compute affine transform on everything + scale = parameters.pop("affine_scale") + shift = parameters.pop("affine_shift") + affine = (z - shift) / scale + affine_log_jac = keras.ops.broadcast_to(-keras.ops.log(scale), keras.ops.shape(affine)) + + # compute spline and overwrite inside part + bins = searchsorted(parameters["vertical_edges"], z) inside = (bins > 0) & (bins <= self.bins) - # inside_indices.shape == (n_inside, ndim(x)) inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) - # first compute affine transform on everything - scale = parameters["affine_scale"] - shift = parameters["affine_shift"] - x = (z - shift) / scale - log_jac = keras.ops.broadcast_to(-keras.ops.log(scale), keras.ops.shape(x)) + # select parameters for inside elements + parameters = {key: value[keras.ops.any(inside, axis=-1)] for key, value in parameters.items()} - # overwrite inside part with spline + # select parameters for the bins + # TODO: need a generic way to do this for arbitrary spline methods upper = bins[inside] upper = expand_as(upper, parameters["horizontal_edges"], side="right") - lower = upper - 1 - # select batch elements that are inside - parameters_inside = {key: value[inside_indices[:, :-1]] for key, value in parameters.items()} - parameters_inside = {key: keras.ops.squeeze(value, axis=1) for key, value in parameters_inside.items()} - - # select bin parameters for inside elements edges = { - "left": keras.ops.take_along_axis(parameters_inside["horizontal_edges"], lower, axis=-1), - "right": keras.ops.take_along_axis(parameters_inside["horizontal_edges"], upper, axis=-1), - "bottom": keras.ops.take_along_axis(parameters_inside["vertical_edges"], lower, axis=-1), - "top": keras.ops.take_along_axis(parameters_inside["vertical_edges"], upper, axis=-1), + "left": keras.ops.take_along_axis(parameters["horizontal_edges"], lower, axis=-1), + "right": keras.ops.take_along_axis(parameters["horizontal_edges"], upper, axis=-1), + "bottom": keras.ops.take_along_axis(parameters["vertical_edges"], lower, axis=-1), + "top": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=-1), } edges = {key: keras.ops.squeeze(value, axis=-1) for key, value in edges.items()} derivatives = { - "left": keras.ops.take_along_axis(parameters_inside["derivatives"], lower, axis=-1), - "right": keras.ops.take_along_axis(parameters_inside["derivatives"], upper, axis=-1), + "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=-1), + "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=-1), } derivatives = {key: keras.ops.squeeze(value, axis=-1) for key, value in derivatives.items()} - # compute spline and jacobian - spline, jac = _rational_quadratic_spline(z[inside], edges=edges, derivatives=derivatives, inverse=True) - x = keras.ops.scatter_update(x, inside_indices, spline) - log_jac = keras.ops.scatter_update(log_jac, inside_indices, jac) + parameters = {"edges": edges, "derivatives": derivatives} + + # compute the spline and jacobian + spline, spline_log_jac = self.method_fn(z[inside], **parameters, inverse=True) + + # overwrite inside part with spline + x = keras.ops.scatter_update(affine, inside_indices, spline) + log_jac = keras.ops.scatter_update(affine_log_jac, inside_indices, spline_log_jac) log_det = keras.ops.sum(log_jac, axis=-1) - return x, log_det + return z, log_det From 0d907e48e298d676b44a7d57a1b2c0ff9bb35cf1 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:18:05 +0100 Subject: [PATCH 23/38] fix sign of log jacobian for inverse pass in rq spline --- .../networks/coupling_flow/transforms/_rational_quadratic.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py b/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py index 980afb88f..a8c973306 100644 --- a/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py +++ b/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py @@ -74,4 +74,7 @@ def _rational_quadratic_spline( denominator = (sk + (dkp + dk - 2 * sk) * xi * (1 - xi)) ** 2 log_jac = keras.ops.log(numerator) - keras.ops.log(denominator) + if inverse: + log_jac = -log_jac + return result, log_jac From dad61cf18cabe963d42d1ebf13fd2b67c51c2261 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:18:51 +0100 Subject: [PATCH 24/38] fix parameter splitting for spline transform --- .../coupling_flow/transforms/spline_transform.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index edef81833..1d549ab0c 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -69,13 +69,9 @@ def params_per_dim(self) -> int: return sum(self.parameter_sizes.values()) def split_parameters(self, parameters: Tensor) -> dict[str, Tensor]: - shape = keras.ops.shape(parameters) - - if shape[-1] % self.params_per_dim != 0: - raise ValueError(f"Invalid number of parameters. Must be divisible by {self.params_per_dim}.") - - dims = shape[-1] // self.params_per_dim - indices = dims * keras.ops.convert_to_tensor(list(self.parameter_sizes.values())) + batch_shape = list(keras.ops.shape(parameters)[:-1]) + parameters = keras.ops.reshape(parameters, batch_shape + [-1, self.params_per_dim]) + indices = np.cumsum(list(self.parameter_sizes.values())).tolist() parameters = keras.ops.split(parameters, indices, axis=-1) parameters = dict(zip(self.parameter_sizes.keys(), parameters)) From ef7de597e44278574a513a675a87e78cc1539066 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:19:08 +0100 Subject: [PATCH 25/38] improve readability --- .../coupling_flow/transforms/spline_transform.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 1d549ab0c..0d97c9f03 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -90,12 +90,10 @@ def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tenso total_height = keras.ops.arcsinh(keras.ops.softplus(parameters["total_height"] + self._shift)) total_height = (self.default_height - self.min_height) * total_height + self.min_height - bin_widths = (total_width - self.bins * self.min_bin_width) * keras.ops.softmax( - parameters["bin_widths"], axis=-1 - ) + self.min_bin_width - bin_heights = (total_height - self.bins * self.min_bin_height) * keras.ops.softmax( - parameters["bin_heights"], axis=-1 - ) + self.min_bin_height + bin_widths = keras.ops.softmax(parameters["bin_widths"], axis=-1) + bin_widths = (total_width - self.bins * self.min_bin_width) * bin_widths + self.min_bin_width + bin_heights = keras.ops.softmax(parameters["bin_heights"], axis=-1) + bin_heights = (total_height - self.bins * self.min_bin_height) * bin_heights + self.min_bin_height # dy / dx affine_scale = total_height / total_width From c89c5d0b7113f951b1b823b17b91b5723eb67d89 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:19:23 +0100 Subject: [PATCH 26/38] fix scale and shift trailing dimension --- .../networks/coupling_flow/transforms/spline_transform.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 0d97c9f03..58f2c9707 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -115,8 +115,8 @@ def constrain_parameters(self, parameters: dict[str, Tensor]) -> dict[str, Tenso "horizontal_edges": horizontal_edges, "vertical_edges": vertical_edges, "derivatives": derivatives, - "affine_scale": affine_scale, - "affine_shift": affine_shift, + "affine_scale": keras.ops.squeeze(affine_scale, axis=-1), + "affine_shift": keras.ops.squeeze(affine_shift, axis=-1), } return constrained_parameters From 00aeb0cb7609d7c65a2a673e21a641e176b1b87d Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:20:01 +0100 Subject: [PATCH 27/38] fix inverse pass return value --- bayesflow/networks/coupling_flow/transforms/spline_transform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 58f2c9707..39ea5e4a0 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -217,4 +217,4 @@ def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) log_det = keras.ops.sum(log_jac, axis=-1) - return z, log_det + return x, log_det From abff6639fc1fd3ffc677d5f05882f1e2fdb907bb Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:20:34 +0100 Subject: [PATCH 28/38] correctly choose bins once for each dimension, even for multi-dimensional inputs --- .../transforms/spline_transform.py | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 39ea5e4a0..5843cbe23 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -5,7 +5,7 @@ ) from bayesflow.types import Tensor -from bayesflow.utils import expand_as, pad, searchsorted +from bayesflow.utils import pad, searchsorted from bayesflow.utils.keras_utils import shifted_softplus from ._rational_quadratic import _rational_quadratic_spline from .transform import Transform @@ -132,17 +132,18 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) affine_log_jac = keras.ops.broadcast_to(keras.ops.log(scale), keras.ops.shape(affine)) # compute spline and overwrite inside part - bins = searchsorted(parameters["horizontal_edges"], x) + bins = searchsorted(parameters["horizontal_edges"], keras.ops.expand_dims(x, axis=-1)) + bins = keras.ops.squeeze(bins, axis=-1) inside = (bins > 0) & (bins <= self.bins) inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) # select parameters for inside elements - parameters = {key: value[keras.ops.any(inside, axis=-1)] for key, value in parameters.items()} + parameters = {key: value[inside] for key, value in parameters.items()} # select parameters for the bins # TODO: need a generic way to do this for arbitrary spline methods - upper = bins[keras.ops.any(inside, axis=-1)] - upper = expand_as(upper, parameters["horizontal_edges"], side="right") + upper = bins[inside] + upper = keras.ops.expand_dims(upper, axis=-1) lower = upper - 1 edges = { @@ -151,10 +152,12 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) "bottom": keras.ops.take_along_axis(parameters["vertical_edges"], lower, axis=-1), "top": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=-1), } + edges = {key: keras.ops.squeeze(value, axis=-1) for key, value in edges.items()} derivatives = { "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=-1), "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=-1), } + derivatives = {key: keras.ops.squeeze(value, axis=-1) for key, value in derivatives.items()} parameters = {"edges": edges, "derivatives": derivatives} @@ -180,17 +183,18 @@ def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) affine_log_jac = keras.ops.broadcast_to(-keras.ops.log(scale), keras.ops.shape(affine)) # compute spline and overwrite inside part - bins = searchsorted(parameters["vertical_edges"], z) + bins = searchsorted(parameters["vertical_edges"], keras.ops.expand_dims(z, axis=-1)) + bins = keras.ops.squeeze(bins, axis=-1) inside = (bins > 0) & (bins <= self.bins) inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) # select parameters for inside elements - parameters = {key: value[keras.ops.any(inside, axis=-1)] for key, value in parameters.items()} + parameters = {key: value[inside] for key, value in parameters.items()} # select parameters for the bins # TODO: need a generic way to do this for arbitrary spline methods upper = bins[inside] - upper = expand_as(upper, parameters["horizontal_edges"], side="right") + upper = keras.ops.expand_dims(upper, axis=-1) lower = upper - 1 edges = { From 1cd2fb59b3604f4f164d1c06fe396af49181a93c Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:21:17 +0100 Subject: [PATCH 29/38] run formatter --- bayesflow/diagnostics/plots/calibration_ecdf.py | 2 +- bayesflow/diagnostics/plots/mmd_hypothesis_test.py | 2 +- bayesflow/simulators/simulator.py | 2 +- bayesflow/utils/dict_utils.py | 2 +- docsrc/source/references.bib | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bayesflow/diagnostics/plots/calibration_ecdf.py b/bayesflow/diagnostics/plots/calibration_ecdf.py index e83fa9ed3..121f18118 100644 --- a/bayesflow/diagnostics/plots/calibration_ecdf.py +++ b/bayesflow/diagnostics/plots/calibration_ecdf.py @@ -176,7 +176,7 @@ def calibration_ecdf( titles = ["Stacked ECDFs"] for ax, title in zip(plot_data["axes"].flat, titles): - ax.fill_between(z, L, H, color=fill_color, alpha=0.2, label=rf"{int((1-alpha) * 100)}$\%$ Confidence Bands") + ax.fill_between(z, L, H, color=fill_color, alpha=0.2, label=rf"{int((1 - alpha) * 100)}$\%$ Confidence Bands") ax.legend(fontsize=legend_fontsize) ax.set_title(title, fontsize=title_fontsize) diff --git a/bayesflow/diagnostics/plots/mmd_hypothesis_test.py b/bayesflow/diagnostics/plots/mmd_hypothesis_test.py index e457dbc61..0fcf07e4f 100644 --- a/bayesflow/diagnostics/plots/mmd_hypothesis_test.py +++ b/bayesflow/diagnostics/plots/mmd_hypothesis_test.py @@ -79,7 +79,7 @@ def fill_area_under_kde(kde_object, x_start, x_end=None, **kwargs): mmd_critical = ops.quantile(mmd_null, 1 - alpha_level) fill_area_under_kde( - kde, mmd_critical, color=alpha_color, alpha=0.5, label=rf"{int(alpha_level*100)}% rejection area" + kde, mmd_critical, color=alpha_color, alpha=0.5, label=rf"{int(alpha_level * 100)}% rejection area" ) if truncate_v_lines_at_kde: diff --git a/bayesflow/simulators/simulator.py b/bayesflow/simulators/simulator.py index 5e0a6e35b..6754f0082 100644 --- a/bayesflow/simulators/simulator.py +++ b/bayesflow/simulators/simulator.py @@ -43,7 +43,7 @@ def rejection_sample( if accept.shape != (sample_shape[axis],): raise RuntimeError( - f"Predicate return array must have shape {(sample_shape[axis],)}. " f"Received: {accept.shape}." + f"Predicate return array must have shape {(sample_shape[axis],)}. Received: {accept.shape}." ) if not accept.dtype == "bool": diff --git a/bayesflow/utils/dict_utils.py b/bayesflow/utils/dict_utils.py index e356a5484..9014c5fe7 100644 --- a/bayesflow/utils/dict_utils.py +++ b/bayesflow/utils/dict_utils.py @@ -191,7 +191,7 @@ def dicts_to_arrays( # Throw if unknown type else: raise TypeError( - f"Only dicts and tensors are supported as arguments, " f"but your targets are of type {type(targets)}" + f"Only dicts and tensors are supported as arguments, but your targets are of type {type(targets)}" ) return dict( diff --git a/docsrc/source/references.bib b/docsrc/source/references.bib index ed45beb50..c6fc16a68 100644 --- a/docsrc/source/references.bib +++ b/docsrc/source/references.bib @@ -23,4 +23,4 @@ @article{radev2020bayesflow pages={1452--1466}, year={2020}, publisher={IEEE} -} \ No newline at end of file +} From 62e1ef541f498a565595d5111a26759775a80304 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:37:19 +0100 Subject: [PATCH 30/38] reduce searchsorted log spam --- bayesflow/utils/logging.py | 6 ++++++ bayesflow/utils/tensor_utils.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bayesflow/utils/logging.py b/bayesflow/utils/logging.py index 45469dabf..6521a14b4 100644 --- a/bayesflow/utils/logging.py +++ b/bayesflow/utils/logging.py @@ -1,5 +1,6 @@ import keras import logging +from functools import lru_cache logger = logging.getLogger("bayesflow") @@ -43,3 +44,8 @@ def log(msg, *args, **kwargs): def warning(msg, *args, **kwargs): _log(msg, *args, callback_fn=logger.warning, **kwargs) + + +@lru_cache(100) +def warn_once(msg, *args, **kwargs): + warning(msg, *args, **kwargs) diff --git a/bayesflow/utils/tensor_utils.py b/bayesflow/utils/tensor_utils.py index 597c08650..7324c0315 100644 --- a/bayesflow/utils/tensor_utils.py +++ b/bayesflow/utils/tensor_utils.py @@ -203,7 +203,7 @@ def searchsorted(sorted_sequence: Tensor, values: Tensor, side: str = "left") -> import jax import jax.numpy as jnp - logging.warning("JAX searchsorted is not yet optimized.") + logging.warn_once("JAX searchsorted is not yet optimized.") # do not vmap over the side argument (we have to pass it as a positional argument) in_axes = [0, 0, None] From af26ba6947a3e84181f04c1362430136e465ddc9 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 16:37:32 +0100 Subject: [PATCH 31/38] log backend used at setup --- bayesflow/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bayesflow/__init__.py b/bayesflow/__init__.py index d0d8d389b..5375e232e 100644 --- a/bayesflow/__init__.py +++ b/bayesflow/__init__.py @@ -36,6 +36,10 @@ def setup(): torch.autograd.set_grad_enabled(False) + from bayesflow.utils import logging + + logging.info(f"Using backend {keras.backend.backend()!r}") + # call and clean up namespace setup() From 20814b7ddc2c5407cfe04ac879292a4050a9d092 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 18:37:09 +0100 Subject: [PATCH 32/38] remove maximum message cache size --- bayesflow/utils/logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bayesflow/utils/logging.py b/bayesflow/utils/logging.py index 6521a14b4..eec4fa854 100644 --- a/bayesflow/utils/logging.py +++ b/bayesflow/utils/logging.py @@ -46,6 +46,6 @@ def warning(msg, *args, **kwargs): _log(msg, *args, callback_fn=logger.warning, **kwargs) -@lru_cache(100) +@lru_cache(None) def warn_once(msg, *args, **kwargs): warning(msg, *args, **kwargs) From 6a526dd91e6b6c4afe9baf7ca6f6815a6ffa5b9b Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 18:37:25 +0100 Subject: [PATCH 33/38] Improve warning message for jax searchsorted --- bayesflow/utils/tensor_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bayesflow/utils/tensor_utils.py b/bayesflow/utils/tensor_utils.py index 7324c0315..a832daa49 100644 --- a/bayesflow/utils/tensor_utils.py +++ b/bayesflow/utils/tensor_utils.py @@ -203,7 +203,7 @@ def searchsorted(sorted_sequence: Tensor, values: Tensor, side: str = "left") -> import jax import jax.numpy as jnp - logging.warn_once("JAX searchsorted is not yet optimized.") + logging.warn_once(f"searchsorted is not yet optimized for backend {keras.backend.backend()!r}") # do not vmap over the side argument (we have to pass it as a positional argument) in_axes = [0, 0, None] From 08a21821eb66700e92949f5574e717b6f2c76b10 Mon Sep 17 00:00:00 2001 From: LarsKue Date: Thu, 23 Jan 2025 18:38:40 +0100 Subject: [PATCH 34/38] Fix spline parameter binning for compiled contexts --- .../transforms/spline_transform.py | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 5843cbe23..34e4fdf04 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -24,6 +24,10 @@ def __init__( method: str = "rational_quadratic", ): super().__init__() + + if bins <= 0: + raise ValueError("Number of bins must be strictly positive.") + self.bins = bins self.min_width = max(min_width, bins * min_bin_width) self.min_height = max(min_height, bins * min_bin_height) @@ -125,26 +129,28 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) # avoid side effects for mutable args parameters = parameters.copy() - # first compute affine transform on everything + # affine transform for outside scale = parameters.pop("affine_scale") shift = parameters.pop("affine_shift") affine = scale * x + shift affine_log_jac = keras.ops.broadcast_to(keras.ops.log(scale), keras.ops.shape(affine)) - # compute spline and overwrite inside part + # spline transform for inside bins = searchsorted(parameters["horizontal_edges"], keras.ops.expand_dims(x, axis=-1)) bins = keras.ops.squeeze(bins, axis=-1) inside = (bins > 0) & (bins <= self.bins) - inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) - # select parameters for inside elements - parameters = {key: value[inside] for key, value in parameters.items()} + upper = bins + lower = upper - 1 - # select parameters for the bins - # TODO: need a generic way to do this for arbitrary spline methods - upper = bins[inside] + # we need to mask out invalid bins to be backend-agnostic + # this does not matter since we will overwrite these values with the affine values anyway + upper = keras.ops.where(inside, upper, keras.ops.ones_like(upper)) + lower = keras.ops.where(inside, lower, keras.ops.zeros_like(lower)) + + # need to expand the dimensions to match the shape of the parameters for take_along_axis upper = keras.ops.expand_dims(upper, axis=-1) - lower = upper - 1 + lower = keras.ops.expand_dims(lower, axis=-1) edges = { "left": keras.ops.take_along_axis(parameters["horizontal_edges"], lower, axis=-1), @@ -153,6 +159,7 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) "top": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=-1), } edges = {key: keras.ops.squeeze(value, axis=-1) for key, value in edges.items()} + derivatives = { "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=-1), "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=-1), @@ -162,11 +169,10 @@ def _forward(self, x: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) parameters = {"edges": edges, "derivatives": derivatives} # compute the spline and jacobian - spline, spline_log_jac = self.method_fn(x[inside], **parameters) + spline, spline_log_jac = self.method_fn(x, **parameters) - # overwrite inside part with spline - z = keras.ops.scatter_update(affine, inside_indices, spline) - log_jac = keras.ops.scatter_update(affine_log_jac, inside_indices, spline_log_jac) + z = keras.ops.where(inside, spline, affine) + log_jac = keras.ops.where(inside, spline_log_jac, affine_log_jac) log_det = keras.ops.sum(log_jac, axis=-1) From a3ce91abb32dd4f6107f3cfcb25fd9efac389d2d Mon Sep 17 00:00:00 2001 From: larskue Date: Fri, 24 Jan 2025 13:24:52 +0100 Subject: [PATCH 35/38] update inverse transform same as forward --- .../transforms/spline_transform.py | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/spline_transform.py b/bayesflow/networks/coupling_flow/transforms/spline_transform.py index 34e4fdf04..3328e38c9 100644 --- a/bayesflow/networks/coupling_flow/transforms/spline_transform.py +++ b/bayesflow/networks/coupling_flow/transforms/spline_transform.py @@ -182,26 +182,28 @@ def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) # avoid side effects for mutable args parameters = parameters.copy() - # first compute affine transform on everything + # affine transform for outside scale = parameters.pop("affine_scale") shift = parameters.pop("affine_shift") affine = (z - shift) / scale affine_log_jac = keras.ops.broadcast_to(-keras.ops.log(scale), keras.ops.shape(affine)) - # compute spline and overwrite inside part + # spline transform for inside bins = searchsorted(parameters["vertical_edges"], keras.ops.expand_dims(z, axis=-1)) bins = keras.ops.squeeze(bins, axis=-1) inside = (bins > 0) & (bins <= self.bins) - inside_indices = keras.ops.stack(keras.ops.nonzero(inside), axis=-1) - # select parameters for inside elements - parameters = {key: value[inside] for key, value in parameters.items()} + upper = bins + lower = upper - 1 + + # we need to mask out invalid bins to be backend-agnostic + # this does not matter since we will overwrite these values with the affine values anyway + upper = keras.ops.where(inside, upper, keras.ops.ones_like(upper)) + lower = keras.ops.where(inside, lower, keras.ops.zeros_like(lower)) - # select parameters for the bins - # TODO: need a generic way to do this for arbitrary spline methods - upper = bins[inside] + # need to expand the dimensions to match the shape of the parameters for take_along_axis upper = keras.ops.expand_dims(upper, axis=-1) - lower = upper - 1 + lower = keras.ops.expand_dims(lower, axis=-1) edges = { "left": keras.ops.take_along_axis(parameters["horizontal_edges"], lower, axis=-1), @@ -210,6 +212,7 @@ def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) "top": keras.ops.take_along_axis(parameters["vertical_edges"], upper, axis=-1), } edges = {key: keras.ops.squeeze(value, axis=-1) for key, value in edges.items()} + derivatives = { "left": keras.ops.take_along_axis(parameters["derivatives"], lower, axis=-1), "right": keras.ops.take_along_axis(parameters["derivatives"], upper, axis=-1), @@ -219,11 +222,10 @@ def _inverse(self, z: Tensor, parameters: dict[str, Tensor]) -> (Tensor, Tensor) parameters = {"edges": edges, "derivatives": derivatives} # compute the spline and jacobian - spline, spline_log_jac = self.method_fn(z[inside], **parameters, inverse=True) + spline, spline_log_jac = self.method_fn(z, **parameters, inverse=True) - # overwrite inside part with spline - x = keras.ops.scatter_update(affine, inside_indices, spline) - log_jac = keras.ops.scatter_update(affine_log_jac, inside_indices, spline_log_jac) + x = keras.ops.where(inside, spline, affine) + log_jac = keras.ops.where(inside, spline_log_jac, affine_log_jac) log_det = keras.ops.sum(log_jac, axis=-1) From 2454c9b6a14266daaee9ee819e4e7000abd7722b Mon Sep 17 00:00:00 2001 From: stefanradev93 Date: Sat, 25 Jan 2025 19:50:27 -0500 Subject: [PATCH 36/38] Update TwoMoons notebook with splines WIP [skip ci] --- examples/TwoMoons_StarterNotebook.ipynb | 742 +++++++++++------------- 1 file changed, 332 insertions(+), 410 deletions(-) diff --git a/examples/TwoMoons_StarterNotebook.ipynb b/examples/TwoMoons_StarterNotebook.ipynb index ae41b77b4..c922c80d2 100644 --- a/examples/TwoMoons_StarterNotebook.ipynb +++ b/examples/TwoMoons_StarterNotebook.ipynb @@ -20,14 +20,20 @@ "start_time": "2024-10-24T08:36:20.807192Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:bayesflow:Using backend 'tensorflow'\n" + ] + } + ], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import seaborn as sns\n", "\n", - "import keras\n", - "\n", "# For BayesFlow devs: this ensures that the latest dev version can be found\n", "import sys\n", "sys.path.append('../')\n", @@ -197,62 +203,12 @@ "\n", "The next step is to tell BayesFlow how to deal with all the simulated variables. You may also think of this as informing BayesFlow about the data flow, i.e., which variables go into which network and what transformations needs to be performed prior to passing the simulator outputs into the networks. This is done via an adapter layer, which is implemented as a sequence of fixed, pseudo-invertible data transforms.\n", "\n", - "There are two ways to build this adapter:" - ] - }, - { - "cell_type": "markdown", - "id": "54a6d149ed3a622e", - "metadata": {}, - "source": [ - "\n", - "1. **Automatically**: You can use the `build_adapter` method of the approximator to create a data adapter with the right output keys for training. You can still modify the data adapter afterward if needed.\n", - "\n", - "For this example, we want to learn the posterior distribution $p(\\theta\\,|\\,x)$, so we **infer** $\\theta$, **conditioning** on $x$." + "Below, we define the data adapter by specifying the input and output keys and the transformations to be applied. This allows us full control over the data flow." ] }, { "cell_type": "code", - "execution_count": 6, - "id": "b6f22643199950cf", - "metadata": { - "ExecuteTime": { - "end_time": "2024-10-24T08:36:23.695091Z", - "start_time": "2024-10-24T08:36:23.687089Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Adapter([ToArray -> ConvertDType -> Concatenate(['theta'] -> 'inference_variables') -> Concatenate(['x'] -> 'inference_conditions') -> Keep(['inference_variables', 'inference_conditions', 'summary_variables']) -> Standardize])" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "adapter = bf.approximators.ContinuousApproximator.build_adapter(\n", - " inference_variables=[\"theta\"],\n", - " inference_conditions=[\"x\"],\n", - ")\n", - "adapter" - ] - }, - { - "cell_type": "markdown", - "id": "68c58e4ee6a14614", - "metadata": {}, - "source": [ - "\n", - "2. **Manually**: You can define the data adapter by specifying the input and output keys and the transformations to be applied. This allows you full control over your data flow." - ] - }, - { - "cell_type": "code", - "execution_count": 7, + "execution_count": 22, "id": "5c9c2dc70f53d103", "metadata": { "ExecuteTime": { @@ -264,10 +220,10 @@ { "data": { "text/plain": [ - "Adapter([ToArray -> ConvertDType -> Standardize -> Rename('theta' -> 'inference_variables') -> Rename('x' -> 'inference_conditions')])" + "Adapter([0: ToArray -> 1: ConvertDType -> 2: Standardize(exclude=['theta']) -> 3: Rename('theta' -> 'inference_variables') -> 4: Rename('x' -> 'inference_conditions')])" ] }, - "execution_count": 7, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -282,8 +238,8 @@ " # convert from numpy's default float64 to deep learning friendly float32\n", " .convert_dtype(\"float64\", \"float32\")\n", " \n", - " # standardize all variables to zero mean and unit variance\n", - " .standardize()\n", + " # standardize target variables to zero mean and unit variance \n", + " .standardize(exclude=\"theta\")\n", " \n", " # rename the variables to match the required approximator inputs\n", " .rename(\"theta\", \"inference_variables\")\n", @@ -299,14 +255,12 @@ "source": [ "## Dataset\n", "\n", - "For this example, we will sample our training data ahead of time and use offline training with a `bf.datasets.OfflineDataset`.\n", - "\n", - "This makes the training process faster, since we avoid repeated sampling. If you want to use online training, you can use an `OnlineDataset` analogously, or just pass your simulator directly to `approximator.fit()`!" + "For this example, we will sample our training data ahead of time and use offline training with a very small number of epochs. In actual applications, you usually want to train much longer in order to max our performance." ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "39cb5a1c9824246f", "metadata": { "ExecuteTime": { @@ -319,13 +273,12 @@ "num_training_batches = 512\n", "num_validation_batches = 128\n", "batch_size = 64\n", - "epochs = 30\n", - "total_steps = num_training_batches * epochs" + "epochs = 20" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "9dee7252ef99affa", "metadata": { "ExecuteTime": { @@ -335,33 +288,8 @@ }, "outputs": [], "source": [ - "training_samples = simulator.sample((num_training_batches * batch_size,))\n", - "validation_samples = simulator.sample((num_validation_batches * batch_size,))" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "51045bbed88cb5c2", - "metadata": { - "ExecuteTime": { - "end_time": "2024-09-23T14:39:53.281170Z", - "start_time": "2024-09-23T14:39:53.275921Z" - } - }, - "outputs": [], - "source": [ - "training_dataset = bf.datasets.OfflineDataset(\n", - " data=training_samples, \n", - " batch_size=batch_size, \n", - " adapter=adapter\n", - ")\n", - "\n", - "validation_dataset = bf.datasets.OfflineDataset(\n", - " data=validation_samples, \n", - " batch_size=batch_size, \n", - " adapter=adapter\n", - ")" + "training_data = simulator.sample(num_training_batches * batch_size,)\n", + "validation_data = simulator.sample(num_validation_batches * batch_size,)" ] }, { @@ -382,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "09206e6f", "metadata": { "ExecuteTime": { @@ -392,7 +320,7 @@ }, "outputs": [], "source": [ - "inference_network = bf.networks.FlowMatching(\n", + "flow_matching = bf.networks.FlowMatching(\n", " subnet=\"mlp\", \n", " subnet_kwargs={\"widths\": (256,)*6 , \"dropout\": 0.0, \"residual\": True}\n", ")" @@ -406,68 +334,32 @@ "This inference network is just a general Flow Matching backbone, not yet adapted to the specific inference task at hand (i.e., posterior appproximation). To achieve this adaptation, we combine the network with our data adapter, which together form an `approximator`. In this case, we need a `ContinuousApproximator` since the target we want to approximate is the posterior of the *continuous* parameter vector $\\theta$." ] }, - { - "cell_type": "code", - "execution_count": 49, - "id": "96ca6ffa", - "metadata": { - "ExecuteTime": { - "end_time": "2024-09-23T14:39:53.371691Z", - "start_time": "2024-09-23T14:39:53.369375Z" - } - }, - "outputs": [], - "source": [ - "fm_approximator = bf.ContinuousApproximator(\n", - " inference_network=inference_network,\n", - " adapter=adapter,\n", - ")" - ] - }, { "cell_type": "markdown", - "id": "566264eadc76c2c", + "id": "76722c33", "metadata": {}, "source": [ - "### Optimizer and Learning Rate\n", - "We find learning rate schedules, such as [cosine decay](https://keras.io/api/optimizers/learning_rate_schedules/cosine_decay/), work well for a wide variety of approximation tasks." - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "e8d7e053", - "metadata": { - "ExecuteTime": { - "end_time": "2024-09-23T14:39:53.433012Z", - "start_time": "2024-09-23T14:39:53.415903Z" - } - }, - "outputs": [], - "source": [ - "initial_learning_rate = 5e-4\n", - "scheduled_lr = keras.optimizers.schedules.CosineDecay(\n", - " initial_learning_rate=initial_learning_rate,\n", - " decay_steps=total_steps,\n", - " alpha=1e-8\n", - ")\n", - "\n", - "optimizer = keras.optimizers.AdamW(learning_rate=scheduled_lr)" + "### Basic Workflow\n", + "We can hide many of the traditional deep learning steps (e.g., specifying a learning rate and an optimizer) within a `Workflow` object. This object just wraps everything together and includes some nice utility functions for training and *in silico* validation." ] }, { "cell_type": "code", - "execution_count": 51, - "id": "51808fcd560489ac", + "execution_count": 10, + "id": "96ca6ffa", "metadata": { "ExecuteTime": { - "end_time": "2024-09-23T14:39:53.476089Z", - "start_time": "2024-09-23T14:39:53.466001Z" + "end_time": "2024-09-23T14:39:53.371691Z", + "start_time": "2024-09-23T14:39:53.369375Z" } }, "outputs": [], "source": [ - "fm_approximator.compile(optimizer=optimizer)" + "flow_matching_workflow = bf.BasicWorkflow(\n", + " simulator=simulator,\n", + " adapter=adapter,\n", + " inference_network=flow_matching,\n", + ")" ] }, { @@ -477,12 +369,12 @@ "source": [ "### Training\n", "\n", - "We are ready to train our deep posterior approximator on the two moons example. We pass the dataset object to the `fit` method and watch as Bayesflow trains." + "We are ready to train our deep posterior approximator on the two moons example. We use the utility function `fit_offline`, which wraps the approximator's super flexible `fit` method." ] }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 11, "id": "0f496bda", "metadata": { "ExecuteTime": { @@ -503,77 +395,55 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 4ms/step - loss: 0.7183 - loss/inference_loss: 0.7183 - val_loss: 0.6021 - val_loss/inference_loss: 0.6021\n", - "Epoch 2/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6388 - loss/inference_loss: 0.6388 - val_loss: 0.4662 - val_loss/inference_loss: 0.4662\n", - "Epoch 3/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6201 - loss/inference_loss: 0.6201 - val_loss: 0.7063 - val_loss/inference_loss: 0.7063\n", - "Epoch 4/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.6079 - loss/inference_loss: 0.6079 - val_loss: 0.4815 - val_loss/inference_loss: 0.4815\n", - "Epoch 5/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6089 - loss/inference_loss: 0.6089 - val_loss: 0.4126 - val_loss/inference_loss: 0.4126\n", - "Epoch 6/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.6070 - loss/inference_loss: 0.6070 - val_loss: 0.5301 - val_loss/inference_loss: 0.5301\n", - "Epoch 7/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5932 - loss/inference_loss: 0.5932 - val_loss: 0.5104 - val_loss/inference_loss: 0.5104\n", - "Epoch 8/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.6104 - loss/inference_loss: 0.6104 - val_loss: 0.4703 - val_loss/inference_loss: 0.4703\n", - "Epoch 9/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.5973 - loss/inference_loss: 0.5973 - val_loss: 0.5964 - val_loss/inference_loss: 0.5964\n", - "Epoch 10/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5774 - loss/inference_loss: 0.5774 - val_loss: 0.6265 - val_loss/inference_loss: 0.6265\n", - "Epoch 11/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.5835 - loss/inference_loss: 0.5835 - val_loss: 0.4252 - val_loss/inference_loss: 0.4252\n", - "Epoch 12/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.5695 - loss/inference_loss: 0.5695 - val_loss: 0.9429 - val_loss/inference_loss: 0.9429\n", - "Epoch 13/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5637 - loss/inference_loss: 0.5637 - val_loss: 0.4232 - val_loss/inference_loss: 0.4232\n", - "Epoch 14/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.5721 - loss/inference_loss: 0.5721 - val_loss: 0.4992 - val_loss/inference_loss: 0.4992\n", - "Epoch 15/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5568 - loss/inference_loss: 0.5568 - val_loss: 0.6984 - val_loss/inference_loss: 0.6984\n", - "Epoch 16/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5741 - loss/inference_loss: 0.5741 - val_loss: 0.6771 - val_loss/inference_loss: 0.6771\n", - "Epoch 17/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5539 - loss/inference_loss: 0.5539 - val_loss: 0.4879 - val_loss/inference_loss: 0.4879\n", - "Epoch 18/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5601 - loss/inference_loss: 0.5601 - val_loss: 0.5392 - val_loss/inference_loss: 0.5392\n", - "Epoch 19/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5685 - loss/inference_loss: 0.5685 - val_loss: 0.5778 - val_loss/inference_loss: 0.5778\n", - "Epoch 20/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5473 - loss/inference_loss: 0.5473 - val_loss: 0.4054 - val_loss/inference_loss: 0.4054\n", - "Epoch 21/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.5568 - loss/inference_loss: 0.5568 - val_loss: 0.3626 - val_loss/inference_loss: 0.3626\n", - "Epoch 22/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5529 - loss/inference_loss: 0.5529 - val_loss: 0.5097 - val_loss/inference_loss: 0.5097\n", - "Epoch 23/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5553 - loss/inference_loss: 0.5553 - val_loss: 0.4594 - val_loss/inference_loss: 0.4594\n", - "Epoch 24/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5328 - loss/inference_loss: 0.5328 - val_loss: 0.5671 - val_loss/inference_loss: 0.5671\n", - "Epoch 25/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5448 - loss/inference_loss: 0.5448 - val_loss: 0.3365 - val_loss/inference_loss: 0.3365\n", - "Epoch 26/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5397 - loss/inference_loss: 0.5397 - val_loss: 0.4711 - val_loss/inference_loss: 0.4711\n", - "Epoch 27/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.5381 - loss/inference_loss: 0.5381 - val_loss: 0.5631 - val_loss/inference_loss: 0.5631\n", - "Epoch 28/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5375 - loss/inference_loss: 0.5375 - val_loss: 0.3975 - val_loss/inference_loss: 0.3975\n", - "Epoch 29/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5443 - loss/inference_loss: 0.5443 - val_loss: 0.3913 - val_loss/inference_loss: 0.3913\n", - "Epoch 30/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5390 - loss/inference_loss: 0.5390 - val_loss: 0.4751 - val_loss/inference_loss: 0.4751\n", - "CPU times: total: 21.5 s\n", - "Wall time: 1min 8s\n" + "Epoch 1/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 4ms/step - loss: 0.7226 - loss/inference_loss: 0.7226 - val_loss: 0.6254 - val_loss/inference_loss: 0.6254\n", + "Epoch 2/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6377 - loss/inference_loss: 0.6377 - val_loss: 0.5348 - val_loss/inference_loss: 0.5348\n", + "Epoch 3/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6253 - loss/inference_loss: 0.6253 - val_loss: 0.6427 - val_loss/inference_loss: 0.6427\n", + "Epoch 4/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6165 - loss/inference_loss: 0.6165 - val_loss: 1.0218 - val_loss/inference_loss: 1.0218\n", + "Epoch 5/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6010 - loss/inference_loss: 0.6010 - val_loss: 0.6841 - val_loss/inference_loss: 0.6841\n", + "Epoch 6/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5999 - loss/inference_loss: 0.5999 - val_loss: 0.7253 - val_loss/inference_loss: 0.7253\n", + "Epoch 7/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.6010 - loss/inference_loss: 0.6010 - val_loss: 0.8324 - val_loss/inference_loss: 0.8324\n", + "Epoch 8/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5904 - loss/inference_loss: 0.5904 - val_loss: 0.6796 - val_loss/inference_loss: 0.6796\n", + "Epoch 9/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5902 - loss/inference_loss: 0.5902 - val_loss: 0.5662 - val_loss/inference_loss: 0.5662\n", + "Epoch 10/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5695 - loss/inference_loss: 0.5695 - val_loss: 0.5778 - val_loss/inference_loss: 0.5778\n", + "Epoch 11/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5627 - loss/inference_loss: 0.5627 - val_loss: 0.5446 - val_loss/inference_loss: 0.5446\n", + "Epoch 12/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5691 - loss/inference_loss: 0.5691 - val_loss: 0.5066 - val_loss/inference_loss: 0.5066\n", + "Epoch 13/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5591 - loss/inference_loss: 0.5591 - val_loss: 0.4995 - val_loss/inference_loss: 0.4995\n", + "Epoch 14/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5526 - loss/inference_loss: 0.5526 - val_loss: 0.4275 - val_loss/inference_loss: 0.4275\n", + "Epoch 15/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5467 - loss/inference_loss: 0.5467 - val_loss: 0.3565 - val_loss/inference_loss: 0.3565\n", + "Epoch 16/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5493 - loss/inference_loss: 0.5493 - val_loss: 0.3889 - val_loss/inference_loss: 0.3889\n", + "Epoch 17/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5445 - loss/inference_loss: 0.5445 - val_loss: 0.6921 - val_loss/inference_loss: 0.6921\n", + "Epoch 18/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5446 - loss/inference_loss: 0.5446 - val_loss: 0.3881 - val_loss/inference_loss: 0.3881\n", + "Epoch 19/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5287 - loss/inference_loss: 0.5287 - val_loss: 0.5459 - val_loss/inference_loss: 0.5459\n", + "Epoch 20/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5506 - loss/inference_loss: 0.5506 - val_loss: 0.4466 - val_loss/inference_loss: 0.4466\n" ] } ], "source": [ - "%%time\n", - "fm_history = fm_approximator.fit(\n", - " epochs=epochs,\n", - " dataset=training_dataset,\n", - " validation_data=validation_dataset,\n", + "history = flow_matching_workflow.fit_offline(\n", + " training_data, \n", + " epochs=epochs, \n", + " batch_size=batch_size, \n", + " validation_data=validation_data\n", ")" ] }, @@ -650,62 +520,28 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 12, "id": "d53a41b8", "metadata": {}, "outputs": [], "source": [ "# Compute the empirical variance of the draws from the prior θ ~ p(θ)\n", - "inference_network = bf.networks.ConsistencyModel(\n", + "consistency_model = bf.networks.ConsistencyModel(\n", " subnet=\"mlp\",\n", " subnet_kwargs={\"widths\": (256,)*6, \"dropout\": 0.0, \"residual\": True},\n", - " total_steps=total_steps,\n", - " max_time=10,\n", + " total_steps=num_training_batches*epochs,\n", + " max_time=10, # this probably needs to be tuned for a novel application\n", " sigma2=1.0, # the data adapter standardizes our parameters, so set to 1.0\n", ")\n", "\n", - "cm_approximator = bf.ContinuousApproximator(\n", - " inference_network=inference_network,\n", + "# Workflow for consistency model\n", + "consistency_model_workflow = bf.BasicWorkflow(\n", + " simulator=simulator,\n", " adapter=adapter,\n", + " inference_network=consistency_model,\n", ")" ] }, - { - "cell_type": "markdown", - "id": "3cc0fed5", - "metadata": {}, - "source": [ - "### Optimizer and Learning Rate\n", - "We use the same settings as for the **Flow Matching** run above." - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "d1bc228a", - "metadata": {}, - "outputs": [], - "source": [ - "initial_learning_rate = 5e-4\n", - "scheduled_lr = keras.optimizers.schedules.CosineDecay(\n", - " initial_learning_rate=initial_learning_rate,\n", - " decay_steps=total_steps,\n", - " alpha=1e-8\n", - ")\n", - "\n", - "optimizer = keras.optimizers.Adam(learning_rate=scheduled_lr)" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "41c4599f", - "metadata": {}, - "outputs": [], - "source": [ - "cm_approximator.compile(optimizer=optimizer)" - ] - }, { "cell_type": "markdown", "id": "9fbcca16", @@ -716,7 +552,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 13, "id": "c3c1a812", "metadata": {}, "outputs": [ @@ -732,77 +568,55 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 6ms/step - loss: 0.4131 - loss/inference_loss: 0.4131 - val_loss: 0.3527 - val_loss/inference_loss: 0.3527\n", - "Epoch 2/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3596 - loss/inference_loss: 0.3596 - val_loss: 0.3809 - val_loss/inference_loss: 0.3809\n", - "Epoch 3/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - loss: 0.3435 - loss/inference_loss: 0.3435 - val_loss: 0.3238 - val_loss/inference_loss: 0.3238\n", - "Epoch 4/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3304 - loss/inference_loss: 0.3304 - val_loss: 0.3097 - val_loss/inference_loss: 0.3097\n", - "Epoch 5/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3249 - loss/inference_loss: 0.3249 - val_loss: 0.3870 - val_loss/inference_loss: 0.3870\n", - "Epoch 6/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3219 - loss/inference_loss: 0.3219 - val_loss: 0.2904 - val_loss/inference_loss: 0.2904\n", - "Epoch 7/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.3156 - loss/inference_loss: 0.3156 - val_loss: 0.3747 - val_loss/inference_loss: 0.3747\n", - "Epoch 8/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3166 - loss/inference_loss: 0.3166 - val_loss: 0.3969 - val_loss/inference_loss: 0.3969\n", - "Epoch 9/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.3099 - loss/inference_loss: 0.3099 - val_loss: 0.2673 - val_loss/inference_loss: 0.2673\n", - "Epoch 10/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3306 - loss/inference_loss: 0.3306 - val_loss: 0.2694 - val_loss/inference_loss: 0.2694\n", - "Epoch 11/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3207 - loss/inference_loss: 0.3207 - val_loss: 0.3024 - val_loss/inference_loss: 0.3024\n", - "Epoch 12/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3184 - loss/inference_loss: 0.3184 - val_loss: 0.3398 - val_loss/inference_loss: 0.3398\n", - "Epoch 13/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3139 - loss/inference_loss: 0.3139 - val_loss: 0.3108 - val_loss/inference_loss: 0.3108\n", - "Epoch 14/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3049 - loss/inference_loss: 0.3049 - val_loss: 0.3164 - val_loss/inference_loss: 0.3164\n", - "Epoch 15/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - loss: 0.3045 - loss/inference_loss: 0.3045 - val_loss: 0.4772 - val_loss/inference_loss: 0.4772\n", - "Epoch 16/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.3021 - loss/inference_loss: 0.3021 - val_loss: 0.2509 - val_loss/inference_loss: 0.2509\n", - "Epoch 17/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.2954 - loss/inference_loss: 0.2954 - val_loss: 0.3196 - val_loss/inference_loss: 0.3196\n", - "Epoch 18/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.2912 - loss/inference_loss: 0.2912 - val_loss: 0.2660 - val_loss/inference_loss: 0.2660\n", - "Epoch 19/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2854 - loss/inference_loss: 0.2854 - val_loss: 0.3047 - val_loss/inference_loss: 0.3047\n", - "Epoch 20/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - loss: 0.2859 - loss/inference_loss: 0.2859 - val_loss: 0.2712 - val_loss/inference_loss: 0.2712\n", - "Epoch 21/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 7ms/step - loss: 0.2844 - loss/inference_loss: 0.2844 - val_loss: 0.1473 - val_loss/inference_loss: 0.1473\n", - "Epoch 22/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - loss: 0.2781 - loss/inference_loss: 0.2781 - val_loss: 0.2537 - val_loss/inference_loss: 0.2537\n", - "Epoch 23/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2752 - loss/inference_loss: 0.2752 - val_loss: 0.2329 - val_loss/inference_loss: 0.2329\n", - "Epoch 24/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2702 - loss/inference_loss: 0.2702 - val_loss: 0.3239 - val_loss/inference_loss: 0.3239\n", - "Epoch 25/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 7ms/step - loss: 0.2734 - loss/inference_loss: 0.2734 - val_loss: 0.3633 - val_loss/inference_loss: 0.3633\n", - "Epoch 26/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.2702 - loss/inference_loss: 0.2702 - val_loss: 0.2883 - val_loss/inference_loss: 0.2883\n", - "Epoch 27/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2684 - loss/inference_loss: 0.2684 - val_loss: 0.2428 - val_loss/inference_loss: 0.2428\n", - "Epoch 28/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - loss: 0.2658 - loss/inference_loss: 0.2658 - val_loss: 0.1842 - val_loss/inference_loss: 0.1842\n", - "Epoch 29/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2649 - loss/inference_loss: 0.2649 - val_loss: 0.1948 - val_loss/inference_loss: 0.1948\n", - "Epoch 30/30\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2732 - loss/inference_loss: 0.2732 - val_loss: 0.2348 - val_loss/inference_loss: 0.2348\n", - "CPU times: total: 32.6 s\n", - "Wall time: 1min 47s\n" + "Epoch 1/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 6ms/step - loss: 0.4156 - loss/inference_loss: 0.4156 - val_loss: 0.3678 - val_loss/inference_loss: 0.3678\n", + "Epoch 2/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3545 - loss/inference_loss: 0.3545 - val_loss: 0.3487 - val_loss/inference_loss: 0.3487\n", + "Epoch 3/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.3349 - loss/inference_loss: 0.3349 - val_loss: 0.3310 - val_loss/inference_loss: 0.3310\n", + "Epoch 4/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.3291 - loss/inference_loss: 0.3291 - val_loss: 0.2774 - val_loss/inference_loss: 0.2774\n", + "Epoch 5/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.3252 - loss/inference_loss: 0.3252 - val_loss: 0.4224 - val_loss/inference_loss: 0.4224\n", + "Epoch 6/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3256 - loss/inference_loss: 0.3256 - val_loss: 0.2495 - val_loss/inference_loss: 0.2495\n", + "Epoch 7/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3398 - loss/inference_loss: 0.3398 - val_loss: 0.4305 - val_loss/inference_loss: 0.4305\n", + "Epoch 8/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3210 - loss/inference_loss: 0.3210 - val_loss: 0.2533 - val_loss/inference_loss: 0.2533\n", + "Epoch 9/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.3113 - loss/inference_loss: 0.3113 - val_loss: 0.2671 - val_loss/inference_loss: 0.2671\n", + "Epoch 10/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3087 - loss/inference_loss: 0.3087 - val_loss: 0.3028 - val_loss/inference_loss: 0.3028\n", + "Epoch 11/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2995 - loss/inference_loss: 0.2995 - val_loss: 0.2349 - val_loss/inference_loss: 0.2349\n", + "Epoch 12/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.2947 - loss/inference_loss: 0.2947 - val_loss: 0.2673 - val_loss/inference_loss: 0.2673\n", + "Epoch 13/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2872 - loss/inference_loss: 0.2872 - val_loss: 0.2196 - val_loss/inference_loss: 0.2196\n", + "Epoch 14/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2843 - loss/inference_loss: 0.2843 - val_loss: 0.2882 - val_loss/inference_loss: 0.2882\n", + "Epoch 15/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.2764 - loss/inference_loss: 0.2764 - val_loss: 0.4631 - val_loss/inference_loss: 0.4631\n", + "Epoch 16/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2783 - loss/inference_loss: 0.2783 - val_loss: 0.2427 - val_loss/inference_loss: 0.2427\n", + "Epoch 17/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2758 - loss/inference_loss: 0.2758 - val_loss: 0.1848 - val_loss/inference_loss: 0.1848\n", + "Epoch 18/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2699 - loss/inference_loss: 0.2699 - val_loss: 0.1851 - val_loss/inference_loss: 0.1851\n", + "Epoch 19/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.2671 - loss/inference_loss: 0.2671 - val_loss: 0.2573 - val_loss/inference_loss: 0.2573\n", + "Epoch 20/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2590 - loss/inference_loss: 0.2590 - val_loss: 0.1604 - val_loss/inference_loss: 0.1604\n" ] } ], "source": [ - "%%time\n", - "cm_history = cm_approximator.fit(\n", - " epochs=epochs,\n", - " dataset=training_dataset,\n", - " validation_data=validation_dataset,\n", + "history = consistency_model_workflow.fit_offline(\n", + " training_data, \n", + " epochs=epochs, \n", + " batch_size=batch_size, \n", + " validation_data=validation_data\n", ")" ] }, @@ -811,19 +625,28 @@ "id": "a94a43f6", "metadata": {}, "source": [ - "## Good 'ol Affine Coupling Flow" + "## Good 'ol Coupling Flows\n", + "\n", + "Of course, BayesFlow also supports established coupling flow models with a variety of parameters, including the timeless *affine* and *spline* flows." ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 14, "id": "27b83a8f", "metadata": {}, "outputs": [], "source": [ - "inference_network = bf.networks.CouplingFlow(subnet=\"mlp\", coupling_kwargs={\"subnet_kwargs\": {\"dropout\": 0.0}})\n", + "affine_flow = bf.networks.CouplingFlow(\n", + " subnet=\"mlp\", \n", + " coupling_kwargs={\"subnet_kwargs\": {\"dropout\": 0.0}}\n", + ")\n", "\n", - "acf_approximator = bf.ContinuousApproximator(inference_network=inference_network, adapter=adapter)" + "spline_flow = bf.networks.CouplingFlow(\n", + " subnet=\"mlp\", \n", + " coupling_kwargs={\"subnet_kwargs\": {\"dropout\": 0.0}}, \n", + " transform=\"spline\" # here is how we change the underlying transform\n", + ")" ] }, { @@ -833,97 +656,165 @@ "metadata": {}, "outputs": [], "source": [ - "initial_learning_rate = 5e-4\n", - "scheduled_lr = keras.optimizers.schedules.CosineDecay(\n", - " initial_learning_rate=initial_learning_rate,\n", - " decay_steps=total_steps,\n", - " alpha=1e-8\n", + "affine_flow_workflow = bf.BasicWorkflow(\n", + " simulator=simulator,\n", + " adapter=adapter,\n", + " inference_network=affine_flow,\n", ")\n", "\n", - "optimizer = keras.optimizers.Adam(learning_rate=scheduled_lr, clipnorm=1.0)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "0b70dee5", - "metadata": {}, - "outputs": [], - "source": [ - "acf_approximator.compile(optimizer=optimizer)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "50e24e10", - "metadata": {}, - "outputs": [], - "source": [ - "%%time\n", - "acf_history = acf_approximator.fit(\n", - " epochs=epochs,\n", - " dataset=training_dataset,\n", - " validation_data=validation_dataset,\n", + "\n", + "spline_flow_workflow = bf.BasicWorkflow(\n", + " simulator=simulator,\n", + " adapter=adapter,\n", + " inference_network=spline_flow,\n", ")" ] }, { "cell_type": "markdown", - "id": "056d3cf2", - "metadata": {}, - "source": [ - "## Going Splines" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "6ae7ba3b", + "id": "8aecf471", "metadata": {}, - "outputs": [], "source": [ - "inference_network = bf.networks.CouplingFlow(\n", - " subnet=\"mlp\", \n", - " coupling_kwargs={\"subnet_kwargs\": {\"dropout\": 0.0}},\n", - " transform=\"spline\"\n", - ")\n", - "\n", - "spline_approximator = bf.ContinuousApproximator(inference_network=inference_network, adapter=adapter)" + "### Coupling Flow Training" ] }, { "cell_type": "code", "execution_count": 16, - "id": "174d8e65", + "id": "f52e8e49", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:bayesflow:Fitting on dataset instance of OfflineDataset.\n", + "INFO:bayesflow:Building on a test batch.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 15ms/step - loss: -0.7232 - loss/inference_loss: -0.7232 - val_loss: -0.8731 - val_loss/inference_loss: -0.8731\n", + "Epoch 2/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.2120 - loss/inference_loss: -1.2120 - val_loss: -1.4010 - val_loss/inference_loss: -1.4010\n", + "Epoch 3/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.2095 - loss/inference_loss: -1.2095 - val_loss: -1.4121 - val_loss/inference_loss: -1.4121\n", + "Epoch 4/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -1.4549 - loss/inference_loss: -1.4549 - val_loss: -1.5548 - val_loss/inference_loss: -1.5548\n", + "Epoch 5/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -1.5452 - loss/inference_loss: -1.5452 - val_loss: -1.7149 - val_loss/inference_loss: -1.7149\n", + "Epoch 6/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -1.6153 - loss/inference_loss: -1.6153 - val_loss: -1.7353 - val_loss/inference_loss: -1.7353\n", + "Epoch 7/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.6965 - loss/inference_loss: -1.6965 - val_loss: -1.7457 - val_loss/inference_loss: -1.7457\n", + "Epoch 8/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -1.7951 - loss/inference_loss: -1.7951 - val_loss: -1.7935 - val_loss/inference_loss: -1.7935\n", + "Epoch 9/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.8665 - loss/inference_loss: -1.8665 - val_loss: -1.8359 - val_loss/inference_loss: -1.8359\n", + "Epoch 10/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.9356 - loss/inference_loss: -1.9356 - val_loss: -2.1203 - val_loss/inference_loss: -2.1203\n", + "Epoch 11/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.0007 - loss/inference_loss: -2.0007 - val_loss: -1.8282 - val_loss/inference_loss: -1.8282\n", + "Epoch 12/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.0690 - loss/inference_loss: -2.0690 - val_loss: -2.2087 - val_loss/inference_loss: -2.2087\n", + "Epoch 13/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.1525 - loss/inference_loss: -2.1525 - val_loss: -1.8864 - val_loss/inference_loss: -1.8864\n", + "Epoch 14/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.2135 - loss/inference_loss: -2.2135 - val_loss: -2.5540 - val_loss/inference_loss: -2.5540\n", + "Epoch 15/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.2743 - loss/inference_loss: -2.2743 - val_loss: -2.3367 - val_loss/inference_loss: -2.3367\n", + "Epoch 16/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.3207 - loss/inference_loss: -2.3207 - val_loss: -2.3932 - val_loss/inference_loss: -2.3932\n", + "Epoch 17/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.3702 - loss/inference_loss: -2.3702 - val_loss: -2.3515 - val_loss/inference_loss: -2.3515\n", + "Epoch 18/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.4036 - loss/inference_loss: -2.4036 - val_loss: -2.2006 - val_loss/inference_loss: -2.2006\n", + "Epoch 19/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.4322 - loss/inference_loss: -2.4322 - val_loss: -2.4065 - val_loss/inference_loss: -2.4065\n", + "Epoch 20/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.4120 - loss/inference_loss: -2.4120 - val_loss: -2.5755 - val_loss/inference_loss: -2.5755\n" + ] + } + ], "source": [ - "initial_learning_rate = 5e-4\n", - "scheduled_lr = keras.optimizers.schedules.CosineDecay(\n", - " initial_learning_rate=initial_learning_rate,\n", - " decay_steps=total_steps,\n", - " alpha=1e-8\n", - ")\n", - "\n", - "optimizer = keras.optimizers.AdamW(learning_rate=scheduled_lr, clipnorm=1.0)\n", - "\n", - "\n", - "spline_approximator.compile(optimizer=optimizer)" + "history = affine_flow_workflow.fit_offline(\n", + " training_data, \n", + " epochs=epochs, \n", + " batch_size=batch_size,\n", + " validation_data=validation_data\n", + ")" ] }, { "cell_type": "code", - "execution_count": null, - "id": "318b8420", + "execution_count": 24, + "id": "afa9839f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:bayesflow:Fitting on dataset instance of OfflineDataset.\n", + "INFO:bayesflow:Building on a test batch.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m50s\u001b[0m 32ms/step - loss: -1.3529 - loss/inference_loss: -1.3529 - val_loss: -1.9426 - val_loss/inference_loss: -1.9426\n", + "Epoch 2/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.0683 - loss/inference_loss: -2.0683 - val_loss: -2.2129 - val_loss/inference_loss: -2.2129\n", + "Epoch 3/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.2016 - loss/inference_loss: -2.2016 - val_loss: -2.1892 - val_loss/inference_loss: -2.1892\n", + "Epoch 4/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.2874 - loss/inference_loss: -2.2874 - val_loss: -1.9549 - val_loss/inference_loss: -1.9549\n", + "Epoch 5/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.4774 - loss/inference_loss: -2.4774 - val_loss: -2.6856 - val_loss/inference_loss: -2.6856\n", + "Epoch 6/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 26ms/step - loss: -2.3485 - loss/inference_loss: -2.3485 - val_loss: -2.5269 - val_loss/inference_loss: -2.5269\n", + "Epoch 7/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -2.4170 - loss/inference_loss: -2.4170 - val_loss: -2.5098 - val_loss/inference_loss: -2.5098\n", + "Epoch 8/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.4346 - loss/inference_loss: -2.4346 - val_loss: -2.5090 - val_loss/inference_loss: -2.5090\n", + "Epoch 9/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 25ms/step - loss: -2.5990 - loss/inference_loss: -2.5990 - val_loss: -2.9927 - val_loss/inference_loss: -2.9927\n", + "Epoch 10/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -2.7069 - loss/inference_loss: -2.7069 - val_loss: -2.8296 - val_loss/inference_loss: -2.8296\n", + "Epoch 11/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.8685 - loss/inference_loss: -2.8685 - val_loss: -2.8763 - val_loss/inference_loss: -2.8763\n", + "Epoch 12/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.0124 - loss/inference_loss: -3.0124 - val_loss: -3.1694 - val_loss/inference_loss: -3.1694\n", + "Epoch 13/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 22ms/step - loss: -3.1153 - loss/inference_loss: -3.1153 - val_loss: -3.0405 - val_loss/inference_loss: -3.0405\n", + "Epoch 14/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.1993 - loss/inference_loss: -3.1993 - val_loss: -3.1885 - val_loss/inference_loss: -3.1885\n", + "Epoch 15/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.2972 - loss/inference_loss: -3.2972 - val_loss: -3.2990 - val_loss/inference_loss: -3.2990\n", + "Epoch 16/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.3746 - loss/inference_loss: -3.3746 - val_loss: -3.3764 - val_loss/inference_loss: -3.3764\n", + "Epoch 17/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.4334 - loss/inference_loss: -3.4334 - val_loss: -3.4334 - val_loss/inference_loss: -3.4334\n", + "Epoch 18/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.4857 - loss/inference_loss: -3.4857 - val_loss: -3.3835 - val_loss/inference_loss: -3.3835\n", + "Epoch 19/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.5123 - loss/inference_loss: -3.5123 - val_loss: -3.2589 - val_loss/inference_loss: -3.2589\n", + "Epoch 20/20\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.4961 - loss/inference_loss: -3.4961 - val_loss: -3.4955 - val_loss/inference_loss: -3.4955\n" + ] + } + ], "source": [ - "# DOES NOT CURRENTLY WORK\n", - "spline_history = spline_approximator.fit(\n", - " epochs=epochs,\n", - " dataset=training_dataset,\n", - " validation_data=validation_dataset,\n", + "history = spline_flow_workflow.fit_offline(\n", + " training_data, \n", + " epochs=epochs, \n", + " batch_size=batch_size,\n", + " validation_data=validation_data\n", ")" ] }, @@ -944,20 +835,46 @@ "\n", "The two moons posterior at point $x = (0, 0)$ should resemble two crescent shapes. Below, we plot the corresponding posterior samples and posterior density. \n", "\n", - "These results suggest that both **Flow Matching** and **Consistency Models** can approximate the expected analytical posterior well. You can achieve an even better fit if you use online training, more epochs, or better optimizer hyperparameters." + "These results suggest that these generative networks can approximate the true posterior well. You can achieve an even better fit if you use online training, more epochs, or better optimizer hyperparameters." ] }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 25, "id": "073bcd0b", "metadata": {}, "outputs": [ + { + "ename": "ValueError", + "evalue": "Exception encountered when calling SplineTransform.call().\n\n\u001b[1mDiscriminant must be non-negative.\u001b[0m\n\nArguments received by SplineTransform.call():\n • xz=tf.Tensor(shape=(1, 3000, 1), dtype=float32)\n • parameters={'horizontal_edges': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'vertical_edges': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'derivatives': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'affine_scale': 'tf.Tensor(shape=(1, 3000, 1), dtype=float32)', 'affine_shift': 'tf.Tensor(shape=(1, 3000, 1), dtype=float32)'}\n • inverse=True", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[25], line 23\u001b[0m\n\u001b[0;32m 18\u001b[0m colors \u001b[38;5;241m=\u001b[39m [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#153c7a\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#7a1515\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#157a2d\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#7a6f15\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m 20\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m ax, net, name, color \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(axes, nets, names, colors):\n\u001b[0;32m 21\u001b[0m \n\u001b[0;32m 22\u001b[0m \u001b[38;5;66;03m# Obtain samples\u001b[39;00m\n\u001b[1;32m---> 23\u001b[0m samples \u001b[38;5;241m=\u001b[39m net\u001b[38;5;241m.\u001b[39msample(conditions\u001b[38;5;241m=\u001b[39mconditions, num_samples\u001b[38;5;241m=\u001b[39mnum_samples)[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtheta\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m 25\u001b[0m \u001b[38;5;66;03m# Plot samples\u001b[39;00m\n\u001b[0;32m 26\u001b[0m ax\u001b[38;5;241m.\u001b[39mscatter(samples[\u001b[38;5;241m0\u001b[39m, :, \u001b[38;5;241m0\u001b[39m], samples[\u001b[38;5;241m0\u001b[39m, :, \u001b[38;5;241m1\u001b[39m], color\u001b[38;5;241m=\u001b[39mcolor, alpha\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.75\u001b[39m, s\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\approximators\\continuous_approximator.py:144\u001b[0m, in \u001b[0;36mContinuousApproximator.sample\u001b[1;34m(self, num_samples, conditions, split, **kwargs)\u001b[0m\n\u001b[0;32m 142\u001b[0m conditions \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39madapter(conditions, strict\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, stage\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minference\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 143\u001b[0m conditions \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mtree\u001b[38;5;241m.\u001b[39mmap_structure(keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mconvert_to_tensor, conditions)\n\u001b[1;32m--> 144\u001b[0m conditions \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minference_variables\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_sample(num_samples\u001b[38;5;241m=\u001b[39mnum_samples, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mconditions, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)}\n\u001b[0;32m 145\u001b[0m conditions \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mtree\u001b[38;5;241m.\u001b[39mmap_structure(keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mconvert_to_numpy, conditions)\n\u001b[0;32m 146\u001b[0m conditions \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39madapter(conditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, strict\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\approximators\\continuous_approximator.py:186\u001b[0m, in \u001b[0;36mContinuousApproximator._sample\u001b[1;34m(self, num_samples, inference_conditions, summary_variables, **kwargs)\u001b[0m\n\u001b[0;32m 183\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 184\u001b[0m batch_shape \u001b[38;5;241m=\u001b[39m (num_samples,)\n\u001b[1;32m--> 186\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minference_network\u001b[38;5;241m.\u001b[39msample(\n\u001b[0;32m 187\u001b[0m batch_shape,\n\u001b[0;32m 188\u001b[0m conditions\u001b[38;5;241m=\u001b[39minference_conditions,\n\u001b[0;32m 189\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mfilter_kwargs(kwargs, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minference_network\u001b[38;5;241m.\u001b[39msample),\n\u001b[0;32m 190\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\utils\\decorators.py:61\u001b[0m, in \u001b[0;36malias..alias_wrapper..wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 58\u001b[0m matches \u001b[38;5;241m=\u001b[39m [name \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m kwargs \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m aliases]\n\u001b[0;32m 60\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m matches:\n\u001b[1;32m---> 61\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 63\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(matches) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m1\u001b[39m \u001b[38;5;129;01mor\u001b[39;00m (\u001b[38;5;28mlen\u001b[39m(matches) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(args) \u001b[38;5;241m>\u001b[39m argpos):\n\u001b[0;32m 64\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[0;32m 65\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfn\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m() got multiple values for argument \u001b[39m\u001b[38;5;132;01m{\u001b[39;00margname\u001b[38;5;132;01m!r}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 66\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThis argument is also aliased as \u001b[39m\u001b[38;5;132;01m{\u001b[39;00maliases\u001b[38;5;132;01m!r}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 67\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\utils\\decorators.py:93\u001b[0m, in \u001b[0;36margument_callback..callback_wrapper..wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 90\u001b[0m args \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlist\u001b[39m(args)\n\u001b[0;32m 91\u001b[0m args[argpos] \u001b[38;5;241m=\u001b[39m callback(args[argpos])\n\u001b[1;32m---> 93\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\inference_network.py:42\u001b[0m, in \u001b[0;36mInferenceNetwork.sample\u001b[1;34m(self, batch_shape, conditions, **kwargs)\u001b[0m\n\u001b[0;32m 39\u001b[0m \u001b[38;5;129m@allow_batch_size\u001b[39m\n\u001b[0;32m 40\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21msample\u001b[39m(\u001b[38;5;28mself\u001b[39m, batch_shape: Shape, conditions: Tensor \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tensor:\n\u001b[0;32m 41\u001b[0m samples \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbase_distribution\u001b[38;5;241m.\u001b[39msample(batch_shape)\n\u001b[1;32m---> 42\u001b[0m samples \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m(samples, conditions\u001b[38;5;241m=\u001b[39mconditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, density\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 43\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m samples\n", + "File \u001b[1;32mc:\\Users\\radevs\\AppData\\Local\\anaconda3\\envs\\bf\\Lib\\site-packages\\keras\\src\\utils\\traceback_utils.py:122\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 119\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n\u001b[0;32m 120\u001b[0m \u001b[38;5;66;03m# To get the full stack trace, call:\u001b[39;00m\n\u001b[0;32m 121\u001b[0m \u001b[38;5;66;03m# `keras.config.disable_traceback_filtering()`\u001b[39;00m\n\u001b[1;32m--> 122\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\u001b[38;5;241m.\u001b[39mwith_traceback(filtered_tb) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 123\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[0;32m 124\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m filtered_tb\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\inference_network.py:26\u001b[0m, in \u001b[0;36mInferenceNetwork.call\u001b[1;34m(self, xz, conditions, inverse, density, training, **kwargs)\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall\u001b[39m(\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m 18\u001b[0m xz: Tensor,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[0;32m 24\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tensor \u001b[38;5;241m|\u001b[39m \u001b[38;5;28mtuple\u001b[39m[Tensor, Tensor]:\n\u001b[0;32m 25\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inverse:\n\u001b[1;32m---> 26\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inverse(xz, conditions\u001b[38;5;241m=\u001b[39mconditions, density\u001b[38;5;241m=\u001b[39mdensity, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 27\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward(xz, conditions\u001b[38;5;241m=\u001b[39mconditions, density\u001b[38;5;241m=\u001b[39mdensity, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\coupling_flow.py:110\u001b[0m, in \u001b[0;36mCouplingFlow._inverse\u001b[1;34m(self, z, conditions, density, training, **kwargs)\u001b[0m\n\u001b[0;32m 108\u001b[0m log_det \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mzeros(keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mshape(z)[:\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m])\n\u001b[0;32m 109\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m layer \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mreversed\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minvertible_layers):\n\u001b[1;32m--> 110\u001b[0m x, det \u001b[38;5;241m=\u001b[39m layer(x, conditions\u001b[38;5;241m=\u001b[39mconditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 111\u001b[0m log_det \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m det\n\u001b[0;32m 113\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m density:\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\couplings\\dual_coupling.py:51\u001b[0m, in \u001b[0;36mDualCoupling.call\u001b[1;34m(self, xz, conditions, inverse, training, **kwargs)\u001b[0m\n\u001b[0;32m 47\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall\u001b[39m(\n\u001b[0;32m 48\u001b[0m \u001b[38;5;28mself\u001b[39m, xz: Tensor, conditions: Tensor \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, inverse: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, training: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[0;32m 49\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m (Tensor, Tensor):\n\u001b[0;32m 50\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inverse:\n\u001b[1;32m---> 51\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inverse(xz, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward(xz, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\couplings\\dual_coupling.py:68\u001b[0m, in \u001b[0;36mDualCoupling._inverse\u001b[1;34m(self, z, conditions, training, **kwargs)\u001b[0m\n\u001b[0;32m 66\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Transform (g(x1; f(x2; x1)), f(x2; x1)) -> (x1, x2)\"\"\"\u001b[39;00m\n\u001b[0;32m 67\u001b[0m z1, z2 \u001b[38;5;241m=\u001b[39m z[\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m, : \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpivot], z[\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpivot :]\n\u001b[1;32m---> 68\u001b[0m (z2, z1), log_det2 \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcoupling2(z2, z1, conditions\u001b[38;5;241m=\u001b[39mconditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 69\u001b[0m (x1, x2), log_det1 \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcoupling1(z1, z2, conditions\u001b[38;5;241m=\u001b[39mconditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 71\u001b[0m x \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mconcatenate([x1, x2], axis\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\couplings\\single_coupling.py:63\u001b[0m, in \u001b[0;36mSingleCoupling.call\u001b[1;34m(self, x1, x2, conditions, inverse, training, **kwargs)\u001b[0m\n\u001b[0;32m 59\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall\u001b[39m(\n\u001b[0;32m 60\u001b[0m \u001b[38;5;28mself\u001b[39m, x1: Tensor, x2: Tensor, conditions: Tensor \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, inverse: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, training: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[0;32m 61\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m ((Tensor, Tensor), Tensor):\n\u001b[0;32m 62\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inverse:\n\u001b[1;32m---> 63\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inverse(x1, x2, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 64\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward(x1, x2, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\couplings\\single_coupling.py:82\u001b[0m, in \u001b[0;36mSingleCoupling._inverse\u001b[1;34m(self, z1, z2, conditions, training, **kwargs)\u001b[0m\n\u001b[0;32m 80\u001b[0m x1 \u001b[38;5;241m=\u001b[39m z1\n\u001b[0;32m 81\u001b[0m parameters \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_parameters(x1, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m---> 82\u001b[0m x2, log_det \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransform(z2, parameters\u001b[38;5;241m=\u001b[39mparameters, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m 84\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m (x1, x2), log_det\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\transforms\\transform.py:18\u001b[0m, in \u001b[0;36mTransform.call\u001b[1;34m(self, xz, parameters, inverse)\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall\u001b[39m(\u001b[38;5;28mself\u001b[39m, xz: Tensor, parameters: \u001b[38;5;28mdict\u001b[39m[\u001b[38;5;28mstr\u001b[39m, Tensor], inverse: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m (Tensor, Tensor):\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inverse:\n\u001b[1;32m---> 18\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inverse(xz, parameters)\n\u001b[0;32m 19\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward(xz, parameters)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\transforms\\spline_transform.py:225\u001b[0m, in \u001b[0;36mSplineTransform._inverse\u001b[1;34m(self, z, parameters)\u001b[0m\n\u001b[0;32m 222\u001b[0m parameters \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124medges\u001b[39m\u001b[38;5;124m\"\u001b[39m: edges, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mderivatives\u001b[39m\u001b[38;5;124m\"\u001b[39m: derivatives}\n\u001b[0;32m 224\u001b[0m \u001b[38;5;66;03m# compute the spline and jacobian\u001b[39;00m\n\u001b[1;32m--> 225\u001b[0m spline, spline_log_jac \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmethod_fn(z, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparameters, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m 227\u001b[0m x \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mwhere(inside, spline, affine)\n\u001b[0;32m 228\u001b[0m log_jac \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mwhere(inside, spline_log_jac, affine_log_jac)\n", + "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\transforms\\_rational_quadratic.py:67\u001b[0m, in \u001b[0;36m_rational_quadratic_spline\u001b[1;34m(x, edges, derivatives, inverse)\u001b[0m\n\u001b[0;32m 65\u001b[0m discriminant \u001b[38;5;241m=\u001b[39m b\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m2\u001b[39m \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m4\u001b[39m \u001b[38;5;241m*\u001b[39m a \u001b[38;5;241m*\u001b[39m c\n\u001b[0;32m 66\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mall(discriminant \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m):\n\u001b[1;32m---> 67\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mDiscriminant must be non-negative.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 69\u001b[0m xi \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2\u001b[39m \u001b[38;5;241m*\u001b[39m c \u001b[38;5;241m/\u001b[39m (\u001b[38;5;241m-\u001b[39mb \u001b[38;5;241m-\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39msqrt(discriminant))\n\u001b[0;32m 70\u001b[0m result \u001b[38;5;241m=\u001b[39m xi \u001b[38;5;241m*\u001b[39m dx \u001b[38;5;241m+\u001b[39m xk\n", + "\u001b[1;31mValueError\u001b[0m: Exception encountered when calling SplineTransform.call().\n\n\u001b[1mDiscriminant must be non-negative.\u001b[0m\n\nArguments received by SplineTransform.call():\n • xz=tf.Tensor(shape=(1, 3000, 1), dtype=float32)\n • parameters={'horizontal_edges': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'vertical_edges': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'derivatives': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'affine_scale': 'tf.Tensor(shape=(1, 3000, 1), dtype=float32)', 'affine_shift': 'tf.Tensor(shape=(1, 3000, 1), dtype=float32)'}\n • inverse=True" + ] + }, { "data": { - "image/png": "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vOkqI239+vXBIHJ7n3/+efAzzNatW3t1Deecc44BzKuvvtpp3dy5czt9tjmQjoH0119/3QDmlltuCW7z61//2gDBbMPuAumBByff+MY3Op3H7/cHkxja39zW1dUFA0xvvfVWp/1eeeWVYN92DGwc6u9KgXQROZoC2ecdv+0TeHDZ1bh7pAPpkZGRpqSkpNN+V1xxhYG2b/Z2tfyPf/xjl+f785//bADz3e9+t8v1Hf3hD38wgJk0aVKvtu/o/vvvN9CWxdyVr3/96wYw119/fcjyww2kdxdzCNz/dgzqHk4g/WA+T/znP/8xgElOTjY1NTWd9gv83g81kN7Tn466GmNra2uDY31Xn18Cn4csyzIFBQXB5S+88IIBQr456HK5jGVZ5vLLLzczZ8404eHhpqmpKbg+8LDhvffe6/V1ytGjGukifWDUqFHMmDGj05/x48f3av+lS5cCcNVVV9G/f/9O62+++WbCw8MpKioiPz8/uHzmzJkAfPzxx8Flgb/PmTOHadOm8dlnnwXran3xxRc0NjYyderUQ57UxeFwcM0111BTU8Nbb70FwLPPPovP5+v1JKPFxcX8+te/5uqrr+b888/n7LPP5uyzz+aFF14AIDc396DaVFBQwKZNmwgLC+Ouu+46qH0nTpzY5SzygYlgeqpr3p3vfe97vT7esmXLgLYJWh0OR6f95s+ff9DnFxE5UdXX1wMQHR190Ps2NDSwcuVKAO64445O66OiovjBD34A7B93O/r+97/faVlKSkqw/mf79/DBgwcDbXOW9FSL9UACx3nppZc61c88FEVFRaxZs4a0tDTmzp3b5TaB5R999FGX67vqh/HjxxMREUFtbS2VlZXB5YH655dffjmjRo3qVRu/+93vArB48eKQ5S6Xi3feeYewsDCuvfbaXh2rKxdddBEpKSksWbIEj8cDtNVMD3yG6UngtdHVa8iyLH70ox+FbAfwySef0NjYyNChQ7nooos67feNb3yDgQMHdlreF78rEZGj4emnnwZg3rx5IcsDNb+fe+65wxoLD8XXvvY1Bg0a1Gl5V/ddra2tvP3229jtdr7zne90ebyDfb89nM8ssH8cuf3227tcf+edd4Zs11euuOKKLmMOt956KwDLly/vcq6wQ3EwnycC98VXXHEF8fHxnfY73PvitLS0LmM2vZ18/NNPP6WxsZEhQ4bw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ac/huuWWW/jkk0+47LLL8Pv9rFu3jqioKK677jrWrFkTHK/bi4mJ4cMPP+Tee+9lyJAh5OfnU19fz913381HH31EeHh4t+c7mr8rEZHeCpRpufTSS4mPjz/g9oGs9OO1vAvA5ZdfzqZNm7jzzjsZNmwY+fn5bNq0iaioKC6//HIWL17Mfffdd9DH/e///m/y8/P5r//6LyZOnEhFRQVr1qyhurqaGTNm8PDDD1NQUMC8efNC9ps7dy6rV6/m29/+NhEREaxbtw5jDJdffjmffvopP/zhDzudy7IsXn31VRYsWEB6ejqFhYW43W5+8pOfsHTp0gNmbZ922ml8/vnnXHrppRQXF7Nnzx6ysrJ48sknexyvj4YJEybw5Zdfcs011xAZGUleXh6xsbH85S9/4U9/+lNwItVjdW8cGRnJu+++yx//+EemTp1KUVERW7duZdy4cTz00EOsWLGC5OTkLvftKWbTfpnNZgt+k1+OT5YxvZySWEREjrrVq1czdepUsrKyQsrhiIiInAz++te/csstt/DNb36TF1988Vg3R0RE5KT0ne98h8WLF7No0aI+nY/kaKmsrCQlJYWEhASqq6uPdXPkFKaMdBGR49iiRYsANGu3iIiclAKTbgUy00VEREQ6CtwXByaWFzlWFEgXETnGcnJyeP7552lpaQku83g8LFy4kCeeeAKbzRacxExERORk8fLLL/Pll18yYsQIvva1rx3r5oiIiMgxtGHDBp588kkaGhqCy4wxPPPMM/z3f/83ADfffPOxap4IAAcu3CgiIkdUUVER8+fPx+l0Mnz4cOLi4ti6dSt1dXVAW73fiRMnHttGioiI9JHzzjuP+vp61q5dC8BDDz2Ezab8HhERkVNZZWUlN910E7feeitDhw4lOTmZHTt2UFlZCcBNN93EpZdeeoxbKac6BdJFRI6xc845h9tvv52cnBxKS0vZsWMHSUlJzJw5k9tvv50LL7zwWDdRRESkz3z00UfY7XZGjBjBPffcc9xMMioiIiLHzrhx4/iv//ovli5dSklJCcXFxcTFxTF79mx+8IMf8K1vfetYN1FEk42KiIiIiIiIiIiIiPRE36EUEREREREREREREemBAul9xBhDXV0dSvAXERE5MWjsFhERObFo7BYRkWNJgfQ+Ul9fT3x8PPX19ce6KV3y+/2UlZXh9/uPdVNOaOrHw6c+7Bvqx8OnPhSN3acG9ePhUx/2DfXj4VMfisbuU4P68fCpD/uG+vHwnWx9qEC6iIiIiIiIiIiIiEgPFEgXEREREREREREREemBAukiIiIiIiIiIiIiIj1QIF1EREREREREREREpAcKpIuIiIiIiIiIiIiI9ECBdBERERERERERERGRHiiQLiIiIiIiIiIiIiLSAwXSRURERERERERERER6oEC6iIiIiIiIiIiIiEgPFEgXEREREREREREREemBAukiIiIiIiIiIiIiIj1QIF1EREREREREREREpAcKpIuIiIiIiIiIiIiI9ECBdBERERERERERERGRHiiQLiIiIiIiIiIiIiLSAwXSRURERERERERERER6oEC6iIiIiIiIiIiIiEgPFEgXEREREREREREREemBAukiIiIiIiIiIiIiIj1QIF1EREREREREREREpAcKpIuIiIiIiIiIiIiI9ECBdBERERERERERERGRHiiQLiIiIiIiIiIiIiLSAwXSRURERERERERERER6oEC6iIiIiIiIiIiIiEgPFEgXEREREREREREREemBAukiIiIiIiIiIiIiIj1QIF1EREREREREREREpAcKpIuIiIiIiIiIiIiI9ECBdBERERERERERERGRHiiQLiIiIiIiIiIiIiLSAwXSRURERERERERERER6oEC6iIiIiIiIiIiIiEgPFEgXEREREREREREREemBAukiIiIiIiIiIiIiIj1QIF1EREREREREREREpAcnbSD98ccfZ/jw4URERDBlyhQ++eSTXu23fPlyHA4HEydOPLINFBERkRAau0VERE4sGrtFRORUclIG0l944QXuuusu7r//ftauXcs555zDRRddRHFxcY/71dbWcsMNNzB79uyj1FIREREBjd0iIiInGo3dIiJyqrGMMeZYN6KvTZs2jcmTJ/PEE08El40dO5bLLruMRx55pNv9rrnmGkaNGoXdbue1115j3bp13W7b0tJCS0tL8N91dXUMHjyY6upq4uLi+uQ6+pLf78flcpGamorNdlI+Pzkq1I+HT33YN9SPh+9E6cPjuW19SWN3ZyfKa/R4p348fOrDvqF+PHwnSh8ez23rSxq7OztRXqPHO/Xj4VMf9g314+E7Ufqwt21zHOF2HHWtra2sXr2a++67L2T5hRdeyIoVK7rdb9GiRWzfvp1nnnmGhx566IDneeSRR/jFL37RabnL5aK5ufngG36E+f1+amtrMcYc1y/c45368fCpD/uG+vHwnSh92L9//2PdhCNOY3fXTpTX6PFO/Xj41Id9Q/14+E6UPtTYrbH7eH+NHu/Uj4dPfdg31I+H70Tpw96O3SddIL2iogKfz0e/fv1Clvfr14+ysrIu99m2bRv33Xcfn3zyCQ5H77rkJz/5CQsWLAj+O/BkPDU19bh9Mm5Z1nH/BOh4p348fOrDvqF+PHzqw+OHxu6u6TXaN9SPh0992DfUj4dPfXj80NjdNb1G+4b68fCpD/uG+vHwnWx9eNIF0gMsywr5tzGm0zIAn8/HvHnz+MUvfsFpp53W6+OHh4cTHh7eabnNZjtuXxiWZR3X7TtRqB8Pn/qwb6gfD5/68PiisbszvUb7hvrx8KkP+4b68fCpD48vGrs702u0b6gfD5/6sG+oHw/fydSHJ10gPSUlBbvd3ukpeHl5eaen5QD19fV8+eWXrF27lttvvx1oe1pijMHhcLB06VLOP//8o9J2ERGRU5HGbhERkROLxm4RETkVnfiPAjoICwtjypQpLFu2LGT5smXLOOusszptHxcXx4YNG1i3bl3wz80338zo0aNZt24d06ZNO1pNFxEROSVp7BYRETmxaOwWEZFT0UmXkQ6wYMECrr/+eqZOncr06dN58sknKS4u5uabbwba6qzt3r2bp556CpvNRmZmZsj+aWlpREREdFouIiIiR4bGbhERkROLxm4RETnVnJSB9G9961tUVlbyy1/+kj179pCZmcnbb7/N0KFDAdizZw/FxcXHuJUiIiISoLFbRETkxKKxW0RETjWWMcYc60acDOrq6oiPj6e2tva4nT28vLyctLS0k6K4/7Gifjx86sO+oX48fOpD0dh9alA/Hj71Yd9QPx4+9aFo7D41qB8Pn/qwb6gfD9/J1ocn/hWIiIiIiIiIiIiIiBxBCqSLiIiIiIiIiIiIiPRAgXQRERERERERERERkR4okC4iIiIiIiIiIiIi0gMF0kVEREREREREREREeqBAuoiIiIiIiIiIiIhIDxRIFxERERERERERERHpgQLpIiIiIiIiIiIiIiI9UCBdRERERERERERERKQHCqSLiIiIiIiIiIiIiPRAgXQRERERERERERERkR4okC4iIiIiIiIiIiIi0gMF0kVEREREREREREREeqBAuoiIiIiIiIiIiIhIDxRIFxERERERERERERHpgQLpIiIiIiIiIiIiIiI9UCBdRERERERERERERKQHCqSLiIiIiIiIiIiIiPRAgXQRERERERERERERkR4okC4iIiIiIiIiIiIi0gMF0kVEREREREREREREeqBAuoiIiIiIiIiIiIhIDxRIFxERERERERERERHpgQLpIiIiIiIiIiIiIiI9UCBdRERERERERERERKQHCqSLiIiIiIiIiIiIiPRAgXQRERERERERERERkR4okC4iIiIiIiIiIiIi0gMF0kVEREREREREREREeqBAuoiIiIiIiIiIiIhIDxRIFxE5CRQUu1i4OIeCYtexboqIiIiIiIiIyElHgXQRkZNAdk4ez761muycvGPdFBERERERERGRk47jWDdAREQO39xZmSE/RURERERERESk7ygjXUTkGOhNKZaDKdeSMSSVBTfOImNI6hFpi4iIiIiIiIjIqUyBdBGRY6B9KZbuAtlHq1yLysKIiIiIiIjI8a7AVcjCnCcpcBUe66bIKUqlXUREjpKCYhfZOXnMnZVJ1uh0lq/dQdbo9GAgu7LGTXJCNHNnZZIxJLXLci2BY1x63uk01NXy7LubmDtr/CFlogeoLIyIiMh+roIC8rKzyZw7l9SMjD47bsX27ax//30mzp5N2qhRfXZcERGRU0V23jKeXf0KAHMzLyA7bxlzMy8gI3X4MW6ZnCoUSBcROUoWvbqK595ew7KVW5g8djBFpdXk5pcyd1YmlTVu1mzeRWl5bUhAfcGNs0KOEQi6gyHK4eW5t9cDVqftDkagLIyIiIhAXnY2q599FoBZCxb03XHfeIPtX3yBo7GR8/vwuCIiIqeKuZkXBH+2D6ovmPXDY9ksOYUokC4icpjaZ5ofKDPc4/WRX+hi8tjBzLt4SnCf5IRoikuriIoMo6SsmiX/WUtljZuH77wkZP9A1nhbRno1jV6HMslFRET6UObcuSE/++y4l16KNyqKzNmz+/S4IiIip4qM1OHBoHn7oHpAgauw2yz1jut62lakOwqki4h0o7cB8uycPBa//jnL1+7g0QVzO20bOM7509q+xl1T3wQQcty5szJZvnYHBcUVuKrd3Z4rkD3u9/spL/dz1/WjsNlsBxXMFxERkc7al3Q5UCa6q6CAVYsWATBt/vxelYBJGTmSCbGx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Zw+dHg9zli1jxYYNIybOFZ6LiIhMD+6aCrbvfxF46KyLksKZwF1B+8yhIF1E5Co20bcVtr1UxY5fHWT9x25J9qh3+fzq2xcREblMRi8+mqh5SfxZREREpp9EhcsHVbmcCdyZMHCX6UNBuoiIfKBE4O5p9iYn0kVEROTSSiw+CvEKF02di4iITH9FrsJzCsbPNXCX6UNBuoiIjFl0FEhOoQ8PzdW3LyIicvkM7z0XERGRK8u5Bu4yfShIFxGRcRcdVWguIiIytTSBLiIiIjJ9KEgXEZEJFx0VERGRy290P7qIiIiITC3LVB+AiIhMvcT0eaLWRURERKZWoh+9xu2e6kMRERERETSRLiJy1RuvH11ERESmlvrRRURERKYXTaSLiFzlEv3o7sqaqT4UEREROS3Rj65aFxGRq4/H28iWyh/g8TZO9aGIyDCaSBcRucqpH11ERERERGT6cNdUsH3/iwBsLvvcFB+NiCQoSBcRucol+tFFRERERERk6pWXrB3xU0SmBwXpIiIiIiIiIiIi00SRq1CT6CLTkDrSRUREREREREREREQmoCBdRERERERERETkMtOioiIzi4J0ERERERERERGRyyyxqKi7pmKqD0VEzoE60kVERERERERERC4zLSoqMrMoSBcREREREREREbnMtKioyMyiahcRERERERERERERkQkoSBcRERERERERERERmYCCdBERERERERERkUng8TaypfIHeLyNU30oIjLJFKSLiIiIiIiIiIhMAndNBdv3v4i7pmKqD0WG0QccMhm02KiIiIiIiIiIiMgkKC9ZO+KnTA+JDzgALfAqF0xBuoiIiIiIiIiIyCQochUqqJ2G9AGHTAYF6SIiIiIiIiIiInLF0gccMhnUkS4iIiIiIiIiInIO1LUtcvVSkC4iIiIiIiIiInIOtJioyNVL1S4iIiIiIiIiIiLnQF3bIlevSzKR/rOf/Yw/+qM/4i//8i+prq4ecV9nZyeLFy++FE8rIiIiF0jXbhERkZlF126RqZHo2i5yFU71oYjIZTbpQfr27dt5+OGHGRwc5NChQ6xcuZLnn38+eX80GqWpqWmyn1ZEREQukK7dIiIiM4uu3SKXlnrQRWQ8k17tsmXLFp555hkef/xxAJ577jk+//nPYxgGjzzyyGQ/nYiIiFwkXbtFRERmFl27RS6tRA86wOayz03x0YjIdDHpQfr777/PQw89lPzzZz7zGbKzs3n44YdJTU3lIx/5yGQ/pYiIiFwEXbtFRERmFl27RS4Nj7cRd00FpQXLgYfUgy4iI0x6tUtqaio9PT0jbvvEJz7Btm3b+MxnPoPb7Z7spxQREZGLoGu3iIjIzKJrt8ilkZhEr247qh50ERlj0oP0kpISdu/ePeb2hx9+mH/8x39k06ZNk/2U49q6dSuFhYWkpqayYsUKfve73024/W9+8xtWrFhBamoqixcv5nvf+95lOU4REZGppmu3iIjIzKJrt8ilUV6ylg0rNIkuIuOb9CD90Ucf5fe///249/3FX/wFzzzzDAsXLpzspx3hP//zP3nsscf42te+xsGDB7n77rv5gz/4A5qbm8fdvrGxkT/8wz/k7rvv5uDBg3z1q1/li1/8Ii+88MIlPU4REZHpQNduERGRmUXXbpFLo8hVqEl0ETkrwzRNc6oPYrKtXLmSW2+9lX/5l39J3rZ8+XIefPBBvvGNb4zZ/oknnsDtdnP06NHkbV/4wheorq7mrbfeGvc5gsEgwWAw+ee+vj4WLFhAT08PmZmZk/hqJkcsFsPr9eJyubBYJv3zk6uGzuPF0zmcHDqPF2+mnMPpfGyTSdfusWbK39HpTufx4ukcTg6dx4s3U87hdD62yaRr91gz5e/odKfzePF0DieHzuPFmynn8FyP7bwXG+3t7eW73/0ur7/+Ok1NTQDk5ORQVFTEihUruPfee7njjjvOd7eTJhQKsX//fp588skRt993333s3bt33Me89dZb3HfffSNuW7duHf/+7/9OOBzGbrePecw3vvEN/vZv/3bM7V6vl6GhoYt4BZdGLBajt7cX0zSn9V/c6U7n8eLpHE4OnceLN1PO4dy5cy96H7p2x+nafXXSebx4OoeTQ+fx4s2Uc6hrt67d0/3v6HSn83jxdA4nh87jxZsp5/Bcr93nFaQ3NDTwkY98hJMnTzJ8kL2lpYXDhw/z0ksvAVBQUMCf//mf89hjj5GVlXU+T3HROjs7iUajzJkzZ8Ttc+bMob29fdzHtLe3j7t9JBKhs7OTefPmjXnMX//1X7N58+bknxOfjLtcrmn7ybhhGNP+E6DpTufx4ukcTg6dx4t3tZxDXbvP0LX76qTzePF0DieHzuPFu1rOoa7dZ+jafXXSebx4OoeTQ+fx4l1p5/C8gvTHH3+ctrY2PvvZz/KlL32J2bNnMzg4yJe+9CVeffVV/uRP/oQ333yTEydO8NRTT/HP//zPfP/73+eTn/zkpTr+szIMY8SfTdMcc9sHbT/e7QkpKSmkpKSMud1isUzbvxiGYUzr45spdB4vns7h5NB5vHhXwznUtfsMXbuvXjqPF0/ncHLoPF68q+Ec6tp9hq7dVy+dx4unczg5dB4v3pV0Ds/rFbz55pusWLGCf/3Xf6WkpITZs2dz7bXXkpubC8B//Md/0Nrayttvv83GjRvp7e3l05/+9IjOtEstPz8fq9U65lPwjo6OMZ9+J8ydO3fc7W02G3l5eZfsWEVERC41XbtFRERmFl27RUREpqfzCtKj0ShLly79wO1uu+02/u3f/o2DBw+ydOlSvvjFL7J///4LPsjz4XA4WLFiBRUVFSNur6io4M477xz3MXfccceY7V9//XU+9KEPjdvTJiIiMlPo2i0iIjKz6NotIiIyPZ1XkF5aWsrvf//7c97++uuv5/XXXyclJWXcVbsvlc2bN/Nv//Zv/PCHP+To0aN8+ctfprm5mS984QtAvGft0UcfTW7/hS98gaamJjZv3szRo0f54Q9/yL//+7/z+OOPX7ZjFhERuRR07RYREZlZdO0WERGZns4rSN+0aRMej4enn376nB+zcOFC1q5dy29/+9vzPrgL9cd//Md8+9vf5qmnnuLmm2/mt7/9Lb/4xS9YtGgRACdPnqS5uTm5fWFhIb/4xS948803ufnmm/m7v/s7vvOd7/CpT33qsh2ziIjIpaBrt8jVyevxULllC16PZ6oPRUTOk67dIiIi09N5LTb68MMP43a7+frXv05jYyNPP/30WfvPhuvr62NwcPCCD/JCbNq0iU2bNo17349+9KMxt91zzz0cOHDgEh+ViIjI5aVrt8jVqcbtZv/27QCUbd48xUcjIudD124REZHp6byCdIAf//jH5ObmsnXrVv7jP/6DT3ziEzQ1NY27bTgc5h//8R+prKzk9ttvv+iDFRERkfOna7fI1aekvHzETxGZWXTtFhERmX7OO0i3Wq380z/9E3/0R3/E17/+dX72s58l78vIyGDevHlkZGQQCoVobGwkEAhgtVp56qmnJvXARURE5Nzo2i1y9XEVFWkSXWQG07Vb5IN5vI24ayooL1lLkatwqg9HRK4C5x2kJ9xzzz385je/4dixY7zwwgu8+eabHDhwAM+wHkabzcZHP/pR/vf//t9nXblbRERELg9du0VERGYWXbtFzs5dU8H2/S8CsLnsc1N8NCJyNbjgID1h6dKlPPnkkzz55JMA9Pb20tPTg2EYXHPNNdhsF/0UIiIiMol07RYREZlZdO0WGau8ZO2InyIil9qkX22zsrLIysqa7N2KiIjIJaJrt4iIyMyia7cIFLkKNYkuIpeVZaoPQERERERERERERERkOlOQLiIiIiIiIiIiIiIyAQXpIiIiIiIiIiIiIiITUJAuIiIiIiIiIiIiIjIBBekiIiIiIiIiIiIiIhNQkC4iIiIiIiIiItNCfedxXj70K+o7j0/1oYiIjGCb6gMQERERERERERHxeBv561e+iWUoxqAtxObVn5vqQxIRSdJEuoiIiIiIiIiITDl3TQX1nY3My5zDAyUfnerDEREZQRPpIiIiIiIiIiIy5cpL1oIJZdesZEn+tVN9OCIiI2giXUREREREREREplyRq5DH7v1z5mXNmepDEREZQ0G6iIiIiIiIiIhMCY+3kS2VP8DjbZzqQxERmZCCdBERERERERERmRLumgq2738Rd03FVB+KiMiEFKSLiIiIiIiIiMhl5/E20uXvYd2ysng/uojINKbFRkVERERERERE5LJz11Tw6nsVFOUXTvWhiIh8IE2ki4iIiIiIiIjIZVdasByH1UHtqWOqdhGRaU9BuoiIiIiIiIiIXHbVbUcJRUMsm7NU1S4iMu2p2kVERERERERERC67RHheXrKWIpfqXURketNEuoiIiIiIiIiIXHIebyNbKn+Ax9sIQJGrkM1ln1OILiIzgoJ0ERERERERERG55Nw1FWzf/6L60EVkRlK1i8wYnmYv7soaystKKFromurDEREREREREZHzMLzKRURkptFEuswY7soatr+2H3dlzVQfioiIiIiIiIicB4+3EXdNhfrQRWTG0kS6zBjlZSUjfoqIiIiIiIjIzLCtagc7Drrp8vfw9P1PTPXhiIicN02ky4xRtNDF5s+Ujal18TR72fJcJZ5m7xQdmYiIiEw2r8dD5ZYteD2eqT4UERERuQiJBUZbetoYigTxBfqm+pBERC6IgnSZ8VT5IiIicuWpcbvZv307NW73VB+KiIiInKc36n7Hp/79L3ij7nfJBUa9/i5SbSlkp2Umt0uE7B5v4xQe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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAABPIAAAH/CAYAAADdWPNMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAADPJ0lEQVR4nOzdeVxU9f4/8NeZGfZdGFAUcEFRQzFxyT00NSsprcy8qVndMm+LUb9ry/223bpeu0XrpT3TyvasMS3lJu6miYiigg4gIIsMCAw7w8zn9wfNkZFhlW3g9Xw8eADnfD7nfD6zfObM+3wWSQghQERERERERERERN2aoqsLQERERERERERERM1jII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0RERERERL3Knj17MH/+fPj7+0OSJPz444/N5tm9ezfCw8Ph6OiIwYMH47333uv4ghIRXYaBPCIiIiIiIupVysvLERYWhnfeeadF6dPT03HDDTdg2rRpSEhIwNNPP41HHnkE33//fQeXlIjIkiSEEF1dCCIiIiIiIqKuIEkSNm/ejFtuuaXRNGvWrIFGo8Hp06flbStXrkRiYiIOHjzYCaUkIqqj6uoCEBEREREREXVnBw8exJw5cyy2zZ07Fx9//DEMBgPs7Owa5KmurkZ1dbX8v8lkwsWLF+Ht7Q1Jkjq8zETUtYQQKC0thb+/PxSK9hsQy0AeERERERERURPy8vLg5+dnsc3Pzw+1tbUoKChAv379GuRZu3YtXnjhhc4qIhF1U1lZWRgwYEC7HY+BPCIiIiIiIqJmXN6LzjxLVWO965566ilERUXJ/5eUlCAwMBBZWVlwd3fvuIISUbeg1+sREBAANze3dj0uA3lERERERERETejbty/y8vIstuXn50OlUsHb29tqHgcHBzg4ODTY7u7uzkAeUS/S3kPpuWotERERERERURMmTZqE2NhYi207duzAuHHjrM6PR0TUURjIIyIiIiIiol6lrKwMx44dw7FjxwAA6enpOHbsGDIzMwHUDYtdtmyZnH7lypXIyMhAVFQUTp8+jU8++QQff/wxnnjiia4oPhH1YhxaS0RERERERL3KkSNHEBERIf9vnstu+fLl+PTTT5GbmysH9QBg0KBB2LZtGx577DH897//hb+/P9566y3ceuutnV52IurdJGGeoZOIiIiIiIiIOoRer4eHhwdKSko4Rx5RL9BR73kOrSUiIiIiIiIiIrIBDOQRERERERERERHZAAbyiIiIiIiIiIiIbAADeURERERERERERDaAgTwiIiIiIiIiIiIbwEAeERERERERERGRDWAgj4iIiIiIiIiIyAYwkEdERERERERERGQDGMgjIiIiIiIiIiKyAQzkERERERERERER2QAG8oiIiIiIiIiIiGwAA3lEREREREREREQ2gIE8IiIiIiIiIiIiG8BAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0REREREREREZAMYyCMiIiIiIiIiIrIBDOQRERERERERERHZAAbyiIiIiIiIiIiIbAADeURERERERERERDaAgTwiIiIiIiIiIiIbwEAeERERERERERGRDWAgj4iIiIiIiIiIyAYwkEdERERERERERGQDGMgjIiIiIiIiIiKyAQzkERERERERERER2QAG8oiIiIiIiIiIiGwAA3lEREREREREREQ2gIE8IiIiIiIiIiIiG8BAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0REREREREREZAMYyCMiIiIiIiIiIrIBDOQRERERERERERHZAAbyiIiIiIiIiIiIbAADeURERERERERERDaAgTwiIiIiIiIiIiIbwEAeERERERERERGRDWAgj4iIiIiIiIiIyAYwkEdERERERERERGQDGMgjIiIiIiIiIiKyAQzkERERERERERER2QAG8oiIiIiIiIiIiGwAA3lEREREREREREQ2gIE8IiIiIiIiIiIiG8BAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0REREREREREZAMYyKM2O3fuHCRJwsCBA7u6KL3ep59+CkmScPfdd7cq365duyBJEq699toOKRdRT8Y2sHe7++67IUkSPv3003Y53sCBAyFJEs6dO9cux6OOYzQa8a9//QshISGwt7dv8DlaUVGBJ554AoMGDYKdnZ3F53N7v26obRq7burJ7TrbGCKinoOBPJKZP+Cb+nnjjTe6uphXrH593n777SbTPvbYY3La9rqoO3fuHJ5//nlexFOvtH//ftx///0YPnw4PDw84ODggP79++Omm27CRx99hPLy8q4uYqdjm9CQ+Uu2JEmwt7dHYWFho2lra2vh6+srp3/++ec7r6DUY4waNQqSJMHJyQl6vb7JtM8++yyeeeYZnDt3DqGhoZgyZQpGjRol7//rX/+K1157Dfn5+RgzZgymTJmCYcOGdXQVOsS5c+fw5JNPYty4cfDx8YG9vT18fHwwffp0vPTSSzh//nxXF7FXMgeEm/q55ZZburqYRETUQVRdXQDqfoYOHQpfX1+r+/r379/JpelYn332GR5++GGr+4xGI7766qt2P+e5c+fwwgsvYMaMGa3uQdfenJ2dERISgsDAwC4tB/V8FRUVWLFiBb755hsAgKOjI4YMGQInJydkZ2dj69at2Lp1K5599lls377d4ktxd2VnZ4eQkJArbhe7U5vQHRkMBnz99ddYtWqV1f3bt2+HTqfr5FJRT3Ls2DEkJSUBAKqqqvDdd9/hnnvusZpWCIH33nsPkiRh//79GDdunMX+oqIifPXVV3B2dkZycjICAgIs9vfr1w8hISHw8PDomMq0o7Vr1+L5559HTU0NFAoFhgwZgiFDhqCwsBD79u3D3r178fLLL+PDDz/EXXfd1dXFbRft1a53Fl9fXwwdOtTqvpEjR3ZyaYiIqLMwkEcNPP30073iy2RISAj++OMPpKSkICQkpMH+2NhY5OXlISQkBCkpKV1Qwo43YcIEJCcnd3UxqIczGAyYM2cO9u/fj759+2LdunW4/fbb4eTkJKc5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OTk5SEtLQ58+fTBjxgw89NBDmDNnTlcXkYja2e7du6FUKjF48GA8/vjj3WaRCyKirjZy5Ej8/e9/x44dO5CVlYXMzEy4u7tj1qxZ+Otf/4o77rijq4tIREQ2hotdEBEREREREXUwLnZB1Lt01Hue416IiIiIiIiIiIhsAAN57UQIAb1eD3ZwJCJbwraLiGwR2y4iIiLqrRjIayelpaXw8PBAaWlph53DZDIhLy8PJpOpw87RGXpKPQDWpTvqKfXoLGy7Wqen1KWn1APoOXXpKfXoLGy7Wod16X56Sj2AnlUXIiJbwEAeERERERERERGRDWAgj4iIiIiIiIiIyAYwkEdERERERERERGQDGMgjIiIiIiIiIiKyAQzkERERERERERER2QAG8oiIiIiIiIiIiGwAA3lEREREREREREQ2gIE8IiIiIiIiIiIiG8BAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0REREREREREZAMYyCMiIiIiIiIiIrIBPTaQFxMTg0GDBsHR0RHh4eHYu3dvi/Lt378fKpUKY8aM6dgCEhFZwbaLiGwR2y4iIiKiztEjA3lff/01Vq9ejWeeeQYJCQmYNm0a5s2bh8zMzCbzlZSUYNmyZZg1a1YnlZSI6BK2XURki9h2EREREXWeHhnIi46Oxr333ov77rsPI0aMwBtvvIGAgAC8++67TeZ74IEHsGTJEkyaNKmTSkpEdAnbLiKyRWy7iIiIiDqPqqsL0N5qamoQHx+PJ5980mL7nDlzcODAgUbzrV+/Hqmpqfj888/x0ksvNXue6upqVFdXy//r9XoAgMlkgslkamPpm2YymSCE6LDjd5aeUg+AdemOOqseCkX73gdh22Ubekpdeko9gJ5Tl86sR3u2X2y7bAPr0v30lHoAtnvtRURkq3pcIK+goABGoxF+fn4W2/38/JCXl2c1z9mzZ/Hkk09i7969UKla9pCsXbsWL7zwQoPtOp0OVVVVrS94C5hMJpSUlEAIYdMfZD2lHgDr0h11Vj369u3brsdj22Ubekpdeko9gJ5Tl86sR3u2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eFd/mC0RUXdQfzVbIiLqnRjIIyKrtJk6rInWQJtZAACIWh4hz3tXf/4786q00RvisGlrvJy2Pk1cUqP7iIjaS1uGwl4+J97l/7MnHhERERF1JwzkEZFVmrgkaDMLEBzoIwfuzEE7a6wF+Vqyj4iovbRlKOzlwToG74iIiIioO2Mgj4isqh98a8lw2KaCfE3tIyJqLxwKS0REREQ9HQN5RGQVg29EZGvYm46IiIiIejpFVxeAiIiIiIiIiIiImsdAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdmADgnkffvtt7j99tvx4IMPIjEx0WJfQUEBBg8e3BGnJSK6Imy7iMgWse0iIiIi6j3aPZC3adMmLF68GBUVFTh+/DgmTpyIjRs3yvuNRiMyMjLa+7RERFeEbRcR2SK2XURERES9i6q9DxgdHY1169bhiSeeAABs2LABDzzwACRJwtKlS9v7dERE7YJtFxHZIrZdRERERL1Luwfyzpw5g4ULF8r/L1++HJ6enli8eDEcHR0xffr09j4lEdEVY9tFRLaIbRcRERFR79LuQ2sdHR1RVFRkse3mm2/G+vXrsXz5cmg0mvY+pVUxMTEYNGgQHB0dER4ejr179zaZfvfu3QgPD4ejoyMGDx6M9957r1PKSUTdA9suIrJFbLuIiIiIepd2D+SFhoZi3759DbYvXrwYb775JlatWtXep2zg66+/xurVq/HMM88gISEB06ZNw7x585CZmWk1fXp6Om644QZMmzYNCQkJePrpp/HII4/g+++/7/CyElH3wLaLiGwR2y4iIiKi3qXdA3nLli3DkSNHrO7761//inXr1iEwMLC9T2shOjoa9957L+677z6MGDECb7zxBgICAvDuu+9aTf/ee+8hMDAQb7zxBkaMGIH77rsP99xzD1599dUOLScRdR9su4jIFrHtIiIiIupd2n2OvLvvvht33313o/ujoqIQFRXV3qeV1dTUID4+Hk8++aTF9jlz5uDAgQNW8xw8eBBz5syx2DZ37lx8/PHHMBgMsLOza5Cnuroa1dXV8v96vR4AYDKZYDKZrrQaVplMJgghOuz4naWn1ANgXbqjttZj2bJlWLZsWaP5Vq9ejdWrV8v7FYr2vQ/Ctss29JS69JR6AD2nLp3V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", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -972,18 +889,23 @@ "conditions = {\"x\": np.array([[0.0, 0.0]]).astype(\"float32\")}\n", "\n", "# Prepare figure\n", - "f, axes = plt.subplots(1, 3, figsize=(15, 6))\n", - "\n", - "# Obtain samples from the two approximators\n", - "nets = [fm_approximator, cm_approximator, acf_approximator]\n", - "names = [\"Flow Matching\", \"Consistency Model\", \"Affine Coupling Flow\"]\n", - "colors = [\"#153c7a\", \"#7a1515\", \"#157a2d\"]\n", + "f, axes = plt.subplots(1, 4, figsize=(15, 6))\n", + "\n", + "# Obtain samples from the approximators (can also use the workflows' methods)\n", + "nets = [\n", + " flow_matching_workflow.approximator, \n", + " consistency_model_workflow.approximator,\n", + " affine_flow_workflow.approximator,\n", + " spline_flow_workflow.approximator\n", + "]\n", + "names = [\"Flow Matching\", \"Consistency Model\", \"Affine Coupling Flow\", \"Spline Coupling Flow\"]\n", + "colors = [\"#153c7a\", \"#7a1515\", \"#157a2d\", \"#7a6f15\"]\n", "\n", "for ax, net, name, color in zip(axes, nets, names, colors):\n", "\n", " # Obtain samples\n", " samples = net.sample(conditions=conditions, num_samples=num_samples)[\"theta\"]\n", - " \n", + "\n", " # Plot samples\n", " ax.scatter(samples[0, :, 0], samples[0, :, 1], color=color, alpha=0.75, s=0.5)\n", " sns.despine(ax=ax)\n", @@ -1007,7 +929,9 @@ "\n", "1. Talts, S., Betancourt, M., Simpson, D., Vehtari, A., & Gelman, A. (2018). Validating Bayesian inference algorithms with simulation-based calibration. *arXiv preprint*.\n", "2. Säilynoja, T., Bürkner, P. C., & Vehtari, A. (2022). Graphical test for discrete uniformity and its applications in goodness-of-fit evaluation and multiple sample comparison. *Statistics and Computing*.\n", - "3. The practical SBC interpretation guide by Martin Modrák: https://hyunjimoon.github.io/SBC/articles/rank_visualizations.html" + "3. The practical SBC interpretation guide by Martin Modrák: https://hyunjimoon.github.io/SBC/articles/rank_visualizations.html\n", + "\n", + "Check out the next tutorial for a detailed walkthrough of the workflow's functionality." ] }, { @@ -1016,9 +940,7 @@ "id": "df35a911", "metadata": {}, "outputs": [], - "source": [ - "## TODO" - ] + "source": [] } ], "metadata": { From 0c9c9fdb350206dc5c29bebe421c504254249c51 Mon Sep 17 00:00:00 2001 From: larskue Date: Mon, 27 Jan 2025 12:59:11 +0100 Subject: [PATCH 37/38] fix spline inverse call for out of bounds values --- .../networks/coupling_flow/transforms/_rational_quadratic.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py b/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py index a8c973306..41f2f8648 100644 --- a/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py +++ b/bayesflow/networks/coupling_flow/transforms/_rational_quadratic.py @@ -63,8 +63,9 @@ def _rational_quadratic_spline( # Eq. 29 in the appendix of the paper discriminant = b**2 - 4 * a * c - if not keras.ops.all(discriminant >= 0): - raise ValueError("Discriminant must be non-negative.") + + # the discriminant must be positive, even when the spline is called out of bounds + discriminant = keras.ops.maximum(discriminant, 0) xi = 2 * c / (-b - keras.ops.sqrt(discriminant)) result = xi * dx + xk From db8dab1daa22976f989383086f3a7cc18f5c3e58 Mon Sep 17 00:00:00 2001 From: stefanradev93 Date: Mon, 27 Jan 2025 23:19:57 -0500 Subject: [PATCH 38/38] Add working splines --- examples/TwoMoons_StarterNotebook.ipynb | 455 +++++++++++++----------- 1 file changed, 251 insertions(+), 204 deletions(-) diff --git a/examples/TwoMoons_StarterNotebook.ipynb b/examples/TwoMoons_StarterNotebook.ipynb index c922c80d2..5dc165ce4 100644 --- a/examples/TwoMoons_StarterNotebook.ipynb +++ b/examples/TwoMoons_StarterNotebook.ipynb @@ -208,7 +208,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 6, "id": "5c9c2dc70f53d103", "metadata": { "ExecuteTime": { @@ -223,7 +223,7 @@ "Adapter([0: ToArray -> 1: ConvertDType -> 2: Standardize(exclude=['theta']) -> 3: Rename('theta' -> 'inference_variables') -> 4: Rename('x' -> 'inference_conditions')])" ] }, - "execution_count": 22, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -273,7 +273,7 @@ "num_training_batches = 512\n", "num_validation_batches = 128\n", "batch_size = 64\n", - "epochs = 20" + "epochs = 30" ] }, { @@ -395,46 +395,66 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 4ms/step - loss: 0.7226 - loss/inference_loss: 0.7226 - val_loss: 0.6254 - val_loss/inference_loss: 0.6254\n", - "Epoch 2/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6377 - loss/inference_loss: 0.6377 - val_loss: 0.5348 - val_loss/inference_loss: 0.5348\n", - "Epoch 3/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6253 - loss/inference_loss: 0.6253 - val_loss: 0.6427 - val_loss/inference_loss: 0.6427\n", - "Epoch 4/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6165 - loss/inference_loss: 0.6165 - val_loss: 1.0218 - val_loss/inference_loss: 1.0218\n", - "Epoch 5/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.6010 - loss/inference_loss: 0.6010 - val_loss: 0.6841 - val_loss/inference_loss: 0.6841\n", - "Epoch 6/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5999 - loss/inference_loss: 0.5999 - val_loss: 0.7253 - val_loss/inference_loss: 0.7253\n", - "Epoch 7/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.6010 - loss/inference_loss: 0.6010 - val_loss: 0.8324 - val_loss/inference_loss: 0.8324\n", - "Epoch 8/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5904 - loss/inference_loss: 0.5904 - val_loss: 0.6796 - val_loss/inference_loss: 0.6796\n", - "Epoch 9/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5902 - loss/inference_loss: 0.5902 - val_loss: 0.5662 - val_loss/inference_loss: 0.5662\n", - "Epoch 10/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5695 - loss/inference_loss: 0.5695 - val_loss: 0.5778 - val_loss/inference_loss: 0.5778\n", - "Epoch 11/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5627 - loss/inference_loss: 0.5627 - val_loss: 0.5446 - val_loss/inference_loss: 0.5446\n", - "Epoch 12/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5691 - loss/inference_loss: 0.5691 - val_loss: 0.5066 - val_loss/inference_loss: 0.5066\n", - "Epoch 13/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5591 - loss/inference_loss: 0.5591 - val_loss: 0.4995 - val_loss/inference_loss: 0.4995\n", - "Epoch 14/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5526 - loss/inference_loss: 0.5526 - val_loss: 0.4275 - val_loss/inference_loss: 0.4275\n", - "Epoch 15/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5467 - loss/inference_loss: 0.5467 - val_loss: 0.3565 - val_loss/inference_loss: 0.3565\n", - "Epoch 16/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5493 - loss/inference_loss: 0.5493 - val_loss: 0.3889 - val_loss/inference_loss: 0.3889\n", - "Epoch 17/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5445 - loss/inference_loss: 0.5445 - val_loss: 0.6921 - val_loss/inference_loss: 0.6921\n", - "Epoch 18/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.5446 - loss/inference_loss: 0.5446 - val_loss: 0.3881 - val_loss/inference_loss: 0.3881\n", - "Epoch 19/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5287 - loss/inference_loss: 0.5287 - val_loss: 0.5459 - val_loss/inference_loss: 0.5459\n", - "Epoch 20/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.5506 - loss/inference_loss: 0.5506 - val_loss: 0.4466 - val_loss/inference_loss: 0.4466\n" + "Epoch 1/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 4ms/step - loss: 0.4375 - loss/inference_loss: 0.4375 - val_loss: 0.3653 - val_loss/inference_loss: 0.3653\n", + "Epoch 2/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3750 - loss/inference_loss: 0.3750 - val_loss: 0.3006 - val_loss/inference_loss: 0.3006\n", + "Epoch 3/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3718 - loss/inference_loss: 0.3718 - val_loss: 0.4908 - val_loss/inference_loss: 0.4908\n", + "Epoch 4/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3625 - loss/inference_loss: 0.3625 - val_loss: 0.2568 - val_loss/inference_loss: 0.2568\n", + "Epoch 5/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3611 - loss/inference_loss: 0.3611 - val_loss: 0.3194 - val_loss/inference_loss: 0.3194\n", + "Epoch 6/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3545 - loss/inference_loss: 0.3545 - val_loss: 0.2798 - val_loss/inference_loss: 0.2798\n", + "Epoch 7/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3464 - loss/inference_loss: 0.3464 - val_loss: 0.3649 - val_loss/inference_loss: 0.3649\n", + "Epoch 8/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3376 - loss/inference_loss: 0.3376 - val_loss: 0.3246 - val_loss/inference_loss: 0.3246\n", + "Epoch 9/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3421 - loss/inference_loss: 0.3421 - val_loss: 0.3664 - val_loss/inference_loss: 0.3664\n", + "Epoch 10/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3361 - loss/inference_loss: 0.3361 - val_loss: 0.2294 - val_loss/inference_loss: 0.2294\n", + "Epoch 11/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3343 - loss/inference_loss: 0.3343 - val_loss: 0.3697 - val_loss/inference_loss: 0.3697\n", + "Epoch 12/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3378 - loss/inference_loss: 0.3378 - val_loss: 0.2370 - val_loss/inference_loss: 0.2370\n", + "Epoch 13/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3275 - loss/inference_loss: 0.3275 - val_loss: 0.2895 - val_loss/inference_loss: 0.2895\n", + "Epoch 14/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3358 - loss/inference_loss: 0.3358 - val_loss: 0.3811 - val_loss/inference_loss: 0.3811\n", + "Epoch 15/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3295 - loss/inference_loss: 0.3295 - val_loss: 0.3383 - val_loss/inference_loss: 0.3383\n", + "Epoch 16/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3293 - loss/inference_loss: 0.3293 - val_loss: 0.3162 - val_loss/inference_loss: 0.3162\n", + "Epoch 17/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3233 - loss/inference_loss: 0.3233 - val_loss: 0.5696 - val_loss/inference_loss: 0.5696\n", + "Epoch 18/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3248 - loss/inference_loss: 0.3248 - val_loss: 0.2916 - val_loss/inference_loss: 0.2916\n", + "Epoch 19/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3195 - loss/inference_loss: 0.3195 - val_loss: 0.3094 - val_loss/inference_loss: 0.3094\n", + "Epoch 20/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3219 - loss/inference_loss: 0.3219 - val_loss: 0.2837 - val_loss/inference_loss: 0.2837\n", + "Epoch 21/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3170 - loss/inference_loss: 0.3170 - val_loss: 0.1897 - val_loss/inference_loss: 0.1897\n", + "Epoch 22/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3178 - loss/inference_loss: 0.3178 - val_loss: 0.3624 - val_loss/inference_loss: 0.3624\n", + "Epoch 23/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3090 - loss/inference_loss: 0.3090 - val_loss: 0.5049 - val_loss/inference_loss: 0.5049\n", + "Epoch 24/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3108 - loss/inference_loss: 0.3108 - val_loss: 0.3213 - val_loss/inference_loss: 0.3213\n", + "Epoch 25/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3121 - loss/inference_loss: 0.3121 - val_loss: 0.3449 - val_loss/inference_loss: 0.3449\n", + "Epoch 26/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3158 - loss/inference_loss: 0.3158 - val_loss: 0.3167 - val_loss/inference_loss: 0.3167\n", + "Epoch 27/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3047 - loss/inference_loss: 0.3047 - val_loss: 0.2979 - val_loss/inference_loss: 0.2979\n", + "Epoch 28/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 3ms/step - loss: 0.3170 - loss/inference_loss: 0.3170 - val_loss: 0.3634 - val_loss/inference_loss: 0.3634\n", + "Epoch 29/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3117 - loss/inference_loss: 0.3117 - val_loss: 0.4235 - val_loss/inference_loss: 0.4235\n", + "Epoch 30/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3115 - loss/inference_loss: 0.3115 - val_loss: 0.4121 - val_loss/inference_loss: 0.4121\n" ] } ], @@ -568,46 +588,66 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 6ms/step - loss: 0.4156 - loss/inference_loss: 0.4156 - val_loss: 0.3678 - val_loss/inference_loss: 0.3678\n", - "Epoch 2/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3545 - loss/inference_loss: 0.3545 - val_loss: 0.3487 - val_loss/inference_loss: 0.3487\n", - "Epoch 3/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.3349 - loss/inference_loss: 0.3349 - val_loss: 0.3310 - val_loss/inference_loss: 0.3310\n", - "Epoch 4/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.3291 - loss/inference_loss: 0.3291 - val_loss: 0.2774 - val_loss/inference_loss: 0.2774\n", - "Epoch 5/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.3252 - loss/inference_loss: 0.3252 - val_loss: 0.4224 - val_loss/inference_loss: 0.4224\n", - "Epoch 6/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3256 - loss/inference_loss: 0.3256 - val_loss: 0.2495 - val_loss/inference_loss: 0.2495\n", - "Epoch 7/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3398 - loss/inference_loss: 0.3398 - val_loss: 0.4305 - val_loss/inference_loss: 0.4305\n", - "Epoch 8/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3210 - loss/inference_loss: 0.3210 - val_loss: 0.2533 - val_loss/inference_loss: 0.2533\n", - "Epoch 9/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.3113 - loss/inference_loss: 0.3113 - val_loss: 0.2671 - val_loss/inference_loss: 0.2671\n", - "Epoch 10/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3087 - loss/inference_loss: 0.3087 - val_loss: 0.3028 - val_loss/inference_loss: 0.3028\n", - "Epoch 11/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2995 - loss/inference_loss: 0.2995 - val_loss: 0.2349 - val_loss/inference_loss: 0.2349\n", - "Epoch 12/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.2947 - loss/inference_loss: 0.2947 - val_loss: 0.2673 - val_loss/inference_loss: 0.2673\n", - "Epoch 13/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2872 - loss/inference_loss: 0.2872 - val_loss: 0.2196 - val_loss/inference_loss: 0.2196\n", - "Epoch 14/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2843 - loss/inference_loss: 0.2843 - val_loss: 0.2882 - val_loss/inference_loss: 0.2882\n", - "Epoch 15/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.2764 - loss/inference_loss: 0.2764 - val_loss: 0.4631 - val_loss/inference_loss: 0.4631\n", - "Epoch 16/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2783 - loss/inference_loss: 0.2783 - val_loss: 0.2427 - val_loss/inference_loss: 0.2427\n", - "Epoch 17/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2758 - loss/inference_loss: 0.2758 - val_loss: 0.1848 - val_loss/inference_loss: 0.1848\n", - "Epoch 18/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2699 - loss/inference_loss: 0.2699 - val_loss: 0.1851 - val_loss/inference_loss: 0.1851\n", - "Epoch 19/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.2671 - loss/inference_loss: 0.2671 - val_loss: 0.2573 - val_loss/inference_loss: 0.2573\n", - "Epoch 20/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2590 - loss/inference_loss: 0.2590 - val_loss: 0.1604 - val_loss/inference_loss: 0.1604\n" + "Epoch 1/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 4ms/step - loss: 0.3610 - loss/inference_loss: 0.3610 - val_loss: 0.3100 - val_loss/inference_loss: 0.3100\n", + "Epoch 2/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.3014 - loss/inference_loss: 0.3014 - val_loss: 0.3638 - val_loss/inference_loss: 0.3638\n", + "Epoch 3/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2846 - loss/inference_loss: 0.2846 - val_loss: 0.3233 - val_loss/inference_loss: 0.3233\n", + "Epoch 4/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2767 - loss/inference_loss: 0.2767 - val_loss: 0.3025 - val_loss/inference_loss: 0.3025\n", + "Epoch 5/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2683 - loss/inference_loss: 0.2683 - val_loss: 0.3097 - val_loss/inference_loss: 0.3097\n", + "Epoch 6/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2674 - loss/inference_loss: 0.2674 - val_loss: 0.2850 - val_loss/inference_loss: 0.2850\n", + "Epoch 7/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2625 - loss/inference_loss: 0.2625 - val_loss: 0.1652 - val_loss/inference_loss: 0.1652\n", + "Epoch 8/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2542 - loss/inference_loss: 0.2542 - val_loss: 0.2975 - val_loss/inference_loss: 0.2975\n", + "Epoch 9/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2552 - loss/inference_loss: 0.2552 - val_loss: 0.2748 - val_loss/inference_loss: 0.2748\n", + "Epoch 10/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2697 - loss/inference_loss: 0.2697 - val_loss: 0.3729 - val_loss/inference_loss: 0.3729\n", + "Epoch 11/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2616 - loss/inference_loss: 0.2616 - val_loss: 0.1787 - val_loss/inference_loss: 0.1787\n", + "Epoch 12/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2558 - loss/inference_loss: 0.2558 - val_loss: 0.2838 - val_loss/inference_loss: 0.2838\n", + "Epoch 13/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2504 - loss/inference_loss: 0.2504 - val_loss: 0.2136 - val_loss/inference_loss: 0.2136\n", + "Epoch 14/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2560 - loss/inference_loss: 0.2560 - val_loss: 0.2751 - val_loss/inference_loss: 0.2751\n", + "Epoch 15/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2438 - loss/inference_loss: 0.2438 - val_loss: 0.2211 - val_loss/inference_loss: 0.2211\n", + "Epoch 16/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2448 - loss/inference_loss: 0.2448 - val_loss: 0.1773 - val_loss/inference_loss: 0.1773\n", + "Epoch 17/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2391 - loss/inference_loss: 0.2391 - val_loss: 0.3960 - val_loss/inference_loss: 0.3960\n", + "Epoch 18/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2334 - loss/inference_loss: 0.2334 - val_loss: 0.1638 - val_loss/inference_loss: 0.1638\n", + "Epoch 19/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2388 - loss/inference_loss: 0.2388 - val_loss: 0.4104 - val_loss/inference_loss: 0.4104\n", + "Epoch 20/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2274 - loss/inference_loss: 0.2274 - val_loss: 0.1807 - val_loss/inference_loss: 0.1807\n", + "Epoch 21/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2228 - loss/inference_loss: 0.2228 - val_loss: 0.1728 - val_loss/inference_loss: 0.1728\n", + "Epoch 22/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2288 - loss/inference_loss: 0.2288 - val_loss: 0.1764 - val_loss/inference_loss: 0.1764\n", + "Epoch 23/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2237 - loss/inference_loss: 0.2237 - val_loss: 0.2428 - val_loss/inference_loss: 0.2428\n", + "Epoch 24/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2197 - loss/inference_loss: 0.2197 - val_loss: 0.1803 - val_loss/inference_loss: 0.1803\n", + "Epoch 25/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.2233 - loss/inference_loss: 0.2233 - val_loss: 0.3102 - val_loss/inference_loss: 0.3102\n", + "Epoch 26/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 5ms/step - loss: 0.2257 - loss/inference_loss: 0.2257 - val_loss: 0.1427 - val_loss/inference_loss: 0.1427\n", + "Epoch 27/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 5ms/step - loss: 0.2132 - loss/inference_loss: 0.2132 - val_loss: 0.4167 - val_loss/inference_loss: 0.4167\n", + "Epoch 28/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2077 - loss/inference_loss: 0.2077 - val_loss: 0.1379 - val_loss/inference_loss: 0.1379\n", + "Epoch 29/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2143 - loss/inference_loss: 0.2143 - val_loss: 0.1349 - val_loss/inference_loss: 0.1349\n", + "Epoch 30/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 4ms/step - loss: 0.2084 - loss/inference_loss: 0.2084 - val_loss: 0.1330 - val_loss/inference_loss: 0.1330\n" ] } ], @@ -632,26 +672,19 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 24, "id": "27b83a8f", "metadata": {}, "outputs": [], "source": [ - "affine_flow = bf.networks.CouplingFlow(\n", - " subnet=\"mlp\", \n", - " coupling_kwargs={\"subnet_kwargs\": {\"dropout\": 0.0}}\n", - ")\n", + "affine_flow = bf.networks.CouplingFlow(subnet=\"mlp\")\n", "\n", - "spline_flow = bf.networks.CouplingFlow(\n", - " subnet=\"mlp\", \n", - " coupling_kwargs={\"subnet_kwargs\": {\"dropout\": 0.0}}, \n", - " transform=\"spline\" # here is how we change the underlying transform\n", - ")" + "spline_flow = bf.networks.CouplingFlow(subnet=\"mlp\", transform=\"spline\")" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 25, "id": "e634dc50", "metadata": {}, "outputs": [], @@ -680,7 +713,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 26, "id": "f52e8e49", "metadata": {}, "outputs": [ @@ -696,46 +729,66 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 15ms/step - loss: -0.7232 - loss/inference_loss: -0.7232 - val_loss: -0.8731 - val_loss/inference_loss: -0.8731\n", - "Epoch 2/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.2120 - loss/inference_loss: -1.2120 - val_loss: -1.4010 - val_loss/inference_loss: -1.4010\n", - "Epoch 3/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.2095 - loss/inference_loss: -1.2095 - val_loss: -1.4121 - val_loss/inference_loss: -1.4121\n", - "Epoch 4/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -1.4549 - loss/inference_loss: -1.4549 - val_loss: -1.5548 - val_loss/inference_loss: -1.5548\n", - "Epoch 5/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -1.5452 - loss/inference_loss: -1.5452 - val_loss: -1.7149 - val_loss/inference_loss: -1.7149\n", - "Epoch 6/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -1.6153 - loss/inference_loss: -1.6153 - val_loss: -1.7353 - val_loss/inference_loss: -1.7353\n", - "Epoch 7/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.6965 - loss/inference_loss: -1.6965 - val_loss: -1.7457 - val_loss/inference_loss: -1.7457\n", - "Epoch 8/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -1.7951 - loss/inference_loss: -1.7951 - val_loss: -1.7935 - val_loss/inference_loss: -1.7935\n", - "Epoch 9/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.8665 - loss/inference_loss: -1.8665 - val_loss: -1.8359 - val_loss/inference_loss: -1.8359\n", - "Epoch 10/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -1.9356 - loss/inference_loss: -1.9356 - val_loss: -2.1203 - val_loss/inference_loss: -2.1203\n", - "Epoch 11/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.0007 - loss/inference_loss: -2.0007 - val_loss: -1.8282 - val_loss/inference_loss: -1.8282\n", - "Epoch 12/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.0690 - loss/inference_loss: -2.0690 - val_loss: -2.2087 - val_loss/inference_loss: -2.2087\n", - "Epoch 13/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.1525 - loss/inference_loss: -2.1525 - val_loss: -1.8864 - val_loss/inference_loss: -1.8864\n", - "Epoch 14/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.2135 - loss/inference_loss: -2.2135 - val_loss: -2.5540 - val_loss/inference_loss: -2.5540\n", - "Epoch 15/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.2743 - loss/inference_loss: -2.2743 - val_loss: -2.3367 - val_loss/inference_loss: -2.3367\n", - "Epoch 16/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.3207 - loss/inference_loss: -2.3207 - val_loss: -2.3932 - val_loss/inference_loss: -2.3932\n", - "Epoch 17/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.3702 - loss/inference_loss: -2.3702 - val_loss: -2.3515 - val_loss/inference_loss: -2.3515\n", - "Epoch 18/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.4036 - loss/inference_loss: -2.4036 - val_loss: -2.2006 - val_loss/inference_loss: -2.2006\n", - "Epoch 19/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.4322 - loss/inference_loss: -2.4322 - val_loss: -2.4065 - val_loss/inference_loss: -2.4065\n", - "Epoch 20/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.4120 - loss/inference_loss: -2.4120 - val_loss: -2.5755 - val_loss/inference_loss: -2.5755\n" + "Epoch 1/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m24s\u001b[0m 17ms/step - loss: -1.7248 - loss/inference_loss: -1.7248 - val_loss: -2.1969 - val_loss/inference_loss: -2.1969\n", + "Epoch 2/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8s\u001b[0m 16ms/step - loss: -2.2365 - loss/inference_loss: -2.2365 - val_loss: -2.3102 - val_loss/inference_loss: -2.3102\n", + "Epoch 3/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 17ms/step - loss: -2.3881 - loss/inference_loss: -2.3881 - val_loss: -2.3807 - val_loss/inference_loss: -2.3807\n", + "Epoch 4/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.3680 - loss/inference_loss: -2.3680 - val_loss: -2.1068 - val_loss/inference_loss: -2.1068\n", + "Epoch 5/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.5437 - loss/inference_loss: -2.5437 - val_loss: -2.5328 - val_loss/inference_loss: -2.5328\n", + "Epoch 6/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.6639 - loss/inference_loss: -2.6639 - val_loss: -2.6180 - val_loss/inference_loss: -2.6180\n", + "Epoch 7/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -2.7511 - loss/inference_loss: -2.7511 - val_loss: -2.7643 - val_loss/inference_loss: -2.7643\n", + "Epoch 8/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.8458 - loss/inference_loss: -2.8458 - val_loss: -2.6873 - val_loss/inference_loss: -2.6873\n", + "Epoch 9/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.9340 - loss/inference_loss: -2.9340 - val_loss: -3.0405 - val_loss/inference_loss: -3.0405\n", + "Epoch 10/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.9189 - loss/inference_loss: -2.9189 - val_loss: -2.8785 - val_loss/inference_loss: -2.8785\n", + "Epoch 11/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -2.9837 - loss/inference_loss: -2.9837 - val_loss: -2.7903 - val_loss/inference_loss: -2.7903\n", + "Epoch 12/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.0446 - loss/inference_loss: -3.0446 - val_loss: -2.9181 - val_loss/inference_loss: -2.9181\n", + "Epoch 13/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -3.0572 - loss/inference_loss: -3.0572 - val_loss: -3.1326 - val_loss/inference_loss: -3.1326\n", + "Epoch 14/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -3.1098 - loss/inference_loss: -3.1098 - val_loss: -2.8643 - val_loss/inference_loss: -2.8643\n", + "Epoch 15/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.1765 - loss/inference_loss: -3.1765 - val_loss: -2.9744 - val_loss/inference_loss: -2.9744\n", + "Epoch 16/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.2259 - loss/inference_loss: -3.2259 - val_loss: -3.2496 - val_loss/inference_loss: -3.2496\n", + "Epoch 17/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.2587 - loss/inference_loss: -3.2587 - val_loss: -3.2098 - val_loss/inference_loss: -3.2098\n", + "Epoch 18/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.3191 - loss/inference_loss: -3.3191 - val_loss: -3.4182 - val_loss/inference_loss: -3.4182\n", + "Epoch 19/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.3424 - loss/inference_loss: -3.3424 - val_loss: -3.2258 - val_loss/inference_loss: -3.2258\n", + "Epoch 20/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.3740 - loss/inference_loss: -3.3740 - val_loss: -3.3169 - val_loss/inference_loss: -3.3169\n", + "Epoch 21/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -3.4080 - loss/inference_loss: -3.4080 - val_loss: -3.3350 - val_loss/inference_loss: -3.3350\n", + "Epoch 22/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -3.4475 - loss/inference_loss: -3.4475 - val_loss: -3.3964 - val_loss/inference_loss: -3.3964\n", + "Epoch 23/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.4809 - loss/inference_loss: -3.4809 - val_loss: -3.3064 - val_loss/inference_loss: -3.3064\n", + "Epoch 24/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.5171 - loss/inference_loss: -3.5171 - val_loss: -3.2936 - val_loss/inference_loss: -3.2936\n", + "Epoch 25/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.5438 - loss/inference_loss: -3.5438 - val_loss: -3.3020 - val_loss/inference_loss: -3.3020\n", + "Epoch 26/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.5721 - loss/inference_loss: -3.5721 - val_loss: -3.6407 - val_loss/inference_loss: -3.6407\n", + "Epoch 27/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.5948 - loss/inference_loss: -3.5948 - val_loss: -3.6379 - val_loss/inference_loss: -3.6379\n", + "Epoch 28/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - loss: -3.6117 - loss/inference_loss: -3.6117 - val_loss: -3.3497 - val_loss/inference_loss: -3.3497\n", + "Epoch 29/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.6138 - loss/inference_loss: -3.6138 - val_loss: -3.5269 - val_loss/inference_loss: -3.5269\n", + "Epoch 30/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - loss: -3.5773 - loss/inference_loss: -3.5773 - val_loss: -3.4148 - val_loss/inference_loss: -3.4148\n" ] } ], @@ -750,7 +803,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 27, "id": "afa9839f", "metadata": {}, "outputs": [ @@ -766,46 +819,66 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m50s\u001b[0m 32ms/step - loss: -1.3529 - loss/inference_loss: -1.3529 - val_loss: -1.9426 - val_loss/inference_loss: -1.9426\n", - "Epoch 2/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.0683 - loss/inference_loss: -2.0683 - val_loss: -2.2129 - val_loss/inference_loss: -2.2129\n", - "Epoch 3/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.2016 - loss/inference_loss: -2.2016 - val_loss: -2.1892 - val_loss/inference_loss: -2.1892\n", - "Epoch 4/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.2874 - loss/inference_loss: -2.2874 - val_loss: -1.9549 - val_loss/inference_loss: -1.9549\n", - "Epoch 5/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.4774 - loss/inference_loss: -2.4774 - val_loss: -2.6856 - val_loss/inference_loss: -2.6856\n", - "Epoch 6/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 26ms/step - loss: -2.3485 - loss/inference_loss: -2.3485 - val_loss: -2.5269 - val_loss/inference_loss: -2.5269\n", - "Epoch 7/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -2.4170 - loss/inference_loss: -2.4170 - val_loss: -2.5098 - val_loss/inference_loss: -2.5098\n", - "Epoch 8/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.4346 - loss/inference_loss: -2.4346 - val_loss: -2.5090 - val_loss/inference_loss: -2.5090\n", - "Epoch 9/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 25ms/step - loss: -2.5990 - loss/inference_loss: -2.5990 - val_loss: -2.9927 - val_loss/inference_loss: -2.9927\n", - "Epoch 10/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -2.7069 - loss/inference_loss: -2.7069 - val_loss: -2.8296 - val_loss/inference_loss: -2.8296\n", - "Epoch 11/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.8685 - loss/inference_loss: -2.8685 - val_loss: -2.8763 - val_loss/inference_loss: -2.8763\n", - "Epoch 12/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.0124 - loss/inference_loss: -3.0124 - val_loss: -3.1694 - val_loss/inference_loss: -3.1694\n", - "Epoch 13/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 22ms/step - loss: -3.1153 - loss/inference_loss: -3.1153 - val_loss: -3.0405 - val_loss/inference_loss: -3.0405\n", - "Epoch 14/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.1993 - loss/inference_loss: -3.1993 - val_loss: -3.1885 - val_loss/inference_loss: -3.1885\n", - "Epoch 15/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.2972 - loss/inference_loss: -3.2972 - val_loss: -3.2990 - val_loss/inference_loss: -3.2990\n", - "Epoch 16/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.3746 - loss/inference_loss: -3.3746 - val_loss: -3.3764 - val_loss/inference_loss: -3.3764\n", - "Epoch 17/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.4334 - loss/inference_loss: -3.4334 - val_loss: -3.4334 - val_loss/inference_loss: -3.4334\n", - "Epoch 18/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.4857 - loss/inference_loss: -3.4857 - val_loss: -3.3835 - val_loss/inference_loss: -3.3835\n", - "Epoch 19/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.5123 - loss/inference_loss: -3.5123 - val_loss: -3.2589 - val_loss/inference_loss: -3.2589\n", - "Epoch 20/20\n", - "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 22ms/step - loss: -3.4961 - loss/inference_loss: -3.4961 - val_loss: -3.4955 - val_loss/inference_loss: -3.4955\n" + "Epoch 1/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m50s\u001b[0m 31ms/step - loss: -0.0305 - loss/inference_loss: -0.0305 - val_loss: -0.5046 - val_loss/inference_loss: -0.5046\n", + "Epoch 2/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -1.2209 - loss/inference_loss: -1.2209 - val_loss: -1.4572 - val_loss/inference_loss: -1.4572\n", + "Epoch 3/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -1.5152 - loss/inference_loss: -1.5152 - val_loss: -1.5478 - val_loss/inference_loss: -1.5478\n", + "Epoch 4/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -1.7783 - loss/inference_loss: -1.7783 - val_loss: -1.6943 - val_loss/inference_loss: -1.6943\n", + "Epoch 5/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -1.9830 - loss/inference_loss: -1.9830 - val_loss: -2.3109 - val_loss/inference_loss: -2.3109\n", + "Epoch 6/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -1.9812 - loss/inference_loss: -1.9812 - val_loss: -2.6307 - val_loss/inference_loss: -2.6307\n", + "Epoch 7/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.2906 - loss/inference_loss: -2.2906 - val_loss: -2.0684 - val_loss/inference_loss: -2.0684\n", + "Epoch 8/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 25ms/step - loss: -2.3631 - loss/inference_loss: -2.3631 - val_loss: -2.2277 - val_loss/inference_loss: -2.2277\n", + "Epoch 9/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.3808 - loss/inference_loss: -2.3808 - val_loss: -2.4927 - val_loss/inference_loss: -2.4927\n", + "Epoch 10/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.5112 - loss/inference_loss: -2.5112 - val_loss: -2.6694 - val_loss/inference_loss: -2.6694\n", + "Epoch 11/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -2.5705 - loss/inference_loss: -2.5705 - val_loss: -2.7786 - val_loss/inference_loss: -2.7786\n", + "Epoch 12/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -2.6979 - loss/inference_loss: -2.6979 - val_loss: -2.6825 - val_loss/inference_loss: -2.6825\n", + "Epoch 13/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.8183 - loss/inference_loss: -2.8183 - val_loss: -2.7877 - val_loss/inference_loss: -2.7877\n", + "Epoch 14/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.7840 - loss/inference_loss: -2.7840 - val_loss: -2.8402 - val_loss/inference_loss: -2.8402\n", + "Epoch 15/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -2.3101 - loss/inference_loss: -2.3101 - val_loss: -2.8259 - val_loss/inference_loss: -2.8259\n", + "Epoch 16/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -2.9274 - loss/inference_loss: -2.9274 - val_loss: -2.9762 - val_loss/inference_loss: -2.9762\n", + "Epoch 17/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.0012 - loss/inference_loss: -3.0012 - val_loss: -2.6167 - val_loss/inference_loss: -2.6167\n", + "Epoch 18/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -3.0712 - loss/inference_loss: -3.0712 - val_loss: -3.1585 - val_loss/inference_loss: -3.1585\n", + "Epoch 19/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -3.1087 - loss/inference_loss: -3.1087 - val_loss: -2.7591 - val_loss/inference_loss: -2.7591\n", + "Epoch 20/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.1919 - loss/inference_loss: -3.1919 - val_loss: -3.3845 - val_loss/inference_loss: -3.3845\n", + "Epoch 21/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -3.2309 - loss/inference_loss: -3.2309 - val_loss: -3.4535 - val_loss/inference_loss: -3.4535\n", + "Epoch 22/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.3305 - loss/inference_loss: -3.3305 - val_loss: -3.1565 - val_loss/inference_loss: -3.1565\n", + "Epoch 23/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.3760 - loss/inference_loss: -3.3760 - val_loss: -3.3958 - val_loss/inference_loss: -3.3958\n", + "Epoch 24/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -3.4144 - loss/inference_loss: -3.4144 - val_loss: -3.2900 - val_loss/inference_loss: -3.2900\n", + "Epoch 25/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.4843 - loss/inference_loss: -3.4843 - val_loss: -3.3188 - val_loss/inference_loss: -3.3188\n", + "Epoch 26/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.5172 - loss/inference_loss: -3.5172 - val_loss: -3.5762 - val_loss/inference_loss: -3.5762\n", + "Epoch 27/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.5435 - loss/inference_loss: -3.5435 - val_loss: -3.4907 - val_loss/inference_loss: -3.4907\n", + "Epoch 28/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.5667 - loss/inference_loss: -3.5667 - val_loss: -3.4892 - val_loss/inference_loss: -3.4892\n", + "Epoch 29/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 23ms/step - loss: -3.5856 - loss/inference_loss: -3.5856 - val_loss: -3.2707 - val_loss/inference_loss: -3.2707\n", + "Epoch 30/30\n", + "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 24ms/step - loss: -3.5624 - loss/inference_loss: -3.5624 - val_loss: -3.4194 - val_loss/inference_loss: -3.4194\n" ] } ], @@ -840,39 +913,13 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 28, "id": "073bcd0b", "metadata": {}, "outputs": [ - { - "ename": "ValueError", - "evalue": "Exception encountered when calling SplineTransform.call().\n\n\u001b[1mDiscriminant must be non-negative.\u001b[0m\n\nArguments received by SplineTransform.call():\n • xz=tf.Tensor(shape=(1, 3000, 1), dtype=float32)\n • parameters={'horizontal_edges': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'vertical_edges': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'derivatives': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'affine_scale': 'tf.Tensor(shape=(1, 3000, 1), dtype=float32)', 'affine_shift': 'tf.Tensor(shape=(1, 3000, 1), dtype=float32)'}\n • inverse=True", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[25], line 23\u001b[0m\n\u001b[0;32m 18\u001b[0m colors \u001b[38;5;241m=\u001b[39m [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#153c7a\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#7a1515\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#157a2d\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#7a6f15\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m 20\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m ax, net, name, color \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(axes, nets, names, colors):\n\u001b[0;32m 21\u001b[0m \n\u001b[0;32m 22\u001b[0m \u001b[38;5;66;03m# Obtain samples\u001b[39;00m\n\u001b[1;32m---> 23\u001b[0m samples \u001b[38;5;241m=\u001b[39m net\u001b[38;5;241m.\u001b[39msample(conditions\u001b[38;5;241m=\u001b[39mconditions, num_samples\u001b[38;5;241m=\u001b[39mnum_samples)[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtheta\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m 25\u001b[0m \u001b[38;5;66;03m# Plot samples\u001b[39;00m\n\u001b[0;32m 26\u001b[0m ax\u001b[38;5;241m.\u001b[39mscatter(samples[\u001b[38;5;241m0\u001b[39m, :, \u001b[38;5;241m0\u001b[39m], samples[\u001b[38;5;241m0\u001b[39m, :, \u001b[38;5;241m1\u001b[39m], color\u001b[38;5;241m=\u001b[39mcolor, alpha\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.75\u001b[39m, s\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.5\u001b[39m)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\approximators\\continuous_approximator.py:144\u001b[0m, in \u001b[0;36mContinuousApproximator.sample\u001b[1;34m(self, num_samples, conditions, split, **kwargs)\u001b[0m\n\u001b[0;32m 142\u001b[0m conditions \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39madapter(conditions, strict\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, stage\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minference\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 143\u001b[0m conditions \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mtree\u001b[38;5;241m.\u001b[39mmap_structure(keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mconvert_to_tensor, conditions)\n\u001b[1;32m--> 144\u001b[0m conditions \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minference_variables\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_sample(num_samples\u001b[38;5;241m=\u001b[39mnum_samples, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mconditions, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)}\n\u001b[0;32m 145\u001b[0m conditions \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mtree\u001b[38;5;241m.\u001b[39mmap_structure(keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mconvert_to_numpy, conditions)\n\u001b[0;32m 146\u001b[0m conditions \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39madapter(conditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, strict\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\approximators\\continuous_approximator.py:186\u001b[0m, in \u001b[0;36mContinuousApproximator._sample\u001b[1;34m(self, num_samples, inference_conditions, summary_variables, **kwargs)\u001b[0m\n\u001b[0;32m 183\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 184\u001b[0m batch_shape \u001b[38;5;241m=\u001b[39m (num_samples,)\n\u001b[1;32m--> 186\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minference_network\u001b[38;5;241m.\u001b[39msample(\n\u001b[0;32m 187\u001b[0m batch_shape,\n\u001b[0;32m 188\u001b[0m conditions\u001b[38;5;241m=\u001b[39minference_conditions,\n\u001b[0;32m 189\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mfilter_kwargs(kwargs, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minference_network\u001b[38;5;241m.\u001b[39msample),\n\u001b[0;32m 190\u001b[0m )\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\utils\\decorators.py:61\u001b[0m, in \u001b[0;36malias..alias_wrapper..wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 58\u001b[0m matches \u001b[38;5;241m=\u001b[39m [name \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m kwargs \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m aliases]\n\u001b[0;32m 60\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m matches:\n\u001b[1;32m---> 61\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 63\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(matches) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m1\u001b[39m \u001b[38;5;129;01mor\u001b[39;00m (\u001b[38;5;28mlen\u001b[39m(matches) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(args) \u001b[38;5;241m>\u001b[39m argpos):\n\u001b[0;32m 64\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[0;32m 65\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfn\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m() got multiple values for argument \u001b[39m\u001b[38;5;132;01m{\u001b[39;00margname\u001b[38;5;132;01m!r}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 66\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThis argument is also aliased as \u001b[39m\u001b[38;5;132;01m{\u001b[39;00maliases\u001b[38;5;132;01m!r}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 67\u001b[0m )\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\utils\\decorators.py:93\u001b[0m, in \u001b[0;36margument_callback..callback_wrapper..wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 90\u001b[0m args \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlist\u001b[39m(args)\n\u001b[0;32m 91\u001b[0m args[argpos] \u001b[38;5;241m=\u001b[39m callback(args[argpos])\n\u001b[1;32m---> 93\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\inference_network.py:42\u001b[0m, in \u001b[0;36mInferenceNetwork.sample\u001b[1;34m(self, batch_shape, conditions, **kwargs)\u001b[0m\n\u001b[0;32m 39\u001b[0m \u001b[38;5;129m@allow_batch_size\u001b[39m\n\u001b[0;32m 40\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21msample\u001b[39m(\u001b[38;5;28mself\u001b[39m, batch_shape: Shape, conditions: Tensor \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tensor:\n\u001b[0;32m 41\u001b[0m samples \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbase_distribution\u001b[38;5;241m.\u001b[39msample(batch_shape)\n\u001b[1;32m---> 42\u001b[0m samples \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m(samples, conditions\u001b[38;5;241m=\u001b[39mconditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, density\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 43\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m samples\n", - "File \u001b[1;32mc:\\Users\\radevs\\AppData\\Local\\anaconda3\\envs\\bf\\Lib\\site-packages\\keras\\src\\utils\\traceback_utils.py:122\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 119\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n\u001b[0;32m 120\u001b[0m \u001b[38;5;66;03m# To get the full stack trace, call:\u001b[39;00m\n\u001b[0;32m 121\u001b[0m \u001b[38;5;66;03m# `keras.config.disable_traceback_filtering()`\u001b[39;00m\n\u001b[1;32m--> 122\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\u001b[38;5;241m.\u001b[39mwith_traceback(filtered_tb) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 123\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[0;32m 124\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m filtered_tb\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\inference_network.py:26\u001b[0m, in \u001b[0;36mInferenceNetwork.call\u001b[1;34m(self, xz, conditions, inverse, density, training, **kwargs)\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall\u001b[39m(\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m 18\u001b[0m xz: Tensor,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[0;32m 24\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tensor \u001b[38;5;241m|\u001b[39m \u001b[38;5;28mtuple\u001b[39m[Tensor, Tensor]:\n\u001b[0;32m 25\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inverse:\n\u001b[1;32m---> 26\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inverse(xz, conditions\u001b[38;5;241m=\u001b[39mconditions, density\u001b[38;5;241m=\u001b[39mdensity, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 27\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward(xz, conditions\u001b[38;5;241m=\u001b[39mconditions, density\u001b[38;5;241m=\u001b[39mdensity, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\coupling_flow.py:110\u001b[0m, in \u001b[0;36mCouplingFlow._inverse\u001b[1;34m(self, z, conditions, density, training, **kwargs)\u001b[0m\n\u001b[0;32m 108\u001b[0m log_det \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mzeros(keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mshape(z)[:\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m])\n\u001b[0;32m 109\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m layer \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mreversed\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minvertible_layers):\n\u001b[1;32m--> 110\u001b[0m x, det \u001b[38;5;241m=\u001b[39m layer(x, conditions\u001b[38;5;241m=\u001b[39mconditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 111\u001b[0m log_det \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m det\n\u001b[0;32m 113\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m density:\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\couplings\\dual_coupling.py:51\u001b[0m, in \u001b[0;36mDualCoupling.call\u001b[1;34m(self, xz, conditions, inverse, training, **kwargs)\u001b[0m\n\u001b[0;32m 47\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall\u001b[39m(\n\u001b[0;32m 48\u001b[0m \u001b[38;5;28mself\u001b[39m, xz: Tensor, conditions: Tensor \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, inverse: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, training: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[0;32m 49\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m (Tensor, Tensor):\n\u001b[0;32m 50\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inverse:\n\u001b[1;32m---> 51\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inverse(xz, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward(xz, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\couplings\\dual_coupling.py:68\u001b[0m, in \u001b[0;36mDualCoupling._inverse\u001b[1;34m(self, z, conditions, training, **kwargs)\u001b[0m\n\u001b[0;32m 66\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Transform (g(x1; f(x2; x1)), f(x2; x1)) -> (x1, x2)\"\"\"\u001b[39;00m\n\u001b[0;32m 67\u001b[0m z1, z2 \u001b[38;5;241m=\u001b[39m z[\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m, : \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpivot], z[\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpivot :]\n\u001b[1;32m---> 68\u001b[0m (z2, z1), log_det2 \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcoupling2(z2, z1, conditions\u001b[38;5;241m=\u001b[39mconditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 69\u001b[0m (x1, x2), log_det1 \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcoupling1(z1, z2, conditions\u001b[38;5;241m=\u001b[39mconditions, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 71\u001b[0m x \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mconcatenate([x1, x2], axis\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\couplings\\single_coupling.py:63\u001b[0m, in \u001b[0;36mSingleCoupling.call\u001b[1;34m(self, x1, x2, conditions, inverse, training, **kwargs)\u001b[0m\n\u001b[0;32m 59\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall\u001b[39m(\n\u001b[0;32m 60\u001b[0m \u001b[38;5;28mself\u001b[39m, x1: Tensor, x2: Tensor, conditions: Tensor \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, inverse: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, training: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[0;32m 61\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m ((Tensor, Tensor), Tensor):\n\u001b[0;32m 62\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inverse:\n\u001b[1;32m---> 63\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inverse(x1, x2, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 64\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward(x1, x2, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\couplings\\single_coupling.py:82\u001b[0m, in \u001b[0;36mSingleCoupling._inverse\u001b[1;34m(self, z1, z2, conditions, training, **kwargs)\u001b[0m\n\u001b[0;32m 80\u001b[0m x1 \u001b[38;5;241m=\u001b[39m z1\n\u001b[0;32m 81\u001b[0m parameters \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_parameters(x1, conditions\u001b[38;5;241m=\u001b[39mconditions, training\u001b[38;5;241m=\u001b[39mtraining, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m---> 82\u001b[0m x2, log_det \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransform(z2, parameters\u001b[38;5;241m=\u001b[39mparameters, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m 84\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m (x1, x2), log_det\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\transforms\\transform.py:18\u001b[0m, in \u001b[0;36mTransform.call\u001b[1;34m(self, xz, parameters, inverse)\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall\u001b[39m(\u001b[38;5;28mself\u001b[39m, xz: Tensor, parameters: \u001b[38;5;28mdict\u001b[39m[\u001b[38;5;28mstr\u001b[39m, Tensor], inverse: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m (Tensor, Tensor):\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inverse:\n\u001b[1;32m---> 18\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_inverse(xz, parameters)\n\u001b[0;32m 19\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward(xz, parameters)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\transforms\\spline_transform.py:225\u001b[0m, in \u001b[0;36mSplineTransform._inverse\u001b[1;34m(self, z, parameters)\u001b[0m\n\u001b[0;32m 222\u001b[0m parameters \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124medges\u001b[39m\u001b[38;5;124m\"\u001b[39m: edges, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mderivatives\u001b[39m\u001b[38;5;124m\"\u001b[39m: derivatives}\n\u001b[0;32m 224\u001b[0m \u001b[38;5;66;03m# compute the spline and jacobian\u001b[39;00m\n\u001b[1;32m--> 225\u001b[0m spline, spline_log_jac \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmethod_fn(z, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparameters, inverse\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m 227\u001b[0m x \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mwhere(inside, spline, affine)\n\u001b[0;32m 228\u001b[0m log_jac \u001b[38;5;241m=\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mwhere(inside, spline_log_jac, affine_log_jac)\n", - "File \u001b[1;32mc:\\Users\\radevs\\Desktop\\Projects\\BayesFlow\\examples\\..\\bayesflow\\networks\\coupling_flow\\transforms\\_rational_quadratic.py:67\u001b[0m, in \u001b[0;36m_rational_quadratic_spline\u001b[1;34m(x, edges, derivatives, inverse)\u001b[0m\n\u001b[0;32m 65\u001b[0m discriminant \u001b[38;5;241m=\u001b[39m b\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m2\u001b[39m \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m4\u001b[39m \u001b[38;5;241m*\u001b[39m a \u001b[38;5;241m*\u001b[39m c\n\u001b[0;32m 66\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39mall(discriminant \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m):\n\u001b[1;32m---> 67\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mDiscriminant must be non-negative.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 69\u001b[0m xi \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2\u001b[39m \u001b[38;5;241m*\u001b[39m c \u001b[38;5;241m/\u001b[39m (\u001b[38;5;241m-\u001b[39mb \u001b[38;5;241m-\u001b[39m keras\u001b[38;5;241m.\u001b[39mops\u001b[38;5;241m.\u001b[39msqrt(discriminant))\n\u001b[0;32m 70\u001b[0m result \u001b[38;5;241m=\u001b[39m xi \u001b[38;5;241m*\u001b[39m dx \u001b[38;5;241m+\u001b[39m xk\n", - "\u001b[1;31mValueError\u001b[0m: Exception encountered when calling SplineTransform.call().\n\n\u001b[1mDiscriminant must be non-negative.\u001b[0m\n\nArguments received by SplineTransform.call():\n • xz=tf.Tensor(shape=(1, 3000, 1), dtype=float32)\n • parameters={'horizontal_edges': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'vertical_edges': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'derivatives': 'tf.Tensor(shape=(1, 3000, 1, 17), dtype=float32)', 'affine_scale': 'tf.Tensor(shape=(1, 3000, 1), dtype=float32)', 'affine_shift': 'tf.Tensor(shape=(1, 3000, 1), dtype=float32)'}\n • inverse=True" - ] - }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABPIAAAH/CAYAAADdWPNMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAADPJ0lEQVR4nOzdeVxU9f4/8NeZGfZdGFAUcEFRQzFxyT00NSsprcy8qVndMm+LUb9ry/223bpeu0XrpT3TyvasMS3lJu6miYiigg4gIIsMCAw7w8zn9wfNkZFhlW3g9Xw8eADnfD7nfD6zfObM+3wWSQghQERERERERERERN2aoqsLQERERERERERERM1jII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0RERERERL3Knj17MH/+fPj7+0OSJPz444/N5tm9ezfCw8Ph6OiIwYMH47333uv4ghIRXYaBPCIiIiIiIupVysvLERYWhnfeeadF6dPT03HDDTdg2rRpSEhIwNNPP41HHnkE33//fQeXlIjIkiSEEF1dCCIiIiIiIqKuIEkSNm/ejFtuuaXRNGvWrIFGo8Hp06flbStXrkRiYiIOHjzYCaUkIqqj6uoCEBEREREREXVnBw8exJw5cyy2zZ07Fx9//DEMBgPs7Owa5KmurkZ1dbX8v8lkwsWLF+Ht7Q1Jkjq8zETUtYQQKC0thb+/PxSK9hsQy0AeERERERERURPy8vLg5+dnsc3Pzw+1tbUoKChAv379GuRZu3YtXnjhhc4qIhF1U1lZWRgwYEC7HY+BPCIiIiIiIqJmXN6LzjxLVWO965566ilERUXJ/5eUlCAwMBBZWVlwd3fvuIISUbeg1+sREBAANze3dj0uA3lERERERERETejbty/y8vIstuXn50OlUsHb29tqHgcHBzg4ODTY7u7uzkAeUS/S3kPpuWotERERERERURMmTZqE2NhYi207duzAuHHjrM6PR0TUURjIIyIiIiIiol6lrKwMx44dw7FjxwAA6enpOHbsGDIzMwHUDYtdtmyZnH7lypXIyMhAVFQUTp8+jU8++QQff/wxnnjiia4oPhH1YhxaS0RERERERL3KkSNHEBERIf9vnstu+fLl+PTTT5GbmysH9QBg0KBB2LZtGx577DH897//hb+/P9566y3ceuutnV52IurdJGGeoZOIiIiIiIiIOoRer4eHhwdKSko4Rx5RL9BR73kOrSUiIiIiIiIiIrIBDOQRERERERERERHZAAbyiIiIiIiIiIiIbAADeURERERERERERDaAgTwiIiIiIiIiIiIbwEAeERERERERERGRDWAgj4iIiIiIiIiIyAYwkEdERERERERERGQDGMgjIiIiIiIiIiKyAQzkERERERERERER2QAG8oiIiIiIiIiIiGwAA3lEREREREREREQ2gIE8IiIiIiIiIiIiG8BAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0REREREREREZAMYyCMiIiIiIiIiIrIBDOQRERERERERERHZAAbyiIiIiIiIiIiIbAADeURERERERERERDaAgTwiIiIiIiIiIiIbwEAeERERERERERGRDWAgj4iIiIiIiIiIyAYwkEdERERERERERGQDGMgjIiIiIiIiIiKyAQzkERERERERERER2QAG8oiIiIiIiIiIiGwAA3lEREREREREREQ2gIE8IiIiIiIiIiIiG8BAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0REREREREREZAMYyCMiIiIiIiIiIrIBDOQRERERERERERHZAAbyiIiIiIiIiIiIbAADeURERERERERERDaAgTwiIiIiIiIiIiIbwEAeERERERERERGRDWAgj4iIiIiIiIiIyAYwkEdERERERERERGQDGMgjIiIiIiIiIiKyAQzkERERERERERER2QAG8oiIiIiIiIiIiGwAA3lEREREREREREQ2gIE8IiIiIiIiIiIiG8BAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0REREREREREZAMYyKM2O3fuHCRJwsCBA7u6KL3ep59+CkmScPfdd7cq365duyBJEq699toOKRdRT8Y2sHe7++67IUkSPv3003Y53sCBAyFJEs6dO9cux6OOYzQa8a9//QshISGwt7dv8DlaUVGBJ554AoMGDYKdnZ3F53N7v26obRq7burJ7TrbGCKinoOBPJKZP+Cb+nnjjTe6uphXrH593n777SbTPvbYY3La9rqoO3fuHJ5//nlexFOvtH//ftx///0YPnw4PDw84ODggP79++Omm27CRx99hPLy8q4uYqdjm9CQ+Uu2JEmwt7dHYWFho2lra2vh6+srp3/++ec7r6DUY4waNQqSJMHJyQl6vb7JtM8++yyeeeYZnDt3DqGhoZgyZQpGjRol7//rX/+K1157Dfn5+RgzZgymTJmCYcOGdXQVOsS5c+fw5JNPYty4cfDx8YG9vT18fHwwffp0vPTSSzh//nxXF7FXMgeEm/q55ZZburqYRETUQVRdXQDqfoYOHQpfX1+r+/r379/JpelYn332GR5++GGr+4xGI7766qt2P+e5c+fwwgsvYMaMGa3uQdfenJ2dERISgsDAwC4tB/V8FRUVWLFiBb755hsAgKOjI4YMGQInJydkZ2dj69at2Lp1K5599lls377d4ktxd2VnZ4eQkJArbhe7U5vQHRkMBnz99ddYtWqV1f3bt2+HTqfr5FJRT3Ls2DEkJSUBAKqqqvDdd9/hnnvusZpWCIH33nsPkiRh//79GDdunMX+oqIifPXVV3B2dkZycjICAgIs9vfr1w8hISHw8PDomMq0o7Vr1+L5559HTU0NFAoFhgwZgiFDhqCwsBD79u3D3r178fLLL+PDDz/EXXfd1dXFbRft1a53Fl9fXwwdOtTqvpEjR3ZyaYiIqLMwkEcNPP30073iy2RISAj++OMPpKSkICQkpMH+2NhY5OXlISQkBCkpKV1Qwo43YcIEJCcnd3UxqIczGAyYM2cO9u/fj759+2LdunW4/fbb4eTkJKc5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OTk5SEtLQ58+fTBjxgw89NBDmDNnTlcXkYja2e7du6FUKjF48GA8/vjj3WaRCyKirjZy5Ej8/e9/x44dO5CVlYXMzEy4u7tj1qxZ+Otf/4o77rijq4tIREQ2hotdEBEREREREXUwLnZB1Lt01Hue416IiIiIiIiIiIhsAAN57UQIAb1eD3ZwJCJbwraLiGwR2y4iIiLqrRjIayelpaXw8PBAaWlph53DZDIhLy8PJpOpw87RGXpKPQDWpTvqKfXoLGy7Wqen1KWn1APoOXXpKfXoLGy7Wod16X56Sj2AnlUXIiJbwEAeERERERERERGRDWAgj4iIiIiIiIiIyAYwkEdERERERERERGQDGMgjIiIiIiIiIiKyAQzkERERERERERER2QAG8oiIiIiIiIiIiGwAA3lEREREREREREQ2gIE8IiIiIiIiIiIiG8BAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdkABvKIiIiIiIiIiIhsAAN5RERERERERERENoCBPCIiIiIiIiIiIhvAQB4REREREREREZENYCCPiIiIiIiIiIjIBjCQR0REREREREREZAMYyCMiIiIiIiIiIrIBPTaQFxMTg0GDBsHR0RHh4eHYu3dvi/Lt378fKpUKY8aM6dgCEhFZwbaLiGwR2y4iIiKiztEjA3lff/01Vq9ejWeeeQYJCQmYNm0a5s2bh8zMzCbzlZSUYNmyZZg1a1YnlZSI6BK2XURki9h2EREREXWeHhnIi46Oxr333ov77rsPI0aMwBtvvIGAgAC8++67TeZ74IEHsGTJEkyaNKmTSkpEdAnbLiKyRWy7iIiIiDqPqqsL0N5qamoQHx+PJ5980mL7nDlzcODAgUbzrV+/Hqmpqfj888/x0ksvNXue6upqVFdXy//r9XoAgMlkgslkamPpm2YymSCE6LDjd5aeUg+AdemOOqseCkX73gdh22Ubekpdeko9gJ5Tl86sR3u2X2y7bAPr0v30lHoAtnvtRURkq3pcIK+goABGoxF+fn4W2/38/JCXl2c1z9mzZ/Hkk09i7969UKla9pCsXbsWL7zwQoPtOp0OVVVVrS94C5hMJpSUlEAIYdMfZD2lHgDr0h11Vj369u3brsdj22Ubekpdeko9gJ5Tl86sR3u2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eFd/mC0RUXdQfzVbIiLqnRjIIyKrtJk6rInWQJtZAACIWh4hz3tXf/4786q00RvisGlrvJy2Pk1cUqP7iIjaS1uGwl4+J97l/7MnHhERERF1JwzkEZFVmrgkaDMLEBzoIwfuzEE7a6wF+Vqyj4iovbRlKOzlwToG74iIiIioO2Mgj4isqh98a8lw2KaCfE3tIyJqLxwKS0REREQ9HQN5RGQVg29EZGvYm46IiIiIejpFVxeAiIiIiIiIiIiImsdAHhERERERERERkQ1gII+IiIiIiIiIiMgGMJBHRERERERERERkAxjIIyIiIiIiIiIisgEM5BEREREREREREdmADgnkffvtt7j99tvx4IMPIjEx0WJfQUEBBg8e3BGnJSK6Imy7iMgWse0iIiIi6j3aPZC3adMmLF68GBUVFTh+/DgmTpyIjRs3yvuNRiMyMjLa+7RERFeEbRcR2SK2XURERES9i6q9DxgdHY1169bhiSeeAABs2LABDzzwACRJwtKlS9v7dERE7YJtFxHZIrZdRERERL1Luwfyzpw5g4ULF8r/L1++HJ6enli8eDEcHR0xffr09j4lEdEVY9tFRLaIbRcRERFR79LuQ2sdHR1RVFRkse3mm2/G+vXrsXz5cmg0mvY+pVUxMTEYNGgQHB0dER4ejr179zaZfvfu3QgPD4ejoyMGDx6M9957r1PKSUTdA9suIrJFbLuIiIiIepd2D+SFhoZi3759DbYvXrwYb775JlatWtXep2zg66+/xurVq/HMM88gISEB06ZNw7x585CZmWk1fXp6Om644QZMmzYNCQkJePrpp/HII4/g+++/7/CyElH3wLaLiGwR2y4iIiKi3qXdA3nLli3DkSNHrO7761//inXr1iEwMLC9T2shOjoa9957L+677z6MGDECb7zxBgICAvDuu+9aTf/ee+8hMDAQb7zxBkaMGIH77rsP99xzD1599dUOLScRdR9su4jIFrHtIiIiIupd2n2OvLvvvht33313o/ujoqIQFRXV3qeV1dTUID4+Hk8++aTF9jlz5uDAgQNW8xw8eBBz5syx2DZ37lx8/PHHMBgMsLOza5Cnuroa1dXV8v96vR4AYDKZYDKZrrQaVplMJgghOuz4naWn1ANgXbqjttZj2bJlWLZsWaP5Vq9ejdWrV8v7FYr2vQ/Ctss29JS69JR6AD2nLp3VdgHt236x7bINrEv301PqAXReXdr72ouIyFa1OpBXUlKCt99+Gzt27EBGRgYAwMvLC8HBwQgPD8e1116LSZMmtXtBW6qgoABGoxF+fn4W2/38/JCXl2c1T15entX0tbW1KCgoQL9+/RrkWbt2LV544YUG23U6Haqqqq6gBo0zmUwoKSmBEMKmP8h6Sj0A1qU7aqweer0eH3/8MXbv3o3z588DADw9PTFw4ECMHj0akydPxrhx41p8nr59+7Zrudl22YaeUpeeUg+g59Sls9ouoH3bL7ZdtoF16X56Sj2AzqtLe197ERHZqlYF8tLS0jB9+nTk5uZCCCFvz8rKwokTJ7B582YAgL+/P+677z6sXr0aHh4e7VviFpIkyeJ/IUSDbc2lt7bd7KmnnrLoWajX6xEQEAC1Wg13d/e2FrtJJpMJkiRBrVbb9Ad+T6kHwLp0R9bqkZaWhpkzZzZou3JycnD69Gn88ssvAOrarnvvvRePPvoo26521FNeW0DPqUtPqQfQc+rCtottV0fqyrqkFpzDlqT/YX7odRjiM/CKj9dTnpeeUg+gZ9WFiMgWtCqQ98QTTyAnJ0e+WPT19UVFRQUeffRR/Pzzz7jzzjuxa9cuZGdn48UXX8R///tfvP/++1iwYEFHlb8BHx8fKJXKBneB8/PzG9z9Nevbt6/V9CqVCt7e3lbzODg4wMHBocF2hULRoR9gkiR1+Dk6Q0+pB8C6dEeX1+Pvf/97i9uuf/7zn4iJiWHb1c56ymsL6Dl16Sn1AHpOXdh2se3qSF1Vly0n/4dNR39AYUURvF28EBk6G8HqQVd0zJ7yvPSUegA9qy5ERN1dq1raXbt2ITw8HB9++CFCQ0Ph6+uLgQMHok+fPgCAzz//HOfPn8fvv/+OFStWoKSkBLfddlujkx13BHt7e4SHhyM2NtZie2xsLCZPnmw1z6RJkxqk37FjB8aNG2d1nhYisi1su4jIFrHtop4gMnQ2loQvBABsiv8BmqTYZnIQERFRU1oVyDMajRg6dGiz6SZMmICPPvoICQkJGDp0KB555BHEx8e3uZCtFRUVhY8++giffPIJTp8+jcceewyZmZlYuXIlgLrhGcuWLZPTr1y5EhkZGYiKisLp06fxySef4OOPP8YTTzzRaWUmoo7DtouIbBHbLuoJgtWDEBVxP1ZMXIQl4QsRGTq7q4tERERk01o1tDYsLAxHjhxpcfqRI0dix44dGDlyJNauXYvvvvuu1QVsizvuuAOFhYV48cUXkZubi9DQUGzbtg1BQUEAgNzcXGRmZsrpBw0ahG3btuGxxx7Df//7X/j7++Ott97Crbfe2inlJaKOxbaLiGwR2y7qScwBPSIiIroyrQrkrVq1CkuWLMHLL7+MZ555pkV5AgMDMXv2bOzZs6dNBWyrVatWYdWqVVb3ffrppw22zZgxA0ePHu3gUhFRV2DbRUS2iG0XEREREV2uVUNrFy9ejMWLF+PZZ5/FfffdhwsXLrQon16vR0VFRZsKSER0pdh2EZEtYttFRERERJdrVY88APjss8/Qp08fxMTE4PPPP8fNN9+MjIwMq2kNBgPefPNNxMXF4ZprrrniwlLX02bqoIlLQmREKIID1V1dHKIWY9tFRLaIbRfZAq0uHZqk2HZZkZaIiIia1upAnlKpxDvvvIPbb78dzz77LL799lt5n5ubG/r16wc3NzfU1NQgPT0dlZWVUCqVePHFF9u14NQ1NHFJ2LS1bgLtqOURXVwaopZj20VtodNqkaTRIDQyEurg4K4uDvVCbLvIFmiSYrEp/gcA4Dx4REREHazVgTyzGTNmYPfu3Th79iy+//577Nq1C0ePHoVWq710cJUK1113HZ577jlMnjy5XQpMXSsyItTiN5GtYdtFrZGk0SB+0yYAQERUVBeXhnoztl3UnZlXouWKtERERB1PEkKI9jxgSUkJioqKIEkS+vfvD5WqzbFCm6LX6+Hh4YGSkhK4u7t3yDlMJhPy8/Ph6+sLhaJV0xt2Kz2lHgDr0h21tR5su9h2WXN5jzxbrkt9PaUeQM+pC9uu1mHb1TqsS/fTU+oB9Ky6dLTOaLuIqPvoqPd8u1/teXh4wMPDo70PS0TUodh2kTXq4GD2xKNujW0XERERUe/CWyZEREREREREREQ2gIE8umLaTB2iN8RBm6mz+JuIiIiIiIiIiNpP75hIhTpU/ZVsAXBVWyIiIiIbo9WlQ5MUi8jQ2QhWD+rq4hAREVEjGMijK2ZtJVuuaktERERkOzRJsdgU/wMAICri/i4uDRERETWGgTy6YsGBakRGhEITl4TIiFD2xCMim3L5yrRERL1RZOhsi99ERETUPXGOvF6oI+axMw+v1cQltdsxiYg6Q5JGg/hNm5Ck0XR1UYiI2kyrS0d03AfQ6tIt/m6pYPUgREXcz2G1RERE3Rx75PVC9ee0a6/ec9aG1xIR2YLQyEiL30REtqj+0FgAHCZLRETUQzGQ1wt1RNAtOFDNIbVEZFPqD6mNiIrq6uIQEbWZVpeOwvIizB0eYTE0lsNkiYiIeh4G8nqh9g66aTN18vx4wYHqdjsuEVFHMAfwygsLkbx9OwAwkEdENk2TFIvtyXFYEr5QHhrLnnhEREQ9EwN51KzLA3Xm/8NC/LHz0FkcOJaOjJwiFBaX4+VHb+rq4hIRNck8J97wuXMRvmQJh9QSUben1aVDkxSLyNDZVuew40IVREREvQcDedQsTVwSNvx0GPsT0rAuKlKeY29/QhoSTmejoqoGSoWEo6ezoM3UsVceEXU79YfR1p8Tj6vUEpEtqD//nbWeduaFKoiIiKjn46q11Cjz6rZhIf4IDvRBctoFrInWQAgTqqproM3Uwd5OCXuVEl7uTkhJ12H95kNdXWwiIgs6rRaaNWtweMMG7Hr9dWjWrIF/WBjUwcHQabWIi46GTqvt6mISEVnQ6tLxt2+fxrx374LapQ+WhC9EmP+IVq9GS0RERD0Le+T1Ys3NbVd/ddt1UZFYE61B0tlcHDx2DrVGEwBAIUkYMcQPpeVVKCiuQNzhM+yVR0TdSpJGgwvJybB3dkbeqVPIT06GoaICOYmJKEhNRfKOHSgvLMRNL7/c1UUlIpJpkmLx44ntMBgNAIBfHvwc0XEfcDVaIiKiXo498noxc6BOE5dkdX9kRCiW3BguB/rWRUXC3dVRDuIBgEkIAEBeQSlMJoHM3OJGj0dE1BX8w8KgtLNDmU4Hz4AA+I8Zg0q9HnveeQfnjx2DobIS6QcOsFceEXUprS7dorddZOhs+Dh7AQDO5Kfit5S9iAydjSXhC1s1F55Wl443dn2E3JILHVJuIiIi6lwM5PVi9QN1LTVhVBD6qd1gp1JAkgBJAnQXS+HqbA9/tRuGBqkRFuLfgaUmImoZ87DZszt3okqvh9FgQM7x43BVq1GUkQFjTQ1U9vaQJAlFGRlI0mg41JaIuox5HjxNUqy8uIVRGAEApTXleDXufQBAYXkR1h/6Bp8d/g63fvxX/Jayt9njfnl0Mw5lJHR4HYiIiKjjcWhtLxYcqEbU8ohG95t77BUWlwMADhxLR/r5Qjg62MFQe6lXXv7Fuv3+vu4oLa9GYkoOZl0TAqD54btERB3FvDpt0MSJ6BMUhMK0NOhzcqDPyQEUCviNGIGRN92EQ+vXw8nDA/5hYXIeAIiIiuriGhBRb2LuZRfmPwJrNP+CtiAdw9RDUFRRAhMEBnsHYf2hb7Dh8DcQQsDRzgHlNZUAgFkh05o+rgAm9r+6U+pBREREHYuBPJJdHnSLjAhFalYBtu45iWJ9JQxGE4xGEyqqDA3yShIwepg/xgwfgLAQf0RviENkRKjFPHtNBQ2JiNqbf1gY0vbvBwAUpKaitqrq0k6TCQVnzmBfTAxqSktRWVSEnMREixVtiYg6k3nl2ei4D6AtSIe/e19U1lbB1cEFTnaOKK0qw6m8MxBCwCiMKKsuh9rVG6umLpOPodWlY/2hb1BcqQcAeDq5Y8XERVh97X3Iz8/vqqoRERFRO2IgjwDUBfHWRGugzSwAADkIdyo1D7k6PbzcneHv4Yys3GJUm2ob5O+ndsfymycgMSUHOw+dxfb9yfJx6v8mIuoMOq0W+2JikHfyJHJOnLAM4v3JaDDAaKi7MeHk5YXQyEiog4PZE4+IOo15CG1k6GwEqwdBq0tHYXkRpg6eiFN5Z5BemAlPJ3cUV+qxI3kXTBBwtXeBwWhAtbEGalcfi954mqRYfJOgQVVtNQDAUeUAbxcvzL/qOvx2fA9mjZmOob6Du6q6RERE1A4YyCMAdcNotZkFCA70sehJ5+biAHs7Ffp4OCMztwg1BqPV/I8vj0BiSg42bY3H3CnDLRbJYE88IupsSRoNCrRa1NbUoKasrMm0Tn364NY334Q6OLiTSkdEVMc8Lx5QtwqtJikWP5+Mhb3SHjn6CzAYDZAgodJQBYG6BcbKasqhgASlpMDIvsMsjhcZOhuF5UUWPfIiQ2dDcyIWf6TGo0JVg6iZXO2WiIjIljGQRwAse86Zh9UCQFiIP3YeOosDx9JhrLdaLQAoFRKMJgGFBCSn52PFgokWxyAi6irmobHJsbE4Hx/fZFqPfv0QMmtWZxSLiMiCeV68+vPjSZCQU5KHWlPdzdNyQ4VFHmc7JxiMBgzzHYyFo69HdNwHcn5NUixWTFyEYPUgizzzQ6+Dc609ZoVO7+gqERERUQdjII8ANL7wRZB/HwBA+vlCKP4M3JmZ/xYC+D42EcWllXhs2bVyEE+bqcP6zYcAACsWTGRwj4g6jXmIbNKWLY2mUahUEAD6jhzZeQUjIqrHPC8eUDfMNmbfRhRWFMFgZRoTM38PP+jKCjF50Hgk5pyWe/QBsOjdV98Qn4FwG+0MXx/fDqgFERERdSYG8qiBy+fLKy6tRFW1AUIACgmoF8sDAAgAF0sq8NPOExgS4CMHBDVxSfjm1wQAgLenC4fYElGn0Gm1OLR+PSqLi1F+8WKj6Uy1tXD19cXohQs7sXRERJbMC1TEndmPtIuZMAlTk+k9HN1w25ibEBk6GxkXz2N/WgDC/EcgqM8AAJd69xEREVHPxEBeL3X5CrX1rd98CAmnsxEyyBdhIf6IPZgiB++EsHKwP3m6OSIsxF/+PzIiFIXF5fLfRESdIUmjwdEvv4ShshKmphotABVFRTi7c6e8Yi3nySOizqZJisWXR39EeXWFPA9eUxLOJ2FJ+AIEqwdBkxSLjKIsJOacxqyQaQ164hEREVHPw0BeL2VezKKwuBzeni5WA3pV1Qa8+mkc0rMKmz2es6MdyipqsPPQWcy6JgRA3XDdlx+9qUPKT0TUmNDISCTHxiLv5EnAaITJ1HjvFt9hdRPFx2/aJOdN0mgY1COiThMZOhuxKXtwIuc0aoyGZtObIPBa3PtYOuG2BnPsERERUc/HQF4vZe4hV1hcjk1b4+Vt6zcfQnFpJUIGqZGSng+TSUCSmj9eZZUBCoWEA8fSoc3UcT48Iuoy6uBg3Pb22/j+4YeR1cRCFwo7Oyz+8EMAgIu3txzEMwf1IqKiOqW8RNS7ZVw8DwAI9OqP9IIsGGFsNs9g7yAAlnPsERERUe/AQF4vZV7cQpupk3vkaeKS8OW2ozDUGjE+NADOjvaoqKpBWUWN1WNIkoQhA7ygL6+Go4MdcgtKkZFTBE1cUrPz4eXqSrBp+ylERoxi0I+I2oVOq5V7013MyEBBenqT6T0DA6EODoZOq5W3mVe7Nf8mIupoMfs24lj2SXg7e7YoiAcA/Ty4aAUREVFvxUBeL1c/oFdYXI4gf09k5BTjzDkd8i+WobHOeAqFBGdHFbIu6OHt6YxH75qB5PR8AC2bD+/Q8Qx8ue04AMki6NfU3H1ERE2p35subf9+VDax0AUA1JSWIi46GuWFhUjevh1AXS+81vbEqx9A5HBcImqtVVOXoaKmEvoqPfLLmp/ORAEJqHeFptWlQ5MUi8jQ2QhWD+rAkhIREVF3oOjqAlD3oIlLwvb9yZg8ZjDuvGEs3F0doVRcuki8fHitySRQVmFAdU0tcvL12LTtaKvON3F0EO68YWyDoJ957j5NXFKb60JEvY9Oq0VBaipc1Wr4h4Vh1C23QOXs3GQeIQT2vfsuKouLEb5kSZt74ZkDiEkaTZvyE1HvNitkGmYPn46ymgo42zk1m16pUCKtMANaXV2vY01SLDbF/wBNUmxHF5WIiIi6AfbIIwCWK8wCQHllDZyd7FFaXg2g6dVq7eyUGDzAG9/8mgAA8PZ0aXRobV2PuxOIGNsfq5deC4XCMpZsDuxxlVsiao0kjQbJO3ZAGI3YFxMDexcX1FZUNJmnXKeDpFSiqrT0iubD43BcIroSWl06Ugsy4O/RF2H+VyH2zB4YTdaH2DqpHDDA0x8pF1Kx/tA3mDl0MmJT9mBiUDgXvCAiIuol2COvF9Fm6hC9IQ7aTJ3V/cnpF/Dz7pMAgJtmXAUv9+bvCgOAMAlcMzoIwUE+mDNlOMJC/Bs9j3kevkPHM6weyzzUl8Nqiag1/MPC4BMcDLd+/ZAVHw9tXFyL8gmjEcVZWVd0bnVwMCKiojislojaRJMUix3Ju3Aq7wzizu5r8u6pAODu5AblnzdCzfPr5enzOayWqA1iYmIwaNAgODo6Ijw8HHv37m1Rvv3790OlUmHMmDEdW0AiIisYyOtFrA1bNQf3Xt+4Cwmns9HHwwnFpZU4cCwNuTp9i44rBPDJ5kPQZhTA080JiSk5jQ6PjYwIxZ03jMXE0UHtVi8iopzERJTrdHB0d4cwGlFbXd1kend/f0hKJSBJcPLyQlx0tMWiF0REnSUydDYWXR35/9u78/go63P//++ZTBYSSCAbEJawBAISiIKHCMqpAQE3UrQepPQb1K9t5bhVsD1gPcftVw9fPdVqrai1itoKQl1o6qFgKqhsgkBAImsgEDAJ2Sd7Msv9+yNmTMgOySQzeT0fjzw093zumesyzsVw5bPIx+SjGodNDsPZ4tgae62qbTWaNuJKSdL8iXM1fcSVuveaxe4KF/Aa69at00MPPaRHH31UaWlpmjFjhm644QZlZWW1ep/VatXixYs1a9YsN0UKAI2xtLYXaW7Zan1zLyK0r3zMJtXUOvRh6kE5nYYM1W2l3MqqWkmSxWJWba1d1bV2lZRV6a5bEpq8Tr2Y4RF6KPla5eXldVJWAPD9stao+Hid2LJFRzZvVkkrH8SvTE7W3j//WVUlJaoqLtb2V15RRWGhbn76aXeFDACSpJiIkXr65uUK7ROi57a+JrvR2sm1hg7nHldxZYkOnz8mSRoUHKnfbn1NUt1+ewDa5/nnn9fdd9+tn/70p5KkF154QZs3b9Yrr7yilStXtnjfPffco0WLFsnHx0cbNmxwU7QA8D1m5PUiDZet1s/Ei4+N0tyrxyliQJBioiNkkuT4rokntd3EkySn06nRw8MV4FfXF64/dVZSq0t5G2pr2S8AtKZ+eWtodLSCwsI0IiGh1fHH//lP1ZSWauD48Rp02WVuihIAWmYymxXRL0wmmVoc08e3j/wsvpoUNV6LptwqSUpJ36z9Zw9p1fZ33BUq4PFqa2u1b98+zZkzp9H1OXPmaOfOnS3et3r1ap08eVKPP/54u16npqZGpaWljb4A4FIxI6+Xqp+JJ9UdTlF/UMWcq8cpuF8fZZ4rVJG19Y3i6xmGoWGDBujyhUNVWFLhel5Jrn9v6fCL5uJpaywAtCQ9JUV73n5bfkFBMpnNMpzNLFEzmVReUCB7TY3CR43StUuXKnz0aA6rANCt4qPGKzRwgM6X5rf4i9TwoDDNHf8D3ZWwQDERI5WRn6mSqlIdzj2uQcGRysjPZK88oB0KCgrkcDg0cODARtcHDhyo3NzcZu85ceKEVqxYoW3btsliad9fo1euXKknn3zykuMFgIa8bkZecXGxkpOTFRISopCQECUnJ6ukpKTF8TabTcuXL9fEiRMVFBSkqKgoLV68WNnZ2e4LuhskJcZp0U1TFB8bpcKSCs25epwWXH+Fli6+Vi/9+keaOnG4+vj7tvk8/n4W3XJdvO66JUHL7kjUXbckaNFNU5SUGOd6jfacQNuRsYA3onZ1jrikJAVHRang5Mnmm3iSZBgqy8mRyWxWn/79OawCuATUrs5zMPuIMgoy5WxlPURRZbHCgga4mnUxESP18r89rekjr9QnRz/T6t3r3RUu4BVMpsYzYA3DaHJNkhwOhxYtWqQnn3xSY8eObffzP/LII7Jara6vs5d4wBYASF7YyFu0aJEOHDigTZs2adOmTTpw4ICSk5NbHF9ZWan9+/frv/7rv7R//359+OGHOn78uJK8fGZG/TLbg8eytXnHUfXv10dh/YO060Cmfvyrt/XF3pOqrrW1+hx9/H2VODVG/fs1f7ptzPAIJSXGKWVreptLZuvjkdq/HBfwJtSuzhEREyPfwMBWT32UpMCwMA2Ki9OYmTPdFBngnahdnSMjP1OFFcWaOuxy9bH4tzguduBoRQSF6vmtf1RGfqbrekmVVZW1Vfrboc369Fj7Tt0EerPw8HD5+Pg0mX2Xl5fXZJaeJJWVlWnv3r26//77ZbFYZLFY9NRTT+ngwYOyWCzasmVLs6/j7++v4ODgRl8AcKm8amntkSNHtGnTJn355ZdK+G5/pNdff13Tpk3TsWPHFBsb2+SekJAQpaamNrr20ksvaerUqcrKytLw4cPdEnt3SUqMU2FJhfYfOafsPKv8fH10NrdE4f2DZBhSVU3Lzbxam02pO4/J4TS0//BZzZ4+ToUlFdq846ikuiWyHV0yyxJb9EbUrs5VePLk99+YTM029cpycuS025V98KBCo6OVnpKiuKQkZuUBHUDt6hwZ+Zl64P3/0rH8k4qNHC2jlT3ysoq+1YZDm3Wm+KwKK+pm5yXFzVb/PiFyylB+eaFWbX+HQy+ANvj5+WnKlClKTU3VLbfc4rqempqqH/7wh03GBwcH69ChQ42urVq1Slu2bNH777+vkSNZ0g7Afbyqkbdr1y6FhIS4PkxK0lVXXaWQkBDt3Lmz2Q+UzbFarTKZTOrfv3+LY2pqalRTU+P6vn7jUqfTKWdLy7kukdPplGEYnfr8o4aGKax/oHLzrRoTHa4fXhunv32WrqAAP23Zc0Lmlj9Lfvd3Y0Nmk5SekaOCkgrNmR6rRTdN1rxrJ8jpdGretRMkGa7v28qjufE9WVf8TLqLt+TirjzM5s6b0Ezt6lzXPvywPv2f/1FVUZGcdntdM685Pj4qLyzUl6tX6/DGjTq1c6fmrVyp8NGjW3zu7nyfFJw8qfS//11x8+a1GmN7eMv7XfKeXNyZR2fVL2pX50g5lKoT+afkcNgVGRSmE2aLaltYNGN32DU/bq7yK4pUWFGstfs+kgzpzqn/JmtVqU4VZml69BTd+EqyIvqGamj/KCWOmaavvz2qa4dMVXh4eJfm4g6853seT/zsJUnLli1TcnKyrrzySk2bNk1//OMflZWVpSVLlkiqWxb77bff6p133pHZbFZcXOMtgCIjIxUQENDkOgB0Na9q5OXm5ioyMrLJ9cjIyBY3Lb1QdXW1VqxYoUWLFrU69bmljUvz8/NVXV3d/qA7wOl0ymq1yjCMS/qDLCffqt1fn1HCpGgNjgjRhBHB+tfLo3Tjv45XfOxQzU6I1p9TvlJ2Tr+2VqdJksxm6bqrxiq4bx/Xc0pO5eXlqZ+/tGjuZa7v28qjufE9WWf9THoCb8nFXXkMGjSo056L2tV5rDk5slZUaOyttypz+/aWB5pMGjBsmM6dOqWhkycr6l//VaU5OTrw6aea1K9fs897ZvduDZ86VUafPt3yPvn600918quvZA8MbDbGjvCW97vkPbm4M4/Oql/Urs6ROCRBpZdZlVuWJz/DTzFBw+UMdDa7V16Qbx9VWMuVGJ2gfx7frgWxNytxSIL6OQP1nzMekCStTH1JtvIa5VTkqqSwWIUFBcq15kklNn16fIdkkq4be40GhzRdPugJeM/3PJ742UuSbr/9dhUWFuqpp55STk6O4uLitHHjRkVHR0uScnJylJWV1amvCQCdwSMaeU888USbp/189dVXkppuWCq1vGnphWw2mxYuXCin06lVq1a1OvaRRx7RsmXLXN+XlpZq2LBhioiI6LK9D5xOp0wmkyIiIi7pD8k1mw9r7cavVWm36KHkMfpm82HtTD+v6OFDNHtG3Qfy+XMTlJ5Zok92Hm2zmWfxMWvwoFL1C6rV2YLjunN+gs5kF+nV9Tu0ZMHVmpnQeEPYzsqjJyCXnqcn5UHtquPOn8nhNWv09dq18uvXTyWHD7c4zmQ2a+y//Iv6hYcrbt48Saqb7TZrlsKbaUzUP69PZaUu+/GPu+X/r8tnzZKlsrLFGDuiJ71PLpW35NKT8qB21XHXzyQyMlJbv92t/z29RQ6HQzml+fLz8VGNw95krMXso9tCkrT1291af+xj/XjyLYofM1EnC07r7+n/1Ly46zTvX+bqxNYs14y8cyXZSis6LLPZrH0F6fIx+2h33kGtnLdCo8NHdFleXaUnvVcuhbfkIXl2Lvfee6/uvffeZh976623Wr33iSee0BNPPNH5QQFAGzyikXf//fdr4cKFrY4ZMWKEvv76a50/f77JY/n5+c1uWtqQzWbTggULlJmZqS1btrT5odDf31/+/k03IzabzV36B5jJZLrk10hKnCjJpKTEOJnN5ibf17/O0EEDFDsyUodPtj4zrtbu1D+2H5WvxSx/P18dzcxTkbVSh0/mKiOrQO//7v8qZniEJCkjK1+rP/pS/fvUNQvHRF/aX0Z7gs74mfQU3pJLT8mD2vU9d/1MhsTHK3PHDlUUFUmtLPExnE6lrV2r+1JTXfvizWzQJLjQxKQkmSRNmDdPzg7kkp+R0Wn770WOGdNqjB3VU94nncFbcukpeVC7vueun0nSxNmSSYoICtXvv3hTeeUFcjqa1rBap1Ov7HxH7/yfFyWTlBQ3W2azWX//5p96+6v12pH5le69ZrGuGFa31O+uhAX63Wd/kt1wqrymQrUOu0L8++hEwSn9/Zt/KilutlLSU5UUN9t1Eq4n6CnvlUvlLXlI3pULAPR0HtHICw8Pb9eeHtOmTZPVatWePXs0depUSdLu3btltVo1ffr0Fu+r/zB54sQJbd26VWFhYZ0We0/U8ITY5r6X6g6dWL8pTaUV7V+uYjaZFRhg0dFT5xUZ1k9mk0l5hWV64L8/0Eu//pFihkcoZWu63t98QOOG95OPf5CW3VF3YmRGVr5StqYrKTHO1fQDPB21y/2yDx7U+aNHVVlY2OZYW3W1q8nWVrMtIiZGicuWyens2LL/9JQU7VuzRpKU2MEmXGc2AYGOoHa5X0zESFdT7f/Ne0RbTuzUuv0pKq0pazK2uLJEMREjtSzx565rSXGztePUV8ooyNSq7e8o7Vy6qmqr9Pae9RoTNrJuxz2TSYYMhQYO0G2X36SkuNn63Wev62+HNuvv6al6feGzHtXMAwCgt/KqX5mMHz9e119/vX72s5/pyy+/1Jdffqmf/exnuvnmmxttuDxu3Dh99NFHkiS73a7bbrtNe/fu1bvvviuHw6Hc3Fzl5uaqtra2u1LpdkmJcZpz9TgFBwW0+55au13llbUaHhWqy0YP0rhRA2U2m3Us87xStqZLkuJjozQ6OlxXjB+qedfW/bY4Iytfy59P0dt/2+MaB/Qm1K7OE5eUJL/AwLqlfT4+rY4N6NtX5w4c0PsPPKBdb7yhDx54QB8/+qjyMzI6NZ4pixYpLimpw/fWNwHTU1I6LR6gM1G7OldKeqre2LVGK/6+UqF9QlRWU97suOgBw5pci4kYqWeSfq07pi7Q/IlzFRzQVw45Veuw6XDeCdmdTjkNp0wyKSZ8hJLiZmv17vX6/MQu1TpsOnL+hH732Z/06MfP6NGPn1FGfmZXpwsAAC6SR8zI64h3331XDz74oObMmSNJSkpK0h/+8IdGY44dOyar1SpJOnfunFK++0vS5Zdf3mjc1q1bde2113Z5zD1RzPAI9e/XR7U2h3wtZtkdzjb3yjMMKXxAkCRD2/ef0s0/mKDpl9f9ZjcpMU4ZWfn67VtbdOJ0vhKvGKrRw+p+25+yNV0ZWQWKGR6upEROfULvRO3qHBExMZr3//6ftq9apb4DB+rQhx/KaGGJbU15uU5s2SJJCgoP1/ljx5SfkaGgsLAOz55rLZ7658rPyNDu1aslSQl33dXmLLv65t/FNAEBd6F2dZ74qPGqttcov6JIq3a8LaOZwy4k6WxJdrPX62f1PfDBf6mkqlRR/SKVX1Eku9N+wXMZ+t1nr+vDgxvl/O7DndNw6tNj21TrtEmSjp7P0PQRU/TnvR9oUtR4PXb9UmbrAQDQQ3hdIy80NFR/+ctfWh1jNOhIjRgxotH3aKzW7pCjmT1aWlJUWqmqapuGR4VKkmYmjNGH//xaD/z3Bxo1NEzHMvPlcDga3VPfvKv/5/Nvb73kJbYs1YWnoXZdmobLUGNnzVLsrFn67b/8S4tNPEny8fNT+KhRKjpzRlGTJqkiP19ho0YpKj5eW59/vsmS1vyMDB1KSVHwhAk6/M03mtjg8fYsg01PSVHa+vWu74PCwtq1nBfoyahdnSMjv25JbK3DJpPJpMigCJXVVDQ7Nr+iUJ8e26ZZsTOaPJaSnqpjeSflMBy6KW62JOnPX70vX5OP+lgCZMjQ2ZIcBVj85TAa18eymnJFhw7TtyXZ2nV6r/ZmHVSVvVo5pXkaNmCInr55eecnDgAAOszrGnnoPHfdkqCzucX6Yt9JVVXZWvi9cGN2m1PDR4Rq1NAwvfvxXq35372qqrHLcBrKybfqmskjVVBSoUmxg133NNyj7/m3t2rN/+6TpCb79kntb9ClbE1v9XkAeJeGe9HV73l3xcKF2vb738tWVdXsPfaaGjklDYiOVsnZs6osKtLQyZO1fdUqFWRkqKKwsFGzLT0lRfvXrtXA6dN1fudOmfT9vnft2QsvLilJFd/t3VdVUqK09etVUViohLvuatIEZH88oHdJSU9VRkGmwgIHqLS6XFX25utWvd9ufU0Hs48oPmq8DmYfcR1WkRQ3W4UVxZLqDrqQ6mbXnSo4rYi+YfIv8dVlg8bq1knX67dbX1NVTbVOFp2Rr9miy4fE6VThaVXZayRJJn1/8vDfDm1WSVWpll77U2bmAQDQzWjkoUUxwyN0+bihOngsWyOHhOqbjKYn0zVkklRda9eh49k6cjJXldU21/W+Qf6y2RyqqKpVTp5VG784olEjhjc5tTY+Nkp//yxdf/8sXfGxUZp1VWyjx9vboLtwlh8z9ADv1nAZanpKiva8/bbCY2IUMmSIClra887pVN4330iqm50XNXGizu7fr+KsLA0cN06SGjXn4pKSZEgKnjBBQ6KjGy15bc8y2IiYGN389NOSpI8ffVRSXUMvZfnyJo3DSzkkA4DnSfpu9lx9Yy4iKFRPbf6drNVND7swSfom55jSzh5SoF+gahy1OllwRi//29OKiRjZZObcM0m/VsqhVE0IHq240Zcpfkjda/wy8R6t2v6OsqzfysdkVpW9SkWVJbKYLXIaDjkNQ2aTWX0s/sorL1BK+maVVZfpyPkMLbwiSSaz2eNOuwUAwBvQyEOrkhLjVFhSoZKyKp06W6iqGnuLY+tn7NXaHKq1fb981mQyae7VsTpfWK75Mydq7T/26dTZQr21Ybee/sU817iMrHytem+7TpzJl83u0Kr3tjdp5DVs0DVszklq1KiLGR6hpMQ41zVm6AHereEy1LikJJ3asUPnjx6Vo52b5/v4+ips1Cil//3vMvn4yC8oSJHjxun80aOKio93vca1Dz2kvLw8Rc6eLbP5+/OiOroMNuGuuxQUFqaKwkKd2r5d4d/Nums4q1BSi8t8AXiXhqfQ1i+ZfWXHn5tt5BmSqr+bNVdeW7f89nDuMT368TOS6mbiNWyuxUSM1Ly467Rh9z9UonJtObFTm49uVerRcB3LO6no0KGaPvJKlVSVKj3nqPx8fDV+4GWqttfoTNE5XTFkgo7ln1RwQLD2nDmgoqoS/c/WVxUW2F+SGp2eCwAAuh6NPLSovlEmSZ/sOCp7B/bKa8hpGPrblnSFD+ir/OIKXTFuqNKPnHS9xuqPdjd4zQKNiY5QgL+v7l14TZPnargM99EXP9b6TWkqLKlQWP8grfnffa5/v7B5d+EMPQDeKyImRknPPKOU5cuVuWtXu+7xDQxUxuefy15TIxmGjm3e7Fpuu33VKoVGR7saaecOHtSGF19U2MiRunbp0kbLYZs7zKJ+mazTMJT23nsaO3u2stPSFDZqlCbdeqtrFl69isJCZe7apVM7dqjg5Emd2V1XI5mZB/QOGfmZWr17vYq+WyLbFh+Zda4kV2/tXid/X3+FBQ1wNdfqnyvtXLp8qqTj5Zm67Yp5mjsuUTsz90omaVj/wdp/9pACfQMUEzZCwwZEqV9AP5V910QsqixReU2liqtKFejbR1Ld4RiBfoGumYQAAMB9aOShRfWNsIRJ0YqJjlDEgCDtOZSlImtlu+4P8LOourZuBp/Dachkkg4cPSeTpMGRIUqcOkYpW9P17sd7VWNzaHp8tGKGh2v+zInKL65Qdp5VP3roDVdD77dvbdWooWEaNTRUqz/arapqm6pr7TqbW/dBd+7VdUvhmmveNWwAtoYluIB3qG/mvfeznynv2DH1GTBAFfn5LY6vf8zs4yOTj48ctbWy19YqPCZG548eVcry5Zo4f74O/e1vqvH11bf79+vc/v3q07+/a4+7isLCRodZVJWUqPDUKYWNGqVT27ervKBATptNe958U4bTqbNpaTq1Y4fmP/ecq+kXFBamPW+/rbT161VTVqaB48drQHS0a1YgAO+Xkp6q9Wkpqqytbtd4h5yyVpfKJJOM2mq9tuMvevPLtVo+6z59eSZNH369UQE+fkocOk2OPtK4yNHacGiz8sryFRsxWl9nH1F26XmZJJlMZp0p+lbltrqZfiaZZDLV7ZVnGE6VO53q6xckh+FQkG+gHvjgv7Ro8nzlVxSxzBYAADehkYcW1TfCTp4tUMaZfE0eP1R3/HCqFv3HO2rPgXP1TTyp7sS6/KJyfbLzmMwmacrYMH19PFtJiRP1x7/uUGW1TTsPnJa/n0W5+aXKyi1RUB8/FZdWqrLapsAAX+0/fFYHjn4ri9mkmu+W7ppM0smsAn2x96T6B/dR8rwrFR01QPGxUY2adxySAfQ+ETExWvj66/rggQeUe+SI/Pr2VW15eav3OB0OWSwWmcxm1ZSXq7KoSH1CQnR23z6dS0uTrbpaoZMnS6qra5k7d+rc/v0qyspS6PDhGjdnjvr076+qkhId/OADGU6nis+eVf9hw1Sam1t3X/1Juk6nSrOz9clvfiNJ2vjYY6598mzV1eo3aJBsNTX6Ni1NJ7ZsUeysWV33HwtAj1F/YMWavR/K5rS1+z5DhuyGQ8VVJZKkRz5eKcMw5HA65DA5FBEUqkPfHtOafRt0LP+kogcMUUF5oXJK8767/7tmna2i0XM2PGXYYTi+X86bd1yS9HX2EZkk1z59AACga9HIQ4vqG2GPvvix69qsq2L1o9mT9P4nX3fouQxDstudMptNMptMMptNeuuj3TIMQxYfH0l1s/Yqq206k1OsWptDdntdsy6/qEy/+D8/0LHMPBUUl6vG0fh5T2QVSJIqq21a/dEelZRVuWYNHjyW3aE98liCC3iXiJgYhY0apbNpaZLTqX6DB8tWWalqq7XxwO9mnMgw6pbXSirLyVFZTs73Q8xmmXx9FThggKojI+Xr56e848fr6pi/v3KPHNHQyZM1ZuZMvX/ffa6GXXl+vioKCtTSb0AKTp7UhocfVml2tiTJUVury264QYWnTin3yBEZDkez9wHwTvUHVpwtztamo1sv+nlqHbYG/25Xes5RDe8/VMfyMmR32JVfXqS88oJLjtf23et8enybPj22rdEpugAAoPPRyEOb7rolwbXvXEZWvs4XlsvP18d1oMWA4D4qLq1q83kMSQH+Fg3oF6CKKpvyisr1P29ukcXiI4uP2bUHX/3zOpx1f+nNyinRM3/6p0rKq+VsYyZgSWmlau1OfZORqyVPrZefpa5JaBhOWcurZBit7/PX3iW4AHq++r3pqsvKpO+aaiaTSRExMTq7b1/TG9qYamw4nTJsNpXl5qqquFiVNpurWWez181A/uqdd/Tlm282br4ZjWe0XMheXa3S7GyZfX3l/O55SnNzZc3O1qDx4zV08mQl3HVXR1IH4OEy8jM1bECULosc65r51l4mfX8AWUM1DpvSTu+T3bDL3+KngoqiDj2v2WSSs5VaVlRZooc3PCXju1fnEAwAALqGue0h6O3qm1sxwyO0+qPdSjvyrcZERygytK9MJqmsoqbdz1VRZVN2/vcnsDmNusad3eHUgOA+8rU0/79kXnFFo5NwW1Jr/75RZy2rVmV1rbbvP6nfvfO5rGXVeu8fae2OFYBnS09J0b41a1SRny+Lv798/Px0ZXKyEn/5y+9n4NVrz34BDcY6GzTxGrLX1Fz0DDqnrW5WS0BwsK65915NuPlmVxOPE2uB3iUlPVWbj25VWN8BGtAnRL7m9v/uvblqZjH5KMDHT84Gv9A0DEN+Pr5Nxvr5+CrEv598TOZG1/r591Uf3wCZTWZZTD5N7jNJyi8vVFTIIA7BAACgCzEjDx3mYzZp+uUjNTNhjFa9t13pJ3LaNSOvLSVlVfIxN/7LtdmkNmfhNcdsNskw6pbq7kjLlGFI/n4WPfiTf73kOAF4hvqTYKPi47V91SoVZGTIbDIpdtYshY0ercKMjG6OsDGTj4/MPj4adfXVip01S9kHD2rfmjUKCgvjxFqgl6lvhMVHjdfB7COKCArVE5ueU1lNRRt3Ns/P4qtAv0D5+lhU67ApblCsJJO+zj7cZGz0gCEqr6mUtaZMJpkU5BuohZOTdCz/lKaPmKKdp/fpdOE5nbV+W/fcZl+ZzCb5mn1ld9bNKj5TdE4p6akssQUAoAvQyEOHNFxmGzM8QrOuitXVP/mdikurZDJ1bFLLhQxDsjsaP8HFNPEkyeJjds3gs/iYFBnWT8/9ar5mXRV78QEC8CgRMTGuBlhodLTSU1JczT1bZftO33YnQ1JQeLgm3Xqr8jMyVFFYqHFz57piBtB7xESMdC1NnRU7Q89v/aMCLAHqYwlQSJ9+Kq+pVE5ZXrufr9JWraKqEtkcdplNJo0KH6Fc63nZnHaZTWaZZZLdqPvcdKLgtOs+Q4bKbRX66NA/VFpdrmN5J+VjNqu85vtTbZ2GU3a7QzaTXX18/XUk94R+u/U15X+3/x5LbAEA6Fw08tAhze0hN3p4uE59W6TI0CDlNFg2e7Gz6TpD/X5UPmaTYkcO1H/eM4cmHtCLNWzqSdKVycna9oc/yFFb61rS2p18AwNlq6pSZVGRsg8eVPbBgzq6ebOmLFrEsloArhl6hRXF2nx0q6L6D5K1uky+PnUf5X1MPiqrKZftuxlxrXEYTv3vN/9Uta1aUt0+whH9IlttDBZWlkiS8soL5GP2kY/JLIvZogCLvwYFRyrHmqsae61q7TaZzWZFBIUp0LeP4qPGKyM/k9l5AAB0Ihp5uGTDBg1Q3z5+umbyaH3+1QnlFVUoMjRIAf6+ysop6fTXs/iY5GvxUVXN9x9WoyL6ye5wKq+ofslJ3RJdwzB0JrtYB49l08gDern6wy+i4uN1eudO9QkOVlR8vDK2bpW9tlYBwcGqrayU0+mU3HhSrMnHR/59+8pWVaXA0NBGM/CYjQf0bg2bYMsSf65Pj23T/nOHFBEUplEToiUZ6t8nRKF9QrR6z3oVlhfJodYP9pKkStv3W6IYUqtNPB+ZZTKbZHfWH0bmkEMOmWRSWNAAXTF0gqxVpfL39ZckXTYwVvkVhcq25upg9hEdzD6iNfs+lMTsPAAAOgONPFyy+uW28bFRkqRT5wr1yzsT9dhLG7vk9RxOQ44au0wmKaiPn2ptDk2KHaJhgwZo844jOptbIrPZpKjIYJWUVil2ZKSSEuO6JBYAnqP+8ItTO3aoICND4TExGjBsmPyDg9UvMFA+fn4qOHFCJh8f9R08WGU5OZ0eg9likdnHRzKb1ad/f/n37auhl1+u6Kuu0qENG3TNvfe6Yo1LSmI2HtDLpaSnNmqCbTmxU+k5R+Xr46srhsS59rjr3ydEhZXFCusbqrzvlrS2l9lkbnQIxoVMZpMCLAGqsFU2OoF7QJ8QfWvN1afHtmtwyEAdzz8lu8OusyXfqrK2UoF+gYqPGi9J2nFqmOvfAQDApaGRh0tWv9z2+be3avfXZ7TopimadVWsPvzn1zqdXSR/P4ucTkPVtXY5nUaTwyI7yvUZ0pACA/z04xsnSpI27ziqiNC+KrJWKXZkhBbdOEUbthzSvQuvUczwiEt7UQAer+HhF9kHD7q+DwoLU1R8vD75zW9k9vVVaHS0LP7+qrZa5ePnp2qrtX0bgDbcKNTHxzWrr29kpKbedZf2/vnP6jdokMpyc1VZVKSqoiLF3Xyzbn76aUnS1ORkSdLW55/XvjVrJIlDLoBern5JbcNTYH19fBUbMVr3XrNYW07sVElVqXKsebI5bLpx/Ey99dV61+y59ujnHyRrdVmjaxazj+s57E6HymvrVjz4mH1kMiS74VCNvUZ2p11FVSUaHBKp+ROv16nCM1o0eb7W7N+gY3knteXEToUFDdCZ4rM6mH1Es2JnXOp/EgAAej0aeegUGVn5Kiyp0Nyrx7lmv9163STlFpSqyFqhbzLOS6rbs2786Ej171N3n5+vue7vvYZkczT+bfCFe+z18bfI6ZR8fesOsvD3s8gwDNfhG/WzAg8ey1ZSYpxStqazrBaAS8N98mJnzXJdT1y2TFuff16VRUUacdVVGjhunL75+GMNmzJFwYMG6cg//iFLYKAqCwrkKkkmkyIvu0x5R45IhqHw72bOFZ46JZnNChs5UoZhyNffXwn/9/+qIj9fE266SWnr18vpcCgwNFQ1paXNxlnfYGRZLYCYiJFKipvtWl57V8IChQUNcO03V38QxidHP5PDcCr1+La67QEaCPLto2pbbYuvEdk3XLX2WlXZazS4X6T8LH4qqylX0Xf74kmSn4+vbA6b+voFqqK2Sj4y64qhE3U8/5SKK0t02aCxevnfntanx7Zp1fZ3FBEUpgxTpqTmm5EAAODi0chDp0jZmq7NO45q0U1TXLPfDh7L1pnsYiVMilZNrUNF1kpNnThcwwb1176vj0uSam1O+ZhNajhNzyRpcGSwJo2N0udfnVRNrU1OQ7osZrD+8eoSZWTlK2VreqOmXcNDOOqbdvUNxa5cVnvybIE+3f61Zl1zucZER3bZ6wDoWi01z8bMnKnw0aMVFR+vDQ8/rNLcXEnSyKuvVsjAgTKbTOo/bJgq8vNVmJmpfoMGKXDAAFUWFWnqHXe4moT71qzRuLlzdcWCBaoqKWn0GvkZGY2W0F54MAeA3u3C5bXLEn+ujPxMPfrxM5KkmWOma8EVSdp/9pCyis9pVFi0SmvKNDZitMYPGqOzxdn69Ng2mSSZZZLFx1dTh0/WqcLTkmHoTPE5TR0+WSaTdO81ixUdOlT/8bf/1o7MPTJkyCyTDMNQoG8fVdRUymQyKX5InJ794aOu+OqbdKu2v6MdmV8pPChUQ0MGq6TK6oobAAB0Dhp56BTNNc0aXkvZmq41/7tPl48bqnnXTpCvanQsq1QV1XYF+FvkYzarutYuQ1KAn0U2m0PDBg3QL5J/oIgBQa4lspKaNO0ysvL1/NtbXQ29es2dsNvZ/v5Zur46cFKVdouW3TGzS18LQNe5sHkWFBamfWvWKCgszHV9/nPPaetzzyl86lT522w6sH69DIdDNeXlqq2slH+/fnLU1mrk9OkKCgtr0hysX9IrSUc3b9aA6Gid2b270WsAwIWam9GWkp6q9WkpkqSwoAF6+ublLZ4Oe8Or/0cOwykfk48uHxqnK4bF6a6EBYqJGKkbXv0/yinLV5W9Sv9Y8hdJ0vNb/6gD2ekymUwyyaT+fYJVXlOhanutnIZTgZYALZoy3xVHfVzPb/2j5k+cq6zib5VfXihrdanOlHyrU4VZmjx0omaOma6D2Uc4vRYAgEtEIw+dormmWcNrDZt6o4aGacnt1+iaqXF6Zd0OzZ85UfnFFYoYEKTfv/uFSqxVCuzjp5kJY1yz65KTprb42vVNQkld3ri70Lxr4xRosWvWNRymAXiT5mboxc6apTGJicrLy5O5rEwmSWf371dxVpYGjhuna+6917X3Xv0Mu/qTcuOSklyHbYybO1dTFi1qslcfADQnJmJkkxltSXGzVVhRLEmKjxqv57f+0XWy7YV+mXiPntv6R00Nn6Sf/OuPNCZyVKPHVm1/R/des7jRc6ce/UJfZx+WyWTSrLF1+9p9nrFL+eWFqrBV6bGN/6MbJ8zS7jP7Xfet2fehFk25VWvveFmrd69XSVWpThWe0Tc5x5R2Ll1/O7RZhuHUjlNf6ZmkX9PMAwDgItHIg1s0bOrV790yM2Gsrps2zrVU9mhmnmptDvUP6aNam6Pde9u5YwltS0YPC1e/WZMUGRnu9tcG0HXaWt4aPnq0bn766UaNuoiYmEZ770nfn5QrNW4O1jf6LhwPAO0REzFST9+8XFLdTLiGS28vNCt2hhLHXK28vDxFhkc2eezCAyhiIkbqpdv+P63evV6SdFfCAqWkp2r7qd0K9A1Qha1KFbYqnSrI0qIptzaaKVg/264+toz8TN325s+VXXpexZUligoZpIyCupmDLLcFAODi0MhDt0vZmq63/7ZHUZEhuvkHEzQzYYxr77v2cMcSWgBoTlsNvwubdyyhBdDZuuIwiYbNuIbPHREUqjd3r5MMQ7+ceY+rCZiRn+kam5Gf2agJ+Nz8x/TbLa9pVPhw3TrpBtfyWgAAcHFo5KHbJSXGaUfaKWVkFWj2tFjNuiqWU2YBeAWadwC6WnNLb7vyNZKn3tbk8YYHckhqtH/fssSfN5r1Fx06VCnpqYqPGs+eeQAAXAQaeeh2McMj9MyyJKVsTe+W5bEAAAC4ePFR47Xj1DDFR41XdOhQ1/59F868y8jP1PKU/1ZGQaZiwkfqTPFZSZxqCwBAR9DIQ7er3yPvwlNnAQAA0PMdzD6ijIJMrdr+jp5J+nWjZbkNpaSn6uj5Ewr0C9T8iXOVX1HEMlsAADrI3N0BAPWnzqZsTe/uUAAAANBBSXGzFRM+0nWQRWvjxg0co1pHrfIrirQs8ecsqwUAoIOYkYdOc7Ez67rz1FkAAABcmpiIkXom6ddKSU9tdYZde8cBAICWMSMPneZiZ9bVnzrLsloAAADPVH8gRlsz7BoenPH81j82OvEWAAC0jRl56DTMrAMAAEB7NDzplsMuAABoPxp56DT1M+sAAACA1tQvrWWJLQAAHUMjDwAAAIBbNVxiCwAA2o898gAAAAAAAAAPQCMPAAAAAAAA8AA08gAAAAAAAAAPQCMPAAAAAAAA8AA08gAAAAAAAAAPQCMPAAAAAAAA8AA08gAAAAAAAAAPQCMPAAAAAAAA8AA08gAAAAAAAAAP4HWNvOLiYiUnJyskJEQhISFKTk5WSUlJu++/5557ZDKZ9MILL3RZjABwIWoXAE9E7QIAAHAvr2vkLVq0SAcOHNCmTZu0adMmHThwQMnJye26d8OGDdq9e7eioqK6OEoAaIzaBcATUbsAAADcy9LdAXSmI0eOaNOmTfryyy+VkJAgSXr99dc1bdo0HTt2TLGxsS3e++233+r+++/X5s2bddNNN7krZACgdgHwSNQuAAAA9/OqRt6uXbsUEhLi+jApSVdddZVCQkK0c+fOFj9QOp1OJScn61e/+pUmTJjQrteqqalRTU2N6/vS0lLXczmdzkvIomVOp1OGYXTZ87uLt+QhkUtP5K48zObOm9BM7fIc3pKLt+QheU8u7syjs+oXtctzkEvP4y15SJ752QsAPJlXNfJyc3MVGRnZ5HpkZKRyc3NbvO+ZZ56RxWLRgw8+2O7XWrlypZ588skm1/Pz81VdXd3u5+kIp9Mpq9UqwzA8+g8yb8lDIpeeyF15DBo0qNOei9rlObwlF2/JQ/KeXNyZR2fVL2qX5yCXnsdb8pA887MXAHgyj2jkPfHEE81+eGvoq6++kiSZTKYmjxmG0ex1Sdq3b59efPFF7d+/v8UxzXnkkUe0bNky1/elpaUaNmyYIiIiFBwc3O7n6Qin0ymTyaSIiAiP/gPfW/KQyKUn6kl5ULvq9KSfyaXylly8JQ/Je3LpSXlQu+r0pJ/JpSKXnsdb8pC8KxcA8AQe0ci7//77tXDhwlbHjBgxQl9//bXOnz/f5LH8/HwNHDiw2fu2bdumvLw8DR8+3HXN4XDo4Ycf1gsvvKDTp083e5+/v7/8/f2bXDebzV36B5jJZOry13AHb8lDIpeeqKfkQe36Xk/5mXQGb8nFW/KQvCeXnpIHtet7PeVn0hnIpefxljwk78oFAHo6j2jkhYeHKzw8vM1x06ZNk9Vq1Z49ezR16lRJ0u7du2W1WjV9+vRm70lOTtZ1113X6NrcuXOVnJysu+6669KDB9BrUbsAeCJqFwAAQM/lEY289ho/fryuv/56/exnP9Nrr70mSfr5z3+um2++udGGy+PGjdPKlSt1yy23KCwsTGFhYY2ex9fXV4MGDWr1tDUA6CzULgCeiNoFAADgfl439/ndd9/VxIkTNWfOHM2ZM0eTJk3Sn//850Zjjh07JqvV2k0RAkBT1C4AnojaBQAA4F5eNSNPkkJDQ/WXv/yl1TGGYbT6eEv7swBAV6F2AfBE1C4AAAD38roZeQAAAAAAAIA3opEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeABLdwfgLQzDkCSVlpZ22Ws4nU6VlZUpICBAZrPn9mC9JQ+JXHoid+bRr18/mUymLn2Nrkbt6hhvycVb8pC8Jxd35+Hp9Yva1THk0vN4Sx4Sn70AwN1o5HWSsrIySdKwYcO6ORIA7mK1WhUcHNzdYVwSahfQO3l6/aJ2Ab2Tp9cuAOgMNPI6SVRUlM6ePdulvyUqLS3VsGHDdPbsWY/+A8xb8pDIpSdyZx79+vXr0ud3B2pXx3hLLt6Sh+Q9ubg7D0+vX9SujiGXnsdb8pD47AUA7kYjr5OYzWYNHTrULa8VHBzs8X/gS96Th0QuPZG35NHVqF0Xx1ty8ZY8JO/JxVvy6GrUrotDLj2Pt+QheVcuANCTefaGDAAAAAAAAEAvQSMPAAAAAAAA8AA08jyIv7+/Hn/8cfn7+3d3KJfEW/KQyKUn8pY8vIk3/Uy8JRdvyUPynly8JQ9v4k0/E3LpebwlD8m7cgEAT2AyDMPo7iAAAAAAAPBmpaWlCgkJ4fRdoJfoqvc8M/IAAAAAAAAAD0AjDwAAAADQ66xatUojR45UQECApkyZom3btrU49sMPP9Ts2bMVERGh4OBgTZs2TZs3b3ZjtABQh0YeAAAAAKBXWbdunR566CE9+uijSktL04wZM3TDDTcoKyur2fFffPGFZs+erY0bN2rfvn1KTEzUvHnzlJaW5ubIAfR27JEHAAAAAOhVEhISNHnyZL3yyiuua+PHj9f8+fO1cuXKdj3HhAkTdPvtt+uxxx5r13j2yAN6F/bI66WKi4uVnJyskJAQhYSEKDk5WSUlJe2+/5577pHJZNILL7zQZTG2R0fzsNlsWr58uSZOnKigoCBFRUVp8eLFys7Odl/Q3+nIlHtJ+vzzzzVlyhQFBARo1KhRevXVV90Uaeu8aelAR38m9Xbs2CGLxaLLL7+8awMEtYva1am8pX5Ru3o+b6ldkufWL2oXtcsdamtrtW/fPs2ZM6fR9Tlz5mjnzp3teg6n06mysjKFhoa2OKampkalpaWNvgDgkhno0a6//nojLi7O2Llzp7Fz504jLi7OuPnmm9t170cffWTEx8cbUVFRxu9+97uuDbQNHc2jpKTEuO6664x169YZR48eNXbt2mUkJCQYU6ZMcWPUhvHee+8Zvr6+xuuvv24cPnzY+MUvfmEEBQUZZ86caXb8qVOnjMDAQOMXv/iFcfjwYeP11183fH19jffff9+tcV+oo3n84he/MJ555hljz549xvHjx41HHnnE8PX1Nfbv3+/myJvqaC71SkpKjFGjRhlz5swx4uPj3RNsL0btonZ1Fm+pX9Quz+AttcswPLN+UbuoXe7y7bffGpKMHTt2NLr+9NNPG2PHjm3Xczz77LNGaGiocf78+RbHPP7444akJl9Wq/WS4gfgGaxWa5e852nk9WCHDx82JBlffvml69quXbsMScbRo0dbvffcuXPGkCFDjPT0dCM6OrpbP1BeSh4N7dmzx5DU5geHzjR16lRjyZIlja6NGzfOWLFiRbPj/+M//sMYN25co2v33HOPcdVVV3VZjO3R0Tyac9lllxlPPvlkZ4fWYReby+23327853/+p/H444/3yA+U3oTa1Ri169J4S/2idvV83lK7DMNz6xe1qzFqV9epb+Tt3Lmz0fXf/OY3RmxsbJv3r1mzxggMDDRSU1NbHVddXW1YrVbX19mzZ2nkAb1IVzXyWFrbg+3atUshISFKSEhwXbvqqqsUEhLS6pRvp9Op5ORk/epXv9KECRPcEWqrLjaPC1mtVplMJvXv378LomzqYqbc79q1q8n4uXPnau/evbLZbF0Wa2vctXTAHS42l9WrV+vkyZN6/PHHuzpEiNp1IWrXxfOW+kXt8gzeUrskz6xf1K7GqF1dKzw8XD4+PsrNzW10PS8vTwMHDmz13nXr1unuu+/W+vXrdd1117U61t/fX8HBwY2+AOBS0cjrwXJzcxUZGdnkemRkZJM/dBp65plnZLFY9OCDD3ZleO12sXk0VF1drRUrVmjRokVu+wOwoKBADoejyR/mAwcObDHu3NzcZsfb7XYVFBR0WaytuZg8LvTcc8+poqJCCxYs6IoQ2+1icjlx4oRWrFihd999VxaLxR1h9nrUru9Ruy6Nt9Qvapdn8JbaJXlm/aJ2NUbt6lp+fn6aMmWKUlNTG11PTU3V9OnTW7xv7dq1uvPOO7VmzRrddNNNXR0mADSLRl43eOKJJ2QymVr92rt3ryTJZDI1ud8wjGavS9K+ffv04osv6q233mpxjCfk0ZDNZtPChQvldDq1atWqTs+jLRfG2FbczY1v7rq7dTSPemvXrtUTTzyhdevWNfuXgu7Q3lwcDocWLVqkJ598UmPHjnVXeF6L2tV2Hg1RuzqPt9Qvalf38JbaJfWO+kXtona5y7Jly/SnP/1Jb775po4cOaKlS5cqKytLS5YskSQ98sgjWrx4sWv82rVrtXjxYj333HO66qqrlJubq9zcXFmt1u5KAUAv1XN/TeLF7r//fi1cuLDVMSNGjNDXX3+t8+fPN3ksPz+/xSnf27ZtU15enoYPH+665nA49PDDD+uFF17Q6dOnLyn2hroyj3o2m00LFixQZmamtmzZ4tbp6Bcz5X7QoEHNjrdYLAoLC+uyWFvTGUsH/vrXv7a5dMAdOppLWVmZ9u7dq7S0NN1///2S6paqGIYhi8WiTz75RDNnznRL7N6A2lWH2uU+3lK/qF3dy1tql+Td9YvaVYfa5T633367CgsL9dRTTyknJ0dxcXHauHGjoqOjJUk5OTnKyspyjX/ttddkt9t133336b777nNdv+OOO/TWW2+5O3wAvVmn7riHTlW/UfHu3btd17788stWNyouKCgwDh061OgrKirKWL58eYc2N+5MF5OHYRhGbW2tMX/+fGPChAlGXl6eO0JtYurUqca///u/N7o2fvz4VjddHj9+fKNrS5Ys6fZNlzuah2HUbeIbEBBgfPTRR10cXcd0JBeHw9Hk/fDv//7vRmxsrHHo0CGjvLzcXWH3KtQualdn8pb6Re3q+byldhmG59Yvahe1y9t11cb3AHomTq3tpa6//npj0qRJxq5du4xdu3YZEydONG6++eZGY2JjY40PP/ywxefoCaendTQPm81mJCUlGUOHDjUOHDhg5OTkuL5qamrcFvd7771n+Pr6Gm+88YZx+PBh46GHHjKCgoKM06dPG4ZhGCtWrDCSk5Nd40+dOmUEBgYaS5cuNQ4fPmy88cYbhq+vr/H++++7LebmdDSPNWvWGBaLxXj55Zcb/bcvKSnprhRcOprLhXrq6WnehtpF7eos3lK/qF2ewVtql2F4Zv2idlG7vB2NPKB3oZHXSxUWFho/+clPjH79+hn9+vUzfvKTnxjFxcWNxkgyVq9e3eJz9IQPlB3NIzMz05DU7NfWrVvdGvvLL79sREdHG35+fsbkyZONzz//3PXYHXfcYfzgBz9oNP6zzz4zrrjiCsPPz88YMWKE8corr7g13pZ0JI8f/OAHzf63v+OOO9wfeDM6+jNpiA+U7kHtonZ1Jm+pX9Suns9bapdheG79onZRu7wZjTygd+mq97zJML7bERYAAAAAAHSJ0tJShYSEyGq1unX/XADdo6ve85xaCwAAAAAAAHgAGnkAAAAAAACAB6CRBwAAAAAAAHgAGnkAAAAAAACAB6CRBwAAAAAAAHgAGnkAAAAAAACAB6CRBwAAAAAAAHgAGnkAAAAAAACAB6CRBwAAAAAAAHgAGnlAB7z33nuaMWOGgoODNWDAAN1yyy06efJkd4cFAK2idgHwRNQuAACaopEHtIPdbteiRYv04x//WDk5Obrxxhs1atQobdiwQTNmzFBxcXF3hwgATVC7AHgiahcAAC2jkQe0w0MPPaS1a9fqySef1PHjx/Xee+9p3759uvvuu5WTk6OXXnqpu0MEgCaoXQA8EbULAICWmQzDMLo7CKAn+/zzz3Xttdfqzjvv1OrVqxs9dujQIU2aNElXX321tm/f3k0RAkBT1C4AnojaBW9WWlqqkJAQWa1WBQcHd3c4ALpYV73nmZEHtOGxxx6Tr6+vnn766SaPRUZGSpLOnDnj7rAAoFXULgCeiNoFAEDraOQBrTh+/Li++OIL/fCHP1RUVFSTxysrK7shKgBoHbULgCeidgEA0DZLdwcA9GQffPCBJCkrK0t33nlnk8eLiookSQMGDHBnWADQKmoXAE9E7QIAoG008oBWfPbZZ5KkPXv2aM+ePS2Oi4mJcVNEANA2ahcAT0TtAgCgbSytBVqxf/9+BQYGyjCMZr8WLVokSZoyZUo3RwoA36N2AfBE1C4AANpGIw9oQUlJiQoKCjR48OBmHzcMw/Wb42uvvVaSXPu6REdHy2Qy6YknnnBPsADwHWoXAE9E7QIAoH1o5AEtKC4uliT169ev2cf37Nmj7OxsRUVFadq0aZKk8vJyXXbZZXr22Wc1aNAgt8UKAPWoXQA8EbULAID2YY88oAUmk0mSVFtb2+zjr7/+uiTp7rvvltlc1xO/8cYbdeONN0qSli9f7oYoAaAxahcAT0TtAgCgfZiRB7RgyJAhslgsyszMVE1NTaPHDh8+rHfeeUehoaFaunRpN0UIAE1RuwB4ImoXAADtQyMPaIGvr68SExNVVVWlF1980XU9KytLt956q2w2m1577TUNGDCgG6MEgMaoXQA8EbULAID2oZEHtOLxxx+Xj4+Pli9frpkzZ2r+/PkaP368Tpw4oZdeekm33XZbd4cIAE1QuwB4ImoXAABto5EHtOLqq6/Wxo0blZCQoC+//FLbt2/XnDlztGvXLt1///3dHR4ANIvaBcATUbsAAGgbh10AbZgzZ47mzJnT3WEAQIdQuwB4ImoXAACto5EHdKLy8nJlZGRIqjt1LTc3VwcOHJCfn58uu+yybo4OAJpH7QLgiahdAIDeyGQYhtHdQQDe4rPPPlNiYmKT69HR0Tp9+rT7AwKAdqB2AfBE1C54mtLSUoWEhMhqtSo4OLi7wwHQxbrqPU8jDwAAAACALkYjD+hduuo9z2EXAAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAAAAB4ABp5AAAAAAAAgAegkQcAAAAA6HVWrVqlkSNHKiAgQFOmTNG2bdtaHf/5559rypQpCggI0KhRo/Tqq6+6KVIA+B6NPAAAAABAr7Ju3To99NBDevTRR5WWlqYZM2bohhtuUFZWVrPjMzMzdeONN2rGjBlKS0vTr3/9az344IP64IMP3Bw5gN7OZBiG0d1BAAAAAADgLgkJCZo8ebJeeeUV17Xx48dr/vz5WrlyZZPxy5cvV0pKio4cOeK6tmTJEh08eFC7du1q12uWlpYqJCREVqtVwcHBl54EgB6tq97zlk57JgAAAAAAerja2lrt27dPK1asaHR9zpw52rlzZ7P37Nq1S3PmzGl0be7cuXrjjTdks9nk6+vb5J6amhrV1NS4vrdarZLq/nIPwPvVv9c7e/4cjTwAAAAAQK9RUFAgh8OhgQMHNro+cOBA5ebmNntPbm5us+PtdrsKCgo0ePDgJvesXLlSTz75ZJPrw4YNu4ToAXiawsJChYSEdNrz0cgDAAAAAPQ6JpOp0feGYTS51tb45q7Xe+SRR7Rs2TLX9yUlJYqOjlZWVlan/qW+O5SWlmrYsGE6e/asRy8T9pY8JHLpiaxWq4YPH67Q0NBOfV4aeQAAAACAXiM8PFw+Pj5NZt/l5eU1mXVXb9CgQc2Ot1gsCgsLa/Yef39/+fv7N7keEhLi0c2JhoKDg70iF2/JQyKXnshs7txzZjm1FgAAAADQa/j5+WnKlClKTU1tdD01NVXTp09v9p5p06Y1Gf/JJ5/oyiuvbHZ/PADoKjTyAAAAAAC9yrJly/SnP/1Jb775po4cOaKlS5cqKytLS5YskVS3LHbx4sWu8UuWLNGZM2e0bNkyHTlyRG+++abeeOMN/fKXv+yuFAD0UiytBQAAAAD0KrfffrsKCwv11FNPKScnR3Fxcdq4caOio6MlSTk5OcrKynKNHzlypDZu3KilS5fq5ZdfVlRUlH7/+9/rRz/6Ubtf09/fX48//nizy209jbfk4i15SOTSE3VVHiajs8/BBQAAAAAAANDpWFoLAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAEAnWLVqlUaOHKmAgABNmTJF27Zta3X8559/rilTpiggIECjRo3Sq6++6qZI29aRXD788EPNnj1bERERCg4O1rRp07R582Y3Rtuyjv5M6u3YsUMWi0WXX3551wbYAR3NpaamRo8++qiio6Pl7++v0aNH680333RTtC3raB7vvvuu4uPjFRgYqMGDB+uuu+5SYWGhm6Jt2RdffKF58+YpKipKJpNJGzZsaPOeznjP08gDAAAAAOASrVu3Tg899JAeffRRpaWlacaMGbrhhhuUlZXV7PjMzEzdeOONmjFjhtLS0vTrX/9aDz74oD744AM3R95UR3P54osvNHv2bG3cuFH79u1TYmKi5s2bp7S0NDdH3lhH86hntVq1ePFizZo1y02Rtu1iclmwYIE+/fRTvfHGGzp27JjWrl2rcePGuTHqpjqax/bt27V48WLdfffd+uabb/TXv/5VX331lX7605+6OfKmKioqFB8frz/84Q/tGt9Z73mTYRjGxQQMAAAAAADqJCQkaPLkyXrllVdc18aPH6/58+dr5cqVTcYvX75cKSkpOnLkiOvakiVLdPDgQe3atcstMbeko7k0Z8KECbr99tv12GOPdVWYbbrYPBYuXKgxY8bIx8dHGzZs0IEDB9wQbes6msumTZu0cOFCnTp1SqGhoe4MtVUdzeO3v/2tXnnlFZ08edJ17aWXXtKzzz6rs2fPuiXm9jCZTProo480f/78Fsd01nueGXkAAAAAAFyC2tpa7du3T3PmzGl0fc6cOdq5c2ez9+zatavJ+Llz52rv3r2y2WxdFmtbLiaXCzmdTpWVlXVrA+li81i9erVOnjypxx9/vKtDbLeLySUlJUVXXnmlnn32WQ0ZMkRjx47VL3/5S1VVVbkj5GZdTB7Tp0/XuXPntHHjRhmGofPnz+v999/XTTfd5I6QO1VnvectnR0YAAAAAAC9SUFBgRwOhwYOHNjo+sCBA5Wbm9vsPbm5uc2Ot9vtKigo0ODBg7ss3tZcTC4Xeu6551RRUaEFCxZ0RYjtcjF5nDhxQitWrNC2bdtksfScdsnF5HLq1Clt375dAQEB+uijj1RQUKB7771XRUVF3bZP3sXkMX36dL377ru6/fbbVV1dLbvdrqSkJL300kvuCLlTddZ7nhl5AAAAAAB0ApPJ1Oh7wzCaXGtrfHPXu0NHc6m3du1aPfHEE1q3bp0iIyO7Krx2a28eDodDixYt0pNPPqmxY8e6K7wO6cjPxOl0ymQy6d1339XUqVN144036vnnn9dbb73VrbPypI7lcfjwYT344IN67LHHtG/fPm3atEmZmZlasmSJO0LtdJ3xnu85LWYAAAAAADxQeHi4fHx8mswqysvLazIDp96gQYOaHW+xWBQWFtZlsbblYnKpt27dOt19993661//quuuu64rw2xTR/MoKyvT3r17lZaWpvvvv19SXTPMMAxZLBZ98sknmjlzpltiv9DF/EwGDx6sIUOGKCQkxHVt/PjxMgxD586d05gxY7o05uZcTB4rV67U1VdfrV/96leSpEmTJikoKEgzZszQb37zm26buXoxOus9z4w8AAAAAAAugZ+fn6ZMmaLU1NRG11NTUzV9+vRm75k2bVqT8Z988omuvPJK+fr6dlmsbbmYXKS6mXh33nmn1qxZ0yP2L+toHsHBwTp06JAOHDjg+lqyZIliY2N14MABJSQkuCv0Ji7mZ3L11VcrOztb5eXlrmvHjx+X2WzW0KFDuzTellxMHpWVlTKbG7eufHx8JH0/m81TdNp73gAAAAAAAJfkvffeM3x9fY033njDOHz4sPHQQw8ZQUFBxunTpw3DMIwVK1YYycnJrvGnTp0yAgMDjaVLlxqHDx823njjDcPX19d4//33uysFl47msmbNGsNisRgvv/yykZOT4/oqKSnprhQMw+h4Hhd6/PHHjfj4eDdF27qO5lJWVmYMHTrUuO2224xvvvnG+Pzzz40xY8YYP/3pT7srBcMwOp7H6tWrDYvFYqxatco4efKksX37duPKK680pk6d2l0puJSVlRlpaWlGWlqaIcl4/vnnjbS0NOPMmTOGYXTde56ltQAAAAAAXKLbb79dhYWFeuqpp5STk6O4uDht3LhR0dHRkqScnBxlZWW5xo8cOVIbN27U0qVL9fLLLysqKkq///3v9aMf/ai7UnDpaC6vvfaa7Ha77rvvPt13332u63fccYfeeustd4fv0tE8erKO5tK3b1+lpqbqgQce0JVXXqmwsDAtWLBAv/nNb7orBUkdz+POO+9UWVmZ/vCHP+jhhx9W//79NXPmTD3zzDPdlYLL3r17lZiY6Pp+2bJlkr7//76r3vMmw/CwuYgAAAAAAABAL8QeeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeAAaeQAAAAAAAIAHoJEHAAAAAAAAeID/H8ylKoP23+mRAAAAAElFTkSuQmCC", + "image/png": "iVBORw0KGgoAAAANSUhEUgAABdIAAAF+CAYAAACGZ+ghAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAADzAElEQVR4nOzdd3xUVfr48c+dmfROChBKKIEECIRqpAgERGxEsSIWRHdXFzu6i2XXtvpz2V3ZXXXR1fWLWECxYVh1ESV0CAIhECAhQ0mAhGQS0ntmzu+PMGOGzCQhpEDyvH3xEm6bc6acufe5zzxHU0ophBBCCCGEEEIIIYQQQgjhkK6jGyCEEEIIIYQQQgghhBBCXMwkkC6EEEIIIYQQQgghhBBCNEIC6UIIIYQQQgghhBBCCCFEIySQLoQQQgghhBBCCCGEEEI0QgLpQgghhBBCCCGEEEIIIUQjJJAuhBBCCCGEEEIIIYQQQjRCAulCCCGEEEIIIYQQQgghRCMkkC6EEEIIIYQQQgghhBBCNEIC6UIIIYQQQgghhBBCCCFEIySQLjrE8ePH0TSNfv36dXRTurwPPvgATdO49957z2u/DRs2oGkaU6dObZN2CSG6Fvle6NruvfdeNE3jgw8+aJXj9evXD03TOH78eKscT4j2YDab+X//7/8RERGBq6trg/Os8vJynnrqKfr374+Li4vd+Vtrf4ZEyzg7r+7M33Ey3gpxYZyN3y29Thetq7Hxu7OOf3JO0TgJpItWYR1AGvvzj3/8o6ObecHq9+fNN99sdNsnnnjCtm1rnTQfP36cF198UQY0IQQAW7du5Te/+Q2RkZH4+fnh5uZGr169uP766/nPf/5DWVlZRzex3ck42ZD1QkzTNFxdXcnPz3e6bW1tLSEhIbbtX3zxxfZrqBCd0PDhw9E0DQ8PD4qLixvd9vnnn+e5557j+PHjREVFMXHiRIYPH25b/+tf/5rXX3+d3NxcRo4cycSJExk8eHBbd6FNHD9+nKeffpqxY8cSFBSEq6srQUFBTJ48mVdeeYWTJ092dBO7JGvwpLE/N954Y0c3U4g2l5mZycKFC4mKisLLywsPDw/69u3LhAkT+N3vfsfatWs7uokXnZKSEpYsWcL06dPp2bMnrq6u+Pn5MXLkSB599FH27NnT0U3skupfBzj74+/v39HNvKQYOroBonMZNGgQISEhDtf16tWrnVvTtj766CMeeeQRh+vMZjOffvppqz/m8ePHeemll5gyZUqH35n29PQkIiKCvn37dmg7hOiKysvLmT9/PqtWrQLA3d2dgQMH4uHhwalTp/j222/59ttvef7551m7dq1dIOZi5eLiQkRExAV/V1xM4+TFqKamhs8++4wFCxY4XL927VpMJlM7t0qIzmnv3r2kpKQAUFlZyRdffMF9993ncFulFO+88w6aprF161bGjh1rt76goIBPP/0UT09PUlNT6dOnj936nj17EhERgZ+fX9t0phW99tprvPjii1RXV6PT6Rg4cCADBw4kPz+fLVu2sHnzZl599VXee+897rrrro5ubqtore+49hISEsKgQYMcrhs6dGg7t0aI9rV+/XpuvPFGSkpK0Ov19OnTh5CQEM6cOcOOHTvYvn07y5YtIy8vr03b4efnR0REBD179mzTx2kN33//Pffcc4/tOenVqxfR0dGUlZWRlpZGcnIyb775Jg899BBvvfVWB7e29QwcOBB3d3dcXFw6uilNcnNza3BuYeXj49POrbm0SSBdtKpnn322SwQuIiIi+Pnnn0lLSyMiIqLB+nXr1nH69GkiIiJIS0vrgBa2vcsuu4zU1NSOboYQXU5NTQ1XXXUVW7dupUePHixevJhbb70VDw8P2zYHDx7kjTfe4P333+fIkSOXRCC9V69eMqa0sUGDBmE0Gvnoo4+cBtI/+ugjgE79/SVEe7F+nvz9/SksLOSjjz5yGkg3mUycOXOGkJAQhxe66enpWCwWoqKiGgTRoS44/dprr7VuB9rAokWL+Mtf/oKLiwsvvPACDz/8MEFBQbb1p0+fZvny5SxevJhdu3Z1mkD6pfYdd80118gvu0SXVFxczO23305JSQnXXXcd//rXvwgLC7OtLyws5JtvvrEls7Sl2bNnM3v27DZ/nAu1Zs0aZs+ejdlsZs6cObz44ot2MZKysjK++eYbXn75ZbZs2dKBLW19P/30U0c3odl69OjR6Z7/jiKlXYRoAetJ/ccff+xwvXX53Xff3W5tEkJ0DS+99BJbt26le/fubN++nXvuuccuiA512WLvvPMOCQkJTn8lJLqevn37MnnyZHbs2IHRaGywvqSkhPj4ePr378/EiRM7oIVCdB5ms5mVK1cC8NZbb6HX69m4cSOZmZkOt6+oqABoMJ43d/2lYN26dfzlL39Bp9Px9ddf8+KLL9oF0aHuQn/RokXs37+fcePGdVBLhRBd1XfffUdeXh6+vr6sWrXKLogOdTdG582bx7fffttBLby45ObmMm/ePMxmM7///e9ZuXJlg0RDLy8v5s6dS3JyMvPnz++glgrReiSQLi5K+fn5/P73vyciIgIPDw8CAgKYOnUqn3zyCUopu22//vprNE3jpptuanCcBx98EE3TcHNzs12AWF3IZJk333wzHh4efPzxxw3aU1ZWxurVq20BC2dSUlJ44YUXGD9+vK2GWM+ePbnpppvYtm1bg+2nTp1KbGwsABs3brSraeWoBvvPP//MXXfdRd++fXFzc6N79+5MmDCBv/zlLxQVFTlsU1VVFS+++CLh4eG4u7vTp08fFi5c6LDOsrPn79zJOD7++GPGjh2Lp6cn3bp149Zbb+Xo0aNOn5ekpCRmzZpFQEAA3t7eXH755XzxxRfALzXqheiqioqKeOONNwD4xz/+0eT8C5MmTWLChAkNln/77bdcffXVBAUF4ebmRv/+/VmwYAEnTpxweJz6E+ns2LGDa665hoCAALy8vLjiiitYv369w/3y8/N56qmniIyMxN3dHS8vL/r168fVV1/N0qVL7bZtbCKfjIwMHnjgAQYMGICbmxs+Pj4MGDCA2bNn25XROt9xcufOncyZM4devXrh6upK9+7dufXWW0lKSnLYn/pj0Pfff8/kyZPx8fHBz8+Pa665xul+UFd7/L333iM2NpbAwEDc3d0ZMGAAN998M9988w1QF3jr3bs3mqaxe/dup8d6+OGH0TSN3/3ud063caaxG8FffPEFFRUV3HnnnU2Otdu2beOmm26ie/fuuLq60rt3b+655x4OHTrkdJ+ysjKeeeYZ+vfvj7u7O/369ePJJ5+ktLS0yXaf72slREf78ccfyc7OpkePHsyZM4dp06ahlOKTTz5psG39MSojI8Nu7LLWNrWeb507tlknOHM2MdiLL75om++gqKiIxx9/3HZuGB4ezp/+9Cdqa2ud9iM1NZX77ruPfv364ebmRmBgINddd53Tcb8xf/rTn4C6Wu/XXXddo9v26tWLO++8s8HyAwcOcPfdd9O7d2/bWHDzzTezY8cOh8eZOnUqmqaxYcMGh+udPW/1lx8+fJjbb7+dkJAQPDw8GDVqFP/3f//XdIfraew77kK+W44cOcIdd9xBcHAwnp6ejBw5knfeeQe4OCbBq6mp4c033+Syyy7D19cXLy8voqOjefXVVykvL7fb9syZM+h0OgIDAxtcX3366ae25+ncDNCqqirc3d1xd3enqqqqzfskOjfrdergwYPx9PQ8r33rf+bWrl3L1KlT8fPzw9fXlxkzZrB58+bzOp6zyUbrX4dbLBb++c9/EhUVhbu7O927d+f+++9vtEzfmTNneO6552z13318fLj88st57733sFgs59XGt956i4KCAoYNG8arr77a6LZubm489thjDZafT+wH7L/XHHH2vNVfXlJSwsKFC+nXr5/tnPy5555rMC41xdk4W/+7JzU1lVtvvZWgoCA8PDwYM2ZMo79oKCkp4fe//72tbf3792fRokWUlZVdNJOAns+1ZHR0NJqmsW/fPrvlOTk5tnH9j3/8Y4P9mvr+7lBKiFYQFhamALVs2bJmbX/s2DEFqLCwsAbr0tPTVZ8+fRSgXF1d1ejRo9WAAQMUoAB1zz33KIvFYts+Ly9PaZqmAgMD7ZYrpdSQIUNs+/30009261566SUFqOeff77Z/bQe68SJE2rOnDkKUJs3b7bb5sMPP1SAeuaZZ9TmzZud9nP69OkKUP7+/mrIkCFq9OjRKigoSAFKr9erTz75xG77hx9+WEVFRSlA+fr6qokTJ9r+3HLLLXbbLl68WGmaZtt2zJgxauDAgcrFxUUBKiEhwbbtsmXLFKDmzp2rJk+erDRNU8OGDVMRERFKp9MpQM2YMaNB+xMSEhSgpkyZYre8/mv79NNP2/4eHR2t3NzcFKB69uypTCZTg2OuW7fOto2vr68aO3as6tmzpwLUkiVLbM+/EF3VJ598ogAVHBysampqWnQM6+cSUL1791ZjxoxRnp6eClABAQHq559/brCPdYx/8803lYuLiwoMDFRjxoxRfn5+ClAGg8FuXFFKqcLCQjVw4EDbWD506FA1evRoFRISojRNU35+fnbbO/teOHbsmG1s9PT0VMOHD1cjR45U3bp1U4CKjo62bXs+4+SSJUts42S3bt3UqFGjVGBgoAKUi4uL+vLLLxs8D9bn7e2331aapqmePXuq0aNHKy8vLwUob29vdejQoQb7nTlzRk2cONG2f1hYmBo7dqwKCQlp0OdnnnlGAeqRRx5x+PpVVVXZ2pmSkuJwm3NZx/np06erwsJC5e7ursLDwxtsN23aNAWo1NRUdf/99ytAvfDCCw22W7p0qe25CwkJUWPHjlX+/v4KUO7u7uq///1vg31KS0vVZZddpgClaZqKiopSQ4cOVZqmqdGjR9u+Ux2dR7TktbK+Z48dO9as50iI1jZ37lwFqMcee0wppdQHH3ygADVkyJAG206cOFGNHTtWAcrNzc1u7Nq2bZuaOHGi07EtOztbKaXUvHnzHH6GXnjhBQWoxx9/XA0ZMkQZDAY1cuRI1a9fP9uY9Ktf/cphHz777DPl6uqqAOXj46NGjhypevToYfscv/HGG81+Pk6dOmV7vOTk5GbvV98333xjO0/09/dXY8eOVcHBwQpQOp1Ovfvuuw32mTJlSoNz3/qcPW/W5c8++6zy8/NTbm5uavTo0baxxdk4bR1v582bZ7e8sWufln63JCcn28ZeDw8PNWbMGFv7Hn300RaNg9Z+n9v+xjh7nPLyctv3ivW9P2LECNv1xciRI1VeXp7dPtb3+b59++yW//a3v7Ud549//KPduo0bNypATZ48udltFsKZN998UwHKz89PFRQUnNe+1s/Ca6+9pjRNU926dVNjx461nbPodDq1atWqBvs5G4ecjSf1r8Ot3zWDBg1Sw4YNUwaDQQFq2LBhqrKyssFjpaSkqF69etmdnw8cONB2nnXLLbc0iKk0ZtCgQQpQ//znP5u9T33nG/tR6pfvNUfnqEo5f96sy+fMmaNGjRpli3tERUXZ+n/55ZersrIyu/0aG7+djX/W756//e1vytvbW/n4+KgxY8bYvrMA9dFHHzU4XlFRkRo1apTt/TJ8+HA1bNgwpWmaGjdunLrjjjvOK+5Wv9+O2u+Ms/ekUud/Lfnwww8roME5w2effWY7zhVXXGG3rrKyUrm7uys3NzdVUVHR7Ha3F4lIiVbRWoF0i8Viu5CYMmWKOn36tG3d999/bzuhXLp0qd1+w4YNU4Dav3+/bVlubq4CbF8U5wbMrSd25wbYG1M/kP7tt98qQP3mN7+x22bGjBkKUAcOHGg0kP755583OEm0WCxq9erVytvbW/n6+qri4mK79c6C1/WtXr3aFox//fXXVXV1tW1dWVmZevfdd9XBgwdty6wDq4uLixo6dKhKS0uzrdu+fbvy9fVVgPr++++b1Rbra2swGJSvr6/67rvvbOuys7PViBEjFKAWLVpkt19xcbHt4mz+/PmqvLzc9py89dZbtgsnCaSLruyhhx5SgLrxxhtbtP+aNWtsn8+PP/7YtryoqEjNnj1bAapfv362z5+VdYx3cXFRr732mqqtrVVKKVVdXa3uvPNOBaiYmBi7ff72t78pQF111VUqPz/fbl1GRob6+9//brfM2feC9eRr3rx5qqSkxG7doUOH1L///W+7Zc0ZJ7///nulaZoKCgpqEIT9z3/+owwGg/Lx8VFZWVl266xjkKenp933XXFxse3m6O23397g8W688UYFqIEDB6odO3bYrUtPT1d/+ctf7P4NqKCgILvx2+rLL79UgBo7dqzT/p2rfiBdKaVuvfVWBaht27bZtjlx4oTS6XTqsssuU0opp4H0pKQk20XaX/7yF2U2m5VSdSe8CxYssF18nvvcPfHEE7bXt/4NgL1796pevXrZbvSeex7R0tdKAumiI5WUlNguKnfu3KmUqhsnPDw8FKB27drVYJ/GLtSVanpsayqQ7uLioiZPnqxOnTplWxcfH6/0er0CGgRqk5OTlZubm3J3d1fvvvuu7bNu3c/X11fp9Xq1d+/eZjwjdee91ovsljh16pTtnPSxxx5TVVVVSimlzGazevXVV219PDdIf6GBdIPBoGJjY1Vubq5dX6xj1rk3Di8kkH4+3y1ms1kNHz5cAeqaa65RZ86csa374osvlJubm62NHRVIf/LJJxWgQkND1e7du23L09PTVWRkpALUbbfdZreP9TznzTfftFs+dOhQ1a1bN+Xu7t4gYP7yyy87DLAL0RJpaWm2mz1jxoxRX3zxhSosLGzWvtbPgsFgUAsXLrSdx9XU1Kjf//73Cupuhp57ztLSQLqLi4sKDQ1ViYmJdu3v3bu37eZcfaWlpbYkl0cffVQVFRXZ1h04cMAWU3nrrbea1V+TyWQbv5r7XVBfS2M/FxpINxgMqlevXnZt3r9/vy2g/9RTT9ntdyGBdBcXF/Xwww/bgsEWi0UtWrTINjZar6msrGPggAED7GI2KSkpKiwszOn5cmNaM5DekmtJ6/f/zTffbHcs63VDr169GgTMN23a5DDAfrGQiJRoFfWzMxz9aSxrub5169YpqMvGsWbY1PeXv/zFtl/9O5PWLIX6g771A7t48WLl5uZm14bq6mrl6empXF1dGwSMGlM/kF5TU6NCQkKUv7+/7W5vVlaW0uv1avTo0Uop1WggvTF/+MMfFNAgK705AaKhQ4cqQL388svNeizrwKppmsNM1IULF9q+bJvTFutrC6jXX3+9wfHi4+MVoEaMGGG3/J133lGAioyMdJhpax3MJZAuujJrQPaJJ55o0f7WrGhrhmR9ZWVltszv999/326ddYyfNWtWg/1MJpPtRlf9C/kHHnhAAeqbb75pVtucfS/MnDlTQfMzGJszTo4ePbrRtlkv/s8dR61jkKMsxH379tmCyPXt3LnT9r12+PDhZvXhiiuuUID6+uuvG6yLi4s7r4scpRoG0r/55hsFqN/+9re2bf785z8r+CVbxFkg3Xrj5IYbbmjwOBaLxXYRVj+gUVxcbAsqfvvttw32++qrr2zP7bkn7C19rSSQLjqSNfv83F9+WG9iORqD2zqQ7uHhoU6cONFgv5tuuklB3S//HC13lmVozdq87777HK4/1z/+8Q8FqFGjRjVr+3M999xzCuqymB259tprFaDuvvtuu+UXGkh3dk1iPT8+N6h7IYH08/lu+d///qcAFRgY6DDIZ33dWxpIb+zPuRyNt0VFRbZx39F3mfW7UdM0ZTQabcutGYr1f0VmMpmUpmlq9uzZasqUKQ0CLtabDT/++GOz+ylEY6w356x/NE1TERER6t5771Wffvqpw0xvpX75LNT/tWR91nOacxP8WhpIBxz+Ku+NN95QgIqLi3O4fPbs2Q7bl5ycrDRNUwMGDHC4/lx79+61taN+UL65Whr7udBAOqC++uqrBvtZ4xReXl52CY0XEkiPjo62uxGtVF0syppAuGfPHtty669GAbVly5YGj1X/dW9JIL2xP+d+Rzp7T7bkWjInJ0dB3S+q6xs2bJjq1q2bev755xu04U9/+pMC1B/+8Idm97M9SY100aoGDRrExIkTG/wZPnx4s/b/4YcfALj11lvp0aNHg/UPPvggbm5uZGRkkJaWZls+ZcoUADZt2mRbZv37zJkziYmJYceOHba6eT///DPl5eWMHTu2xZM2GQwG5syZQ2FhoW2ykRUrVmA2m5s9yWhmZiZ//vOfue2225g2bRqTJk1i0qRJfPbZZwAkJyefV5uMRiMHDx7E1dWVxx9//Lz2HTlyJGPHjm2w3DrRU2N1zZ25//77m328devWAXUTtBoMhgb7ycQkQtTVzIO6SXvOV2lpKdu3bwfgkUceabDe09OTX//618AvY/G5fvWrXzVYFhQUZKv5Wv9z3adPH6BuHovG6u82xXqcL774wmGdxPOVkZHBnj17CAkJIS4uzuE21uUbN250uN7R8zB8+HDc3d0pKioiPz/fttxa/3z27NkMGjSoWW287777AFi+fLndcpPJxPfff4+rqyt33HFHs47lyDXXXENQUBCrVq2ipqYGqKuZbv1ea4z1veHoPaRpGo8++qjddgCbN2+mvLycsLAwrrnmmgb73XDDDfTq1avB8tZ4rYToCB999BEAc+fOtVturfm9cuXKCxoXW+Lqq6+md+/eDZY7Oi+rrq7mu+++Q6/XN6gxa3W+n70L+f6CX8aUhx9+2OF6a91dZ99fLXXTTTc5vCZZsGABAFu3bnU4l1BLnM93i/W8+aabbsLPz6/Bfhd63hwSEuLwmq65E1Fv2bKF8vJy+vbtyw033NBg/bhx4xg/fjxKKVtfwPk1nVKKKVOmMGXKFKqqqkhMTATqarBv374dFxcXxo8ffyFdFsLm2WefZf369Vx77bW4urqilCItLY0PPviAOXPmMHjw4EbrNlvHB2fL165d2yrtDAgIcDhPnLPr7a+++gpwPNYAjBgxgn79+nH06FFOnjzZ5ONbx3Vo2dje0tjPherVq5fDcen666+nb9++lJWVsXXr1lZ5rPvuuw+dzj7s6uLiQnR0NGD/Gm3evJnKykpbTO1cU6dOpX///i1ui5ubm9Nx3dH3yLlaei0ZEhJCZGQkJpPJNpdSfn4+Bw8eZPLkyXZzwFhZvwMam3OwIzWMVglxAZ599lmnJ9zNcfjwYQCGDh3qcL2Pjw99+vTBaDRy+PBhIiMjgV8+YPU/fBs3biQgIIDhw4czZcoUNm3aRGJiIpMnT7ZtZz1Za6m77rqLN954g48++oibbrqJjz76CL1e36wAx/Lly3nwwQeprKx0us2ZM2fOqz3WgWno0KH4+Pic174DBw50uDwkJASgWZPB1RcUFORwQHZ2vPT0dKDuC9wRZ8uF6Eqsn+uWXLQbjUYsFgtubm4MGDDA4TbDhg0DfhmLz9XYOJGWlmb3uZ4/fz5//etf+eCDD/j++++5+uqrueKKK4iNjXX6+I489NBDLF++nD/96U98+OGHdscJDQ1t9nGs9u/fD0BlZSWTJk1yuI11XD516pTD9c6eh+DgYE6cOEFpaSmBgYHAL+Py5Zdf3uw23nrrrTz66KN8++235OXlERQUBNTdrK2pqeGWW26hW7duzT7euVxcXLjttttYunQp3333HWFhYaSkpHDdddcRHBzsdL/CwkLb5FXOvqcdvYesf4+MjHQ4ialOp2Pw4MENnu/WeK2EaG+nTp0iISEBaBhIt07UnJubyw8//MC1117bbu06n/O8w4cPU1lZiaurq9M2Wm9sNvezdyHfX9Y2QdNjT05ODsXFxfj6+rbocc41ZMgQh8utk19XVVVx5MiRVjlPPZ/vlqbOm8PCwvD19aW4uLhFbbnmmmsuaDK7psZ9qHvNtm/fbvd90b17dwYPHszhw4dJTU0lMjLS7rrNem20ceNGpkyZwq5duygvL2f8+PHnPTGkEI2JjY0lNjaWiooKdu3aRWJiIt999x0bNmwgMzOTa6+9lj179tjiEfU5Gzesy52dZ5+v871+t55XPf/88/y///f/HO6bl5cH1I3tjm6+1lc/3lBWVnbe425LYz8XKiIiokFwG+oSQiIiIsjMzOTw4cNcffXVF/xY5/MaNTWuQ93N1WPHjrWoLT169GDLli0t2hcu7Fpy8uTJpKamsnHjRoYMGWJ3g/Tyyy/H1dXVNtbX1taybds2DAYDEyZMaHF725JkpIuLinUgsQ4sjnTv3h2wvwPas2dPBg0aRE5ODmlpaRQUFLB//36uuOIKdDpdg0B7awXSx40bR2RkJN999x2bNm0iOTmZGTNm2NrozJEjR/j1r39NZWUlTz75JElJSRQXF2OxWFBK8d577wHYMgWby3qy7O/vf959cXYX2folc76ZoE0d71zWCytnNwDO98aAEJ2RNWu3JSdQ1vE1ODjY6UWto/G1vvMZJ0JDQ9m+fTs333wzRUVFLF++nF/96lcMHDiQ8ePH2zIamjJy5Eg2bdrEVVddxalTp/j3v//NXXfdRe/evZk5c6YtUN1cRUVFQN14uXXrVod/du/eDUBFRYXDY5zP89CScdnLy4vbbruNmpoaVq5caVtuzVC/kBvWVtZfTn388cd8/PHHdsucqX+y7+x72tF7qP57zxlH35ut8VoJ0d4++eQTLBYLo0ePJiIiwm6dq6srt956K/BL1np7OZ9xy/rZq66udvrZ27ZtG0CjCSH1Wb+/jh8/3qL2N3WNUH8McfYd1hLOHk/TNNuY1lqPdz6vUVPnzU2ta2stvaaDX67P6l+3+fv7M2LECMaPH4+Li0urX9MJ4YyHhwdXXHEFTz31FOvXr2fTpk14eXlRUVHB66+/7nCf8zlHuhDne/1uHdt3797tdGy3tq0551X1f014IdcmLRknLkR7Pl5nHNdbci3paFy3Lvfw8GDcuHHs2LGD6upqdu3aRVlZGWPHjm3xr9jamgTSxUXF29sbgNzcXKfb5OTkAA0HkfrB8vp3uAAmTJhgO+kym822O1zN/XliY+666y6qq6ttAYjmlHWx/px+zpw5/O1vf2PkyJH4+PjYBqQTJ060qC3W56SwsLBF+3ck6yDpLPO9Nb88hbhUWe/Kb9u27bzLAljHV5PJ5PTGmLPxtaWGDBnCF198QWFhIQkJCbz44otERkayY8cOrrrqqmYHVC6//HLWrl1LQUEB//vf/1i0aBG9e/fmhx9+YMaMGec15lmfh4kTJ6Lq5opx+qelAZ/6Wjoun1veZf/+/SQlJdGjR49WyZC5/PLLGTRoEGvWrOHjjz/G19fXafkUK+tzB86/px29h+q/95xxdLz2fq2EaA3WAPmePXvQNK3Bn3fffReoK/vU0mzhtmb97PXq1avJz15zEy2s318FBQXs27evxW1qauwB+/HHem7trJ1NZcg7G7eUUrZ1HRHYaOq8GTr23Lm1rukKCwvtkqOsAZft27dTXV0tgXTR7iZNmmQr0bJz506H2zgbN6yfh44Khlo/l+np6U2O69ZyG40JCgqylS1sSYm9lo4TbTWu12+LjOsNXci1pKNAup+fn63EzZQpU6ioqGDnzp2XxLgugXRxURk8eDAABw8edLi+pKTEFmS2bmtVv6aetaaSdZmnpydjx45l+/bt7Nixg5KSEkaNGmUXFGipu+66C03TyMzMxNvbmxtvvLHJfawX/M5+quKsNrqzO39W1p/SHDx48JILPFtfT2cXV9afognRlV177bV4e3uTm5vLF198cV77hoeHo9PpqKqqcjrnwYEDB4CG4+uFcnNzY+rUqbzwwgukpKQwceJESktL7bKtm8Pb25uZM2fy5z//mdTUVAYOHMipU6f4/vvvbds0NU5afz566NAhLBbL+XfmPFnH5R07dpzXfhMmTCAyMpLdu3eTkpJi+4n9XXfdhV6vb5W23XnnnVRVVZGTk8PNN9/c5Jwh/v7+tgxMZ9/Tjt5D1r+npaU5PPG2WCwOa1+292slxIVKSkoiJSUFTdPo3r270z+urq5UVFTw5ZdfdnSTHRo0aBAuLi5kZ2efd5lBZ0JDQ20lmpYuXXre+zd1jWAde7p3725XXsAamHAWODEajY0+rrNfPR07doyqqip0Op3Tn+63pabOmzMzMzv0Ro21fYcOHXIacHF2zlH/mm7z5s1YLBa7gIo14LJ9+3a2bduGXq9vleQoIZrLWtaiurra4Xpn44Z1eWufZzeX9bwqJSWl1Y55++23A/Duu+9iNpvPa9+Wxn4udFxPS0tzeF5prYV/7uO1l6bGdejYmMiFXEv26tWLAQMGkJ2dza5du9i3b5/tBin8Mu5v2LDhoq+PDhJIFxeZmTNnAvD5559z+vTpBuv//e9/U1VVRVhYWIOfy9a/y7Vx40Z8fX0ZOXKkbf3kyZMpLy/nr3/9q932FyosLIwHHniA6dOn89RTTzWrPp81WFE/e8YqNTWVNWvWNLqfs59aDRw4kKioKKqrq3njjTea24WLwowZM4C6MgOOvoQvpE6jEJ2Fv7+/bXKXxx9/vMks3Po/v/f29rbdvHvzzTcbbFtRUcF//vMf4JexuC3o9XrbJEhZWVktPo6np6dtIuv6x2lqnBw0aBBRUVGcOXOGDz/8sMWP31zWm6urV6/myJEj57WvdbK4999/n08++QRonbIuVnfffTfTp09n+vTptsmBmmJ9bzh6DymlbMvrv4cmTZqEp6cnx48fdzjBVnx8vMM6y+39WglxoazZ6JMnT+b06dNO/zz55JN2219sPD09mTlzJhaLpVXPJ//whz8A8N577/Hdd981um1WVpZt3INfxpS33nrL4fbWdp77/WUNeP38888N9tm1a5fT5BWrL7/80uH5uvVmwMSJEzvkp+fW8+avvvrKYfJMR583W8f9EydO2Cbdrm/Xrl1s374dTdNsfbHq06cP/fr149SpU7z//vuA/XWbNbjy97//neLiYkaNGiUlIEWrycvLa/KXNtZza2eTyDu7WWhdftVVV11AC1vOOjHpG2+8cd5lW515+OGH8ff358CBAzz33HONbltVVWX3ndLS2E9j43pZWRmffvppo+04efKkw3jLt99+S0ZGBl5eXh1yc27SpEm4u7tz+PBhhyUwN23a1OL66K3hQq8lrWP3K6+80uAG6YQJEzAYDKxfv54tW7ag1+udzo90MZBAurioTJs2jXHjxlFVVcUdd9xh9zOfH374gZdeegmAp59+ukHWYd++fQkLC+PkyZPs2bOHSZMm2WXtWT+o8fHxdv9uDW+//TY//vgjL7zwQrO2r5+Rs3fvXtvyw4cPc+utt+Lq6upwP+sszQcPHnR6B/aVV14B4MUXX+SNN96wq7NeXl7Of/7zn/OuKdwe7rjjDnr06MHBgwftJmFVSvH222+zYsWKDm6hEBeHF198kfHjx5OTk8P48eP56KOPGtSoPXz4MA899BBTp061G0cXLVoE1I099T9TJSUl3HPPPZhMJvr168ecOXMuuJ3PPfcc77//foOSJikpKaxatQqA0aNHN3mc3/72t3z22WeUl5fbLd+0aRM//fRTg+M0Z5xcvHgxmqbx0EMP8Z///KdBmZyjR4/y6quv8tVXXzXZvqaMGTOG2bNnU1lZyTXXXNPgpN9oNPK3v/3N4b733HMPBoOBt956i5ycHMaOHWvLcG8NAwYM4Mcff+THH39k/PjxzdrnySefxGAw8M033/D666/bMnqqq6t57LHHSElJwc/Pj9/+9re2fXx9fW2B+gULFth9B+3bt49HH30UFxcXh4/Xnq+VEBfCbDbbfmXTVJm/u+66C6jLvGppOb+29qc//Qk3NzdeeeUV/vznPze4OZmdnc0///lP3nnnnWYfc+bMmSxcuBCLxcLs2bN56aWXbBPbWZlMJl5//XWGDx9uN17+9re/xdfXl7179/LEE0/YMkEtFgt/+ctf+Pbbb3FxcbHdpLC65pprgLrgff0yDOnp6cybNw+DwdBom81mM3feeaddO7/++mtbEOF3v/tds/vfmq688kpGjBhBXl4ec+fOtfuuXb16Na+99prTcbU9+Pr62r4HHn74YZKSkmzrjhw5wrx58wC47bbbHGb0179u8/HxYdSoUbZ1EydORK/Xt8k1nRAff/wxI0eO5L333iM/P99uXWFhIc8//7xtbhlrwsO5UlJS+P3vf2+7Dq+treXZZ59l9+7d+Pj48OCDD7ZtJ5x44IEHGDBgAAkJCdx5551kZ2fbrS8tLWXVqlUsXLiw2cfs3r07y5YtQ6/Xs3jxYubOndvgV4YVFRWsWrWKUaNG8X//93+25S2N/cTGxuLu7s6uXbts5dKg7vW59957G7xu5zIYDDzyyCN22d0HDx7k4YcfBuDBBx/skJtzfn5+3H///UDdeUT95/HgwYPMmzevQ8d1uLBrycbicd7e3owePZoNGzZQXFzMyJEjW23S8DahhGgFYWFhClDLli1r1vbHjh1TgAoLC2uwLj09XfXu3VsBys3NTY0ePVqFh4crQAHq7rvvVhaLxeFx7777btt2ixcvtltXXFys9Hq9ApROp1MFBQXn2UtlO/aJEyeatf3mzZsd9rOmpkZdfvnlClB6vV4NGTJERUVFKU3TVM+ePdUrr7yiADVv3rwGx5w2bZoClI+Pj4qJiVFTpkxRt99+u902r732mtI0TQHKz89PjR07Vg0aNEi5uLgoQCUkJNi2XbZsmdPHUkqphIQEBagpU6Y0a3ljr62V9Xk817p165Srq6ut3ePGjVOhoaEKUK+//rrttROiqyspKVE333yz7bPk4eGhoqKi1Lhx41SvXr1sy3v37q32799vt+/TTz9tW9+nTx81duxY5eXlpQAVEBCgdu7c2eDxrGP8sWPHHLZnypQpDcaWG264wfaZDQ8PV5dddpndWB4bG6tqamps2zsbO6KjoxWgDAaDGjJkiLrsssts7QHUXXfd1aA9zRkn33rrLdt3go+PjxozZowaO3as6t69u+3Yb7/9tt0+zsaupp6nM2fOqPHjx9v279evn91jNTZezpo1y7bfW2+95XS7xljH+enTpzd7n/vvv18B6oUXXmiwbunSpbbvmO7du6tx48Ypf39/2/f2f//73wb7lJSUqDFjxihAaZqmhg8fbvveGz16tJozZ47T84iWvFZNvWeFaG3ff/+9ApS7u7sqLCxscvtRo0YpQL322mtKqabPn5ydd1nNmzfP4WfohRdecPpZVqrx88CvvvpKeXp62vo1cuRIddlll6k+ffrYPnuLFi1qsq/nevnll23npDqdTg0ePNj2HaHT6RSgPD091SeffGK33zfffGM7TwwICFDjxo1TISEhtuP8+9//bvBYFotFXXnllbZtIiIiVFRUlNLpdGry5Mlq7ty5Dp836/P5zDPPKD8/P+Xu7q7GjBmj+vXrZ+v7ggULmv18Nvb6tvS7JTk52Tb2enp6qrFjx9ra98gjj9j2y8zMdHrsc1n77ey64HzaV15ermJjY239Gzp0qIqOjraN59HR0SovL8/hMd9//33bftdcc02D9ePGjbOtj4+Pb3ZbhWjKP/7xD9t7C1D9+/dXl112mRo0aJBt/AHUU0891WBf62fBei0eGBioxo0bp4KCgmxj0MqVKxvs52z8djaeNPV90Nh4c+jQIdW/f39be4YMGaJiYmLU4MGDbZ/NmJiY5j5dNmvWrFGBgYF21xjjxo1TQ4cOVe7u7rbzv0cffdRuv5bGfv70pz/ZtunVq5caM2aM8vDwUN27d1cvvviiw+fN+nzOmTNHjRo1SmmapqKiotTw4cNt57Xjxo1TpaWlzX4+nY1/jq6N6nP2mhcVFamRI0faXp8RI0bY2jd27Fjb+fKHH37o8LiOWPvd2PVGc9unVMuuJZVS6siRI7b9fHx8VG1trd363/3ud7b1CxcubHZbO4JkpIuLTnh4OElJSTz11FP07duXAwcOkJuby+TJk/noo49Yvny50xq459bPq69+NsOIESPw9/dvsz40xWAwsHbtWh555BG6d++O0WiksLCQ+++/n927d9vNgH2uFStWcO+99+Lr68vu3bvZuHFjg9q7Tz/9NNu2beO2227D09OT5ORkiouLGTduHH/961+blQXaEa688kq2b9/OddddB9Tdee3VqxcrV67kgQceADp2pmohLhbe3t588cUXbNq0ifvvv58+ffpw/PhxkpOTUUpx3XXX8f7773P48GGioqLs9n3ttddYs2YNM2bMoLS0lH379hEUFMSDDz5IcnKyrezKhfrDH/7A008/zbhx4ygtLWXv3r1UVFQwZcoUPvzwQ3744YcmMwGh7qfbjz32mC3zzvornpkzZxIfH++w5EdzxsmHHnqIvXv38qtf/Yrg4GAOHDhAeno6QUFB3HHHHXz++efcc889rfJcBAQEsHHjRv71r38xceJECgoKSElJwdPTk1tuucVpqQL4JdvJ1dWVO+64o1Xac6F++9vfsnnzZm688UYsFgt79+7F09OTu+66iz179tjG8Pq8vb3ZsGEDixYtom/fvqSlpVFSUsITTzzBxo0bcXNzc/p47flaCdFS1jIts2bNws/Pr8ntrVnpF2t5F4DZs2dz8OBBHnvsMfr160daWhoHDx7E09OT2bNns3z5cp5++unzPu4f//hH0tLS+P3vf8/IkSPJy8tjz549FBQUMHHiRF599VWMRiNz58612y8uLo7du3dz55134u7uzt69e1FKMXv2bLZs2cJvfvObBo+laRpff/01CxcuJDQ0lGPHjlFWVsYzzzzDDz/80GR23+DBg9m5cyez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3e4iVxoV0mVUXe7Gnb27w32+IX5aH4JGtYiITD7Fr7zCgW3nN0fSGBcRkZDg7wofqoux93l+wWaii4iIiIQ6FdJlVE2GbnCNahERmXxy7r4bgwsbi4qISPjSWBYREREJRyqky6iazN3gl9stLyIily716qvViS4iIiIiIiIhyzLRC5Dw4u8Gn4yFan+3vKOgeKKXIiIiIiIiIiIiIiFEHelyxZjM3fIiIiIiIiIiIiIyeamQLlcMzU4XERERERERERGRS6HRLiIiIiIiIiIiIiIiQ1AhXURERERERERERERkCCqki4iIiIiIiIiIiIgMQYV0EREREREREREREZEhqJAuIiIiIiIiIiIiIjIEFdJFRERERERERERERIagQrqIiIiIiIiIiIiIyBBUSBcRERERERERERERGYIK6SIiIiIiIiIiIiIiQ1AhXURERERERERERERkCCqki4iIiIiIiIiIiIgMQYV0EREREREREREREZEhqJAuIiIiIiIiIiIiIjIEFdJFRERERERERERERIagQrqIiIiIiIiIiIiIyBDCrpDe0NDA2rVrSUpKIikpibVr19LY2Djs67/yla9gGAZPPfXUmK1RRESGplwuIhL6lMtFREKfcrmIyAVhV0hfs2YNhw4d4vXXX+f111/n0KFDrF27dljXvvzyyxQWFpKRkTHGqxQRkaEol4uIhD7lchGR0KdcLiJygW2iFzCajh07xuuvv857771HXl4eAL/4xS+46aabOH78OFlZWYNee/bsWb72ta/xxhtv8OlPf3q8liwiIv0ol4uIhD7lchGR0KdcLiLSV1gV0vfu3UtSUlIgwQPceOONJCUlsWfPnkGTvM/nY+3atfzd3/0dixYtGtZzdXV10dXVFfi4ubk5cC+fz3cZUQyPz+fDNM1xea6JEu4xhnt8oBjHisUSdm8m6kO5PLwoxtAX7vHBxMUYzvlcuTy8KMbwEO4xKpePvispl/ufS98joU0xhofJXGcJq0J6VVUVaWlpA46npaVRVVU16HUbN27EZrPx9a9/fdjP9YMf/IDvfe97A467XC46OzuHfZ9L5fP5aGpqwjTNsP2LO9xjDPf4QDGOlWnTpo3L80wU5fLwohhDX7jHBxMXYzjnc+Xy8KIYw0O4x6hcPvqupFwO+h4JB4oxPEzmOktIFNK/+93vBk2ovb3//vsAGIYx4DHTNIMeB9i/fz8/+tGPOHDgwKDnBPPNb36TDRs2BD5ubm5m1qxZ2O12EhMTh32fS+Xz+TAMA7vdHtbfOOEcY7jHB4pR+lIuH+hK+PpRjKEv3OODKyPG0aJcPtCV8PWjGMNDuMcY7vGNJuXy4ML9ayjc4wPFGC4mc4whUUj/2te+xv333z/kOVdddRWHDx+murp6wGMul4v09PSg17377rvU1NQwe/bswDGv18s3vvENnnrqKU6dOhX0uqioKKKiogYct1gs4/ZJNgxjXJ9vIoR7jOEeHyhGuUC5PLgr4etHMYa+cI8ProwYR4NyeXBXwtePYgwP4R5juMc3WpTLBxfuX0PhHh8oxnAxWWMMiUJ6amoqqampFz3vpptuoqmpiX379nHDDTcAUFhYSFNTEzfffHPQa9auXcudd97Z59jq1atZu3Yt69atu/zFi4gIoFwuIhIOlMtFREKfcrmIyKUJiUL6cC1YsIBPfOITfOlLX+LnP/85AF/+8pe56667+myCkZ2dzQ9+8APuvfdeUlJSSElJ6XOfiIgIpk2bNuQO1CIiMjaUy0VEQp9yuYhI6FMuFxHpa3L1x4+C3/3udyxevJhVq1axatUqlixZwm9+85s+5xw/fpympqYJWqGIiFyMcrmISOhTLhcRCX3K5SIiF4RVRzrA1KlT+e1vfzvkOaZpDvn4YDO7RERkfCiXi4iEPuVyEZHQp1wuInJB2HWki4iIiIiIiIiIiIiMJhXSRURERERERERERESGoEK6iIiIiIiIiIiIiMgQVEgXERERERERERERERmCCukiIiIiIiIiIiIiIkNQIV1EREREREREREREZAgqpIuIiIiIiIiIiIiIDEGFdBERERERERERERGRIaiQLiIiIiIiIiIiIiIyBBXSRURERERERERERESGoEK6iIiIiIiIiIiIiMgQVEgXERERERERERERERmCCukiIiIiIiIiIiIiIkNQIV1EREREREREREREZAgqpIuIiIiIiIiIiIiIDEGFdBERERERERERERGRIaiQLiIiIiIiIiIiIiIyBBXSRURERERERERERESGoEK6iIiIiIiIiIiIiMgQVEgXERERERERERERERmCbaIXEC5M0wSgubl5XJ7P5/PR0tJCdHQ0Fkt4vh4S7jGGe3ygGMdSQkIChmGM2/NdKZTLR59iDH3hHh9MbIzK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", "text/plain": [ "
" ]