{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:49.487171Z", "iopub.status.busy": "2026-05-11T22:15:49.487106Z", "iopub.status.idle": "2026-05-11T22:15:49.537514Z", "shell.execute_reply": "2026-05-11T22:15:49.537104Z" }, "tags": [ "remove-input" ] }, "outputs": [], "source": [ "# This cell does not render in the docs because of the tag `remove-input`\n", "%load_ext autoreload\n", "%autoreload 2\n", "\n", "import warnings\n", "\n", "warnings.filterwarnings(\"ignore\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Custom Encoders\n", "\n", "Glass Box UMAP wraps a neural network around UMAP's loss. The choice of network, the *encoder*, controls what the model can learn about your data and what kinds of features it can attribute back to inputs. The library ships a strong default, and an encoder registry lets you plug in your own.\n", "\n", "This guide is about that registry. It first walks through what the default encoder looks like and why it's structured the way it is. Then, it describes the registry contract: what your class must promise so Glass Box UMAP can use it. And finally, as a worked example, we register a custom encoder and run it on a dataset." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The default encoder\n", "\n", "The default encoder is `DeepPReLUNet`. It is intentionally a flat multi-layer perceptron (MLP), built from three kinds of layer:\n", "\n", "* `nn.Linear(..., bias=False)`.\n", "* `VmapPReLU`, a home-brewed equivalent of [PReLU](https://docs.pytorch.org/docs/2.11/generated/torch.nn.PReLU.html) that's compatible with an efficient calculation of the Jacobian via [vmap](https://docs.pytorch.org/tutorials/unstable/vmap_recipe.html).\n", "* `LayerNormDetached`, which is a layer norm without an additive learned offset (bias term).\n", "\n", "The combination is not arbitrary. Glass Box UMAP's defining feature is *exact* per-feature attribution, and that property requires the encoder to be **piecewise linear** and **bias-free**. Linear layers without bias and PReLU activations together define a piecewise linear map. On any small neighborhood of the input space, the encoder behaves exactly like a single matrix multiplication, and that matrix is the encoder's Jacobian at that point. Multiplying by the input recovers an exact contribution from each feature to each embedding coordinate. Add a bias or use a non-piecewise-linear activation, and that property breaks.\n", "\n", "Here is the actual class." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:49.538860Z", "iopub.status.busy": "2026-05-11T22:15:49.538785Z", "iopub.status.idle": "2026-05-11T22:15:52.428915Z", "shell.execute_reply": "2026-05-11T22:15:52.428539Z" } }, "outputs": [ { "data": { "text/plain": [ "DeepPReLUNet(\n", " (flatten): Flatten(start_dim=1, end_dim=-1)\n", " (model): Sequential(\n", " (0): Linear(in_features=64, out_features=128, bias=False)\n", " (1): VmapPReLU(num_parameters=1)\n", " (2): LayerNormDetached()\n", " (3): Dropout(p=0.0, inplace=False)\n", " (4): Linear(in_features=128, out_features=128, bias=False)\n", " (5): VmapPReLU(num_parameters=1)\n", " (6): LayerNormDetached()\n", " (7): Dropout(p=0.0, inplace=False)\n", " (8): Linear(in_features=128, out_features=128, bias=False)\n", " (9): VmapPReLU(num_parameters=1)\n", " (10): Dropout(p=0.0, inplace=False)\n", " (11): Linear(in_features=128, out_features=2, bias=False)\n", " )\n", ")" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from glass_box_umap.parametric_umap.models import DeepPReLUNet\n", "\n", "DeepPReLUNet(input_dims=(64,), n_components=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A few things worth pointing out about this architecture:\n", "\n", "* It is a flat MLP. The `Flatten` at the top means the encoder is structure-agnostic. Whatever shape the input has, it sees a single long vector.\n", "* Width and depth are modest. Three hidden layers of 128 units is enough to learn a good 2D embedding for most datasets without becoming hard to train.\n", "* Dropout defaults to 0. Glass Box UMAP relies on a clean, deterministic forward pass for attribution. Dropout would inject noise into the Jacobian.\n", "\n", "## Changing default encoder parameters\n", "\n", "The default encoder has default parameters:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:52.430416Z", "iopub.status.busy": "2026-05-11T22:15:52.430270Z", "iopub.status.idle": "2026-05-11T22:15:52.469751Z", "shell.execute_reply": "2026-05-11T22:15:52.469367Z" }, "tags": [ "remove-input" ] }, "outputs": [], "source": [ "DeepPReLUNet?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These parameters can be modified using [GlassBoxUMAP](../autoapi/glass_box_umap/index.rst#glass_box_umap.GlassBoxUMAP)'s `encoder_kwargs` attribute:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:52.471076Z", "iopub.status.busy": "2026-05-11T22:15:52.471005Z", "iopub.status.idle": "2026-05-11T22:15:52.495513Z", "shell.execute_reply": "2026-05-11T22:15:52.495168Z" } }, "outputs": [], "source": [ "from glass_box_umap import GlassBoxUMAP\n", "\n", "# Let's make the hidden size 512.\n", "reducer = GlassBoxUMAP(\n", " min_dist=0.1,\n", " n_neighbors=15,\n", " encoder_kwargs={\"hidden_size\": 512},\n", ")\n", "\n", "# I changed my mind, let's also have just 1 hidden layer\n", "reducer.encoder_kwargs[\"n_hidden_layers\"] = 1\n", "\n", "# Scratch all that, I just want the defaults\n", "reducer.encoder_kwargs = {}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above changes all modify the encoder state. The choice only becomes hardened once `fit(...)` (or `fit_transform(...)`) is called.\n", "\n", "## The registry contract\n", "\n", "Any `nn.Module` can be plugged in via the encoder registry. The contract is small.\n", "\n", "1. **Constructor signature.** Your class accepts `input_dims: tuple[int, ...]` and `n_components: int` as it's first two arguments. Any extra kwargs are fine. They get passed through `encoder_kwargs` when you instantiate `GlassBoxUMAP` (seen above).\n", "2. **Forward signature.** `forward(x)` returns a tensor of shape `(batch, n_components)`. Glass Box UMAP handles batching and the rest of the training loop.\n", "3. **Decoration.** The class is registered with `@register_encoder(\"name\")`. Once registered, you can instantiate it with `GlassBoxUMAP(encoder_name=\"your_encoder_name\", encoder_kwargs={...})` exactly like a built-in.\n", "4. **For exact attribution.** Every `Linear` and `Conv` layer is bias-free, and every activation is piecewise linear. `VmapPReLU` is provided.\n", "\n", "The first three are required. The fourth is required only if you want `compute_contributions` to keep returning exact attributions. If you're willing to give that up, you can use any architecture you like." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A worked example: a Maxout encoder\n", "\n", "The default encoder is a sequence of `Linear` and `VmapPReLU` layers. PReLU is itself a piecewise-linear function: `PReLU(x) = max(αx, x)`, a two-way max with a tied negative-slope parameter. The whole network is a composition of two-way maxes.\n", "\n", "[Maxout](https://arxiv.org/abs/1302.4389) generalizes that. Each Maxout unit takes a `k`-way max over `k` independent linear projections of its input. Because each piece is a separate linear function, a Maxout layer with `k` projections can represent any continuous convex piecewise-linear function with `k` pieces, while a PReLU layer of the same width is restricted to functions that are pointwise reflections of two affine pieces. With `k = 2` and a tied slope you essentially recover PReLU. With larger `k` you get genuinely more expressive layers per unit. (In practice this means Maxout layers can be narrower than PReLU layers for the same approximation capacity, at the cost of more parameters per unit.)\n", "\n", "This architecture satisfies our constraints. A `k`-way max of bias-free linear projections is itself piecewise linear and bias-free. Exact attribution still works. At any input `x`, exactly one of the `k` projections is the active one, and the local Jacobian is just that projection's weight matrix.\n", "\n", "Before implementing this custom encoder, let's first take a look at the existing registry:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:52.496682Z", "iopub.status.busy": "2026-05-11T22:15:52.496617Z", "iopub.status.idle": "2026-05-11T22:15:52.513660Z", "shell.execute_reply": "2026-05-11T22:15:52.513233Z" } }, "outputs": [ { "data": { "text/plain": [ "{'default': glass_box_umap.parametric_umap.models.DeepPReLUNet,\n", " 'default_conv': glass_box_umap.parametric_umap.models.ConvEncoder}" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from glass_box_umap.parametric_umap.registry import view_registry\n", "\n", "view_registry()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Glass Box UMAP comes shipped with the above encoders. To register your own encoder, you just need to define it, and decorate it with `@register_encoder(\"your_encoder_name\")`:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:52.514819Z", "iopub.status.busy": "2026-05-11T22:15:52.514735Z", "iopub.status.idle": "2026-05-11T22:15:52.531533Z", "shell.execute_reply": "2026-05-11T22:15:52.531170Z" } }, "outputs": [], "source": [ "import math\n", "\n", "from torch import Tensor, nn\n", "\n", "from glass_box_umap.components import LayerNormDetached\n", "from glass_box_umap.parametric_umap.registry import register_encoder\n", "\n", "\n", "class MaxoutLayer(nn.Module):\n", " \"\"\"One Maxout layer: ``k``-way max over independent bias-free linear projections.\"\"\"\n", "\n", " def __init__(self, in_features: int, out_features: int, k: int) -> None:\n", " super().__init__()\n", " self.out_features = out_features\n", " self.k = k\n", " self.linear = nn.Linear(in_features, out_features * k, bias=False)\n", "\n", " def forward(self, x: Tensor) -> Tensor:\n", " z = self.linear(x).view(x.shape[0], self.out_features, self.k)\n", " return z.max(dim=-1).values\n", "\n", "\n", "@register_encoder(\"maxout_mlp\")\n", "class MaxoutEncoder(nn.Module):\n", " \"\"\"Bias-free, piecewise-linear encoder built from Maxout layers.\n", "\n", " Each hidden unit is a ``k``-way max over independent linear projections,\n", " which preserves exact attribution while giving each unit more expressive\n", " pieces than a PReLU activation does.\n", " \"\"\"\n", "\n", " def __init__(\n", " self,\n", " input_dims: tuple[int, ...],\n", " n_components: int = 2,\n", " hidden_size: int = 128,\n", " n_hidden_layers: int = 3,\n", " k: int = 4,\n", " ) -> None:\n", " super().__init__()\n", " in_features = math.prod(input_dims)\n", " self.flatten = nn.Flatten()\n", "\n", " layers: list[nn.Module] = []\n", " prev = in_features\n", " for i in range(n_hidden_layers):\n", " layers.append(MaxoutLayer(prev, hidden_size, k))\n", " if i < n_hidden_layers - 1:\n", " layers.append(LayerNormDetached(hidden_size))\n", " prev = hidden_size\n", " layers.append(nn.Linear(hidden_size, n_components, bias=False))\n", "\n", " self.model = nn.Sequential(*layers)\n", "\n", " def forward(self, x: Tensor) -> Tensor:\n", " return self.model(self.flatten(x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can verify it's registered with another call to `view_registry`:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:52.532753Z", "iopub.status.busy": "2026-05-11T22:15:52.532689Z", "iopub.status.idle": "2026-05-11T22:15:52.548595Z", "shell.execute_reply": "2026-05-11T22:15:52.548201Z" } }, "outputs": [ { "data": { "text/plain": [ "{'default': glass_box_umap.parametric_umap.models.DeepPReLUNet,\n", " 'default_conv': glass_box_umap.parametric_umap.models.ConvEncoder,\n", " 'maxout_mlp': __main__.MaxoutEncoder}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "view_registry()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Running it on the digits dataset\n", "\n", "The sklearn `digits` dataset is 8x8 grayscale images of handwritten digits, flattened here into 64-dim tabular vectors.\n", "\n", "We hand the registered encoder to `GlassBoxUMAP` by name. We tailor the `encoder_kwargs` so that the model parameter count roughly matches the default encoder." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:52.549638Z", "iopub.status.busy": "2026-05-11T22:15:52.549567Z", "iopub.status.idle": "2026-05-11T22:15:52.592257Z", "shell.execute_reply": "2026-05-11T22:15:52.591942Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "X shape: (1797, 64), dtype=torch.float32\n", "y shape: (1797,), classes=[0 1 2 3 4 5 6 7 8 9]\n" ] } ], "source": [ "import numpy as np\n", "import torch\n", "from sklearn.datasets import load_digits\n", "\n", "from glass_box_umap import GlassBoxUMAP\n", "\n", "digits = load_digits()\n", "X = torch.from_numpy(digits.data.astype(np.float32))\n", "y = digits.target.astype(int)\n", "\n", "print(f\"X shape: {tuple(X.shape)}, dtype={X.dtype}\")\n", "print(f\"y shape: {y.shape}, classes={np.unique(y)}\")\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:15:52.593605Z", "iopub.status.busy": "2026-05-11T22:15:52.593507Z", "iopub.status.idle": "2026-05-11T22:16:36.285081Z", "shell.execute_reply": "2026-05-11T22:16:36.284568Z" } }, "outputs": [], "source": [ "reducer_default = GlassBoxUMAP(\n", " random_state=42,\n", " quiet=True,\n", ")\n", "\n", "reducer_default.fit(X)\n", "embed_default = reducer_default.transform(X)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:16:36.286461Z", "iopub.status.busy": "2026-05-11T22:16:36.286377Z", "iopub.status.idle": "2026-05-11T22:17:17.796477Z", "shell.execute_reply": "2026-05-11T22:17:17.796120Z" } }, "outputs": [], "source": [ "reducer_maxout = GlassBoxUMAP(\n", " encoder_name=\"maxout_mlp\",\n", " encoder_kwargs={\"hidden_size\": 96, \"n_hidden_layers\": 2, \"k\": 3},\n", " random_state=42,\n", " quiet=True,\n", ")\n", "\n", "reducer_maxout.fit(X)\n", "embed_maxout = reducer_maxout.transform(X)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:17:17.798179Z", "iopub.status.busy": "2026-05-11T22:17:17.798098Z", "iopub.status.idle": "2026-05-11T22:17:17.914544Z", "shell.execute_reply": "2026-05-11T22:17:17.914078Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA44AAAIQCAYAAADO7DATAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAChCElEQVR4nOzdBXwUZ/oH8N+sb9wTAgnuXgqUUqVCKfWrG5Wru175X92oXa96latQl6u3V6fUrlihUByCJUgS4r46/88zYUNkdyNkLfv73k3Jzsxu3n13MzPPvO/7vIqqqiqIiIiIiIiIfND52kBERERERETEwJGIiIiIiIjaxRZHIiIiIiIi8ouBIxEREREREfnFwJGIiIiIiIj8YuBIREREREREfjFwJCIiIiIiIr8YOBIREREREZFfDByJiIiIiIjILwaOEWDjxo04+uijkZiYCEVR8MknnwTk9xx22GHaEm3uvvturV6D6corr8RRRx0V1N9J4WXNmjUwGAxYtWpVqItCRFFq7ty52vlv69atQfudjzzyCIYNGwa32609lt8tZXjssccQagcccABuvfXWUBeDKGwxcOzGA69nsVgsyM7OxvTp0/HUU0+hurp6n15/1qxZWLlyJR544AG88cYb2H///REMO3fu1IKq5cuXB+X3RYstW7bgpZdewv/93/81rfOcOD2L0WhEWloaDjzwQG2//Px8hJMff/yxTXkHDBiA888/H5s3b/b5vnQ6HVJSUjBjxgwsWLCgy79fXuvqq6/2uV1ugIwaNcrrtpKSEu358t1u/Tcsf7s7duzo1Ou15+2338YTTzzRZv2IESMwc+ZM3HnnnV16XaJIOCf++uuvbbarqoqcnBxt+3HHHYdI8uCDD3q9edv6OqD1snDhwpCUN9xUVVXh4Ycfxt/+9jftfBAMq1evxmmnnaado2JiYrRz6yGHHILPP/+8zb5SrmeffRaFhYVBKRtRpDGEugA9yb333ov+/fvD4XBoBx25uL7++uvx+OOP47PPPsOYMWM6/Zr19fXaBfbf//53vxfKgQoc77nnHvTr1w/jxo0L6u/uyZ588knte3L44Ye32XbWWWfh2GOP1e7ElpeXY8mSJVrQIc95+eWXceaZZyKcXHvttZg4caL2nV+2bBlefPFF/Pe//9VudMjNk9bvy+VyYcOGDfjXv/6lvX95f6NHj0a4sNlseOihh/D0009322tK4CitinIsaO3yyy/X6mXTpk0YOHBgt/1OonAgN2Lk+3/QQQe1WP/TTz9h+/btMJvNiDQSOJ566qk46aST/F4HtDZo0KAglC78vfLKK3A6ndo5IVi2bdum3cCXm/ByXqqrq8OHH36IE044AS+88AIuvfTSpn1PPPFEJCQkaOco+SyJqCUGjt1IWlGatwbOnj0bP/zwg3ZHVQ5Qa9euhdVq7dRr7t69W/s3KSmpO4tKASQnJbmr6Y0EWG+99ZYWMHiz33774dxzz21z0pOuynLSGz58OMaOHYtwcfDBB2sXUeLCCy/EkCFDtGDytdde077/vt6XPE/+Xp577jntBB0u5AbJv//9b63szQPfQDnyyCORnJys1RcvUqinkZsi//nPf7SeN9It20OCyQkTJmit/z39OiDa1NbWIjY21uf2V199VbsekpsKwfweytKc3IiX76Dc2G8eOEorqJzTXn/9de3GebCHsRCFO3ZVDbBp06bhjjvu0C7+33zzzRbb1q1bpx2gpOueHETlZCMtkx7Sla5v377az7fccot2AJPWPyGvJ+Pkhg4dqgWjqampWleM1uMUfI3fa29cg7SWSkuSJyDwdLeR5/kj3fwuuugiZGZmaneTR44cqd1hbP3a8lrvv/++1v22T58+2vs/4ogjkJeX1+Y1Fy1apB305QJbTkjScistcM1JgC7BiGyXIFvuGkqg3pp0m5L3Jb9PWnjkbqMv8nnJiUXqVz4jae0rKCjw2oVx6dKlWtcXCRibd0H19vvlYkkCho6S74DUu91u18aGNFdRUaG1ZEm3L6lvuast3YA8Y0c85LG0XMrnIe9dPp/LLrtMa9VsTr5fcqPj22+/1YIo2Ve6VH700Ucd/r57uuP6I5+VkJa2rryfQJHPTlpFpdWxI9r7jsj3Q1pg5e/V8zfk+RsW0sVX9vn0008D8n6IQklalUpLS/Hdd981rZPj2AcffICzzz7b63NknJt00Zdzmvxdyd+X7N86+JC/pdbnFmkNlPVffvllp84NF1xwQYu/S1/nT/lZAiO50eP5e5bndkbz8XzSQ0POQ3Ksk/OS9MBoTa4TTj/9dKSnp2v1Ied86YHU3B9//KEFrNJSFhcXp51LvXWNlS6bcoyW15Hz7v333+/z2PrVV1811Vt8fLzWrV6e37re5PfJcVzO0bLfOeec4/O9y3nhzz//7ND5T7ozS0BnMpk6fP7pDL1er51n5JzTmuQfkGM2h+kQtcUWxyA477zztAtSuRi/5JJLtHVyAJ46dSp69+6N2267TTs4SyAl3V+kC8XJJ5+MU045RTvR3XDDDU1d/eQgLeQE89tvv2kXqnICkJORtN7IRagk3fDV4tVR0rIlLSAy/koO3p4LfTmh+1JUVKQNLPeMP5MTnZx8Lr74Ym1cQ+uuenJxLnf3br75ZlRWVmpBkZx0JFD0kAsOCWR69eqF6667DllZWdpJ/4svvtAei++//147acr4BTnRS/de6Woo9SvdJz0XBNJ9UlrupFyyn3SXueuuu7QgqjUJaCXglxP2X//6V63lV15TgkM5STdvAZYLI/n98llIq5q31/OQz0zqZ/z48Z36PKZMmaJdYDS/AJOWzUMPPVQL1iUIzM3N1V5fWst27drVYlydbJfgU24CSIugnMCfeeYZ7b3873//0wKY5smYzjjjDK1VVFo55SJNbkp8/fXX7Sb08QSCctHnj+eGhdwM6Mr7CRTpYibjNKXVUf4u/bU6duQ7Ihd48t2Wbnn//Oc/ted5/oY95MJYAkf5G5ELP6KeQo69cux65513tGOkkHOC/E3I8VJaIluTm4LSIiXnAgky3333Xe34I8d8CV6EHMckmLjxxhu1Y5IEAHJ8lxYiOd94Wpc6em7oKMkxIH/rkyZNamqlat3FXN5b65ZUOea3PiZKq6t0n5RjnWyX85+c82WMuOd4LEGWnHvlsfw+Ka8cY2Vsnhx/PNcSso8cOySpi+wrN0TlWkC6BE+ePFnbT4bPyPAAOe95rjkkcPXWC0repxz7JU+D3LiTY7NcX0iXYzm2Na83eT3ZT7ZJMOzv2kOO554eKP7IzTu5Af3ee+/h448/bvrcJcgtKytDR0gywebnNSFBv3wH5DOSm/TyXZRzXWtyTBZybuzsuZqox1Npn7366quqVOWSJUt87pOYmKiOHz++6fERRxyhjh49Wm1oaGha53a71QMPPFAdPHhw07otW7Zor/3oo4+2eL26uro2v2PBggXavq+//nrTurvuuktb56vM8voehx56qLZ4yPuRfWTfjrj44ovVXr16qSUlJS3Wn3nmmdr795R5/vz52usOHz5ctdlsTfs9+eST2vqVK1dqj51Op9q/f3+1b9++anl5eYvXlLryGDdunJqRkaGWlpY2rVuxYoWq0+nU888/v2ndSSedpFosFnXbtm1N69asWaPq9foWdbR161Zt3QMPPNDid0q5DAZDi/VSX/Lc559/vkN1dO6556qpqalt1vv6nJs78cQTtX0qKyu1x/fdd58aGxurbtiwocV+t912m1b+/Px87fEvv/yiPe+tt95qsd/XX3/dZr3Utaz78MMPm9bJ75PPtfn31/MZvvLKK+ru3bvVnTt3qv/973/Vfv36qYqiNP0teN7XPffco+1XWFiolWfixIna+v/85z9Nr9nR9yPkuVdddZXPupLPZeTIkV63STnk+fK34e1veNOmTdrnfO211/p8vc58R2bOnKnVqy9vv/229rsXLVrkcx+iSNL87+mZZ55R4+Pjm47/p512mnr44YdrP8vfhfx9+Du32e12ddSoUeq0adNarN+1a5eakpKiHnXUUdp5RI5Pubm5TcfHzpwbZs2a5fVv1Nv5U45Rsr+v9+xtMZvNTft5jolyHigrK2ta/+mnn2rrP//886Z1hxxyiFZ3zc9Zrc9/cl4zmUzacctDjsfyPHm+x/XXX9/mOFNcXKydm5tfC1RXV6tJSUnqJZdc0uJ3yrFb9m2+XupBnivH6I64/fbbtf3ld/g6/zkcDvWMM85QrVar+s0333jdryOLnKNau+yyy5q2y3fg1FNPbfEZNCd1esUVV3TofRFFE3ZVDRJpZfBkV5U7ZtJ9RloqZJ3cnZRFWq7kzp20+HjL7Nhc87uEMm5Onivd+qSVQ+6kBptcy0tL6fHHH6/97HlPssh7kjt8rcsld42lG4qHp1XTk5VT7mxKy5i0VLYe4+npPiQtUdKdRLrMSFdBD+nOKneiPV2W5A7mN998o7XoSktW85ZVKV9zcidb7mzK59P8fUhr5+DBgzF//vwW+0s3I3kvHSGfU/NWts7wtFR5vkcydkjqTF6veTmlG5C8359//rlpP7n7KvXRfD+5qyqv2fr9SCubtHh7yJ1saYWTz6N1pjm5KywtuPIcuSvs6cbVeoyPtOzKflKHUmZpNf7HP/7RND6yM+8n0KR1QnoJyN14+X5509nviD+e70NPHO9FJH8j0sojLYZy7JJ/fXVTbX1uk670cu6Q40Lr84f8rUn2S+mFIdvlPCBdVz2t9h09N3Q3T5maL9Ky1Zq0dDU/F7Q+/0kPBjnmyTG2+Tmr+flPjovSk0nOa3Lc8pAeOlLHMjRCejIIeb/SI0haSz3kmNy6a6mUV7pvSi+n5sc26doprZfejm1XXHFFh89/Mta1da8LD2lh9rQuS3mlh1Drz7x13fpavOUCkGsJ2SbnKGmJlvqT3+mN5zxERC2xq2qQ1NTUICMjQ/tZxvFJcCXd3GTxpri4WOvG6ouciOfMmaN1I5Qgs7ERppGcaINNTnJyspGLbVl8vafmWp8MPSdRz7g7T7dHf9MgyDgEIeM+WpOgUIJFCWbkgkXqTC7qW5PnNr+IkMBd6tPbvqJ19xf5nJoHwO1p/ll19jskZByJp5zSlUlO/v7qW/aT74Tn++drPw+5AdF6XKwkvfF0MZWTt4d0ZZYLHrmokBTnUufNk2B4SDcruSBoaGjQbppIFzU5aTfX0ffTXfwlPbj99tu17lrSnbr1eNqufEc68n1gEgbqieTvWW7+SNdM6fIof/fNbxi1JkGDjL2ToE+yHHt4+/uQ7q4yzljGEcsxRsb2dfbc4C+RS1dIYNaR5Djtnf88AaS/85+cd6VOfb1HubklY65lbLvUh6fbanOtnyvHtubj1Vtr3Z1ejvcyXKY7yDWNnOck0PY2p7SMue9MfoDWZO5IWYTcDJXAVG52y/CY1t8vOS7zmEzUFgPHIJDxTXLh7knH7RmMLmP7Wrd2dTR19zXXXKMFjXIHTcaQSIuSHOTkRNp8sLuvA1/ri/Z95fmdMsZPxkZ403o6Egk2ujOw6s73IvUmJy9vZWx9t7QzmXJlnEvrhDQdJVM6SPDnOXFLOeXOua/Jij3Bnuwnz5Nsrt74CtQ6QqbS6MiJXAIsz34yZlXqVcbZyJgbz0VWR99PR8gFhtwo8EYutDz7+CJ37+W7LDdBpJz7+h3xx/N9kMCbqCeS1i8Z3y89FqSlx1eW8F9++UUb3yjjhCXbsrScyU0YOddJ4OmtBev333/Xfpax/fJ32ZW5AYN1noyU85+QG2fNbxJ6tL4xKD1uOlrncv6TMZFyI9dzA7Q5uR6SsfQy3lMCx9bHaPk8PJnm2yOtzO3d0JUbGDLGVKaIah1Ay41wHpOJ2mLgGARyABaeINHTpUROiF29eyZZ5iRAk+5+HtKa0zpDmOcupqxvfrL23I31pzN32yT4kBOBHNj35Y5gc56kAxIw+XpNT9bZ9evXe81GJwd+uaMsJyAJ8Dx3U5tr/Vz5vXLylkQpnQlWOkLudkoAJzcSJNjvKJnLU1pgm09pIeWUu7Pt1bfsJ0kiJCFER4JcT4t4889fTqyis8kkfJGkMZKARlr25EKhM++nI+R7IS2bEjy2fs+ez9vz3fFFyiatGZIcorXOfEfa+zuS7thy4dXd3zWicCFd3+UCXTJ9SsITX2S4gxyrpTWw+RyPEjh6c9VVV2lBiLRUSRItSaAlCXM6c27wnCe9Zdf0dp4MViuU5zpBzn/+zruSjMbXe5TjiiQO8tRHR89/Qm42dte53MPT2ifHPG/zWktXWknKJjcXpYeKJMZpHqhK66m3OTK9kS613lotm/PcXGzdS0t6cUkXVmm1JaKWOMYxwOTi9b777tMOdp6xBHJAlgOaZD7zNoaqI3fU5G5l6zuTki2u9R1Sz0mg+fgwzzi09nhOqt5OqN7K85e//EU78Xs70XX0LmFzknlN6k0uBlqXwfPe5Y60TBsh76f5PlIGGfvhya4n5ZPA/ZNPPkF+fn7TfjLWTi5SmpPMdrK/ZOhrXcfyWO5yd5W0DstryPQdHSUXLzJOR+6eyrQszccOSUDZuvxC6kLu7Hr2k++FfA9bk31a1+3OnTu1E7aHjJGROa2knr3dge4KuYkhF5JSdk/K846+n46Qz13G/raebkXupkt2QKnL5t3avJG/HQnU5TVaj+3szHdE/o78dR+X74J0JevMjQSiSCIt8PJ3J5lNpWugL/I3JYFZ8/OYdI+X47a3m6cShEp3cukVIL1t5GaP5yZXR88Nnr91+RuVrvIecm5ufhxs/vfckXPivpKgUFpeZdxm83OW8BxzpL6ku6VkZW4+tZZkOJcWWsl06umhIu9XAvfFixe3OC+37oki50l5jkxtIsfQ7jiXNz//CU8rsTcSrEomXbmhKGPNm/eg6uoYR2/DHOS9yXlNbizKlFPNec7P/rLIE0Urtjh2I+m2Jnf55AJXDtwSNMoBTO70Sern5t0uZAC9HNSlq5904ZG7i/IcuXCWrq0rVqzw+7vkjpy0ZMrFphz05HnSqtQ65becVGQshaQol6BDTjRyIpKTUuuTUWtyMpUL/Oeff15rTZQTpoyR8HXHT07gcpdP9pH3JOWSRECS1EDK1tE02h5yt1QuNuRCQy4AJAGNXAxIHUsKck+A8eijj2rdn+SkJO/Tk3Jd6kYuVDzkIl9ORjImT+bAlM9J9pOL9uYXDPK+ZYyN3MGWk7EkHpD3L3dJ5UJCxtJIN+OukM9cPiOpD29jSKSupJVLTpZycSLTrkgwLhdT8nk3v0srn6d8r+S7IIGlJLuRmwKSll4uqqTsclddpriQIE3uykuQJt8Jae2Wu8+SkEbG8DUfcyQtX1KP8rtlahH5vsh309dd/66S6VTkpoB8b+RCoaPvx0MuPuRzak1uysh3Rt6nTGUjF0pyASBdVOX1JcW6PK8jXXSlZVTqXe7Ky/ekK98ReR9ygSstITJXm1xEey6e5eJFUubL95GoJ/M1hKE5SbAlE7Ifc8wxWvdWueCXc6UM3Wh+jJb1kpBFurrL1E9CpheS848cOyQpjJw/OnpukKDzb3/7m9YyKtMVeaafkGNh66Q88vcsx28ppyQFk/Nh87GDnuuA1uQY1DyBTUfIWHA5Z8hNVDmmyO+S442M6fTccJPjkFxnyH5yHJEWOrnZJeNDm8/7K0MA5FgmdSvHXs90HHJ90rxuJWiU9y5Bm/xeqRvP9YL8Xum5InXdFfL+Zcym1J8k/fFFjqdyvpFxiFIezw3Aro5xlPOf3ACVQFxyEsiNQAmY5XOSXluthxZIfcp1E6fiIPIi1Glde4LWabgljXNWVpaWJlymmKiqqvL6PEmfLSnBZV+j0aj27t1bPe6449QPPvig3WkaZHqKCy+8UE1LS1Pj4uLU6dOnq+vWrdNSirdOFb506VJ18uTJWrkkXfnjjz/eoek4PCnCR4wYoU0x0JGpOYqKirRpEnJycrT3JO9Nph558cUX20zl0HwqhubvtfXv+PXXX7W6lPTikgp9zJgx6tNPP91in++//16dOnWqlsI7ISFBPf7447WpNlr76aef1AkTJmh1MWDAAG0aDV9TlsiUFAcddJD2O2UZNmyY9t7Wr1/foWkffJFpHgYNGuT1vXsWqW9JNS+f2+zZs9ukY/eQtOayXV5P3pN8H2RKl8cee0xLY9+cfAby3qWOpC5lOphbb71VS93u4UmPL2nQpZ4ljby879afla/PsLPTjFxwwQXatBZ5eXmdej/+0rDLtB5Cprq5++67tfLL+5DP8IADDlDffPPNTk2p40k57+1z7sh3pKamRj377LO1FPfyOs3T/n/11Vfauo0bN/qtR6KeNkWVr+k4Xn75ZW1KKs+xR16r9TH6lFNO0Y5hMi1Oc54pLR5++OFOnxu+/fZbbdoPOe4MHTpUO054OzfIeVamuZDXk22e862/6Tian9f8HRNbTxMkVq1apZ588sna8UOmk5Ky3XHHHS32WbZsmXYNINcCMTEx2nQnv/32W5vX//PPP7VzlryOXG/IsVLqu/W1gOcYL68pU3DI/gMHDtSO17///nvTPvLe5bjXGXL9IeVsPu2Krzr517/+pa2/+eab1X3xzjvvqEceeaSamZmpnVuTk5O1x/J9ac3lcmnTT8nUIUTUliL/8RZQElFgSLY8Geshd6bb6y4ZbDKGUe4IS2ZDCjy5sy6tyd66xBER9TTSJVhaHqU1VFqBw410i5bWbskpID2ciKgljnEkCjI5acoJU7poUvSS8bUSoHsbe0pE1BNJN2HpNivdiJuPXwwXkgxNuj8zaCTyji2ORNSELY5ERERE5A1bHImIiIiIiMgvBo5E1EQy9nF8IxEREVHoVVdX4/rrr9cyIMv0MZKhWbLehwoDRyIiIiIiojDz17/+VZsiRqbTkenJZKoxmZZmx44dISkPxzgSERERERGFkfr6em2O6E8//VSb57b5fLIyR623uawDzYAIJ1m5du7cqVWspLUnIqLOkVmZpDuMTGguE6dHO55XiIii97zS0NAAu90e0LpRWsUsZrNZW5pzOp1wuVywWCwt1kuX1V9//RWhEPGBowSNOTk5oS4GEVHEKygoQJ8+fRDteF4hIorO84oEjQl9cuAoLQnY74iLi0NNTU2LdXfddRfuvvvuFuukUWzKlCnatF3Dhw9HZmYm3nnnHSxYsACDBg1CKER84CiV6vliJiQkhLo4REQRp6qqSrsB5zmeRjueV4iIovO8Ii2NEjRO+PQH6GPjuv31XbU1WHritDZxS+vWRg8Z23jRRRehd+/e0Ov12G+//XDWWWdh6dKlCIWIDxw9Tb1S+QwciYj2/Xga7XheISLq3uNppJGg0RCAwNGjo3HLwIED8dNPP6G2tlYLxnv16oUzzjgDAwYMQChEVqdjIiIiIiKiKBIbG6sFjeXl5fjmm29w4oknhqQcEd/iSERERERE1NN88803WjKdoUOHIi8vD7fccguGDRuGCy+8MCTlYYsjERERERFRmKmsrMRVV12lBYvnn38+DjroIC2YNBqNISkPWxyJiIiIiIjCzOmnn64t4YItjkREREREROQXA0ciIiIiIiLyi4EjERERERER+cXAkYiIiIiIiPxi4EhERERERER+MXAkIiIiIiIiBo5ERERERETUdWxxJCIiIiIiIr8YOBIREREREZFfDByJiIiIiIjILwaORERERERE5BcDRyKi1tZ+BTw6DHh6ElC2jfVDREQ9nrO8AfVrSmEvqIaqqqEuDoUhQ6gLQEQUVv4xCqguaPy5dhfw1BjgpJeAcaeFpDjlDeVYVrQMTrcTU7KnIMGcEJJyEBFRz1WzpBAVn+UBjr0Boz7NgvSLR8OQbAlp2Sh8MHAkIvLYtmhv0NjcJ38NeuAod3vvX3g/3t/wfov1l4y6BNdOuDaoZSEiop7LWWFDxSd5gKtlK6OrpAGFDy9B2mWjYemfFLLyUfhgV1UiIo/fngybupj96+w2QaP496p/46KvL0KBtwCXiIioE1SHC+Ufb2gTNDZX9tY6bT8iBo5ERB7pw8OiLgprC/Hfzf/1uX1J0RKc/fnZqLZXB7VcRETUs1R8sRm29RV+93HXOuAorg9amSh8MXAkIvI4fHZYHCr9BY0eFY4KnP756XC4HUEpExER9SyqW0Xd8t0d2BHQWTm6jRg4EhHtpTcAF33btkam3RHUWnpt9Wsd2m97zXa8vur1gJeHiIh6IKUxeOzQrmZ9wItD4Y8tjkREzeVOBs77BMg5AMgcDRz9AHDQ9UGrI5fbhXJbeYf3f2PtGwEtDxER9UyKokCfZGp/R70CRa8Eo0gU5tjuTETU2sDDG5cQqGyo7NT+VbaqgJWFiIh6Lmd5PVylDe3uJ9Ny6CwMGYgtjkREYeXjvI87tb9DdXCiZiIi6rS6pcWAu/39rCNSWbukYVdVIqIwEmOI6fRzvt7ydUDKQkREPZertmPJ1dQGZ8DLQpGBgSMRURg5ou8RnX7OF5u/CEhZiIio5+poplR3A+dwpEbssExEFEY2V27u9HNUyZVORETUQXV/FKPmt52N5w9VziGKlizHG1N2HOuVNGxxJCIKI6nWzo8lOSznsICUhYiIeh5HcR0qvtwMZ4MNLrd0Q20MGFUtgGxLF2MMcgkpXDFwJCIKIwt2Luj0cz7e8DET5BARUYc4dtfB3eCEzVGPelcNHG4b3KrLZ/Bo29K5bN/UcwU0cPz5559x/PHHIzs7W2v+/uSTT1psly/nnXfeiV69esFqteLII4/Exo0bA1kkIqKwNr9gfqefs6psFX7M/zEg5SEiop5Drr0b1pZBdaiwGuIQa0iAQWfSrtNV1XuKVdXZgdSrFBUCGjjW1tZi7NixePbZZ71uf+SRR/DUU0/h+eefx6JFixAbG4vp06ejoaH9OWWIiHqiant1l573xto3ur0sRETUs9g2VaBu+e494xqlk6pORjfC4baj3l3r9Tmm3IQgl5KiMjnOjBkztMXXHY8nnngCt99+O0488URt3euvv47MzEytZfLMM88MZNGIiMJSbnwu1pev7/TztlZtDUh5iIioZ6hfVYLS99cDTveeFkZJjaNqgaNRZ4YRZq8Jcsy58SEpL4WfkI1x3LJlCwoLC7XuqR6JiYmYPHkyFizo/BgfIqKe4C9D/oI4Q+cz2DU4GuB0ca4tIiJqy1FUi7JPNgL2vd1OJUjUKbqmf2VpQwHcNk7HQSEOHCVoFNLC2Jw89mzzxmazoaqqqsVCRNRTTO09FU9MewLxxs7d4a12VuOmn24KWLmIiChyOQrroHYlADTqoI83BaJIFIEiLqvqnDlztJZJz5KTkxPqIhERdatJWZPgRueTEfxY8CPKG8r5aRARUQv6RBNg6Pxlv6lXHIwZMaxNCm3gmJWVpf1bVFTUYr089mzzZvbs2aisrGxaCgoKAl5WIqJgemXVK2hwdj5JmASbK4pXBKRMREQUuUx9ExAzspPzBJv1iJvSK1BFoggUssCxf//+WoA4b968pnXS7VSyq06ZMsXn88xmMxISElosREQ9xc6anXhr7VuIMXTtDq9OF3EdSYiIKMBkHKOzpBM3JBUg8chcWMemB7JYFGECmlW1pqYGeXl5LRLiLF++HCkpKcjNzcX111+P+++/H4MHD9YCyTvuuEOb8/Gkk04KZLGIiMJWha0CTrcTrj2TMXeWw+Ho9jIREVHkc+6u7/jOamNSHG9ZVil6BfTW9O+//47x48dri7jxxhu1n++8807t8a233oprrrkGl156KSZOnKgFml9//TUsFksgi0VEFLb6JfRDVmwWbE5bl57/wJIHtBTrREREHm67C+6Gzt1YrP55O9wNzNZNQQocDzvssMY5Ylotc+fO1bbLXYx7771Xy6La0NCA77//HkOGDAlkkYiIwlqMMQaPHPIIchNyvW7PsGTgxgk34tyh53rdvrt+N3bW7gxwKYmIKJKojs4nXJOpO6p/2xGI4lCE4mAYIqIw0y+xHx46+CHEGmNh0plg1VthNVjRP6E/3j7ubVw46kJcN+E6n893u7twgUBERD2WLsYAXby5089zlXY+URv1XAwciYjC0PDU4Thp0Ela8GjQGZBoSsTNE29GZmzj3LcWo+8u/T/m/xjEkhIRUbiTXn7xR3rvyeKPsXdcQMpDkSmgyXGIiKjrJ/lbJ96Kw3IOQ0l9CUakjMCApAEt9sm0ZqKovuWURmJ9+XpWe5hwutx48efNePGXzaiqbxxflJsSg2uPGIQTxvaGQc/7t0QUHHWLdnVqf12iCXGTo3M6jgdwC2IDECbVwomjELl4xiIiClM6RYcDeh2A4wYc1yZoFJ+e9KnX503p7XtKIwqu+75Yg0e+WY+KOgfckqVQBbaW1uHG9//E4L9/hUteX4If1rUN/omIujs5jqOkE1lVAaScPgQKb26FjMvl0mackJknrFYrBg4ciPvuuy+kCfAYOBIRRahYUyxePupl6Jodyo/pdwxmDpgZ0nJRo027a/Dagm0+q0NO/d+tKcYN7/6BT5czAQURBY6iU6Az6Tv1nJK5a2DbXBGwMpF/Dz/8MJ577jk888wzWLt2rfb4kUcewdNPPx2yqmNXVSKiCDYpexJ+P+935FfmI8GcgPQYTtYcLt5fkt+h/SobXHh3ST5OHNc74GUiouikGHSIP7A3Kr/dAnR0mmCHG6XvrEP23w8IcOnIm99++w0nnngiZs5svBncr18/vPPOO1i8eDFChS2OREQRzqgzYmDyQAaNYaSyzoFXft3S4f0LK+oCWh4iorhDeiP5L0OgS+l4dlV3TefmfqTuc+CBB2LevHnYsGGD9njFihX49ddfMWPGDIQKWxyJiIi62a0frpCb9R1WXd/RJgAioq4nXYvdLxMx4zJQ/2cxyj7aCNjbGS9nUFjdAVBVVdXisdls1pbmbrvtNm2/YcOGQa/Xa2MeH3jgAZxzzjkh+0zY4khERNSNam1OfLO6cwlvbC7OvUlEwRvvGDMuE1k37g9dvNHvvrFTojOraqDl5OQgMTGxaZkzZ06bfd5//3289dZbePvtt7Fs2TK89tpreOyxx7R/Q4UtjkRERN3oq5WdS3kvzMbOJa0gItpXhiQLLIOTUfdHcWO2rtaMOiTNaJvRm/ZdQUEBEhISmh63bm0Ut9xyi9bqeOaZZ2qPR48ejW3btmlB5qxZsxAKbHEkIiLqRrV2Z+efY3Nh7a6WXZeIiAIt4YhcGDJj2m7QK8i8apzWvZUCUO8JCS0Wb4FjXV0ddLqWoZp0WXW7Q9dDhYEjERFFjJ9//hnHH388srOztQuaTz75pMV2md/qzjvvRK9evbR5r4488khs3LgxqGV8/qfNnX5Og8OFDUXVASkPEZEvhlQrMq4Yi7S/jkbiSQMRN60Pkk4bjOx7DoQxK5YVF0LHH3+8Nqbxv//9L7Zu3YqPP/4Yjz/+OE4++eSQlYmBIxERRYza2lqMHTsWzz77rNftMsfVU089heeffx6LFi1CbGwspk+fjoaGhqCUTwLXwsrO/y7pJRbKSZ2JKHrpzAZYBiUh/oBsJB3dH3ETsqAzMEQItaeffhqnnnoqrrzySgwfPhw333wzLrvsMtx3330hKxPHOBIRUcSQNOS+UpFL4PXEE0/g9ttv1+a+Eq+//joyMzO1lknPOJFAqrO7vA4V6ojfNpXipPF9urlEREQUieLj47VzmizhgrcTiIioR9iyZQsKCwu17qkekq1u8uTJWLBgQVDKcMfHK7v83LxidlUlIqLwxRZHIiLqESRoFNLC2Jw89mzzxmazaYuv+bU66teNJfh4+U501dpdDByJiCh8scWRiIiimqQ2bz6flsyv1RUrtld0uZuqqHe4Ud+FjKxERETBwMCRiIh6hKysLO3foqKiFuvlsWebN7Nnz0ZlZWXTIvNrdcXvW8uwr2psDByJiCg8MXAkIqIeoX///lqAOG/evBbdTiW76pQpU3w+T+bPaj2nVles3F6BfSGzpcVbjPv0GkRERIHCMY5ERBQxampqkJeX1yIhzvLly5GSkoLc3Fxcf/31uP/++zF48GAtkLzjjju0OR9POumkgJZLMrqW1Dr26TVmjM6CxajvtjIRERF1JwaOREQUMX7//XccfvjhTY9vvPFG7d9Zs2Zh7ty5uPXWW7W5Hi+99FJUVFTgoIMOwtdffw2LxRLQci3c3Lluqia9grE5SdhaUgdFAY4f0wv/N3NEwMpHRES0rxg4EhFRxDjssMO01j1fFEXBvffeqy3BtKWk1u92ow44dUIOlmwtQ3KsCTceNRRTBqYGrXxERET7ioEjERHRPspNiUGcSUGNvW1Qe/SIDMw+dgT6p8WynomIKGIxOQ4REdE+mjooFZccMqjppCqJbmKMOqTGmnDz9GEMGomIKOIxcCQiItpH0kX2mmmDkZloQXKMEf3SYpESa9bmday3u1i/REQU8Rg4EhERdccJVafguDHZcKtAWY0NVQ0ODM6Iw9CseNYvERFFPI5xJCIi6iY3Tx+CjHgzlhdUIDvJgksOGcApNoiIqEdg4EhERNRNzAa9FiwSERH1NOyqSkRERERERH4xcCQiIiIiIiK/GDgSERERERGRXwwciYiIiIiIiIEjERERERERdR1bHImIiIiIiMgvBo5ERERERETkFwNHIiIiIiIi8ouBIxEREREREfnFwJGIiIiIiIj8YuBIREREREREfjFwJCIiIiIiIr8YOBIREREREREDRyIiIiIiIuo6tjgSERERERGRXwwciYiIiIiIyC8GjkREREREROQXA0ciIiIiIiLyi4EjERERERER+WXwv5mIiIiIiPbJ768Cv/wDcDYAQ2cCxz4CGMysVIooDByJiIiIiAJl6WvAF9fvfbxsLlBTDJz9DuucIgoDRyIiIiKiQFBV4PNr267f8CVgqwbM8az3MLRs6bGwWq3d/rr19fUAfkKk4hhHIiIiIqJAWDLX97bCVaxziigMHImIiIiIAuH3f/veZrCwzimiMHAkIiIiIgqE1MG+t/UayzqniMLAkYiIiIgoEA69xfv6yxcAOl6GU2ThN5aIiIiIKBCyRgHnfQJY0wGdAUjqB9y2A8gawfomv/r16wdFUdosV111FUKFWVWJiIiIiAJl4OHA3/JYv9QpS5Ysgcvlanq8atUqHHXUUTjttNMQKgwciYiIiIiIwkh6enqLxw899BAGDhyIQw89NGRlYldVIiIiIiKiMGW32/Hmm2/ioosu0rqrhgpbHImIiIiIiIKkqqqqxWOz2awtvnzyySeoqKjABRdcgFBiiyMREREREVGQ5OTkIDExsWmZM2eO3/1ffvllzJgxA9nZ2SH9jNjiSERRzel0wuFwwGKxhLT7BxEREUWHgoICJCQkND3219q4bds2fP/99/joo48QagwciSiqVFdXY/Hixdi9ezd27dqldReRgLFPnz4444wzEBsbG+oiEhERUQ+WkJDQInD059VXX0VGRgZmzpyJUGNXVSKKGjabDW+99RZ++eUXrFu3DpWVlVBVFW63G/n5+VpXECIiIqJw4Ha7tcBx1qxZMBhC397HwJGIoqprSGFhoc/tZWVlWLt2bVDLREREROSNdFGVG9uS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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "CMAP = \"tab10\"\n", "\n", "fig, axes = plt.subplots(1, 2, figsize=(12, 6))\n", "for ax, Z, title in zip(\n", " axes,\n", " [embed_default, embed_maxout],\n", " [\"Default encoder (DeepPReLUNet)\", \"MaxoutEncoder (k=3)\"],\n", "):\n", " sc = ax.scatter(Z[:, 0], Z[:, 1], c=y, cmap=CMAP, s=8, alpha=0.85)\n", " ax.set(title=title)\n", "fig.colorbar(sc, ax=axes, label=\"digit\", ticks=range(10))\n", "plt.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The registry let us swap a meaningfully different architecture into Glass Box UMAP without touching the library, and the result is a sensible embedding.\n", "\n", "## Exact attribution still works\n", "\n", "The whole reason for the bias-free, piecewise-linear constraints is that `compute_contributions` returns a contribution from each input feature to each embedding coordinate, and those contributions sum exactly to the embedding. Maxout was designed to keep that property intact: a `k`-way max of bias-free linear functions is itself bias-free and piecewise linear. We can verify that the property still holds end to end.\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2026-05-11T22:17:17.915890Z", "iopub.status.busy": "2026-05-11T22:17:17.915795Z", "iopub.status.idle": "2026-05-11T22:17:18.362452Z", "shell.execute_reply": "2026-05-11T22:17:18.362119Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "contributions shape: (1797, 2, 64)\n", "max |reconstructed - embedding|: 3.81e-06\n", "matches embedding (atol 1e-4): True\n" ] } ], "source": [ "contributions = reducer_maxout.compute_contributions(X)\n", "n_samples, n_components = contributions.shape[:2]\n", "reconstructed = contributions.reshape(n_samples, n_components, -1).sum(axis=2)\n", "\n", "print(f\"contributions shape: {contributions.shape}\")\n", "print(f\"max |reconstructed - embedding|: {np.max(np.abs(reconstructed - embed_maxout)):.2e}\")\n", "print(f\"matches embedding (atol 1e-4): {np.allclose(reconstructed, embed_maxout, atol=1e-4)}\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Saving/Loading\n", "\n", "Models built on a custom encoder and then saved to disk need a small extra step at load time. Glass Box UMAP checkpoints store the encoder by *name*, not by class. When you call `load`, the library looks the name up, rebuilds an encoder of the same architecture, and then reattaches the saved weights. If your encoder's name does not appear in `view_registry()` at the moment `load` runs, the lookup fails with `ValueError: Encoder 'your_encoder_name' not found`.\n", "\n", "The fix is to make sure your `@register_encoder(...)` decorator has executed before you call `load`. In practice that means putting your encoder in an importable module and importing it on the loading side:\n", "\n", "```python\n", "# Either import it\n", "import my_project.encoders\n", "\n", "# Or define and register it\n", "@register_encoder(\"your_encoder_name\")\n", "class YourEncoder(nn.Module):\n", " ...\n", "\n", "reducer = GlassBoxUMAP.load(\"model.pt\")\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conclusion\n", "\n", "Custom encoders can be registered using a one-line decorator, so long as its constructor takes `input_dims` and `n_componens` as its first two arguments, and `forward` returns a tensor of shape `(batch, n_components)`. If you create a custom encoder, always verify it preserves exact feature attributions.\n", "\n", ":::{warning}\n", "Please keep in mind that the kNN graph is upstream of the encoder. Custom architectures change how the model represents inputs, not which inputs are considered neighbors. If you need a different notion of similarity, consider supplying a precomputed nearest-neighbors graph.\n", ":::\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "glass-box-umap (3.13.1)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.1" } }, "nbformat": 4, "nbformat_minor": 4 }