From 52806e9740b9471bd714fb2955bc5b337edb727e Mon Sep 17 00:00:00 2001 From: Agustinus Kristiadi Date: Mon, 19 Aug 2024 12:13:21 -0400 Subject: [PATCH 1/3] Make importing `asdfghjkl` conditional to the installed optional dependency --- .github/workflows/pytest.yml | 1 + README.md | 12 ++++---- laplace/__init__.py | 1 + laplace/baselaplace.py | 15 ++++++++-- laplace/curvature/__init__.py | 42 ++++++++++++++++++--------- laplace/curvature/asdfghjkl.py | 26 ++++++++++------- setup.cfg | 5 ++-- tests/test_baselaplace.py | 7 ++++- tests/test_curv_backends_asdfghjkl.py | 9 ++++++ 9 files changed, 81 insertions(+), 37 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 01aaff7..e9246a3 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -21,6 +21,7 @@ jobs: run: | python -m pip install --upgrade pip pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu + pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl pip install -e . - name: Test with pytest run: | diff --git a/README.md b/README.md index 6629e1c..24c38c1 100644 --- a/README.md +++ b/README.md @@ -56,14 +56,14 @@ The [code](https://github.com/runame/laplace-redux) to reproduce the experiments To install laplace with `pip`, run the following: ```bash -pip install git+https://github.com/aleximmer/laplace@update-deps +pip install laplace-torch ``` -> [!WARNING] -> The ASDL dependency has recently been updated and it breaks the compatibility with -> `laplace-torch`. Please _do not_ install `laplace-torch` from `pip` or the `main` -> branch. Instead install it as above, from the `update-deps` branch. -> We're actively fixing this issue. +Additionally, if you want to use the `asdfghjkl` backend, please install it via: + +```bash +pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl +``` For development purposes, e.g. if you would like to make contributions, clone the repository and then install: diff --git a/laplace/__init__.py b/laplace/__init__.py index cf00f53..e0acc36 100644 --- a/laplace/__init__.py +++ b/laplace/__init__.py @@ -14,6 +14,7 @@ FunctionalLaplace, KronLaplace, LowRankLaplace, + ParametricLaplace, ) from laplace.laplace import Laplace from laplace.lllaplace import ( diff --git a/laplace/baselaplace.py b/laplace/baselaplace.py index 534db91..e6de580 100644 --- a/laplace/baselaplace.py +++ b/laplace/baselaplace.py @@ -2,6 +2,7 @@ import warnings from collections.abc import MutableMapping +from importlib.util import find_spec from math import log, pi, sqrt from typing import Any, Callable @@ -1686,6 +1687,9 @@ class LowRankLaplace(ParametricLaplace): are usedto reduce the costs of inversion to the that of a \\(K \times K\\) matrix if we have a rank of K. + Note that only `AsdfghjklHessian` backend is supported. Install it via: + pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl + See `BaseLaplace` for the full interface. """ @@ -1695,6 +1699,9 @@ def __init__( self, model: nn.Module, likelihood: Likelihood | str, + backend: type[CurvatureInterface] = AsdfghjklHessian + if find_spec("asdfghjkl") is not None + else CurvatureInterface, sigma_noise: float | torch.Tensor = 1, prior_precision: float | torch.Tensor = 1, prior_mean: float | torch.Tensor = 0, @@ -1702,9 +1709,14 @@ def __init__( enable_backprop: bool = False, dict_key_x: str = "inputs_id", dict_key_y: str = "labels", - backend=AsdfghjklHessian, backend_kwargs: dict[str, Any] | None = None, ): + if find_spec("asdfghjkl") is None: + raise ImportError( + """To use LowRankLaplace, please install the old asdfghjkl dependency: """ + """pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl""" + ) + super().__init__( model, likelihood, @@ -1718,7 +1730,6 @@ def __init__( backend=backend, backend_kwargs=backend_kwargs, ) - self.backend: AsdfghjklHessian def _init_H(self): self.H: tuple[torch.Tensor, torch.Tensor] | None = None diff --git a/laplace/curvature/__init__.py b/laplace/curvature/__init__.py index ed7f054..1e4b9bf 100644 --- a/laplace/curvature/__init__.py +++ b/laplace/curvature/__init__.py @@ -1,4 +1,5 @@ import logging +from importlib.util import find_spec from laplace.curvature.curvature import CurvatureInterface, EFInterface, GGNInterface @@ -7,16 +8,6 @@ except ModuleNotFoundError: logging.info("Backpack backend not available.") -try: - from laplace.curvature.asdfghjkl import ( - AsdfghjklEF, - AsdfghjklGGN, - AsdfghjklHessian, - AsdfghjklInterface, - ) -except ModuleNotFoundError: - logging.info("Asdfghjkl backend not available.") - try: from laplace.curvature.asdl import AsdlEF, AsdlGGN, AsdlHessian, AsdlInterface except ModuleNotFoundError: @@ -39,10 +30,6 @@ "BackPackInterface", "BackPackGGN", "BackPackEF", - "AsdfghjklInterface", - "AsdfghjklGGN", - "AsdfghjklEF", - "AsdfghjklHessian", "AsdlInterface", "AsdlGGN", "AsdlEF", @@ -52,3 +39,30 @@ "CurvlinopsEF", "CurvlinopsHessian", ] + +if find_spec("asdfghjkl") is None: + logging.info( + """Asdfghjkl backend not available since the old asdfghjkl dependency """ + """is not installed. If you want to use it, run: """ + """pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl""" + ) +else: + try: + from laplace.curvature.asdfghjkl import ( + AsdfghjklEF, # noqa: F401 + AsdfghjklGGN, # noqa: F401 + AsdfghjklHessian, # noqa: F401 + AsdfghjklInterface, # noqa: F401 + ) + + __all__.extend( + [ + "AsdfghjklInterface", + "AsdfghjklGGN", + "AsdfghjklEF", + "AsdfghjklHessian", + "AsdlInterface", + ] + ) + except ModuleNotFoundError: + logging.info("Asdfghjkl backend not available.") diff --git a/laplace/curvature/asdfghjkl.py b/laplace/curvature/asdfghjkl.py index ad7dacf..4890c73 100644 --- a/laplace/curvature/asdfghjkl.py +++ b/laplace/curvature/asdfghjkl.py @@ -2,21 +2,25 @@ import warnings from collections.abc import MutableMapping +from importlib.util import find_spec from typing import Any import numpy as np import torch -from asdfghjkl import ( - COV, - FISHER_EXACT, - FISHER_MC, - SHAPE_DIAG, - SHAPE_FULL, - SHAPE_KRON, - fisher_for_cross_entropy, -) -from asdfghjkl.gradient import batch_gradient -from asdfghjkl.hessian import hessian_eigenvalues, hessian_for_loss + +if find_spec("asdfghjkl") is not None: + from asdfghjkl import ( + COV, + FISHER_EXACT, + FISHER_MC, + SHAPE_DIAG, + SHAPE_FULL, + SHAPE_KRON, + fisher_for_cross_entropy, + ) + from asdfghjkl.gradient import batch_gradient + from asdfghjkl.hessian import hessian_eigenvalues, hessian_for_loss + from torch import nn from torch.utils.data import DataLoader diff --git a/setup.cfg b/setup.cfg index 7e9135a..926b981 100644 --- a/setup.cfg +++ b/setup.cfg @@ -37,11 +37,10 @@ install_requires = torchvision torchaudio backpack-for-pytorch - asdfghjkl - asdl @ git+https://github.com/kazukiosawa/asdl + asdfghjkl == 0.1a4 torchmetrics opt_einsum - curvlinops-for-pytorch @ git+https://github.com/f-dangel/curvlinops + curvlinops-for-pytorch >= 2.0 python_requires = >=3.9 [options.packages.find] diff --git a/tests/test_baselaplace.py b/tests/test_baselaplace.py index 5015a61..216dfba 100644 --- a/tests/test_baselaplace.py +++ b/tests/test_baselaplace.py @@ -2,6 +2,7 @@ from collections.abc import MutableMapping from copy import deepcopy +from importlib.util import find_spec from itertools import product from math import prod, sqrt @@ -24,7 +25,11 @@ torch.manual_seed(240) torch.set_default_tensor_type(torch.DoubleTensor) -flavors = [FullLaplace, KronLaplace, DiagLaplace, LowRankLaplace] + +flavors = [FullLaplace, KronLaplace, DiagLaplace] +if find_spec("asdfghjkl") is not None: + flavors.append(LowRankLaplace) + online_flavors = [FullLaplace, KronLaplace, DiagLaplace] diff --git a/tests/test_curv_backends_asdfghjkl.py b/tests/test_curv_backends_asdfghjkl.py index 3d928bd..fe87d3b 100644 --- a/tests/test_curv_backends_asdfghjkl.py +++ b/tests/test_curv_backends_asdfghjkl.py @@ -1,4 +1,13 @@ import pytest + +pytestmark = pytest.mark.skipif( + pytest.importorskip( + "asdfghjkl", reason="The old asdfghjkl dependency is not installed" + ) + is None, + reason="The old asdfghjkl dependency is not installed", +) + import torch from asdfghjkl.operations import Bias, Scale from torch import nn From d6d1364e9b83c367856be578be2072dbdfb03869 Mon Sep 17 00:00:00 2001 From: Agustinus Kristiadi Date: Mon, 19 Aug 2024 14:01:19 -0400 Subject: [PATCH 2/3] Run test workflow where `asdfghjkl` is not installed --- .github/workflows/pytest.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index e9246a3..7ec4a0e 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -20,11 +20,15 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip + pip install pytest + pip install pytest-mock pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu - pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl pip install -e . + - name: Test without the old asdfghjkl + run: | + pip uninstall -y asdfghjkl-old + pytest tests - name: Test with pytest run: | - pip install pytest - pip install pytest-mock + pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl pytest tests From 7968c663965c1c5a0d921159430af9ef1fa5394d Mon Sep 17 00:00:00 2001 From: Agustinus Kristiadi Date: Tue, 20 Aug 2024 10:39:03 -0400 Subject: [PATCH 3/3] Update docs --- docs/baselaplace.html | 219 +++++++++++++++++- docs/curvature/index.html | 182 --------------- docs/index.html | 358 +++++++++++++++++++++++++++-- docs/laplace.html | 11 +- docs/lllaplace.html | 69 ++++++ docs/regression_example.png | Bin 24499 -> 27918 bytes docs/regression_example_online.png | Bin 21978 -> 28360 bytes docs/utils/enums.html | 8 + docs/utils/index.html | 63 +++++ docs/utils/utils.html | 62 +++++ 10 files changed, 767 insertions(+), 205 deletions(-) diff --git a/docs/baselaplace.html b/docs/baselaplace.html index 0a19629..a5a3cef 100644 --- a/docs/baselaplace.html +++ b/docs/baselaplace.html @@ -81,7 +81,7 @@

Parameters

Subclasses

Instance variables

@@ -492,6 +492,206 @@

Inherited members

+
+class FunctionalLaplace +(model: nn.Module, likelihood: Likelihood | str, n_subset: int, sigma_noise: float | torch.Tensor = 1.0, prior_precision: float | torch.Tensor = 1.0, prior_mean: float | torch.Tensor = 0.0, temperature: float = 1.0, enable_backprop: bool = False, dict_key_x='inputs_id', dict_key_y='labels', backend: type[CurvatureInterface] | None = laplace.curvature.backpack.BackPackGGN, backend_kwargs: dict[str, Any] | None = None, independent_outputs: bool = False, seed: int = 0) +
+
+

Applying the GGN (Generalized Gauss-Newton) approximation for the Hessian in the Laplace approximation of the posterior +turns the underlying probabilistic model from a BNN into a GLM (generalized linear model). +This GLM (in the weight space) is equivalent to a GP (in the function space), see +Approximate Inference Turns Deep Networks into Gaussian Processes (Khan et al., 2019)

+

This class implements the (approximate) GP inference through which +we obtain the desired quantities (posterior predictive, marginal log-likelihood). +See Improving predictions of Bayesian neural nets via local linearization (Immer et al., 2021) +for more details.

+

Note that for likelihood='classification', we approximate L_{NN} with a diagonal matrix +( L_{NN} is a block-diagonal matrix, where blocks represent Hessians of per-data-point log-likelihood w.r.t. +neural network output f , See Appendix A.2.1 for exact definition). We +resort to such an approximation because of the (possible) errors found in Laplace approximation for +multiclass GP classification in Chapter 3.5 of R&W 2006 GP book, +see the question +here +for more details. Alternatively, one could also resort to one-vs-one or one-vs-rest implementations +for multiclass classification, however, that is not (yet) supported here.

+

Parameters

+
+
num_data : int
+
number of data points for Subset-of-Data (SOD) approximate GP inference.
+
diagonal_kernel : bool
+
GP kernel here is product of Jacobians, which results in a C \times C matrix where C is the output +dimension. If diagonal_kernel=True, only a diagonal of a GP kernel is used. This is (somewhat) equivalent to +assuming independent GPs across output channels.
+
+

See BaseLaplace class for the full interface.

+

Ancestors

+ +

Subclasses

+ +

Instance variables

+
+
var gp_kernel_prior_variance
+
+
+
+
var log_det_ratio : torch.Tensor
+
+

Computes log determinant term in GP marginal likelihood

+

For classification we use eq. (3.44) from Chapter 3.5 from +GP book R&W 2006 with +(note that we always use diagonal approximation D of the Hessian of log likelihood w.r.t. f):

+

log determinant term := \log | I + D^{1/2}K D^{1/2} |

+

For regression, we use "standard" GP marginal likelihood:

+

log determinant term := \log | K + \sigma_2 I |

+
+
var scatter : torch.Tensor
+
+

Compute scatter term in GP log marginal likelihood.

+

For classification we use eq. (3.44) from Chapter 3.5 from +GP book R&W 2006 with \hat{f} = f :

+

scatter term := f K^{-1} f^{T}

+

For regression, we use "standard" GP marginal likelihood:

+

scatter term := (y - m)K^{-1}(y -m )^T , +where m is the mean of the GP prior, which in our case corresponds to + m := f + J (\theta - \theta_{MAP})

+
+
var prior_precision
+
+
+
+
+

Methods

+
+
+def fit(self, train_loader: DataLoader | MutableMapping, progress_bar: bool = False) +
+
+

Fit the Laplace approximation of a GP posterior.

+

Parameters

+
+
train_loader : torch.data.utils.DataLoader
+
train_loader.dataset needs to be set to access N, size of the data set +train_loader.batch_size needs to be set to access b batch_size
+
progress_bar : bool
+
whether to show a progress bar during the fitting process.
+
+
+
+def predictive_samples(self, x: torch.Tensor | MutableMapping[str, torch.Tensor | Any], pred_type: PredType | str = PredType.GLM, n_samples: int = 100, diagonal_output: bool = False, generator: torch.Generator | None = None) ‑> torch.Tensor +
+
+

Sample from the posterior predictive on input data x. +Can be used, for example, for Thompson sampling.

+

Parameters

+
+
x : torch.Tensor or MutableMapping
+
input data (batch_size, input_shape)
+
pred_type : {'glm'}, default='glm'
+
type of posterior predictive, linearized GLM predictive.
+
n_samples : int
+
number of samples
+
diagonal_output : bool
+
whether to use a diagonalized glm posterior predictive on the outputs. +Only applies when pred_type='glm'.
+
generator : torch.Generator, optional
+
random number generator to control the samples (if sampling used)
+
+

Returns

+
+
samples : torch.Tensor
+
samples (n_samples, batch_size, output_shape)
+
+
+
+def functional_variance(self, Js_star: torch.Tensor) ‑> torch.Tensor +
+
+

GP posterior variance:

+

k_{**} - K_{*M} (K_{MM}+ L_{MM}^{-1})^{-1} K_{M*}

+

Parameters

+
+
Js_star : torch.Tensor of shape (N*, C, P)
+
Jacobians of test data points
+
+

Returns

+
+
f_var : torch.Tensor of shape (N*,C, C)
+
Contains the posterior variances of N* testing points.
+
+
+
+def functional_covariance(self, Js_star: torch.Tensor) ‑> torch.Tensor +
+
+

GP posterior covariance:

+

k_{**} - K_{*M} (K_{MM}+ L_{MM}^{-1})^{-1} K_{M*}

+

Parameters

+
+
Js_star : torch.Tensor of shape (N*, C, P)
+
Jacobians of test data points
+
+

Returns

+
+
f_var : torch.Tensor of shape (N*xC, N*xC)
+
Contains the posterior covariances of N* testing points.
+
+
+
+def optimize_prior_precision(self, pred_type: PredType | str = PredType.GP, method: TuningMethod | str = TuningMethod.MARGLIK, n_steps: int = 100, lr: float = 0.1, init_prior_prec: float | torch.Tensor = 1.0, prior_structure: PriorStructure | str = PriorStructure.SCALAR, val_loader: DataLoader | None = None, loss: torchmetrics.Metric | Callable[[torch.Tensor], torch.Tensor | float] | None = None, log_prior_prec_min: float = -4, log_prior_prec_max: float = 4, grid_size: int = 100, link_approx: LinkApprox | str = LinkApprox.PROBIT, n_samples: int = 100, verbose: bool = False, progress_bar: bool = False) ‑> None +
+
+

optimize_prior_precision_base from BaseLaplace with pred_type='gp'

+
+
+def log_marginal_likelihood(self, prior_precision: torch.Tensor | None = None, sigma_noise: torch.Tensor | None = None) ‑> torch.Tensor +
+
+

Compute the Laplace approximation to the log marginal likelihood. +Requires that the Laplace approximation has been fit before. +The resulting torch.Tensor is differentiable in prior_precision and +sigma_noise if these have gradients enabled. +By passing prior_precision or sigma_noise, the current value is +overwritten. This is useful for iterating on the log marginal likelihood.

+

Parameters

+
+
prior_precision : torch.Tensor, optional
+
prior precision if should be changed from current prior_precision value
+
sigma_noise : torch.Tensor, optional
+
observation noise standard deviation if should be changed
+
+

Returns

+
+
log_marglik : torch.Tensor
+
 
+
+
+
+def state_dict(self) ‑> dict +
+
+
+
+
+def load_state_dict(self, state_dict: dict) +
+
+
+
+
+

Inherited members

+ +
class FullLaplace (model: nn.Module, likelihood: Likelihood | str, sigma_noise: float | torch.Tensor = 1.0, prior_precision: float | torch.Tensor = 1.0, prior_mean: float | torch.Tensor = 0.0, temperature: float = 1.0, enable_backprop: bool = False, dict_key_x: str = 'input_ids', dict_key_y: str = 'labels', backend: type[CurvatureInterface] | None = None, backend_kwargs: dict[str, Any] | None = None) @@ -718,7 +918,7 @@

Inherited members

class LowRankLaplace -(model: nn.Module, likelihood: Likelihood | str, sigma_noise: float | torch.Tensor = 1, prior_precision: float | torch.Tensor = 1, prior_mean: float | torch.Tensor = 0, temperature: float = 1, enable_backprop: bool = False, dict_key_x: str = 'inputs_id', dict_key_y: str = 'labels', backend=laplace.curvature.asdfghjkl.AsdfghjklHessian, backend_kwargs: dict[str, Any] | None = None) +(model: nn.Module, likelihood: Likelihood | str, backend: type[CurvatureInterface] = laplace.curvature.curvature.CurvatureInterface, sigma_noise: float | torch.Tensor = 1, prior_precision: float | torch.Tensor = 1, prior_mean: float | torch.Tensor = 0, temperature: float = 1, enable_backprop: bool = False, dict_key_x: str = 'inputs_id', dict_key_y: str = 'labels', backend_kwargs: dict[str, Any] | None = None)

Laplace approximation with low-rank log likelihood Hessian (approximation). @@ -732,6 +932,8 @@

Inherited members

imes K matrix if we have a rank of K.

+

Note that only AsdfghjklHessian backend is supported. Install it via: +pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl

See BaseLaplace for the full interface.

Ancestors

-
-class AsdfghjklInterface -(model: nn.Module, likelihood: Likelihood | str, last_layer: bool = False, subnetwork_indices: torch.LongTensor | None = None, dict_key_x: str = 'input_ids', dict_key_y: str = 'labels') -
-
-

Interface for asdfghjkl backend.

-

Ancestors

- -

Subclasses

- -

Methods

-
-
-def jacobians(self, x: torch.Tensor | MutableMapping[str, torch.Tensor | Any], enable_backprop: bool = False) ‑> tuple[torch.Tensor, torch.Tensor] -
-
-

Compute Jacobians \nabla_\theta f(x;\theta) at current parameter \theta -using asdfghjkl's gradient per output dimension.

-

Parameters

-
-
x : torch.Tensor
-
input data (batch, input_shape) on compatible device with model.
-
enable_backprop : bool, default = False
-
whether to enable backprop through the Js and f w.r.t. x
-
-

Returns

-
-
Js : torch.Tensor
-
Jacobians (batch, parameters, outputs)
-
f : torch.Tensor
-
output function (batch, outputs)
-
-
-
-def gradients(self, x: torch.Tensor | MutableMapping[str, torch.Tensor | Any], y: torch.Tensor) ‑> tuple[torch.Tensor, torch.Tensor] -
-
-

Compute gradients \nabla_\theta \ell(f(x;\theta, y) at current parameter -\theta using asdfghjkl's backend.

-

Parameters

-
-
x : torch.Tensor
-
input data (batch, input_shape) on compatible device with model.
-
y : torch.Tensor
-
 
-
-

Returns

-
-
loss : torch.Tensor
-
 
-
Gs : torch.Tensor
-
gradients (batch, parameters)
-
-
-
-

Inherited members

- -
-
-class AsdfghjklGGN -(model: nn.Module, likelihood: Likelihood | str, last_layer: bool = False, subnetwork_indices: torch.LongTensor | None = None, dict_key_x: str = 'input_ids', dict_key_y: str = 'labels', stochastic: bool = False) -
-
-

Implementation of the GGNInterface using asdfghjkl.

-

Ancestors

- -

Inherited members

- -
-
-class AsdfghjklEF -(model: nn.Module, likelihood: Likelihood | None, last_layer: bool = False, dict_key_x: str = 'input_ids', dict_key_y: str = 'labels') -
-
-

Implementation of the EFInterface using asdfghjkl.

-

Ancestors

- -

Inherited members

- -
-
-class AsdfghjklHessian -(model: nn.Module, likelihood: Likelihood | str, last_layer: bool = False, dict_key_x: str = 'input_ids', dict_key_y: str = 'labels', low_rank: int = 10) -
-
-

Interface for asdfghjkl backend.

-

Ancestors

- -

Methods

-
-
-def eig_lowrank(self, data_loader: DataLoader) ‑> tuple[torch.Tensor, torch.Tensor, torch.Tensor] -
-
-
-
-
-

Inherited members

- -
class AsdlInterface (model: nn.Module, likelihood: Likelihood | str, last_layer: bool = False, subnetwork_indices: torch.LongTensor | None = None, dict_key_x: str = 'input_ids', dict_key_y: str = 'labels') @@ -1056,25 +893,6 @@

BackPackEF

  • -

    AsdfghjklInterface

    - -
  • -
  • -

    AsdfghjklGGN

    -
  • -
  • -

    AsdfghjklEF

    -
  • -
  • -

    AsdfghjklHessian

    - -
  • -
  • AsdlInterface

    • jacobians
    • diff --git a/docs/index.html b/docs/index.html index 6a88fac..ef64eab 100644 --- a/docs/index.html +++ b/docs/index.html @@ -67,19 +67,30 @@

      Table of contents

    • References
    • Setup

      -

      For full compatibility, install this package in a fresh virtual env. +

      +

      [!IMPORTANT] We assume Python >= 3.9 since lower versions are (soon to be) deprecated. -PyTorch version 2.0 and up is also required for full compatibility. -To install laplace with pip, run the following:

      +PyTorch version 2.0 and up is also required for full compatibility.

      +
      +

      To install laplace with pip, run the following:

      pip install laplace-torch
       
      -

      For development purposes, clone the repository and then install:

      +

      Additionally, if you want to use the asdfghjkl backend, please install it via:

      +
      pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl
      +
      +

      For development purposes, e.g. if you would like to make contributions, +clone the repository and then install:

      # first install the build system:
       pip install --upgrade pip wheel packaging
       
      -# then install the develop 
      +# then install the develop
       pip install -e ".[all]"
       
      +
      +

      [!NOTE] +See contributing guideline. +We're looking forward to your contributions!

      +

      Example usage

      Simple usage

      In the following example, a pre-trained model is loaded, @@ -114,9 +125,9 @@

      Simple usage

      hessian_structure="diag") la.fit(train_loader) la.optimize_prior_precision( - method="gridsearch", - pred_type="glm", - link_approx="probit", + method="gridsearch", + pred_type="glm", + link_approx="probit", val_loader=val_loader ) @@ -234,6 +245,8 @@

      Subnetwork Laplace

      a subnetwork within a neural network (while keeping all other parameters fixed at their MAP estimates), as proposed in [11]. It also exemplifies different ways to specify the subnetwork to perform inference over.

      +

      First, we make use of SubnetLaplace, where we specify the subnetwork by +generating a list of indices for the active model parameters.

      from laplace import Laplace
       
       # Pre-trained model
      @@ -264,6 +277,26 @@ 

      Subnetwork Laplace

      subnetwork_indices=subnetwork_indices) la.fit(train_loader)
      +

      Besides SubnetLaplace, you can, as already mentioned, also treat the last +layer only using Laplace(..., subset_of_weights='last_layer'), which uses +LLLaplace. As a third method, you may define a subnetwork by disabling +gradients of fixed model parameters. The different methods target different use +cases. Each method has pros and cons, please see this +discussion +for details. In summary

      +
        +
      • Disable-grad: General method to perform Laplace on specific types of +layer/parameter, e.g. in an LLM with LoRA. Can be used to emulate LLLaplace +as well. Always use subset_of_weights='all' for this method.
      • +
      • subnet selection by disabling grads is more efficient than +SubnetLaplace since it avoids calculating full Jacobians first
      • +
      • disabling grads can only be performed on Parameter level and not for +individual weights, so this doesn't cover all cases that SubnetLaplace +offers such as Largest*SubnetMask or RandomSubnetMask
      • +
      • LLLaplace: last-layer specific code with improved performance (#145)
      • +
      • SubnetLaplace: more fine-grained partitioning such as +LargestMagnitudeSubnetMask
      • +

      Serialization

      As with plain torch, we support to ways to serialize data.

      One is the familiar state_dict approach. Here you need to save and re-create @@ -314,7 +347,7 @@

      Serialization

      Structure

      The laplace package consists of two main components:

        -
      1. The subclasses of laplace.BaseLaplace that implement different sparsity structures: different subsets of weights ("all", "subnetwork" and "last_layer") and different structures of the Hessian approximation ("full", "kron", "lowrank" and "diag"). This results in nine currently available options: FullLaplace, KronLaplace, DiagLaplace, the corresponding last-layer variations FullLLLaplace, KronLLLaplace, and DiagLLLaplace (which are all subclasses of laplace.LLLaplace), laplace.SubnetLaplace (which only supports "full" and "diag" Hessian approximations) and LowRankLaplace (which only supports inference over "all" weights). All of these can be conveniently accessed via the laplace.Laplace function.
      2. +
      3. The subclasses of laplace.BaseLaplace that implement different sparsity structures: different subsets of weights ('all', 'subnetwork' and 'last_layer') and different structures of the Hessian approximation ('full', 'kron', 'lowrank', 'diag' and 'gp'). This results in ten currently available options: FullLaplace, KronLaplace, DiagLaplace, FunctionalLaplace the corresponding last-layer variations FullLLLaplace, KronLLLaplace, DiagLLLaplace and FunctionalLLLaplace (which are all subclasses of laplace.LLLaplace), laplace.SubnetLaplace (which only supports 'full' and 'diag' Hessian approximations) and LowRankLaplace (which only supports inference over 'all' weights). All of these can be conveniently accessed via the laplace.Laplace function.
      4. The backends in laplace.curvature which provide access to Hessian approximations of the corresponding sparsity structures, for example, the diagonal GGN.
      @@ -970,7 +1003,7 @@

      Sub-modules

      Functions

      -def Laplace(model: torch.nn.Module, likelihood: Likelihood | str, subset_of_weights: SubsetOfWeights | str = SubsetOfWeights.LAST_LAYER, hessian_structure: HessianStructure | str = HessianStructure.KRON, *args, **kwargs) ‑> ParametricLaplace +def Laplace(model: torch.nn.Module, likelihood: Likelihood | str, subset_of_weights: SubsetOfWeights | str = SubsetOfWeights.LAST_LAYER, hessian_structure: HessianStructure | str = HessianStructure.KRON, *args, **kwargs) ‑> BaseLaplace

      Simplified Laplace access using strings instead of different classes.

      @@ -982,13 +1015,14 @@

      Parameters

       
      subset_of_weights : SubsetofWeights or {'last_layer', 'subnetwork', 'all'}, default=SubsetOfWeights.LAST_LAYER
      subset of weights to consider for inference
      -
      hessian_structure : HessianStructure or str in {'diag', 'kron', 'full', 'lowrank'}, default=HessianStructure.KRON
      -
      structure of the Hessian approximation
      +
      hessian_structure : HessianStructure or str in {'diag', 'kron', 'full', 'lowrank', 'gp'}, default=HessianStructure.KRON
      +
      structure of the Hessian approximation (note that in case of 'gp', +we are not actually doing any Hessian approximation, the inference is instead done in the functional space)

      Returns

      -
      laplace : ParametricLaplace
      -
      chosen subclass of ParametricLaplace instantiated with additional arguments
      +
      laplace : BaseLaplace
      +
      chosen subclass of BaseLaplace instantiated with additional arguments
      @@ -1141,7 +1175,7 @@

      Parameters

      Subclasses

      Instance variables

      @@ -1776,9 +1810,209 @@

      Inherited members

    +
    +class FunctionalLaplace +(model: nn.Module, likelihood: Likelihood | str, n_subset: int, sigma_noise: float | torch.Tensor = 1.0, prior_precision: float | torch.Tensor = 1.0, prior_mean: float | torch.Tensor = 0.0, temperature: float = 1.0, enable_backprop: bool = False, dict_key_x='inputs_id', dict_key_y='labels', backend: type[CurvatureInterface] | None = laplace.curvature.backpack.BackPackGGN, backend_kwargs: dict[str, Any] | None = None, independent_outputs: bool = False, seed: int = 0) +
    +
    +

    Applying the GGN (Generalized Gauss-Newton) approximation for the Hessian in the Laplace approximation of the posterior +turns the underlying probabilistic model from a BNN into a GLM (generalized linear model). +This GLM (in the weight space) is equivalent to a GP (in the function space), see +Approximate Inference Turns Deep Networks into Gaussian Processes (Khan et al., 2019)

    +

    This class implements the (approximate) GP inference through which +we obtain the desired quantities (posterior predictive, marginal log-likelihood). +See Improving predictions of Bayesian neural nets via local linearization (Immer et al., 2021) +for more details.

    +

    Note that for likelihood='classification', we approximate L_{NN} with a diagonal matrix +( L_{NN} is a block-diagonal matrix, where blocks represent Hessians of per-data-point log-likelihood w.r.t. +neural network output f , See Appendix A.2.1 for exact definition). We +resort to such an approximation because of the (possible) errors found in Laplace approximation for +multiclass GP classification in Chapter 3.5 of R&W 2006 GP book, +see the question +here +for more details. Alternatively, one could also resort to one-vs-one or one-vs-rest implementations +for multiclass classification, however, that is not (yet) supported here.

    +

    Parameters

    +
    +
    num_data : int
    +
    number of data points for Subset-of-Data (SOD) approximate GP inference.
    +
    diagonal_kernel : bool
    +
    GP kernel here is product of Jacobians, which results in a C \times C matrix where C is the output +dimension. If diagonal_kernel=True, only a diagonal of a GP kernel is used. This is (somewhat) equivalent to +assuming independent GPs across output channels.
    +
    +

    See BaseLaplace class for the full interface.

    +

    Ancestors

    + +

    Subclasses

    + +

    Instance variables

    +
    +
    var gp_kernel_prior_variance
    +
    +
    +
    +
    var log_det_ratio : torch.Tensor
    +
    +

    Computes log determinant term in GP marginal likelihood

    +

    For classification we use eq. (3.44) from Chapter 3.5 from +GP book R&W 2006 with +(note that we always use diagonal approximation D of the Hessian of log likelihood w.r.t. f):

    +

    log determinant term := \log | I + D^{1/2}K D^{1/2} |

    +

    For regression, we use "standard" GP marginal likelihood:

    +

    log determinant term := \log | K + \sigma_2 I |

    +
    +
    var scatter : torch.Tensor
    +
    +

    Compute scatter term in GP log marginal likelihood.

    +

    For classification we use eq. (3.44) from Chapter 3.5 from +GP book R&W 2006 with \hat{f} = f :

    +

    scatter term := f K^{-1} f^{T}

    +

    For regression, we use "standard" GP marginal likelihood:

    +

    scatter term := (y - m)K^{-1}(y -m )^T , +where m is the mean of the GP prior, which in our case corresponds to + m := f + J (\theta - \theta_{MAP})

    +
    +
    var prior_precision
    +
    +
    +
    +
    +

    Methods

    +
    +
    +def fit(self, train_loader: DataLoader | MutableMapping, progress_bar: bool = False) +
    +
    +

    Fit the Laplace approximation of a GP posterior.

    +

    Parameters

    +
    +
    train_loader : torch.data.utils.DataLoader
    +
    train_loader.dataset needs to be set to access N, size of the data set +train_loader.batch_size needs to be set to access b batch_size
    +
    progress_bar : bool
    +
    whether to show a progress bar during the fitting process.
    +
    +
    +
    +def predictive_samples(self, x: torch.Tensor | MutableMapping[str, torch.Tensor | Any], pred_type: PredType | str = PredType.GLM, n_samples: int = 100, diagonal_output: bool = False, generator: torch.Generator | None = None) ‑> torch.Tensor +
    +
    +

    Sample from the posterior predictive on input data x. +Can be used, for example, for Thompson sampling.

    +

    Parameters

    +
    +
    x : torch.Tensor or MutableMapping
    +
    input data (batch_size, input_shape)
    +
    pred_type : {'glm'}, default='glm'
    +
    type of posterior predictive, linearized GLM predictive.
    +
    n_samples : int
    +
    number of samples
    +
    diagonal_output : bool
    +
    whether to use a diagonalized glm posterior predictive on the outputs. +Only applies when pred_type='glm'.
    +
    generator : torch.Generator, optional
    +
    random number generator to control the samples (if sampling used)
    +
    +

    Returns

    +
    +
    samples : torch.Tensor
    +
    samples (n_samples, batch_size, output_shape)
    +
    +
    +
    +def functional_variance(self, Js_star: torch.Tensor) ‑> torch.Tensor +
    +
    +

    GP posterior variance:

    +

    k_{**} - K_{*M} (K_{MM}+ L_{MM}^{-1})^{-1} K_{M*}

    +

    Parameters

    +
    +
    Js_star : torch.Tensor of shape (N*, C, P)
    +
    Jacobians of test data points
    +
    +

    Returns

    +
    +
    f_var : torch.Tensor of shape (N*,C, C)
    +
    Contains the posterior variances of N* testing points.
    +
    +
    +
    +def functional_covariance(self, Js_star: torch.Tensor) ‑> torch.Tensor +
    +
    +

    GP posterior covariance:

    +

    k_{**} - K_{*M} (K_{MM}+ L_{MM}^{-1})^{-1} K_{M*}

    +

    Parameters

    +
    +
    Js_star : torch.Tensor of shape (N*, C, P)
    +
    Jacobians of test data points
    +
    +

    Returns

    +
    +
    f_var : torch.Tensor of shape (N*xC, N*xC)
    +
    Contains the posterior covariances of N* testing points.
    +
    +
    +
    +def optimize_prior_precision(self, pred_type: PredType | str = PredType.GP, method: TuningMethod | str = TuningMethod.MARGLIK, n_steps: int = 100, lr: float = 0.1, init_prior_prec: float | torch.Tensor = 1.0, prior_structure: PriorStructure | str = PriorStructure.SCALAR, val_loader: DataLoader | None = None, loss: torchmetrics.Metric | Callable[[torch.Tensor], torch.Tensor | float] | None = None, log_prior_prec_min: float = -4, log_prior_prec_max: float = 4, grid_size: int = 100, link_approx: LinkApprox | str = LinkApprox.PROBIT, n_samples: int = 100, verbose: bool = False, progress_bar: bool = False) ‑> None +
    +
    +

    optimize_prior_precision_base from BaseLaplace with pred_type='gp'

    +
    +
    +def log_marginal_likelihood(self, prior_precision: torch.Tensor | None = None, sigma_noise: torch.Tensor | None = None) ‑> torch.Tensor +
    +
    +

    Compute the Laplace approximation to the log marginal likelihood. +Requires that the Laplace approximation has been fit before. +The resulting torch.Tensor is differentiable in prior_precision and +sigma_noise if these have gradients enabled. +By passing prior_precision or sigma_noise, the current value is +overwritten. This is useful for iterating on the log marginal likelihood.

    +

    Parameters

    +
    +
    prior_precision : torch.Tensor, optional
    +
    prior precision if should be changed from current prior_precision value
    +
    sigma_noise : torch.Tensor, optional
    +
    observation noise standard deviation if should be changed
    +
    +

    Returns

    +
    +
    log_marglik : torch.Tensor
    +
     
    +
    +
    +
    +def state_dict(self) ‑> dict +
    +
    +
    +
    +
    +def load_state_dict(self, state_dict: dict) +
    +
    +
    +
    +
    +

    Inherited members

    + +
    class LowRankLaplace -(model: nn.Module, likelihood: Likelihood | str, sigma_noise: float | torch.Tensor = 1, prior_precision: float | torch.Tensor = 1, prior_mean: float | torch.Tensor = 0, temperature: float = 1, enable_backprop: bool = False, dict_key_x: str = 'inputs_id', dict_key_y: str = 'labels', backend=laplace.curvature.asdfghjkl.AsdfghjklHessian, backend_kwargs: dict[str, Any] | None = None) +(model: nn.Module, likelihood: Likelihood | str, backend: type[CurvatureInterface] = laplace.curvature.curvature.CurvatureInterface, sigma_noise: float | torch.Tensor = 1, prior_precision: float | torch.Tensor = 1, prior_mean: float | torch.Tensor = 0, temperature: float = 1, enable_backprop: bool = False, dict_key_x: str = 'inputs_id', dict_key_y: str = 'labels', backend_kwargs: dict[str, Any] | None = None)

    Laplace approximation with low-rank log likelihood Hessian (approximation). @@ -1792,6 +2026,8 @@

    Inherited members

    imes K matrix if we have a rank of K.

    +

    Note that only AsdfghjklHessian backend is supported. Install it via: +pip install git+https://git@github.com/wiseodd/asdl@asdfghjkl

    See BaseLaplace for the full interface.

    Ancestors

      @@ -2152,6 +2388,67 @@

      Inherited members

    +
    +class FunctionalLLLaplace +(model: nn.Module, likelihood: Likelihood | str, n_subset: int, sigma_noise: float | torch.Tensor = 1.0, prior_precision: float | torch.Tensor = 1.0, prior_mean: float | torch.Tensor = 0.0, temperature: float = 1.0, enable_backprop: bool = False, feature_reduction: FeatureReduction = None, dict_key_x: str = 'inputs_id', dict_key_y: str = 'labels', last_layer_name: str = None, backend: type[CurvatureInterface] | None = laplace.curvature.backpack.BackPackGGN, backend_kwargs: dict[str, Any] | None = None, independent_outputs: bool = False, seed: int = 0) +
    +
    +

    Here not much changes in terms of GP inference compared to FunctionalLaplace class. +Since now we treat only the last layer probabilistically and the rest of the network is used as a "fixed feature +extractor", that means that the X \in \mathbb{R}^{M \times D} in GP inference changes +to \tilde{X} \in \mathbb{R}^{M \times l_{n-1}} , +where l_{n-1} is the dimension of the output +of the penultimate NN layer.

    +

    See FunctionalLaplace for the full interface.

    +

    Ancestors

    + +

    Methods

    +
    +
    +def fit(self, train_loader: DataLoader) ‑> None +
    +
    +

    Fit the Laplace approximation of a GP posterior.

    +

    Parameters

    +
    +
    train_loader : torch.data.utils.DataLoader
    +
    train_loader.dataset needs to be set to access N, size of the data set +train_loader.batch_size needs to be set to access b batch_size
    +
    +
    +
    +def state_dict(self) ‑> dict +
    +
    +
    +
    +
    +def load_state_dict(self, state_dict: dict) +
    +
    +
    +
    +
    +

    Inherited members

    + +
    class SubnetLaplace (model: nn.Module, likelihood: Likelihood | str, subnetwork_indices: torch.LongTensor, sigma_noise: float | torch.Tensor = 1.0, prior_precision: float | torch.Tensor = 1.0, prior_mean: float | torch.Tensor = 0.0, temperature: float = 1.0, backend: Type[CurvatureInterface] | None = None, backend_kwargs: dict | None = None, asdl_fisher_kwargs: dict | None = None) @@ -2423,6 +2720,10 @@

    Class variables

    +
    var GP
    +
    +
    +
    @@ -2473,6 +2774,10 @@

    Class variables

    +
    var GP
    +
    +
    +
    @@ -2663,6 +2968,19 @@

    KronLaplace

    DiagLaplace

  • +

    FunctionalLaplace

    + +
  • +
  • LowRankLaplace

  • @@ -2684,6 +3002,14 @@

    KronLLL

    DiagLLLaplace

  • +

    FunctionalLLLaplace

    + +
  • +
  • SubnetLaplace

    • assemble_full_samples
    • diff --git a/docs/laplace.html b/docs/laplace.html index f0637b1..c9ca171 100644 --- a/docs/laplace.html +++ b/docs/laplace.html @@ -32,7 +32,7 @@

      Module laplace.laplace

      Functions

      -def Laplace(model: torch.nn.Module, likelihood: Likelihood | str, subset_of_weights: SubsetOfWeights | str = SubsetOfWeights.LAST_LAYER, hessian_structure: HessianStructure | str = HessianStructure.KRON, *args, **kwargs) ‑> ParametricLaplace +def Laplace(model: torch.nn.Module, likelihood: Likelihood | str, subset_of_weights: SubsetOfWeights | str = SubsetOfWeights.LAST_LAYER, hessian_structure: HessianStructure | str = HessianStructure.KRON, *args, **kwargs) ‑> BaseLaplace

      Simplified Laplace access using strings instead of different classes.

      @@ -44,13 +44,14 @@

      Parameters

       
      subset_of_weights : SubsetofWeights or {'last_layer', 'subnetwork', 'all'}, default=SubsetOfWeights.LAST_LAYER
      subset of weights to consider for inference
      -
      hessian_structure : HessianStructure or str in {'diag', 'kron', 'full', 'lowrank'}, default=HessianStructure.KRON
      -
      structure of the Hessian approximation
      +
      hessian_structure : HessianStructure or str in {'diag', 'kron', 'full', 'lowrank', 'gp'}, default=HessianStructure.KRON
      +
      structure of the Hessian approximation (note that in case of 'gp', +we are not actually doing any Hessian approximation, the inference is instead done in the functional space)

      Returns

      -
      laplace : ParametricLaplace
      -
      chosen subclass of ParametricLaplace instantiated with additional arguments
      +
      laplace : BaseLaplace
      +
      chosen subclass of BaseLaplace instantiated with additional arguments
      diff --git a/docs/lllaplace.html b/docs/lllaplace.html index 339237f..c43df23 100644 --- a/docs/lllaplace.html +++ b/docs/lllaplace.html @@ -341,6 +341,67 @@

      Inherited members

    +
    +class FunctionalLLLaplace +(model: nn.Module, likelihood: Likelihood | str, n_subset: int, sigma_noise: float | torch.Tensor = 1.0, prior_precision: float | torch.Tensor = 1.0, prior_mean: float | torch.Tensor = 0.0, temperature: float = 1.0, enable_backprop: bool = False, feature_reduction: FeatureReduction = None, dict_key_x: str = 'inputs_id', dict_key_y: str = 'labels', last_layer_name: str = None, backend: type[CurvatureInterface] | None = laplace.curvature.backpack.BackPackGGN, backend_kwargs: dict[str, Any] | None = None, independent_outputs: bool = False, seed: int = 0) +
    +
    +

    Here not much changes in terms of GP inference compared to FunctionalLaplace class. +Since now we treat only the last layer probabilistically and the rest of the network is used as a "fixed feature +extractor", that means that the X \in \mathbb{R}^{M \times D} in GP inference changes +to \tilde{X} \in \mathbb{R}^{M \times l_{n-1}} , +where l_{n-1} is the dimension of the output +of the penultimate NN layer.

    +

    See FunctionalLaplace for the full interface.

    +

    Ancestors

    + +

    Methods

    +
    +
    +def fit(self, train_loader: DataLoader) ‑> None +
    +
    +

    Fit the Laplace approximation of a GP posterior.

    +

    Parameters

    +
    +
    train_loader : torch.data.utils.DataLoader
    +
    train_loader.dataset needs to be set to access N, size of the data set +train_loader.batch_size needs to be set to access b batch_size
    +
    +
    +
    +def state_dict(self) ‑> dict +
    +
    +
    +
    +
    +def load_state_dict(self, state_dict: dict) +
    +
    +
    +
    +
    +

    Inherited members

    + +
    @@ -375,6 +436,14 @@

    DiagLLLaplace

  • +
  • +

    FunctionalLLLaplace

    + +
  • diff --git a/docs/regression_example.png b/docs/regression_example.png index cdbd951fa8ce5a0358f3747a423b77bff21a89c6..4b81bb5bfa50d7d86676d2928ab1106a7fc251ab 100644 GIT binary patch literal 27918 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 diff --git a/docs/regression_example_online.png b/docs/regression_example_online.png index 89d1a57c8b7cc27a6de011d49f2c6fe6cb3a5dcf..db383c945320a674bfae1e5eee06098ae84bc324 100644 GIT binary patch literal 28360 zcmb5VRa6~K7cGiQAUFhfcMopCEfCz@-60!ycY;HZ;OcO(7#MgraACv20DqZize5DRaXX8tJ1g0l zI=dM-nt;g}INMv>Ia^y861$o>I$7A+vN3WqGSd^AJ3HGu@h~yj{GSgn+Bupru|r8V z0FA)gOKLcQfgu}wT;N55g%)67wj5HT!piO$rT=tEMuH0 zXg}dNP$2Xm93VEycH|)1h+@II0@DJs?&XN#IoNrH4hRrotRo%H8_IOu>b=}dI|Rq2 z8ytiiC{8P!&yJT7*m+xd$R^l2owBYm`q<^r!$e8rBw=VQOJIrPB+1dFXyZhvfgj?9 zqcB81?jc&{qezpZg&8Z51t|a@B@e)*2}A?#;LJ*rBm)02^jrK>&VP+?{D7kX?ywg9 zKQ(cZFhB@G6jM~d2#OJSGH<+>o5`=KK@(Htx}8;W19j%*L5B4BV!F zJbWVv&y7t=>f0GgXnsCx4HM66_m)GG(wj7))API(iy6-r@Zt&2y_o!le0w=az8;Jr zA{ArLh0pi6lh8`w^Zt6j)ZxYJ+UgaP4Z2%0Q^W|0k4MXL-wJE@?p(9o&whWQdVkp$ zY(8yR85|ke?tDA$eAq|_lUZ~u^o)9!Un9O;uLy&qW4pNvVlNWe2&hom` zKnv?-9LV;(k}8l(7nhP6A{4xT*p6|!8lrOQg8p)%DA`)2POt4eCHCLtv76NPdbfiA z^B{-sdX#N;ZtnJ|UXr|c?{a{su&5}s^}HipECQ?AWaO7Jvc<;?Op`G-Z9r&hX?a|a zeQk~DGi1pEopE=(zn-68vaK}OZ1*4w?z~)2>;sqC_1+l0W?hj)=XVtq(}}Fl#6)QE z-~$QY1%{T)vd4-Gv!q>J?*ypA;yWZh<>X5s67VFZvYB1YDt&h$0^QE3T|Rnd_`E%W zUPhI^^9QY*?g4j9o^B2ii3B`5SB3Dt+CmWv3chc^FvaDgMtos1?Fs&@ZQljGXw5m! zb4-6oD8~XU3I4t3^>+aTEP7&mB*=?i^zY18^Yp{R!*}j)=->IeaLh9NW)7h?+OEg9 z_1>QrY|rKxH8nNOEi4SS`=ds)1+$?Mu$V2T$;D#`*S>xskIVNRAo9r=9+r;gyOIPO z7ku|rE!XU;F&X*6TO}O%G1c7nt4{DCJ#8;nBhId_S63rU=W`4#o{x?lZ%N|B>|%ua^e zKM(3~h`-eXgffbXaoU&#C^EpV8N&aBfRM`T#`s;}kvvBMPG^Dp`K0#V{cJl%FnZs9bh&| zu@PBqSDV)U*;!hWqQGrjy0^qwr1h^hJ3Tudph*oMYTjmo&YD4D0ypXkSl3Q3mjmaDP~h@{ug-5bg@RMFv!aTMih7@wNTuL?o>$i0 zPwN+4dEf3<>=LrGCr~Bus|O}By`K(WCf;9=E8DILDxD0Ntf%AEv8p6OoV@ z&{c~71Nw^Vw(j-yyWlIknvRQ#V6;5xA?Qwp_Xbw*0X(hX^s;?BninZ~qz{-~#-OTf zMcEm4C4RX7Q1nMovWO8o2}Z5zYk5ODkihIIuX!}VqeQNd5@4-g(wVAX^h zh{78Pqskh*J6-Vrrj~|@Y2Qrn83$M;OS*#SQQ`nTt_k7=3u|fNJw86J&23P`%l>7T z!%IxOD zf^=D-jvcGNZI+gnNQ2(_41)_oAc7(W~$#%s){a?gx_*kNY-ym13a2teTV zm`2saeqKpQcv>26O-;>{=O~(#-RAvsaamb@US7b-$;s>6%RlSQp~mE`D|h6do^qL} ztDFc_^3+`=CZ5_^`N+(232qCViVK7VdRd)Hj`#7Eme87mIj8Lo$pvrgvgC zWYml4UAOB_n{Twg+c!b{^;;1U|3349F7p*Sts~Vg$MY=4gRvMMHA`Vw**OY zp{$YqyE_zu9QBeAQYkk7DJZ;j$ekwZVnS(CgiV7Gg8m4mj=_&j9|(`$wEIizVVmfE zFzAbJ%25sgLVt}KQNj;rT?3W)F{IL}+xa7zFsN26^$`*=j)lw8uQX3#$Ss$g&ATM zs_h_!cz6c?*_8A zbrEXd@wts>Bjx47h%>#mQphnOAOHOO_~$(&gP@?`T+a|(hCB(boSYm6CZ-J#i7VCil0_I~*0 zwVJ*#C|V&>+$Vn^JMLcg$&vZq#6|+!hdg>APT-gsz*KLsmWI0+zpMM2BHHlWs&=pU zJPFw0b$w!o-|v(y1~oY>z9YW~g;{m}<2$b+(KEw$cg#8Jz?{bAhl=|I7L3DroXzed zodL-wOmv#bn7izO%pvV%%1%&&mAKdf!2mm7E>`vn05hxFut$3pY z21>20A`ESb{Fk2xC6yn<8J_!_`qRiShLzLT%=7x%34zwgAl$r4w8i6D$iUDZzYK}GrXr*g$cGq@A70qp-^ zQSN+M%E&ZELp55(7RYQA2Ku!pdMW-EX@T26iK496xyqNl|9lSYG2kOa{>ZRYS?-20 zf?t7_mm8Sl*v%X3z5>nu5Lat1P_F9SZ2>-})nL6@loy?wpC1V1%MiV{tK>5EYX8ga z0Z98kOtp)R0OaZUd2w4?+k3MK{(EgpE2~F<<$*WtXMvgkLP|qTO^osB63Acn-SAX5 zXV3*K8uD~59n9rj)PI(q)f^e{7jWFRkGfb3z74(rt)>9e5AdjemC;=5 zZ40cK<|1ZFGO^YYPtZfoK(dTy70FQ;Hf{A20&8sDPrn;UW`fn<>J0Vl3NLF2!lbb8*8Cij;!-vu)PSaPq-e%@>Ub;$leS_hq{y!WS) zP8;C;(~!RywE9C)$y)lH`ob|YfOwVZv|{;c*)|8Ad*8RNm3A=Nwq1(bww`h_cD^_s z9Us#$Fqi-z{a_4WiOI=%$Hfk}f6$WU@(LJw18c06>-XuL3RR5e#`xXX?kLA!BOT{l zGF3`d9d?t{909t1|KRjraK;#f*;Tr73+x)Q0O%ODZ`Ou_@JoC>do@_9F_F#U!$DzO zW6)}_KPoPCJa50Rv6!Lcv{~+r#9>QeHW0Zt6L^1dg75=#+8Z?(O<^h1tPclNz{k2i zn97@S$qXU)B8LQ%c#{52?UYAcP#y@l7_|*ux*x_9LO419TC2+ z+CwsRJdi3C%AdZCMt%J^$k4b7G06}(H#aAmr)WB!5jJLObhg^84LYr-0T$?1ohADN zSshH?Geux(x0YRdA3RmY-@F)smURnc-gT=~`F18*Gjib^DlZ(W4K?ax!|3_E za(q0Ccr_QDQueQHBRV2Xae2AP-O19b;|RkVNRY_qh2^~SUEqTk6W@_faPQ*>BjR*h z6lV52P4Fkz981Ash;`)_%|4SxQePGPhAq=ehjzvN+fBPPQR2pgW>|VZOc32w>m5SCz1)3cKq*C)rb#5-{e7P3v z2k{>PuGW!f4-XIauV3#+9$29x3gVe%m;G6W9bs&7`~CqUk_s+F4E(C3q{J%=1c)@Z zFCG(tKl9?6#`oAK2v%`E)HAsW7XxnnDG6nwnJvK>-wt;;tOiV>(<=K$DLmk}L z!))FrwrLL9ILRNu3kEqH*m-Pd-)|Mj+Xv_8i7nHBWFu=D`2&#Wk^oQgGxxvyjnVDr zFNkIa0;Oo1?dA9Vm#k>MsbFGYXhPOly$a=YkcpVF`z^$A^V$KK2u(`bVTs+6w>zaE z^(aRY3GHLX(Eb`oy{~p<;wXr?Kc6<{QGZg?^Kt>m$`ZnrL8A|1aA)#>Z4McJ50O;< zPwM!9e4t-6QO`(cQQ%~OAAAqsi*N~)a?(IgL4PeV4Q7iiTN8_&U)x*WydhBw<;XB* zEQop^10jQ2qEV*YpY8}&@lv;Y*I@mGd=Z%1V&5OL-#6#A?Bs6k$w5Lh?2e9(=9ZQa zcb!BV`gx^lMgWoE=H@onH04*ngH=&f@NLkK%z;i-1gX~WI;`m{Il zn3!1aHmmmAN|k20R|}df(A)~cLpKXg9()a}y%>q#=_v^!VwvXNX_HAE%KYr?h0pu> z`!0}@dp8f3=yzI8sk zYW?f943i0fjxT#(JL5``!pH;cH5g_eNoA#Og{FOhy=KSIo5`3`F!XDl7|0?jY)(F3 zuQQr?H*bHYG8=R=GBvKqd3$@irQ?T*#^W@d;&v!x=qvA`Gio=*vW;^Ybqan3-C1LZ z2`gd%d1QWjLdS84Vl7*%O25ndb^J~t<0+cC8Rysk1_+o?8yhtmaD8abft~!Zv}g;L z5?il#;k~!79a)dp`%a4nA;5!aXlb_q4QqV5T+jb>0*IpfQr^CCZPz7}*@cDk1;dT+ zK2PYkx3{o2&qqAnfrdPUpgkUJHn$znX8Zj=nOhXV(*plp{Heua8Z}(8Bjzm-*t>Xi zco(-u1L4*oN$CB_Cu#{x_v=2{A8V`!i8oS|wCi?3Z{h=s0Z_AVz3)h#UtX35=$7pO zAhg4Bsb4N*e2f9>q_yp<&zt8sKpKR04$ka`7kmzJK_KhfpjSz96**THpzeXz** z=0%PufLmUgfPAP2oFVndqkD1<8gJT_=+aO+nHsX!=JkM_pyTa*QawOTOKUh3Pl4|= z$^v>_m0@b{1#r7z>LXAv+`F@+Y2D(BfsH*Krvu=KQz z`ipov;L;OMARE~i05GqtMu2`WHt)o*MFV2f#DoG^kW0G{A6kFSZM}WrJe|d;pV4E! zz`_ymmaYM{wDnsQ<#*SYe&)aP$msDM9GDttfUWIyJBRPF z6SoF(1I&?+X~Yhm^3r9-1_aK@C9mvEep{Poa(mkc{RLvN<#@`!y902^buqa2#|fVw zN=iL00HaY@FixXf;UzWZWfMGC`fx0z@T{?tnrt_S^hMkOR#ydZqb$HAI5Prx55-45 z1TKgBY9LufCCKww#H`09C5bU(lgFVb)^FOUBjZt6@41fH!#DuelW$6&(n811yo* z?jN77`)1IY5fCdYzU;!Iw>Bz$I`z z{F6-Biy1ce+crggZglMb&oAZn%j`$5sEA~2B_$`HXV{xR9tjvN9{ZVYMHLnQPBZ=^ zXC9zSchBt823lI$#ReNZK>Zl>z;tgi16=)i-l0jGky1Wm5b!!DblleZfXxw6Lb#fz z_f-}xm>ZxH!~rINVVt&Eqj3<~3*X1aTm2SJSFtffmHlB1xwq@$;^KnEm25bNQ;z_4 z9bl7b)EL8;mzR$ME@S1onxbMCU@?XD8Ga!C?u5^qQ_O(l!)A!ny4Sr!KaLqQ=ILLrNUIoGe>&dT!T_8no z@Ehs3tA?W(V1iG7Qc+}c>$Da<6_dN< zbpXQgeO@kMU-`fDT|#ZzW20c2A#v}Z^he_K08`xgUF`_SN2_bkRdsdFmHQOV0qWgC zctWIb|B(gUts0Am0G2x}uA?eTFIw5xF|jW?vvljVPB~|QX?hZ0*2xqe9u6SU)BN>T zi=RQ7IV7=(p_y?N0FF|;Cs_A3oKY;3#k4ZlBOXwZZLe8 z0`=TCoY`J9m==SRcvjRXQD!;xZ#dXA^sF&Jy(6D0JeE3ENvaUP?T z-2LAMzPWUOQ^Jmx^QSqL8A$=AUsL)&RM8^EV)~3K*w9}9K6TGH6M762*Ay+LqKLta zYCFY@M2cls60%_Rzm7-D*cxa}b~PCUVSr%7&s$|lD)8u+Cq=Z#<*OI|d95ncf!Cs) zi2SczSLa-2>>nGFxAriYw+zCTFYv=o+Sss5gJ0Kh7S*WYBv}d53nr&=00RgH6Cgt_ z?L?&|hNpQIc!z->bk;(e9?R%>zTA4PB`G)<22f(fm6hjj@5{@}%E;Av00F9l%IkG8 zQs7IR@w2fZX=n^78g=>elNyX1F#zCM^FoMvTpcT=)qhTZcjy6qiWhO#F`Frn`%s@r zbZRvY+u|PrYi}$aD6fEG(p!;?wK;)RA2}}R&)3K>*MoB*iq1o4<;6v>*(uM5IFrwT zlGi{c3y7wIacTxX>ak44Wsz#H`Am-7%YdgffYShEYaj5x^vBXT07@UtwFUQf5hBR^ z^X5PqS&nq+v(AD>y(K2#GQxl8hSJIo!?_Zbwb$*tz>!@;z-38HN>cpsu#mOJ?s`2VvDo*#!522r>6!0 zMHWQ|F=gq`VO*`bI%=!dWUAI=s5-{K+ngV4{0qSTE{?GIeBL>MsixfpczEKZasQ>( zKy-P1pfgQtXUfRmSqA|l?8B%5vO{L$x_A1APdGk4zBcZ}g&&FcH5%|1*eqwMgFoZ- z0~icIbU{&(d1bTH2VZ3(VNk$;hKAOohLLPNlX;2bqO!*AXB?@V$zv&00q<#fJ#AHHLMv25^(igf^GW=GxjUt$R08HcmD|?{9 zO)_Q%IHSjQ)K~Yn$9)gLaW=QMUfuO-Tp9Zi&fHFvfL1l>4ul74K=^Wa*qA&|pF&jr zOc6-|tB$?EqNZkE0z}qz*_gWuL=VB+qF*O zE*H&k&3y^jePSe5x82tDBN$L@TRG;QGEX#jmVjE;PgRk5LYiUs0L1&lzTo>1;6g}B zNJ!j+7?UHoo%ZYjsr7;FY=G*c|8>LMDq91cJSGC-k|(b~E*if%>;-H(D_kC$aYuZ6 zXrdYRrA7Rm1i5nhrDb{Iv;*&n5}HWbE7lIa2t_en+N%s2)OP+jLaZeO?BK3BHNCMo z3Bn=3hrRpx@8$9OaqZlDA%-jgQF(b~sCeJ>3|H#&_GABOuGPG{NO3@VWJxq z6%VkJtRjWMspD^qLTmI?53qA^H~^&L8nBYk;Gn=R-1)QtO7T&W!*`igeBC;_d44rE zGb6faZ~dyJUggej`~4|tVtE!#|L%ZP9P@r_F`og@2H7^YMjCRk->%nMF&5r90iW8g z+;-=bLv9V^%_+A#nbSO4G;Sm-HSg`U?pNbz#jlp_IS9Ve?W>Ne`%%&a>TaGFU9is> z!eFgySq*GA-Z{14M;#D)pAQr#Phxf8O%l4a;*X~OaM;+`yu96a?&pLM9!1||FdIOq zX*)oF(RC-$wR;L1=onIUY9|k3 z46*mRzHIzz027j+?vH0URp-Er*`8PhlK}(Jol2`p9!9E@aOUs=zUMA`k1yo!W?CZoVS!Fh*|B7Y#@m z$7dh;+ZY5SI;Ms?pgzHLr1$$q}mtPa}B%m%NL`&%hw`2c?`Nd zJ@9hCzxywySlgEvp)Tx6bVwf`V`P$RN+7?z_yMLA;S4)Bu>9NsXelZwk-jyj;N5J{ zGDq%%??Y>{hP`-L9>PK!OD}>ivbJ)X&Q&ph!D#yhr6L|W?C;pxM_#1fhfVe0$ARCGD0rzNpoMbD<)La`f(fFh$6Jl})t3w@sNqB(zA+nUv`3pwp?-%(SG`}gYyGDvebN25{lV2U>^ z=;IJK=v%sW*h*IYp%7Nd!lRfb(eBRqWlO@I`PinOJmxd+491+t6BB_<Oydy@*Eg3A!R>` z-Yt`3AI%3R9tGQ@p^4}v6fxc&1_T}FRMh@FNt1)Ra!U>hq(Ic-8spxg!RN*ZQJU~X zVlw8nUw>3E^kbd-DsV39#47o2(iF_uUmD~|<*67vg%VfDqIdHzc5~LoR`wWC(^7X? z4u#x}4V}hmPg);@Vf*M28Y)JFwsRRt;}pu%6U0_b0tFHK-!+XW4xnF)Ul7@ai$2r4 zhCT(Eb2;{QgqeP!E0)bY7Tz!Q8y9CrGsGf779LO~Il<%kYZ>A{rJp9c&9nZzOXRT| zu)Ao3mDO~u*>QiJT?mX|-Cqa&IdFTV26X3_X`R!jF(%=%5z#YgO(#7FZ$LCj(?)WM zQbL$Bx!YgbuRe1|-oh{(_pcW`iBJX}R0Z8x9!nvoVJ?pMZycr0`!g1Tv5K!nZu%!5 zEh{qzgrXE}KGoeKsXu@Jeh~)ZZ@;7z>fS`4$r-AWZHWqk%=|pr0DaUExSC@~RBg=K zE3(Cws^D1iEW7|7Od>j|Mcd1S`h{^*6hm`9V)9`eCf6b0eC-*$(z5})uxDJx=Z#}P zu3}g_`GUB6yJ`|Y^sWueZ5m5t+)%(O@D2{K8dh=nsP8q`(lCZ^70FLLPU3*3+rWXD z-3L)i^IMfCfkX^_Z<0>zzq=|}EoQzy^i~d&)?7uLRwVk6J`CzQC}%=nH|@rZG)_ju zl{Toh(PYPtFeYF@rYbT#3i&8V${jeQwrSmBXvpELKe|i}=s6qRE4|R!E3qnOY$6O^ zwG>#fhLMA6XbuUu7bu=MW8h$>%O>kIPlEbIw(L-m14{fE@Ya}{F1je%YVyGg<+lIu zdUrcW$gNj9CgyYKJO|oz5w=L6qehA*nt)SrfMXv)|7l0Pfonp@aUtu4)OYcPhr<1< zhLHAIX2mqPsYAb3GpzkzPaIi9m8z_i9%wOu!Me=OK&LjuF%L)Op6c8IogKD-a6kKv zh91cz&)^~fHB**h++Sb&1P=-AV??eB0O_!@>| zD%UB&eOqIt#z#+_>L=&sz6N#lVssZrn|u?D5#ZQpSk>qxh)L%TZ5^1xUo+y(fq4I!bJ%tZ`xPO zoyMVdy!Z|#Php$#4f=J~rW)zV4Mh-Ehr-jKlX%7{(p3QltDuV@&7gI`Mbh4`Py~`$ zdJ(w8G=?-^TFx1QW<$)wQa_b=;N z`qv=1e;{%AeL_w0yWm^`L%qQ>`3cNQ2sTW+un%U6Gm@hH*|^_Wnv9}$^dXw;DQ3PD@{Jg?<+eO_I} zqw$A~V)*A}zQyA+>r5GzAB$; zw*~q6qxn5QSv1a;!1VU-0qSaT3zGE8+&|cIR@3uX{tWe=Nk!ek(Mn4$p; zugZwZ1y;x0Jx|S5cw?lh2`Pp(vbZ{GL{31dr59D=qo%$G6c#>zUHw~UG4lXeiXbcN z_*a8{=djfyV^*7xluhpIKvYp4VnPEgt;A=n$CP_VUm^xXrdVgDq&&5W_>4!|59BmOrUFmM9s}D+2p2^=)DtknU@qm;~ zXtLN9ensSQP?SO!tm}+1td2NP7(=Si-qiif34cCCoTKJ%!r1X(I4zm3vU2*f=%?0oHcJM>fZ+HrR6^u(t+S(cv9-E#3& z{y024xJH*9wJ^k&mMB=&Y{{0}f1wGTQ{u_Tan@;EV>nsc!l+Q-N1{#%@BV`TS!Tgf zH2A~)4xdVu;qdAQO1DLIL~>Xp?ijIShAL1c0M2vNxK^a5wox5z%X3<<$UC%wYijk; zGS7lngDI}*`>{m0MGcX=dLyP)#ggIVvfKZ9BH5lRZ+)8%B}!fnGrhe~DHX3aq8K+g zG(m6?=Pcb8!?0o~DhN)Q#r;jqS4=d5RSWgiz}r+KbS={V5QEgRIt&bFjMmx!MJ(#h z5;^L_%O`q&7-)Ogiuf=LK8{L4K?Ino#{B@eGu2|7s&W)OdzeNU141r=wK)>&DO2Xl z#19hx0mP}MO>Dfc6Ae!D>Ikl%1(pk(Zt_UHuT293Av1?p}wOQA1kDkdmwU3Y2I)+%Pvv=U+XBRB*Y%B@KVV`}&kV{ED2FWo?5U>(fj zS2-+-qM?>dN<|NW3j?#lGw~}>u2mihS(rE+%VdP!4+bAa{f`T%Wki*f$fhv+0qm5; zgK|KX@h_k@m$i(3oxqPV_A;Hwh)3ZXZu2d6&+joy2;%0G=(Cb*Z4#}! zIE|u2W!{4w@qB)J&ZLfEh;SOn#V*xE%zDd0Z z!e)>yz0PSMJFk`|g!NrBO=B>zL8#AqQTBLK5HH&Pj4aX;RFfzuGwf(jr=xMk`6`|z z!7Z}5%}h4u-{|%y8xlr}PjE4zShsQKka=br;Wdl@a zdIZr1ATJ19s?`r^RZ$tri@GWCxwkw^A!~+VRb~%_%i(<9pVzmqADe(B_EDQSJUGw? z%1V3}e<8KKA9sNRy1b+5U%zt>oqmr@2@R}mCBf>~tNo>vee@Bt97&VQm{w7Hwc$40 zn5@lBy?u9k^^IK@_;Gh0QFeoHxKVY5CQ0-bbw9D!$tG#hxB`Dbh~L9ld#YhTsK2p` zE(a;neVPg!f}RM0r`ibI#HtYJ&dfM%`MZhgf50GrMwO<(r;33TtC)u)ma`xqAlTi| zKmZErkn}gn)M%Q6b0tfq&JIOAH{bGpbxs?~@kOer^1yM_K+pwW`O*qonxM}l%Vbz`8mW+vr{#KGL3kN$V z&0lDh4G&(&6U1+>$^x#Opg7Ns8LKv?ACAj^z}IcJEg|@X3LInT>3YGH`aYSrL4#5I z_pW?P{C>fy?|MaJ%2?q@@nPa#2LlxU^*Kv{eH;h&58)Roe!{KOF`h3>p%**cuIyuJ z^hyoViDo}ANhrk;3tp>yz74uDQl8PE*~;-#s&=V<6%AOuunnxl{rpM$Q%vTjX#HXz zVJJTx4!;>3%S5sN@FBCc>(8JrnV*3wO4Sy$dUFqhZY$NA7y|3l(xve-^<;1Yo%WYO z%kBbvK~bjMjNRHc9$655o%c+t%9K?>dRkd~S-srWEHWOFf&tl9Oa_NnO%IKVXeY+s z0@4juzAD-l%wwsBNSjlMa?tfX&@)Pky04`S^VFj8vUr!Z`->@wZlsSTt%?BZk#vtf zm*0(?WC9Luxk_Bbn791-M1xD=;Ch%9D3^aMCa+g3axB;)SC+5{XyVD<>k(cLPY(wni$0GDG1(<}@`y zKS3N;mU$Q!1V!WY4h&(`x8g_$QDk6ELZD>Bxfu5oE5pw9z5a_|(3wce%aMHZXy^oaT?_L~@A3%?Jemu^=;K&0uMZJ@&PyQpfMDc0P|8`;pA1xYmuNH7WWBlj1S9 z(M))gT2T^W)0C)ylX>Fm6WBR!f`)aZh^S#d$*j0TS+tEf%ZkW+;-W~m&ghk@r06$y zm+UGlHKgF&%M^iRC@f0z6|U(98Vv&)oJX4j@?3+4z|*E}o6*bpt4zzJ;%|TzQk zEMgh#9f_MkgqABkP^4iUodp@d#ad!?)Fbcf3d z@%tqOi+HuIVroy{82yKPLvtg(H4Xt)4Mj4(J!FJ4E@H`>1sbQm5f}ilN?; zg6JG!n^xc25Z}h z>T*-wKRNX%=JK4|Q5W*o^mtLM_`MH)+eV7!Qd9AVB1l_dTv}ry!5Cj0wd*qt!al2W zcGO2OVEjDA=P&X77Q8c!5ju&3lR|^}0}d8Kr5i{U2DaOjM%1Pa4YuT!}j+;!fm^=S z(2kkJm%R`mbH{LR!TA~fiZqCXK-kDn<=2~^f>4x-vF6{zrrM?eM} zI4(sHkRv{valx8>mscIM-wk^e`p#mk7CMZ>ts(*?T!!7=XGj{y_z|UO)GsQrJa}E9 z*LGeoiq?oK>8XchOAbDznm^!dhTs)Bl*dqPhW+J+68()W{ZJvv{7QP8ML`634)du= zZFaKaW!RWyA{JqUeZ5wOsXnv)kXmj!oLA-UA1I=dt!r|221MwMRH|sJ<`Mv~c=t;xy&Zi_o92|AVGJxaz^moV8{V zZGxhVytGuEfV6~X2>(__oOUJ5a9hJmg7~)>i#@ubiBsamuZibbEW{q;zP(e?T*Vrj zP|%_zN?$+QR1Y}UP)E3-1cdhE1_PuSp^X8795M?(mC#vHYHM=vGZx?yaUkKPg^XC{ zxY$8Yu%XZdrbb$XAKkz4P~(qWJ#kGiV2QZTa4Q8BQIK|1Y%%)#$1%UP<_hKzqJH(9 zrP5A66R8%|pTMG{BJ(?tB&o9abnhjBJwPV2MQ^w2k^MJNvJiWu5ILZ;1Gy4MQJ89x zv_h};a=o&C5^FkDVQ+8Ps8rNGl1yUMdM$|gjGk*pq#EL^B&+&*y{cC6Bzd@m6(^FW z0Y=0oR!6urZcHMRG-&f?wcOC9aG>j`x5`Xu8(XaHMj;woWwclYRlZ_2Rf}+cw5;B< zuqp}FI!}rwH*VEfB7vYnNX75m$}Ug;B8WTKMO^G26!c&owzOE)Ui{t0K*lOo&c;Fd z=E<0jMyUQm+M3m-AjFen&`sMaD9S9!FBe5I!qFJ)KfIW%h@giSca21JUVUL1}#b#%b$ck%Ob;;rXjbE z&C{i=R{SNye(NLBD`ge8m6L3a*>3J_dTdJV*X40PwvwVB1_xD#I_g&w9TDA;uAeUD z1BFx`atYtAiWeu`H$W8Xqbc^6nkPe?GFTTo5&0fw(FeTP2%**e5L;#v(Thw;&4H;A zcD%D*sTt%Pm(up^JhVoq43RaB5g^T4qdn!?HBSGs?oZKpsUy9f(BF+i7|g?^!WM>E z#>Yk-ZG~!=i&+p{TNa>`q}c|FM!?;rvjYsmK@uv&5)rkuisJjhVqS&_nAYlOX z7*l`=L=gZ~5b%N|Mo3Q=PzZkj-cS3%pWjhf3qIdTaR;5TelASElzNHJIiH|3#n6ReWKg*Xlt=1Jmd*Y*k0t#Ez!r&F&?Cp)GuxA~Xl%sKf z$%Qf0sc9*+2SwV4q@Jz{{ldx#=&~T6Owlhl`D7&qmYM5kTKMmWyrM0q62YyxoE}jfgF1WC z5GFU*DK7A`Q>Bhp$)G!l=U%E=(_WfY6Yv(9dW$nn0@e3D;BCsj zq_{t(ns&qP!MXN}rXnjDQ5kbZYfdzW$Twlap4>V&bvz8~^NUD@#B0M896|HZ&IqNg zpcrHG=;6v}6hF334>}QTwZLkeOJiRl#4QqYjfGZ4r_9e6ed`;?K4D8%e7);fjTcJ| zD7vk~nT1&4*UFfy6y5d5G-y8A6;<{={E>Wwlo=G-z3Aiqid2%Qqvr99iu|-t-xVLf zD>3qXGFk%{Z}~?0r#lqAY7g~Vm9@QFtorCUjv>*Qn`>DoV!=?MFe$9P*7&Mj4c@7x z1Skrvih+VP#q*>Y&~IR zY`^&-$uY6tw#lH^`d7xhYP{KJoiL> zDUA87Rm#m!6uXAaE#&x{qG;xrerZw7)(T^;f*hO04OqCnmpBi};$US=-Sx#62hN7{ zm)jBSYb1_@*LM`Un)%yUrBvRRv)Z=?oKYT6a!q^bGk;d;AJ&BjiC#)xTr zs+6I2IXO%@H@9e{(@zL7&iNAOTvF$gNna0WV7?X35p8TY(1Xb{-TFDfiSn?VXs|bh zI1JX26*JBR+TTrLh0lVq5v;f~ai*#MN%1t(mK7l*7*$QaY+y+;b#x!e=%?8$)IZum zF;nUu15O7>fRghfx!kpYlUI5bE3###G=I8w4X+M|$#5gCoDZi=b0UC$w!Cn%y3ef_(GE(v(Ekr^wZ+IR?UZ#;9wOIAe% z_&!3F?HS)4cgvzPr&7i^Sh_d=r2}H)B(I;@z&r<~I`sSKSui1m_OA-QYKybsl{M^k z3g$}?^Px62C&DLj1XP#(Pik>}j3wh3(J&E^F>;&1MxvsJW9JfZeXU0vCBBSM_Ser< zS7K8nTl#mBvgnq{VXq45YLO$UBk!Q{p!wMG2Q*m0?4%RYxX`c--|lJ!0h5K#KB=TE z%q&}5Ce;CrDGSRZQ*uEpXT)Uuo5rAA;wWi>K9#%_E^_3)%+B=&g}6WV<_+1tTa?C3 zXg1;OcvyWKvZrKVx--ZW`mSPHw29Q^)}cR_Ixel$pC$qtf?RIB8*G z1Dq7N2uCZ-knmK;?-#%R7NG}OQ4?aZ_1k0%7vX4f3RekZCzC>*UsAqsaCo&5#(&o=3zMI+*NU3PW_M@cLi4>|m8rH0e*kfnLDh&G?nQ0J zIzktkP<5S~Xkn+Fn@V;>0B7@pcbY-FywB;8x~PP3z#%y*Uf$Mc6%CElBa&0Wacxwn z>7~JQB5&Lo_Q$i;RM|8K*&1*QA*je%pLU;G1u@jxofF3*9(>Adgm2OQ;l&$R6;v4> z8;t$7Q-H0aj`{D+A@Z&&PL`fBwYDfMDW}!^T_(ka^Y4|}#@c!hsIjXAnpDDJ283NN z)4WAA!YtRMA0D#QgD(O_z^%Xo?Ktd~y*q*t#?MM@-F1dKHMQxgyYdNM$v_z?l5qn4 zUW`w~s9P$jBQwW_h$xYv=v$28aH#a~Dz1w|<%I&5lcEZO8HHMq9iEcKSN^s8pT&O? zPJf}z*HNTH68SQSc6bI;R0>GDkEQQ$c#Nsv@>FIc7%@-v+nR7xWhtr@@9qR@GXgeE7B zV`EKrMnXEIQ$j$5A%_;E+W`SV8Ug8UkOt`xq>&QPz2krPoIPjv>+T1RN9G;g ze(!tleV*TAnbJ@hA!Uck5satLMdCnr!kRWl6bJJWqUM{+1S!A`UN%>ug^$pC;%`;R>c`E_u4Rk;y{oAS93GnN`E$z~JD*R!X9;%GGzBTuTUZF||ax z?2;P&>lWXFlJp;3Ke7uZP5Cz764Da}?+3nov+{3dcrqtwQMQ}in z=&&dWtE=psiMN=RF+Ay9Hu#8O6CHK+RU!F?$B$)@l>Wvr5@hzSw9rLIt@t_#+FTDb zeYEv(EqIA=6B|GtJ#(jy^r7H|LB%vIh8FkUZv7Z~LJ?W}Q+UCX6*a$#vRSA60)IxU zp)-f!-0(yR5`N0)QlCn!XS~dl_S@0F7#O70%M*RYN0VY>!}Pyay{P}}v!$(nt1Qs#?T^CF}+{?Z&0+z1Jhm2f30es49xxG1r7 z{}d3Nl!7BnaYwkkGKbloo~)wP8Ebw?P`4$8A;0saWCczmiD9f+uHL)DK1IQm!AZ=D zCn&?wuJ|EbX;3~jv&&EGS+w6?S!ZUxRJuU_j6LRysXpP(pM8_4#&fl|R+5)?YgHjE zG=ycM40wxUQ?ob#B27IFjR?I73#x(1RAz&~%v9&2{>F+6 z(11J;K598@{8`c5c+yLm&TE6rk=_9BIg6ZcZ1W~kC_L6+AOX5owx>0#*=^Gi_H7dO>EAX54~$2OE&saSQChY=2x~+$_8Fe+qL#rRb|02|$NmD>BF$}7 zn7uF7jhPaIWpOu6zPdc)puJKfDbdLV^R#Eihh!B5A2t;#5}!caQRTPyYbnCa>R@{u z$)(-$dxdyw>2BMa76+>sdYiu_9fv!0Iq4O9r`*%DqN&_d$-9hN@^g-VU%sk=8FsFg z;Vxd;J3i>yCKU;($|G>?Lg`vf@8(!HgcLe$X?h2~>UeEBVXr0(v2)C8S5l@g^879+ z|0uu#x7UYV<^3oQ1|5}ZwL?uBX?dZWJo;>1_RSs zxa;P#FGmu;UlJyZq!hHh@DZ^#U}FCw3^6txj>jkNAZ_!nL**kPaG)CbDVJHYEnqoK zh95=s3>>6xU&9Aa?R~1~oy-_69zL45ZD{?rnK3K(X4utk{^PKI*w5+6==s1BJvg0f zS~-NT|H?iPn=&(Wj`N9~8m9)$Bdww!6S(fns-J-no^%~0s1eijmnUlVbe(#YhW(yT zhU-2(SiQbdB|2%eKm1u4v3=fn-VLo_};W`(X2xbh=<%@{ex;#efjsk4nui* z`6QhjU z{Ki`|t55-o^`M{={hZxrpRWlUn%)@aOkhvw7au}8!8K@%Roa{K7ju%3CtbhvG$!4& zLIc{Os`CI}_)Ko+T2bN1q>%Ao7vAmX@^Ow>5=0Mvsi1Z_$=mDE6HPshE|qL}$mGhp zL3J=E5USqAe0ZWs$&yaHK_?fQJ`@qfV_8j#&3O4+mtR%6&=^8vst`3H6*b#?yiPUv zjD~)8Wcx9M4lje46Puas;YkbJU$S&(B0~#N?;$tI1j16k8sBUSlUT87FxVAUO7^ z?zpoQLi*^Be-m*`X{2R;^plIX96pK6>;2(UlaJWRNyN{fxcO=7HWkSmz55i9S(<1q zEp55OA19U`Q+@TCwbu;t0_9dl1rOpUqAk1K+0ekO?P*aE2lhFGFn`s(N+{VqYsk9f zj1_@X_sc42{lv7Xx(Zl$CGNp!EXCv23s&@G6^=Jg3Y7Fzs)Js}*>ipA*3dGUH>IkL#QsF)oo%; zc6^HZve6+!ju=h$)P%Kk!L^=yaOSOnYoDEeH{;0mCgetbFopEKu%G@j?WMn^xF>T0 zVFY{bYkL}UdG1VCJ}$M6FgdtXdtV{74occ5E)dU0P4Hm~2U-X->217E;^$1C#;N9H zVTkq#>jQx;3dr_f1Fj7d3P@xT1F3>4Cy@kPBl}oxTQQH)d+_w}E6O=&giW0$|GK+} zeHh8WFz1$|=MLvuQZOd#XcB_LaLaTeGcDitgdaXx@7xgu0qIoQ1t)*EH<=3W2@t;C z=qGiV^{oz-qNi__1$%o800!|^Uv`vYRSp~9e7pCTs1py&B47pOK`msb;YpeA$LwDv z=&RgAynGmg8uPuQM?F!!sz0rrq7*hX$sdM7;m>g9jUY-_5^(RL- zNAQ~p;X#)3weEf;OQwd9u`;XXeYn8Pn`s8-3d3DELxddf8RZp3G0;G%p(ms*- zv}F}dPo`yw45{d)m$wORW|sy6MHRSM;=MgbeZ`vYkx5QVac2#C@_Hwdm6R0lKR+N7 z+bbv~{cI;IK8#yAb@~Uv?LsLY=tAnFMvTwT_~=&stb2+3nv#~ldbs@fXP${_ z-1x%?ImJy)L?S27(_bJVab4vM`QYORxkW+03TdmH=6SKOuzW$PjaJ*d9-W?HHodk^ z4U2(wjbwh-o%AtB!&ykXh2Hgv*0kY;Irc=D zI@Ii0jMOA)bvc$5$9XNg2n3Uw&X;+|o>p5<%o*{%kG_U`*!r^p{Vs)CHR$WmkUi5FtoXiL+y$L%o&HI7#v^|A^G(eUg4)gw2ZwUGF7*iq)nLvd`GT;>;Z!$e zKT7PdF|;^0h$5z^6XX~u`1xHo1edhAZOdHq_kSd~A(|8(LZc__{=+WT88CvmV2W^U+Gjfi*URY4+y) zdM$H#K}%l#hGv0@iyt{|woR{F&U8HCE{QFDx|kywd$*zH)EsVowdnKizunuG1>7pe zqwa%bouuV1$E0AKve3bY*+$`WlSde&_#-FaJ67Edj};~x_+a29Zvjy3h^z1dBv_>z z)!2UUm0OY0%5#e57Pq4@G+FI`RG|%hI5L>^k}_D*=oiaPu#uo+XqrinP8kgBrO~Ktg%U_F0R6_o${~_o#O>a zn_DIm_f#g=dE$BDYi7qUo!X^bQI`ADU%jsJ-Un-t*Ro#Zuz(x9Zn@LR4`AU<=N1F-Zgux*1@TL1+}wJ#D+?eQ)A{iGpOxfc&9y@a96^K*-e~r=%zs z13SNyge${M%z%cnkgYb>cp2N{TL7VCnGondq+s^kQ$=PJGa44gP+dntQ>=s5wehU75Z4Q<|Ogy?r=5 zlv=8x{(SN8&v!Wlq1;O(-o($UTHc}!%-Fg|dX2A_&_C_#_0^zJwj-STwn7?C=5IJV z7xk3tXytB^h91T}f*co2OiCvcyx~kF1&S-X)VtEULclS`%ob- z3iBc9vZGgmqEpBED6zCD^`h|d>7#i>uEKe;p_Q(iri9<0GVUCKQss6cW zX#1eyHrzU1*s19m9=Z8jD!ZT7%eR?*+(dF@bV8Quw(XT{OD(gql@vyvTIe?g<1Z%= zbYhj{?1L0*x&yffS=XAP4IVi;^mK-q(2&{umm8QGi3GyAko7&{c@k&3C7hGj_Yaj=wie6J zMK4`FE9;7=MMUHszK&8o!aXWiuMDHa!3=w2j6{H*2{lJUu>N$8#dsVyS?SUIt=EiO z`O5ksjy$pNe(F@EU{bv~Ul;tT&xub=grb{RoP9*v>im*9BP;)%3F7N;Pid^Y$GsGp z1-B0|I!_9u9rVdS z;&2~Q0Z{#Bz1-q=i?r{k2*XU9U%V-SQs73v!zg2)e(VSp#Ab+T5&pD0+hc}hf#qOtzY6@Xou|Rq*wF=UfJj3UVYcC7UUseX zcQWyqglDOYXGKZU{63YwkdkO$f;48!zg<{q1sUP#1QSISCR%m9a__XT8(2JXnNSm@ z_&WlRTvpFhEP1^LyS0N}|H|=vcqzBU&8oQd$DB-T{_R3*I_A7ZmJc@d41JZUdAD3s zn83V_CznK_5-Bh z(CVcHj`4gEyaATTL?c-D07H(*muiVjkCRtP!`iuq)b67rr0bF<7n z3_l+>HN7B#6Z9So63fiALcLb?N!)f~3Ob|d7dYp?f)vAF&)0aXSx}t{4p!MhENbK; z0whvN&xx77DwqgeT^e||)EC?%X1!SWa+_uWg4~W~FT>VF)ic9|)M!fEx$3zEs}lTQ z@YMO^$yR6P9S%`f{Pi^~|5H8K{iLdf5U#J~*15-6VvO0dPGw5)!R;6Po&`4441M~c zi~j5@WjZQ&3jjH8_wAlpEecNP-RzZB+Wxt{7N$xM&^Zb(h@5onALH&+<_Q%pwLy6$yc_}Cpg-5U`V@DT=blrM z_eYyAd#yCS_G^u`-m2!;Vli1aJd%V;x@raAaMFU;w(oTkCQIKdL zDi1FsJIylRjD0JC7oS011%01SIqOa(*SZq5) z^td z=67fM!Yf#Dp_6q>LIzjGh^XFTm3h$?%T0-k?8NjBGhX(OT-hY3a0VeD8EFX&Gn6jmLYBlH6_^7 zomOzxQmrRn%P>BO|4Xx}f8cf*ws=!f)>!l+irGujWTi8>wc?1YNxZy$#4keca7N`= zid&WV;iO}*n}%<+mZ^v;O;WtJSx>cXwiLfq)ns^2={?c#=Cqkka<9^P_(xVte{UMD zub%A-GP9*_Y82&I-);{FI5ILbug`M-4g*72LqP!@1%Ps^abkz7Mak;QN7@d7(v7Ba zQQP>$Q5TyrtdoXPMS4GYw30X*l!xKXZs+2bnn^ifmYB@L9qkM)c;D(`S!@&HMff4@1c2cJ zO;PLe#Nivl9iY;lApXJD%<{GC*~p~h3L~L<{d3Tts0mGIbUB{Bz*{z69L@+IJ>0Mn z!BfxC9JG)<8~@Fkz(h35Ht6xIYc$VLG`Yn)>ZGbNvI`*(hsA*8Gt|CJGvf_pk z!RCQLlVZIx@8(vU0ZGgA+k&lg3+k-Q`oYonlLu?k1xgbzx8_R%ov;%d)k79%irWee z66!x2fZk~MBY#7q_e~T<w`T6-F)z!RQO+V=W+_e3r%=~nT!vO4N zfRY^_1^>;o%MDEJ?d?6hL=uDXLBAM+z&X=--gGJH5Sr?W(DIFeW%3h}hCh>%=|IQE z>@t_tc~e<`a|LqS5Avzc>1(p}p$~K?f=)1!)SF4>#$5x8*Of(bLD=B6Iwa?X~eFg%O`cv0U2096YB1>N_e? zCo<`R!>lC@u+#5>q5`ySB_+(_9RDYFIeyG6S#C16-rv_{8@-j#HImY&)TpiaFJ;*vpkGX}rpK`d1li&C?>z{S>VpGeJT09~eFT?&p=w zVxfn5u6;XaiSJ*Tuk}6yLwG*deuMAWvV0aCkUy%Kf@&4Fc%;xo2SV~rkUbyv@|E{r zlhh4!4=7$Ty9Y#nRXr1nE3q-8t6;6(&QQ0$7ABGOv!17PZiviyalq&Kjlhg$JH{Gd zOd5|`Z(6+tAV_}tRV~WN%^eDyMj``fe7ts}RJJ1-P-$uD+&BYzC4qn%7=3)KyDT9^@oho@VP`Ckl*LL|vVC?hX#6V7VA?EzoY~YwSFM z({wgx6(3lJ?Ws|-3UI5}lC(xfp)84dN!M3*LDe-i_*cu{GdVd7TWA{kn&UMP=$X&& z4^!xM|48~pTUNC5pb*pSt|_F^Mf1mj(Sy^$Pv<6qr*!B}*bX}soc}EP&k8#;Gc(A8 z1=O!z@Or;c7%1NSJ??u>??Zp4q#*ia=X}Sy)oPo$KY5$R?u(r8r(^42IAOEtli_bV zNrnTHLWvLc^{HTUb@cRlz$Fj$^yC9_DL+4dk-t4rR8f2s6V5&d0NFYU+D`G zsX*p90-J4z<{qsvy*B~)Zoq3L#-tE6My{qwT1ABbC0lOBF{oZ^CR%XgSg=7aQZyoO z0qD|~ieItzDOBR5YBsNpNTUk~qM3gGdZmOU=g1Y7xPO2B9a;33ZOomwpkFq$&DFT> zzmFp6FVWHOMHg^a@MFh+mr-Dyv1AEN)#S~c*~yr60VGw_BuYh>Vr`&niWKT zrTfi4bBP?Ln62q<^E_5-;2vL7w+eV&(6L)7()sU0C?l5#hAFS5*EoO%({vNngmWHe zjJMsP-u!dClC;1kn?*oL7ip|5PqQ7weSEOSAQh-Sv-xZB`@{uN*v1hZ%S+!!g zgEop-gKDW%^WX6UON5FysAeZ%$dmYi8=e_KiGD8e56tQ{Ph+N;PccjCF8!$baqt7{ zP>|-zzp5bCB)r}-)qD?W#FE*o@%P03+p#=$?@l(D<|(fH`+r9_6eV4hZkPSP4(zmp-&VUfVD!@?N&=AVd22$mPiX zE$0vqw)Pj(zfD{qjvYcS#Pc|en0_IFY#muj8kn2!R_22Lb#Q@=l3l!tpSf(Z!eLl^U>*2(YqZ zK-ORY^$^;(JU;jfBNyS8MyM zTs3=9W>6{k7c}AN3N(I2>57b??!X8Dg)`p(&+f(H*^O({F2eOL=sKxV)qi?wiYnog zl5s+1$c3n;v8L*o6jQCM{r~nTgCiLg(Er1P&R6+W{1nYVxP#gA)62HMpeD-QHb)~+ z`RQcCKRYi9f@fL44*hS!wiOLvItmB~fc_%bW%RI?aMZ58&m?%1TRpuID#SP`F=T9n-|*Aq&hflIKd&fq#ewIufebJ6(CbevG3=L#h`K zmb|{H%^h4wLiARW|NV_!8N>@&L_F=LKv6XOI|H&#O;nLkLWLHxn8N?Hq>UJl*AGn+ z==_#9h-Cr&;G0d*twi>2gsJdshtoQc?<{+C=V>coD5?4GE7+CfJ&S`Be95af-_*ro z!RrpV(mLKgY;JMQUKea) z|2~`rLmp?Kx=ZE1AuA9cg4`J-@i>so;t7bW$*HM#d->;SKnOcJy+m3)An^Dr5e{0q zxF0V*7zLtPX#+JWu8{BKNRw*4C&s<`dlrC*!LA0;I2=88&JP}7G=6i>79U+V&G`+l zbw9z`a=;OA;{1`)`v_1>3vTR8XGg$Jc!F*y8Ju_R*(^jEFoc$ z`tDsCDEMJ_Srr$D_YD+_(2zLS#gg}RQ#AhZf_I)&mGA68x&ouEU&FQ_2^$+5(8|J*4zTlL{Re+V zbfhH*23O{`Rv5&@GRgUDt*6@hMv?16i{_Ntp6`02RC0t{(X{sjp`NV_NTL{0&UJw4 z7Phv6vN&H@rezmnQ&UO3Op6;Eecx~N^z?u?24-mC!ZYM41-?Kpu)cwUw*v~GP%F>| z^0VugxBomx`1{^KK@Eg&K>sWvFsH`<{3WuR zAuwz5Ezk*!K!CzG$TBM2!GCVyrAY~F$OcuqobE*fDZG4Gc*SNRE*UI?d6f+n9eFQ=s;PJr>VDsYmUC=WmzgPV1&fz8cdvKj^Ck)i1q+8%O zC+yj0dszUme;eqbj$nPmOO5V@NGv}SL>O%MkiE#-%Rfi~^DYaupuP||BeoUK>jsg6 z*hp3uRZV_A9f%DlY`fihIszgS#+F+AYOcYIMW*M@r~oz=)-VEr(8YI-2W5UT0NeTj z`7q3Q;|EawG~|E3c>mP@#;=Bi+J!tlJcfZ0n*q>#p)uhNoSLSl1)PX3Hk#`{bk6yI z2l$P-M?!4ywK0-`Gu55NV-=pBo$V}2h3C0HSGDcj@ZA>3eqdd>OW;l2R!=X*p=N$~ z_gir$Qim>$n6d)hF7cY$+Ns)kCtE+iFMa?ZPY3G0;`!%`L13jj-f#XIbk#+hfnbyA zb!}Wjt7&YUL+-SDAGIB*Ga^_QDv1KFv}ftI*a(r&`_ewSplL#u*V+bnAWzjIFWEr;vhcLr75cI z?!fgmVDEs1U+nKoq|`Dtl(?n`Y6DgdJ^8Y{YP(&QIuAdC1I*4W}URp^+QWbLgfGP22n28O{P zEXmAnck;twBMu$QFs0=?=Kt zRn~qmCj9{`w*@sAknKT(q_=5PN8W^Bmm literal 21978 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 diff --git a/docs/utils/enums.html b/docs/utils/enums.html index 3950f25..8dee31b 100644 --- a/docs/utils/enums.html +++ b/docs/utils/enums.html @@ -89,6 +89,10 @@

    Class variables

    +
    var GP
    +
    +
    +
    @@ -139,6 +143,10 @@

    Class variables

    +
    var GP
    +
    +
    +
    diff --git a/docs/utils/index.html b/docs/utils/index.html index bc8e991..d8cbd35 100644 --- a/docs/utils/index.html +++ b/docs/utils/index.html @@ -294,6 +294,58 @@

    Returns

    Classes

    +
    +class SoDSampler +(N, M, seed: int = 0) +
    +
    +

    Base class for all Samplers.

    +

    Every Sampler subclass has to provide an :meth:__iter__ method, providing a +way to iterate over indices or lists of indices (batches) of dataset elements, and a :meth:__len__ method +that returns the length of the returned iterators.

    +

    Args

    +
    +
    data_source : Dataset
    +
    This argument is not used and will be removed in 2.2.0. +You may still have custom implementation that utilizes it.
    +
    +

    Example

    +
    >>> # xdoctest: +SKIP
    +>>> class AccedingSequenceLengthSampler(Sampler[int]):
    +>>>     def __init__(self, data: List[str]) -> None:
    +>>>         self.data = data
    +>>>
    +>>>     def __len__(self) -> int:
    +>>>         return len(self.data)
    +>>>
    +>>>     def __iter__(self) -> Iterator[int]:
    +>>>         sizes = torch.tensor([len(x) for x in self.data])
    +>>>         yield from torch.argsort(sizes).tolist()
    +>>>
    +>>> class AccedingSequenceLengthBatchSampler(Sampler[List[int]]):
    +>>>     def __init__(self, data: List[str], batch_size: int) -> None:
    +>>>         self.data = data
    +>>>         self.batch_size = batch_size
    +>>>
    +>>>     def __len__(self) -> int:
    +>>>         return (len(self.data) + self.batch_size - 1) // self.batch_size
    +>>>
    +>>>     def __iter__(self) -> Iterator[List[int]]:
    +>>>         sizes = torch.tensor([len(x) for x in self.data])
    +>>>         for batch in torch.chunk(torch.argsort(sizes), len(self)):
    +>>>             yield batch.tolist()
    +
    +
    +

    Note: The :meth:__len__ method isn't strictly required by

    +

    :class:~torch.utils.data.DataLoader, but is expected in any +calculation involving the length of a :class:~torch.utils.data.DataLoader.

    +
    +

    Ancestors

    +
      +
    • torch.utils.data.sampler.Sampler
    • +
    • typing.Generic
    • +
    +
    class FeatureExtractor (model: nn.Module, last_layer_name: str | None = None, enable_backprop: bool = False, feature_reduction: FeatureReduction | str | None = None) @@ -1108,6 +1160,10 @@

    Class variables

    +
    var GP
    +
    +
    +
    @@ -1158,6 +1214,10 @@

    Class variables

    +
    var GP
    +
    +
    +
    @@ -1287,6 +1347,9 @@

    Index

  • Classes

    • +

      SoDSampler

      +
    • +
    • FeatureExtractor

      • forward
      • diff --git a/docs/utils/utils.html b/docs/utils/utils.html index b8cc116..37f6c91 100644 --- a/docs/utils/utils.html +++ b/docs/utils/utils.html @@ -167,6 +167,61 @@

        Returns

  • +

    Classes

    +
    +
    +class SoDSampler +(N, M, seed: int = 0) +
    +
    +

    Base class for all Samplers.

    +

    Every Sampler subclass has to provide an :meth:__iter__ method, providing a +way to iterate over indices or lists of indices (batches) of dataset elements, and a :meth:__len__ method +that returns the length of the returned iterators.

    +

    Args

    +
    +
    data_source : Dataset
    +
    This argument is not used and will be removed in 2.2.0. +You may still have custom implementation that utilizes it.
    +
    +

    Example

    +
    >>> # xdoctest: +SKIP
    +>>> class AccedingSequenceLengthSampler(Sampler[int]):
    +>>>     def __init__(self, data: List[str]) -> None:
    +>>>         self.data = data
    +>>>
    +>>>     def __len__(self) -> int:
    +>>>         return len(self.data)
    +>>>
    +>>>     def __iter__(self) -> Iterator[int]:
    +>>>         sizes = torch.tensor([len(x) for x in self.data])
    +>>>         yield from torch.argsort(sizes).tolist()
    +>>>
    +>>> class AccedingSequenceLengthBatchSampler(Sampler[List[int]]):
    +>>>     def __init__(self, data: List[str], batch_size: int) -> None:
    +>>>         self.data = data
    +>>>         self.batch_size = batch_size
    +>>>
    +>>>     def __len__(self) -> int:
    +>>>         return (len(self.data) + self.batch_size - 1) // self.batch_size
    +>>>
    +>>>     def __iter__(self) -> Iterator[List[int]]:
    +>>>         sizes = torch.tensor([len(x) for x in self.data])
    +>>>         for batch in torch.chunk(torch.argsort(sizes), len(self)):
    +>>>             yield batch.tolist()
    +
    +
    +

    Note: The :meth:__len__ method isn't strictly required by

    +

    :class:~torch.utils.data.DataLoader, but is expected in any +calculation involving the length of a :class:~torch.utils.data.DataLoader.

    +
    +

    Ancestors

    +
      +
    • torch.utils.data.sampler.Sampler
    • +
    • typing.Generic
    • +
    +
    +