{"cells": [{"cell_type": "markdown", "id": "100c2262", "metadata": {"papermill": {"duration": 0.018049, "end_time": "2023-03-14T16:08:42.495700", "exception": false, "start_time": "2023-03-14T16:08:42.477651", "status": "completed"}, "tags": []}, "source": ["\n", "# Tutorial 9: Normalizing Flows for Image Modeling\n", "\n", "* **Author:** Phillip Lippe\n", "* **License:** CC BY-SA\n", "* **Generated:** 2023-03-14T16:07:05.259127\n", "\n", "In this tutorial, we will take a closer look at complex, deep normalizing flows.\n", "The most popular, current application of deep normalizing flows is to model datasets of images.\n", "As for other generative models, images are a good domain to start working on because\n", "(1) CNNs are widely studied and strong models exist,\n", "(2) images are high-dimensional and complex,\n", "and (3) images are discrete integers.\n", "In this tutorial, we will review current advances in normalizing flows for image modeling,\n", "and get hands-on experience on coding normalizing flows.\n", "Note that normalizing flows are commonly parameter heavy and therefore computationally expensive.\n", "We will use relatively simple and shallow flows to save computational cost and allow you to run the notebook on CPU,\n", "but keep in mind that a simple way to improve the scores of the flows we study here is to make them deeper.\n", "This notebook is part of a lecture series on Deep Learning at the University of Amsterdam.\n", "The full list of tutorials can be found at https://uvadlc-notebooks.rtfd.io.\n", "\n", "\n", "---\n", "Open in [![Open In Colab](data:image/png;base64,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){height=\"20px\" width=\"117px\"}](https://colab.research.google.com/github/PytorchLightning/lightning-tutorials/blob/publication/.notebooks/course_UvA-DL/09-normalizing-flows.ipynb)\n", "\n", "Give us a \u2b50 [on Github](https://www.github.com/Lightning-AI/lightning/)\n", "| Check out [the documentation](https://pytorch-lightning.readthedocs.io/en/stable/)\n", "| Join us [on Slack](https://www.pytorchlightning.ai/community)"]}, {"cell_type": "markdown", "id": "87ad8b6e", "metadata": {"papermill": {"duration": 0.008889, "end_time": "2023-03-14T16:08:42.513816", "exception": false, "start_time": "2023-03-14T16:08:42.504927", "status": "completed"}, "tags": []}, "source": ["## Setup\n", "This notebook requires some packages besides pytorch-lightning."]}, {"cell_type": "code", "execution_count": 1, "id": "d2626593", "metadata": {"colab": {}, "colab_type": "code", "execution": {"iopub.execute_input": "2023-03-14T16:08:42.564704Z", "iopub.status.busy": "2023-03-14T16:08:42.564240Z", "iopub.status.idle": "2023-03-14T16:08:45.876740Z", "shell.execute_reply": "2023-03-14T16:08:45.875371Z"}, "id": "LfrJLKPFyhsK", "lines_to_next_cell": 0, "papermill": {"duration": 3.355994, "end_time": "2023-03-14T16:08:45.879658", "exception": false, "start_time": "2023-03-14T16:08:42.523664", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\r\n", "\u001b[0m"]}], "source": ["! pip install --quiet \"ipython[notebook]>=8.0.0, <8.12.0\" \"seaborn\" \"pytorch-lightning>=1.4, <2.0.0\" \"torch>=1.8.1, <1.14.0\" \"tabulate\" \"lightning>=2.0.0rc0\" \"torchmetrics>=0.7, <0.12\" \"torchvision\" \"matplotlib\" \"setuptools==67.4.0\""]}, {"cell_type": "markdown", "id": "c4fcf3d8", "metadata": {"papermill": {"duration": 0.009032, "end_time": "2023-03-14T16:08:45.902797", "exception": false, "start_time": "2023-03-14T16:08:45.893765", "status": "completed"}, "tags": []}, "source": ["
\n", "Throughout this notebook, we make use of [PyTorch Lightning](https://lightning.ai/docs/pytorch/stable/).\n", "The first cell imports our usual libraries."]}, {"cell_type": "code", "execution_count": 2, "id": "91b34352", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:45.922980Z", "iopub.status.busy": "2023-03-14T16:08:45.922606Z", "iopub.status.idle": "2023-03-14T16:08:49.148569Z", "shell.execute_reply": "2023-03-14T16:08:49.147852Z"}, "papermill": {"duration": 3.238278, "end_time": "2023-03-14T16:08:49.150284", "exception": false, "start_time": "2023-03-14T16:08:45.912006", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["Global seed set to 42\n"]}, {"name": "stdout", "output_type": "stream", "text": ["Using device cuda:0\n"]}], "source": ["import math\n", "import os\n", "import time\n", "import urllib.request\n", "from urllib.error import HTTPError\n", "\n", "import lightning as L\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", "import matplotlib_inline.backend_inline\n", "import numpy as np\n", "import seaborn as sns\n", "import tabulate\n", "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "import torch.optim as optim\n", "import torch.utils.data as data\n", "import torchvision\n", "from IPython.display import HTML, display\n", "from lightning.pytorch.callbacks import LearningRateMonitor, ModelCheckpoint\n", "from matplotlib.colors import to_rgb\n", "from torch import Tensor\n", "from torchvision import transforms\n", "from torchvision.datasets import MNIST\n", "from tqdm.notebook import tqdm\n", "\n", "%matplotlib inline\n", "matplotlib_inline.backend_inline.set_matplotlib_formats(\"svg\", \"pdf\") # For export\n", "matplotlib.rcParams[\"lines.linewidth\"] = 2.0\n", "sns.reset_orig()\n", "\n", "# Path to the folder where the datasets are/should be downloaded (e.g. MNIST)\n", "DATASET_PATH = os.environ.get(\"PATH_DATASETS\", \"data\")\n", "# Path to the folder where the pretrained models are saved\n", "CHECKPOINT_PATH = os.environ.get(\"PATH_CHECKPOINT\", \"saved_models/tutorial11\")\n", "\n", "# Setting the seed\n", "L.seed_everything(42)\n", "\n", "# Ensure that all operations are deterministic on GPU (if used) for reproducibility\n", "torch.backends.cudnn.deterministic = True\n", "torch.backends.cudnn.benchmark = False\n", "\n", "# Fetching the device that will be used throughout this notebook\n", "device = torch.device(\"cpu\") if not torch.cuda.is_available() else torch.device(\"cuda:0\")\n", "print(\"Using device\", device)"]}, {"cell_type": "markdown", "id": "4bcabe69", "metadata": {"papermill": {"duration": 0.009295, "end_time": "2023-03-14T16:08:49.170996", "exception": false, "start_time": "2023-03-14T16:08:49.161701", "status": "completed"}, "tags": []}, "source": ["Again, we have a few pretrained models. We download them below to the specified path above."]}, {"cell_type": "code", "execution_count": 3, "id": "0a65243d", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:49.191095Z", "iopub.status.busy": "2023-03-14T16:08:49.190541Z", "iopub.status.idle": "2023-03-14T16:08:50.538855Z", "shell.execute_reply": "2023-03-14T16:08:50.537598Z"}, "papermill": {"duration": 1.361205, "end_time": "2023-03-14T16:08:50.541518", "exception": false, "start_time": "2023-03-14T16:08:49.180313", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Downloading https://raw.githubusercontent.com/phlippe/saved_models/main/tutorial11/MNISTFlow_simple.ckpt...\n"]}, {"name": "stdout", "output_type": "stream", "text": ["Downloading https://raw.githubusercontent.com/phlippe/saved_models/main/tutorial11/MNISTFlow_vardeq.ckpt...\n"]}, {"name": "stdout", "output_type": "stream", "text": ["Downloading https://raw.githubusercontent.com/phlippe/saved_models/main/tutorial11/MNISTFlow_multiscale.ckpt...\n"]}], "source": ["# Github URL where saved models are stored for this tutorial\n", "base_url = \"https://raw.githubusercontent.com/phlippe/saved_models/main/tutorial11/\"\n", "# Files to download\n", "pretrained_files = [\"MNISTFlow_simple.ckpt\", \"MNISTFlow_vardeq.ckpt\", \"MNISTFlow_multiscale.ckpt\"]\n", "# Create checkpoint path if it doesn't exist yet\n", "os.makedirs(CHECKPOINT_PATH, exist_ok=True)\n", "\n", "# For each file, check whether it already exists. If not, try downloading it.\n", "for file_name in pretrained_files:\n", " file_path = os.path.join(CHECKPOINT_PATH, file_name)\n", " if not os.path.isfile(file_path):\n", " file_url = base_url + file_name\n", " print(\"Downloading %s...\" % file_url)\n", " try:\n", " urllib.request.urlretrieve(file_url, file_path)\n", " except HTTPError as e:\n", " print(\n", " \"Something went wrong. Please try to download the file from the GDrive folder, or contact the author with the full output including the following error:\\n\",\n", " e,\n", " )"]}, {"cell_type": "markdown", "id": "23698177", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.009424, "end_time": "2023-03-14T16:08:50.566184", "exception": false, "start_time": "2023-03-14T16:08:50.556760", "status": "completed"}, "tags": []}, "source": ["We will use the MNIST dataset in this notebook.\n", "MNIST constitutes, despite its simplicity, a challenge for small generative models as it requires the global understanding of an image.\n", "At the same time, we can easily judge whether generated images come from the same distribution as the dataset\n", "(i.e. represent real digits), or not.\n", "\n", "To deal better with the discrete nature of the images, we transform them\n", "from a range of 0-1 to a range of 0-255 as integers."]}, {"cell_type": "code", "execution_count": 4, "id": "9965c930", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:50.586882Z", "iopub.status.busy": "2023-03-14T16:08:50.586498Z", "iopub.status.idle": "2023-03-14T16:08:51.988192Z", "shell.execute_reply": "2023-03-14T16:08:51.987570Z"}, "papermill": {"duration": 1.413875, "end_time": "2023-03-14T16:08:51.989455", "exception": false, "start_time": "2023-03-14T16:08:50.575580", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\n", "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to /__w/6/s/.datasets/MNIST/raw/train-images-idx3-ubyte.gz\n"]}, {"data": {"application/vnd.jupyter.widget-view+json": {"model_id": "8e868462f756444d9b1a566c8f77d457", "version_major": 2, "version_minor": 0}, "text/plain": [" 0%| | 0/9912422 [00:00 make them a tensor and discretize\n", "transform = transforms.Compose([transforms.ToTensor(), discretize])\n", "\n", "# Loading the training dataset. We need to split it into a training and validation part\n", "train_dataset = MNIST(root=DATASET_PATH, train=True, transform=transform, download=True)\n", "L.seed_everything(42)\n", "train_set, val_set = torch.utils.data.random_split(train_dataset, [50000, 10000])\n", "\n", "# Loading the test set\n", "test_set = MNIST(root=DATASET_PATH, train=False, transform=transform, download=True)\n", "\n", "# We define a set of data loaders that we can use for various purposes later.\n", "# Note that for actually training a model, we will use different data loaders\n", "# with a lower batch size.\n", "train_loader = data.DataLoader(train_set, batch_size=256, shuffle=False, drop_last=False)\n", "val_loader = data.DataLoader(val_set, batch_size=64, shuffle=False, drop_last=False, num_workers=4)\n", "test_loader = data.DataLoader(test_set, batch_size=64, shuffle=False, drop_last=False, num_workers=4)"]}, {"cell_type": "markdown", "id": "f2a87c6f", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.010169, "end_time": "2023-03-14T16:08:52.011203", "exception": false, "start_time": "2023-03-14T16:08:52.001034", "status": "completed"}, "tags": []}, "source": ["In addition, we will define below a function to simplify the visualization of images/samples.\n", "Some training examples of the MNIST dataset is shown below."]}, {"cell_type": "code", "execution_count": 5, "id": "d170c817", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:52.035150Z", "iopub.status.busy": "2023-03-14T16:08:52.034845Z", "iopub.status.idle": "2023-03-14T16:08:52.192780Z", "shell.execute_reply": "2023-03-14T16:08:52.192170Z"}, "papermill": {"duration": 0.172541, "end_time": "2023-03-14T16:08:52.193954", "exception": false, "start_time": "2023-03-14T16:08:52.021413", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/pdf": "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jzHkUR7z5BmQxxLy/PUIcfTY0DOonH9YJlopz+M+8C2wZs2aVjAf8E88k0cccp6ohImesuRFYO0iaB+/DTgflzfPwuHDh9l6zrFzTnnyGEMe5TFPnoWSPR4IRsoFTabmdx5DzCMGzLmWT1taWviTdzNIns8KDveDonmVPAEGA3hkif8KnI+153WCTKcBXwO8CU899VR6njzGkEd5tOfJozyW4TEQ6DajIx4nLaMGKnPtn9ZGuhZrexPZMnbsWM7Snn5ReeodowA8zgXs78x0bGXeEuA83VcETkvC6taOHTvS8+TRgDzKozwGn8pjQJkeM011HDS1Ju9kz2NdINJ6mlzPCeCCJnnzzPwccMYT3MD0xk2nvI+AqWDPnj2ZzvR7QI/Lly9Pz5PHGPIoj+a8/uCxfOx5L4De0tI9lt9vxQWtgsbVl0G2whnz+Pb/HWDQoEFsLuViVivB+vXr+b6j5TR4Nr4JsIzt7e3pefIYQx7dkEd5lEdrXj/yyDcqFi9eHPN4I/gSeBE0Nzdzbttgh+r0PwZ1nJpp06ZlK1hiHh9D8RzIJlOOjmPAmDFjOOjg9gBUhNYEcIb90aNHs4wrgFOePMaQRzfkUR7l0ZrXjzySjo6OEeBuQI8o9p9AZAfekHU9VKf/kYPyyvcYgaPwuK7KwYMH94J7QE0ls2bNSlh8pTJPHmPIoxvyKI/n5NGW1888Ki9nnjz6kSePfuTJox958uhHnjz6kSePfuTJox958uhHnjz6kSePfuTJox958uhHnjz6kSePfuSFHsWljTz6gTz6gTz6gTz6gTz6gTz6wf8BhQQ12wplbmRzdHJlYW0KZW5kb2JqCjE0IDAgb2JqCjM0NDQKZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFsgMTEgMCBSIF0gL0NvdW50IDEgPj4KZW5kb2JqCjE1IDAgb2JqCjw8IC9DcmVhdG9yIChNYXRwbG90bGliIHYzLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZykKL1Byb2R1Y2VyIChNYXRwbG90bGliIHBkZiBiYWNrZW5kIHYzLjcuMSkgL0NyZWF0aW9uRGF0ZSAoRDoyMDIzMDMxNDE2MDg1MlopCj4+CmVuZG9iagp4cmVmCjAgMTYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDE2IDAwMDAwIG4gCjAwMDAwMDUxNTUgMDAwMDAgbiAKMDAwMDAwMDYwNyAwMDAwMCBuIAowMDAwMDAwNjI4IDAwMDAwIG4gCjAwMDAwMDA2ODggMDAwMDAgbiAKMDAwMDAwMDcwOSAwMDAwMCBuIAowMDAwMDAwNzMwIDAwMDAwIG4gCjAwMDAwMDAwNjUgMDAwMDAgbiAKMDAwMDAwMDM0NCAwMDAwMCBuIAowMDAwMDAwNTg3IDAwMDAwIG4gCjAwMDAwMDAyMDggMDAwMDAgbiAKMDAwMDAwMDU2NyAwMDAwMCBuIAowMDAwMDAwNzYyIDAwMDAwIG4gCjAwMDAwMDUxMzQgMDAwMDAgbiAKMDAwMDAwNTIxNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDE2IC9Sb290IDEgMCBSIC9JbmZvIDE1IDAgUiA+PgpzdGFydHhyZWYKNTM2NgolJUVPRgo=", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:08:52.069465\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["def show_imgs(imgs, title=None, row_size=4):\n", " # Form a grid of pictures (we use max. 8 columns)\n", " num_imgs = imgs.shape[0] if isinstance(imgs, Tensor) else len(imgs)\n", " is_int = imgs.dtype == torch.int32 if isinstance(imgs, Tensor) else imgs[0].dtype == torch.int32\n", " nrow = min(num_imgs, row_size)\n", " ncol = int(math.ceil(num_imgs / nrow))\n", " imgs = torchvision.utils.make_grid(imgs, nrow=nrow, pad_value=128 if is_int else 0.5)\n", " np_imgs = imgs.cpu().numpy()\n", " # Plot the grid\n", " plt.figure(figsize=(1.5 * nrow, 1.5 * ncol))\n", " plt.imshow(np.transpose(np_imgs, (1, 2, 0)), interpolation=\"nearest\")\n", " plt.axis(\"off\")\n", " if title is not None:\n", " plt.title(title)\n", " plt.show()\n", " plt.close()\n", "\n", "\n", "show_imgs([train_set[i][0] for i in range(8)])"]}, {"cell_type": "markdown", "id": "bd028bb1", "metadata": {"papermill": {"duration": 0.010648, "end_time": "2023-03-14T16:08:52.215564", "exception": false, "start_time": "2023-03-14T16:08:52.204916", "status": "completed"}, "tags": []}, "source": ["## Normalizing Flows as generative model\n", "\n", "In the previous lectures, we have seen Energy-based models, Variational Autoencoders (VAEs)\n", "and Generative Adversarial Networks (GANs) as example of generative models.\n", "However, none of them explicitly learn the probability density function $p(x)$ of the real input data.\n", "While VAEs model a lower bound, energy-based models only implicitly learn the probability density.\n", "GANs on the other hand provide us a sampling mechanism for generating new data, without offering a likelihood estimate.\n", "The generative model we will look at here, called Normalizing Flows, actually models the true data distribution\n", "$p(x)$ and provides us with an exact likelihood estimate.\n", "Below, we can visually compare VAEs, GANs and Flows\n", "(figure credit - [Lilian Weng](https://lilianweng.github.io/lil-log/2018/10/13/flow-based-deep-generative-models.html)):\n", "\n", "
\n", "\n", "The major difference compared to VAEs is that flows use *invertible* functions $f$\n", "to map the input data $x$ to a latent representation $z$.\n", "To realize this, $z$ must be of the same shape as $x$.\n", "This is in contrast to VAEs where $z$ is usually much lower dimensional than the original input data.\n", "However, an invertible mapping also means that for every data point $x$, we have a corresponding latent representation\n", "$z$ which allows us to perform lossless reconstruction ($z$ to $x$).\n", "In the visualization above, this means that $x=x'$ for flows, no matter what invertible function $f$ and input $x$ we choose.\n", "\n", "Nonetheless, how are normalizing flows modeling a probability density with an invertible function?\n", "The answer to this question is the rule for change of variables.\n", "Specifically, given a prior density $p_z(z)$ (e.g. Gaussian) and an invertible function $f$,\n", "we can determine $p_x(x)$ as follows:\n", "\n", "$$\n", "\\begin{split}\n", " \\int p_x(x) dx & = \\int p_z(z) dz = 1 \\hspace{1cm}\\text{(by definition of a probability distribution)}\\\\\n", " \\Leftrightarrow p_x(x) & = p_z(z) \\left|\\frac{dz}{dx}\\right| = p_z(f(x)) \\left|\\frac{df(x)}{dx}\\right|\n", "\\end{split}\n", "$$\n", "\n", "Hence, in order to determine the probability of $x$, we only need to determine its probability in latent space,\n", "and get the derivate of $f$.\n", "Note that this is for a univariate distribution, and $f$ is required to be invertible and smooth.\n", "For a multivariate case, the derivative becomes a Jacobian of which we need to take the determinant.\n", "As we usually use the log-likelihood as objective, we write the multivariate term with logarithms below:\n", "\n", "$$\n", "\\log p_x(\\mathbf{x}) = \\log p_z(f(\\mathbf{x})) + \\log{} \\left|\\det \\frac{df(\\mathbf{x})}{d\\mathbf{x}}\\right|\n", "$$\n", "\n", "Although we now know how a normalizing flow obtains its likelihood, it might not be clear what a normalizing flow does intuitively.\n", "For this, we should look from the inverse perspective of the flow starting with the prior probability density $p_z(z)$.\n", "If we apply an invertible function on it, we effectively \"transform\" its probability density.\n", "For instance, if $f^{-1}(z)=z+1$, we shift the density by one while still remaining a valid probability distribution,\n", "and being invertible.\n", "We can also apply more complex transformations, like scaling: $f^{-1}(z)=2z+1$, but there you might see a difference.\n", "When you scale, you also change the volume of the probability density, as for example on uniform distributions\n", "(figure credit - [Eric Jang](https://blog.evjang.com/2018/01/nf1.html)):\n", "\n", "
\n", "\n", "You can see that the height of $p(y)$ should be lower than $p(x)$ after scaling.\n", "This change in volume represents $\\left|\\frac{df(x)}{dx}\\right|$ in our equation above,\n", "and ensures that even after scaling, we still have a valid probability distribution.\n", "We can go on with making our function $f$ more complex.\n", "However, the more complex $f$ becomes, the harder it will be to find the inverse $f^{-1}$ of it,\n", "and to calculate the log-determinant of the Jacobian $\\log{} \\left|\\det \\frac{df(\\mathbf{x})}{d\\mathbf{x}}\\right|$.\n", "An easier trick to stack multiple invertible functions $f_{1,...,K}$ after each other, as all together,\n", "they still represent a single, invertible function.\n", "Using multiple, learnable invertible functions, a normalizing flow attempts to transform\n", "$p_z(z)$ slowly into a more complex distribution which should finally be $p_x(x)$.\n", "We visualize the idea below\n", "(figure credit - [Lilian Weng](https://lilianweng.github.io/lil-log/2018/10/13/flow-based-deep-generative-models.html)):\n", "\n", "
\n", "\n", "Starting from $z_0$, which follows the prior Gaussian distribution, we sequentially apply the invertible\n", "functions $f_1,f_2,...,f_K$, until $z_K$ represents $x$.\n", "Note that in the figure above, the functions $f$ represent the inverted function from $f$ we had above\n", "(here: $f:Z\\to X$, above: $f:X\\to Z$).\n", "This is just a different notation and has no impact on the actual flow design because all $f$ need to be invertible anyways.\n", "When we estimate the log likelihood of a data point $x$ as in the equations above,\n", "we run the flows in the opposite direction than visualized above.\n", "Multiple flow layers have been proposed that use a neural network as learnable parameters,\n", "such as the planar and radial flow.\n", "However, we will focus here on flows that are commonly used in image\n", "modeling, and will discuss them in the rest of the notebook along with\n", "the details of how to train a normalizing flow."]}, {"cell_type": "markdown", "id": "be852389", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.010512, "end_time": "2023-03-14T16:08:52.236613", "exception": false, "start_time": "2023-03-14T16:08:52.226101", "status": "completed"}, "tags": []}, "source": ["## Normalizing Flows on images\n", "\n", "
\n", "\n", "To become familiar with normalizing flows, especially for the application of image modeling,\n", "it is best to discuss the different elements in a flow along with the implementation.\n", "As a general concept, we want to build a normalizing flow that maps an input image (here MNIST) to an equally sized latent space:\n", "\n", "
\n", "\n", "As a first step, we will implement a template of a normalizing flow in PyTorch Lightning.\n", "During training and validation, a normalizing flow performs density estimation in the forward direction.\n", "For this, we apply a series of flow transformations on the input $x$ and estimate the probability\n", "of the input by determining the probability of the transformed point $z$ given a prior,\n", "and the change of volume caused by the transformations.\n", "During inference, we can do both density estimation and sampling new points by inverting the flow transformations.\n", "Therefore, we define a function `_get_likelihood` which performs density estimation,\n", "and `sample` to generate new examples.\n", "The functions `training_step`, `validation_step` and `test_step` all make use of `_get_likelihood`.\n", "\n", "The standard metric used in generative models, and in particular normalizing flows, is bits per dimensions (bpd).\n", "Bpd is motivated from an information theory perspective and describes how many bits we would need to encode a particular example in our modeled distribution.\n", "The less bits we need, the more likely the example in our distribution.\n", "When we test for the bits per dimension of our test dataset, we can judge whether our model generalizes to new samples of the dataset and didn't memorize the training dataset.\n", "In order to calculate the bits per dimension score, we can rely on the negative log-likelihood and change the log base (as bits are binary while NLL is usually exponential):\n", "\n", "$$\\text{bpd} = \\text{nll} \\cdot \\log_2\\left(\\exp(1)\\right) \\cdot \\left(\\prod d_i\\right)^{-1}$$\n", "\n", "where $d_1,...,d_K$ are the dimensions of the input.\n", "For images, this would be the height, width and channel number.\n", "We divide the log likelihood by these extra dimensions to have a metric which we can compare for different image resolutions.\n", "In the original image space, MNIST examples have a bits per dimension\n", "score of 8 (we need 8 bits to encode each pixel as there are 256\n", "possible values)."]}, {"cell_type": "code", "execution_count": 6, "id": "e75ff1f5", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:52.260104Z", "iopub.status.busy": "2023-03-14T16:08:52.259443Z", "iopub.status.idle": "2023-03-14T16:08:52.276630Z", "shell.execute_reply": "2023-03-14T16:08:52.276152Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.031425, "end_time": "2023-03-14T16:08:52.278733", "exception": false, "start_time": "2023-03-14T16:08:52.247308", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class ImageFlow(L.LightningModule):\n", " def __init__(self, flows, import_samples=8):\n", " \"\"\"\n", " Args:\n", " flows: A list of flows (each a nn.Module) that should be applied on the images.\n", " import_samples: Number of importance samples to use during testing (see explanation below). Can be changed at any time\n", " \"\"\"\n", " super().__init__()\n", " self.flows = nn.ModuleList(flows)\n", " self.import_samples = import_samples\n", " # Create prior distribution for final latent space\n", " self.prior = torch.distributions.normal.Normal(loc=0.0, scale=1.0)\n", " # Example input for visualizing the graph\n", " self.example_input_array = train_set[0][0].unsqueeze(dim=0)\n", "\n", " def forward(self, imgs):\n", " # The forward function is only used for visualizing the graph\n", " return self._get_likelihood(imgs)\n", "\n", " def encode(self, imgs):\n", " # Given a batch of images, return the latent representation z and ldj of the transformations\n", " z, ldj = imgs, torch.zeros(imgs.shape[0], device=self.device)\n", " for flow in self.flows:\n", " z, ldj = flow(z, ldj, reverse=False)\n", " return z, ldj\n", "\n", " def _get_likelihood(self, imgs, return_ll=False):\n", " \"\"\"Given a batch of images, return the likelihood of those.\n", "\n", " If return_ll is True, this function returns the log likelihood of the input. Otherwise, the ouptut metric is\n", " bits per dimension (scaled negative log likelihood)\n", " \"\"\"\n", " z, ldj = self.encode(imgs)\n", " log_pz = self.prior.log_prob(z).sum(dim=[1, 2, 3])\n", " log_px = ldj + log_pz\n", " nll = -log_px\n", " # Calculating bits per dimension\n", " bpd = nll * np.log2(np.exp(1)) / np.prod(imgs.shape[1:])\n", " return bpd.mean() if not return_ll else log_px\n", "\n", " @torch.no_grad()\n", " def sample(self, img_shape, z_init=None):\n", " \"\"\"Sample a batch of images from the flow.\"\"\"\n", " # Sample latent representation from prior\n", " if z_init is None:\n", " z = self.prior.sample(sample_shape=img_shape).to(device)\n", " else:\n", " z = z_init.to(device)\n", "\n", " # Transform z to x by inverting the flows\n", " ldj = torch.zeros(img_shape[0], device=device)\n", " for flow in reversed(self.flows):\n", " z, ldj = flow(z, ldj, reverse=True)\n", " return z\n", "\n", " def configure_optimizers(self):\n", " optimizer = optim.Adam(self.parameters(), lr=1e-3)\n", " # An scheduler is optional, but can help in flows to get the last bpd improvement\n", " scheduler = optim.lr_scheduler.StepLR(optimizer, 1, gamma=0.99)\n", " return [optimizer], [scheduler]\n", "\n", " def training_step(self, batch, batch_idx):\n", " # Normalizing flows are trained by maximum likelihood => return bpd\n", " loss = self._get_likelihood(batch[0])\n", " self.log(\"train_bpd\", loss)\n", " return loss\n", "\n", " def validation_step(self, batch, batch_idx):\n", " loss = self._get_likelihood(batch[0])\n", " self.log(\"val_bpd\", loss)\n", "\n", " def test_step(self, batch, batch_idx):\n", " # Perform importance sampling during testing => estimate likelihood M times for each image\n", " samples = []\n", " for _ in range(self.import_samples):\n", " img_ll = self._get_likelihood(batch[0], return_ll=True)\n", " samples.append(img_ll)\n", " img_ll = torch.stack(samples, dim=-1)\n", "\n", " # To average the probabilities, we need to go from log-space to exp, and back to log.\n", " # Logsumexp provides us a stable implementation for this\n", " img_ll = torch.logsumexp(img_ll, dim=-1) - np.log(self.import_samples)\n", "\n", " # Calculate final bpd\n", " bpd = -img_ll * np.log2(np.exp(1)) / np.prod(batch[0].shape[1:])\n", " bpd = bpd.mean()\n", "\n", " self.log(\"test_bpd\", bpd)"]}, {"cell_type": "markdown", "id": "939bf7af", "metadata": {"papermill": {"duration": 0.01055, "end_time": "2023-03-14T16:08:52.304898", "exception": false, "start_time": "2023-03-14T16:08:52.294348", "status": "completed"}, "tags": []}, "source": ["The `test_step` function differs from the training and validation step in that it makes use of importance sampling.\n", "We will discuss the motiviation and details behind this after\n", "understanding how flows model discrete images in continuous space."]}, {"cell_type": "markdown", "id": "248c83f9", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.010749, "end_time": "2023-03-14T16:08:52.326437", "exception": false, "start_time": "2023-03-14T16:08:52.315688", "status": "completed"}, "tags": []}, "source": ["### Dequantization\n", "\n", "Normalizing flows rely on the rule of change of variables, which is naturally defined in continuous space.\n", "Applying flows directly on discrete data leads to undesired density models where arbitrarly high likelihood are placed on a few, particular values.\n", "See the illustration below:\n", "\n", "
\n", "\n", "The black points represent the discrete points, and the green volume the density modeled by a normalizing flow in continuous space.\n", "The flow would continue to increase the likelihood for $x=0,1,2,3$ while having no volume on any other point.\n", "Remember that in continuous space, we have the constraint that the overall volume of the probability density must be 1 ($\\int p(x)dx=1$).\n", "Otherwise, we don't model a probability distribution anymore.\n", "However, the discrete points $x=0,1,2,3$ represent delta peaks with no width in continuous space.\n", "This is why the flow can place an infinite high likelihood on these few points while still representing a distribution in continuous space.\n", "Nonetheless, the learned density does not tell us anything about the distribution among the discrete points,\n", "as in discrete space, the likelihoods of those four points would have to sum to 1, not to infinity.\n", "\n", "To prevent such degenerated solutions, a common solution is to add a small amount of noise to each discrete value, which is also referred to as dequantization.\n", "Considering $x$ as an integer (as it is the case for images), the dequantized representation $v$ can be formulated as $v=x+u$ where $u\\in[0,1)^D$.\n", "Thus, the discrete value $1$ is modeled by a distribution over the interval $[1.0, 2.0)$, the value $2$ by an volume over $[2.0, 3.0)$, etc.\n", "Our objective of modeling $p(x)$ becomes:\n", "\n", "$$ p(x) = \\int p(x+u)du = \\int \\frac{q(u|x)}{q(u|x)}p(x+u)du = \\mathbb{E}_{u\\sim q(u|x)}\\left[\\frac{p(x+u)}{q(u|x)} \\right]$$\n", "\n", "with $q(u|x)$ being the noise distribution.\n", "For now, we assume it to be uniform, which can also be written as $p(x)=\\mathbb{E}_{u\\sim U(0,1)^D}\\left[p(x+u) \\right]$.\n", "\n", "In the following, we will implement Dequantization as a flow transformation itself.\n", "After adding noise to the discrete values, we additionally transform the volume into a Gaussian-like shape.\n", "This is done by scaling $x+u$ between $0$ and $1$, and applying the invert of the sigmoid function $\\sigma(z)^{-1} = \\log z - \\log 1-z$.\n", "If we would not do this, we would face two problems:\n", "\n", "1.\n", "The input is scaled between 0 and 256 while the prior distribution is a Gaussian with mean $0$ and standard deviation $1$.\n", "In the first iterations after initializing the parameters of the flow, we would have extremely low likelihoods for large values like $256$.\n", "This would cause the training to diverge instantaneously.\n", "2.\n", "As the output distribution is a Gaussian, it is beneficial for the flow to have a similarly shaped input distribution.\n", "This will reduce the modeling complexity that is required by the flow.\n", "\n", "Overall, we can implement dequantization as follows:"]}, {"cell_type": "code", "execution_count": 7, "id": "9e1c0242", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:52.349387Z", "iopub.status.busy": "2023-03-14T16:08:52.348820Z", "iopub.status.idle": "2023-03-14T16:08:52.362864Z", "shell.execute_reply": "2023-03-14T16:08:52.362396Z"}, "papermill": {"duration": 0.028177, "end_time": "2023-03-14T16:08:52.365251", "exception": false, "start_time": "2023-03-14T16:08:52.337074", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class Dequantization(nn.Module):\n", " def __init__(self, alpha=1e-5, quants=256):\n", " \"\"\"\n", " Args:\n", " alpha: small constant that is used to scale the original input.\n", " Prevents dealing with values very close to 0 and 1 when inverting the sigmoid\n", " quants: Number of possible discrete values (usually 256 for 8-bit image)\n", " \"\"\"\n", " super().__init__()\n", " self.alpha = alpha\n", " self.quants = quants\n", "\n", " def forward(self, z, ldj, reverse=False):\n", " if not reverse:\n", " z, ldj = self.dequant(z, ldj)\n", " z, ldj = self.sigmoid(z, ldj, reverse=True)\n", " else:\n", " z, ldj = self.sigmoid(z, ldj, reverse=False)\n", " z = z * self.quants\n", " ldj += np.log(self.quants) * np.prod(z.shape[1:])\n", " z = torch.floor(z).clamp(min=0, max=self.quants - 1).to(torch.int32)\n", " return z, ldj\n", "\n", " def sigmoid(self, z, ldj, reverse=False):\n", " # Applies an invertible sigmoid transformation\n", " if not reverse:\n", " ldj += (-z - 2 * F.softplus(-z)).sum(dim=[1, 2, 3])\n", " z = torch.sigmoid(z)\n", " else:\n", " z = z * (1 - self.alpha) + 0.5 * self.alpha # Scale to prevent boundaries 0 and 1\n", " ldj += np.log(1 - self.alpha) * np.prod(z.shape[1:])\n", " ldj += (-torch.log(z) - torch.log(1 - z)).sum(dim=[1, 2, 3])\n", " z = torch.log(z) - torch.log(1 - z)\n", " return z, ldj\n", "\n", " def dequant(self, z, ldj):\n", " # Transform discrete values to continuous volumes\n", " z = z.to(torch.float32)\n", " z = z + torch.rand_like(z).detach()\n", " z = z / self.quants\n", " ldj -= np.log(self.quants) * np.prod(z.shape[1:])\n", " return z, ldj"]}, {"cell_type": "markdown", "id": "8f1d2ba6", "metadata": {"papermill": {"duration": 0.010565, "end_time": "2023-03-14T16:08:52.390006", "exception": false, "start_time": "2023-03-14T16:08:52.379441", "status": "completed"}, "tags": []}, "source": ["A good check whether a flow is correctly implemented or not, is to verify that it is invertible.\n", "Hence, we will dequantize a randomly chosen training image, and then quantize it again.\n", "We would expect that we would get the exact same image out:"]}, {"cell_type": "code", "execution_count": 8, "id": "05d6e03d", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:52.412837Z", "iopub.status.busy": "2023-03-14T16:08:52.412458Z", "iopub.status.idle": "2023-03-14T16:08:52.426314Z", "shell.execute_reply": "2023-03-14T16:08:52.425832Z"}, "papermill": {"duration": 0.027687, "end_time": "2023-03-14T16:08:52.428343", "exception": false, "start_time": "2023-03-14T16:08:52.400656", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["Global seed set to 42\n"]}, {"name": "stdout", "output_type": "stream", "text": ["Dequantization was not invertible.\n", "Original value: 0\n", "Reconstructed value: 1\n"]}], "source": ["# Testing invertibility of dequantization layer\n", "L.seed_everything(42)\n", "orig_img = train_set[0][0].unsqueeze(dim=0)\n", "ldj = torch.zeros(\n", " 1,\n", ")\n", "dequant_module = Dequantization()\n", "deq_img, ldj = dequant_module(orig_img, ldj, reverse=False)\n", "reconst_img, ldj = dequant_module(deq_img, ldj, reverse=True)\n", "\n", "d1, d2 = torch.where(orig_img.squeeze() != reconst_img.squeeze())\n", "if len(d1) != 0:\n", " print(\"Dequantization was not invertible.\")\n", " for i in range(d1.shape[0]):\n", " print(\"Original value:\", orig_img[0, 0, d1[i], d2[i]].item())\n", " print(\"Reconstructed value:\", reconst_img[0, 0, d1[i], d2[i]].item())\n", "else:\n", " print(\"Successfully inverted dequantization\")\n", "\n", "# Layer is not strictly invertible due to float precision constraints\n", "# assert (orig_img == reconst_img).all().item()"]}, {"cell_type": "markdown", "id": "64743184", "metadata": {"papermill": {"duration": 0.010719, "end_time": "2023-03-14T16:08:52.453044", "exception": false, "start_time": "2023-03-14T16:08:52.442325", "status": "completed"}, "tags": []}, "source": ["In contrast to our expectation, the test fails.\n", "However, this is no reason to doubt our implementation here as only one single value is not equal to the original.\n", "This is caused due to numerical inaccuracies in the sigmoid invert.\n", "While the input space to the inverted sigmoid is scaled between 0 and 1, the output space is between $-\\infty$ and $\\infty$.\n", "And as we use 32 bits to represent the numbers (in addition to applying logs over and over again),\n", "such inaccuries can occur and should not be worrisome.\n", "Nevertheless, it is good to be aware of them, and can be improved by using a double tensor (float64).\n", "\n", "Finally, we can take our dequantization and actually visualize the\n", "distribution it transforms the discrete values into:"]}, {"cell_type": "code", "execution_count": 9, "id": "d4d49a0a", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:52.476344Z", "iopub.status.busy": "2023-03-14T16:08:52.475761Z", "iopub.status.idle": "2023-03-14T16:08:52.922166Z", "shell.execute_reply": "2023-03-14T16:08:52.921514Z"}, "papermill": {"duration": 0.462246, "end_time": "2023-03-14T16:08:52.926115", "exception": false, "start_time": "2023-03-14T16:08:52.463869", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/pdf": "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IC9uCi9vIDExMyAvcSAvciAvcyAvdCAvdSAvdiAxMjEgL3kgL3ogXQo+PgovV2lkdGhzIDEzIDAgUiA+PgplbmRvYmoKMTQgMCBvYmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Gb250TmFtZSAvQk1RUURWK0RlamFWdVNhbnMgL0ZsYWdzIDMyCi9Gb250QkJveCBbIC0xMDIxIC00NjMgMTc5NCAxMjMzIF0gL0FzY2VudCA5MjkgL0Rlc2NlbnQgLTIzNiAvQ2FwSGVpZ2h0IDAKL1hIZWlnaHQgMCAvSXRhbGljQW5nbGUgMCAvU3RlbVYgMCAvTWF4V2lkdGggMTM0MiA+PgplbmRvYmoKMTMgMCBvYmoKWyA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMAo2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDMxOCA0MDEgNDYwIDgzOCA2MzYKOTUwIDc4MCAyNzUgMzkwIDM5MCA1MDAgODM4IDMxOCAzNjEgMzE4IDMzNyA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2CjYzNiA2MzYgMzM3IDMzNyA4MzggODM4IDgzOCA1MzEgMTAwMCA2ODQgNjg2IDY5OCA3NzAgNjMyIDU3NSA3NzUgNzUyIDI5NQoyOTUgNjU2IDU1NyA4NjMgNzQ4IDc4NyA2MDMgNzg3IDY5NSA2MzUgNjExIDczMiA2ODQgOTg5IDY4NSA2MTEgNjg1IDM5MCAzMzcKMzkwIDgzOCA1MDAgNTAwIDYxMyA2MzUgNTUwIDYzNSA2MTUgMzUyIDYzNSA2MzQgMjc4IDI3OCA1NzkgMjc4IDk3NCA2MzQgNjEyCjYzNSA2MzUgNDExIDUyMSAzOTIgNjM0IDU5MiA4MTggNTkyIDU5MiA1MjUgNjM2IDMzNyA2MzYgODM4IDYwMCA2MzYgNjAwIDMxOAozNTIgNTE4IDEwMDAgNTAwIDUwMCA1MDAgMTM0MiA2MzUgNDAwIDEwNzAgNjAwIDY4NSA2MDAgNjAwIDMxOCAzMTggNTE4IDUxOAo1OTAgNTAwIDEwMDAgNTAwIDEwMDAgNTIxIDQwMCAxMDIzIDYwMCA1MjUgNjExIDMxOCA0MDEgNjM2IDYzNiA2MzYgNjM2IDMzNwo1MDAgNTAwIDEwMDAgNDcxIDYxMiA4MzggMzYxIDEwMDAgNTAwIDUwMCA4MzggNDAxIDQwMSA1MDAgNjM2IDYzNiAzMTggNTAwCjQwMSA0NzEgNjEyIDk2OSA5NjkgOTY5IDUzMSA2ODQgNjg0IDY4NCA2ODQgNjg0IDY4NCA5NzQgNjk4IDYzMiA2MzIgNjMyIDYzMgoyOTUgMjk1IDI5NSAyOTUgNzc1IDc0OCA3ODcgNzg3IDc4NyA3ODcgNzg3IDgzOCA3ODcgNzMyIDczMiA3MzIgNzMyIDYxMSA2MDUKNjMwIDYxMyA2MTMgNjEzIDYxMyA2MTMgNjEzIDk4MiA1NTAgNjE1IDYxNSA2MTUgNjE1IDI3OCAyNzggMjc4IDI3OCA2MTIgNjM0CjYxMiA2MTIgNjEyIDYxMiA2MTIgODM4IDYxMiA2MzQgNjM0IDYzNCA2MzQgNTkyIDYzNSA1OTIgXQplbmRvYmoKMTYgMCBvYmoKPDwgL0QgMTcgMCBSIC9QIDE4IDAgUiAvYSAxOSAwIFIgL2IgMjAgMCBSIC9jIDIxIDAgUiAvZCAyMiAwIFIgL2UgMjMgMCBSCi9laWdodCAyNCAwIFIgL2YgMjUgMCBSIC9maXZlIDI2IDAgUiAvZm91ciAyNyAwIFIgL2h5cGhlbiAyOCAwIFIgL2kgMjkgMCBSCi9sIDMwIDAgUiAvbiAzMSAwIFIgL25pbmUgMzIgMCBSIC9vIDMzIDAgUiAvb25lIDM0IDAgUiAvcGVyaW9kIDM1IDAgUgovcSAzNiAwIFIgL3IgMzcgMCBSIC9zIDM4IDAgUiAvc2V2ZW4gMzkgMCBSIC9zaXggNDAgMCBSIC9zcGFjZSA0MSAwIFIKL3QgNDIgMCBSIC90aHJlZSA0MyAwIFIgL3R3byA0NCAwIFIgL3UgNDUgMCBSIC92IDQ2IDAgUiAveSA0NyAwIFIgL3ogNDggMCBSCi96ZXJvIDQ5IDAgUiA+PgplbmRvYmoKMyAwIG9iago8PCAvRjEgMTUgMCBSID4+CmVuZG9iago0IDAgb2JqCjw8IC9BMSA8PCAvVHlwZSAvRXh0R1N0YXRlIC9DQSAwIC9jYSAxID4+Ci9BMiA8PCAvVHlwZSAvRXh0R1N0YXRlIC9DQSAxIC9jYSAxID4+Ci9BMyA8PCAvVHlwZSAvRXh0R1N0YXRlIC9DQSAwLjUgL2NhIDAuNSA+PgovQTQgPDwgL1R5cGUgL0V4dEdTdGF0ZSAvQ0EgMC44IC9jYSAwLjggPj4gPj4KZW5kb2JqCjUgMCBvYmoKPDwgPj4KZW5kb2JqCjYgMCBvYmoKPDwgPj4KZW5kb2JqCjcgMCBvYmoKPDwgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFsgMTEgMCBSIF0gL0NvdW50IDEgPj4KZW5kb2JqCjUwIDAgb2JqCjw8IC9DcmVhdG9yIChNYXRwbG90bGliIHYzLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZykKL1Byb2R1Y2VyIChNYXRwbG90bGliIHBkZiBiYWNrZW5kIHYzLjcuMSkgL0NyZWF0aW9uRGF0ZSAoRDoyMDIzMDMxNDE2MDg1MlopCj4+CmVuZG9iagp4cmVmCjAgNTEKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDE2IDAwMDAwIG4gCjAwMDAwMjQ1MDUgMDAwMDAgbiAKMDAwMDAyNDIyNSAwMDAwMCBuIAowMDAwMDI0MjU3IDAwMDAwIG4gCjAwMDAwMjQ0NDIgMDAwMDAgbiAKMDAwMDAyNDQ2MyAwMDAwMCBuIAowMDAwMDI0NDg0IDAwMDAwIG4gCjAwMDAwMDAwNjUgMDAwMDAgbiAKMDAwMDAwMDM0MyAwMDAwMCBuIAowMDAwMDEzNjMxIDAwMDAwIG4gCjAwMDAwMDAyMDggMDAwMDAgbiAKMDAwMDAxMzYwOSAwMDAwMCBuIAowMDAwMDIyNzc2IDAwMDAwIG4gCjAwMDAwMjI1NjkgMDAwMDAgbiAKMDAwMDAyMjA4MSAwMDAwMCBuIAowMDAwMDIzODI5IDAwMDAwIG4gCjAwMDAwMTM2NTEgMDAwMDAgbiAKMDAwMDAxMzg4OCAwMDAwMCBuIAowMDAwMDE0MTMxIDAwMDAwIG4gCjAwMDAwMTQ1MTEgMDAwMDAgbiAKMDAwMDAxNDgyOCAwMDAwMCBuIAowMDAwMDE1MTMzIDAwMDAwIG4gCjAwMDAwMTU0MzcgMDAwMDAgbiAKMDAwMDAxNTc1OSAwMDAwMCBuIAowMDAwMDE2MjI3IDAwMDAwIG4gCjAwMDAwMTY0MzYgMDAwMDAgbiAKMDAwMDAxNjc1OCAwMDAwMCBuIAowMDAwMDE2OTI0IDAwMDAwIG4gCjAwMDAwMTcwNTAgMDAwMDAgbiAKMDAwMDAxNzE5NCAwMDAwMCBuIAowMDAwMDE3MzEzIDAwMDAwIG4gCjAwMDAwMTc1NDkgMDAwMDAgbiAKMDAwMDAxNzk0NCAwMDAwMCBuIAowMDAwMDE4MjM1IDAwMDAwIG4gCjAwMDAwMTgzOTAgMDAwMDAgbiAKMDAwMDAxODUxMyAwMDAwMCBuIAowMDAwMDE4ODI5IDAwMDAwIG4gCjAwMDAwMTkwNjIgMDAwMDAgbiAKMDAwMDAxOTQ2OSAwMDAwMCBuIAowMDAwMDE5NjExIDAwMDAwIG4gCjAwMDAwMjAwMDQgMDAwMDAgbiAKMDAwMDAyMDA5NCAwMDAwMCBuIAowMDAwMDIwMzAwIDAwMDAwIG4gCjAwMDAwMjA3MTMgMDAwMDAgbiAKMDAwMDAyMTAzNyAwMDAwMCBuIAowMDAwMDIxMjg0IDAwMDAwIG4gCjAwMDAwMjE0MzEgMDAwMDAgbiAKMDAwMDAyMTY0NSAwMDAwMCBuIAowMDAwMDIxNzkzIDAwMDAwIG4gCjAwMDAwMjQ1NjUgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA1MSAvUm9vdCAxIDAgUiAvSW5mbyA1MCAwIFIgPj4Kc3RhcnR4cmVmCjI0NzE2CiUlRU9GCg==", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:08:52.653925\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["\n", "\n", "def visualize_dequantization(quants, prior=None):\n", " \"\"\"Function for visualizing the dequantization values of discrete values in continuous space.\"\"\"\n", " # Prior over discrete values. If not given, a uniform is assumed\n", " if prior is None:\n", " prior = np.ones(quants, dtype=np.float32) / quants\n", " prior = prior / prior.sum() # Ensure proper categorical distribution\n", "\n", " inp = torch.arange(-4, 4, 0.01).view(-1, 1, 1, 1) # Possible continuous values we want to consider\n", " ldj = torch.zeros(inp.shape[0])\n", " dequant_module = Dequantization(quants=quants)\n", " # Invert dequantization on continuous values to find corresponding discrete value\n", " out, ldj = dequant_module.forward(inp, ldj, reverse=True)\n", " inp, out, prob = inp.squeeze().numpy(), out.squeeze().numpy(), ldj.exp().numpy()\n", " prob = prob * prior[out] # Probability scaled by categorical prior\n", "\n", " # Plot volumes and continuous distribution\n", " sns.set_style(\"white\")\n", " _ = plt.figure(figsize=(6, 3))\n", " x_ticks = []\n", " for v in np.unique(out):\n", " indices = np.where(out == v)\n", " color = to_rgb(\"C%i\" % v)\n", " plt.fill_between(inp[indices], prob[indices], np.zeros(indices[0].shape[0]), color=color + (0.5,), label=str(v))\n", " plt.plot([inp[indices[0][0]]] * 2, [0, prob[indices[0][0]]], color=color)\n", " plt.plot([inp[indices[0][-1]]] * 2, [0, prob[indices[0][-1]]], color=color)\n", " x_ticks.append(inp[indices[0][0]])\n", " x_ticks.append(inp.max())\n", " plt.xticks(x_ticks, [\"%.1f\" % x for x in x_ticks])\n", " plt.plot(inp, prob, color=(0.0, 0.0, 0.0))\n", " # Set final plot properties\n", " plt.ylim(0, prob.max() * 1.1)\n", " plt.xlim(inp.min(), inp.max())\n", " plt.xlabel(\"z\")\n", " plt.ylabel(\"Probability\")\n", " plt.title(\"Dequantization distribution for %i discrete values\" % quants)\n", " plt.legend()\n", " plt.show()\n", " plt.close()\n", "\n", "\n", "visualize_dequantization(quants=8)"]}, {"cell_type": "markdown", "id": "044aceb3", "metadata": {"papermill": {"duration": 0.019884, "end_time": "2023-03-14T16:08:52.969239", "exception": false, "start_time": "2023-03-14T16:08:52.949355", "status": "completed"}, "tags": []}, "source": ["The visualized distribution show the sub-volumes that are assigned to the different discrete values.\n", "The value $0$ has its volume between $[-\\infty, -1.9)$, the value $1$ is represented by the interval $[-1.9, -1.1)$, etc.\n", "The volume for each discrete value has the same probability mass.\n", "That's why the volumes close to the center (e.g. 3 and 4) have a smaller area on the z-axis as others\n", "($z$ is being used to denote the output of the whole dequantization flow).\n", "\n", "Effectively, the consecutive normalizing flow models discrete images by the following objective:\n", "\n", "$$\\log p(x) = \\log \\mathbb{E}_{u\\sim q(u|x)}\\left[\\frac{p(x+u)}{q(u|x)} \\right] \\geq \\mathbb{E}_{u}\\left[\\log \\frac{p(x+u)}{q(u|x)} \\right]$$\n", "\n", "Although normalizing flows are exact in likelihood, we have a lower bound.\n", "Specifically, this is an example of the Jensen inequality because we need to move the log into the expectation so we can use Monte-carlo estimates.\n", "In general, this bound is considerably smaller than the ELBO in variational autoencoders.\n", "Actually, we can reduce the bound ourselves by estimating the expectation not by one, but by $M$ samples.\n", "In other words, we can apply importance sampling which leads to the following inequality:\n", "\n", "$$\\log p(x) = \\log \\mathbb{E}_{u\\sim q(u|x)}\\left[\\frac{p(x+u)}{q(u|x)} \\right] \\geq \\mathbb{E}_{u}\\left[\\log \\frac{1}{M} \\sum_{m=1}^{M} \\frac{p(x+u_m)}{q(u_m|x)} \\right] \\geq \\mathbb{E}_{u}\\left[\\log \\frac{p(x+u)}{q(u|x)} \\right]$$\n", "\n", "The importance sampling $\\frac{1}{M} \\sum_{m=1}^{M} \\frac{p(x+u_m)}{q(u_m|x)}$ becomes\n", "$\\mathbb{E}_{u\\sim q(u|x)}\\left[\\frac{p(x+u)}{q(u|x)} \\right]$ if $M\\to \\infty$,\n", "so that the more samples we use, the tighter the bound is.\n", "During testing, we can make use of this property and have it implemented in `test_step` in `ImageFlow`.\n", "In theory, we could also use this tighter bound during training.\n", "However, related work has shown that this does not necessarily lead to\n", "an improvement given the additional computational cost, and it is more\n", "efficient to stick with a single estimate [5]."]}, {"cell_type": "markdown", "id": "aca798a1", "metadata": {"papermill": {"duration": 0.014861, "end_time": "2023-03-14T16:08:53.000621", "exception": false, "start_time": "2023-03-14T16:08:52.985760", "status": "completed"}, "tags": []}, "source": ["### Variational Dequantization\n", "\n", "Dequantization uses a uniform distribution for the noise $u$ which effectively leads to images being represented as hypercubes\n", "(cube in high dimensions) with sharp borders.\n", "However, modeling such sharp borders is not easy for a flow as it uses smooth transformations to convert it into a Gaussian distribution.\n", "\n", "Another way of looking at it is if we change the prior distribution in the previous visualization.\n", "Imagine we have independent Gaussian noise on pixels which is commonly the case for any real-world taken picture.\n", "Therefore, the flow would have to model a distribution as above, but with the individual volumes scaled as follows:"]}, {"cell_type": "code", "execution_count": 10, "id": "320081f9", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:53.040814Z", "iopub.status.busy": "2023-03-14T16:08:53.040389Z", "iopub.status.idle": "2023-03-14T16:08:53.454171Z", "shell.execute_reply": "2023-03-14T16:08:53.453564Z"}, "papermill": {"duration": 0.439315, "end_time": "2023-03-14T16:08:53.458705", "exception": false, "start_time": "2023-03-14T16:08:53.019390", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/pdf": "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RW5jb2RpbmcgPDwgL1R5cGUgL0VuY29kaW5nCi9EaWZmZXJlbmNlcyBbIDMyIC9zcGFjZSA0NSAvaHlwaGVuIC9wZXJpb2QgNDggL3plcm8gL29uZSAvdHdvIC90aHJlZSAvZm91ciAvZml2ZSAvc2l4Ci9zZXZlbiAvZWlnaHQgL25pbmUgNjggL0QgODAgL1AgOTcgL2EgL2IgL2MgL2QgL2UgL2YgMTA1IC9pIDEwOCAvbCAxMTAgL24KL28gMTEzIC9xIC9yIC9zIC90IC91IC92IDEyMSAveSAveiBdCj4+Ci9XaWR0aHMgMTMgMCBSID4+CmVuZG9iagoxNCAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0ZvbnROYW1lIC9CTVFRRFYrRGVqYVZ1U2FucyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFsgLTEwMjEgLTQ2MyAxNzk0IDEyMzMgXSAvQXNjZW50IDkyOSAvRGVzY2VudCAtMjM2IC9DYXBIZWlnaHQgMAovWEhlaWdodCAwIC9JdGFsaWNBbmdsZSAwIC9TdGVtViAwIC9NYXhXaWR0aCAxMzQyID4+CmVuZG9iagoxMyAwIG9iagpbIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwCjYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgMzE4IDQwMSA0NjAgODM4IDYzNgo5NTAgNzgwIDI3NSAzOTAgMzkwIDUwMCA4MzggMzE4IDM2MSAzMTggMzM3IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYKNjM2IDYzNiAzMzcgMzM3IDgzOCA4MzggODM4IDUzMSAxMDAwIDY4NCA2ODYgNjk4IDc3MCA2MzIgNTc1IDc3NSA3NTIgMjk1CjI5NSA2NTYgNTU3IDg2MyA3NDggNzg3IDYwMyA3ODcgNjk1IDYzNSA2MTEgNzMyIDY4NCA5ODkgNjg1IDYxMSA2ODUgMzkwIDMzNwozOTAgODM4IDUwMCA1MDAgNjEzIDYzNSA1NTAgNjM1IDYxNSAzNTIgNjM1IDYzNCAyNzggMjc4IDU3OSAyNzggOTc0IDYzNCA2MTIKNjM1IDYzNSA0MTEgNTIxIDM5MiA2MzQgNTkyIDgxOCA1OTIgNTkyIDUyNSA2MzYgMzM3IDYzNiA4MzggNjAwIDYzNiA2MDAgMzE4CjM1MiA1MTggMTAwMCA1MDAgNTAwIDUwMCAxMzQyIDYzNSA0MDAgMTA3MCA2MDAgNjg1IDYwMCA2MDAgMzE4IDMxOCA1MTggNTE4CjU5MCA1MDAgMTAwMCA1MDAgMTAwMCA1MjEgNDAwIDEwMjMgNjAwIDUyNSA2MTEgMzE4IDQwMSA2MzYgNjM2IDYzNiA2MzYgMzM3CjUwMCA1MDAgMTAwMCA0NzEgNjEyIDgzOCAzNjEgMTAwMCA1MDAgNTAwIDgzOCA0MDEgNDAxIDUwMCA2MzYgNjM2IDMxOCA1MDAKNDAxIDQ3MSA2MTIgOTY5IDk2OSA5NjkgNTMxIDY4NCA2ODQgNjg0IDY4NCA2ODQgNjg0IDk3NCA2OTggNjMyIDYzMiA2MzIgNjMyCjI5NSAyOTUgMjk1IDI5NSA3NzUgNzQ4IDc4NyA3ODcgNzg3IDc4NyA3ODcgODM4IDc4NyA3MzIgNzMyIDczMiA3MzIgNjExIDYwNQo2MzAgNjEzIDYxMyA2MTMgNjEzIDYxMyA2MTMgOTgyIDU1MCA2MTUgNjE1IDYxNSA2MTUgMjc4IDI3OCAyNzggMjc4IDYxMiA2MzQKNjEyIDYxMiA2MTIgNjEyIDYxMiA4MzggNjEyIDYzNCA2MzQgNjM0IDYzNCA1OTIgNjM1IDU5MiBdCmVuZG9iagoxNiAwIG9iago8PCAvRCAxNyAwIFIgL1AgMTggMCBSIC9hIDE5IDAgUiAvYiAyMCAwIFIgL2MgMjEgMCBSIC9kIDIyIDAgUiAvZSAyMyAwIFIKL2VpZ2h0IDI0IDAgUiAvZiAyNSAwIFIgL2ZpdmUgMjYgMCBSIC9mb3VyIDI3IDAgUiAvaHlwaGVuIDI4IDAgUiAvaSAyOSAwIFIKL2wgMzAgMCBSIC9uIDMxIDAgUiAvbmluZSAzMiAwIFIgL28gMzMgMCBSIC9vbmUgMzQgMCBSIC9wZXJpb2QgMzUgMCBSCi9xIDM2IDAgUiAvciAzNyAwIFIgL3MgMzggMCBSIC9zZXZlbiAzOSAwIFIgL3NpeCA0MCAwIFIgL3NwYWNlIDQxIDAgUgovdCA0MiAwIFIgL3RocmVlIDQzIDAgUiAvdHdvIDQ0IDAgUiAvdSA0NSAwIFIgL3YgNDYgMCBSIC95IDQ3IDAgUiAveiA0OCAwIFIKL3plcm8gNDkgMCBSID4+CmVuZG9iagozIDAgb2JqCjw8IC9GMSAxNSAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0ExIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDAgL2NhIDEgPj4KL0EyIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDEgL2NhIDEgPj4KL0EzIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDAuNSAvY2EgMC41ID4+Ci9BNCA8PCAvVHlwZSAvRXh0R1N0YXRlIC9DQSAwLjggL2NhIDAuOCA+PiA+PgplbmRvYmoKNSAwIG9iago8PCA+PgplbmRvYmoKNiAwIG9iago8PCA+PgplbmRvYmoKNyAwIG9iago8PCA+PgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZXMgL0tpZHMgWyAxMSAwIFIgXSAvQ291bnQgMSA+PgplbmRvYmoKNTAgMCBvYmoKPDwgL0NyZWF0b3IgKE1hdHBsb3RsaWIgdjMuNy4xLCBodHRwczovL21hdHBsb3RsaWIub3JnKQovUHJvZHVjZXIgKE1hdHBsb3RsaWIgcGRmIGJhY2tlbmQgdjMuNy4xKSAvQ3JlYXRpb25EYXRlIChEOjIwMjMwMzE0MTYwODUzWikKPj4KZW5kb2JqCnhyZWYKMCA1MQowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDAyNDY5MCAwMDAwMCBuIAowMDAwMDI0NDEwIDAwMDAwIG4gCjAwMDAwMjQ0NDIgMDAwMDAgbiAKMDAwMDAyNDYyNyAwMDAwMCBuIAowMDAwMDI0NjQ4IDAwMDAwIG4gCjAwMDAwMjQ2NjkgMDAwMDAgbiAKMDAwMDAwMDA2NSAwMDAwMCBuIAowMDAwMDAwMzQyIDAwMDAwIG4gCjAwMDAwMTM4MTYgMDAwMDAgbiAKMDAwMDAwMDIwOCAwMDAwMCBuIAowMDAwMDEzNzk0IDAwMDAwIG4gCjAwMDAwMjI5NjEgMDAwMDAgbiAKMDAwMDAyMjc1NCAwMDAwMCBuIAowMDAwMDIyMjY2IDAwMDAwIG4gCjAwMDAwMjQwMTQgMDAwMDAgbiAKMDAwMDAxMzgzNiAwMDAwMCBuIAowMDAwMDE0MDczIDAwMDAwIG4gCjAwMDAwMTQzMTYgMDAwMDAgbiAKMDAwMDAxNDY5NiAwMDAwMCBuIAowMDAwMDE1MDEzIDAwMDAwIG4gCjAwMDAwMTUzMTggMDAwMDAgbiAKMDAwMDAxNTYyMiAwMDAwMCBuIAowMDAwMDE1OTQ0IDAwMDAwIG4gCjAwMDAwMTY0MTIgMDAwMDAgbiAKMDAwMDAxNjYyMSAwMDAwMCBuIAowMDAwMDE2OTQzIDAwMDAwIG4gCjAwMDAwMTcxMDkgMDAwMDAgbiAKMDAwMDAxNzIzNSAwMDAwMCBuIAowMDAwMDE3Mzc5IDAwMDAwIG4gCjAwMDAwMTc0OTggMDAwMDAgbiAKMDAwMDAxNzczNCAwMDAwMCBuIAowMDAwMDE4MTI5IDAwMDAwIG4gCjAwMDAwMTg0MjAgMDAwMDAgbiAKMDAwMDAxODU3NSAwMDAwMCBuIAowMDAwMDE4Njk4IDAwMDAwIG4gCjAwMDAwMTkwMTQgMDAwMDAgbiAKMDAwMDAxOTI0NyAwMDAwMCBuIAowMDAwMDE5NjU0IDAwMDAwIG4gCjAwMDAwMTk3OTYgMDAwMDAgbiAKMDAwMDAyMDE4OSAwMDAwMCBuIAowMDAwMDIwMjc5IDAwMDAwIG4gCjAwMDAwMjA0ODUgMDAwMDAgbiAKMDAwMDAyMDg5OCAwMDAwMCBuIAowMDAwMDIxMjIyIDAwMDAwIG4gCjAwMDAwMjE0NjkgMDAwMDAgbiAKMDAwMDAyMTYxNiAwMDAwMCBuIAowMDAwMDIxODMwIDAwMDAwIG4gCjAwMDAwMjE5NzggMDAwMDAgbiAKMDAwMDAyNDc1MCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDUxIC9Sb290IDEgMCBSIC9JbmZvIDUwIDAgUiA+PgpzdGFydHhyZWYKMjQ5MDEKJSVFT0YK", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:08:53.205021\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["visualize_dequantization(quants=8, prior=np.array([0.075, 0.2, 0.4, 0.2, 0.075, 0.025, 0.0125, 0.0125]))"]}, {"cell_type": "markdown", "id": "b202c9c8", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.015208, "end_time": "2023-03-14T16:08:53.492761", "exception": false, "start_time": "2023-03-14T16:08:53.477553", "status": "completed"}, "tags": []}, "source": ["Transforming such a probability into a Gaussian is a difficult task, especially with such hard borders.\n", "Dequantization has therefore been extended to more sophisticated, learnable distributions beyond uniform in a variational framework.\n", "In particular, if we remember the learning objective\n", "$\\log p(x) = \\log \\mathbb{E}_{u}\\left[\\frac{p(x+u)}{q(u|x)} \\right]$,\n", "the uniform distribution can be replaced by a learned distribution $q_{\\theta}(u|x)$ with support over $u\\in[0,1)^D$.\n", "This approach is called Variational Dequantization and has been proposed by Ho et al.\n", "[3].\n", "How can we learn such a distribution?\n", "We can use a second normalizing flow that takes $x$ as external input and learns a flexible distribution over $u$.\n", "To ensure a support over $[0,1)^D$, we can apply a sigmoid activation function as final flow transformation.\n", "\n", "Inheriting the original dequantization class, we can implement variational dequantization as follows:"]}, {"cell_type": "code", "execution_count": 11, "id": "9977763b", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:53.525421Z", "iopub.status.busy": "2023-03-14T16:08:53.525020Z", "iopub.status.idle": "2023-03-14T16:08:53.536012Z", "shell.execute_reply": "2023-03-14T16:08:53.535528Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.029932, "end_time": "2023-03-14T16:08:53.538205", "exception": false, "start_time": "2023-03-14T16:08:53.508273", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class VariationalDequantization(Dequantization):\n", " def __init__(self, var_flows, alpha=1e-5):\n", " \"\"\"\n", " Args:\n", " var_flows: A list of flow transformations to use for modeling q(u|x)\n", " alpha: Small constant, see Dequantization for details\n", " \"\"\"\n", " super().__init__(alpha=alpha)\n", " self.flows = nn.ModuleList(var_flows)\n", "\n", " def dequant(self, z, ldj):\n", " z = z.to(torch.float32)\n", " img = (z / 255.0) * 2 - 1 # We condition the flows on x, i.e. the original image\n", "\n", " # Prior of u is a uniform distribution as before\n", " # As most flow transformations are defined on [-infinity,+infinity], we apply an inverse sigmoid first.\n", " deq_noise = torch.rand_like(z).detach()\n", " deq_noise, ldj = self.sigmoid(deq_noise, ldj, reverse=True)\n", " for flow in self.flows:\n", " deq_noise, ldj = flow(deq_noise, ldj, reverse=False, orig_img=img)\n", " deq_noise, ldj = self.sigmoid(deq_noise, ldj, reverse=False)\n", "\n", " # After the flows, apply u as in standard dequantization\n", " z = (z + deq_noise) / 256.0\n", " ldj -= np.log(256.0) * np.prod(z.shape[1:])\n", " return z, ldj"]}, {"cell_type": "markdown", "id": "b13b49a8", "metadata": {"papermill": {"duration": 0.014961, "end_time": "2023-03-14T16:08:53.572621", "exception": false, "start_time": "2023-03-14T16:08:53.557660", "status": "completed"}, "tags": []}, "source": ["Variational dequantization can be used as a substitute for dequantization.\n", "We will compare dequantization and variational dequantization in later experiments."]}, {"cell_type": "markdown", "id": "4d25fabd", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.014996, "end_time": "2023-03-14T16:08:53.602877", "exception": false, "start_time": "2023-03-14T16:08:53.587881", "status": "completed"}, "tags": []}, "source": ["### Coupling layers\n", "\n", "
\n", "\n", "Next, we look at possible transformations to apply inside the flow.\n", "A recent popular flow layer, which works well in combination with deep neural networks,\n", "is the coupling layer introduced by Dinh et al.\n", "[1].\n", "The input $z$ is arbitrarily split into two parts, $z_{1:j}$ and $z_{j+1:d}$, of which the first remains unchanged by the flow.\n", "Yet, $z_{1:j}$ is used to parameterize the transformation for the second part, $z_{j+1:d}$.\n", "Various transformations have been proposed in recent time [3,4], but here we will settle for the simplest and most efficient one: affine coupling.\n", "In this coupling layer, we apply an affine transformation by shifting the input by a bias $\\mu$ and scale it by $\\sigma$.\n", "In other words, our transformation looks as follows:\n", "\n", "$$z'_{j+1:d} = \\mu_{\\theta}(z_{1:j}) + \\sigma_{\\theta}(z_{1:j}) \\odot z_{j+1:d}$$\n", "\n", "The functions $\\mu$ and $\\sigma$ are implemented as a shared neural network,\n", "and the sum and multiplication are performed element-wise.\n", "The LDJ is thereby the sum of the logs of the scaling factors: $\\sum_i \\left[\\log \\sigma_{\\theta}(z_{1:j})\\right]_i$.\n", "Inverting the layer can as simply be done as subtracting the bias and dividing by the scale:\n", "\n", "$$z_{j+1:d} = \\left(z'_{j+1:d} - \\mu_{\\theta}(z_{1:j})\\right) / \\sigma_{\\theta}(z_{1:j})$$\n", "\n", "We can also visualize the coupling layer in form of a computation graph,\n", "where $z_1$ represents $z_{1:j}$, and $z_2$ represents $z_{j+1:d}$:\n", "\n", "
\n", "\n", "In our implementation, we will realize the splitting of variables as masking.\n", "The variables to be transformed, $z_{j+1:d}$, are masked when passing $z$ to the shared network to predict the transformation parameters.\n", "When applying the transformation, we mask the parameters for $z_{1:j}$\n", "so that we have an identity operation for those variables:"]}, {"cell_type": "code", "execution_count": 12, "id": "d18ee4c7", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:53.634921Z", "iopub.status.busy": "2023-03-14T16:08:53.634448Z", "iopub.status.idle": "2023-03-14T16:08:53.647226Z", "shell.execute_reply": "2023-03-14T16:08:53.646704Z"}, "papermill": {"duration": 0.031527, "end_time": "2023-03-14T16:08:53.649422", "exception": false, "start_time": "2023-03-14T16:08:53.617895", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class CouplingLayer(nn.Module):\n", " def __init__(self, network, mask, c_in):\n", " \"\"\"Coupling layer inside a normalizing flow.\n", "\n", " Args:\n", " network: A PyTorch nn.Module constituting the deep neural network for mu and sigma.\n", " Output shape should be twice the channel size as the input.\n", " mask: Binary mask (0 or 1) where 0 denotes that the element should be transformed,\n", " while 1 means the latent will be used as input to the NN.\n", " c_in: Number of input channels\n", " \"\"\"\n", " super().__init__()\n", " self.network = network\n", " self.scaling_factor = nn.Parameter(torch.zeros(c_in))\n", " # Register mask as buffer as it is a tensor which is not a parameter,\n", " # but should be part of the modules state.\n", " self.register_buffer(\"mask\", mask)\n", "\n", " def forward(self, z, ldj, reverse=False, orig_img=None):\n", " \"\"\"\n", " Args:\n", " z: Latent input to the flow\n", " ldj: The current ldj of the previous flows.\n", " The ldj of this layer will be added to this tensor.\n", " reverse: If True, we apply the inverse of the layer.\n", " orig_img (optional): Only needed in VarDeq. Allows external\n", " input to condition the flow on (e.g. original image)\n", " \"\"\"\n", " # Apply network to masked input\n", " z_in = z * self.mask\n", " if orig_img is None:\n", " nn_out = self.network(z_in)\n", " else:\n", " nn_out = self.network(torch.cat([z_in, orig_img], dim=1))\n", " s, t = nn_out.chunk(2, dim=1)\n", "\n", " # Stabilize scaling output\n", " s_fac = self.scaling_factor.exp().view(1, -1, 1, 1)\n", " s = torch.tanh(s / s_fac) * s_fac\n", "\n", " # Mask outputs (only transform the second part)\n", " s = s * (1 - self.mask)\n", " t = t * (1 - self.mask)\n", "\n", " # Affine transformation\n", " if not reverse:\n", " # Whether we first shift and then scale, or the other way round,\n", " # is a design choice, and usually does not have a big impact\n", " z = (z + t) * torch.exp(s)\n", " ldj += s.sum(dim=[1, 2, 3])\n", " else:\n", " z = (z * torch.exp(-s)) - t\n", " ldj -= s.sum(dim=[1, 2, 3])\n", "\n", " return z, ldj"]}, {"cell_type": "markdown", "id": "1e103dac", "metadata": {"papermill": {"duration": 0.014956, "end_time": "2023-03-14T16:08:53.684033", "exception": false, "start_time": "2023-03-14T16:08:53.669077", "status": "completed"}, "tags": []}, "source": ["For stabilization purposes, we apply a $\\tanh$ activation function on the scaling output.\n", "This prevents sudden large output values for the scaling that can destabilize training.\n", "To still allow scaling factors smaller or larger than -1 and 1 respectively,\n", "we have a learnable parameter per dimension, called `scaling_factor`.\n", "This scales the tanh to different limits.\n", "Below, we visualize the effect of the scaling factor on the output activation of the scaling terms:"]}, {"cell_type": "code", "execution_count": 13, "id": "44e8290a", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:53.715799Z", "iopub.status.busy": "2023-03-14T16:08:53.715417Z", "iopub.status.idle": "2023-03-14T16:08:54.573050Z", "shell.execute_reply": "2023-03-14T16:08:54.572427Z"}, "papermill": {"duration": 0.877475, "end_time": "2023-03-14T16:08:54.576709", "exception": false, "start_time": "2023-03-14T16:08:53.699234", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/pdf": "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YXN0Q2hhciAyNTUKL0ZvbnREZXNjcmlwdG9yIDE0IDAgUiAvU3VidHlwZSAvVHlwZTMgL05hbWUgL0JNUVFEVitEZWphVnVTYW5zCi9Gb250QkJveCBbIC0xMDIxIC00NjMgMTc5NCAxMjMzIF0gL0ZvbnRNYXRyaXggWyAwLjAwMSAwIDAgMC4wMDEgMCAwIF0KL0NoYXJQcm9jcyAxNiAwIFIKL0VuY29kaW5nIDw8IC9UeXBlIC9FbmNvZGluZwovRGlmZmVyZW5jZXMgWyAzMiAvc3BhY2UgNDYgL3BlcmlvZCA0OCAvemVybyAvb25lIC90d28gL3RocmVlIDUzIC9maXZlIDU4IC9jb2xvbiA4MyAvUwo5NyAvYSA5OSAvYyAxMDIgL2YgL2cgMTA1IC9pIDEwOCAvbCAxMTAgL24gL28gMTE0IC9yIDExNiAvdCBdCj4+Ci9XaWR0aHMgMTMgMCBSID4+CmVuZG9iagoxNCAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0ZvbnROYW1lIC9CTVFRRFYrRGVqYVZ1U2FucyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFsgLTEwMjEgLTQ2MyAxNzk0IDEyMzMgXSAvQXNjZW50IDkyOSAvRGVzY2VudCAtMjM2IC9DYXBIZWlnaHQgMAovWEhlaWdodCAwIC9JdGFsaWNBbmdsZSAwIC9TdGVtViAwIC9NYXhXaWR0aCAxMzQyID4+CmVuZG9iagoxMyAwIG9iagpbIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwCjYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgMzE4IDQwMSA0NjAgODM4IDYzNgo5NTAgNzgwIDI3NSAzOTAgMzkwIDUwMCA4MzggMzE4IDM2MSAzMTggMzM3IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYKNjM2IDYzNiAzMzcgMzM3IDgzOCA4MzggODM4IDUzMSAxMDAwIDY4NCA2ODYgNjk4IDc3MCA2MzIgNTc1IDc3NSA3NTIgMjk1CjI5NSA2NTYgNTU3IDg2MyA3NDggNzg3IDYwMyA3ODcgNjk1IDYzNSA2MTEgNzMyIDY4NCA5ODkgNjg1IDYxMSA2ODUgMzkwIDMzNwozOTAgODM4IDUwMCA1MDAgNjEzIDYzNSA1NTAgNjM1IDYxNSAzNTIgNjM1IDYzNCAyNzggMjc4IDU3OSAyNzggOTc0IDYzNCA2MTIKNjM1IDYzNSA0MTEgNTIxIDM5MiA2MzQgNTkyIDgxOCA1OTIgNTkyIDUyNSA2MzYgMzM3IDYzNiA4MzggNjAwIDYzNiA2MDAgMzE4CjM1MiA1MTggMTAwMCA1MDAgNTAwIDUwMCAxMzQyIDYzNSA0MDAgMTA3MCA2MDAgNjg1IDYwMCA2MDAgMzE4IDMxOCA1MTggNTE4CjU5MCA1MDAgMTAwMCA1MDAgMTAwMCA1MjEgNDAwIDEwMjMgNjAwIDUyNSA2MTEgMzE4IDQwMSA2MzYgNjM2IDYzNiA2MzYgMzM3CjUwMCA1MDAgMTAwMCA0NzEgNjEyIDgzOCAzNjEgMTAwMCA1MDAgNTAwIDgzOCA0MDEgNDAxIDUwMCA2MzYgNjM2IDMxOCA1MDAKNDAxIDQ3MSA2MTIgOTY5IDk2OSA5NjkgNTMxIDY4NCA2ODQgNjg0IDY4NCA2ODQgNjg0IDk3NCA2OTggNjMyIDYzMiA2MzIgNjMyCjI5NSAyOTUgMjk1IDI5NSA3NzUgNzQ4IDc4NyA3ODcgNzg3IDc4NyA3ODcgODM4IDc4NyA3MzIgNzMyIDczMiA3MzIgNjExIDYwNQo2MzAgNjEzIDYxMyA2MTMgNjEzIDYxMyA2MTMgOTgyIDU1MCA2MTUgNjE1IDYxNSA2MTUgMjc4IDI3OCAyNzggMjc4IDYxMiA2MzQKNjEyIDYxMiA2MTIgNjEyIDYxMiA4MzggNjEyIDYzNCA2MzQgNjM0IDYzNCA1OTIgNjM1IDU5MiBdCmVuZG9iagoxNiAwIG9iago8PCAvUyAxNyAwIFIgL2EgMTggMCBSIC9jIDE5IDAgUiAvY29sb24gMjAgMCBSIC9mIDIxIDAgUiAvZml2ZSAyMiAwIFIKL2cgMjMgMCBSIC9pIDI0IDAgUiAvbCAyNSAwIFIgL24gMjcgMCBSIC9vIDI4IDAgUiAvb25lIDI5IDAgUgovcGVyaW9kIDMwIDAgUiAvciAzMSAwIFIgL3NwYWNlIDMyIDAgUiAvdCAzMyAwIFIgL3RocmVlIDM0IDAgUiAvdHdvIDM1IDAgUgovemVybyAzNiAwIFIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL0YxIDE1IDAgUiA+PgplbmRvYmoKNCAwIG9iago8PCAvQTEgPDwgL1R5cGUgL0V4dEdTdGF0ZSAvQ0EgMCAvY2EgMSA+PgovQTIgPDwgL1R5cGUgL0V4dEdTdGF0ZSAvQ0EgMSAvY2EgMSA+PiA+PgplbmRvYmoKNSAwIG9iago8PCA+PgplbmRvYmoKNiAwIG9iago8PCA+PgplbmRvYmoKNyAwIG9iago8PCAvRjEtRGVqYVZ1U2Fucy1taW51cyAyNiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFsgMTEgMCBSIF0gL0NvdW50IDEgPj4KZW5kb2JqCjM3IDAgb2JqCjw8IC9DcmVhdG9yIChNYXRwbG90bGliIHYzLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZykKL1Byb2R1Y2VyIChNYXRwbG90bGliIHBkZiBiYWNrZW5kIHYzLjcuMSkgL0NyZWF0aW9uRGF0ZSAoRDoyMDIzMDMxNDE2MDg1NFopCj4+CmVuZG9iagp4cmVmCjAgMzgKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDE2IDAwMDAwIG4gCjAwMDAwMTAxOTIgMDAwMDAgbiAKMDAwMDAwOTk3MCAwMDAwMCBuIAowMDAwMDEwMDAyIDAwMDAwIG4gCjAwMDAwMTAxMDEgMDAwMDAgbiAKMDAwMDAxMDEyMiAwMDAwMCBuIAowMDAwMDEwMTQzIDAwMDAwIG4gCjAwMDAwMDAwNjUgMDAwMDAgbiAKMDAwMDAwMDM0OCAwMDAwMCBuIAowMDAwMDAzMDI5IDAwMDAwIG4gCjAwMDAwMDAyMDggMDAwMDAgbiAKMDAwMDAwMzAwOCAwMDAwMCBuIAowMDAwMDA4Njc4IDAwMDAwIG4gCjAwMDAwMDg0NzEgMDAwMDAgbiAKMDAwMDAwODAzMiAwMDAwMCBuIAowMDAwMDA5NzMxIDAwMDAwIG4gCjAwMDAwMDMwNDkgMDAwMDAgbiAKMDAwMDAwMzQ2MyAwMDAwMCBuIAowMDAwMDAzODQzIDAwMDAwIG4gCjAwMDAwMDQxNDggMDAwMDAgbiAKMDAwMDAwNDI5MyAwMDAwMCBuIAowMDAwMDA0NTAyIDAwMDAwIG4gCjAwMDAwMDQ4MjQgMDAwMDAgbiAKMDAwMDAwNTIzOCAwMDAwMCBuIAowMDAwMDA1MzgyIDAwMDAwIG4gCjAwMDAwMDU1MDEgMDAwMDAgbiAKMDAwMDAwNTY3MyAwMDAwMCBuIAowMDAwMDA1OTA5IDAwMDAwIG4gCjAwMDAwMDYyMDAgMDAwMDAgbiAKMDAwMDAwNjM1NSAwMDAwMCBuIAowMDAwMDA2NDc4IDAwMDAwIG4gCjAwMDAwMDY3MTEgMDAwMDAgbiAKMDAwMDAwNjgwMSAwMDAwMCBuIAowMDAwMDA3MDA3IDAwMDAwIG4gCjAwMDAwMDc0MjAgMDAwMDAgbiAKMDAwMDAwNzc0NCAwMDAwMCBuIAowMDAwMDEwMjUyIDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgMzggL1Jvb3QgMSAwIFIgL0luZm8gMzcgMCBSID4+CnN0YXJ0eHJlZgoxMDQwMwolJUVPRgo=", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:08:54.070086\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["with torch.no_grad():\n", " x = torch.arange(-5, 5, 0.01)\n", " scaling_factors = [0.5, 1, 2]\n", " sns.set()\n", " fig, ax = plt.subplots(1, 3, figsize=(12, 3))\n", " for i, scale in enumerate(scaling_factors):\n", " y = torch.tanh(x / scale) * scale\n", " ax[i].plot(x.numpy(), y.numpy())\n", " ax[i].set_title(\"Scaling factor: \" + str(scale))\n", " ax[i].set_ylim(-3, 3)\n", " plt.subplots_adjust(wspace=0.4)\n", " sns.reset_orig()\n", " plt.show()"]}, {"cell_type": "markdown", "id": "0a4c5cae", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.016704, "end_time": "2023-03-14T16:08:54.614666", "exception": false, "start_time": "2023-03-14T16:08:54.597962", "status": "completed"}, "tags": []}, "source": ["Coupling layers generalize to any masking technique we could think of.\n", "However, the most common approach for images is to split the input $z$ in half, using a checkerboard mask or channel mask.\n", "A checkerboard mask splits the variables across the height and width dimensions and assigns each other pixel to $z_{j+1:d}$.\n", "Thereby, the mask is shared across channels.\n", "In contrast, the channel mask assigns half of the channels to $z_{j+1:d}$, and the other half to $z_{1:j+1}$.\n", "Note that when we apply multiple coupling layers, we invert the masking for each other layer so that each variable is transformed a similar amount of times.\n", "\n", "Let's implement a function that creates a checkerboard mask and a channel mask for us:"]}, {"cell_type": "code", "execution_count": 14, "id": "124363d3", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:54.649537Z", "iopub.status.busy": "2023-03-14T16:08:54.649056Z", "iopub.status.idle": "2023-03-14T16:08:54.656432Z", "shell.execute_reply": "2023-03-14T16:08:54.655621Z"}, "papermill": {"duration": 0.027594, "end_time": "2023-03-14T16:08:54.658995", "exception": false, "start_time": "2023-03-14T16:08:54.631401", "status": "completed"}, "tags": []}, "outputs": [], "source": ["def create_checkerboard_mask(h, w, invert=False):\n", " x, y = torch.arange(h, dtype=torch.int32), torch.arange(w, dtype=torch.int32)\n", " xx, yy = torch.meshgrid(x, y)\n", " mask = torch.fmod(xx + yy, 2)\n", " mask = mask.to(torch.float32).view(1, 1, h, w)\n", " if invert:\n", " mask = 1 - mask\n", " return mask\n", "\n", "\n", "def create_channel_mask(c_in, invert=False):\n", " mask = torch.cat([torch.ones(c_in // 2, dtype=torch.float32), torch.zeros(c_in - c_in // 2, dtype=torch.float32)])\n", " mask = mask.view(1, c_in, 1, 1)\n", " if invert:\n", " mask = 1 - mask\n", " return mask"]}, {"cell_type": "markdown", "id": "8d6f119f", "metadata": {"papermill": {"duration": 0.016328, "end_time": "2023-03-14T16:08:54.696519", "exception": false, "start_time": "2023-03-14T16:08:54.680191", "status": "completed"}, "tags": []}, "source": ["We can also visualize the corresponding masks for an image of size $8\\times 8\\times 2$ (2 channels):"]}, {"cell_type": "code", "execution_count": 15, "id": "e73db108", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:54.730666Z", "iopub.status.busy": "2023-03-14T16:08:54.730376Z", "iopub.status.idle": "2023-03-14T16:08:55.071855Z", "shell.execute_reply": "2023-03-14T16:08:55.071060Z"}, "papermill": {"duration": 0.361902, "end_time": "2023-03-14T16:08:55.074928", "exception": false, "start_time": "2023-03-14T16:08:54.713026", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["/usr/local/lib/python3.9/dist-packages/torch/functional.py:504: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:3190.)\n", " return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined]\n"]}, {"data": {"application/pdf": "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dVNhbnMKL0ZvbnRCQm94IFsgLTEwMjEgLTQ2MyAxNzk0IDEyMzMgXSAvRm9udE1hdHJpeCBbIDAuMDAxIDAgMCAwLjAwMSAwIDAgXQovQ2hhclByb2NzIDE3IDAgUgovRW5jb2RpbmcgPDwgL1R5cGUgL0VuY29kaW5nCi9EaWZmZXJlbmNlcyBbIDMyIC9zcGFjZSA2NyAvQyA5NyAvYSAvYiAvYyAvZCAvZSAxMDQgL2ggMTA3IC9rIDEwOSAvbSAxMTEgL28gMTE0IC9yIC9zCl0KPj4KL1dpZHRocyAxNCAwIFIgPj4KZW5kb2JqCjE1IDAgb2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRvciAvRm9udE5hbWUgL0JNUVFEVitEZWphVnVTYW5zIC9GbGFncyAzMgovRm9udEJCb3ggWyAtMTAyMSAtNDYzIDE3OTQgMTIzMyBdIC9Bc2NlbnQgOTI5IC9EZXNjZW50IC0yMzYgL0NhcEhlaWdodCAwCi9YSGVpZ2h0IDAgL0l0YWxpY0FuZ2xlIDAgL1N0ZW1WIDAgL01heFdpZHRoIDEzNDIgPj4KZW5kb2JqCjE0IDAgb2JqClsgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAKNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCAzMTggNDAxIDQ2MCA4MzggNjM2Cjk1MCA3ODAgMjc1IDM5MCAzOTAgNTAwIDgzOCAzMTggMzYxIDMxOCAzMzcgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNgo2MzYgNjM2IDMzNyAzMzcgODM4IDgzOCA4MzggNTMxIDEwMDAgNjg0IDY4NiA2OTggNzcwIDYzMiA1NzUgNzc1IDc1MiAyOTUKMjk1IDY1NiA1NTcgODYzIDc0OCA3ODcgNjAzIDc4NyA2OTUgNjM1IDYxMSA3MzIgNjg0IDk4OSA2ODUgNjExIDY4NSAzOTAgMzM3CjM5MCA4MzggNTAwIDUwMCA2MTMgNjM1IDU1MCA2MzUgNjE1IDM1MiA2MzUgNjM0IDI3OCAyNzggNTc5IDI3OCA5NzQgNjM0IDYxMgo2MzUgNjM1IDQxMSA1MjEgMzkyIDYzNCA1OTIgODE4IDU5MiA1OTIgNTI1IDYzNiAzMzcgNjM2IDgzOCA2MDAgNjM2IDYwMCAzMTgKMzUyIDUxOCAxMDAwIDUwMCA1MDAgNTAwIDEzNDIgNjM1IDQwMCAxMDcwIDYwMCA2ODUgNjAwIDYwMCAzMTggMzE4IDUxOCA1MTgKNTkwIDUwMCAxMDAwIDUwMCAxMDAwIDUyMSA0MDAgMTAyMyA2MDAgNTI1IDYxMSAzMTggNDAxIDYzNiA2MzYgNjM2IDYzNiAzMzcKNTAwIDUwMCAxMDAwIDQ3MSA2MTIgODM4IDM2MSAxMDAwIDUwMCA1MDAgODM4IDQwMSA0MDEgNTAwIDYzNiA2MzYgMzE4IDUwMAo0MDEgNDcxIDYxMiA5NjkgOTY5IDk2OSA1MzEgNjg0IDY4NCA2ODQgNjg0IDY4NCA2ODQgOTc0IDY5OCA2MzIgNjMyIDYzMiA2MzIKMjk1IDI5NSAyOTUgMjk1IDc3NSA3NDggNzg3IDc4NyA3ODcgNzg3IDc4NyA4MzggNzg3IDczMiA3MzIgNzMyIDczMiA2MTEgNjA1CjYzMCA2MTMgNjEzIDYxMyA2MTMgNjEzIDYxMyA5ODIgNTUwIDYxNSA2MTUgNjE1IDYxNSAyNzggMjc4IDI3OCAyNzggNjEyIDYzNAo2MTIgNjEyIDYxMiA2MTIgNjEyIDgzOCA2MTIgNjM0IDYzNCA2MzQgNjM0IDU5MiA2MzUgNTkyIF0KZW5kb2JqCjE3IDAgb2JqCjw8IC9DIDE4IDAgUiAvYSAxOSAwIFIgL2IgMjAgMCBSIC9jIDIxIDAgUiAvZCAyMiAwIFIgL2UgMjMgMCBSIC9oIDI0IDAgUgovayAyNSAwIFIgL20gMjYgMCBSIC9vIDI3IDAgUiAvciAyOCAwIFIgL3MgMjkgMCBSIC9zcGFjZSAzMCAwIFIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL0YxIDE2IDAgUiA+PgplbmRvYmoKNCAwIG9iago8PCAvQTEgPDwgL1R5cGUgL0V4dEdTdGF0ZSAvQ0EgMSAvY2EgMSA+PiA+PgplbmRvYmoKNSAwIG9iago8PCA+PgplbmRvYmoKNiAwIG9iago8PCA+PgplbmRvYmoKNyAwIG9iago8PCAvSTEgMTMgMCBSID4+CmVuZG9iagoxMyAwIG9iago8PCAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDIxMiAvSGVpZ2h0IDExNgovQ29sb3JTcGFjZSBbL0luZGV4ZWQgL0RldmljZVJHQiAyICj///9/f38AAAApXSAvQml0c1BlckNvbXBvbmVudCA4Ci9GaWx0ZXIgL0ZsYXRlRGVjb2RlCi9EZWNvZGVQYXJtcyA8PCAvUHJlZGljdG9yIDEwIC9Db2xvcnMgMSAvQ29sdW1ucyAyMTIgPj4gL0xlbmd0aCAzMSAwIFIgPj4Kc3RyZWFtCnic7dAxTkAxDETBD/c/NJ1pXCxSENnPvNKS5Uyejxf2/PUDfiOolqBagmoJqiWolqBagmoJqqV/g/qcnumHo+/ZdjTbzEbbASgoKCgoKKgLUCdOzWhDZZvh90FBQUFBQUHdiTpxakYbKtsMvw8KCgoKCuoFqBOnZrShss3w+6CgoKCgoKDuRJ04NaMNlW2G3wcFBQUFBQV1J+rEqRltqGwz/D4oKCgoKKgXoE6cmtGGyjbD74OCgoKCgoK6E3Xi1Iw2VLYZfh8UFBQUFBTUnaj6oFqCagmqJaiWoFqCagmqJaiWoFr6AjRXYBEKZW5kc3RyZWFtCmVuZG9iagozMSAwIG9iagoyMzUKZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFsgMTEgMCBSIF0gL0NvdW50IDEgPj4KZW5kb2JqCjMyIDAgb2JqCjw8IC9DcmVhdG9yIChNYXRwbG90bGliIHYzLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZykKL1Byb2R1Y2VyIChNYXRwbG90bGliIHBkZiBiYWNrZW5kIHYzLjcuMSkgL0NyZWF0aW9uRGF0ZSAoRDoyMDIzMDMxNDE2MDg1NFopCj4+CmVuZG9iagp4cmVmCjAgMzMKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDE2IDAwMDAwIG4gCjAwMDAwMDY4MzIgMDAwMDAgbiAKMDAwMDAwNjE1NyAwMDAwMCBuIAowMDAwMDA2MTg5IDAwMDAwIG4gCjAwMDAwMDYyNDkgMDAwMDAgbiAKMDAwMDAwNjI3MCAwMDAwMCBuIAowMDAwMDA2MjkxIDAwMDAwIG4gCjAwMDAwMDAwNjUgMDAwMDAgbiAKMDAwMDAwMDMzNyAwMDAwMCBuIAowMDAwMDAwNjYyIDAwMDAwIG4gCjAwMDAwMDAyMDggMDAwMDAgbiAKMDAwMDAwMDY0MiAwMDAwMCBuIAowMDAwMDA2MzIzIDAwMDAwIG4gCjAwMDAwMDQ5NDggMDAwMDAgbiAKMDAwMDAwNDc0MSAwMDAwMCBuIAowMDAwMDA0MzYyIDAwMDAwIG4gCjAwMDAwMDYwMDEgMDAwMDAgbiAKMDAwMDAwMDY4MiAwMDAwMCBuIAowMDAwMDAwOTkwIDAwMDAwIG4gCjAwMDAwMDEzNzAgMDAwMDAgbiAKMDAwMDAwMTY4NyAwMDAwMCBuIAowMDAwMDAxOTkyIDAwMDAwIG4gCjAwMDAwMDIyOTYgMDAwMDAgbiAKMDAwMDAwMjYxOCAwMDAwMCBuIAowMDAwMDAyODU1IDAwMDAwIG4gCjAwMDAwMDMwMTAgMDAwMDAgbiAKMDAwMDAwMzM0MSAwMDAwMCBuIAowMDAwMDAzNjMyIDAwMDAwIG4gCjAwMDAwMDM4NjUgMDAwMDAgbiAKMDAwMDAwNDI3MiAwMDAwMCBuIAowMDAwMDA2ODEyIDAwMDAwIG4gCjAwMDAwMDY4OTIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAzMyAvUm9vdCAxIDAgUiAvSW5mbyAzMiAwIFIgPj4Kc3RhcnR4cmVmCjcwNDMKJSVFT0YK", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:08:54.954296\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}, {"data": {"application/pdf": "JVBERi0xLjQKJazcIKu6CjEgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cgL1BhZ2VzIDIgMCBSID4+CmVuZG9iago4IDAgb2JqCjw8IC9Gb250IDMgMCBSIC9YT2JqZWN0IDcgMCBSIC9FeHRHU3RhdGUgNCAwIFIgL1BhdHRlcm4gNSAwIFIKL1NoYWRpbmcgNiAwIFIgL1Byb2NTZXQgWyAvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAvSW1hZ2VJIF0gPj4KZW5kb2JqCjExIDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL1Jlc291cmNlcyA4IDAgUgovTWVkaWFCb3ggWyAwIDAgMTY2Ljg2IDExMi42ODUgXSAvQ29udGVudHMgOSAwIFIgL0Fubm90cyAxMCAwIFIgPj4KZW5kb2JqCjkgMCBvYmoKPDwgL0xlbmd0aCAxMiAwIFIgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCnicVY87b8JAEIT7/RVThoK728O3mJKnFTqSk1JEKZAxBoONjCX4+1ks5UEx0syd5ttduyhux7x4y2aYv5P9S3lHjEpVwqFS3cHIVCU5TTWxiElF7fnHMnsjadAH988fiPbUYmx8Lw7eJIJ0ZFhwLfCBBnaq2E7ZlequyAzPm7R9TRI8Rms1+F9eXsO+MhYXbGiDVv/LJ5BmavUMh6FuhcSZcUjZB0zEjETrNItkVwz2iPv+trijT7zMD9umKc6ot91pgC/ENS0j6RD6BusbROgKZW5kc3RyZWFtCmVuZG9iagoxMiAwIG9iagoyMDgKZW5kb2JqCjEwIDAgb2JqClsgXQplbmRvYmoKMTggMCBvYmoKPDwgL0xlbmd0aCAyMzUgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCnicNVFJbgAxCLvnFf5ApbAn75mq6qH9/7WGUS8DA9jYJO/BRiQ+xJDuKFd8yuo0y/A7WeTFz0rh5L2ICqQqwgppB89yVjMMnhuZApcz8VlmPpkWOxZQTcRxduQ0g0GIaVxHy+kw0zzoCbk+GHFjp1muYkjr3VK9vtfynyrKR9bdLLdO2dRK3aJn7Elcdl5PbWlfGHUUNwWRDh87vAf5IuYsLjqRbvabKYeVpCE4LYAfiaFUzw6vESZ+ZiR4yp5O76M0vPZB0/W9e0FHbiZkKrdQRiqerDTGjKH6jWgmqe//gZ71vb7+AENNVLkKZW5kc3RyZWFtCmVuZG9iagoxOSAwIG9iago8PCAvTGVuZ3RoIDMwNyAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeJw9kktuAzEMQ/c+hS4QwPrZnvOkKLqY3n/bJyXpihzZFkVqlrpMWVMekDSThH/p8HCxnfI7bM9mZuBaopeJ5ZTn0BVi7qJ82cxGXVknxeqEZjq36FE5Fwc2Taqfqyyl3S54Dtcmnlv2ET+80KAe1DUuCTd0V6NlKTRjqvt/0nv8jDLgakxdbFKrex88XkRV6OgHR4kiY5cX5+NBCelKwmhaiJV3RQNB7vK0ynsJ7tveasiyB6mYzjspZrDrdFIubheHIR7I8qjw5aPYa0LP+LArJfRI2IYzcifuaMbm1MjikP7ejQRLj65oIfPgr27WLmC8UzpFYmROcqxpi1VO91AU07nDvQwQ9WxFQylzkdXqX8POC2uWbBZ4SvoFHqPdJksOVtnbqE7vrTzZ0PcfWtd0HwplbmRzdHJlYW0KZW5kb2JqCjIwIDAgb2JqCjw8IC9MZW5ndGggMjQ5IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4nD1QO45EIQzrOYUv8CTyI3AeRqstZu/frgOaKVBMfrYzJNARgUcMMZSv4yWtoK6Bv4tC8W7i64PCIKtDUiDOeg+IdOymNpETOh2cMz9hN2OOwEUxBpzpdKY9ByY5+8IKhHMbZexWSCeJqiKO6jOOKZ4qe594FiztyDZbJ5I95CDhUlKJyaWflMo/bcqUCjpm0QQsErngZBNNOMu7SVKMGZQy6h6mdiJ9rDzIozroZE3OrCOZ2dNP25n4HHC3X9pkTpXHdB7M+Jy0zoM5Fbr344k2B02N2ujs9xNpKi9Sux1anX51EpXdGOcYEpdnfxnfZP/5B/6HWiIKZW5kc3RyZWFtCmVuZG9iagoyMSAwIG9iago8PCAvTGVuZ3RoIDE2NCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeJxFkMdxBTEMQ++qAiUwgAr1rMfzD+v+r4b000F6GEIMYk/CsFxXcWF0w4+3LTMNf0cZ7sb6MmO81VggJ+gDDJGJq9Gk+nbFGar05NVirqOiXC86IhLMkuOrQCN8OrLHk7a2M/10Xh/sIe8T/yoq525hAS6q7kD5Uh/x1I/ZUeqaoY8qK2seatpXhF0RSts+LqcyTt29A1rhvZWrPdrvPx52OvIKZW5kc3RyZWFtCmVuZG9iagoyMiAwIG9iago8PCAvTGVuZ3RoIDgzIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4nD3MORKAMAgF0J5T/COEyCL3cRyLeP9WMNEGHqt6oCE4g7rBreFgyrp0E+9T49XGnBIJqHhKTZa6C3rUtL7Uvmjgu+vmS9WJP83PF50Pux0Z3QplbmRzdHJlYW0KZW5kb2JqCjIzIDAgb2JqCjw8IC9MZW5ndGggNDcgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCnicMzK3UDBQsDQBEoYWJgrmZgYKKYZclhBWLhdMLAfMAtGWcAoinsGVBgC5Zw0nCmVuZHN0cmVhbQplbmRvYmoKMjQgMCBvYmoKPDwgL0xlbmd0aCAyNTggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCnicRZFLcgQgCET3noIjgPzkPJNKZTG5/zYNzmQ2dpeo/YRKI6YSLOcUeTB9yfLNZLbpdzlWOxsFFEUomMlV6LECqztTxJlriWrrY2XkuNM7BsUbzl05qWRxo4x1VHUqcEzPlfVR3fl2WZR9Rw5lCtiscxxs4MptwxgnRput7g73iSBPJ1NHxe0g2fAHJ419lasrcJ1s9tFLMA4E/UITmOSLQOsMgcbNU/TkEuzj43bngWBveRFI2RDIkSEYHYJ2nVz/4tb5vf9xhjvPtRmuHO/id5jWdsdfYpIVcwGL3Cmo52suWtcZOt6TM8fkpvuGzrlgl7uDTO/5P9bP+v4DHilm+gplbmRzdHJlYW0KZW5kb2JqCjI1IDAgb2JqCjw8IC9MZW5ndGggMTYzIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4nEWQOxIDIQxDe06hI/gjAz7PZjIpNvdvY9hsUsDTWCCDuxOC1NqCieiCh7Yl3QXvrQRnY/zpNm41EuQEdYBWpONolFJ9ucVplXTxaDZzKwutEx1mDnqUoxmgEDoV3u2i5HKm7s75Q3D1X/W/Yt05m4mBycodCM3qU9z5NjuiurrJ/qTH3KzXfivsVWFpWUvLCbedu2ZACdxTOdqrPT8fCjr2CmVuZHN0cmVhbQplbmRvYmoKMjYgMCBvYmoKPDwgL0xlbmd0aCAzMzQgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCnicLVJLcsUgDNtzCl2gM/gH5DzpdLp4vf+2kpNFRg5g9DHlholKfFkgt6PWxLeNzECF4a+rzIXPSNvIOojLkIu4ki2Fe0Qs5DHEPMSC76vxHh75rMzJswfGL9l3Dyv21IRlIePFGdphFcdhFeRYsHUhqnt4U6TDqSTY44v/PsVzLQQtfEbQgF/kn6+O4PmSFmn3mG3TrnqwTDuqpLAcbE9zXiZfWme5Oh7PB8n2rtgRUrsCFIW5M85z4SjTVka0FnY2SGpcbG+O/VhK0IVuXEaKI5CfqSI8oKTJzCYK4o+cHnIqA2Hqmq50chtVcaeezDWbi7czSWbrvkixmcJ5XTiz/gxTZrV5J89yotSpCO+xZ0vQ0Dmunr2WWWh0mxO8pITPxk5PTr5XM+shORUJqWJaV8FpFJliCdsSX1NRU5p6Gf778u7xO37+ASxzfHMKZW5kc3RyZWFtCmVuZG9iagoyNyAwIG9iago8PCAvTGVuZ3RoIDE4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4nDM2tFAwgMMUQ640AB3mA1IKZW5kc3RyZWFtCmVuZG9iagoxNiAwIG9iago8PCAvVHlwZSAvRm9udCAvQmFzZUZvbnQgL0JNUVFEVitEZWphVnVTYW5zIC9GaXJzdENoYXIgMCAvTGFzdENoYXIgMjU1Ci9Gb250RGVzY3JpcHRvciAxNSAwIFIgL1N1YnR5cGUgL1R5cGUzIC9OYW1lIC9CTVFRRFYrRGVqYVZ1U2FucwovRm9udEJCb3ggWyAtMTAyMSAtNDYzIDE3OTQgMTIzMyBdIC9Gb250TWF0cml4IFsgMC4wMDEgMCAwIDAuMDAxIDAgMCBdCi9DaGFyUHJvY3MgMTcgMCBSCi9FbmNvZGluZyA8PCAvVHlwZSAvRW5jb2RpbmcKL0RpZmZlcmVuY2VzIFsgMzIgL3NwYWNlIDY3IC9DIDk3IC9hIDEwMSAvZSAxMDQgL2ggMTA3IC9rIC9sIC9tIC9uIDExNSAvcyBdCj4+Ci9XaWR0aHMgMTQgMCBSID4+CmVuZG9iagoxNSAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0ZvbnROYW1lIC9CTVFRRFYrRGVqYVZ1U2FucyAvRmxhZ3MgMzIKL0ZvbnRCQm94IFsgLTEwMjEgLTQ2MyAxNzk0IDEyMzMgXSAvQXNjZW50IDkyOSAvRGVzY2VudCAtMjM2IC9DYXBIZWlnaHQgMAovWEhlaWdodCAwIC9JdGFsaWNBbmdsZSAwIC9TdGVtViAwIC9NYXhXaWR0aCAxMzQyID4+CmVuZG9iagoxNCAwIG9iagpbIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwCjYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgMzE4IDQwMSA0NjAgODM4IDYzNgo5NTAgNzgwIDI3NSAzOTAgMzkwIDUwMCA4MzggMzE4IDM2MSAzMTggMzM3IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYKNjM2IDYzNiAzMzcgMzM3IDgzOCA4MzggODM4IDUzMSAxMDAwIDY4NCA2ODYgNjk4IDc3MCA2MzIgNTc1IDc3NSA3NTIgMjk1CjI5NSA2NTYgNTU3IDg2MyA3NDggNzg3IDYwMyA3ODcgNjk1IDYzNSA2MTEgNzMyIDY4NCA5ODkgNjg1IDYxMSA2ODUgMzkwIDMzNwozOTAgODM4IDUwMCA1MDAgNjEzIDYzNSA1NTAgNjM1IDYxNSAzNTIgNjM1IDYzNCAyNzggMjc4IDU3OSAyNzggOTc0IDYzNCA2MTIKNjM1IDYzNSA0MTEgNTIxIDM5MiA2MzQgNTkyIDgxOCA1OTIgNTkyIDUyNSA2MzYgMzM3IDYzNiA4MzggNjAwIDYzNiA2MDAgMzE4CjM1MiA1MTggMTAwMCA1MDAgNTAwIDUwMCAxMzQyIDYzNSA0MDAgMTA3MCA2MDAgNjg1IDYwMCA2MDAgMzE4IDMxOCA1MTggNTE4CjU5MCA1MDAgMTAwMCA1MDAgMTAwMCA1MjEgNDAwIDEwMjMgNjAwIDUyNSA2MTEgMzE4IDQwMSA2MzYgNjM2IDYzNiA2MzYgMzM3CjUwMCA1MDAgMTAwMCA0NzEgNjEyIDgzOCAzNjEgMTAwMCA1MDAgNTAwIDgzOCA0MDEgNDAxIDUwMCA2MzYgNjM2IDMxOCA1MDAKNDAxIDQ3MSA2MTIgOTY5IDk2OSA5NjkgNTMxIDY4NCA2ODQgNjg0IDY4NCA2ODQgNjg0IDk3NCA2OTggNjMyIDYzMiA2MzIgNjMyCjI5NSAyOTUgMjk1IDI5NSA3NzUgNzQ4IDc4NyA3ODcgNzg3IDc4NyA3ODcgODM4IDc4NyA3MzIgNzMyIDczMiA3MzIgNjExIDYwNQo2MzAgNjEzIDYxMyA2MTMgNjEzIDYxMyA2MTMgOTgyIDU1MCA2MTUgNjE1IDYxNSA2MTUgMjc4IDI3OCAyNzggMjc4IDYxMiA2MzQKNjEyIDYxMiA2MTIgNjEyIDYxMiA4MzggNjEyIDYzNCA2MzQgNjM0IDYzNCA1OTIgNjM1IDU5MiBdCmVuZG9iagoxNyAwIG9iago8PCAvQyAxOCAwIFIgL2EgMTkgMCBSIC9lIDIwIDAgUiAvaCAyMSAwIFIgL2sgMjIgMCBSIC9sIDIzIDAgUiAvbSAyNCAwIFIKL24gMjUgMCBSIC9zIDI2IDAgUiAvc3BhY2UgMjcgMCBSID4+CmVuZG9iagozIDAgb2JqCjw8IC9GMSAxNiAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0ExIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDEgL2NhIDEgPj4gPj4KZW5kb2JqCjUgMCBvYmoKPDwgPj4KZW5kb2JqCjYgMCBvYmoKPDwgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0kxIDEzIDAgUiA+PgplbmRvYmoKMTMgMCBvYmoKPDwgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0aCAyMTIgL0hlaWdodCAxMTYKL0NvbG9yU3BhY2UgWy9JbmRleGVkIC9EZXZpY2VSR0IgMiAo////f39/AAAAKV0gL0JpdHNQZXJDb21wb25lbnQgOAovRmlsdGVyIC9GbGF0ZURlY29kZQovRGVjb2RlUGFybXMgPDwgL1ByZWRpY3RvciAxMCAvQ29sb3JzIDEgL0NvbHVtbnMgMjEyID4+IC9MZW5ndGggMjggMCBSID4+CnN0cmVhbQp4nO3PwRGAMBDDwIP+i6YBnmEYJasG7J1rw+bvA18EVQmqElQlqEpQlaAqQVWCqnQMalb2NnqvDAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKqovKB1UJqhJUJahKUJWgKkFVgqoEVekBUBpgEQplbmRzdHJlYW0KZW5kb2JqCjI4IDAgb2JqCjE0NgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZXMgL0tpZHMgWyAxMSAwIFIgXSAvQ291bnQgMSA+PgplbmRvYmoKMjkgMCBvYmoKPDwgL0NyZWF0b3IgKE1hdHBsb3RsaWIgdjMuNy4xLCBodHRwczovL21hdHBsb3RsaWIub3JnKQovUHJvZHVjZXIgKE1hdHBsb3RsaWIgcGRmIGJhY2tlbmQgdjMuNy4xKSAvQ3JlYXRpb25EYXRlIChEOjIwMjMwMzE0MTYwODU1WikKPj4KZW5kb2JqCnhyZWYKMCAzMAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDAwNTU4MyAwMDAwMCBuIAowMDAwMDA0OTk3IDAwMDAwIG4gCjAwMDAwMDUwMjkgMDAwMDAgbiAKMDAwMDAwNTA4OSAwMDAwMCBuIAowMDAwMDA1MTEwIDAwMDAwIG4gCjAwMDAwMDUxMzEgMDAwMDAgbiAKMDAwMDAwMDA2NSAwMDAwMCBuIAowMDAwMDAwMzM3IDAwMDAwIG4gCjAwMDAwMDA2NDAgMDAwMDAgbiAKMDAwMDAwMDIwOCAwMDAwMCBuIAowMDAwMDAwNjIwIDAwMDAwIG4gCjAwMDAwMDUxNjMgMDAwMDAgbiAKMDAwMDAwMzgxOCAwMDAwMCBuIAowMDAwMDAzNjExIDAwMDAwIG4gCjAwMDAwMDMyNDUgMDAwMDAgbiAKMDAwMDAwNDg3MSAwMDAwMCBuIAowMDAwMDAwNjYwIDAwMDAwIG4gCjAwMDAwMDA5NjggMDAwMDAgbiAKMDAwMDAwMTM0OCAwMDAwMCBuIAowMDAwMDAxNjcwIDAwMDAwIG4gCjAwMDAwMDE5MDcgMDAwMDAgbiAKMDAwMDAwMjA2MiAwMDAwMCBuIAowMDAwMDAyMTgxIDAwMDAwIG4gCjAwMDAwMDI1MTIgMDAwMDAgbiAKMDAwMDAwMjc0OCAwMDAwMCBuIAowMDAwMDAzMTU1IDAwMDAwIG4gCjAwMDAwMDU1NjMgMDAwMDAgbiAKMDAwMDAwNTY0MyAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDMwIC9Sb290IDEgMCBSIC9JbmZvIDI5IDAgUiA+PgpzdGFydHhyZWYKNTc5NAolJUVPRgo=", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:08:55.028934\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["checkerboard_mask = create_checkerboard_mask(h=8, w=8).expand(-1, 2, -1, -1)\n", "channel_mask = create_channel_mask(c_in=2).expand(-1, -1, 8, 8)\n", "\n", "show_imgs(checkerboard_mask.transpose(0, 1), \"Checkerboard mask\")\n", "show_imgs(channel_mask.transpose(0, 1), \"Channel mask\")"]}, {"cell_type": "markdown", "id": "1bda3665", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017332, "end_time": "2023-03-14T16:08:55.118805", "exception": false, "start_time": "2023-03-14T16:08:55.101473", "status": "completed"}, "tags": []}, "source": ["As a last aspect of coupling layers, we need to decide for the deep neural network we want to apply in the coupling layers.\n", "The input to the layers is an image, and hence we stick with a CNN.\n", "Because the input to a transformation depends on all transformations before,\n", "it is crucial to ensure a good gradient flow through the CNN back to the input,\n", "which can be optimally achieved by a ResNet-like architecture.\n", "Specifically, we use a Gated ResNet that adds a $\\sigma$-gate to the skip connection,\n", "similarly to the input gate in LSTMs.\n", "The details are not necessarily important here, and the network is\n", "strongly inspired from Flow++ [3] in case you are interested in building\n", "even stronger models."]}, {"cell_type": "code", "execution_count": 16, "id": "de6ca2e1", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:55.155408Z", "iopub.status.busy": "2023-03-14T16:08:55.154889Z", "iopub.status.idle": "2023-03-14T16:08:55.171000Z", "shell.execute_reply": "2023-03-14T16:08:55.170454Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.037079, "end_time": "2023-03-14T16:08:55.173218", "exception": false, "start_time": "2023-03-14T16:08:55.136139", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class ConcatELU(nn.Module):\n", " \"\"\"Activation function that applies ELU in both direction (inverted and plain).\n", "\n", " Allows non-linearity while providing strong gradients for any input (important for final convolution)\n", " \"\"\"\n", "\n", " def forward(self, x):\n", " return torch.cat([F.elu(x), F.elu(-x)], dim=1)\n", "\n", "\n", "class LayerNormChannels(nn.Module):\n", " def __init__(self, c_in, eps=1e-5):\n", " \"\"\"\n", " This module applies layer norm across channels in an image.\n", " Inputs:\n", " c_in - Number of channels of the input\n", " eps - Small constant to stabilize std\n", " \"\"\"\n", " super().__init__()\n", " self.gamma = nn.Parameter(torch.ones(1, c_in, 1, 1))\n", " self.beta = nn.Parameter(torch.zeros(1, c_in, 1, 1))\n", " self.eps = eps\n", "\n", " def forward(self, x):\n", " mean = x.mean(dim=1, keepdim=True)\n", " var = x.var(dim=1, unbiased=False, keepdim=True)\n", " y = (x - mean) / torch.sqrt(var + self.eps)\n", " y = y * self.gamma + self.beta\n", " return y\n", "\n", "\n", "class GatedConv(nn.Module):\n", " def __init__(self, c_in, c_hidden):\n", " \"\"\"\n", " This module applies a two-layer convolutional ResNet block with input gate\n", " Args:\n", " c_in: Number of channels of the input\n", " c_hidden: Number of hidden dimensions we want to model (usually similar to c_in)\n", " \"\"\"\n", " super().__init__()\n", " self.net = nn.Sequential(\n", " ConcatELU(),\n", " nn.Conv2d(2 * c_in, c_hidden, kernel_size=3, padding=1),\n", " ConcatELU(),\n", " nn.Conv2d(2 * c_hidden, 2 * c_in, kernel_size=1),\n", " )\n", "\n", " def forward(self, x):\n", " out = self.net(x)\n", " val, gate = out.chunk(2, dim=1)\n", " return x + val * torch.sigmoid(gate)\n", "\n", "\n", "class GatedConvNet(nn.Module):\n", " def __init__(self, c_in, c_hidden=32, c_out=-1, num_layers=3):\n", " \"\"\"Module that summarizes the previous blocks to a full convolutional neural network.\n", "\n", " Args:\n", " c_in: Number of input channels\n", " c_hidden: Number of hidden dimensions to use within the network\n", " c_out: Number of output channels. If -1, 2 times the input channels are used (affine coupling)\n", " num_layers: Number of gated ResNet blocks to apply\n", " \"\"\"\n", " super().__init__()\n", " c_out = c_out if c_out > 0 else 2 * c_in\n", " layers = []\n", " layers += [nn.Conv2d(c_in, c_hidden, kernel_size=3, padding=1)]\n", " for layer_index in range(num_layers):\n", " layers += [GatedConv(c_hidden, c_hidden), LayerNormChannels(c_hidden)]\n", " layers += [ConcatELU(), nn.Conv2d(2 * c_hidden, c_out, kernel_size=3, padding=1)]\n", " self.nn = nn.Sequential(*layers)\n", "\n", " self.nn[-1].weight.data.zero_()\n", " self.nn[-1].bias.data.zero_()\n", "\n", " def forward(self, x):\n", " return self.nn(x)"]}, {"cell_type": "markdown", "id": "3084a0b1", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017371, "end_time": "2023-03-14T16:08:55.211629", "exception": false, "start_time": "2023-03-14T16:08:55.194258", "status": "completed"}, "tags": []}, "source": ["### Training loop\n", "\n", "Finally, we can add Dequantization, Variational Dequantization and Coupling Layers together to build our full normalizing flow on MNIST images.\n", "We apply 8 coupling layers in the main flow, and 4 for variational dequantization if applied.\n", "We apply a checkerboard mask throughout the network as with a single channel (black-white images),\n", "we cannot apply channel mask.\n", "The overall architecture is visualized below.\n", "\n", "\n", "
"]}, {"cell_type": "code", "execution_count": 17, "id": "1bec6c41", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:55.248636Z", "iopub.status.busy": "2023-03-14T16:08:55.248203Z", "iopub.status.idle": "2023-03-14T16:08:55.257903Z", "shell.execute_reply": "2023-03-14T16:08:55.257293Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.030947, "end_time": "2023-03-14T16:08:55.260082", "exception": false, "start_time": "2023-03-14T16:08:55.229135", "status": "completed"}, "tags": []}, "outputs": [], "source": ["def create_simple_flow(use_vardeq=True):\n", " flow_layers = []\n", " if use_vardeq:\n", " vardeq_layers = [\n", " CouplingLayer(\n", " network=GatedConvNet(c_in=2, c_out=2, c_hidden=16),\n", " mask=create_checkerboard_mask(h=28, w=28, invert=(i % 2 == 1)),\n", " c_in=1,\n", " )\n", " for i in range(4)\n", " ]\n", " flow_layers += [VariationalDequantization(var_flows=vardeq_layers)]\n", " else:\n", " flow_layers += [Dequantization()]\n", "\n", " for i in range(8):\n", " flow_layers += [\n", " CouplingLayer(\n", " network=GatedConvNet(c_in=1, c_hidden=32),\n", " mask=create_checkerboard_mask(h=28, w=28, invert=(i % 2 == 1)),\n", " c_in=1,\n", " )\n", " ]\n", "\n", " flow_model = ImageFlow(flow_layers).to(device)\n", " return flow_model"]}, {"cell_type": "markdown", "id": "a2bc5ef0", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017328, "end_time": "2023-03-14T16:08:55.296857", "exception": false, "start_time": "2023-03-14T16:08:55.279529", "status": "completed"}, "tags": []}, "source": ["For implementing the training loop, we use the framework of PyTorch Lightning and reduce the code overhead.\n", "If interested, you can take a look at the generated tensorboard file,\n", "in particularly the graph to see an overview of flow transformations that are applied.\n", "Note that we again provide pre-trained models (see later on in the notebook)\n", "as normalizing flows are particularly expensive to train.\n", "We have also run validation and testing as this can take some time as well with the added importance sampling."]}, {"cell_type": "code", "execution_count": 18, "id": "25bb5564", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:55.333029Z", "iopub.status.busy": "2023-03-14T16:08:55.332680Z", "iopub.status.idle": "2023-03-14T16:08:55.346583Z", "shell.execute_reply": "2023-03-14T16:08:55.345982Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.034613, "end_time": "2023-03-14T16:08:55.348820", "exception": false, "start_time": "2023-03-14T16:08:55.314207", "status": "completed"}, "tags": []}, "outputs": [], "source": ["def train_flow(flow, model_name=\"MNISTFlow\"):\n", " # Create a PyTorch Lightning trainer\n", " trainer = L.Trainer(\n", " default_root_dir=os.path.join(CHECKPOINT_PATH, model_name),\n", " accelerator=\"auto\",\n", " devices=1,\n", " max_epochs=200,\n", " gradient_clip_val=1.0,\n", " callbacks=[\n", " ModelCheckpoint(save_weights_only=True, mode=\"min\", monitor=\"val_bpd\"),\n", " LearningRateMonitor(\"epoch\"),\n", " ],\n", " )\n", " trainer.logger._log_graph = True\n", " trainer.logger._default_hp_metric = None # Optional logging argument that we don't need\n", "\n", " train_data_loader = data.DataLoader(\n", " train_set, batch_size=128, shuffle=True, drop_last=True, pin_memory=True, num_workers=8\n", " )\n", " result = None\n", "\n", " # Check whether pretrained model exists. If yes, load it and skip training\n", " pretrained_filename = os.path.join(CHECKPOINT_PATH, model_name + \".ckpt\")\n", " if os.path.isfile(pretrained_filename):\n", " print(\"Found pretrained model, loading...\")\n", " ckpt = torch.load(pretrained_filename, map_location=device)\n", " flow.load_state_dict(ckpt[\"state_dict\"])\n", " result = ckpt.get(\"result\", None)\n", " else:\n", " print(\"Start training\", model_name)\n", " trainer.fit(flow, train_data_loader, val_loader)\n", "\n", " # Test best model on validation and test set if no result has been found\n", " # Testing can be expensive due to the importance sampling.\n", " if result is None:\n", " val_result = trainer.test(flow, dataloaders=val_loader, verbose=False)\n", " start_time = time.time()\n", " test_result = trainer.test(flow, dataloaders=test_loader, verbose=False)\n", " duration = time.time() - start_time\n", " result = {\"test\": test_result, \"val\": val_result, \"time\": duration / len(test_loader) / flow.import_samples}\n", "\n", " return flow, result"]}, {"cell_type": "markdown", "id": "321c2785", "metadata": {"papermill": {"duration": 0.017358, "end_time": "2023-03-14T16:08:55.387653", "exception": false, "start_time": "2023-03-14T16:08:55.370295", "status": "completed"}, "tags": []}, "source": ["## Multi-scale architecture\n", "\n", "
\n", "\n", "One disadvantage of normalizing flows is that they operate on the exact same dimensions as the input.\n", "If the input is high-dimensional, so is the latent space, which requires larger computational cost to learn suitable transformations.\n", "However, particularly in the image domain, many pixels contain less information in the sense\n", "that we could remove them without loosing the semantical information of the image.\n", "\n", "Based on this intuition, deep normalizing flows on images commonly apply a multi-scale architecture [1].\n", "After the first $N$ flow transformations, we split off half of the latent dimensions and directly evaluate them on the prior.\n", "The other half is run through $N$ more flow transformations, and depending on the size of the input,\n", "we split it again in half or stop overall at this position.\n", "The two operations involved in this setup is `Squeeze` and `Split` which\n", "we will review more closely and implement below."]}, {"cell_type": "markdown", "id": "b67b73bc", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017403, "end_time": "2023-03-14T16:08:55.422536", "exception": false, "start_time": "2023-03-14T16:08:55.405133", "status": "completed"}, "tags": []}, "source": ["### Squeeze and Split\n", "\n", "When we want to remove half of the pixels in an image, we have the problem of deciding which variables to cut,\n", "and how to rearrange the image.\n", "Thus, the squeezing operation is commonly used before split, which divides the image into subsquares\n", "of shape $2\\times 2\\times C$, and reshapes them into $1\\times 1\\times 4C$ blocks.\n", "Effectively, we reduce the height and width of the image by a factor of 2 while scaling the number of channels by 4.\n", "Afterwards, we can perform the split operation over channels without the need of rearranging the pixels.\n", "The smaller scale also makes the overall architecture more efficient.\n", "Visually, the squeeze operation should transform the input as follows:\n", "\n", "
\n", "\n", "The input of $4\\times 4\\times 1$ is scaled to $2\\times 2\\times 4$ following\n", "the idea of grouping the pixels in $2\\times 2\\times 1$ subsquares.\n", "Next, let's try to implement this layer:"]}, {"cell_type": "code", "execution_count": 19, "id": "1ae89a3f", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:55.458800Z", "iopub.status.busy": "2023-03-14T16:08:55.458447Z", "iopub.status.idle": "2023-03-14T16:08:55.467921Z", "shell.execute_reply": "2023-03-14T16:08:55.467065Z"}, "papermill": {"duration": 0.030217, "end_time": "2023-03-14T16:08:55.470193", "exception": false, "start_time": "2023-03-14T16:08:55.439976", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class SqueezeFlow(nn.Module):\n", " def forward(self, z, ldj, reverse=False):\n", " B, C, H, W = z.shape\n", " if not reverse:\n", " # Forward direction: H x W x C => H/2 x W/2 x 4C\n", " z = z.reshape(B, C, H // 2, 2, W // 2, 2)\n", " z = z.permute(0, 1, 3, 5, 2, 4)\n", " z = z.reshape(B, 4 * C, H // 2, W // 2)\n", " else:\n", " # Reverse direction: H/2 x W/2 x 4C => H x W x C\n", " z = z.reshape(B, C // 4, 2, 2, H, W)\n", " z = z.permute(0, 1, 4, 2, 5, 3)\n", " z = z.reshape(B, C // 4, H * 2, W * 2)\n", " return z, ldj"]}, {"cell_type": "markdown", "id": "414c6bf6", "metadata": {"papermill": {"duration": 0.017403, "end_time": "2023-03-14T16:08:55.508292", "exception": false, "start_time": "2023-03-14T16:08:55.490889", "status": "completed"}, "tags": []}, "source": ["Before moving on, we can verify our implementation by comparing our output with the example figure above:"]}, {"cell_type": "code", "execution_count": 20, "id": "c1f0cc17", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:55.544965Z", "iopub.status.busy": "2023-03-14T16:08:55.544742Z", "iopub.status.idle": "2023-03-14T16:08:55.551366Z", "shell.execute_reply": "2023-03-14T16:08:55.550861Z"}, "papermill": {"duration": 0.026587, "end_time": "2023-03-14T16:08:55.552899", "exception": false, "start_time": "2023-03-14T16:08:55.526312", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Image (before)\n", " tensor([[[[ 1, 2, 3, 4],\n", " [ 5, 6, 7, 8],\n", " [ 9, 10, 11, 12],\n", " [13, 14, 15, 16]]]])\n", "\n", "Image (forward)\n", " tensor([[[[ 1, 2, 5, 6],\n", " [ 3, 4, 7, 8]],\n", "\n", " [[ 9, 10, 13, 14],\n", " [11, 12, 15, 16]]]])\n", "\n", "Image (reverse)\n", " tensor([[[[ 1, 2, 3, 4],\n", " [ 5, 6, 7, 8],\n", " [ 9, 10, 11, 12],\n", " [13, 14, 15, 16]]]])\n"]}], "source": ["sq_flow = SqueezeFlow()\n", "rand_img = torch.arange(1, 17).view(1, 1, 4, 4)\n", "print(\"Image (before)\\n\", rand_img)\n", "forward_img, _ = sq_flow(rand_img, ldj=None, reverse=False)\n", "print(\"\\nImage (forward)\\n\", forward_img.permute(0, 2, 3, 1)) # Permute for readability\n", "reconst_img, _ = sq_flow(forward_img, ldj=None, reverse=True)\n", "print(\"\\nImage (reverse)\\n\", reconst_img)"]}, {"cell_type": "markdown", "id": "b64f0fc8", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017584, "end_time": "2023-03-14T16:08:55.591185", "exception": false, "start_time": "2023-03-14T16:08:55.573601", "status": "completed"}, "tags": []}, "source": ["The split operation divides the input into two parts, and evaluates one part directly on the prior.\n", "So that our flow operation fits to the implementation of the previous layers,\n", "we will return the prior probability of the first part as the log determinant jacobian of the layer.\n", "It has the same effect as if we would combine all variable splits at the\n", "end of the flow, and evaluate them together on the prior."]}, {"cell_type": "code", "execution_count": 21, "id": "e144a578", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:55.628014Z", "iopub.status.busy": "2023-03-14T16:08:55.627560Z", "iopub.status.idle": "2023-03-14T16:08:55.634432Z", "shell.execute_reply": "2023-03-14T16:08:55.633786Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.027109, "end_time": "2023-03-14T16:08:55.636027", "exception": false, "start_time": "2023-03-14T16:08:55.608918", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class SplitFlow(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.prior = torch.distributions.normal.Normal(loc=0.0, scale=1.0)\n", "\n", " def forward(self, z, ldj, reverse=False):\n", " if not reverse:\n", " z, z_split = z.chunk(2, dim=1)\n", " ldj += self.prior.log_prob(z_split).sum(dim=[1, 2, 3])\n", " else:\n", " z_split = self.prior.sample(sample_shape=z.shape).to(device)\n", " z = torch.cat([z, z_split], dim=1)\n", " ldj -= self.prior.log_prob(z_split).sum(dim=[1, 2, 3])\n", " return z, ldj"]}, {"cell_type": "markdown", "id": "63b1fe64", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017596, "end_time": "2023-03-14T16:08:55.676678", "exception": false, "start_time": "2023-03-14T16:08:55.659082", "status": "completed"}, "tags": []}, "source": ["### Building a multi-scale flow\n", "\n", "After defining the squeeze and split operation, we are finally able to build our own multi-scale flow.\n", "Deep normalizing flows such as Glow and Flow++ [2,3] often apply a split operation directly after squeezing.\n", "However, with shallow flows, we need to be more thoughtful about where to place the split operation as we need at least a minimum amount of transformations on each variable.\n", "Our setup is inspired by the original RealNVP architecture [1] which is shallower than other,\n", "more recent state-of-the-art architectures.\n", "\n", "Hence, for the MNIST dataset, we will apply the first squeeze operation after two coupling layers, but don't apply a split operation yet.\n", "Because we have only used two coupling layers and each the variable has been only transformed once, a split operation would be too early.\n", "We apply two more coupling layers before finally applying a split flow and squeeze again.\n", "The last four coupling layers operate on a scale of $7\\times 7\\times 8$.\n", "The full flow architecture is shown below.\n", "\n", "
\n", "\n", "Note that while the feature maps inside the coupling layers reduce with the height and width of the input,\n", "the increased number of channels is not directly considered.\n", "To counteract this, we increase the hidden dimensions for the coupling layers on the squeezed input.\n", "The dimensions are often scaled by 2 as this approximately increases the computation cost by 4 canceling with the squeezing operation.\n", "However, we will choose the hidden dimensionalities $32, 48, 64$ for the\n", "three scales respectively to keep the number of parameters reasonable\n", "and show the efficiency of multi-scale architectures."]}, {"cell_type": "code", "execution_count": 22, "id": "f65414af", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:55.713291Z", "iopub.status.busy": "2023-03-14T16:08:55.712818Z", "iopub.status.idle": "2023-03-14T16:08:55.723271Z", "shell.execute_reply": "2023-03-14T16:08:55.722130Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.031541, "end_time": "2023-03-14T16:08:55.725764", "exception": false, "start_time": "2023-03-14T16:08:55.694223", "status": "completed"}, "tags": []}, "outputs": [], "source": ["def create_multiscale_flow():\n", " flow_layers = []\n", "\n", " vardeq_layers = [\n", " CouplingLayer(\n", " network=GatedConvNet(c_in=2, c_out=2, c_hidden=16),\n", " mask=create_checkerboard_mask(h=28, w=28, invert=(i % 2 == 1)),\n", " c_in=1,\n", " )\n", " for i in range(4)\n", " ]\n", " flow_layers += [VariationalDequantization(vardeq_layers)]\n", "\n", " flow_layers += [\n", " CouplingLayer(\n", " network=GatedConvNet(c_in=1, c_hidden=32),\n", " mask=create_checkerboard_mask(h=28, w=28, invert=(i % 2 == 1)),\n", " c_in=1,\n", " )\n", " for i in range(2)\n", " ]\n", " flow_layers += [SqueezeFlow()]\n", " for i in range(2):\n", " flow_layers += [\n", " CouplingLayer(\n", " network=GatedConvNet(c_in=4, c_hidden=48), mask=create_channel_mask(c_in=4, invert=(i % 2 == 1)), c_in=4\n", " )\n", " ]\n", " flow_layers += [SplitFlow(), SqueezeFlow()]\n", " for i in range(4):\n", " flow_layers += [\n", " CouplingLayer(\n", " network=GatedConvNet(c_in=8, c_hidden=64), mask=create_channel_mask(c_in=8, invert=(i % 2 == 1)), c_in=8\n", " )\n", " ]\n", "\n", " flow_model = ImageFlow(flow_layers).to(device)\n", " return flow_model"]}, {"cell_type": "markdown", "id": "4d5371d1", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017539, "end_time": "2023-03-14T16:08:55.765523", "exception": false, "start_time": "2023-03-14T16:08:55.747984", "status": "completed"}, "tags": []}, "source": ["We can show the difference in number of parameters below:"]}, {"cell_type": "code", "execution_count": 23, "id": "3fd1623f", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:55.802358Z", "iopub.status.busy": "2023-03-14T16:08:55.801981Z", "iopub.status.idle": "2023-03-14T16:08:57.208234Z", "shell.execute_reply": "2023-03-14T16:08:57.207398Z"}, "papermill": {"duration": 1.426841, "end_time": "2023-03-14T16:08:57.209967", "exception": false, "start_time": "2023-03-14T16:08:55.783126", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Number of parameters: 556,312\n", "Number of parameters: 628,388\n", "Number of parameters: 1,711,818\n"]}], "source": ["def print_num_params(model):\n", " num_params = sum(np.prod(p.shape) for p in model.parameters())\n", " print(f\"Number of parameters: {num_params:,}\")\n", "\n", "\n", "print_num_params(create_simple_flow(use_vardeq=False))\n", "print_num_params(create_simple_flow(use_vardeq=True))\n", "print_num_params(create_multiscale_flow())"]}, {"cell_type": "markdown", "id": "ee63fa46", "metadata": {"papermill": {"duration": 0.028226, "end_time": "2023-03-14T16:08:57.262815", "exception": false, "start_time": "2023-03-14T16:08:57.234589", "status": "completed"}, "tags": []}, "source": ["Although the multi-scale flow has almost 3 times the parameters of the single scale flow,\n", "it is not necessarily more computationally expensive than its counterpart.\n", "We will compare the runtime in the following experiments as well."]}, {"cell_type": "markdown", "id": "fa5919dc", "metadata": {"papermill": {"duration": 0.017593, "end_time": "2023-03-14T16:08:57.301622", "exception": false, "start_time": "2023-03-14T16:08:57.284029", "status": "completed"}, "tags": []}, "source": ["## Analysing the flows\n", "\n", "In the last part of the notebook, we will train all the models we have implemented above,\n", "and try to analyze the effect of the multi-scale architecture and variational dequantization.\n", "\n", "### Training flow variants\n", "\n", "Before we can analyse the flow models, we need to train them first.\n", "We provide pre-trained models that contain the validation and test performance, and run-time information.\n", "As flow models are computationally expensive, we advice you to rely on\n", "those pretrained models for a first run through the notebook."]}, {"cell_type": "code", "execution_count": 24, "id": "655f8984", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:57.338023Z", "iopub.status.busy": "2023-03-14T16:08:57.337827Z", "iopub.status.idle": "2023-03-14T16:08:57.789595Z", "shell.execute_reply": "2023-03-14T16:08:57.788785Z"}, "papermill": {"duration": 0.472976, "end_time": "2023-03-14T16:08:57.792209", "exception": false, "start_time": "2023-03-14T16:08:57.319233", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["GPU available: True (cuda), used: True\n"]}, {"name": "stderr", "output_type": "stream", "text": ["TPU available: False, using: 0 TPU cores\n"]}, {"name": "stderr", "output_type": "stream", "text": ["IPU available: False, using: 0 IPUs\n"]}, {"name": "stderr", "output_type": "stream", "text": ["HPU available: False, using: 0 HPUs\n"]}, {"name": "stderr", "output_type": "stream", "text": ["GPU available: True (cuda), used: True\n"]}, {"name": "stderr", "output_type": "stream", "text": ["TPU available: False, using: 0 TPU cores\n"]}, {"name": "stderr", "output_type": "stream", "text": ["IPU available: False, using: 0 IPUs\n"]}, {"name": "stderr", "output_type": "stream", "text": ["HPU available: False, using: 0 HPUs\n"]}, {"name": "stderr", "output_type": "stream", "text": ["GPU available: True (cuda), used: True\n"]}, {"name": "stderr", "output_type": "stream", "text": ["TPU available: False, using: 0 TPU cores\n"]}, {"name": "stderr", "output_type": "stream", "text": ["IPU available: False, using: 0 IPUs\n"]}, {"name": "stderr", "output_type": "stream", "text": ["HPU available: False, using: 0 HPUs\n"]}, {"name": "stdout", "output_type": "stream", "text": ["Found pretrained model, loading...\n", "Found pretrained model, loading...\n", "Found pretrained model, loading...\n"]}], "source": ["flow_dict = {\"simple\": {}, \"vardeq\": {}, \"multiscale\": {}}\n", "flow_dict[\"simple\"][\"model\"], flow_dict[\"simple\"][\"result\"] = train_flow(\n", " create_simple_flow(use_vardeq=False), model_name=\"MNISTFlow_simple\"\n", ")\n", "flow_dict[\"vardeq\"][\"model\"], flow_dict[\"vardeq\"][\"result\"] = train_flow(\n", " create_simple_flow(use_vardeq=True), model_name=\"MNISTFlow_vardeq\"\n", ")\n", "flow_dict[\"multiscale\"][\"model\"], flow_dict[\"multiscale\"][\"result\"] = train_flow(\n", " create_multiscale_flow(), model_name=\"MNISTFlow_multiscale\"\n", ")"]}, {"cell_type": "markdown", "id": "f704f49e", "metadata": {"papermill": {"duration": 0.017977, "end_time": "2023-03-14T16:08:57.833000", "exception": false, "start_time": "2023-03-14T16:08:57.815023", "status": "completed"}, "tags": []}, "source": ["### Density modeling and sampling\n", "\n", "Firstly, we can compare the models on their quantitative results.\n", "The following table shows all important statistics.\n", "The inference time specifies the time needed to determine the\n", "probability for a batch of 64 images for each model, and the sampling\n", "time the duration it took to sample a batch of 64 images."]}, {"cell_type": "code", "execution_count": 25, "id": "5e593b47", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:57.870186Z", "iopub.status.busy": "2023-03-14T16:08:57.869973Z", "iopub.status.idle": "2023-03-14T16:08:57.878622Z", "shell.execute_reply": "2023-03-14T16:08:57.878204Z"}, "papermill": {"duration": 0.029186, "end_time": "2023-03-14T16:08:57.880201", "exception": false, "start_time": "2023-03-14T16:08:57.851015", "status": "completed"}, "tags": []}, "outputs": [{"data": {"text/html": ["\n", "\n"], "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["%%html\n", "\n", ""]}, {"cell_type": "code", "execution_count": 26, "id": "80d4f2a9", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:57.922444Z", "iopub.status.busy": "2023-03-14T16:08:57.922013Z", "iopub.status.idle": "2023-03-14T16:08:57.936216Z", "shell.execute_reply": "2023-03-14T16:08:57.935832Z"}, "papermill": {"duration": 0.035789, "end_time": "2023-03-14T16:08:57.938405", "exception": false, "start_time": "2023-03-14T16:08:57.902616", "status": "completed"}, "tags": []}, "outputs": [{"data": {"text/html": ["\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
Model Validation Bpd Test Bpd Inference time Sampling time Num Parameters
simple 1.080 bpd 1.078 bpd 20 ms 18 ms 556,312
vardeq 1.045 bpd 1.043 bpd 26 ms 18 ms 628,388
multiscale1.022 bpd 1.020 bpd 23 ms 15 ms 1,711,818
"], "text/plain": [""]}, "metadata": {}, "output_type": "display_data"}], "source": ["\n", "table = [\n", " [\n", " key,\n", " \"%4.3f bpd\" % flow_dict[key][\"result\"][\"val\"][0][\"test_bpd\"],\n", " \"%4.3f bpd\" % flow_dict[key][\"result\"][\"test\"][0][\"test_bpd\"],\n", " \"%2.0f ms\" % (1000 * flow_dict[key][\"result\"][\"time\"]),\n", " \"%2.0f ms\" % (1000 * flow_dict[key][\"result\"].get(\"samp_time\", 0)),\n", " \"{:,}\".format(sum(np.prod(p.shape) for p in flow_dict[key][\"model\"].parameters())),\n", " ]\n", " for key in flow_dict\n", "]\n", "display(\n", " HTML(\n", " tabulate.tabulate(\n", " table,\n", " tablefmt=\"html\",\n", " headers=[\"Model\", \"Validation Bpd\", \"Test Bpd\", \"Inference time\", \"Sampling time\", \"Num Parameters\"],\n", " )\n", " )\n", ")"]}, {"cell_type": "markdown", "id": "b4bc8486", "metadata": {"papermill": {"duration": 0.018627, "end_time": "2023-03-14T16:08:57.980586", "exception": false, "start_time": "2023-03-14T16:08:57.961959", "status": "completed"}, "tags": []}, "source": ["As we have intially expected, using variational dequantization improves upon standard dequantization in terms of bits per dimension.\n", "Although the difference with 0.04bpd doesn't seem impressive first, it is a considerably step for generative models\n", "(most state-of-the-art models improve upon previous models in a range of 0.02-0.1bpd on CIFAR with three times as high bpd).\n", "While it takes longer to evaluate the probability of an image due to the variational dequantization,\n", "which also leads to a longer training time, it does not have an effect on the sampling time.\n", "This is because inverting variational dequantization is the same as dequantization: finding the next lower integer.\n", "\n", "When we compare the two models to multi-scale architecture, we can see that the bits per dimension score again dropped by about 0.04bpd.\n", "Additionally, the inference time and sampling time improved notably despite having more parameters.\n", "Thus, we see that the multi-scale flow is not only stronger for density modeling, but also more efficient.\n", "\n", "Next, we can test the sampling quality of the models.\n", "We should note that the samples for variational dequantization and standard dequantization are very similar,\n", "and hence we visualize here only the ones for variational dequantization and the multi-scale model.\n", "However, feel free to also test out the `\"simple\"` model.\n", "The seeds are set to obtain reproducable generations and are not cherry picked."]}, {"cell_type": "code", "execution_count": 27, "id": "e1cbb1be", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:08:58.019235Z", "iopub.status.busy": "2023-03-14T16:08:58.018946Z", "iopub.status.idle": "2023-03-14T16:09:00.213140Z", "shell.execute_reply": "2023-03-14T16:09:00.212673Z"}, "papermill": {"duration": 2.214889, "end_time": "2023-03-14T16:09:00.214392", "exception": false, "start_time": "2023-03-14T16:08:57.999503", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["Global seed set to 44\n"]}, {"data": {"application/pdf": "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", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:00.147318\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["L.seed_everything(44)\n", "samples = flow_dict[\"vardeq\"][\"model\"].sample(img_shape=[16, 1, 28, 28])\n", "show_imgs(samples.cpu())"]}, {"cell_type": "code", "execution_count": 28, "id": "e60cb58e", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:09:00.254458Z", "iopub.status.busy": "2023-03-14T16:09:00.254291Z", "iopub.status.idle": "2023-03-14T16:09:00.375395Z", "shell.execute_reply": "2023-03-14T16:09:00.374906Z"}, "papermill": {"duration": 0.142231, "end_time": "2023-03-14T16:09:00.376562", "exception": false, "start_time": "2023-03-14T16:09:00.234331", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["Global seed set to 44\n"]}, {"data": {"application/pdf": "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", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:00.310180\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["L.seed_everything(44)\n", "samples = flow_dict[\"multiscale\"][\"model\"].sample(img_shape=[16, 8, 7, 7])\n", "show_imgs(samples.cpu())"]}, {"cell_type": "markdown", "id": "9c6d84f7", "metadata": {"papermill": {"duration": 0.019612, "end_time": "2023-03-14T16:09:00.415899", "exception": false, "start_time": "2023-03-14T16:09:00.396287", "status": "completed"}, "tags": []}, "source": ["From the few samples, we can see a clear difference between the simple and the multi-scale model.\n", "The single-scale model has only learned local, small correlations while the multi-scale model was able to learn full,\n", "global relations that form digits.\n", "This show-cases another benefit of the multi-scale model.\n", "In contrast to VAEs, the outputs are sharp as normalizing flows can naturally model complex,\n", "multi-modal distributions while VAEs have the independent decoder output noise.\n", "Nevertheless, the samples from this flow are far from perfect as not all samples show true digits."]}, {"cell_type": "markdown", "id": "944d6269", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.019671, "end_time": "2023-03-14T16:09:00.455179", "exception": false, "start_time": "2023-03-14T16:09:00.435508", "status": "completed"}, "tags": []}, "source": ["### Interpolation in latent space\n", "\n", "Another popular test for the smoothness of the latent space of generative models is to interpolate between two training examples.\n", "As normalizing flows are strictly invertible, we can guarantee that any image is represented in the latent space.\n", "We again compare the variational dequantization model with the multi-scale model below."]}, {"cell_type": "code", "execution_count": 29, "id": "7970cd2a", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:09:00.495723Z", "iopub.status.busy": "2023-03-14T16:09:00.495365Z", "iopub.status.idle": "2023-03-14T16:09:00.530122Z", "shell.execute_reply": "2023-03-14T16:09:00.529642Z"}, "papermill": {"duration": 0.056622, "end_time": "2023-03-14T16:09:00.531336", "exception": false, "start_time": "2023-03-14T16:09:00.474714", "status": "completed"}, "tags": []}, "outputs": [], "source": ["@torch.no_grad()\n", "def interpolate(model, img1, img2, num_steps=8):\n", " \"\"\"\n", " Args:\n", " model: object of ImageFlow class that represents the (trained) flow model\n", " img1, img2: Image tensors of shape [1, 28, 28]. Images between which should be interpolated.\n", " num_steps: Number of interpolation steps. 8 interpolation steps mean 6 intermediate pictures besides img1 and img2\n", " \"\"\"\n", " imgs = torch.stack([img1, img2], dim=0).to(model.device)\n", " z, _ = model.encode(imgs)\n", " alpha = torch.linspace(0, 1, steps=num_steps, device=z.device).view(-1, 1, 1, 1)\n", " interpolations = z[0:1] * alpha + z[1:2] * (1 - alpha)\n", " interp_imgs = model.sample(interpolations.shape[:1] + imgs.shape[1:], z_init=interpolations)\n", " show_imgs(interp_imgs, row_size=8)\n", "\n", "\n", "exmp_imgs, _ = next(iter(train_loader))"]}, {"cell_type": "code", "execution_count": 30, "id": "2e17956c", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:09:00.571381Z", "iopub.status.busy": "2023-03-14T16:09:00.571218Z", "iopub.status.idle": "2023-03-14T16:09:00.781262Z", "shell.execute_reply": "2023-03-14T16:09:00.780473Z"}, "papermill": {"duration": 0.231591, "end_time": "2023-03-14T16:09:00.782599", "exception": false, "start_time": "2023-03-14T16:09:00.551008", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["Global seed set to 42\n"]}, {"data": {"application/pdf": "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VA0L200OKXPQGdt9KTC+aGmbtXLlSrXN61m7dm3ga6WBlShDyXr37m3O8hogTf/kyZNZFuzKlSvOOjBqiAu5oyGLw1dUVJiDwrKEjRs3uuZZ0Lf7vimkmVpkmcNkguIgv5qALSn0j3XVMKpG1aiaClWjalSNqllA1ahallnCLabaMICku4DtR5RMq7A1a9akp+EArUGnTp1k9FrEsLDdZNI5Y7P/NtgPcs46cODAWOC92eKjZs2aE0HYpOyhlYhLoAx/k6uhMWswWL169QWQU8Hkme3Zs2dngDvBww8/LLtPApMnT5Z/li1b5p3CO/ssF5D8is1+YVmR3tzINYyqUbUcCkbV7MOoGlXLoWBUzT4simqyerkzUZg8dxo3btzJwD/0TZlWYQsWLPD1OMrKyn4BIoaF7SZFkAEk3qYolg8aNMj2HU+bLFnnZvr06fpuVC/wxBNPRMgKLdgfQfv27dMJtWvXng/ghHRD1HkUsi9YvrgBWVRNoGrBWVQtD1lUTaBqwVlULQ9ZVE2gasFZVC0PWe9a1eQOgvNYoSnITBQXMdMq7MSJE7Lou7SS4uLiFwCaahZhNrseAiNGjJA1UFu2bClrdqrzd+crK2duRCtJahZVE6hacFZim3+cWVRNoGrBWYlt/nFmvWtVy1dmYs9cnFmJLVicWVQtn2FJzUpsweLMomr5DEtqVmILFmcWVctnWFKzEluwOLOoWj7DkpqV2ILFmUXV8hmW1KzEFizOLKqWz7CkZiW2YHFmUbV8hiU1K7EFizPrhqhGCLmuUDVCYoGqERILVI2QWKBqhMQCVSMkFqgaIbHwf3T69MoKZW5kc3RyZWFtCmVuZG9iagoxNCAwIG9iago0Mjk2CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9QYWdlcyAvS2lkcyBbIDExIDAgUiBdIC9Db3VudCAxID4+CmVuZG9iagoxNSAwIG9iago8PCAvQ3JlYXRvciAoTWF0cGxvdGxpYiB2My43LjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcpCi9Qcm9kdWNlciAoTWF0cGxvdGxpYiBwZGYgYmFja2VuZCB2My43LjEpIC9DcmVhdGlvbkRhdGUgKEQ6MjAyMzAzMTQxNjA5MDBaKQo+PgplbmRvYmoKeHJlZgowIDE2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNiAwMDAwMCBuIAowMDAwMDA2MDYyIDAwMDAwIG4gCjAwMDAwMDA1OTYgMDAwMDAgbiAKMDAwMDAwMDYxNyAwMDAwMCBuIAowMDAwMDAwNjc3IDAwMDAwIG4gCjAwMDAwMDA2OTggMDAwMDAgbiAKMDAwMDAwMDcxOSAwMDAwMCBuIAowMDAwMDAwMDY1IDAwMDAwIG4gCjAwMDAwMDAzMzcgMDAwMDAgbiAKMDAwMDAwMDU3NiAwMDAwMCBuIAowMDAwMDAwMjA4IDAwMDAwIG4gCjAwMDAwMDA1NTYgMDAwMDAgbiAKMDAwMDAwMDc1MSAwMDAwMCBuIAowMDAwMDA2MDQxIDAwMDAwIG4gCjAwMDAwMDYxMjIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAxNiAvUm9vdCAxIDAgUiAvSW5mbyAxNSAwIFIgPj4Kc3RhcnR4cmVmCjYyNzMKJSVFT0YK", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:00.640028\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}, {"data": {"application/pdf": "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G9oEqk11UL+xw6LaqB1AgDDTbBuAWjLKvjPE661u3LhqdOHChY3Lwrbylv5HAfZf1oROnTppB97TbkS+8dT7EB4LvX///hy7Iv2AGuHs2vuh2oZBUtcjhbx8NHjw4ErAGkRxrgHV1dU8mOFHdV1dnX+QKYtHns2bN5eDHTt2cIwB9rCcNGkSX1Nr8Mo/K8//YfILE9VENVGtaRHVHEQ1Ua2JEdUcRDVRrYlpvGqoh9QuawLVDh06dDo9lAMHEm8a1f4GOBKFumyQ8PBF0Og+kK+//jpvxquKzB1UdGVg7C5LliyxycodxvfllJWVpRY5aNAgDjPCETImT57MG78qvQWYO3fuHpB/w2pqanhZ5LbbbnsG0C/tskxos9jZctmyZae9o3s0JktUI6KaPktUCyFLVCOimj5LVAshS1Tz8gRQWaiksgBhNrPyLszSpUt5xy6z+vmsfoOuL13wLA4LtxW4HglSLF++PPfouDmzgmxE3s46efIkH/zAyRnPnZ4DNt+8ChUZZZao5kVUy84S1ULIEtW8iGrZWaJaCFmimhdRLTtLVAsh63pRDSXIF1Dy7ZTBdlweYazBMWPG8AaR/9P5OcOCZ+VB3KskrlmimhdRLTsrtg2LMktU8yKqZWfFtmFRZl0vquWdGds9F2VWbBsWZZaoFmZYXLNi27Aos0S1MMPimhXbhkWZJaqFGRbXrNg2LMosUS3MsLhmxbZhUWaJamGGxTUrtg2LMktUCzMsrlmxbViUWaJamGFxzYptw6LMuiqqCYLQpIhqghAJopogRIKoJgiRIKoJQiSIaoIQCaKaIETCfwHkuJnRCmVuZHN0cmVhbQplbmRvYmoKMTQgMCBvYmoKNDI4OAplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZXMgL0tpZHMgWyAxMSAwIFIgXSAvQ291bnQgMSA+PgplbmRvYmoKMTUgMCBvYmoKPDwgL0NyZWF0b3IgKE1hdHBsb3RsaWIgdjMuNy4xLCBodHRwczovL21hdHBsb3RsaWIub3JnKQovUHJvZHVjZXIgKE1hdHBsb3RsaWIgcGRmIGJhY2tlbmQgdjMuNy4xKSAvQ3JlYXRpb25EYXRlIChEOjIwMjMwMzE0MTYwOTAwWikKPj4KZW5kb2JqCnhyZWYKMCAxNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDAwNjA2MCAwMDAwMCBuIAowMDAwMDAwNTk2IDAwMDAwIG4gCjAwMDAwMDA2MTcgMDAwMDAgbiAKMDAwMDAwMDY3NyAwMDAwMCBuIAowMDAwMDAwNjk4IDAwMDAwIG4gCjAwMDAwMDA3MTkgMDAwMDAgbiAKMDAwMDAwMDA2NSAwMDAwMCBuIAowMDAwMDAwMzM3IDAwMDAwIG4gCjAwMDAwMDA1NzYgMDAwMDAgbiAKMDAwMDAwMDIwOCAwMDAwMCBuIAowMDAwMDAwNTU2IDAwMDAwIG4gCjAwMDAwMDA3NTEgMDAwMDAgbiAKMDAwMDAwNjAzOSAwMDAwMCBuIAowMDAwMDA2MTIwIDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgMTYgL1Jvb3QgMSAwIFIgL0luZm8gMTUgMCBSID4+CnN0YXJ0eHJlZgo2MjcxCiUlRU9GCg==", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:00.743094\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["L.seed_everything(42)\n", "for i in range(2):\n", " interpolate(flow_dict[\"vardeq\"][\"model\"], exmp_imgs[2 * i], exmp_imgs[2 * i + 1])"]}, {"cell_type": "code", "execution_count": 31, "id": "3ca1ae47", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:09:00.828856Z", "iopub.status.busy": "2023-03-14T16:09:00.828634Z", "iopub.status.idle": "2023-03-14T16:09:01.038969Z", "shell.execute_reply": "2023-03-14T16:09:01.038355Z"}, "papermill": {"duration": 0.236091, "end_time": "2023-03-14T16:09:01.041318", "exception": false, "start_time": "2023-03-14T16:09:00.805227", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["Global seed set to 42\n"]}, {"data": {"application/pdf": "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3wSkz9j1RAnyi0QM831/FXA2isXHU0xlZWV8Ns2oUaN47OwiKDSLT0V1q2aLxT5myPHjx3k/nvvZM55Z/mGs81KvYy9WGLv1ANi2bZv7rJ13mFSzkGoBYb7vSzWpJtWkWniWVLOQagFZUi3pqnFqbYTxzLI1F0YEoqh27dq1uwFbV1JSEtZ1/mEmiz4HsuP7H4NGyOIsKdXV1V8F5aA0/YzQXbt25ZcVGMbK5uB+586d/JVP6JwxY0bEIFtYxE/xaTT19fVXws7GFyMrPyLu9IsSJtUapFpoWMRPSTWvMKnWINVCwyJ+Sqp5hUVRbQ/giZRU+llyEydOfAFEzzQKO3nyZGn2j+UXQYQgW5jJojyLlh1tNK7WBXMjqiSpWVKNSLXgrMSWf5xZUo1IteCsxJZ/nFlSjUi14KzEln+cWa9Y1TjbtXWYgmdqevTowfuromcahWFQbzubEdFpW5jJohy/z58/n57NmTPH+6ajYmUVjFQrXpZUI1ItOCux5R9nllQjUi04K7HlH2fWK1a1YmUmdsvFmZXYhsWZJdWKGZbUrMQ2LM4sqVbMsKRmJbZhcWZJtWKGJTUrsQ2LM0uqFTMsqVmJbVicWVKtmGFJzUpsw+LMkmrFDEtqVmIbFmeWVCtmWFKzEtuwOLNuiGpCiEZFqgkRC1JNiFiQakLEglQTIhakmhCxINWEiIX/AVsQdvEKZW5kc3RyZWFtCmVuZG9iagoxNCAwIG9iago0MjA2CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9QYWdlcyAvS2lkcyBbIDExIDAgUiBdIC9Db3VudCAxID4+CmVuZG9iagoxNSAwIG9iago8PCAvQ3JlYXRvciAoTWF0cGxvdGxpYiB2My43LjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcpCi9Qcm9kdWNlciAoTWF0cGxvdGxpYiBwZGYgYmFja2VuZCB2My43LjEpIC9DcmVhdGlvbkRhdGUgKEQ6MjAyMzAzMTQxNjA5MDBaKQo+PgplbmRvYmoKeHJlZgowIDE2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNiAwMDAwMCBuIAowMDAwMDA1OTY5IDAwMDAwIG4gCjAwMDAwMDA1OTYgMDAwMDAgbiAKMDAwMDAwMDYxNyAwMDAwMCBuIAowMDAwMDAwNjc3IDAwMDAwIG4gCjAwMDAwMDA2OTggMDAwMDAgbiAKMDAwMDAwMDcxOSAwMDAwMCBuIAowMDAwMDAwMDY1IDAwMDAwIG4gCjAwMDAwMDAzMzcgMDAwMDAgbiAKMDAwMDAwMDU3NiAwMDAwMCBuIAowMDAwMDAwMjA4IDAwMDAwIG4gCjAwMDAwMDA1NTYgMDAwMDAgbiAKMDAwMDAwMDc1MSAwMDAwMCBuIAowMDAwMDA1OTQ4IDAwMDAwIG4gCjAwMDAwMDYwMjkgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAxNiAvUm9vdCAxIDAgUiAvSW5mbyAxNSAwIFIgPj4Kc3RhcnR4cmVmCjYxODAKJSVFT0YK", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:00.902316\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}, {"data": {"application/pdf": "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LgEPPvjgad+FuD0uVxlfQ4l74+CS1BLKJmZc+Nul5itqQShqWTJHl6IWJFPUcqKoZckcXYpakExRy4miliVzdClqQbIConb+/PmOgBdwy5YtLt/IP2qclWRc7K0JIQvvehRwGQTHhekKcpGn04Rw5SkLScxdkcoUNQ+KmkcWV5ei5kVRa+2KbfWP0qWoeVHUWrtiW/2jdN0qUWtoaOBIMFZ/h/XbMpx5yND63G0a9hz/FkIW3sVJVWbUoO+bTIrlygNFrXguRc2LotbaFdvqH6VLUfOiqLV2xbb6R+m6VaJ25MiRluF0ttcKZjvzkHHuzp133lkOOF8/hCy8i91dXAUPbcPjoE1deaCoFc+lqHlR1Fq7Ylv9o3Qpal4Utdau2Fb/KF2KmhdFrbUrttU/StetErWjR49yfW8+pvB9lXhOZ54FnD59Oofvue6uWlI8WVxdilpuFLVMV2wLFqVLUcuNopbpim3BonTdKlHL2xnbKxelK7YFi9KlqBVTFldXbAsWpUtRK6Ysrq7YFixKl6JWTFlcXbEtWJQuRa2Ysri6YluwKF2KWjFlcXXFtmBRuhS1Ysri6optwaJ0KWrFlMXVFduCRem6KVETQrQpipoQkaCoCREJipoQkaCoCREJipoQkaCoCREJ/wMaQIH1CmVuZHN0cmVhbQplbmRvYmoKMTQgMCBvYmoKNDE3NAplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvUGFnZXMgL0tpZHMgWyAxMSAwIFIgXSAvQ291bnQgMSA+PgplbmRvYmoKMTUgMCBvYmoKPDwgL0NyZWF0b3IgKE1hdHBsb3RsaWIgdjMuNy4xLCBodHRwczovL21hdHBsb3RsaWIub3JnKQovUHJvZHVjZXIgKE1hdHBsb3RsaWIgcGRmIGJhY2tlbmQgdjMuNy4xKSAvQ3JlYXRpb25EYXRlIChEOjIwMjMwMzE0MTYwOTAxWikKPj4KZW5kb2JqCnhyZWYKMCAxNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDAwNTkzNCAwMDAwMCBuIAowMDAwMDAwNTk2IDAwMDAwIG4gCjAwMDAwMDA2MTcgMDAwMDAgbiAKMDAwMDAwMDY3NyAwMDAwMCBuIAowMDAwMDAwNjk4IDAwMDAwIG4gCjAwMDAwMDA3MTkgMDAwMDAgbiAKMDAwMDAwMDA2NSAwMDAwMCBuIAowMDAwMDAwMzM3IDAwMDAwIG4gCjAwMDAwMDA1NzYgMDAwMDAgbiAKMDAwMDAwMDIwOCAwMDAwMCBuIAowMDAwMDAwNTU2IDAwMDAwIG4gCjAwMDAwMDA3NTEgMDAwMDAgbiAKMDAwMDAwNTkxMyAwMDAwMCBuIAowMDAwMDA1OTk0IDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgMTYgL1Jvb3QgMSAwIFIgL0luZm8gMTUgMCBSID4+CnN0YXJ0eHJlZgo2MTQ1CiUlRU9GCg==", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:01.001884\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["L.seed_everything(42)\n", "for i in range(2):\n", " interpolate(flow_dict[\"multiscale\"][\"model\"], exmp_imgs[2 * i], exmp_imgs[2 * i + 1])"]}, {"cell_type": "markdown", "id": "648f4caa", "metadata": {"papermill": {"duration": 0.020808, "end_time": "2023-03-14T16:09:01.086975", "exception": false, "start_time": "2023-03-14T16:09:01.066167", "status": "completed"}, "tags": []}, "source": ["The interpolations of the multi-scale model result in more realistic digits\n", "(first row $7\\leftrightarrow 8\\leftrightarrow 6$, second row $9\\leftrightarrow 4\\leftrightarrow 6$),\n", "while the variational dequantization model focuses on local patterns that globally do not form a digit.\n", "For the multi-scale model, we actually did not do the \"true\" interpolation between the two images\n", "as we did not consider the variables that were split along the flow (they have been sampled randomly for all samples).\n", "However, as we will see in the next experiment, the early variables do not effect the overall image much."]}, {"cell_type": "markdown", "id": "2628a523", "metadata": {"papermill": {"duration": 0.020664, "end_time": "2023-03-14T16:09:01.128363", "exception": false, "start_time": "2023-03-14T16:09:01.107699", "status": "completed"}, "tags": []}, "source": ["### Visualization of latents in different levels of multi-scale\n", "\n", "In the following we will focus more on the multi-scale flow.\n", "We want to analyse what information is being stored in the variables split at early layers,\n", "and what information for the final variables.\n", "For this, we sample 8 images where each of them share the same final latent variables,\n", "but differ in the other part of the latent variables.\n", "Below we visualize three examples of this:"]}, {"cell_type": "code", "execution_count": 32, "id": "52225998", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:09:01.171113Z", "iopub.status.busy": "2023-03-14T16:09:01.170822Z", "iopub.status.idle": "2023-03-14T16:09:01.406005Z", "shell.execute_reply": "2023-03-14T16:09:01.405490Z"}, "papermill": {"duration": 0.259501, "end_time": "2023-03-14T16:09:01.408520", "exception": false, "start_time": "2023-03-14T16:09:01.149019", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["Global seed set to 44\n"]}, {"data": {"application/pdf": "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", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:01.214433\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}, {"data": {"application/pdf": "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dGxpYi5vcmcpCi9Qcm9kdWNlciAoTWF0cGxvdGxpYiBwZGYgYmFja2VuZCB2My43LjEpIC9DcmVhdGlvbkRhdGUgKEQ6MjAyMzAzMTQxNjA5MDFaKQo+PgplbmRvYmoKeHJlZgowIDE2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNiAwMDAwMCBuIAowMDAwMDA1Mjg1IDAwMDAwIG4gCjAwMDAwMDA2MDcgMDAwMDAgbiAKMDAwMDAwMDYyOCAwMDAwMCBuIAowMDAwMDAwNjg4IDAwMDAwIG4gCjAwMDAwMDA3MDkgMDAwMDAgbiAKMDAwMDAwMDczMCAwMDAwMCBuIAowMDAwMDAwMDY1IDAwMDAwIG4gCjAwMDAwMDAzNDQgMDAwMDAgbiAKMDAwMDAwMDU4NyAwMDAwMCBuIAowMDAwMDAwMjA4IDAwMDAwIG4gCjAwMDAwMDA1NjcgMDAwMDAgbiAKMDAwMDAwMDc2MiAwMDAwMCBuIAowMDAwMDA1MjY0IDAwMDAwIG4gCjAwMDAwMDUzNDUgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAxNiAvUm9vdCAxIDAgUiAvSW5mbyAxNSAwIFIgPj4Kc3RhcnR4cmVmCjU0OTYKJSVFT0YK", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:01.290435\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}, {"data": {"application/pdf": "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OWZBOVp7Y/uUY6hPOWbhXMiRZeRGwe0b59Bz0xO6udwsjjeWj/sieoX0fWVlZcZ2KCn62Ibb1LgnCuvT9/Xv3z96D/0kPk7I2Qg8n/9IsrS0NMvM3dw+5RhAOSrHJL6zkuO2bdtmAX/PJ+P/87uA1SnilvNe4Eu8/iOnlCxatKgF7o+oubmgsAn6+JystrbW7hRxfKcBV1MHfKzeSZMmxfIpRxPlqBwT+JSjcgz47HPkPIuRI0eaQnzhguDVwE7aEKOcfNHL2LFjC5sXEu2N/tXN9+1IycdlxkOHDg3UKR9F5t68Mk/f50HAx4WAWZbuRfqUo49yVI4JfcpROQZ89jl+CxQ254ILLuBLCq2dhjf6QG4qVdRsT/vC3r17812MLePj4rUOHToYuo+D49YTLOP66urq/DmWHtzs5BmQxKccfZRjEm/0gcoxjk85+pwrOW4HnTt3Zif1k2A6CN9pKdQbfSDfglxeXk4fF5PNBJEvC87HxxXk3jxZTiCdNWsWf9JyPuTYBzBA1mdlZSWHBZL6lKOPckzijT5QOcbxpfHe+SRe+dL1KUc3fMrRDZ9ydMOnHN3wKUc3fMrRDZ9ydMOnHN3wKUc3fMrRDZ9ydMPn5yje3yhHN1CObqAc3UA5uoFydAPl6Ab/BV56Qy4KZW5kc3RyZWFtCmVuZG9iagoxNCAwIG9iago0MTY4CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9QYWdlcyAvS2lkcyBbIDExIDAgUiBdIC9Db3VudCAxID4+CmVuZG9iagoxNSAwIG9iago8PCAvQ3JlYXRvciAoTWF0cGxvdGxpYiB2My43LjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcpCi9Qcm9kdWNlciAoTWF0cGxvdGxpYiBwZGYgYmFja2VuZCB2My43LjEpIC9DcmVhdGlvbkRhdGUgKEQ6MjAyMzAzMTQxNjA5MDFaKQo+PgplbmRvYmoKeHJlZgowIDE2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNiAwMDAwMCBuIAowMDAwMDA1OTMzIDAwMDAwIG4gCjAwMDAwMDA2MDcgMDAwMDAgbiAKMDAwMDAwMDYyOCAwMDAwMCBuIAowMDAwMDAwNjg4IDAwMDAwIG4gCjAwMDAwMDA3MDkgMDAwMDAgbiAKMDAwMDAwMDczMCAwMDAwMCBuIAowMDAwMDAwMDY1IDAwMDAwIG4gCjAwMDAwMDAzNDQgMDAwMDAgbiAKMDAwMDAwMDU4NyAwMDAwMCBuIAowMDAwMDAwMjA4IDAwMDAwIG4gCjAwMDAwMDA1NjcgMDAwMDAgbiAKMDAwMDAwMDc2MiAwMDAwMCBuIAowMDAwMDA1OTEyIDAwMDAwIG4gCjAwMDAwMDU5OTMgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAxNiAvUm9vdCAxIDAgUiAvSW5mbyAxNSAwIFIgPj4Kc3RhcnR4cmVmCjYxNDQKJSVFT0YK", "image/svg+xml": ["\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:01.368132\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["L.seed_everything(44)\n", "for _ in range(3):\n", " z_init = flow_dict[\"multiscale\"][\"model\"].prior.sample(sample_shape=[1, 8, 7, 7])\n", " z_init = z_init.expand(8, -1, -1, -1)\n", " samples = flow_dict[\"multiscale\"][\"model\"].sample(img_shape=z_init.shape, z_init=z_init)\n", " show_imgs(samples.cpu())"]}, {"cell_type": "markdown", "id": "994633e5", "metadata": {"papermill": {"duration": 0.021725, "end_time": "2023-03-14T16:09:01.456409", "exception": false, "start_time": "2023-03-14T16:09:01.434684", "status": "completed"}, "tags": []}, "source": ["We see that the early split variables indeed have a smaller effect on the image.\n", "Still, small differences can be spot when we look carefully at the borders of the digits.\n", "For instance, the hole at the top of the 8 changes for different samples although all of them represent the same coarse structure.\n", "This shows that the flow indeed learns to separate the higher-level\n", "information in the final variables, while the early split ones contain\n", "local noise patterns."]}, {"cell_type": "markdown", "id": "5df5dcc5", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.021783, "end_time": "2023-03-14T16:09:01.499950", "exception": false, "start_time": "2023-03-14T16:09:01.478167", "status": "completed"}, "tags": []}, "source": ["### Visualizing Dequantization\n", "\n", "As a final part of this notebook, we will look at the effect of variational dequantization.\n", "We have motivated variational dequantization by the issue of sharp edges/boarders being difficult to model,\n", "and a flow would rather prefer smooth, prior-like distributions.\n", "To check how what noise distribution $q(u|x)$ the flows in the\n", "variational dequantization module have learned, we can plot a histogram\n", "of output values from the dequantization and variational dequantization\n", "module."]}, {"cell_type": "code", "execution_count": 33, "id": "c062358b", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:09:01.545124Z", "iopub.status.busy": "2023-03-14T16:09:01.544837Z", "iopub.status.idle": "2023-03-14T16:09:01.574131Z", "shell.execute_reply": "2023-03-14T16:09:01.573585Z"}, "papermill": {"duration": 0.054855, "end_time": "2023-03-14T16:09:01.576533", "exception": false, "start_time": "2023-03-14T16:09:01.521678", "status": "completed"}, "tags": []}, "outputs": [], "source": ["def visualize_dequant_distribution(model: ImageFlow, imgs: Tensor, title: str = None):\n", " \"\"\"\n", " Args:\n", " model: The flow of which we want to visualize the dequantization distribution\n", " imgs: Example training images of which we want to visualize the dequantization distribution\n", " \"\"\"\n", " imgs = imgs.to(device)\n", " ldj = torch.zeros(imgs.shape[0], dtype=torch.float32).to(device)\n", " with torch.no_grad():\n", " dequant_vals = []\n", " for _ in tqdm(range(8), leave=False):\n", " d, _ = model.flows[0](imgs, ldj, reverse=False)\n", " dequant_vals.append(d)\n", " dequant_vals = torch.cat(dequant_vals, dim=0)\n", " dequant_vals = dequant_vals.view(-1).cpu().numpy()\n", " sns.set()\n", " plt.figure(figsize=(10, 3))\n", " plt.hist(dequant_vals, bins=256, color=to_rgb(\"C0\") + (0.5,), edgecolor=\"C0\", density=True)\n", " if title is not None:\n", " plt.title(title)\n", " plt.show()\n", " plt.close()\n", "\n", "\n", "sample_imgs, _ = next(iter(train_loader))"]}, {"cell_type": "code", "execution_count": 34, "id": "e66ef8de", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:09:01.626826Z", "iopub.status.busy": "2023-03-14T16:09:01.626504Z", "iopub.status.idle": "2023-03-14T16:09:02.283549Z", "shell.execute_reply": "2023-03-14T16:09:02.282977Z"}, "papermill": {"duration": 0.684094, "end_time": "2023-03-14T16:09:02.288395", "exception": false, "start_time": "2023-03-14T16:09:01.604301", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/vnd.jupyter.widget-view+json": {"model_id": "bbe213511b3245368a116d011cf7a97d", "version_major": 2, "version_minor": 0}, "text/plain": [" 0%| | 0/8 [00:00\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:01.959626\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["visualize_dequant_distribution(flow_dict[\"simple\"][\"model\"], sample_imgs, title=\"Dequantization\")"]}, {"cell_type": "code", "execution_count": 35, "id": "50826bcf", "metadata": {"execution": {"iopub.execute_input": "2023-03-14T16:09:02.341693Z", "iopub.status.busy": "2023-03-14T16:09:02.341310Z", "iopub.status.idle": "2023-03-14T16:09:03.127501Z", "shell.execute_reply": "2023-03-14T16:09:03.126890Z"}, "papermill": {"duration": 0.815664, "end_time": "2023-03-14T16:09:03.131581", "exception": false, "start_time": "2023-03-14T16:09:02.315917", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/vnd.jupyter.widget-view+json": {"model_id": "b2b8c9cb3fdd4e77bf734fc7a847d4ff", "version_major": 2, "version_minor": 0}, "text/plain": [" 0%| | 0/8 [00:00\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2023-03-14T16:09:02.796830\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.7.1, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n"], "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["visualize_dequant_distribution(flow_dict[\"vardeq\"][\"model\"], sample_imgs, title=\"Variational dequantization\")"]}, {"cell_type": "markdown", "id": "1c94ee1f", "metadata": {"papermill": {"duration": 0.026779, "end_time": "2023-03-14T16:09:03.188381", "exception": false, "start_time": "2023-03-14T16:09:03.161602", "status": "completed"}, "tags": []}, "source": ["The dequantization distribution in the first plot shows that the MNIST images have a strong bias towards 0 (black),\n", "and the distribution of them have a sharp border as mentioned before.\n", "The variational dequantization module has indeed learned a much smoother distribution with a Gaussian-like curve which can be modeled much better.\n", "For the other values, we would need to visualize the distribution $q(u|x)$ on a deeper level, depending on $x$.\n", "However, as all $u$'s interact and depend on each other, we would need\n", "to visualize a distribution in 784 dimensions, which is not that\n", "intuitive anymore."]}, {"cell_type": "markdown", "id": "ae3bae45", "metadata": {"papermill": {"duration": 0.026724, "end_time": "2023-03-14T16:09:03.241886", "exception": false, "start_time": "2023-03-14T16:09:03.215162", "status": "completed"}, "tags": []}, "source": ["## Conclusion\n", "\n", "In conclusion, we have seen how to implement our own normalizing flow, and what difficulties arise if we want to apply them on images.\n", "Dequantization is a crucial step in mapping the discrete images into continuous space to prevent underisable delta-peak solutions.\n", "While dequantization creates hypercubes with hard border, variational dequantization allows us to fit a flow much better on the data.\n", "This allows us to obtain a lower bits per dimension score, while not affecting the sampling speed.\n", "The most common flow element, the coupling layer, is simple to implement, and yet effective.\n", "Furthermore, multi-scale architectures help to capture the global image context while allowing us to efficiently scale up the flow.\n", "Normalizing flows are an interesting alternative to VAEs as they allow an exact likelihood estimate in continuous space,\n", "and we have the guarantee that every possible input $x$ has a corresponding latent vector $z$.\n", "However, even beyond continuous inputs and images, flows can be applied and allow us to exploit\n", "the data structure in latent space, as e.g. on graphs for the task of molecule generation [6].\n", "Recent advances in [Neural ODEs](https://arxiv.org/pdf/1806.07366.pdf) allow a flow with infinite number of layers,\n", "called Continuous Normalizing Flows, whose potential is yet to fully explore.\n", "Overall, normalizing flows are an exciting research area which will continue over the next couple of years."]}, {"cell_type": "markdown", "id": "ab8843c8", "metadata": {"papermill": {"duration": 0.026911, "end_time": "2023-03-14T16:09:03.295703", "exception": false, "start_time": "2023-03-14T16:09:03.268792", "status": "completed"}, "tags": []}, "source": ["## References\n", "\n", "[1] Dinh, L., Sohl-Dickstein, J., and Bengio, S. (2017).\n", "\u201cDensity estimation using Real NVP,\u201d In: 5th International Conference on Learning Representations, ICLR 2017.\n", "[Link](https://arxiv.org/abs/1605.08803)\n", "\n", "[2] Kingma, D. P., and Dhariwal, P. (2018).\n", "\u201cGlow: Generative Flow with Invertible 1x1 Convolutions,\u201d In: Advances in Neural Information Processing Systems, vol.\n", "31, pp.\n", "10215--10224.\n", "[Link](http://papers.nips.cc/paper/8224-glow-generative-flow-with-invertible-1x1-convolutions.pdf)\n", "\n", "[3] Ho, J., Chen, X., Srinivas, A., Duan, Y., and Abbeel, P. (2019).\n", "\u201cFlow++: Improving Flow-Based Generative Models with Variational Dequantization and Architecture Design,\u201d\n", "in Proceedings of the 36th International Conference on Machine Learning, vol.\n", "97, pp.\n", "2722\u20132730.\n", "[Link](https://arxiv.org/abs/1902.00275)\n", "\n", "[4] Durkan, C., Bekasov, A., Murray, I., and Papamakarios, G. (2019).\n", "\u201cNeural Spline Flows,\u201d In: Advances in Neural Information Processing Systems, pp.\n", "7509\u20137520.\n", "[Link](http://papers.neurips.cc/paper/8969-neural-spline-flows.pdf)\n", "\n", "[5] Hoogeboom, E., Cohen, T. S., and Tomczak, J. M. (2020).\n", "\u201cLearning Discrete Distributions by Dequantization,\u201d arXiv preprint arXiv2001.11235v1.\n", "[Link](https://arxiv.org/abs/2001.11235)\n", "\n", "[6] Lippe, P., and Gavves, E. (2021).\n", "\u201cCategorical Normalizing Flows via Continuous Transformations,\u201d\n", "In: International Conference on Learning Representations, ICLR 2021.\n", "[Link](https://openreview.net/pdf?id=-GLNZeVDuik)"]}, {"cell_type": "markdown", "id": "24215753", "metadata": {"papermill": {"duration": 0.026354, "end_time": "2023-03-14T16:09:03.348421", "exception": false, "start_time": "2023-03-14T16:09:03.322067", "status": "completed"}, "tags": []}, "source": ["## Congratulations - Time to Join the Community!\n", "\n", "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the Lightning\n", "movement, you can do so in the following ways!\n", "\n", "### Star [Lightning](https://github.com/Lightning-AI/lightning) on GitHub\n", "The easiest way to help our community is just by starring the GitHub repos! This helps raise awareness of the cool\n", "tools we're building.\n", "\n", "### Join our [Slack](https://www.pytorchlightning.ai/community)!\n", "The best way to keep up to date on the latest advancements is to join our community! Make sure to introduce yourself\n", "and share your interests in `#general` channel\n", "\n", "\n", "### Contributions !\n", "The best way to contribute to our community is to become a code contributor! At any time you can go to\n", "[Lightning](https://github.com/Lightning-AI/lightning) or [Bolt](https://github.com/Lightning-AI/lightning-bolts)\n", "GitHub Issues page and filter for \"good first issue\".\n", "\n", "* [Lightning good first issue](https://github.com/Lightning-AI/lightning/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n", "* [Bolt good first issue](https://github.com/Lightning-AI/lightning-bolts/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n", "* You can also contribute your own notebooks with useful examples !\n", "\n", "### Great thanks from the entire Pytorch Lightning Team for your interest !\n", "\n", "[![Pytorch Lightning](data:image/png;base64,NDA0OiBOb3QgRm91bmQ=){height=\"60px\" width=\"240px\"}](https://pytorchlightning.ai)"]}, {"cell_type": "raw", "metadata": {"raw_mimetype": "text/restructuredtext"}, "source": [".. customcarditem::\n", " :header: Tutorial 9: Normalizing Flows for Image Modeling\n", " :card_description: In this tutorial, we will take a closer look at complex, deep normalizing flows. The most popular, current application of deep normalizing flows is to model datasets of...\n", " :tags: Image,GPU/TPU,UvA-DL-Course\n", " :image: _static/images/course_UvA-DL/09-normalizing-flows.jpg"]}], "metadata": {"jupytext": {"cell_metadata_filter": "id,colab_type,colab,-all", "formats": "ipynb,py:percent", "main_language": "python"}, "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.9.16"}, "papermill": {"default_parameters": {}, "duration": 23.837617, "end_time": "2023-03-14T16:09:04.999019", "environment_variables": {}, "exception": null, "input_path": "course_UvA-DL/09-normalizing-flows/NF_image_modeling.ipynb", "output_path": ".notebooks/course_UvA-DL/09-normalizing-flows.ipynb", "parameters": {}, "start_time": "2023-03-14T16:08:41.161402", "version": "2.4.0"}, "widgets": {"application/vnd.jupyter.widget-state+json": {"state": {"022d5e4feba64ae0928ed7f3872066d4": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "03403854507e4c1d82b2987d56a49a06": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_10dd727b74354aedafd5edc7db9549c8", "placeholder": "\u200b", "style": "IPY_MODEL_72e2bef6f95849f3b2a0157e2ae7d38f", "tabbable": null, "tooltip": null, "value": " 4542/4542 [00:00<00:00, 302461.36it/s]"}}, "04427c133ec74f93997b1bb09c212b93": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "07c5caa1cdc1422c953a73791e4deb9e": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "0aeadef176b2496588e4f17a7b736316": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "FloatProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_93e00f14a44948dcbd5b7b278de95bf1", "max": 1648877.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_35c8abf4b2d44eb1a9e990d070993da4", "tabbable": null, "tooltip": null, "value": 1648877.0}}, "0dfc77c724fe4dda8fa5ed6733af68d9": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_bb1e7ecd74f646189cde10378bfed99a", "placeholder": "\u200b", "style": "IPY_MODEL_758c5cc85a124fd6b1a1e5fc08e4578b", "tabbable": null, "tooltip": null, "value": " 0/8 [00:00<?, ?it/s]"}}, "0eb9bbfb6b8b423e90e7466594745546": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "10dd727b74354aedafd5edc7db9549c8": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "16f7dfe27ae0431f882ae8a7521045b1": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "1995f3296f964c10b7b2c669529f7ae2": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "1d86d0fabf6a402bb5546127da7d9bfd": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "1db7ae52a4e14296ad74930df9a97e79": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": ""}}, "21b86501888548e285936fadbc245102": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_c2ebe72c3bd64974b4786470efc97363", "placeholder": "\u200b", "style": "IPY_MODEL_1995f3296f964c10b7b2c669529f7ae2", "tabbable": null, "tooltip": null, "value": " 1648877/1648877 [00:00<00:00, 15388647.04it/s]"}}, "25676a4efd8540fb93d4cf022d30d53f": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_ced0fd121fc2474ba4c1abb075e13f5d", "placeholder": "\u200b", "style": "IPY_MODEL_e69479b2f0cf41f2b1b48ebb2ebf58d4", "tabbable": null, "tooltip": null, "value": " 0%"}}, "25d20e49e81241cebfe05a6a212c597c": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": ""}}, "29068e73798d4582a1e52fb849969cf1": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "29f6933ebb224f55bdab78facfbd0916": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "2c5126982c5e4f6698e08f10d0afc360": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "FloatProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_758427a471744b47ab6192598eefc69b", "max": 8.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_1db7ae52a4e14296ad74930df9a97e79", "tabbable": null, "tooltip": null, "value": 8.0}}, "312e269520644f68abf6c03135cf0e0d": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": ""}}, "339023c700c64174b9a147df03787e07": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "35c8abf4b2d44eb1a9e990d070993da4": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": ""}}, "411e2bdd0d104a759cf2219457a9ea10": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": "hidden", "width": null}}, "558441ee629d4bd9a4fdc90089a3586c": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "60985b1c703d4f8aa3aba175811d2a69": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_8a2bd283700345c0a750d978690229cc", "IPY_MODEL_0aeadef176b2496588e4f17a7b736316", "IPY_MODEL_21b86501888548e285936fadbc245102"], "layout": "IPY_MODEL_04427c133ec74f93997b1bb09c212b93", "tabbable": null, "tooltip": null}}, "6224fdd5ab06423482c0205dc09216d1": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_d97bd4b5fe8a49499d119431d07cf0fb", "placeholder": "\u200b", "style": "IPY_MODEL_a0812f0a0f8e40a0991db82254c34e4f", "tabbable": null, "tooltip": null, "value": " 0%"}}, "66fc512f4207461b9e493495d88854e7": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "67a200eee455445bad5167f0917cb600": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "FloatProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_07c5caa1cdc1422c953a73791e4deb9e", "max": 4542.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_25d20e49e81241cebfe05a6a212c597c", "tabbable": null, "tooltip": null, "value": 4542.0}}, "6e93eead70d64710b21580c9dfdcab47": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_c496aa960e8f441a96ebcfb22e62e988", "IPY_MODEL_fa7f221d159f44a399abb85eb67a0201", "IPY_MODEL_e249257f48ab4642814161e5cbe3a3c4"], "layout": "IPY_MODEL_339023c700c64174b9a147df03787e07", "tabbable": null, "tooltip": null}}, "6ef3a3aa22d64d32972473557f20dc75": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": "hidden", "width": null}}, "70b1f09cd80c4b6d954c95765acf99ac": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "72e2bef6f95849f3b2a0157e2ae7d38f": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "758427a471744b47ab6192598eefc69b": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "758c5cc85a124fd6b1a1e5fc08e4578b": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "85c1da41f2e24252b1bfd646e70cdce8": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_c73775d8b0f64318b72d97215a38fdd9", "IPY_MODEL_67a200eee455445bad5167f0917cb600", "IPY_MODEL_03403854507e4c1d82b2987d56a49a06"], "layout": "IPY_MODEL_d5feb3c4282f42c4950e191fc88be2a9", "tabbable": null, "tooltip": null}}, "8a2bd283700345c0a750d978690229cc": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_ab54194ee2f84f5e83f08a888c5a305f", "placeholder": "\u200b", "style": "IPY_MODEL_ff9e6a2733e34e72bfb2541bdf073901", "tabbable": null, "tooltip": null, "value": "100%"}}, "8e868462f756444d9b1a566c8f77d457": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_d63d18e016b24e3786cada711468334a", "IPY_MODEL_a5e6be0f0d264bd68359c69613627269", "IPY_MODEL_ed5753a1b5e24a52b3de7d67a56394be"], "layout": "IPY_MODEL_1d86d0fabf6a402bb5546127da7d9bfd", "tabbable": null, "tooltip": null}}, "93b1209a50b74dabbb125bc942d22e42": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "93e00f14a44948dcbd5b7b278de95bf1": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "a0812f0a0f8e40a0991db82254c34e4f": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "a50cba50ade742a4b7490036e1e11dc5": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "a5e6be0f0d264bd68359c69613627269": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "FloatProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_29f6933ebb224f55bdab78facfbd0916", "max": 9912422.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_d6df66553ca0434198434c840620964a", "tabbable": null, "tooltip": null, "value": 9912422.0}}, "a9b352eea54247f68d5c4fb54771ffff": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_a50cba50ade742a4b7490036e1e11dc5", "placeholder": "\u200b", "style": "IPY_MODEL_cf866df37d1d4998924e0ec0647dc3bb", "tabbable": null, "tooltip": null, "value": " 0/8 [00:00<?, ?it/s]"}}, "ab54194ee2f84f5e83f08a888c5a305f": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "b2b8c9cb3fdd4e77bf734fc7a847d4ff": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_6224fdd5ab06423482c0205dc09216d1", "IPY_MODEL_2c5126982c5e4f6698e08f10d0afc360", "IPY_MODEL_0dfc77c724fe4dda8fa5ed6733af68d9"], "layout": "IPY_MODEL_411e2bdd0d104a759cf2219457a9ea10", "tabbable": null, "tooltip": null}}, "b86389928edd42a6a9e52ef9cd86f311": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "bb1e7ecd74f646189cde10378bfed99a": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "bbe213511b3245368a116d011cf7a97d": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_25676a4efd8540fb93d4cf022d30d53f", "IPY_MODEL_ed5fb11f3a9e47b69aad48f8bf1f7461", "IPY_MODEL_a9b352eea54247f68d5c4fb54771ffff"], "layout": "IPY_MODEL_6ef3a3aa22d64d32972473557f20dc75", "tabbable": null, "tooltip": null}}, "c2ebe72c3bd64974b4786470efc97363": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "c496aa960e8f441a96ebcfb22e62e988": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_0eb9bbfb6b8b423e90e7466594745546", "placeholder": "\u200b", "style": "IPY_MODEL_b86389928edd42a6a9e52ef9cd86f311", "tabbable": null, "tooltip": null, "value": "100%"}}, "c73775d8b0f64318b72d97215a38fdd9": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_ebe1de3fe436417e9648098be8d9b038", "placeholder": "\u200b", "style": "IPY_MODEL_558441ee629d4bd9a4fdc90089a3586c", "tabbable": null, "tooltip": null, "value": "100%"}}, "ced0fd121fc2474ba4c1abb075e13f5d": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "cf866df37d1d4998924e0ec0647dc3bb": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "d1b544192fff4a4da583c624d12890b3": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "d5feb3c4282f42c4950e191fc88be2a9": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "d63d18e016b24e3786cada711468334a": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_e21ced0da6c14114927d42a13bb051a8", "placeholder": "\u200b", "style": "IPY_MODEL_93b1209a50b74dabbb125bc942d22e42", "tabbable": null, "tooltip": null, "value": "100%"}}, "d6df66553ca0434198434c840620964a": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": ""}}, "d97bd4b5fe8a49499d119431d07cf0fb": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "e21ced0da6c14114927d42a13bb051a8": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "e249257f48ab4642814161e5cbe3a3c4": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_70b1f09cd80c4b6d954c95765acf99ac", "placeholder": "\u200b", "style": "IPY_MODEL_16f7dfe27ae0431f882ae8a7521045b1", "tabbable": null, "tooltip": null, "value": " 28881/28881 [00:00<00:00, 1838816.19it/s]"}}, "e69479b2f0cf41f2b1b48ebb2ebf58d4": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "ebe1de3fe436417e9648098be8d9b038": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "ed5753a1b5e24a52b3de7d67a56394be": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_022d5e4feba64ae0928ed7f3872066d4", "placeholder": "\u200b", "style": "IPY_MODEL_29068e73798d4582a1e52fb849969cf1", "tabbable": null, "tooltip": null, "value": " 9912422/9912422 [00:00<00:00, 26360107.18it/s]"}}, "ed5fb11f3a9e47b69aad48f8bf1f7461": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "FloatProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_d1b544192fff4a4da583c624d12890b3", "max": 8.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_ff4e278d816b407d972984608281faaa", "tabbable": null, "tooltip": null, "value": 8.0}}, "fa7f221d159f44a399abb85eb67a0201": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "FloatProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_66fc512f4207461b9e493495d88854e7", "max": 28881.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_312e269520644f68abf6c03135cf0e0d", "tabbable": null, "tooltip": null, "value": 28881.0}}, "ff4e278d816b407d972984608281faaa": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": ""}}, "ff9e6a2733e34e72bfb2541bdf073901": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}}, "version_major": 2, "version_minor": 0}}}, "nbformat": 4, "nbformat_minor": 5}