diff --git a/bayesflow/networks/__init__.py b/bayesflow/networks/__init__.py
index cef2ea0e7..858cfbf13 100644
--- a/bayesflow/networks/__init__.py
+++ b/bayesflow/networks/__init__.py
@@ -1,4 +1,5 @@
from .cif import CIF
+from .consistency_models import ConsistencyModel
from .coupling_flow import CouplingFlow
from .deep_set import DeepSet
from .flow_matching import FlowMatching
diff --git a/bayesflow/networks/consistency_models/consistency_model.py b/bayesflow/networks/consistency_models/consistency_model.py
index 68bf6944f..d316709b8 100644
--- a/bayesflow/networks/consistency_models/consistency_model.py
+++ b/bayesflow/networks/consistency_models/consistency_model.py
@@ -15,13 +15,24 @@
@register_keras_serializable(package="bayesflow.networks")
class ConsistencyModel(InferenceNetwork):
- """Implements a consistency model according to https://arxiv.org/abs/2303.01469"""
+ """Implements a Consistency Model with Consistency Training (CT) as
+ described in [1-2]. The adaptations to CT described in [2] were taken
+ into account in this implementation.
+
+ [1] Song, Y., Dhariwal, P., Chen, M. & Sutskever, I. (2023).
+ Consistency Models.
+ arXiv preprint arXiv:2303.01469
+
+ [2] Song, Y., & Dhariwal, P. (2023).
+ Improved Techniques for Training Consistency Models:
+ arXiv preprint arXiv:2310.14189
+ Discussion: https://openreview.net/forum?id=WNzy9bRDvG
+ """
def __init__(
self,
total_steps: int | float,
subnet: str | type = "mlp",
- base_distribution: str = "normal",
max_time: int | float = 200,
sigma2: float = 1.0,
eps: float = 0.001,
@@ -29,14 +40,38 @@ def __init__(
s1: int | float = 50,
**kwargs,
):
- super().__init__(base_distribution=base_distribution, **keras_kwargs(kwargs))
+ """Creates an instance of a consistency model (CM) to be used
+ for standalone consistency training (CT).
+
+ Parameters:
+ -----------
+ total_steps : int
+ The total number of training steps, can be calculate as
+ number of epochs * number of batches
+ subnet : str or type, optional, default: "mlp"
+ A neural network type for the consistency model, will be
+ instantiated using subnet_kwargs.
+ max_time : int or float, optional, default: 200.0
+ The maximum time of the diffusion
+ sigma2 : float or Tensor of dimension (input_dim, 1),
+ optional, default: 1.0
+ Controls the shape of the skip-function
+ eps : float, optional, default: 0.001
+ The minimum time
+ s0 : int or float, optional, default: 10
+ Initial number of discretization steps
+ s1 : int or float, optional, default: 50
+ Final number of discretization steps
+ **kwargs : dict, optional, default: {}
+ Additional keyword arguments
+ """
+ # Normal is the only supported base distribution for CMs
+ super().__init__(base_distribution="normal", **keras_kwargs(kwargs))
self.total_steps = float(total_steps)
self.student = find_network(subnet, **kwargs.get("subnet_kwargs", {}))
self.student_projector = keras.layers.Dense(units=None, bias_initializer="zeros", kernel_initializer="zeros")
- self.teacher = None
- self.teacher_projector = None
self.sigma2 = ops.convert_to_tensor(sigma2)
self.sigma = ops.sqrt(sigma2)
@@ -49,20 +84,22 @@ def __init__(
self.s1 = float(s1)
self.current_step = 0.0
+ self.seed_generator = keras.random.SeedGenerator()
+
def _schedule_discretization(self) -> int:
- """Schedule function for adjusting the discretization level `N` during the course
- of training.
+ """Schedule function for adjusting the discretization level `N` during
+ the course of training.
- Implements the function N(k) from https://arxiv.org/abs/2310.14189, Section 3.4.
+ Implements the function N(k) from [2], Section 3.4.
"""
k_ = math.floor(self.total_steps / (math.log(self.s1 / self.s0) / math.log(2.0) + 1.0))
out = min(self.s0 * math.pow(2.0, math.floor(self.current_step / k_)), self.s1) + 1.0
return int(out)
- def discretize_time(self, num_steps, rho=7.0):
- """Function for obtaining the discretized time according to
- https://arxiv.org/pdf/2310.14189.pdf, Section 2, bottom of page 2.
+ def _discretize_time(self, num_steps, rho=7.0):
+ """Function for obtaining the discretized time according to [2],
+ Section 2, bottom of page 2.
"""
N = num_steps + 1.0
@@ -93,15 +130,7 @@ def build(self, xz_shape, conditions_shape=None):
input_shape = self.student.compute_output_shape(input_shape)
self.student_projector.build(input_shape)
- # Clone
- self.teacher = keras.models.clone_model(self.student)
- self.teacher_projector = keras.models.clone_model(self.student_projector)
- self.teacher.set_weights(self.student.weights)
- self.teacher_projector.set_weights(self.student_projector)
- self.teacher.trainable = False
- self.student_projector.trainable = False
-
- # Choose coefficient according to https://arxiv.org/pdf/2310.14189.pdf, Section 3.3
+ # Choose coefficient according to [2] Section 3.3
self.c_huber = 0.00054 * math.sqrt(xz_shape[-1])
self.c_huber2 = self.c_huber**2
@@ -116,27 +145,70 @@ def call(
return self._inverse(xz, conditions=conditions, **kwargs)
return self._forward(xz, conditions=conditions, **kwargs)
+ def _forward_train(self, x: Tensor, noise: Tensor, t: Tensor, conditions: Tensor = None, **kwargs) -> Tensor:
+ """Forward function for training. Calls consistency function with
+ noisy input
+ """
+ inp = x + t * noise
+ return self.consistency_function(inp, t, conditions=conditions, **kwargs)
+
def _forward(self, x: Tensor, conditions: Tensor = None, **kwargs) -> Tensor:
- pass
+ # Consistency Models only learn the direction from noise distribution
+ # to target distribution, so we cannot implement this function.
+ raise NotImplementedError("Consistency Models are not invertible")
def _inverse(self, z: Tensor, conditions: Tensor = None, **kwargs) -> Tensor:
- pass
-
- def consistency_function(
- self, x: Tensor, t: Tensor, conditions: Tensor = None, student: bool = True, **kwargs
- ) -> Tensor:
- """Compute consistency function with either the student or the teacher network."""
+ """Generate random draws from the approximate target distribution
+ using the multistep sampling algorithm from [1], Algorithm 1.
+
+ Parameters
+ ----------
+ z : Tensor
+ Samples from a standard normal distribution
+ conditions : Tensor, optional, default: None
+ Conditions for a approximate conditional distribution
+ **kwargs : dict, optional, default: {}
+ Additional keyword arguments. Include `steps` (default: 10) to
+ adjust the number of sampling steps.
+
+ Returns
+ -------
+ x : Tensor
+ The approximate samples
+ """
+ steps = kwargs.get("steps", 10)
+ x = keras.ops.copy(z) * self.max_time
+ discretized_time = keras.ops.flip(self._discretize_time(steps), axis=-1)
+ t = keras.ops.full((*keras.ops.shape(x)[:-1], 1), discretized_time[0], dtype=x.dtype)
+ x = self.consistency_function(x, t, conditions=conditions)
+ for n in range(1, steps):
+ noise = keras.random.normal(keras.ops.shape(x), dtype=keras.ops.dtype(x), seed=self.seed_generator)
+ x_n = x + keras.ops.sqrt(keras.ops.square(discretized_time[n]) - self.eps**2) * noise
+ t = keras.ops.full_like(t, discretized_time[n])
+ x = self.consistency_function(x_n, t, conditions=conditions)
+ return x
+
+ def consistency_function(self, x: Tensor, t: Tensor, conditions: Tensor = None, **kwargs) -> Tensor:
+ """Compute consistency function.
+
+ Parameters
+ ----------
+ x : Tensor
+ Input vector
+ t : Tensor
+ Vector of time samples in [eps, T]
+ conditions : Tensor
+ The conditioning vector
+ **kwargs : dict, optional, default: {}
+ Additional keyword arguments passed to the network.
+ """
if conditions is not None:
xtc = ops.concatenate([x, t, conditions], axis=-1)
else:
xtc = ops.concatenate([x, t], axis=-1)
- # Compute either student or teacher output (no grads for teacher during training)
- if student:
- f = self.student_projector(self.student(xtc, **kwargs))
- else:
- f = self.teacher_projector(self.teacher(xtc, **kwargs))
+ f = self.student_projector(self.student(xtc, **kwargs))
# Compute skip and out parts (vectorized, since self.sigma2 is of shape (1, input_dim)
# Thus, we can do a cross product with the time vector which is (batch_size, 1) for
@@ -147,53 +219,41 @@ def consistency_function(
out = skip * x + out * f
return out
- def update_teacher(self):
- """
- Update function for copying student network weights to teacher network weights.
- Should be called after the optimizer update of the student. EMA was dropped,
- see https://arxiv.org/pdf/2310.14189.pdf, Section 3.2.
- """
-
- for w_teacher, w_student in zip(self.teacher.weights, self.student.weights):
- w_teacher.assign(keras.ops.stop_gradient(w_student))
-
- for w_teacher, w_student in zip(self.teacher_projector.weights, self.student_projector.weights):
- w_teacher.assign(keras.ops.stop_gradient(w_student))
-
- def compute_metrics(self, data: dict[str, Tensor], stage: str = "training") -> dict[str, Tensor]:
- base_metrics = super().compute_metrics(data, stage=stage)
+ def compute_metrics(self, x: Tensor, conditions: Tensor = None, stage: str = "training") -> dict[str, Tensor]:
+ base_metrics = super().compute_metrics(x, conditions=conditions, stage=stage)
+ # The discretization schedule requires the number of passed training steps.
+ # To be independent of external information, we track it here.
self.current_step += 1
- x = data["inference_variables"]
- c = data.get("inference_conditions")
-
- # z = self.base_distribution.sample((ops.shape(x)[0],))
-
current_num_steps = self._schedule_discretization()
- discretized_time = self.discretize_time(current_num_steps)
+ discretized_time = self._discretize_time(current_num_steps)
# Randomly sample t_n and t_[n+1] and reshape to (batch_size, 1)
- # adapted noise schedule from https://arxiv.org/pdf/2310.14189.pdf,
- # Section 3.5
+ # adapted noise schedule from [2], Section 3.5
p_mean = -1.1
p_std = 2.0
log_p = ops.log(
ops.erf((ops.log(discretized_time[1:]) - p_mean) / (ops.sqrt(2.0) * p_std))
- ops.erf((ops.log(discretized_time[:-1]) - p_mean) / (ops.sqrt(2.0) * p_std))
)
- times = keras.random.categorical([log_p], ops.shape(x)[0])[0]
+ times = keras.random.categorical(ops.expand_dims(log_p, 0), ops.shape(x)[0], seed=self.seed_generator)[0]
t1 = ops.take(discretized_time, times)[..., None]
t2 = ops.take(discretized_time, times + 1)[..., None]
- teacher_out = self._forward(x, conditions=c, student=False, training=stage == "training")
+ # generate noise vector
+ noise = keras.random.normal(keras.ops.shape(x), dtype=keras.ops.dtype(x), seed=self.seed_generator)
+
+ teacher_out = self._forward_train(x, noise, t1, conditions=conditions, training=stage == "training")
+ # difference between teacher and student: different time,
+ # and no gradient for the teacher
teacher_out = ops.stop_gradient(teacher_out)
- student_out = self._forward(x, conditions=c, student=True, training=stage == "training")
+ student_out = self._forward_train(x, noise, t2, conditions=conditions, training=stage == "training")
- # weighting function, see https://arxiv.org/pdf/2310.14189.pdf, Section 3.1
+ # weighting function, see [2], Section 3.1
lam = 1 / (t2 - t1)
- # Pseudo-huber loss, see https://arxiv.org/pdf/2310.14189.pdf, Section 3.3
+ # Pseudo-huber loss, see [2], Section 3.3
loss = ops.mean(lam * (ops.sqrt(ops.square(teacher_out - student_out) + self.c_huber2) - self.c_huber))
return base_metrics | {"loss": loss}
diff --git a/examples/TwoMoons_ConsistencyModel.ipynb b/examples/TwoMoons_ConsistencyModel.ipynb
new file mode 100644
index 000000000..7b1efa7ce
--- /dev/null
+++ b/examples/TwoMoons_ConsistencyModel.ipynb
@@ -0,0 +1,704 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "009b6adf",
+ "metadata": {},
+ "source": [
+ "# Consistency Models for Posterior Estimation\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "d5f88a59",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:46.551814Z",
+ "start_time": "2024-09-23T14:39:46.032170Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "import seaborn as sns\n",
+ "\n",
+ "# ensure the backend is set\n",
+ "import os\n",
+ "if \"KERAS_BACKEND\" not in os.environ:\n",
+ " # set this to \"torch\", \"tensorflow\", or \"jax\"\n",
+ " os.environ[\"KERAS_BACKEND\"] = \"jax\"\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",
+ "\n",
+ "import bayesflow as bf"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "eadaf793-ab63-4f69-b962-178e343ca21b",
+ "metadata": {},
+ "source": [
+ "In this notebook, we use Consistency Models (CMs) as a plug-in replacement to obtain posterior samples with fewer sampling steps.\n",
+ "\n",
+ "CMs can be trained in two ways: First, they can be used to _distill_ an existing score-based diffusion model, thereby massively decreasing the sampling time at the expense of an additional training phase. Second, they can be trained from scratch using a procedure named _Consistency Training_. For now, we only support the latter.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6286c800-460a-4881-87d8-c3aca7aeec70",
+ "metadata": {},
+ "source": [
+ "## Background\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fdff817a-6321-4af0-9d41-7ec80097f93b",
+ "metadata": {},
+ "source": [
+ "Consistency Models [1] leverage some nice properties of score-based diffusion to enable few-step sampling. Score-based diffusion initially relied on a stochastic differential equation (SDE) for sampling, but there is also a ordinary (non-stochastic) differential equation (ODE) has the same _marginal_ distribution at each time step $t$ [2]. This means that even though SDE and ODE produce different paths from the noise distribution to the target distribution, the resulting distributions when looking at many paths at time $t$ is the same. The ODE is also called Probability Flow ODE.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4a2e996d-355a-4fab-8347-728e563c6014",
+ "metadata": {},
+ "source": [
+ "CMs now leverage the fact that there is no randomness in the ODE formulation. That means, if you start at a certain point in the latent space, you will always take the same path and always end up at the same point in the data space. The same is true for every point on the path: if you integrate to get to time $t=0$, you will end up at the same point as well. In short: for each path, there is exactly one corresponding point in latent space (at $t=T$) and one corresponding point in data space (at $t=0$). The goal of CMs is now the following: each point at a time point $t$ belongs to exactly one path, and we want to predict where this path will end up at $t=0$. The function that does this is called the _consistency function_ $f$. If we have the correct function for all $t\\in(0,T]$, we can just sample from the latent distribution ($t=T$) and use $f$ to directly map to the corresponding point at $t=0$, which is in the target distribution. So for sampling from the target distribution, we avoid any integration and only need one evaluation of the consistency function. In practice, the one-step sampling does not work very well. Instead, we leverage a multi-step sampling method where we call $f$ multiple times. Please check out the [1] for more background on this sampling procedure.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "25023294-3096-4ebc-83a6-a372208e0504",
+ "metadata": {},
+ "source": [
+ "When only reading the above you might wonder why we also learn the mapping to $t=0$ of all intermediate time steps $t\\in[0, T]$, and not only for $t=T$. The main answer is that for efficient training, we do not want to actually compute the two associated points explicitly. Doing so would require to do a precise integration at training time, which is often not feasible as it is too computationally costly. Learning all time steps opens up the possibility for a different training approach where we can avoid this.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9e6eb121-f89f-4268-9a0d-6fa733c758ff",
+ "metadata": {},
+ "source": [
+ "The details of this become a bit more complicated, and we advise you to take a look at [1] if you are interested in a more thorough and mathematical discussion. Here we will give a rough description of the underlying concepts.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9b201899-b946-4432-bcac-106b9d580d32",
+ "metadata": {},
+ "source": [
+ "First, we know that at $t=0$, it holds that $f(\\theta,t=0)=\\theta$, as $\\theta$ is part of the path that ends at $\\theta$. This _boundary condition_ serves as an \"anchor\" for our training, this is the information that the network knows at the start of the training procedure (we encode it with a time-dependent skip-connection, so the network is forced to be the identity function at $t=0$).\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a11f7ac7-9c11-49c1-b29c-3f0d44c4bf49",
+ "metadata": {},
+ "source": [
+ "For training, we now somehow have to propagate this information to the rest of the part. The basic idea for this is simple. We just take a point $\\theta_1$ closer to the data distribution (smaller time $t_1$) and integrate for a small time step $dt$ to a point $\\theta_2$ on the same path that is closer to the latent distribution (larger time $t_2=t_1+dt$). As we know that for $t=0$ our network provides the correct output for our path, we want to propagate the information from smaller times to larger times. Our training goal is to move the output of $f(\\theta_2, t=t_2)$ towards the output of $f(\\theta_1, t=t_1)$. How to choose $\\theta_1$, $t_1$ and $dt$ is an empirical question, see the [1] for some thoughts on what works well.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "73ff5ed5-dbd0-423b-b4f4-8d209947ed87",
+ "metadata": {},
+ "source": [
+ "In the case of _distillation_, we start with a trained score-based diffusion model. We can use it to integrate the Probability Flow ODE to get from $\\theta_1$ to $\\theta_2$. If we do not have such a model, it seems as if we were stuck. We do not know which points lie on the same path, so we do not know which outputs to make similar. Fortunately, it turns out that there is an _unbiased approximator_ that, if averaged over many samples (check out the paper for the exact description), will also give us the correct score. If we use this approximator instead of the score model, and use only a single Euler step to move along the path, we get an algorithm similar to the one described for distillation. It is called Consistency Training (CT) and allows us to train a consistency model using only _samples_ from the data distribution. The algorithm for this was improved a lot in [3], and we have incorporated those improvements into our implementation.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "283e8fea-9a36-4f8a-80f5-19e2fe98bd09",
+ "metadata": {},
+ "source": [
+ "We have made several approximations to get to a standalone Consistency Training algorithm. As a consequence, the introduced hyperparameters and their choice unfortunately becomes somewhat unintuitive. We have to rely on empirical observations and heuristics to see what works. This was done in [4], we encourage you to use the values provided there as starting points. If you happen to find hyperparameters that work significantly better, please let us know (e.g., by opening an issue or sending an email). This will help others to find the correct region in the hyperparameter space.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8da3535f-0354-40a4-991f-845c33ff75b8",
+ "metadata": {},
+ "source": [
+ "To make this work for Bayesian inverse problems in simulation-based inference, we can make the whole process conditional on some quantity $x$, so we can produce conditional distributions as well. Below, you can see a conceptual visualization of posterior estimation with CMs.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6c105be4-c490-4100-9502-60dd7405cfb4",
+ "metadata": {},
+ "source": [
+ "![Visualization of the way consistency models map from the path to the end point in the data distribution. Depicts the concepts described in the main text.](https://arxiv.org/html/2312.05440v2/extracted/5435837/figures/cmpe_main.png)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "baafb8fd-5b14-4ddf-a6dd-8272f706deaa",
+ "metadata": {},
+ "source": [
+ "### References\n",
+ "\n",
+ "[1] Song, Y., Dhariwal, P., Chen, M., & Sutskever, I. (2023). Consistency Models. _arXiv preprint_. [https://doi.org/10.48550/arXiv.2303.01469](https://doi.org/10.48550/arXiv.2303.01469)\n",
+ "\n",
+ "[2] Song, Y., Sohl-Dickstein, J., Kingma, D. P., Kumar, A., Ermon, S., & Poole, B. (2021). Score-Based Generative Modeling through Stochastic Differential Equations. In _International Conference on Learning Representations_. [https://openreview.net/forum?id=PxTIG12RRHS](https://openreview.net/forum?id=PxTIG12RRHS)\n",
+ "\n",
+ "[3] Song, Y., & Dhariwal, P. (2023). Improved Techniques for Training Consistency Models. _arXiv preprint_. [https://doi.org/10.48550/arXiv.2310.14189](https://doi.org/10.48550/arXiv.2310.14189)\n",
+ "\n",
+ "[4] Schmitt, M., Pratz, V., Köthe, U., Bürkner, P.-C., & Radev, S. T. (2024). Consistency Models for Scalable and Fast Simulation-Based Inference. _arXiv preprint_. [https://doi.org/10.48550/arXiv.2312.05440](https://doi.org/10.48550/arXiv.2312.05440)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c63b26ba",
+ "metadata": {},
+ "source": [
+ "## Simulator: Two Moons\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9525ffd7",
+ "metadata": {},
+ "source": [
+ "We will use the Concistency Model as a plug-in replacement for Flow Matching. Check out the tutorial \"Two moons toy example with flow matching\" for more details on the simulator and setting.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "4b89c861527c13b8",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:46.747091Z",
+ "start_time": "2024-09-23T14:39:46.744830Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "simulator = bf.benchmarks.simulators.TwoMoons()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f6e1eb5777c59eba",
+ "metadata": {},
+ "source": [
+ "We generate some data to see what the simulator does:\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "e6218e61d529e357",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:46.798575Z",
+ "start_time": "2024-09-23T14:39:46.790581Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "# generate 64 random draws from the joint distribution p(r, alpha, theta, x)\n",
+ "sample_data = simulator.sample((64,))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "46174ccb0167026c",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:46.854911Z",
+ "start_time": "2024-09-23T14:39:46.852129Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Type of sample_data:\n",
+ "\t \n",
+ "Keys of sample_data:\n",
+ "\t dict_keys(['parameters', 'observables'])\n",
+ "Types of sample_data values:\n",
+ "\t {'parameters': , 'observables': }\n",
+ "Shapes of sample_data values:\n",
+ "\t {'parameters': (64, 2), 'observables': (64, 2)}\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(\"Type of sample_data:\\n\\t\", type(sample_data))\n",
+ "print(\"Keys of sample_data:\\n\\t\", sample_data.keys())\n",
+ "print(\"Types of sample_data values:\\n\\t\", {k: type(v) for k, v in sample_data.items()})\n",
+ "print(\"Shapes of sample_data values:\\n\\t\", {k: v.shape for k, v in sample_data.items()})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fee88fcfd7a373b0",
+ "metadata": {},
+ "source": [
+ "## Data Adapter\n",
+ "\n",
+ "The next step is to tell BayesFlow how to deal with the simulated variables. You may also think of this as informing BayesFlow about the data flow, i.e., which variables go into which network.\n",
+ "\n",
+ "For this example, we want to learn the posterior distribution $p(\\theta\\,|\\,x)$, so we **infer** $\\theta$, **conditioning** on $x$. In the output from the last command, we see that the simulator provides $\\theta$ as `\"parameters\"` and $x$ as `\"observables\"`.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "c9637c576d4ad4e5",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:46.905081Z",
+ "start_time": "2024-09-23T14:39:46.903091Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "data_adapter = bf.ContinuousApproximator.build_data_adapter(\n",
+ " inference_variables=[\"parameters\"],\n",
+ " inference_conditions=[\"observables\"],\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "254e287b2bccdad",
+ "metadata": {},
+ "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"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "39cb5a1c9824246f",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:46.950573Z",
+ "start_time": "2024-09-23T14:39:46.948624Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "batch_size = 64\n",
+ "num_training_batches = 512\n",
+ "num_validation_batches = 128"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "9dee7252ef99affa",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:53.268860Z",
+ "start_time": "2024-09-23T14:39:46.994697Z"
+ }
+ },
+ "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": 8,
+ "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(training_samples, batch_size=batch_size, data_adapter=data_adapter)\n",
+ "validation_dataset = bf.datasets.OfflineDataset(validation_samples, batch_size=batch_size, data_adapter=data_adapter)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2d4c6eb0",
+ "metadata": {},
+ "source": [
+ "## Training a neural network to approximate all posteriors\n",
+ "\n",
+ "The next step is to set up the neural network that will approximate the posterior $p(\\theta\\,|\\,x)$.\n",
+ "\n",
+ "Consistency models use _scheduling functions_ to adjust some of the hyperparameters, for example the time discretization during training. Consequently, we have to specify the total number of training steps (_gradient updates_) before the start of the training.\n",
+ "For offline training with a given number of epochs, we can calculate it as below:\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "516ac3c4-b66f-4cf0-a443-b00705a6ace5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "epochs = 30\n",
+ "total_steps = epochs * num_training_batches"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2c7980ec-5623-43e3-847e-16a5b6eb8777",
+ "metadata": {},
+ "source": [
+ "Apart from the usual parameters like learning rate and batch size, CMs come with a number of different hyperparameters. Unfortunately, they can heavily interact, so they can be hard to tune. The main hyperparameters are:\n",
+ "\n",
+ "- Maximum time `max_time`: This also serves as the standard deviation of the latent distribution. You can experiment with this, values from 10-200 seem to work well. In any case, it should be larger than the standard deviation of the target distribution.\n",
+ "- Minimum/maximum number of discretization steps during training `s0`/`s1`: The effect of those is hard to grasp. 10 works well for `s0`. Intuitively, increasing `s1` along with the number of epochs should lead to better result, but in practice we sometimes observe a breakdown for high values of `s1`. This seems to be problem-dependent, so just try it out.\n",
+ "- `sigma2` modifies the time-dependency of the skip connection. Its effect on the training is unclear, we recommend leaving it at 1.0 or setting it to the approximate variance of the target distribution.\n",
+ "- Smallest time value `eps` ($t=\\epsilon$ is used instead of $t=0$ for numerical reasons): No large effect in our experiments, as long as it is kept small enough. Probably not worth tuning.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "09206e6f",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:53.339590Z",
+ "start_time": "2024-09-23T14:39:53.319852Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "# Compute the empirical variance of the draws from the prior θ ~ p(θ)\n",
+ "sigma2 = keras.ops.var(training_samples[\"parameters\"], axis=0, keepdims=True)\n",
+ "\n",
+ "inference_network = bf.networks.ConsistencyModel(\n",
+ " subnet=\"mlp\",\n",
+ " subnet_kwargs=dict(\n",
+ " depth=6,\n",
+ " width=256,\n",
+ " ),\n",
+ " total_steps = total_steps,\n",
+ " max_time=10, # works well for this task\n",
+ " sigma2=sigma2, # pass the empirical variance to the network\n",
+ " # the remaining hyperparameters (s0, s1, eps) are the default values\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "851e522f",
+ "metadata": {},
+ "source": [
+ "This inference network is just a general consistency model architecture, 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$.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "96ca6ffa",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:53.371691Z",
+ "start_time": "2024-09-23T14:39:53.369375Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "approximator = bf.ContinuousApproximator(\n",
+ " inference_network=inference_network,\n",
+ " data_adapter=data_adapter,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "566264eadc76c2c",
+ "metadata": {},
+ "source": [
+ "### Optimizer and Learning Rate\n",
+ "\n",
+ "We use an Adam optimizer with [cosine decay](https://keras.io/api/optimizers/learning_rate_schedules/cosine_decay/) to decrease the learning rate towards zero over the training time.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "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,\n",
+ " total_steps,\n",
+ ")\n",
+ "\n",
+ "optimizer = keras.optimizers.Adam(learning_rate=scheduled_lr)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "51808fcd560489ac",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:39:53.476089Z",
+ "start_time": "2024-09-23T14:39:53.466001Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "approximator.compile(optimizer=optimizer)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "708b1303",
+ "metadata": {},
+ "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. This notebook is being executed on a consumer-grade CPU and training is still reasonably fast. If you have a GPU available, training will be even faster, especially for larger networks.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "0f496bda",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:42:36.067393Z",
+ "start_time": "2024-09-23T14:39:53.513436Z"
+ }
+ },
+ "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/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 6ms/step - loss: 0.4117 - loss/inference_loss: 0.4117 - val_loss: 0.3387 - val_loss/inference_loss: 0.3387\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.3568 - loss/inference_loss: 0.3568 - val_loss: 0.3603 - val_loss/inference_loss: 0.3603\n",
+ "Epoch 3/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3503 - loss/inference_loss: 0.3503 - val_loss: 0.2898 - val_loss/inference_loss: 0.2898\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.3362 - loss/inference_loss: 0.3362 - val_loss: 0.4429 - val_loss/inference_loss: 0.4429\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.3343 - loss/inference_loss: 0.3343 - val_loss: 0.3929 - val_loss/inference_loss: 0.3929\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.3311 - loss/inference_loss: 0.3311 - val_loss: 0.2825 - val_loss/inference_loss: 0.2825\n",
+ "Epoch 7/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3264 - loss/inference_loss: 0.3264 - val_loss: 0.3029 - val_loss/inference_loss: 0.3029\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.3222 - loss/inference_loss: 0.3222 - val_loss: 0.3447 - val_loss/inference_loss: 0.3447\n",
+ "Epoch 9/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3222 - loss/inference_loss: 0.3222 - val_loss: 0.3209 - val_loss/inference_loss: 0.3209\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.3141 - loss/inference_loss: 0.3141 - val_loss: 0.2195 - val_loss/inference_loss: 0.2195\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.3123 - loss/inference_loss: 0.3123 - val_loss: 0.3043 - val_loss/inference_loss: 0.3043\n",
+ "Epoch 12/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.3121 - loss/inference_loss: 0.3121 - val_loss: 0.3225 - val_loss/inference_loss: 0.3225\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.3089 - loss/inference_loss: 0.3089 - val_loss: 0.2082 - val_loss/inference_loss: 0.2082\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.3028 - loss/inference_loss: 0.3028 - val_loss: 0.2394 - val_loss/inference_loss: 0.2394\n",
+ "Epoch 15/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2996 - loss/inference_loss: 0.2996 - val_loss: 0.3735 - val_loss/inference_loss: 0.3735\n",
+ "Epoch 16/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2949 - loss/inference_loss: 0.2949 - val_loss: 0.2624 - val_loss/inference_loss: 0.2624\n",
+ "Epoch 17/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2956 - loss/inference_loss: 0.2956 - val_loss: 0.3925 - val_loss/inference_loss: 0.3925\n",
+ "Epoch 18/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2904 - loss/inference_loss: 0.2904 - val_loss: 0.2991 - val_loss/inference_loss: 0.2991\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.2953 - loss/inference_loss: 0.2953 - val_loss: 0.2517 - val_loss/inference_loss: 0.2517\n",
+ "Epoch 20/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2867 - loss/inference_loss: 0.2867 - val_loss: 0.3187 - val_loss/inference_loss: 0.3187\n",
+ "Epoch 21/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2880 - loss/inference_loss: 0.2880 - val_loss: 0.3218 - val_loss/inference_loss: 0.3218\n",
+ "Epoch 22/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2819 - loss/inference_loss: 0.2819 - val_loss: 0.2689 - val_loss/inference_loss: 0.2689\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.2775 - loss/inference_loss: 0.2775 - val_loss: 0.2354 - val_loss/inference_loss: 0.2354\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.2848 - loss/inference_loss: 0.2848 - val_loss: 0.2992 - val_loss/inference_loss: 0.2992\n",
+ "Epoch 25/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2699 - loss/inference_loss: 0.2699 - val_loss: 0.1976 - val_loss/inference_loss: 0.1976\n",
+ "Epoch 26/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2760 - loss/inference_loss: 0.2760 - val_loss: 0.3003 - val_loss/inference_loss: 0.3003\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.2774 - loss/inference_loss: 0.2774 - val_loss: 0.3333 - val_loss/inference_loss: 0.3333\n",
+ "Epoch 28/30\n",
+ "\u001b[1m512/512\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - loss: 0.2745 - loss/inference_loss: 0.2745 - val_loss: 0.2938 - val_loss/inference_loss: 0.2938\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.2795 - loss/inference_loss: 0.2795 - val_loss: 0.2968 - val_loss/inference_loss: 0.2968\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.2720 - loss/inference_loss: 0.2720 - val_loss: 0.2105 - val_loss/inference_loss: 0.2105\n"
+ ]
+ }
+ ],
+ "source": [
+ "history = approximator.fit(\n",
+ " epochs=epochs,\n",
+ " dataset=training_dataset,\n",
+ " validation_data=validation_dataset,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b90a6062",
+ "metadata": {},
+ "source": [
+ "## Validation\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ca62b21d",
+ "metadata": {},
+ "source": [
+ "### Two Moons Posterior\n",
+ "\n",
+ "By design, the two moons posterior at point $x = (0, 0)$ should resemble two crescent moons, hence the name. Below, we plot the corresponding posterior samples.\n",
+ "\n",
+ "These results suggest that our consistency model posterior estimation setup can approximate the target posterior well. You can achieve an even better fit if you use online training, more epochs, or better hyperparameters. We won't do that here because this tutorial shall only illustrate the basic setup for consistency models in amortized inference with bayesflow.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "8562caeb",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2024-09-23T14:42:38.584554Z",
+ "start_time": "2024-09-23T14:42:36.076923Z"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(-0.4, 0.4)"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhgAAAIQCAYAAADD1xd9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/TGe4hAAAACXBIWXMAAA9hAAAPYQGoP6dpAACLuElEQVR4nOzdeXxV9YH//9e5S/aQPYSYhN2Asoo1bK2CFetGtU6V0kFr1alluljamer026n6a2udVqrTKd3GKta1M4rFZVAq0QpIsKwiIRCWLISQmz25Se52zu+Py70mJIGA97Ik7+fjwcPec8859/O5uTP3fT+rYVmWhYiIiEgE2c52AURERGTwUcAQERGRiFPAEBERkYhTwBAREZGIU8AQERGRiFPAEBERkYhTwBAREZGIU8AQERGRiFPAEBERkYhTwBAREZGIU8AQERGRiFPAkH499dRTGIYR/udwOMjLy+OOO+7g8OHDEX+9jRs38sADD9Dc3Bzxe8PH9Tl06FBU7j8YnMvvUbQ/H335JO/Hufxenq6HHnqIiy66CNM0w8fa29u59957yc3NJS4ujmnTpvHCCy+c1v0Heq8nnniCCy64ALfbfdp1kTPAEunHk08+aQHWk08+ab3//vvWunXrrAceeMCKjY21Ro8ebbW3t0f09X7+859bgHXw4MGI3jekrq7Oev/9962urq6o3H8wCP3No/U3+CSi/fnoyyf5zAy2z9vhw4etxMRE63/+5396HL/qqqus1NRU67e//a21bt0666677rIA69lnnz3l1xjovXw+nzV+/Hjr3//93z9RnSS6FDCkX6Evmw8++KDH8R/+8IcWYD3zzDMRfb1ofYG43e6I3i/a9z2bFDCCBuPf9pP613/9V+uCCy6wAoFA+Njrr79uAdZzzz3X49yrrrrKys3Ntfx+/4Dvf6r3+sUvfmGlpKTob3UOUxeJnLKZM2cCUFFRET62fv16rrzySpKTk0lISGD27Nm8/vrrPa5zuVz80z/9E/n5+cTGxpKVlcWcOXP461//ygMPPMC//Mu/ADB69Ohwt8w777wTvn7fvn0sXryY7OxsYmNjmThxIr/+9a97vMYDDzyAYRhs3bqVf/iHfyAtLY2xY8cC/TdZD6TsJ7pvX05U15Dy8nLuuOMOxo8fT0JCAhdccAE33HADH374YZ+vvXPnTr74xS+SkpJCeno6y5Ytw+/3U1ZWxuc+9zmSk5MZNWoU//Ef/9Hn9du2beMLX/gCw4YNIyUlhX/8x3/E5XL1W4dTed8HWue+DOR9GMjnoy+f9G/b12fmL3/5C1OmTCE2NpYxY8bw+OOPh+/RXV/Xhs776KOP+NKXvkRKSgrDhw/nq1/9Ki0tLSesy5EjR0hKSmLRokU9jr/22ms4nU5+8IMfnPD6T8Lr9fLEE0+wePFibLaPvzZWrVpFUlISX/ziF3ucf8cdd1BTU0NJScmAX+NU7/XlL3+Z1tbW0+6OkehznO0CyPmnvLwcgKysLADeffddrrrqKqZMmcITTzxBbGwsK1as4IYbbuD555/n1ltvBWDJkiVs3bqVn/zkJ1x44YU0NzezdetWGhoauOuuu2hsbORXv/oVL7/8MiNGjADgoosuAmD37t3Mnj2bgoICHn30UXJycnjzzTf51re+RX19PT/60Y96lPELX/gCixYt4p577jlhP+1Ay36q9z1RXUNqamrIyMjgZz/7GVlZWTQ2NrJy5UqKiorYtm0bhYWFPe55yy238I//+I987WtfY+3atfzHf/wHPp+Pv/71ryxdupTvfe97PPfcc3z/+99n3LhxfOELX+hx/U033cQtt9zCPffcw0cffcQPf/hDdu/eTUlJCU6ns896nMr7PpA692Ug78PJPh99icbfds2aNXzhC1/gM5/5DC+++CJ+v59f/OIXHD169IR1PN7NN9/Mrbfeyp133smHH37I/fffD8Af//jHfq8ZMWIE//qv/xoOWzNmzOCdd97hi1/8Il//+tf5yU9+0ud1lmURCAQGVC6Ho++vhJKSEhoaGpg3b16P47t27WLixIm9rpsyZUr4+dmzZw/otU/1Xjk5OUyYMIHXX3+dr371qwN6DTnDznYTipy7Qs3lmzZtsnw+n9XW1ma99tprVlZWlpWcnGzV1tZalmVZM2fOtLKzs622trbwtX6/35o0aZKVl5dnmaZpWZZlJSUlWffee2+/r3eiJvCrr77aysvLs1paWnoc/8Y3vmHFxcVZjY2NlmVZ1o9+9CML6LNvtq/m/4GW/UT37cvJ6toXv99veb1ea/z48dZ3vvOd8PHQaz/66KM9zp82bZoFWC+//HL4mM/ns7KysqwvfOELva7vfk/Lsqxnn322V1fX8e/RQN/3061zX/p7H061iyQSf9vj349PfepTVn5+vuXxeMLntLW1WRkZGdbx/++0r89b6LX+4z/+o8e5S5cuteLi4sJl6o/b7bZyc3OtK6+80tq8ebOVnJxs3XHHHSe8rri42AIG9K+/9/aRRx6xgPD/zYeMHz/euvrqq3udX1NTYwHWT3/60xPW55Pe68tf/rI1fPjwAb+GnFnqIpGTmjlzJk6nk+TkZK6//npycnL4v//7P4YPH47b7aakpIR/+Id/ICkpKXyN3W5nyZIlVFdXU1ZWBsBll13GU089xY9//GM2bdqEz+cb0Ot3dXXx9ttvc9NNN5GQkIDf7w//u/baa+nq6mLTpk09rrn55ptPet9TKfup3BcGVle/389Pf/pTLrroImJiYnA4HMTExLBv3z5KS0t7nX/99df3eDxx4kQMw+Caa64JH3M4HIwbN65H91XIl7/85R6Pb7nlFhwOB8XFxX3W4VTf99P9+57q+zAQ0fjbut1u/v73v3PjjTcSExMTPp6UlMQNN9xwSuVbuHBhj8dTpkyhq6uLurq6E16XkJDAj3/8Y95++23mzZvHNddcwx/+8Ide3TPdzZgxgw8++GBA/3Jzc/u8R01NDYZhkJmZ2eu5E732iZ471fP7ei47O5u6ujr8fv8pvY6cGQoYclJPP/00H3zwAdu2baOmpoadO3cyZ84cAJqamrAsK9xk3V3o/1mFmshffPFFbr/9dv77v/+bWbNmkZ6ezm233UZtbe0JX7+hoQG/38+vfvUrnE5nj3/XXnstAPX19T2u6as8xzuVsp/KfWFgdV22bBk//OEPufHGG3n11VcpKSnhgw8+YOrUqXR2dva6Z3p6eo/HMTExJCQkEBcX1+t4V1dXr+tzcnJ6PHY4HGRkZPTbhXGq7/vp/n1P9X0YiGj8bUP3HD58eK/n+jp2IhkZGT0ex8bGAgyovhdeeCEQ/MJ96qmnsNvtJzw/KSmJadOmDehf9+DUXWdnJ06ns9dr9ff5aWxsBHp/Zk/kdO4VFxeHZVl9ft7l7NMYDDmpiRMncumll/b5XFpaGjabjSNHjvR6rqamBiD8qyczM5PHHnuMxx57jMrKSlavXs19991HXV0da9as6ff109LSwr88//mf/7nPc0aPHt3j8UB+OZ1K2U/lvqHrTlbXZ555httuu42f/vSnPa6tr68nNTV1QK9zKmpra7ngggvCj/1+Pw0NDb2+7EJO9X0/3b9vNN6HaPxt09LSMAyjz/EWJwtRkbJ9+3auv/565syZw4YNG/jjH//Y798m5N133+01dqI/Bw8eZNSoUb2OZ2Zm4vV6cbvdJCYmho9PnjyZ559/Hr/f32PsRGiA7qRJkwb0uqd7r8bGRmJjY3u0Usm5Qy0Y8okkJiZSVFTEyy+/3OPXl2maPPPMM+Tl5YV/cXVXUFDAN77xDa666iq2bt0K9P8rLiEhgXnz5rFt2zamTJnCpZde2utff1+S0Sj7qeqrrhD8QgvVOeT111+PyiJmAM8++2yPx3/+85/x+/1cccUVfZ7/Sd73/urcl4G+D6fyKz8af9vExEQuvfRSXnnlFbxeb/h4e3s7r7322ind63SUlZVx9dVXM2vWLIqLi/n85z/PAw88cNLZJ5HoIpkwYQIA+/fv73H8pptuor29nZdeeqnH8ZUrV5Kbm0tRUdGA63c69zpw4MAJB/rK2aUWDPnEHn74Ya666irmzZvH9773PWJiYlixYgW7du3i+eefxzAMWlpamDdvHosXL2bChAkkJyfzwQcfhEflQ/AXDMDjjz/O7bffjtPppLCwkOTkZB5//HHmzp3Lpz/9ab7+9a8zatQo2traKC8v59VXX2XdunVRK/upGkhdITim4qmnnmLChAlMmTKFLVu28POf/5y8vLzTqsvJvPzyyzgcDq666qrwLJKpU6dyyy239HvNQN/3gda5LwN9H070+ehLNP62Dz30ENdddx1XX3013/72twkEAvz85z8nKSkp3JQfDYcOHeKzn/0shYWFvPTSSzidTn72s58xadIkfvrTn/LII4/0e21ycnK/LZADFQqhmzZtCs/qALjmmmu46qqr+PrXv05rayvjxo3j+eefZ82aNTzzzDO9ulQMw+Dyyy/vc3rxqd7LNE02b97MnXfe+YnqJlF0VoeYyjmtv4W2+vLee+9Z8+fPtxITE634+Hhr5syZ1quvvhp+vqury7rnnnusKVOmWMOGDbPi4+OtwsJC60c/+lGPhXLuv/9+Kzc317LZbBZgFRcXh587ePCg9dWvftW64IILLKfTaWVlZVmzZ8+2fvzjH4fPCY3Sd7lc/dbn+JHyJyv7ye57vIHWtampybrzzjut7OxsKyEhwZo7d6713nvvWZdffrl1+eWXn/S1b7/9disxMbHX619++eXWxRdf3Ov6LVu2WDfccIOVlJRkJScnW1/60peso0ePnvQ9Gsj7PtA692Wg74Nlnfjz0ZdP+rft6/1YtWqVNXnyZCsmJsYqKCiwfvazn1nf+ta3rLS0tJNe299rnWiBs5qaGmvs2LHWJZdc0ms2z913323FxsaekcXHPv3pT1vXXnttr+NtbW3Wt771LSsnJ8eKiYmxpkyZYj3//PN9ngdYixYt6vc1Bnovy7Kst99+O/y5lnOTYVmWdeZjjYicKQ888AAPPvggLperz1kA8sn4fD6mTZvGBRdcwFtvvXW2ixM1L730ErfeeisVFRU9xvIM1BtvvMH111/Pjh07wq1Rn8SSJUs4cOAAGzZs+MT3kuhQF4mIyCm48847ueqqqxgxYgS1tbX89re/pbS0lMcff/xsFy2qvvCFL/CpT32Khx9+mP/6r/865euLi4tZtGhRRMLF/v37efHFF0+7a1TODAUMEZFT0NbWxve+9z1cLhdOp5NLLrmEN954g89+9rNnu2hRZRgGf/jDH1i9ejWmafZYMnwgfv7zn0esLJWVlfzXf/0Xc+fOjdg9JfLURSIiIiIRd0amqa5YsYLRo0cTFxfHjBkzeO+99wZ03YYNG3A4HEybNi26BRQREZGIinrAePHFF7n33nv5wQ9+wLZt2/j0pz/NNddcQ2Vl5Qmva2lp4bbbbuPKK6+MdhFFREQkwqLeRVJUVMQll1zCb37zm/CxiRMncuONN/Lwww/3e92iRYsYP348drudV155he3bt0ezmCIiIhJBUW3B8Hq9bNmyhQULFvQ4vmDBAjZu3NjvdU8++ST79+/vtQV3XzweD62treF/LS0tuFwuNLRERETk7InqLJL6+noCgUCvjYCGDx/e79r9+/bt47777uO9997rsR59fx5++GEefPDBXsf37NlDSkrK6RX8PGCaJi0tLaSkpJzyaO7zieo5eAyFOoLqOdgMhXqaptnvMvGfxBmZpnr8kryWZfW5TG8gEGDx4sU8+OCDA94n4P7772fZsmXhx62treTn55OVlRWVDaPOFaZpYhgGWVlZg/ZDD6rnYDIU6giq52AzFOppmmZU7hvVgJGZmYndbu/VWlFXV9fn9sZtbW38/e9/Z9u2bXzjG98AghW3LAuHw8Fbb73F/Pnze1wTGxvba6MkAJvNNmg/DCGGYaieg8hQqOdQqCOonoPNUKlnpEX13YqJiWHGjBmsXbu2x/G1a9cye/bsXucPGzaMDz/8kO3bt4f/3XPPPRQWFrJ9+/ZT2plPREREzp6od5EsW7aMJUuWcOmllzJr1ix+//vfU1lZyT333AMEuzgOHz7M008/jc1mY9KkST2uz87OJi4urtdxEREROXdFPWDceuutNDQ08NBDD3HkyBEmTZrEG2+8wciRIwE4cuTISdfEEBERkfPLoFsqvLW1lZSUFJqamgb9IM+6ujqys7MHdb+g6jl4DIU6guo52AyFep7O3jIDMTjfLRERETmrFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4hQwREREJOIUMERERCTiFDBEREQk4s5IwFixYgWjR48mLi6OGTNm8N577/V77vr165kzZw4ZGRnEx8czYcIEfvnLX56JYoqIiEiEOKL9Ai+++CL33nsvK1asYM6cOfzud7/jmmuuYffu3RQUFPQ6PzExkW984xtMmTKFxMRE1q9fz9e+9jUSExP5p3/6p2gXV0RERCIg6i0Yy5cv58477+Suu+5i4sSJPPbYY+Tn5/Ob3/ymz/OnT5/Ol770JS6++GJGjRrFP/7jP3L11VefsNVDREREzi1RbcHwer1s2bKF++67r8fxBQsWsHHjxgHdY9u2bWzcuJEf//jHfT7v8XjweDzhx62trQCYpolpmqdZ8nOfaZpYljWo6wiq52AyFOoIqudgMxTqaZomNlvk2xuiGjDq6+sJBAIMHz68x/Hhw4dTW1t7wmvz8vJwuVz4/X4eeOAB7rrrrj7Pe/jhh3nwwQd7HXe5XHi93tMv/DnONE1aWlqwLCsqH4xzheo5eAyFOoLq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",
+ "text/plain": [
+ "