Repository: MagNet-DL/magnet Branch: master Commit: bff6748803ac Files: 69 Total size: 502.4 KB Directory structure: gitextract_kpew33sp/ ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── Tutorials/ │ └── MNIST-Quickstart/ │ ├── MNIST-Quickstart.ipynb │ └── mnist_quickstart.py ├── arghandle/ │ ├── README.md │ ├── __init__.py │ ├── core.py │ └── handlers.py ├── docs/ │ ├── Makefile │ ├── make.bat │ ├── requirements.txt │ └── source/ │ ├── _static/ │ │ └── css/ │ │ └── magnet-theme.css │ ├── _templates/ │ │ └── footer.html │ ├── conf.py │ ├── data.rst │ ├── debug.rst │ ├── index.rst │ ├── magnet.rst │ ├── nodes.rst │ ├── training.rst │ └── utils.rst ├── environment.yml ├── magnet/ │ ├── __init__.py │ ├── _autograd.py │ ├── data/ │ │ ├── __init__.py │ │ ├── core.py │ │ ├── data.py │ │ ├── dataloader.py │ │ ├── sampler.py │ │ └── transforms.py │ ├── debug.py │ ├── nodes/ │ │ ├── __init__.py │ │ ├── core.py │ │ ├── functional/ │ │ │ ├── __init__.py │ │ │ ├── activations.py │ │ │ ├── functional.py │ │ │ ├── losses.py │ │ │ └── metrics.py │ │ └── nodes.py │ ├── training/ │ │ ├── __init__.py │ │ ├── callbacks.py │ │ ├── history.py │ │ ├── train.py │ │ └── utils.py │ └── utils/ │ ├── __arghandle__/ │ │ ├── __init__.py │ │ └── images.py │ ├── __init__.py │ ├── _node.py │ ├── images.py │ ├── misc.py │ ├── plot.py │ ├── statistical.py │ └── varseq.py ├── readthedocs.yml ├── setup.py └── tests/ ├── data/ │ └── test_dataloader.py ├── nodes/ │ ├── test_core.py │ └── test_nodes.py ├── test_debug.py ├── training/ │ ├── test_callbacks.py │ ├── test_history.py │ └── test_train.py └── utils/ ├── test__node.py ├── test_images.py ├── test_plot.py ├── test_statistical.py └── test_varseq.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Created by https://www.gitignore.io/api/python,pycharm+all,jupyternotebook **/checkpoints/ ### JupyterNotebook ### .ipynb_checkpoints */.ipynb_checkpoints/* # Remove previous ipynb_checkpoints # git rm -r .ipynb_checkpoints/ # ### PyCharm+all ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff: .idea/**/workspace.xml .idea/**/tasks.xml .idea/dictionaries # Sensitive or high-churn files: .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.xml .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml # Gradle: .idea/**/gradle.xml .idea/**/libraries # CMake cmake-build-debug/ # Mongo Explorer plugin: .idea/**/mongoSettings.xml ## File-based project format: *.iws ## Plugin-specific files: # IntelliJ /out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Cursive Clojure plugin .idea/replstate.xml # Ruby plugin and RubyMine /.rakeTasks # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties ### PyCharm+all Patch ### # Ignores the whole idea folder # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 .idea/ ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class /__init__.py # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ test_todo.py # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook test*.ipynb # pyenv .python-version # celery beat schedule file celerybeat-schedule.* # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ # End of https://www.gitignore.io/api/python,pycharm+all,jupyternotebook ================================================ FILE: .travis.yml ================================================ language: python dist: xenial python: - "3.6" install: - python setup.py install - pip install codecov before_script: - export PYTHONPATH=$PYTHONPATH:$(pwd) script: - pytest tests/ --cov=magnet after_success: - codecov ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 Vaisakh Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # MagNet: Deep Learning Projects that Build Themselves
MagNet Logo

[![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/svaisakh/magnet/blob/master/LICENSE) [![Build Status](https://travis-ci.org/MagNet-DL/magnet.svg?branch=master)](https://travis-ci.org/MagNet-DL/magnet) [![Documentation Status](https://readthedocs.org/projects/magnet-dl/badge/?version=latest)](https://magnet-dl.readthedocs.io/en/latest/?badge=latest) ![Python Version](https://img.shields.io/badge/python-3.6-blue.svg) [![GitHub Release](https://img.shields.io/badge/release-v0.1.0-ff69b4.svg)](https://github.com/svaisakh/magnet/releases) [![Join the chat at https://gitter.im/MagNet-DL/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/MagNet-DL/Lobby/?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](https://github.com/svaisakh/magnet/pulls) [![codecov](https://codecov.io/gh/MagNet-DL/magnet/branch/master/graph/badge.svg)](https://codecov.io/gh/MagNet-DL/magnet) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/16de4d80b50f40988f6886008a78593b)](https://www.codacy.com/app/svaisakh/magnet?utm_source=github.com&utm_medium=referral&utm_content=MagNet-DL/magnet&utm_campaign=Badge_Grade) [![Project Stats](https://www.openhub.net/p/magnet/widgets/project_thin_badge.gif)](https://www.openhub.net/p/magnet) MagNet is a high-level Deep Learning API, wrapped around PyTorch. It was developed with the aim of reducing boilerplate code and writing Deep Learning architectures with more grace. You should take a look at it if you need something that is: - **Intelligent.** MagNet's ``Node``s are _self-aware_. Intelligent. They attach to each other like magnets (hence the name). This enables you to build complex architectures easily. - **Simple.** MagNet's API enables a simplistic workflow. Get the data. Define the model. Train. Debug. Test. Deploy. - **Extensible.** Written on top of the awesome PyTorch library, MagNet can also mix with lower-level details. - **Ready.** The ``Trainer`` can accommodate **any training logic**, however complex. This means that you can do almost any experiment / research with all the features that MagNet has to offer.
# Getting started: 30 seconds to MagNetize The core idea of MagNet is the ``Node``. Nodes are PyTorch modules that can change their properties dynamically based on the computational graph. This way, they attach to each other... like magnets! Here, we define a simple 3-layer CNN. Note that you only need to specify the bare essentials. No need to specify the strides, paddings, input sizes, or even flatten the output before feeding it to the final layer. ```python model = nn.Sequential(mn.Conv(32), *mn.Conv() * 2, mn.Linear(10, act=None)) summarize(model, x=torch.randn(1, 1, 28, 28)) """ +----------+------------+----------------------+ | Node | Shape | Trainable Parameters | +----------+------------+----------------------+ | input | 1, 28, 28 | 0 | +----------+------------+----------------------+ | Conv | 32, 14, 14 | 320 | +----------+------------+----------------------+ | Conv | 64, 7, 7 | 18,496 | +----------+------------+----------------------+ | Conv | 128, 4, 4 | 73,856 | +----------+------------+----------------------+ | Linear | 10 | 20,490 | +----------+------------+----------------------+ Total Trainable Parameters: 113,162 """ ``` Now, we'll get the dataset in a ``Data`` container. ``Data`` is a class that abstracts away the different sets (training, validation, test) and provides easy access to loaders. ```python data = Data.get('mnist') ``` Next, we'll create a ``Trainer``. MagNet's ``Trainer`` class abstracts away the training process and allows you to add features through ``callbacks``. You can _implement your own training logic_. Here, we'll just use the built-in ``SupervisedTrainer``. ```python trainer = SupervisedTrainer(model) # Tracks the loss, metrics and adds a nice progress-bar monitor_callback = callbacks.Monitor() # Train the model for one epoch trainer.train(data(batch_size=64, shuffle=True), callbacks=[monitor_callback]) ``` See the progress ```python monitor_callback ```
Monitor Plot
For a more thorough introduction, check out: [Quickstart - Training an AI to Recognize Handwritten Digits](Tutorials/MNIST-Quickstart/MNIST-Quickstart.ipynb) # Installation Clone the MagNet repository by running ``git clone https://github.com/svaisakh/magnet.git`` Create the conda environment that has all the needed packages and dependencies. `` cd magnet && conda env update `` Add the directory to the ```$PYTHONPATH``` variable by adding the following line to your ```.bashrc``` ``export PYTHONPATH=$PYTHONPATH:~/magnet`` Point to a directory to store datasets by default. ``export MAGNET_DATAPATH=""`` Update by running ``source ~/.bashrc`` Anytime you use MagNet, activate the conda environment ``conda activate magnet``
# Nodes - Models that build themselves! Nodes are PyTorch modules that are _self-aware_! Nodes can react to what's going on and dynamically change based on the input. You don't have to worry about specifying the dimensionality of the input, reshaping or having to work out whether to use Conv1D, Conv2D or Conv3D. Here's a simple Deep Neural Network with two hidden layers: ```python dnn = nn.Sequential(mn.Linear(50), mn.Linear(10, act=None)) ``` You don't need to specify anything except the bare essentials. ```python # Intelligent reshaping between nodes conv = mn.Conv(32) linear = mn.Linear(10) x = torch.randn(1, 1, 28, 28) y = conv(x) print(y.shape) # Output: torch.Size([1, 32, 14, 14]) z = linear(y) print(z.shape) # Output: torch.Size([1, 10]) # Din't need to flatten input to Linear layer ``` MagNet's Nodes are built just in time, according to the computational graph. ## Witty Features Create multiple copies of the node ```python mn.Linear(10) * 4 ``` Create multiple copies with different hidden sizes ```python mn.Linear() * (50, 30, 10) mn.Conv() * (50, 30, 10) ``` Built-in activation functions and batch normalization ```python model = nn.Sequential(mn.Conv(32), mn.Conv(64, act='tanh', bn=True), mn.Conv(128, act='lrelu'), mn.Conv(10, act=None)) ``` ## Examples DCGAN: ```python conv = lambda *args, **kwargs: mn.Conv(*args, k=5, p='same', act='lrelu', **kwargs) discriminator = nn.Sequential(conv(32), *conv(bn=True) * (64, 128, 256), mn.Linear(act='sigmoid')) conv = lambda *args, p='same', bn=True, **kwargs: mn.Conv(*args, k=5, p=p, bn=bn, **kwargs) generator = nn.Sequential(mn.Linear((256, 7, 7)), *conv(p='double') * 2, conv(32), conv(1, bn=False, act='tanh')) ``` State of the art, 34-layer ResNet: ```python class ResBlock(mn.Node): def __init__(self, c=None, p='same'): super().__init__(c) def build(self, x): # Tell the ResBlock how it should build itself c = self._args['c'] p = 'half' if c is None and self._args['p'] != 'same' else 'same' self.convs = nn.Sequential(mn.Conv(c, p=p), mn.Conv(c, p='same', act=None)) super().build(x) def forward(self, x): res = self.convs(x) # If downsampling, pad using zeros if x.shape[-1] != res.shape[-1]: x = F.avg_pool2d(x, 2, 2, x.shape[2] % 2) x = torch.cat([x, torch.zeros(x.shape[0], res.shape[1] - x.shape[1], x.shape[2], x.shape[3])], dim=1) return F.relu(res + x) res_layer = lambda n, c=None: nn.Sequential(ResBlock(c, p='half'), *[ResBlock(c) for _ in range(n - 1)]) resnet34 = nn.Sequential(mn.Conv(64, k=7), nn.MaxPool2d(3, 2, 1), res_layer(3, 64), res_layer(4), res_layer(6), res_layer(3), nn.AvgPool2d(7), mn.Linear(1000, act=None)).eval() ```
# Painless Training MagNet's helps you train your models simply, effortlessly. ```python # Train a classifier trainer = SupervisedTrainer(model) trainer.train(data(batch_size=16, shuffle=True)) ``` ##### Feature Filled Callbacks Additional bells and whistles can be added using _callbacks_. ```python # This callback monitors the training and logs the losses and metrics. # Also displays a nice progress bar monitor = callbacks.Monitor() # This callback tracks the metrics on a validation set validate = callbacks.Validate(data(batch_size=16, mode='val'), SupervisedTrainer.validate) # This callback saves and loads all models, optimizers, schedulers etc. periodically checkpoint = callbacks.Checkpoint(save_path) # This is some goofy callback defined by you. I don't know what it does exactly i_am_kewl = MyGeniusCallback() # Train again trainer.train(data(batch_size=16, shuffle=True), callbacks=[validate, monitor, checkpoint, i_am_kewl]) ``` You don't need to write training loops, logging or serialization code. ## Bring your own logic MagNet is a general purpose framework. Which means you can **use any training logic** and plug it right into the trainer. ```python class MyTrainer(Trainer): def optimize(self): # Override this method with my own crazy logic generator, discriminator = self.models optimizer_generator, optimizer_discriminator = self.optimizers x = next(self.dataloader) z = torch.randn(x.shape[0], 32) x_fake = generator(z) p_x = discriminator(x) loss_x = some_loss_fn(p_x) loss_x.backward() optimizer_discriminator(loss_x) p_x_fake = discriminator(x_fake) # Some wierd stuff here # ... p_x_delta_2_nice_place = discriminator(generator(x_really_real)) # ... # Some out this world shit here # ... and_that_is_how_you_invest_in_bitcoin = F.cross_entropy(z_strawberry_hat) # ... return massive_blood_loss """ ``` And then, you can use the trainer like always in all it's might and glory. ```python trainer = MyTrainer(models=[generator, discriminator], optimizers=[nn.Adam(generator.parameters()), nn.Adam(discriminator.parameters())]) trainer.train(data(batch_size=64, shuffle=True), epochs=13.8e9, callbacks=callbacks) ```
# Debugging Tools #### Catch breaks in computational graph ```python # Suppose this is the loss function def reconstruction_loss(x_gen, y): return torch.tensor([F.cross_entropy(input_, target) for input_, target in zip(x_gen, y)]).mean() # The check_flow() method can trace any breaks in gradient flow. mdb.check_flow(trainer, data) # Raises RuntimeError with a list of broken parameteres # Aha! The loss function had created a new Tensor # which did not have the gradient history def reconstruction_loss(x_gen, y): return torch.stack([F.cross_entropy(input_, target) for input_, target in zip(x_gen, y)]).mean() mdb.check_flow(trainer, data) # No breaks. No errors. Safe to move on. ``` #### Overfit a small sample If you can't overfit on a small sample, the model probably cannot model the complexity of the data. ```python model = mn.Linear(10) # ... # The overfit() function trains the model on various sample sizes and batch sizes. mdb.overfit(trainer, data, batch_size=64) ```
Failed Overfitting Failed Overfitting
```python # Oops! Looks like there was something wrong. # Loss does not considerable decrease for samples sizes >= 4. # Of course, the activation was 'relu'. model = mn.Linear(10, act=None) # ... mdb.overfit(trainer, data, batch_size=64) ```
Good Overfitting Good Overfitting
#### Watch the model evolve Sometimes, it is helpful to understand exactly how the model evolves over time. When does the model learn to attend, to decode, to summarize, to track, to colorize? The ``Babysitter`` callback constantly monitors the model and logs the mean relative gradients for each parameter. This will tell you how the model is learning as training progresses. ```python # Just add the callback into the mix trainer.train(dataloader, epochs, callbacks=[*my_existing_callbacks, Babysitter()]) ```
# Automatic Acceleration **MagNet's codebase is device-agnostic.** All data, models, tensors created by MagNet are automatically run on the faster hardware. No need to shuttle between ``.to(device)`` and ``.cpu()`` calls. ```python # When run on CPU import magnet as mag # Prints: Running your code on a CPU """ Your code here """ ``` ```python # When run on GPU import magnet as mag # Prints: Accelerating your code on an NVIDIA 1080Ti GPU. """ Same code here """ ```
## Contributors Needed I'm actively looking for contributors who can help take this forward. Lots of Node building, Data Loading, Trainer Watching and Bug Squashing to be done. Join us on Gitter. [![Join the chat at https://gitter.im/MagNet-DL/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/MagNet-DL/Lobby/?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Handcrafted with ❤ by Vaisakh


Created my free logo at LogoMakr.com ================================================ FILE: Tutorials/MNIST-Quickstart/MNIST-Quickstart.ipynb ================================================ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Training an AI to Recognize Handwritten Digits" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Accelerating your code on a shiney new Tesla P100-PCIE-16GB .\n" ] } ], "source": [ "import magnet.nodes as mn\n", "\n", "from magnet.data import Data\n", "from magnet.training import SupervisedTrainer, callbacks\n", "from magnet.utils import summarize" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from mnist_quickstart import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load the MNIST Dataset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "MagNet's Data class is an abstraction over the training sets and uses MagNet's DataLoaders, Sampler and collate functions." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Load the MNIST Dataset using the simple get() method\n", "data = Data.get('mnist')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is what the digits look like" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAi0AAAIuCAYAAABzfTjcAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3XWAlNX3x/G3haJYKIKNooCCYqAiFioWJgZgoCB2gV8QxUABA8VuscFEEQu7FRRb7E6UEMQAFOv3h79zn/PsPjvM7k48z/J5/eP1zuzs3WVm9plzzz1ngX///fdfRERERFJuwXIvQERERCQfumgRERGRTNBFi4iIiGSCLlpEREQkE3TRIiIiIpmwcFU3/PLrb3z0yec0XHYZ6tVbpJRrEhERkfnU3Ll/MuOnmbRs3oyllmwQu63Ki5aPPvmcW+8cXfTFiYiIiFR0yP77sOnGbWJzVV60NGy4DABPjh3DzBk/FndlIiIiIsAyDZdnh107h+sQr8qLlnqL/LclNHPGj0ybOrl4qxMRERGpwK5DPCXiioiISCbookVEREQyQRctIiIikgm6aBEREZFM0EWLiIiIZIIuWkRERCQTdNEiIiIimVBlnRZJv4033jiMjzvuOAAOPvjgMDdixAgArrjiijD35ptvlmh1IiLpctlll4XxCSecAMB7770HwG677RZu+/rrr0u7MMmbIi0iIiKSCamLtCy00EJhvPTSS1d5P4ssLL744mGuRYsWABx77LFh7sILLwRg//33B+D3338Ptw0dOhSAQYMG1XbZJbXBBhsA8OSTT4a5pZZaCoB///03zHXv3h2APfbYI8wtt9xypVhiZmy//fYA3H777QBss8024baPP/64LGsqldNPPx2IP/8XXPC/zzEdOnQA4Pnnny/5uqQ0llxyyTBu0OC/pnS77rprmGvUqBEAF198cZj7448/SrS6wmratCkABx10UJj7559/AFhnnXUAaNmyZbitrkdamjdvDsAiruLs1ltvDcDVV18NRL+f6njggQcA6NatGwBz586t1TqTKNIiIiIimaCLFhEREcmEkm0PrbbaamFcr149ANq3bx/mttxySwCWWSbq6rjPPvtU63t89913AFx++eVhrnPnzgD8+uuvALzzzjvhtqyFvjfddFMARo8eDcS3z2xbyH5OiEJz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X1/R8vTTT6/y63wlQkt8+uyzz4qxxDrPjjzL/OG9994Doh47flvajrdOmzat9AvLk0+gHDlyZOy/UjjWq+7DDz8Mc+uss065lpM332PMjm0fcsgh1XoMf3zb/gbbtqptm0H0WkoDRVpEREQkEwoSaencuXPsv0l85+WHH34YgL/++ivMWbKtdSetq6wvkhV6qjiWwnr00UfDeL/99ivjSqrH90WxhHRfTEryZxHbG264IcxZIUr7hArx9yiZf3z99dcArLfeemVeSfW8/fbbYWxlM1599VUAzj777HCbdYT3x9+tO7cvGeKP2KeZIi0iIiKSCbpoERERkUxY4N+ksnfAN999z/mXXss9I69n2tRshI1ERCpaaqmlABg1alSYsyrD9913X5jr2bMnUDcS/0WyrNEKTdiv++Gc3OcoVltlpdhtirSIiIhIJpS1y7OISLFZH68uXbqEOUvE9ZVDLSFeCbki6aVIi4iIiGSCLlpEREQkE7Q9JCLzBdsmgqg+i6/TIiLpp0iLiIiIZIIuWkRERCQTdNEiIiIimaCLFhEREckEXbSIiIhIJuiiRURERDJBR55FROZzzZs3B+Cxxx4LcwsttBAAq6++elnWJJJEkRYRERHJBEVaRETmQ1dccUUYd+3aFYCGDRuGuYcffrjkaxKZF0VaREREJBN00SIiIiKZoO2h+dzTTz8dxgsssAAA2223XbmWU6V1110XgN122y3MHX744QC89tprALz99tuVvu7SSy8N47lz5xZziSKp1rhxYwDuu+8+ANq1axdu+/fffwF47733wlyvXr1KuDqR/CjSIiIiIpmQukjLIossEsbt27cH4NxzzwVgiy22KMua6qJLLrkEiH7HACNGjCjXchIdeeSRYTxs2DAAGjRoUOl+zZo1A6Bbt26VbrMoDMCzzz5b6CVKDfl/R0sC/f3338PcxhtvDMCSSy4JwIEHHhhue+655wCYNGlSXt9r8uTJADzwwANh7vXXX6/BqrPHjjIDXHjhhQBsttlmle43YMAAIP57mT59epFXVzoWRb7zzjvDXKdOnYAoivvdd9+VfmFSbYq0iIiISCbookVEREQyIXXbQ0svvXQYWzjfwrtNmjQJt9mcVM/QoUMBOOqoowD4888/w20+KTcN7rnnnjAeNGgQkLw9lMvo0aPD2LaPnnjiiQKsTmpj4MCBYdyvX79qfe3OO+9co+9pWyAAH3zwARDfLrDxV199VaPHTyNfd8W2Q5LY1khd3UKtX78+EE8xsPcSez7dcMMNpV+YVJsiLSIiIpIJqYu0JLEIiyIttWfHHC3h+aWXXgq3jRo1qixrqsqMGTPC+KyzzgKihFyAJZZYAoBvvvkGgNVWW63SYyyzzDJhvNNOOwGKtORifWbsk+n+++8fbjv66KMr3X/s2LEA9OzZs1rfZ++9987rfpYMOnHixLzu//HHH4dxixYtgOg5sOGGG4bbWrduDcA555wT5ux71IVIiyXg3nHHHWHOklGN/zfwScp10ezZswH49NNPw9zKK68MQKNGjcqyprTr27dvGNerVw+AddZZJ8z55Hjz0UcfAdCqVauirUuRFhEREcmETERaKn5CmJ9svfXWYXzaaacB0adfH4nIxX9atk+Yn3/+OVD9fIJyufbaa4H4Meg2bdoA8Msvv+T1GFdddVXhF5ZhHTt2BOKfuO25YrllVnSsKr5AWXVY1AuiqMAnn3xS6X72CfmHH36o0feB6Nj0u+++G+aSonJ77LEHEEWPsqx79+5A/Od85JFHgCifLd8j43WJfw/o0KEDEI8ezG+22WabMLa/DTbXuXPncFvS3+Ck94a1114biHLG7Dh5ISnSIiIiIpmgixYRERHJhExsD1kYarHFFivzSkpv+PDhYWyhNwu5+STaXE499dQwXm655YCob88777xTkHWWik+ctJ9rgw02yOtrLZlsfmTHOddbb70wt8kmm1R5/19//RWA22+/PcxZdWF/TNhXsa0O256sOC4G61eVtCX0xx9/hPH1119f1HUU2/jx48PYXhM+qfjEE08E5s9tIfPqq69WmuvSpQsAJ598cpirzXZkGqy44ophbK/XNddcs9L9fIkRO9hgW0FvvPFGuG2jjTbK6/suuOCCsccqBkVaREREJBMyEWkxbdu2DeNXXnmljCspHUtEhOpHnOzTlh1jBfjnn3+q9Rhpc++994axRZoef/xxIB5FSDJkyBAA9ttvvyKtLh0smnbeeeeFuUMPPRSIJ2/bJykrOAhRl985c+YA0XHyrPDRtMsvvxyAgw8+uMr7b7755mGc1CU8C/bcc08g3lPI3it8gcaaRsXqKoso2HPGErEBrrvuurKsqbYsud5HDVddddVqPYZF8n/88ccwt/zyywOw0korhbmb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pFyfnGtUUVjyZVuPvhp3XXHwwQeHsdVf8Ym2l112GRBVks4SRVpEREQkEzIRaREREZH8PPHEE2FslXB9R/MsRliMIi0iIiKSCbpoERERkUzQ9pCIiEgdYo1GARZeuG79mVekRURERDJBFy0iIiKSCbpoERERkUzQRYuIiIhkgi5aREREJBN00SIiIiKZoIsWERERyQRdtIiIiEgm1K2qMyL/b8011wTgvPPOC3OdO3cGYP311w9zH330UWkXJiIiNaZIi4iIiGSCLlpEREQkE7Q9JHVG+/btw/ixxx4DYNq0aWHuqquuAmDKlCmlXZikVvPmzcP42muvBeDAAw8Mcz/88EPJ11ROHTp0CGPrX7PgggtWuv35558v5bJEAkVaREREJBNSE2np3r07ADvuuGOY22CDDQBo0aJFpfu/8sorAOy+++5h7ueffy7mEjNriSWWCOPnnnsOgJVWWgmALbbYItz21VdflXJZBbPrrrsCcO+994Y5+9R82mmnhbnZs2eXdmFSpSWXXDKMGzRoAMRfv6X6t+rUqVMYb7311gAcdthhYc4Suf/666+SrKdcevToAcDxxx8f5v75559K97v44osBGDFiBBBFL6Hu/44kbsCAAQCcc845Ye6CCy4A4JRTTina91WkRURERDJBFy0iIiKSCWXZHlp++eUBuOGGG8KcbfPMnDkzzI0fPx6Iti18ktiWW24JwMsvvxzm1l133aKsN61siwegUaNGlW7/6aefANh2223D3MYbbwzAxx9/DMD06dOLucSiWmuttQAYNWoUEE8O7Nu3L5Ac4pby69+/fxhbmPmkk04Kc5dccklJ1vH6669XmjvzzDPD+M477wTgs88+K8l6Ssm2hCDanvc1jJLY7RdeeCEA999/f7jt66+/LvAKS2v11VcP4xNPPBGAY445JswtvPB/fy7vuuuuMHfAAQeUaHXp4Ld1bSvx33//DXN9+vQB4NNPPwXgxhtvLPgaFGkRERGRTChLpMWOozZt2jTMWQLPsGHDwtyMGTNiX9eyZcswfvXVV4H4kcWBAwcCMHjw4MIuuAxat24NwAknnBDm/CcBiP/sq622WqXHGDp0KBCPQC2wwAIATJo0CYB69eoVaMWlsdhii4WxRereffddALp06RJumx8jLA0bNgSga9euAJx66qnhNh+VM6effjoQrxpcTj7C8cUXXwDwwAMPFPV7NmnSpKiPX27LLLNMGNvBhptvvhmIIt4Qf10Zqxbtjzz795y6omfPngBceumlYc4iBUceeWSYW3XVVYH489T+1tT1ytoWZTr66KPDXOPGjSvdz8pJ+B2QQlOkRURERDKhZJGWHXbYIYw33HBDIMpFgGhfOxd/NWtXxfZpEaIr5roQadluu+0A6NWrV5X3+eOPP8L4tttui30dJB87s/3HW265BcheTsuQIUPCeLPNNgNg7bXXBuCXX34py5rKqV27dmFseSCbbropEN9r9mNjv0v/6dleQ+VgR58higZYCYSk3JNCfK///e9/Oe+33377AemJRuVrr732AuDwww8Pc/a7tMjJvKKRFvX2kZbrr7++oOssNR9Ztrw3i9DbcW6IfnafY7nRRhsB8UjLr7/+WrzFpoi9z8zrdXDUUUcB8MEHHxRtLYq0iIiISCbookVEREQyoWTbQ5bIA9HxQX90rLqs+qnfHrJksqWWWirMZWnL4Kyzzgpjf/zT3HrrrUDUT8eOHfo5S7YDePzxx4F4wp3dz1ePzYJFF10UgIMOOijMWXXf7777rhxLKiv7N/Xh+nXWWQeI/o39cVRLaD344IPDnG19+C0mC5/PnTu3GMsO5lV92V7DgwYNAuL/7naUvzbsuLxtpdUF/ndk7xVJ/HZPLpa0X5OvTSu//Xn22WcD0THdK664IufX2vba1KlTw5wdaKiL/EGZyy+/vMr7WY8qiN6Tiynbz0ARERGZb5Qs0vLss8+GsSXi1qa/iE9CNXYEyxf8sR40WeB7BNWvXx+IF2yyPjpJnWftk6M/5moF52bNmhXmLJrz+++/F2jVpWHFyHyypu8rNL+xyIlFVwCeeOIJIN5PpyI7ygnQsWNHAFZZZZUwZ4/3zjvvFG6xCSwRHKLj2D7B0ey0004A7LPPPmHOF6WsKfu0bEerAdZcc81K97vnnntq/b2KzSIs/siuJdn617kdR7UCYXZE3vP3tyj10ksvXelxs8Z+Vp/Ib9Hma665psqv82UmfE+q+cFDDz0UxkmFW+354cuUzJkzp+jrUqRFREREMkEXLSIiIpIJJdseKvR2hIV133///TDXqlUrIKrbkTU+OXbnnXcG4mE5q3Br/TB82NZqDOy6665hzioK+9bhuUKhaWZJcOPGjQtzb775ZrmWU3ZJYdiaVo/1yeo//vhjjddUHX///XcYW5LfgQceGOZsu9Mce+yxYTxmzBigdjWGVlhhBSB5SygLrA4LREm3SVs3EyZMCGPbDrSeQ0k1V/z2sv2efY+iLPGHP+x9w7bIIKru+tdff1X5GFb/CqLnykUXXVTQdaaV/T2F5DpPV199NQBPPvlkydYEirSIiIhIRpSl91Ah/Pnnn0Duq+Ssefvtt8P4lVdeAeKRFqt2a9WFfSfcpN5Ddlx0Xkf50so6eUN0LHe99dbL62utI7gd/4V4VC7r7DiqP5ZqR4Ht6H+zZs3CbfZp2bp8A0yePBmA/fffP8yV4wjnzz//DMSjaBUjLf7f3XrAzCvSYse3ff8YY8e9s8b+HX3SrfHRbIuw+N5lFflka4vWJEVifQTYKuxm4aj4vvvuG8ZW9dlXDK/Y286z14QvB/Dbb78B8VITdZFF7f17i0Va/PFmn9RcSoq0iIiISCbookVEREQyIbPbQ1YhNamlelabWPnaM0mVfK2exejRo4Hk8N2NN94Y5nxF1CzyFT4//PBDAL788stK97OQuU+QW3bZZYH477Rfv34AXHXVVQVfa6lZkpxPkLPmf9YIzm8FmW7duoVx2qoi+3b2hxxySJX323zzzYH4dmr79u1j/4Wopo+vmp0Pe65BYarvFtIZZ5wBxGs6mXPPPTeMczW2e+mllwB49NFHw5xPUK3ItkUguT5WWvnn0McffwzA+PHjq7x/kyZNwti233wFYNtmz/W7yjJ7X7Qkb//eMnHiRCCeLF+uWl+KtIiIiEgmZDbSYn0RWrRoUem2xx57rMqv83142rRpA0Sf3CCqgGlX5uXiK+Hm45FHHgHiSWLffvttQddUaoceemgYW5Vj/0nPEi2tkqpPuLS+S7467M033wzA559/HuZyPVfSzJJQrbopQNu2bYEoAuc/KVn16WK2jK8tX+l2m222AeLVrc2VV14Z+29V7FNydau4+uR3+9TpI5jlYD3F7N/bRwAWWmihaj2W9X6rCXtuZaEHkVVTBhg4cCAQHeDwrM+VRbAh+jvhK6qff/75RVlnOfmEanuu+4iTGT58OBA/2FAu6X/miYiIiJCRSIvlr/geKX7vuiJ/dfzGG28AsNFGGwHxfht2dNLnwNhRy3IUVPKfmLbaaisgudOqGTt2bBjvvvvuxVtYiVm+hi8OlXS03f5NLVqSlKNx9913h7EdoR4wYECYy2qkxX5H/kimvT78z2zuu+8+IN2RFs/yk/xx7OqyCEtSYax82e+3HJGW1q1bh7FFASxXq5Q9gHy/L4tuprkH0fbbb19pLim/zyIx1113HRAvG2HRKF9sLynPMOt8NHvFFVeM3eZzu2pauLIYFGkRERGRTNBFi4iIiGRCybaH6tevH8bW98PC+xCFYX3FQmPHmn0vhFz8/Xx/HoCbbropjG17xfdb+eqrr/L6HsVw1113hfHee+8N5A5t1ybsnWZJiWAfffRRpTmrcJvvkVar9vnuu+/WYnXpYpWTIb6dUJE/Dju/sBC/vU78dqpV4bUEzTSynkyQXPG6VHxl2SxUwrUjyf5I7qhRo4B44nqjRo2AKLnfb8Xb8V97ntQ1ffr0AaBXr15hruLfE6u8DvD999+XZmF5UKRFREREMqFokRaLrJx11llAPFG0ZcuWeT2GJT5ZoqxPxvRJmsaOTPpE3LR2ArZCcQA9e/YEYJ999glzdtXr12+9Quz+FrGaHyT1xKluEcHvvvuuUMtJJevPU9Ojvlnje8d88803QLzA4J133lnl19oR4jRHWnLp379/0b+HvU9fcMEFlW6ziHS5Cozl8t577wFw1FFHhTmLKPh+S/b8sKPzr7/+erjNknPrEjt4AtHvwx9dt87r1v07TdEVT5EWERERyQRdtIiIiEgmFG17yM7FWzKPr2RqCXG+j4ydA/f3sxCkhfV9Mqa1Gv/iiy/CnPVe8b0y0srXEhg8eHCl2y251Ff9tIqFtj2UlZob1WUJcblq1NSEVVnNam+qeZkzZw4QbQs999xz4ba5c+eWY0k1Zq/rESNGALDmmmuG26x+hO8hZVsChbbjjjsCUX2UtPQisorIhea37u09ebnllgtzU6dOBaLk3DT34bHnjh/79xTrL9S4cWMgOvwA6dz2qimrPfbggw+GuaRK8pdccgkAJ598cmkWVkOKtIiIiEgmFC3SYp9QLJrir2J9d9ZcLNnWej6svPLK4Ta74u/SpUuYy0KEpUOHDkD8OKPZY489wvipp54C4sd/KyYNlvN4djFZEnIhjnQvssgiYWyJeSNHjqz146aF/2RsyXXWH8SOeEP2niuWhO8rdpaDvedYJdhS8lGBir1+rI8WxCMK1eEr3dpj7LnnnpXu56PZu+22G1D+3mw1ZdFWgOOOOw6Ac845B4gn4tYlFlVJiq54PhKTZoq0iIiISCbookVEREQyoWjbQxbanzlzJpB/opxVvwW45557ANh1112BeJJut27dgPTWYamKJSb7Sr3PP/88AA8//HCYs20NC8f6r7GwcRrahBeDJRj/8MMPYe6ggw4C4lseudjvz9+/adOmABxyyCGFWGZZ2XPh8ccfD3O2lWGJdEkNJOU/9r7kn2MVG8Z5VlH4yCOPDHNJTTwL6eyzzw5ja4JZscI3wLPPPgvEt1MtidZv41htF3v/8FteVul29uzZYc5+Zmu2WfHxsuiOO+4IY6tDklSHpi7xTYIr8sn6WTnYoUiLiIiIZELRIi2ffPIJEFWeHD58eLjNjtD56oSW7HXSSSeFOUscmjBhAgBHH310uC3fZN60seOo/lORjX3SqB1vvuyyy8KcHbe0yr/5Rh2yxj79+n45vtKpuf3224HoOGybNm3CbdZS3h9dtORw32sqq+zToU9OtwqfSb8ribPEZN9XxyIKdgTWs+jcCSecEOaKHWl5+umnw9iqZY8ePRqIR1y23nprIF4BeauttqrycZMqJlu0N+mYcF3Qtm1bAJZffvkwZ/+WWTjAURtDhgyp8jb/NyQtx/nnRZEWERERyYSiRVrsKKZd5fXr1y/cZlf6O++8c6Wv88eu+vbtC8Bjjz1WrGWWXFK/IMtNefLJJ8Nc0iclKyr30EMPFWl16eKLhxkfRfCF9yBeNM6OlPu8gKwVWKuoY8eOYWw5PlZQDpTDUhMWxYXouK/PLfOfzCH6xA5RdKIU7HtZNPGII44It+Xb5dxMnjwZgBdffDHMWa5OXepq7PMjLdLve5jVpdIHFbVq1SqMl1hiiUq3Dxo0CIgid1miSIuIiIhkgi5aREREJBOKtj1kzjjjjNh/53fWN8WzZEBfAXPGjBlAfIvEquTOj+z3kLRlVNfZUW079uodfPDBYWzHXKVmrCLqiSeeGObsYID1Syt31VTb3jjzzDPDnB1i8Fvwtj3v+7UNGzYMgM8//xyAcePGFXexZWbb6RBtq/lk/VmzZpV8TaXSrl27MF5yySUr3W7lQwpRdbzUFGkRERGRTCh6pEXibr31ViBe2MmiUP5TnCUkW+dNmb/Ur18/jC0h3R9ztQS6MWPGlHZh8wE7Ol5xnFb2nmL/lf8cf/zxYTxx4kQgHnmqy2688cYwtp51iy++eJjzRSmzRpEWERERyQRdtIiIiEgmaHuoxKzqoO93Udd7X0j19ejRI4yPOeYYAMaPHx/mfAKuiFTme+5YXZJiVzFOo9VXX73cSygoRVpEREQkExRpEUkR67ZrvZMgqup7/fXXhznf8VxEKmvSpEm5lyBFoEiLiIiIZIIuWkRERCQTtD0kkiKvvvoqAKuuumqZVyIikj6KtIiIiEgm6KJFREREMkEXLSIiIpIJumgRERGRTNBFi4iIiGSCLlpEREQkE3TRIiIiIpmgixYRERHJhEwVl7vjjjvCuF27dgDsv//+YW7ChAklX5OIiIiUhiItIiIikgm6aBEREZFMyNT20Oqrrx7GTZs2BWDkyJFhrlWrVgD8+eefJV1XMe2zzz5hvNhiiwHQtm1bAPr06RNue/bZZwG48cYbw9yHH34IwJtvvln0dYqIiBSbIi0iIiKSCZmItFjHW4sweGuttVYYL7zwfz9O1iIt9evXB6BFixZhbsiQIQBsv/32YW7RRReNfd0///wTxttss03svwBffvklAM8880yYO/nkkwH45ZdfAPj7779r/wNISdjzBGCnnXYC4MwzzwxzG2ywAQD//vtvlY/Rq1evMP7pp58q3f7ZZ58B8N5779VusTWw1157hfHxxx8PwLbbbgvAAgssEG7L9fPdf//9Yfzoo48C8MQTTwCw3HLLhds++eQTAH777bfaLlukTlh33XWBKIK/4oorhtt22203AB544IEwN378+EqPMXz4cABmzpxZtHUq0iIiIiKZoIsWERERyYQF/q0i1vrNd99z/qXXcs/I65k2dXKp1xXTunVrACZOnFjpNh8O3nfffYH4tknarL/++gBstdVWYc5C/bvuumvJ1jFo0CAA7rvvvjBXji2BYltttdXC+OWXXwai3zek52e2rUHbvkuy+OKLh/F+++1XlHW8//77QPRasm2UYrJtoREjRoS5JZZYomCP/+mnnwLx39+PP/4IwNy5cyvd/3//+18YJ4XAReqiiy++GIDevXvX+DFsy/m0004D4LrrrqvR4zRaoQn7dT+ck/scxWqrrBS7TZEWERERyYRUJ+JaYm2uT5933nlnGKc5wmIswnL55Zfndf9vvvkmjPNJmvXJU3ZEOoklcE6bNi3MpSXqYJo3bx7Gv//+OxD/feTjmmuuCWP7VP3rr78WYHWF9eSTTwKw8sorl3UdVjbgtddeA+DW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WvnXkq+UXNGsWbOAeFVP629Viq60xWYRJR9RbdCgARB//7DE5JpEFOoiey3Y+4Yvp2D9uF544YVKX+crdVvvu1wVp0vBIvN25Np6kwF07NgRiHq0QRQZOvLII0u1xIJRpEVEREQyQRctIiIikglF2x6y5lOXXnopAF27ds3r63y1V2sLb5UF33nnnRqvZ8SIETX+2pry2z3PPPMMAM2aNavy/j5UZ/U0khJJV1ttNaDwtTTKUVegEHzVTzN69OgyrCQ/1lQtV62eo446KoynTJlS6faff/4ZiIelLQG9b9++AOy0007htupuFWbB4MGD87qfNTscO3ZsmPOh8izy23xWtdhvl1lS8SGHHBLmnn/++RKtLhusKehWW20FxOvWWJXcH3/8sdLX+ffJilv01oizFFq0aBHG9lpYcMH/4hC+mniuwxx77713pTnbUkxrDTRFWkRERCQTihZpsRb3uSIs/pPPRRddBMR7nczreGbaWVIjREcyLTHYVyZNYsml9t9Cs54q06dPD3M33XRTUb5XsVk1Su+NN94ow0ryY8+Bddddt8r7JCUAepYs7T9x+74n1XHLLbeE8Ysvvlijxygliy5ZNHderJ+S/RdgzJgxQFRWoSr2mrAj0laJG8pbObdVq1ZhbBEW31vL3n+zllRfSieffDIAiy22GBDvy2VRS4tqz4tF80aOHFnIJebkK1r70h8QP95s/PuDReAWXrjyJYC9NiZOnFiQdRaaIi0iIiKSCUWLtNjVmvXa+f7778Ntdvz35ptvLta3Tx37VGbFf/yVseU41Ma3334LQLdu3cLchx9+WOX9bZ/T8oayyHrFHH300UDd6EicL19YrTr8EV/7tx82bFiY++ijj2q3sBKwHCb7hFwTvqdXLr6EAMSL7p166qlAvBN7qfh/RzvS7fveKMIyb/aefMIJJwDRvydE+YXzKhFgzwf7m+YjccXWoUOHMPYFVQFOPPHEMN5ss82AeOHFpAiS5TydcsophVxmwSnSIiIiIpmgixYRERHJhKJtD1lfCwvhy3+sFfhzzz0X5qwXSNOmTcOcr25phg8fDiQnaX7xxRcATJgwoVBLTT1LUraQrK8CmWb22vDbo7YN4as515Y/5m9HIK3fCmS3Guz9998PxI+F29gf+03qv1JdX375JRCF3+1IKURbAhWTIEvBl3+wpNys/nuWm1V/th53EFVMTjOfbGtJ5pacvswyy4TbOnXqVOVj+ET0iy++GEh/vzZFWkRERCQTytrleX7mj0P7nhcmC1f65WafIOzY9sCBA8u5nLxZUavDDjsszFkCrPVMytegQYMqPa7xJQV8sam64tZbb600btu2bZirGOX1RQhzdbQ9/fTTw/i+++4DoqieRTQh3lW5nLLenVpqxjrZA+y4445AlIy9wgor5Pzaxx9/HIgn4ZcjobwmFGkRERGRTNBFi4iIiGSCtock8z7++GMgd4+NtLvwwgtj/5Wa8cnYFROzb7zxxoJ+r0I/nkhN2VbRiiuuWOaVFJ8iLSIiIpIJirRIZvXv37/cSxARkRJSpEVEREQyQRctIiIikgm6aBEREZFM0EWLiIiIZIIuWkRERCQTdNEiIiIimaCLFhEREckEXbSIiIhIJuiiRURERDIhUxVxhwwZEsbWPt63ZW/VqhUAv/32W2kXJiIiIkWnSIuIiIhkQqojLQsttBAAZ5xxBgB9+/YNtz322GMATJgwIcytueaaAEycOLFUSxSRlNtpp50AOOWUU8LcE088AcAbb7xRaU5E0kuRFhEREckEXbSIiIhIJqR6e6hbt24ADBw4EIChQ4eG20499dSyrElEsmW33XYDYOuttw5z22yzDQDPP/98mBs3bhwAs2bNKuHqymeXXXYJ44cffhiA77//PswdccQRALz++uthbtq0aSVanZTaggv+F8Owv7dnnnlmuG3AgAFA/G9wuSjSIiIiIpmQukjLpptuGsaXXnopAG+++SYAgwYNKsuaJN3atm0LwGuvvRbm/vnnnyrv7z9BnH322cVbmJSVRRIOOeSQKu/joy9LL700MP9EWjx7vTRp0iTMPfjggwA89NBDYW7vvfcu7cKkqJo2bRrGgwcPBuDAAw8E4u+hW2yxRUnXlYsiLSIiIpIJumgRERGRTEjd9tBRRx0VxssuuywAF110EQB//PFHWdYk6WbbPT6cme/2UKNGjQAYPXo0AC+88EIxlpgZq666KgB9+vQBYPPNNw+32fjll18Oc+3bty/h6uatWbNmYXzHHXcAsMQSS1R5/9tvvz2Mp06dWryFpcAyyywDwNVXXw3AVlttldfX+W1XqVsuvvjiMN5zzz1jt/35559h/Mgjj5RsTfOiSIuIiIhkQmoiLXYEsXv37mHu7rvvBtJxzCpNWrduDcSTo6655ppK91tggQUAePzxx8PcZZddBsCjjz5azCUWjU8cs5/LJw9W13HHHQfAJ598AtT9SEuXLl3CeLPNNgOSoym5fPfdd4VfWIH07t07jJdaaqkq7/f0008DUfIhwF9//VW8haXA+uuvD0SHHVZaaaVwW67IpP8dffDBBwA88MADxVhiTosttlgYW4TU+PdCe99be+21q/X4PrJw2223AfEj4H///Xe1Hi/NmjdvDkTPiSR2zBmS/76UiyItIiIikgmpibRY9MD6DQFMmjSpXMtJjf322y+M9913XyAqluU/efz777+VvtbmdthhhzBnV9annXYaADfffHOBV1xcCy8cPWWt15TEVcxLgeh5ZLfNi+WtWNkBgFGjRhVqiQU3bNgwALp27ZrX/f1rYn5hOYK5cnzm5brrrgOiyIw/Dl1st9xySxj7iGExnHPOOUB07BugV69eAEyfPr2o37tYGjduHMaWo7LGGmtUef+05jIp0iIiIiKZoIsWERERyYTUbA/tuuuuAPzwww9h7qabbirXcsrOqhL6I2nLL788ACNHjgTiCbb16tUD4Pzzzw9zFZPVIAoRrrLKKgVecWn4pMB8HH744WG88cYbA/Fj9XWRlQjwW4vmnnvuCeN777230u1p3gLKZYMNNgCi14hnWxlXXHFFSddUTpZwb4nmSazXTHXY+8fqq69es4XVwqKLLhrGViW9kGUwfGqCJSvvscceYa5du3YAjB07tmDfs5Ss4jPk3hYaP348AJ9++mnR11QTirSIiIhIJpQ10mKJYQAbbbQRADfeeGOY++ijj0q+prTo0aMHEP/keMoppwBw+eWXA/FPGRZpWWeddcLcMcccA8QT7+xT56+//lqEVRdWUhfaXCx5DqJOpZ4dgfWfMG1sxySzzCIs9onQR1UsYvfKK6+UfmFF0qpVqzBed911q7yfJXD+73//K/aSUsOS8HMdZfbsufLiiy+GOevLlNRvqHPnzgDcddddYe7HH3+s2WLzZNFniI4n+2PKteWT/O1IvC/A16FDByC7kZZ59Y2yCIsd+JgyZUrR11QTirSIiIhIJuiiRURERDKhrNtD/fr1C+MVVlgBSHe1zVJacsklK81ZxU4LiVq9FojCwb4XTFI9Bqv06OtvZEE+Ye6kLSEvV8g8qc5NFvh6Fbb9YTVW+vbtG2779ttvS7uwEjji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hmP77Fx55ZXD2Prrrw/AXnvtBcDChQvDuUsvvRSIR6SfffZZAB555JGc5yh39neoppGUJXnuueeAeAR4SRRpERERkUxIdaTF7gR+//33nHMXXXQRUF7bz/xd7v333w/EI0kmaZt3t27dAOjevXsYO+OMM4D43bjdYWbtdWvbti0Ae+65Zxjr27cvEEUWkvz888/heMGCBQWaXfEddNBBAFx99dVhzHK/pk2bBsDIkSPDObvL3nzzzcPYo48+CkS5LWnSpUsXAI4++mggigpBPFenJnzUYbPNNgNg7NixYcy/NlnkPyu22247AMaNGxfG7P1hn6f//e9/wzkrn9C6desw5qNbZu211wbggAMOyNe086Jhw4bh2ApnWlkMiEddKuNfP8uh8pG4H3/8EYAOHTqEMYvklmNui4/s5yPCYnkrL7zwQp2eR5EWERERyQRdtIiIiEgmpHp5qF27dkDy1l07t2jRoqLOqZAee+yxcGxLY2+++WYY22WXXYBou6YP31kS2Q033BDG7PzSSy8dxp544on8TroANtpoIyAenu7duzcQbYOHKEnuxhtvBOIVgo855hgAnn766TBmS2PlwJaFfBVPC4s/+OCDALRq1Sqc23vvvYH4Fk5bMrrkkksKO9k6GDFiRN6eyyqfArz66qsATJ8+PW/PXyq2dHrFFVeEsf322y/ncbYkfPLJJwPxpTHb7OAT/0844YRKnyNtRo0aFY5t2dgnVtvvxvjx48NY8+bNgShp/6yzzgrn7HPGLyvZxhC/PF+Oy0LGkmQ9vzU5aZnHztdkC3NNKdIiIiIimZDqSEt947cg2jbNN954I4z99NNPscf7q1mLMiRFUizhEuDwww/Py1zzxYoL+TulVVZZBYjubCBKKrWiYwBTp04FogTbTTbZJJyzSMs777xTiGmXxODBg8OxRVEsWgJRhMWst9564diKFPokVotilFMEqipTpkwJx/a7VvE1yworZwBR0qh//1uRSf/+sIjku+++m/N8a665JhAVrvQef/zxcHzOOefUZdp5t/HGGwNRdAWi5GPbLl8Z29592WWXATB8+PBwbrXVVgPg+uuvD2MWzfYRrayyKLyP1lcsFmefzVDYyElNKdIiIiIimaCLFhEREcmEVC8PWcJYfXHVVVeF41NPPRWIL+dYuH/QoEE5//aOO+7IGbM6DJaElkZWodInHNsymG8LP3HiRCC5imdVfvnll7pOMTWscickV7it6MUXXwzHltTs/105VoBNYstq/r1j1YOztjxky0I+GdSWhfwynyWXTp48udLn8kntVvfKlkW8yy+/PBz/8MMPtZl2wdiSjX9f2+vhK6lXp1q639Rhy8t+OfXYY48F4vVtssQn1iZVV6+4PJSmJSFPkRYRERHJhFRHWnyVw4p8pdNyce6554Zjq2LrO49ad1FLtvX9GizR0t8FWPVYH8VIG0ua85U7aytp665Prss6X53Ttupa5VOIvleLHhx11FHhnPWb8f13fIf0cmTRA0setcRtiCdYZklVFWmPPPLIcFxVhGWDDTYA4hWTrQJx1li0cNiwYWHs9NNPB+Djjz8OY+eddx4Qj0hXLJdhXZ8Bdt55ZyBeIiAfn1GlkJR0a/7xj38UdzJ5oEiLiIiIZIIuWkRERCQTUr08VJWbbrqp1FPIu99++y0cH3zwwUC8LoIl51ryql8essqovXr1CmNpXhYqhDZt2pR6CgXlE2et/oZPzrUlRVsm8O8PS1S0aspQnvVZfC0b+92x7903JM3q9+5r7xhbEk6qv+IdccQRAAwdHJK3SwAAIABJREFUOhSI13qx6tJrrLFGGLPGm1n4HPGfk1bLyScr27FV1gY49NBDgSjB1p/bcsstgfKoeFtVZduKybdZoEiLiIiIZELqIi2+14OvyAdRlUcor62sSawN+iuvvBLG/J0zwFJLRdecs2bNArJxV1QMVv10/vz5JZ5JYdiWVn93aP2FLOLSrFmzcK5jx45APPmynFh5hAsvvDCMWdLxQQcdBGQ3uuL5yJqx76vi5yXEyyNYj6Jll10WgA033DCcs0RVH2l5+eWXgdxK3Gn0+++/h2OLOPntygMGDADgyiuvDGNff/117Dl23HHHcFwOEZaqWFKuj8JYL6Fi9A+qC0VaREREJBNSF2lp3LhxOLY7A/PSSy+F4xkzZhRtTqVgHWn91syKeQk+8rL66qsD0XZGWPIad7mw94lf77didP4OrBz54mgVC6X57706xeiyzCJJ/vu04/XXXz/2X4i2jPvoSxaK7VkXd98jyCImS4qiWfRxjz32AOJlI+x3x+c8+ZyQrLPXxrYyQxSZNJ06dQrHSXkgWWXbmocMGZJzzm+DtmN7nN8OnabcF0VaREREJBN00SIiIiKZkLrlofrMt5a3dvN+G69tbbRtzb71+imnnALA8ccfH8asf0a5s8q/vpdKViue5oMl5/rlQ1sGufXWW0syp0K75557AFiwYEEYs0TMq6++GognJtvSUdK2cEtyhvT1Jvr0008BuPTSS8OYVUquuJwO8d8DS7a1ZSGfxL3FFlsA8UT+LCyXVcVvVLBq0f57ti3g9vr512rx4sWxf5dltrTjl3iSlnsqLh/5/09Tcq4iLSIiIpIJirSkyJNPPhmOq9NLyEdajBVFgmj7+Ny5c/M/2RTp2rUrEO/iO3PmzFJNp2Rsq/Po0aOBeFKq71tUjqyjte9sbex1ad++fc6Y3xZr24l9obK0RVpsm65FTSoeV0fz5s0BGD9+fM452/ZaDnx/Jiu4aN29IepDZK+DbfGGqCu6jzalIcqQL0mRFvv+LMLik3QtMbli2Y1SUKRFREREMkEXLSIiIpIJWh5KgVGjRgFRTyGIQvs+sXbq1KlLfC4L/QI0adIkX1NMNUtWfvvtt8NYfVwesmqmTZs2BeLvl6eeeqoUU0oFC/H7UL8txX744YdhzCdplrPu3bsD8eVD6z1UDrVZ7HPUatp4SYnoVjXblpAAJk2aBMBFF10Uxuz9UQ6VlZPY8pAtC/nloTQtjSnSIiIiIpmQqUjLvHnzSj2FvPGJkYcccggQ36J33XXXAfDwww9X+hx+C6clSPktiz6JV8qTJZQC3HXXXUB0B33JJZeUZE5Z4nv51JfXLakyqnV+/vjjj4s9nbzbaaedAFhhhRXCmPUSmj17dqX/7tVXXw3H1svKR2b69esHRJ/N5cYiK926dSvtRJZAkRYRERHJBF20iIiISCakbnmodevWlZ4bMWJEEWdSWLvuums4trD0okWLwtjTTz9d6b+1xl6+4q0lnvrE3XLXokULAP72t78BMHny5FJOpyR847xWrVoBUdO7tNUYSZOjjjoq9l+A999/Hyjf123VVVcFogaL/vNmzpw5JZlTIXTo0CFnzP52+O+5Ko888kjO45dffvk8zK6wrP6KX+KxxodJybRJtViSpKl+jyItIiIikgmpi7QceuihpZ5CUVgreO+nn34Kx7/99hsAPXr0CGPrr78+kJwoOG3aNKB+Jd9aDybb2p20xbFcWVTFb9OsL4mktWWvGcCAAQOA+LbfBx54oOhzKqbDDjss9v8+aX/ixInFnk5Rvf766zV6vJVRWGaZ1P2JTGQRlqQkax9NqQkfmUmqoFsqirSIiIhIJmTjMrIMTZ8+PRzbGrPfovfYY48t8Tl8js/gwYPzOLts8N14Ab744osSzaT4rPtsu3btwphtxSzXLZl15Tv2brbZZkDUHRrg/PPPL/qcCs0KDkJUWsE6Yft8qHLy+++/A/F8FOuOXRWfC3PmmWcC8TIUaY5iJ0VYastyYNIUXfEUaREREZFM0EWLiIiIZEImlofeeOON2H/LwTXXXBOOv/zySwBOO+20nMdNmTIlHFtPmT322AOI+oXUd1Yp2bb6livfG8cqufplRiXgJhszZgwQr347YcIEIF6Zuhz57dtrr702AD///DMAX3/9dUnmVGhWGXrQoEFhzJbb77zzzpzHW68iWxKC6DWySsEAI0eOzPtc88WWdJKWieyc3wZtW5jTugRUFUVaREREJBNSF2nx/R+MXRX++uuvxZ5OwfiokR37K31ZMuu7Y4Wxvvrqq1JOp2Csx5S/67MEwYceeiiMlWv32eqwXjFdu3YNY1Ys7sADDwTiCcrlGJXySbf33XcfEJVJ8I477rhiTakkLCHfR9Es4frKK6+s9N/5qNTZZ58NwEcffVSIKeadRUyyGDmpKUVaREREJBN00SIiIiKZkLrloX/+85+JxyIAp556aji25aFy6kmVxL7Pjh07hjFbMk1zcmAxvfjii0B8idUSs63P11NPPVX8iRVRly5dwvHmm2+ec/76668HYOzYsUWbUyn5n7cl20r2KdIiIiIimZC6SItIVVZaaaWcsfHjx5dgJsVjidpZ6YNSCvYaWSdj+R9fMuG8884r4UxE8kORFhEREckEXbSIiIhIJijeLJlyzjnnJB6L1Hfjxo1LPBYpJ4q0iIiISCbookVEREQyQRctIiIikgm6aBEREZFM0EWLiIiIZIIuWkRERCQTdNEiIiIimaCLFhEREckEXbSIiIhIJuiiRURERDJBFy0iIiKSCeo9JKm13HLLheMNNtgAgH333TeMzZs3D4BNN90UgDZt2oRzw4cPB2D06NFh7I8//ijcZEVEpOAUaREREZFMKGmkZbPNNgvHd9xxBwAbbbRRGHvggQcAOOKIIwD48ccfizi7dOjWrVs4ttfrvPPOA2D55Zev8t8utdT/rknbtm0bxr766qt8TzEv1lprrXB80UUXAbDLLruEsRVWWAGAX3/9NYwtXrwYgGbNmgGwcOHCcG7UqFEAfPHFF2HsmWeeyfe0U8V+d7p27QrATTfdVK1/16BBg3D8ww8/ALDVVlsB8MEHH+RziiIidaJIi4iIiGSCLlpEREQkE0qyPLTJJpsA8NRTT4Wxli1bAvHw/1577QXA7bffDsDjjz9erCmWxGGHHRaOL7jgAiC+BNS8eXMA/vzzz9h/K2OJp6+88krO2F133QXA2LFjw7mPPvqotlOvM7+UYXP0c/v+++8B+M9//hPGbOmiRYsWQPy988gjjwBw/PHHh7FyWh5ae+21Adh7773D2DHHHAPAGmusASz5/WH84+y1HDduHBAtzQK89tprtZ+wiKTa6quvDsCAAQNyzh1yyCEAtGvXLufcCSecEI5vvfVWAAYNGgTAkCFDwrn33nsPgO222y6MLVq0qMbzVKRFREREMqEkkZZtt90WiKIrAHPnzgXiyblnnHEGAPfeey8AG2+8cTg3Y8aMgs+zJv7yl7+E4++++w6o/lXkjjvuCMCwYcPCmN/uW1d+K7A555xzAJgzZ04YK2Wk5aijjgrHM2fOrPPzWdRl5513DmMWRbCt0llj84coCtWlS5eCfK31118fiN8VlSLSYknCPmJWncdDFEFaeeWVATj33HPDuZNPPjn2GICJEycC6ftsKQb7eZ999tlh7IADDgCizyeAF154obgTqwWL5Pfq1SuMWTTA3gsQ/ewHDx4MwKWXXlrjr2XRb3vdNtxww3Du4osvBuKR7rRo0qQJAPvvv38Ys78JFsVNklQ24tprr008rsh+Lg0bNgxjirSIiIhI2UpNcbnbbrsNiN/lzJ49G4juMA888MBwrjZXxYXUs2fPcGz5FLNmzarWv/3www8BuPzyy8OY5bQsWLAgjNnrYNtSP//883DO7rz93cX2229f6df85JNPAPjXv/5VrTkWWj6iK3/729/CsRWjmzBhQhibP39+nb9GsdgWb4juXnbfffcwtuKKK9bqef22cIturrrqqrV6rnxr1apVON51112B6C7Yb4mvSlKkJen/LarpxyyyO2bMmDBmv1fTp0+v1tdPs1VWWQWISgR8+umn4dyrr74aOwdwyimnANWPrvTp0weI8qGKyf/MLHqw9NJL5zwuKVJgJRZefvnlMFbV9+x/Ny3Pcosttsh53IsvvgikJ9Ky2mqrhWPLJ1133XVzHmefk1aGBKK/Neutt14YS8p9qeill14Kxxbp/Pnnn2sw61yKtIiIiEgm6KJFREREMiE1y0NZN3LkyFr/2y+//BKAO++8M4x98803AHz88cdhzHrsWNjRtpUBXHXVVdX6Whbms+Us//xZZSFt//rZFunjjjsujFV3C3Aa7LPPPuG4f//+eXvezz77LBxfc801QLRNsdT875BfCisWS1i3ZSKAvn37AlF1blu2hbqHuYthmWWij3jb0GBLbe3btw/nLPHfl6GwUhPV1bRp01rPs6Y233xzAE477TQg3pPMlgh9NWf7vLNNEhAlnNrGkMmTJ1fra1999dXhuOKykH/9rrvuumo9X6HZspCfmy0L+c0X119/PQCPPfYYEE/VaNy4cewxS2JpDT6Nw/5u1ZUiLSIiIpIJmYq0VDcZL6v++9//hmO7y/G9h+wOYtKkSUD1ew+NGDEijFlCYTlEWGz74v333w/E3x9///vfgfidVRbY3b4Vc6qJSy65BIgSLH3vJrsTveyyy8JYo0aNaj3PQvBJflUZOnQokJ+frd8G7bfDGotG2BZp+90DePLJJ+v89QvFfra+QKMl5luBRp+ob1HICy+8MIylOXH9zDPPBKLiigMHDgznxo8fD8STzn/66aec53jzzTdj/12Sfv36AfENIcZKR/Tu3TuM1WY7byHYVmafdGubXPwGEp+YXZGVPjjyyCOr9TUPOuggoDAFYRVpERERkUzQRYuIiIhkQkmWh3755ZecMUus2m+//cKYT64C6NGjRzi2pZEff/yxEFMsiZVWWikcW9jzyiuvDGPV6T3kQ522xOQTLX///fc8zrh4rJbIwQcfHMYsSdIqLfpwrL1+dg7gnnvuAeJVgNPm0UcfBeLVn42vMWHfw8033xzGrrjiCiD6/Xr44YfDufPOOw+I6vNAlHzpl5F8L6Ni86H1008/HUhOQrY5+ppEta1ie+ONN4ZjS8z0CZxZsuyyy4ZjWxLwn6FTp04FotfPKt56dakGXMzfK/+zh2hJCKIk/LqwmkH33XdfGNtyyy2B+LKqJZwefvjhQLz/WZrZZ8S3335b6WPatm0bjn3l3KpYjTK/jJpvirSIiIhIJpQk0jJ69GgAunbtGsYs8XCHHXYIY1ZNzyosWsVFiO4garotL81uuOGGcOwjTpXx1Wxta5mvLOsTe7PIJyHbdma/TbMifwd00kkn5Zy3Co5JUYxSs2q+a665ZqWP8XeyVt20Kv7xSXfBVtlzSQndxeKrzlovKot6WBIkRH1yfBTGKqIWqm+Q3ZGmMbHb3vejRo0KY3Zn7Le0Wv8dS+j3SbdffPEFkJywWl12l10Mb731FhBF6P3fButgnxTRT2L9yXzfO0vs9T3lkpx//vlAcb/3mrKNCj5aYp3g7W8xRH+DrTebfz/5/lMV+UrC9jtZyHIAirSIiIhIJuiiRURERDKhJMtDljB59NFHhzG/NGJsecPqCfgQoO0D9+Gt3377Le9zLaaahul9EpWFd7O+JOT5EOO0adOA+M/b6gr4hNOKfLKhNR60pFSImqWVmrW2t2TrJD7pNh+6d+8OVB36LRX7XbYmoj4h0mqPWFgf4g3zauuYY46p9JzVm3jjjTfq/HXyzTYoJCVLvvbaa+HYKqPutddeQJSI7R9nzVgrY4nt66yzDhCvIlvMzx5rqGmJ6zfddFM4d+qppwKwePHiaj1Xu3btAGjSpEm1Hu/r8/gllLSy5o9+idWq3u6xxx5hzJbgrQ5SVZ9FEL1XrD4UFKe2jyItIiIikgkN/qykIcvML7/m8muHM27MSL79Zlax5xVjW/ms/wdE2zT9dk3fWyGLrBoqJN81WVVCf3Vs7ArX7qKg+i3l6wtLlttmm23C2Iorrliq6cQ89NBDQO5WTojuZPwdTXWTDKtyxBFHAFX3HrLKo1D9/lZZYkm9EL0/fLL3v//9byD6vUpjiYWll14agNtuuy2M1bSi8ldffQXEk/uNT4i3beHW08i/Xy3qUUxWxdj3+bHKr77cQRLrhWMRg5YtW4Zz/jPCWN+2zp07h7ElRabSxG+Jt95m1n8M4iU3KuO/30JWvW3VelX69B/AmScdQ7u28WRoRVpEREQkEzLRe8juKv32Zusts/XWW4exrEda/Jqw5V94Nmbb7HxOkBVfe/bZZ8OYdUD13XPrsqUx6+z9k3QXVQo+ilExemZdvgFeeeUVID/RFc9eD1964NBDD409xrbHliuLcEG0DdSzXIk0RliMFYz0OTn2fdmWYIhyWir+jCEqVLnbbrtV+bUsh+W9994DSt/DzLag+3wNi75UVR4Bou30ljvnfw+SOhJbNCdL0RXPf35YXph/X/vfhYrmzp0LxCN4hYiwVIciLSIiIpIJumgRERGRTMjE8pDxibjWW2PPPfcMYxdffDGQ/a3PS2KVLG3bGkTbeH2rcUuctIqIUL+Xh4wlEUIUSi5FpVOfA18xH37ixInhuNAJjr6nUcV5VJKnn3nWw2r11VcPY/a9+sq8vqdN2i1cuDAcWxkAXw5gyJAhscf7bcKDBg2q89e3Leh+S3Ap2O9yTX+nk6pR+15dd999d90mliLNmjUDcvv7Vcaq0pci2boiRVpEREQkEzIVafGsi6R1g4XorrmcCqxVZcqUKeHY+ur44lfWN8PfRZ111llFml362PvDF51KYy8ZKQzr3AvR50bDhg3D2Ndffw0kbzvPKt+jygoYvv7660B+oiuej0pkiW1nT9r84KNR+egeXUpNmzYNxwceeCAQbVv2LNHYf042bty4wLOrPkVaREREJBN00SIiIiKZkNnloSQbbbQRUH+Whzyr1ZCUaGtt3Os7X1G2lOx9WlWvm0LxYV5bHrBQsWdJ3j48nnWDBw8Ox1YJ1yca33XXXQDMmDGjuBMrIKuiDdCoUSMgvqEhn0pds6W2rFfRCiusEMY++ugjAO69996SzKkQbHkQoo0sntVpscfdeOON4ZzV+EkDRVpEREQkE8oq0mKdR0u95a4U+vbtC0SvgeerrabtzsG2H1922WVhzK7067J13fqx+O7hlohb6s7Ob7/9NgDDhw8PY5deemlRvrZPvrQOyknstc93Fd5SsB5L/ntfaqn/3a999tlnYayctrRaB2cfzbP+QtbNt76zLsa2/XfBggXh3BVXXAHEK1NnlZXDGDhwYM45q5oOUYXsefPmFWditaRIi4iIiGSCLlpEREQkE8pqeSjNbD+8JftZeBqgbdu2QBS+9Xxb+M022yx2zoe7k5qDTZs2DShNwmd1WfPCU045JYytt956AJx88slhzBLjquIrWt56661A1FgT4J133gHiS0b1xQknnABE1ZQrM3/+fKA8EnCtLstRRx0FxJNurQrwAQccEMasgV45sLpNO+ywQxg79thjgfJY8sgHq8+y8cYbA/DSSy+Fc3fccUdJ5pQvPgHbPkeXX375MPbII48AcNttt4Ux+92335s2bdqEc1bDKA0UaREREZFMKGmkZaeddgrHt9xyCxC/C7CEMbtrzprOnTuHY/v+7G7P93vZfffdAZgzZ04Y69+/PxC/YrbEsaR+MElj119/PRBvP542VtX3yy+/DGO77bYbEG1LhSg511ewtSiN9Y/p06dPOGeJiH679y677JLzHGnle4Jsu+22QDwq4F+vijbccEMAbr755jBm1ZH9ludff/0ViG+T33///QF4/vnnazv11Nh1112B+O+hsd5OFn0rBxtssEE4trtr33vIorz1mX8vXHPNNbFzhdoKXkyWVOx7l9nfDR/J79evHwA///xzznNYZWD/+ZuGnkNGkRYRERHJhJJGWrp37x6OLVLgC/zYnaIVthkzZkw459fb0srnYdx3330AHHbYYTmPq23+gK1BAkyePBmAoUOHhrFXX321Vs9bTHaXb9EVgHvuuQeI3znaWJIGDRoA8WjTM888A8R7U82ePTsPM86f//u//wvHs2bNAmDVVVcF4uvPduz7SlUl6fUw/j1jxdbKIX8liS8mV9GwYcOA+DbXrDv66KPDsb3XrdM7RJG1+szyBwFatmwJRN2xrSdTllmhPIuuQPQet63/kBxhsb9NvXv3BuJ5LD73pdQUaREREZFM0EWLiIiIZEJJl4dGjBgRjs8991wAOnbsGMZGjhwJRBX9fO8Eq3jq24XbEkxa+FD8kCFDgCjBskWLFlX+W+sl5EN0tk3atq1++umn4dxzzz2XhxmXzrvvvhuO99tvPyCeeGpbdn04f+rUqUD0c/fJYvba2+uYRg8++GA4PuSQQwDo1atXQb+m/Z5BeS4LjRs3LhyvvfbasXM+0XKTTTYB4svRPnkxSyzJ2t5DEG1e8Nt4Jdr04E2aNAmAl19+udjTybumTZvmjNnfhk6dOoUxO957773D2BZbbAFAw4YNgWiLPKSrr5QiLSIiIpIJJY20+EiB8XfcXbt2BaLkIou4QLSl1XfuTfNWVouYWEGjE088MZyz3kDXXXddGJs+fToQ9YOoT6zIl0WnKh6Xo7POOguIigkuKRJXHWPHjg3HtuXetpiXK3/nWDER2Z/bZ599ANh6662LM7ECsjvixx9/PIxZ7xyJS/obYaUhrA8awOLFi4s2p0Lr2bNn7L9LYn+H/PspTRRpERERkUzQRYuIiIhkQoM/k4o5ADO//JrLrx3OuDEj+fabWcWel4hIjfnE60o+2gAYNWoUACeddFIYy1LNlpVWWikc21Jy3759w1jWE/MLZc899wzHEyZMiJ3zqQY+FSFLrKaTr66exM77qtmWxG7vJ1+1vdhatV6VPv0HcOZJx9Cu7V9i5xRpERERkUxQl2cRqRfGjx8fjq3zc1ZZOQiIqmArurJkvpP36NGjgagibjlserA+c1YSpBwp0iIiIiKZoIsWERERyQQtD4lI2SjnsLjna85I9X344YfhOKl5raSfIi0iIiKSCbpoERERkUzQRYuIiIhkgi5aREREJBN00SIiIiKZoIsWERERyQRdtIiIiEgm6KJFREREMkEXLSIiIpIJumgRERGRTNBFi4iIiGSCeg+J1CONGzcOx//85z8B2GOPPcLYzJkzAVhjjTWKOi+RUlt99dXD8TPPPAPAOuusE8a+/fZbAP7+97+HsXfffbdIsxOjSIuIiIhkQmoiLVtuuSUAm266aRg79dRTAVhzzTUB2GGHHcK5F154oYizk6w577zzAPjHP/4Rxuyu6NJLLw1j9957b3EnVmIbbLBBOO7VqxcAf/75Zxjzx2m1+eabAzBlypSCPP++++4bju1zxu6ypfy0b98egCeffDKMrbXWWgD88ccfYWyllVYCYMKECWGsQ4cOxZhiUbVq1QqAkSNHhjH7rPCGDBkCwNChQ4szsf9PkRYRERHJBF20iIiISCaUZHmoZcuWANx4441hbMcddwRg5ZVXznm8hawfeOCBMPbVV19V+vznnntuOH7ppZcAmDNnTh1mLIV20UUXhePx48cD8NZbb9XoOXyS6RlnnAHElzs6deoEwFFHHRXG6svy0DLL/O9X/cwzz6zycb/88ksxplNjO++8czgeO3YsAN98800Y22STTQD47bffav01+vbtC8Cdd94Zxh5++GEA9t9//1o/b9bZMj3AOeecA8CkSZOAbL8uO+20ExAt9zRt2jTnMS+//HI43nrrrQFYaqnyvNc/9thjgeh3rWfPnuGcXyYztjz0/fffh7FbbrmlkFMEFGkRERGRjChJpMW2jNX0Kt0iNAArrrhipY976KGHwvGDDz4IwEEHHQTAr7/+WqOvmUbrrrsuACeddFIY6927NxAlUQG8//77QDzyZK9HqdnPz7bbDhw4MJwbMGAAEN+CWNM76KS7pvrM7or22WefnHMff/xxOLb3UVrssssuAIwePTqM2eeA/zxo0KBBnb/WwoULgfhdpd2N33XXXQAccsghdf46aeajCPY9H3DAAWHMolsXX3xxcSeWJ34r/3XXXQckf1a8+eabAPTo0SOMWVTWJ7NnlUWN7rjjjjC26qqrArDccssBydGVJFdccUU4btKkCRCtotQl8lkZRVpEREQkE4oWabEtzQC33nprsb5suHM88cQTAbj88suL9rXzbfDgwQCcddZZQPwOwXI3fA5Hx44dgfhd6sEHHwyUPuJicxs1alSlj8nH3bP8jy8gV5HPFfvwww+LMZ0latasGRBtWbftphDdAQ4fPjyMLV68uM5f034nvv766zD217/+FYg+v5o3bx7OzZ8/v85fM20222yzcNyvX7+c8/bzePvtt4s2p3waM2ZMOLbPIDN79uxwfNxxxwHxHK/DDjsMgIYNGxZyigXTrVu3cHzfffcByTmkNeX/DvmoC8CwYcPq/PwVKdIiIiIimaCLFhEREcmEgi8PtWjRAoDHHnssjC2//PK1eq5HH300HK+wwgpAlFC0JLbV86abbgpjP/30U63mUSg+ifaEE04Aoi2GEC2XWIKtr+Bo2/a++OKLMPbaa6/lPK+Ff0u9PCSF57csWtVPb968eUC89EBa3HDDDUBU/daz5c5BgwYVbT5rr702EE9k9luj08pv799qq60AOP300wH47rvvwjlLvvRLycYSciHqV5U1Z599NgBdunTJOWfLQr4S8iuvvJLzuLlz5xZodsXhk+zzsSxUFXvfaXlIRERE6q2CR1psW2Jtoiu2Xeqaa64B4lEHe17fj8gSfC0K49nXT2NhIIuE+GiURUSmT58exmy75QcffADAggULwjnA1y4BAAANEElEQVTbBn3kkUeGsaReGb7vjpQ3H4mwBFK/5X+vvfYC4omnpeSTQHfffffYOV8c0kdLJZkV27v66qvDmH2enn/++TmPv+eee4DocwSiCIsvrfDjjz/mf7IF4pPPbct/UhLt/fffD8QLyZUT68NW3chkTf9GJj3eInfrr79+GPN/y+oifX/BRURERBLookVEREQyoeDLQ76nTE1ddtllAFxwwQU55yxcnNSPyO9HtyUV25NvIXFITjorBWvt7cPjFq7t379/tZ5ju+22A6JaLhDVbHnqqafCmF9SSjvfb+aRRx4p4UyyxZZT/etntU0mT54cxl544YXiTqwSnTt3BqJ+NhAl8BtfMXnq1KkFnY9/jaxOi/GVYNOWiOuXxW1Jx+rdQJS4b8n6llwMsM022wDx5Z+TTz45ZyxL/HsoaVnI+tL5z8xyZH8/q1vh1tT08f7fWHVd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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x, y = next(data(batch_size=64))\n", "show_images(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Define Linear Node" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define a simple Linear classifier using a Linear ``Node``.\n", "\n", "Nodes are at MagNet's heart.\n", "

\n", "They are _self-aware_ modules.\n", "

\n", "They react to the computational graph and change their properties accordingly" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# Note that the activation has to be explicitly disabled.\n", "# The default is ReLU.\n", "model = mn.Linear(10, act=None)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Linear()" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model\n", "# The model is not yet built.\n", "# Makes sense since we don't know the input dimensionality yet" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "MagNet automatically builds Nodes just in time.\n", "\n", "Let's summarize the model" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "+--------+-----------+----------------------+\n", "| Node | Shape | Trainable Parameters |\n", "+--------+-----------+----------------------+\n", "| input | 1, 28, 28 | 0 |\n", "+--------+-----------+----------------------+\n", "| Linear | 10 | 7,850 |\n", "+--------+-----------+----------------------+\n", "Total Trainable Parameters: 7,850\n" ] } ], "source": [ "summarize(model, x) # x is the input to the model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will ask the model to sort digits into respective buckets.\n", "\n", "The first column represents $0$, the second $1$ and so on...\n", "\n", "All the digits in the first column are what the model thinks is $0$.\n", "\n", "The correct results are in black and the wrong ones are in white." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "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uj79urvqd97usmbN4tKmSevKlSvr+vbvwR5TAADf0pw9e/ZsrBcBAAAAAImGK1MAAAAA4AMnUwAAAADgAydTAAAAAOCD5zS/g4cOuzXrNrrcuXK6DBnSR3NNAAAAABBzJ06cdHv37XdXlijusmfL+o//3fNkas26jW7UuIkRXRwAAAAAxLuG9R5xlSqU/cftnidTuXPntC8sWCBf5FYGAACQgK6rUCHWS0hRflqyJNZLAP5h5649btS4iXZu9L88T6YypP//al/BAvlckcIXRWZ1AAAACWrP7p2xXkKKwudNxLNz50b/iwEUAAAAAOADJ1MAAAAA4AMnUwAAAADgAydTAAAAAOADJ1MAAAAA4AMnUwAAAADgg+dodKRe3bp1s3zo0CHLHTp0sJw5c2bnnHPTp0+32x544AHLN9xwg+UJEyZYLliwYHgXCwAAAMQIV6YAAAAAwAdOpgAAAADAB2p+cM45N378eMtdunSxfPToUctZs2a13K5dO+ecc1WqVLHbSpUqZXnhwoWW7733XsuLFy+2nCFDhuQuGwAAwNOKFSssz5gxwznn3Jo1a+y2DRs2WP7+++8tnzp1KuDxzp49azlHjhyWa9WqZblly5aWy5Yt62fZSCBcmQIAAAAAHziZAgAAAAAfqPmlYjpl78knn7R84sSJgPfXyX7n5MuXz7JeSr/lllssf/vtt5aHDRtm+bnnngttwQni5MmTlnv06GF5zpw5ll9//XXL1apVi8q6Ymnz5s2WO3bsaHns2LEB73/NNddY1pqoeuWVVyxrBRXB2717t+U6depYzpUrl+UPP/zQ8rkpngAQb/7880/L9evXt6yfQc69V1StWtVuq1GjRsDsZefOnZZnz55t+eOPPw6Y69WrZ3ngwIGWM2bMmORjITFwZQoAAAAAfOBkCgAAAAB8oOaXymzatMnyE088Ydmr2nfhhRdavv7664N+HK0GXXfddZbbtGlj+YorrrB81113BX3seLRs2TLLL7/8suW5c+dazpIli+VgamlaF9T6wsaNGy1rVfPZZ5+1XKJECcvp0qVL8rEi4bfffrN89913W9b1p0mTJuDXamVUs+rZs6flSZMmWb7nnntCX2wq1blzZ8sLFiwIeJ9KlSpZLl26tOXBgwdb1lpgrL3//vuWmzZtarlv376WixYtavn++++PzsKA//Hll19a1olv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PSxTpozlP//807LW/PS5qfVhnRYYL68HXJkCAAAAAB84mQIAAAAAH+Km5qeT6H777TfLmTNntqybf8XzxoaRppPvdu3aZdlrw0mdOqebQ8ZaJDbIDMaOHTssjx492rJXtU8vTderV89yr169At5fN5XUzU+TM61n8eLFvr8WKcOxY8cst2rVyrJW+7S2p5Wy/v37W9Z6be/evS3r1M1gKida69ApeLr5ZCLQ95J3333XslbLvCZGff3115Y7depkWasne/futTx48GDLutmkTl5MlIlq+n3zmsgXLlq32rp1a0QfK5q0wqfTzZ544gnLF1zg/2Pa6dOnLY8aNcryp59+almnTfbp08ey/k5369bN8m233eZ7PYlGJ0gnh/7e64RFnRyYiPRPRcaNG2e5Zs2aAe+v0xHbtGljWeuC+qcrBQsWtKwV1Hic4smVKQAAAADwgZMpAAAAAPAhpjU/ra3oxCgvOklIaytZsmQJeH+tquTOnduyXkbUCSHxTDd385ospapWrWq5adOmEVlTotIpVDqxKBg6eW/hwoVhWxOQlNmzZ1ueOnWqZa32vfHGG5Zbt25tWacrffDBB2FZj76+6kbbWglKZNmyZbNcuXLlgPfR20uVKmVZa+teEzp37txpuXbt2pYnTJhgOVEqf/BHJz1qDhedwqcT6DTrZymtm86fP99yrVq1LOtrj254nVLo77FuSutF/1xh48aNlm+//XbLKamaqvQ94Oabb/Z9HJ1e2aRJE8tal543b57v40cDV6YAAAAAwAdOpgAAAADAh5jW/HRSik7wU1oFvPvuu8PyuP369bOslxRffPFFy8mZoBMJWvH5/vvvk7z/jBkzLGtdJRZ0U0xdlypXrlxE13D8+HHLodbzdAJNMLR2pTWIQoUKWdYpOD179rTs9bPVaipSD33evvDCC5Z1I26t7em0Sa2w6n30tU3rz3fddZflHDlyBFyPTgL88ssvLSfihpPhphOsKlSoYFkrkG+99VbAr922bZtlfR/SiWr4dzpdEsHTKcn6GUunAGv1VKf56XNbq4OJRqt9kyZNshzMJrxKpySm1GpfJOj0ytKlS1vW6apr1qyJ6ppCxZUpAAAAAPCBkykAAAAA8CGmXbaVK1f6/lqtUuklWqWbrU6ePNmyTlzRy9TPPfec5Xir+emmhcFceo51tU/phDGdSqgbMnfs2DGia9CJWjNnzvR9nLx581q+5pprLGtdVDct9ZoCpvQStxedZPPKK68keX+kDF999ZXlLVu2WNZKnlb7lFZO9HnbsmVLyx06dEhyDfv27bP83nvvWdaa36pVq5I8TmqilV59/dM6s9cGqYsWLbJctGhRy/rzT210AquXp556KgorSdlKlChheeTIkZZ16rH+LHTj1TvvvNNy4cKFI7TCyFixYoXlYD5f6e9iom1SHi/0M7xuXq3ff93YPN5xZQoAAAAAfOBkCgAAAAB8iGmX7eqrr7YczOapJUuWtFy+fHnLwVxS1q/VzSx37NhhWacL6gbB8eD999+3rJvEqXvvvTday0nS8OHDLS9btsyyrl2nX2mOBN0QUeucvXr1Cnh/rXlqDa9Ro0aWr7/++nAu8V8lyubSiI6uXbsmeZ89e/ZY1qmAOvXs0KFDlr/44gvLOlVSN1TXaX76u1ynTp1glh11OsWwU6dOAe+jv9M6wSwSHnjgAcu6oeqSJUss6wRb3dhXK5aNGzeO1BLjxoIFCyx7bdip73k6mRLJlylTJsv6e6TTbTds2GB58ODBloN5fYq1Zs2aJXkfnbLZtGlTy1q/1Ylzjz/+uOVXX301uUtM0e655x7L+nl+7969lrXmHu+4MgUAAAAAPnAyBQAAAAA+xLTmlydPHss6FSY5Dh8+bHnKlCmWveobt99+u2WvjSoThU7iiQW93K0bTyr9mTdv3jziawqke/fulr2qPyoeKp+6yS+gk7MqVqwY8D5a89PqmFbEQq2LabVPp6W2bds2pONEi9ajvTYWbtiwYbSWcx6tNmvNRTcVP336tOXVq1dHZ2Fx4rvvvrOsU2BVwYIFLetG1olIN4vVXLt2bctXXnmlZf3ThUjTmrlOWNNNfvV2rdBdcsklEV5daM5V9LyqiL/88otlnRC5fPlyy/pnA0on1OHfeX0PX3vttSivJDy4MgUAAAAAPnAyBQAAAAA+xNfOtD7NnTvXsk48+vjjjwPeXycAdenSxbJOV0pEOkGvR48eUX9MrfadOHEi4P11auPNN98cuYX9C60qxarCt337dstnzpyxrBvW6dS1p59+OjoLQ1zR56rmv/76y/KsWbPC8ljZs2e3rJO8tIKmmyvWr18/LI8bScFUt3VaodaTovl+EMw6R48ebbl3796RXE5cGD9+fJL3iWbVLdIefvhhy8OGDQt4e9asWS1r/U+rUZHeRLZ06dKWW7RoEXANOiFTN/eOB5kzZ3bOnf87p6+tdevWtbx27dqAx9DnnddrNP5JN4/XevWpU6cs6wbmiYQrUwAAAADgAydTAAAAAOBDxGp+Wl3SSXpr1qyxPHDgQMs6lUfpRrq6cdynn35qWS8L6vQj9eabb1pu1aqVZb1sHs90g7MZM2YEvI9uwNmxY0fLL7/8suVw1drOTe7Ty/xJ3dc555588smwPH6imzlzpmXdUFVrAvfdd59l3UQYqUeNGjUs6+Q9rdeGSustuoG51om0ypPIOnToYNmrbvTCCy9YTpv2v/99MZrTRn/++eck75OoU64iSatuKYl+vmnZsqXlcePGWR4xYoTlsWPHWtb3jUcffdSybjJfuHDhsKzTa5Lojh07LOvnkmzZsoXlccNBK/W7du2yfK4G6JxzDz74oOUKFSpY1tq9HkenpuKf9LmZK1cuy7phfKJOLeXKFAAAAAD4wMkUAAAAAPgQse7QsmXLLOsmqXXq1LGsm6AtWLDA8uLFiwMe5+DBgwEfq3jx4pb1UqxOtLvooossJ+LUPp1spBt26saG6q233rL81VdfWdYJcVob8qo7rlu3zrLWC8/VELSWphvy6kScJk2aBDx2aqYbcwLBGDp0aMAMb4UKFbKsE8Z06qtW0rVSpfUkrUonx/z58y0vWbIk4GNpbSi12bZtm+W9e/fGcCWxpe/HWud76aWXLHfu3Nny559/btlr8998+fJZ1g23tcqmUzy1qudlypQpAW/ft2+f5Xit+akCBQpY1t/LUL399tvhWE6KVapUqYC3z5s3L8orCT+uTAEAAACAD5xMAQAAAIAPEav56YQk3ZDrww8/DJi96GVnnUxTq1Yty/fff7/lDBkyhL7YBKBT+HSj4fbt21v2qvx53T5x4kTLWi0JZeO5KlWqWO7atavlWG3ImyiCmaakm0sDCJ1uYDp48GDLZcuWtazVPn3t69SpU8CvfeCBByzfdNNNAR938+bNlnVq7YEDByxr/clr40993S9RokTAx0pJtPq/devWgPfRqZNa308NdMqmVv9PnDhhuU+fPpanTZtmWT8HaC1Qc3LoJMy2bdtajref0e7du51z50/QvPbaa30fT6eE6mbL+Kcbb7wx4O063ThRcWUKAAAAAHzgZAoAAAAAfIhYzU83Ig1GtWrVLOuGaLfddpvleLtcHCu33HKLZb3EPGfOHMt66f79998Py+OWK1fO8rkKmk650s3u8O90KlPPnj0ta/2oevXqUV0TkJLpFFfdkFfrdiNHjrS8fv16y3/88YdlrfwNGjTIcij16H9Ts2ZNy7r5ur7+plTBTFLTajubmf8//fMGfU/Wut2KFSss65S/c7W3/6VTBLVGqH960bBhQ8uPPfaYZa86Vzw4NyVSN0SvWrWqZf28pBuc79+/3/I777xjedSoUZZPnz4d3sWmAJUrVw6YN23aZFlr0YmKK1MAAAAA4AMnUwAAAADgQ8SukU+YMMGyTpHRy78FCxa0rBWMcNUlUgOd9qRTDTWzwWf80frA0aNHY7gSIHXTWtTjjz8eMOtkOa37eG0k7yVnzpyWs2TJYlkrfFoz0o3QU4NZs2YFvP2hhx6yXKZMmWgtJ+HpZ6lrrrkmYPaiddaUaNeuXZYnT54cMCP5Lr/8css6NVrPEQ4fPhzVNUUCV6YAAAAAwAdOpgAAAADAh4jV/HSzRM0AAMQj3Ux7/vz5Ae+jty9btiyk4+tm5uXLlw9xdSnf9ddfb/mHH36wrJMVdePj3LlzR2dhAHy59dZbA95+bqpiSsGVKQAAAADwgZMpAAAAAPCBHe8AAAiSbpquGcn3zDPPWB4/frzlUqVKWabaB8Q3neBXq1Ytyzq1Tzc7Tgm4MgUAAAAAPnAyBQAAAAA+UPMDAAAxV7JkSct//PFHDFcCwK8NGzZY1o3KUzKuTAEAAACAD5xMAQAAAIAP1PwAAAB8SJMmTayXAAR09uzZWC8hxdi6bbt7p++7nv87V6YAAAAAwAdOpgAAAADAB06mAAAAAMAHTqYAAAAAwAdOpgAAAADAB06mAAAAAMAHTqYAAAAAwAdOpgAAAADABzbtBQAAABAxBw8etPzRRx9ZnjRpkuU5c+ZYLlGihOUbb7zRcunSpS0/8cQTlnPnzh2+xYaIK1MAAAAA4AMnUwAAAADgAzU//MPXX39t+dZbb7WcNu0/z70HDx5s+ZlnnonougAAACLl2muvtbxo0SLLmTJlspwmTRrLZ8+eDen4b7/9tuXOnTtbPnbsWEjHSUQ//vij5RYtWljOkCGD5Xz58lnevHmz5XXr1lnW7/8PP/xgeezYsZYDfV6NJK5MAQAAAIAPnEwBAAAAgA/U/FIxnZrSs2dPywsWLLCsl0r10uo5s2fPtkzND4h/EyZMsPzZZ59ZXr58ueWLL77Ycvny5S137NjRcvr06SO1RACIiaJFi1rOmDGjZa3zHTp0yLJW1y655BLLl19+ecDjv/LKK5ZHjRplee3atT5XnDjGjRtnWat9Y8aMsVyrVi3L3377reUGDRpY3rp1q+Xx48dbfuCBByzXqVMnDCsOHlemAAAAAMAHTqYAAAAAwIe4qfnt2bPH8k8//RTwPtOnT7c8dOhQy2fOnLGstbThw4dbrlKliuWrr746eYtNYJ988onlRo0aWU4Nk2SA1GTlypWW27dvb/nLL7+0nDNnTsvlypWzvHHjRsuzZs2yPHXq1IDHKVSoUBhWHH5aV9SaslYXtVaidAPImjVrRmB1ABJRq1atLGt1rU+fPpZXrFhh+aGHHgp4nK5du1p+5JFHwrnEuJQ9e3bLhQsXtuz1Gqwb9er389lnn7Ws33+dlEjNDwAAAAASACdTAAAAAOBD3NT8mjRpYvnzzz9P8v5eG3Lp7TpdrmXLlpZ79+7tZ4kJRTfe1X+vTupLTrXv7rvvds4516FDB9/HABBeOhHq3O+oc84dPXrUsm4U2bBhQ8u6WeLp06ctDxgwwPJLL71keffu3ZbjteaXK1cuy7/++qtlfY/xer/RTTqLFCliOUeOHJY/+ugjy5dddlnyFotUTaeVVapUKcn7lylTxnLFihUt6/NWac11w4YNlrW6q68NBw8eTHINKdHMmTMt792717LWftevX2/577//tqyfh3755ZckH6tbt26+15mI3njjDcsvvPBCSF+bNWtWy9dcc41lrfmdOHHC/+KSiStTAAAAAOADJ1MAAAAA4EPUa3779++3rBP8dFKfV4UvOUaPHm1ZJ6vcdNNNYX+saNqxY4dl3YxTLzcfOXLE9/E7depk+a677rJctmxZ59z5G68lOq1G3nrrrUnev1q1apZvueUWy3opOzlr0OMDXrS+dscdd1jOmzevZZ3iWbVq1SSPmS5dOss6ueqtt97yvc5Y0E3Ft23bFvA+OoHrzz//tLx06VLL69atC/i1t99+u+X8+fNb/vDDDy17bd6ZiHRyrk7g0qqY1h0PHz5sWb8PixYtSvL4wXwOePTRRy1rrVXrq4miR48elvV3V2lVTzeRVV63K/0ZtW7d2rJWB9u1a2dZfxdSOq1YZsuWLeB9rrjiCsu6sewNN9xguUCBAgG/dteuXZa9XpNSKp3mpzk59Pmurx/RxpUpAAAAAPCBkykAAAAA8CEqNT+t9jVt2tTy5MmTo/HwzjnnDhw4YHn8+PGWE73mV69ePct6uTlUetl60KBBlm+77Tbfx0w0WrEL9f6atRqZHMHUNZA66STOunXrBrx95MiRlnVD3lDpa6dO+WvevLll3SA9njZF1ymDXhMHdSKfWrZsmeV9+/ZZ1ilnzZo1s6ybzVevXt3yiy++aFmnyiYi3cx52rRplrV+9ttvvwX8Wq316/2VVvu87qO02v7DDz9Y1vqlbg4az/R995VXXrGs1aWePXta1vcHnSj3448/Bjz+zTffbPn++++3rO/9WhPWyppX3S0l0s9Rhw4dspwnTx7LBQsWtJw+fXrLOu3U6/nbvXt3yzt37kzeYlMp3ZBev89ekyyjgStTAAAAAOADJ1MAAAAA4ENUan56eT851b777rvPsm7Iq5e7hw0bZlknBKqhQ4daHjhwoO/1xINNmzb5/trnn3/estZPLr300mStCeGhUwGTMyEQKU+jRo0s6wacX3zxheXkVPtOnjxpWaefauVv8eLFlnVj3yFDhvh+3HgSzPdPXyu13qbvT/369bN85513Wi5ZsmRylxiXtFYXau1G38uDqflt377d8pYtWyxrxfW1114LaQ2xohvm6mbT9957r+XkVMjnzZsX8DgdO3a0rFOAM2fO7PuxUgr9ExXdtFefUzodVauR+lzW4+j0UARPa9f6ZxVa3x4zZkw0l3QerkwBAAAAgA+cTAEAAACAD1Gp+emUI69Ntbxu180SixcvnuRjadVCJzAtWLAg4P3vueceyzNmzEjy+CnJkiVLLOsl1NRa89MqndYgvDbnVV4b7AYzIdCrujF//vwkvxaph04rmzRpkmXdVPfGG28My2NpFTqY57BOduvbt6/ljBkzhmU98erc5uX/m/W9Sqt9NWvWtKzvSV6TBuON/jxz5sxpWaeb6fPFa/PZcNEpkjpZcdWqVRF93EjT3yet42sVUCt5iIxbb73Vsn5G0sl++hlS6Ya8yalcpzZ6vtC1a1fLs2bNsnzq1CnLutl16dKlI7w6b1yZAgAAAAAfOJkCAAAAAB+iUvPT+pRuyueldu3alkOtCeilft2AzmsjyWDWE8+0NqKTDIOxcOFCy7rRX+PGjS3rpsa1atWyHMykpUQWrg1zvep/yqtSqNOXkDrpJrla6ylQoIDlNm3ahOWx1q9fb1mrg6po0aKW//zzT8s7duyw7FXZTk3KlCljuX379pZfeOEFyzp5qm3bttFZWDLly5fP8jXXXGNZf+aRrvapK6+8MmqPFU1alWzQoIHldu3aWZ46daplrUaFSt/LU/r7eqi0qrdmzRrLOrXPyx9//GF579694V1Ygtq1a5fliRMnWh43bpxl/SyqU2X1M5luIq3TZmMpsc8kAAAAACBGOJkCAAAAAB+iUvMLlV663717d8AcjCeffDJcS4pbWms8cuSI5Q8//DCk45w4ccLy4MGDLQ8aNMjyiy++aDl9+vTOufPrk/Xr1w/pMVMzrb4GMy0QqZNWHmbPnm1ZKxI6WSpUf//9t+XXX3/dsta2dPNOnTD5wAMPWP75558t6+sQG396++6772K9hN7nOuwAACAASURBVGQpX7685XBNkcQ/aQVKc7jcf//9lrVKpTXC1EonVubPnz+kr508eXK4l5PwtEr+3HPPBbxP5cqVLV911VWWR4wYYfnQoUOWly9fbrlIkSJhWacfXJkCAAAAAB+icmVK/wtmnz59krx/ly5dAmYv+l9RE32gRKj0D51HjRoVMP/++++WhwwZYvnzzz+3vHLlyoDH1+9t7969/3UtDRs2tKz/Ff222277168DEJj+VzcVriuYo0ePtjx+/HjLup/Q4sWLLesV7I0bNwY8pq5ZhwAh8Ydz6JXGnj17xnAl/2/RokUBb9f3vMOHD1vOmjVrxNeUCK677jrLl19+ecD7cGXq/M9IV1xxheVgBnXo1VrdCyk1K1y4sOWXX37Z8iWXXGL5mWeesZwuXTrLejVK91nUrFdZoy11nXkAAAAAQJhwMgUAAAAAPkSl5tekSRPLwdT8EF56CbVr166W9Q/OtQrRuXNnywMHDrQcyh4ULVq0sKyXyi+77LKgj5HS6NAJ3VuqY8eOAe8DaF1XJWcftG+//dZy9+7dLWuF6+OPP7as+wlphU9fM/SPs3VvOpw/aEJr6PyuJ1+WLFkC3r5z507LR48etUzN7//p7/2FF15oefXq1ZanTJkS8Gsvvvhiy7qXUiLT78E777xjuWLFipb1NVcrzvr5pmXLlpZLlixpWZ93+rqZ2hQrVsxyt27dQvraHDlyBLz94MGDyVlS2HBlCgAAAAB84GQKAAAAAHyISs1P6yN33XWX5Z9++snyrl27fB8/OROSEn26UnJkypQpYO7Xr59lnbiidZXPPvvMOXf+xJ8DBw5Y1v0EHn/8ccs6GQyAP6FUbp1z7uTJk5bHjBljWesqTZs2tXzfffcFPM6yZcsC3q7TBXUSYGqydOlSy1qP1sqk1pzz5csXnYWlYDNmzAh4u9azQt0fKDU7t3+kc+e/bzdv3tyy7r20adMmy4m2R6Luz/f8889b1n+rF93f84cffrBcu3Ztyzr9T/+8Rf/sBcHTPRfjEVemAAAAAMAHTqYAAAAAwIeo1Px0o65z9TDnnJs+fbrlBx980HJyNt4N9WtT2ya/obrooossP/zww//Iw4cPt9v00rf6+eefLU+bNs1yLDdYiyfVqlWL9RKQwunvqeYqVapY7t+/f5LHmThxYsDba9SokYzVJZZjx45Z1qml+n72119/WS5evLhlr43StUIdjOPHj1v+9NNPA+aUSif1/fbbbwHvo8/r1Ew35C1YsKBlrw1oS5QoYVmrqvo5Sb/nHTp0CN9io+TchsWDBg36x23/S/8U5Z577rGsv986UdJrUp/WThG8devWWV6xYoVlfc7qczmWOJMAAAAAAB84mQIAAAAAH6JS8/OiE6P0cl64PPnkk5ZDrVEkih07dljes2ePZd1oM5KPq4/v5cSJE5Z14l9qM3/+/IC3U/ODF91w+/vvv7f8+++/W86dO3fArx02bJjlV199NeAxx40bZzmYKXxer6N58+ZN8msTjU7nW7t2rWXd8PSXX34J+LW6wadWfxo0aGBZa35///13wOPoZqI6CVenrA4YMCDwPyCF0uesfm4oXbq05bp160Z1TbGmlXn9XFWnTh3LWkfT56dm/Qyh71dDhgyxrLX9/fv3J2fZUaM1vnOT9bw25J0zZ45l/dMFrfapsmXLWtZapSpTpkyIK44N/Tf++uuvlrUi6vVvDJfNmzdbbt++vWX9GWl1WqvWscSVKQAAAADwgZMpAAAAAPAhpjU/pZftwuWDDz6wfPXVVwe8j15S1MvXeuk2ns2ePduyVj8GDx5sWaedaBUiGNu3b7e8bds2y61bt3bOnV898qK1ourVq4f0+CnJ119/HeslIMG0bdvWsk5q0ypPrVq1LM+dO9eyVqB0KqdOsSpWrJjvtWltyOv1NdHohp2ffPKJ5X379oV0HJ02tXv37oBZqz+6sf3TTz8d8D5MqPt/WjXV77M+rwsUKBDVNcWCVvt0yuapU6csaw1Pf1+VVrtq1qxpecmSJWFZZzzQKtgNN9zgnDv/ubNq1SrLWqcNhk459tpMvVu3biEdM5oWLFhgecSIEZZ18qh+ngxXze/MmTOWly9fblmf1/pnJPq91Q2lixQpEpb1JBdXpgAAAADAB06mAAAAAMCHuKn5xYpOLPnmm28sJ0rNT+kkntq1a1vOlSuX5ZtuuimkY65fv96yfq9CoVUinQqTGrzxxhuWO3bsGPB2wEv58uUtt2nTxnKvXr0s9+3bN+DXXnrppZZnzJhhWTfmTI5MmTJZvuyyy8JyzFjbunWrZa9q3wUX/Pdt06vycsstt1i+8847A97n9ttvt5wtW7aQ1pna7Nq1y7JupJqa6bTJLl26WJ43b55lnch3+vTpgMfRemRKqvape++91/K5qXD6ZwsPPfRQksfImTOnZZ2SqBVCnTi3evVqy2+99VaIK46eZ555xrJWwy+++GLL6dOntzx16lTfj7Vw4ULLOs30iy++CHh//byqFdRnn33W9xoihStTAAAAAOADJ1MAAAAA4EOqqfnp5BCv2/Wy7NGjRy3rxonx5txkGuecK1mypGXdZFLrKtOmTQvp+HrZ2mtSzTm66adOIdPpVKkZm/MiVGnT/ve/d73zzjsB79OjRw/L9evXt9y5c2fLRYsW9b0GneipG3AHs8lvohk+fLhl3bxT6fvBI488EvE1wblRo0ZZ3rJli+Urr7wyYE4NtKbmVRuvV69eksdZsWJFuJaUUA4dOmR5586dlitXrmxZP1NptTpPnjyW9TPShAkTLL/22muWjx07FoYVR8Ydd9xhWWt+f/zxh2WdWBjKZ8L/pV+rdWn93dUKn2atGsYjrkwBAAAAgA+cTAEAAACAD6mm5qd1GS9a8XjppZcsR2JD4XDRtU2fPt2yTq/RiXzhphsB6sZ0uvllaqb1CzbtRbjo75o+xzJkyGA5Xbp0YXksnRp2+PBhy7o5qFaFdKPZRFOoUCHLDRo0iOFKoLym6+bNmzdgxv/LnTu3Zf0MpJv5pob3Jd10tkOHDs4556666iq7TaujWuPV11N15MgRy7q5rVb7NmzYkIwVR0/v3r0tay30wIEDlidNmmQ5X758lrU+rvfRirROj9WpiQ8++KDlSpUq+Vp7POHKFAAAAAD4wMkUAAAAAPiQamp+oWrSpInluXPnxnAlwdONM2fOnGlZp9AMGTIkyePoJpM6fWX27NmWX3nlFeecc61bt7bbdMJNaqa1K900UTfyZLIfkkMrO5kzZ47JGv7++2/LWpNJ5Jof4lNK2RQ62nRaseaBAwda9tqcOiXRSajnpsLdeOONdpu+ZnlV+z777DPLo0ePtjxx4sSwrTMWdEpe1apVA96nRo0aSR5HN/9NjbgyBQAAAAA+cDIFAAAAAD6k6Jpfzpw5Ld90002Wv/nmmyS/dseOHRFZU7QUK1bM8oABAwJmhI9ORNJqn96uNT8gUVSpUsVy9uzZLR88eDAWywGQTF4bUqdUumlu+/btY7gSpFRcmQIAAAAAHziZAgAAAAAfUnTNTzcX083Cgqn5AaHQOp/XJohM8EMi0s1QdbNPIFqGDh1qWTei7dy5cyyWAwDn4coUAAAAAPjAyRQAAAAA+JCia36qZcuWATMQSVrto+YHAKHbu3evZd2kukiRIrFYDgCchytTAAAAAOADJ1MAAAAA4EOqqfkBsTBv3rxYLwEAUgyd5nfxxRfHcCXxb8iQIQEzgPDiyhQAAAAA+MDJFAAAAAD4QM0PCIM33ngjYAYAJM8HH3wQ6yV4Onv2bKyXkKKkSZMm1ksAQsaVKQAAAADwgZMpAAAAAPCBkykAAAAA8IGTKQAAAADwgZMpAAAAAPCBaX74h99++83ynXfeaXn37t2W586d65xzrkKFCtFbGAAAABBHuDIFAAAAAD5wMgUAAAAAPlDzwz/Ur1/f8saNGwPe51z976+//orKmgAAAIB4w5UpAAAAAPCBkykAAAAA8IGaH5xzzm3bts3yzp07k7z/kSNHIrkcAABStP3791vesmWL5QULFlieNGmS5Ztvvtnyr7/+avns2bOW16xZY7lNmzaWn3jiiTCsOPW64447LH/55ZeW06RJY1l/Dnr7oUOHLI8dO9byyJEjLf/www9hW2uiadWqlWX9vi1fvtzy9ddfb7ldu3aWs2bNGuHVBYcrUwAAAADgAydTAAAAAOBDiq75bd++3fLs2bMtn9tw1jnnjh07Znnp0qWWCxUqZPmyyy6zfO+991q+/fbbLefJkycMK46devXqWdZNe+FNaxZvv/225TFjxiT5tfqcGj9+vGU2QQaA1KdLly6Wtdqnvvnmm4C3e9XLnnnmmYDH14m9HTp0CH2xqUTBggUtv/POO5b//PNPy40bN7ZcokQJy6VLl7Zct25dy/ozadSokeXnn3/e8tChQ5Oz7IQzYMAAy/r8VfrcX7lypWX9vJUjR44IrC44XJkCAAAAAB84mQIAAAAAH1JEzU8v82llauHChZYPHDhg2esyotq0aZPlRYsWWZ44caLl7777znKi1/yCqfalS5fOcsuWLSO5nLjVv39/y1qPOHz4sOVs2bJZ1jrfqVOnLK9evdpyrVq1LP/yyy8BjwMASHw//vij5bZt21r2qvCpiy66yHKWLFksnzlzxnLatP/9b+T6pw4bN260/MEHH1g+ePCg5RYtWlguVqxYkutJ6UqWLGm5VKlSlnPmzGn577//TvI4zZo1s1yzZk3Lw4cPtzxw4EDLOi1Zp/+lVD///LNlneCXPn16yw0bNrQ8Y8YMyzq9snLlypFaYpK4MgUAAAAAPnAyBQAAAAA+JFTNb9++fZY7d+5sedCgQZa1SqUyZsxoOVeuXJZvu+02y+PGjUtyDTr977333rPct2/fJL823nz11VeWdfNApZUB3VitR48ekVtYnHnttdcs679bn2vly5e3rJP9dOLjnj17LBctWtSybtZYtWpVy6+++qrlRx55xLI+l5E6aa108+bNlnWClFabJ0+ebFmnemn1R6srjz32mOXMmTNb1qqFVpv1NbVnz56WdYrq66+/bll/LyJp2LBhlv/666+A9/noo48sa/3Wi1el6uWXX7b80ksvWU70CjjCSyfBeVX7dHPehx9+2PJ9991nWd9DvGidr2nTppa3bt1quU+fPpb1vUU/YwXzpxEpkdbua9SoYTmYap/Sz40TJkywrH8G0LVrV8v6mSM11Pz0fUuzatKkiWX97DVkyBDL1PwAAAAAIMFwMgUAAAAAPsR9zU8vj1arVs3yihUrLOslaJ2UUq5cOcv333+/Za1kLV682HIwNT+lx0lEvXr1snz06NGA99FpQ3oZOjUZMWKEZb28XLt2bctaNfWq9eTLl8/yt99+a7lfv36WP/30U8sNGjSwrM/3bt26Bb12pBxaLXnqqacs6wafN910k2WtE+kG00pfO7Xqq9UJ1bt3b8s6WUw3t9TNz5X+vuh9wj01TKc7derUyfKuXbuS/Npg6kxa7dP7d+/e3fK8efMsT5kyxXKBAgWSPH68+emnnyzPnDkzLMf8/fffLWtdPlwyZMhgOdRKVqRpXUzfT3RSsNa6k+Ppp58OmG+99VbLWjXUirr+Tj/33HNhWU+i0T8t0d/pcKlQoULA27VyjX/n9ac90caVKQAAAADwgZMpAAAAAPAh7mt+77//vmWtOimtcugUFC/ff/+9Za0Fnj17NmBW99xzj+UnnngiyceKN7oBsU7aUjpp66233or4muKRbnaoOXv27Ja19hjqxC6tiI4aNcryl19+aVkrru+8845lan6pk04M1WqfWrBggeW6detaDqaiMnjw4IC36+vlF198YVl/L/744w/LWn3TrBteFy5cOMn1+KUVqWCqfV60Jr5s2bKAt+sGk0o3ZtX1tGvXzrK+l8SKvh9Ur17d8unTpy3r9EK9PVwiMSkuEafPhavaFwytnmq9UCf+6Xu/1t10s/pEVKlSJefc+b+7J06ciOhjFilSxLJOnNPPnyq1/knF/9Jps151vhIlSkRrOf+KK1MAAAAA4AMnUwAAAADgQ1zW/FauXGlZLzXrpfs6depY1s1kvcyaNcuyTknTCVbFixe3/OyzzwY8TiJW+06ePGlZN531qmzoZXydXJWa6IbG+rzTDUw1J4duZqoT2PRxtX6B1Gnq1KlJ3kcrJDolUidJeunYsWPA27UOozU/deGFF1rWTYF1U0rdcDSS3njjDcvjx4+33KxZM8vB1Azz5s1rWX8vvW5v0aKF5a+//tryd999Z1k387322mst62TEaLruuuss6/uBvmckh9ab9Ji6OXlyKp9ahdYNmrW2pVMWdTptapYjRw7L+nt59913W9bPTFq30p9j+vTpI7XEsNLn4bk/b9Cacq1atSyvWrXK9+OkS5fOstaBp02bZlm/96px48aWU8NGvcHInz+/Za/PojoZNJZS5ydlAAAAAEgmTqYAAAAAwIe4rPlpDW/Pnj2Wr776asu6SWrWrFkDHkcnoL366quWtT6lm1xOnz7dcrZs2UJddtzSyTBeVaEXXnjBcsWKFSO+pninU3a0zqfPx/nz51vWyWleDh8+bFnrJu+++65lfW4+88wzlvW5jJRt7969lrXmvGTJkoD318rzwIEDLefOnTss6wnmua21lAcffDAsj+uXbg6sOTm8pnXq7R9//LHlxx57zPLcuXMtr1+/3rL+3D755BPLhQoVSt5i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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "order(model, data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Train the Model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since this is a [supervised learning](https://machinelearningmastery.com/supervised-and-unsupervised-machine-learning-algorithms) problem, we will use the simple ``SupervisedTrainer`` class." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# Track the accuracy of classification as well\n", "trainer = SupervisedTrainer(model, metrics='accuracy')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Callbacks breathe life into MagNet's training process.\n", "\n", "Callbacks allow you to add additional features to the trainer." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# This callback tracks metrics (loss, accuracy) on a held-out validation set\n", "validate_callback = callbacks.Validate(data(batch_size=64, mode='val'),\n", " SupervisedTrainer.validate)\n", "\n", "# This callback logs the metrics and adds a nice progress bar\n", "monitor_callback = callbacks.Monitor()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Train for an epoch with batch size $64$" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "scrolled": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=750), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r" ] } ], "source": [ "trainer.train(data(batch_size=64, shuffle=True),\n", " callbacks=[validate_callback, monitor_callback])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Take a look at the Monitor callback to see how training went" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "scrolled": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/vaisakh/magnet/magnet/utils/statistical.py:122: RuntimeWarning: window_fraction (0.3) too low for order (3) and length (9) of data\n", "Returning raw data\n", " RuntimeWarning)\n" ] }, { "data": { "image/png": "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NA1ln90b37q7wcRCF+PzHYVmYkuD9E1coXP0/l3okLeEiC9HPFhFOlRHzF+OyaTI93HplRMREREREXmM2axOymLHKYsd3xvL5/MsrI4xNtfO5EI300u7u9AzzT9VCx3xZe+7F1q70L8YhWUREREREZF9xjAMQt4SQt4SGrO/uje+dXeDiflOxhc6P9iFnrxC5+ibe49xO0KEvaVEfTnigWpS4fd3oc1FWMnjS2FZRERERETkgLBZnZTFT1AWP7E3ls/nWVwdZ2y+UAs9s9TP7PLQfbvQZpOVoCd9Xy10OnwEl91frKUUncKyiIiIiIjIAWYYBkFvmqD3Z9VCdzI+/8EudP/k1ftqoT/YhS4v1EKH64n6codiF1phWURERERE5BAq1EKfoCx2/y70wuooY3MdTC50Mb3U/9O10GY7QXeKsK+MeKCSZLCWdLgep91XrKU8EgrLIiIiIiIiArxfC11KyFt6Xy30na01xhc6mJjvYmqxl9nlQfomLt9XC+1xRAj7MoVmYoFq0uF6wr6yIqzi4VBYFhERERERkZ/LbnOTi58mFz+9N5bP55lfGWFsro3JxW6mF/uZWxliaPoW798LbTU7CLhT+CwVVFX9D0Wa/cejsCwiIiIiIiIfmWEYhH0Zwr4MR/nC3vjm1jJjcx1MLHQytdjL9OIAG3fnijjTj0dhWURERERERB4ah81HRfIcFclzAKyvr9PT01PkWX10pmJPQERERERERORxo7AsIiIiIiIi8gCFZREREREREZEHKCyLiIiIiIiIPEBhWUREREREROQBCssiIiIiIiIiD1BYFhEREREREXmAwrKIiIiIiIjIAxSWRURERERERB6gsCwiIiIiIiLyAIVlERERERERkQcoLIuIiIiIiIg8QGFZRERERERE5AEKyyIiIiIiIiIPUFgWEREREREReYDCsoiIiIiIiMgDFJZFREREREREHqCwLCIiIiIiIvIAhWURERERERGRBygsi4iIiIiIiDxAYVlERERERETkAQrLIiIiIiIiIg+wFHsCUhxbd+8CMDk1U+SZ3G9zc5OZuQWc7kkcDkexp3Oo6LUvHr32xaPXvnj02heXXv/i0WtfPHrti+dxfe3fz0LvZ6MHKSwfUvPziwB8+7t/W+SZiIiIiIiIFM/8/CLkyn5q3Mjn8/kizEeKbHlllc7uPkLBADabtdjT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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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IyIiIiIirqMeWakXb289MiIiIiIi4lqqSkRERERERMSjqJAVERERERERj6JCVkRERERERDyKClkRERERERHxKCpkRURERERExKOokBURERERERGPokJWREREREREPIoKWREREREREfEoKmRFRERERETEo6iQFREREREREY+iQlZEREREREQ8igpZERERERER8SgqZEVERERERMSjqJAVERERERERj6JCVkRERERERDyKClkRERERERHxKCpkRURERERExKOokBURERERERGPokJWREREREREPIoKWREREREREfEoKmRFRERERETEoxhdHYDUZC4vByAtPdPFkVRnMpnIzM4lICgNf39/V4fToij3rqX8u45y7zrKveso966j3LuOcu867pr7ylqosjb6Xypk3VBOTh4AH81Z6OJIREREREREXCcnJw8S29fY7mW32+0uiEfOoKCwiH0HDhMRHoavr4+rwxEREREREWlSZnM5Obl5dOvaiVYhwTXaVciKiIiIiIiIR9FkTyIiIiIiIuJRVMiKiIiIiIiIR1EhKyIiIiIiIh5FhayIiIiIiIh4FC2/04KZzWbmzvmCJUuWk5aWTnBQEBf27cPMmTcRFx9b5/Ps33+QzZu2sm/vfvbu3UdWVjYAK1ctaqzQPZ4zcm8ymdi0aSvr125g587dpKWnY/D2Jja2HRePGMY106YSGBjQyHfieZz13H/26Vz27N7L0V+PkZebT3l5ORGREfTp04trr7uaxMQOjXULHstZuXd03ttn3k1ycgreBm+Wr/ivE6NuPpyV//v+MJsd25Nqbf/r3x7i0ksvcULEzYezn/2CggLmzlnAurXrSUtLx2AwEN06mj69e3HHnbfps/83nJH7bdt2MOu+B8+634TLxvLnvzxwriE3G8587vfs2cfcOV+wa+ce8vPz8Q/wp1PHRCZMHMf48WPw8vJqpLvwTM7M/bFfk/nk48/ZunUHhYWFRERGMHjwAG659UbCwkIb6Q7qRrMWt1Bms5kH/vgXdibtJjIygl69epCWls7evfsJCAjg5Vef57zzutTpXI88/Dhr16yvsV2FrGPOyv333/+Xfz33MgDt2yeQ2LE9xcUl7N61l5KSEhIS4nnltX8RHh7W2LfkMZz53I8ZPQlvL286dkokKjISgKNHfyU19Tg+Pj48+Y/HGDR4QGPejkdxZu7/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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "monitor_callback" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test the Model's Performance" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1MAAAHJCAYAAABg2mOQAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3XmgjHX///EPx75vWbIkbVJCopvSchPRQqhIiKyFaEFIQrlFhQpRCCllX4pSKhKJVIqUkihL2ff190c/716+5urMXGbmzPJ8/PVqXGfOx5gzM1fX67w/6U6ePHnSAQAAAABCkj6tFwAAAAAA8YiTKQAAAADwgZMpAAAAAPCBkykAAAAA8IGTKQAAAADwgZMpAAAAAPCBkykAAAAA8CFDWi8AABDfTp486T768GP37rvz3Y/rfnIHDx5y+fLncxUrVnCN77nTFS9e7IyvOXz4iFv6+TK3bNmXbu2aH9zvf/zhjh877vLmzeMuu+xSd3u9W12FCuU8v+fP639xo14Z4775ZrU7ceK4K33pJe7+Vve5smUv8/yafn0HuIUffeqGjxzqSpe+OCx/dwBAckvHpr0AAL+OHj3qnurzjFu8aIlzzrmUlBSXLVtWt3fvPuecc5kzZ3a9n3zcXXNtldO+7pGHu7sVX35l/50xU0aXkpLiDh08ZLc1aFjPdezU/ozv+dtvm1zb1h3dgQMHXEpKikufkt4dPXLUZcyY0T33wv/cFVdcfsbXrFyxyj3cpZurW+9W1+XhjmH5uwMAQM0PAODbqFfGuMWLlriUlBTXsVN79+686W723Knu7SkT3XXXX+sOHz7s+j41wG3e/PtpX3fs2HFXrFhR1659K/f6hNHugwVz3Lz5M90bb451N9xYzTnn3NQpM9yM6bPP+J7jxk5wBw4ccDfXvsm9O2+6e2/eDNe48Z3u6NGjbtQrY844/ujRo27ICy+5PHlyu1at74vI4wAASE6cTAEAfNm5c5ed7DRq3NA1aFjPZc6c2TnnXMGC57jeT/ZwxYsXc4cPH3ZjXxt/2te2bn2fe33CaNeo8Z3uvPNK2O1Fi57rnuzT0115ZXnnnHOT35pyxvdduWKVS5+S3nXs1N5lzpzZZciQwd3fuoXLmy+v+/67Ne7QoUOnHT/5rSlu48bfXNv2rVzOnDnD+hgAAJIbJ1MAAF9Wrlzljh496pxzruGd9c/48wwZUtwd9W93zjn36aefuQMHDtqfXV72MpeSkhLwftOlS+dq1qrhnHPujz+2uD179pz257v37HG5c+d22bNnP+17FS5U0J04ccIqhqe+fuKEN13ZKy5zN998k8+/KQAAgXEyBQDwZeuWrc4553LkyOHy5s0T8JgS5xV3zjl35MgR9+23q4O+71y5/7mCdOLEidP+LHeuXG737t1u//79dtvx48fdlq3bXPr06V3OnDns9heHjnBHjx5zXbp0dOnSpQv6+wMAEAxOpgAAvpw6Ofm/Jzvq+PHjljf88mvQ9/31qm+dc87lzZfX5c6d+7Q/q3BleXfi+An34rAR7vDhI+7YsePutVdfdzt37HRlypR2WbJkcc4599niz92SJUtd/QZ1XakLzg/6ewMAECxGowMAfClUqKBzzrkDBw64bdu2u4IFzznjmF83bLT81187grrf7dv/dLNmznXOOXfzzTedcUWpefMm7vMly9y89z5wH7z/kU3zy5Ahg2vdpqVzzrnDhw+7F4eNcAUK5HctWjb19fcDACA1XJkCAPhSvkI5lyHD3/9PbvKbZw6KOHz4iJs6dab990H5nSkvx44dd/37DXQHDx50hQoVdE3ubXTGMeeVLOGGvfScq3z1VS5Tpkwufbr0rly5su655//nypUv65xzbvzrb7gtW7a6Bx5s47Jly+Z27tzlBjw9yN1+a0NX66bbXZeHuroffvjR718dAADnHFemAAA+5cuX1912ex03fdosN23aTJctezZ3e91bXN68edzP639xI0e86rZu2epSUlLc8ePHXbr0qf/O0rChL7uvV33jMmbM6Hr17u5y5Mge8LiLLrrAPTvo6YB/9uuvG93bk6e5ildVcP+tfoM7fPiI69K5q9vwy6/uyorlXe7cud3iRUtc506PuZGvDHPnlSwR8H4AAEgNJ1MAAN/atW/tft/8h1u2bLmbMH6SmzB+0ml/3vL+5m7a1Blu167dLkeOHB738rfRo8a4WTPnuvQp6V3PJ7q5smUv87WmoS+87Jxz7qHODzrnnJs75z234ZdfT9uw9/33P3TP9H/WvfbqONe3f29f3wcAAGp+AADfMmfO5AYM7Oue6N3dVal6tTu3aBF3btEi7ppr/uMGDX7G3dPkLrdv399T94oVK+p5PxPGT3JvTJzs0qVL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/rJ86623Wtbnnda2kDz0s0n37t2dc6e/35w8edKyvjbp7ddee63la665JuDxa9eutfzGG2+c7bIRR7gyBQAAAAA+cDIFAAAAAD4kTc2vWLFilu+77z7L5cuXt6yXcQsWLGhZp7VoPeihhx4K9zLjxql6n1Yje/fubXnZsmWWO3XqFL2FxYCPP/7Y8o033hjS1z755JOW+/TpE6YVpT2t0y5atMiy1vZq165teffu3SHdv/7svvzyy5ZvuummgLe3bNkypPtPBlqVnD9/fljus1WrVparVq1quVu3bmG5f6Sdxo0bW37zzTcj+r30ualVe60D6+ulVvvUDz/8EP7FISZNmDDBcpMmTSyfqu5pPU+tXLnSsk6D1el/WhfV+9H3IWp+yYUrUwAAAADgAydTAAAAAOBDwtX8ihYtalmrPJrPO++8kO5zxowZlpO52qeb8p6ajqPVPt2k7tFHH7W8devWKKwudoRa7VNPPfWU5RtuuCFgjkdbtmyx3KtXL8s//fST5VCrfUo3VNRa6cKFCy0XKVLE9/0nKt309PXXX7d8++23W/7iiy9Cus+mTZtafvHFFy0fPXrU8oIFC0K6T8QerypdJJyawOaccxkzZrT84IMPWh45cmTU1hMJuiF5165dAx6jv3Kgf98jR46EZQ36aw+ffPKJZd34WDe1jbWNafX1TKe36lS+U/mZZ56x26ZPn25548aNlv/880/LEydOtDx+/HjL1apVs8xG0OGlUxP137Nhw4aWc+XKZVl/VSDU962zxZUpAAAAAPCBkykAAAAA8CEhan46sWvgwIGW9ZK12r9/v2WdLHbzzTdHYHWJQyfYaL3vFK19LFmyJCprikVaKQiGTqHSmp/WBUO9z1imP6ORUKNGjYC3f/rppxH9vvFCqzA6ta9AgQKWdQPUYFSuXNmybti9a9cuy1qR/v7770O6f5xeb9MNR9WhQ4csHz58OKLr0U2zI0EnPuokyK+//tqyTluLR3nz5rXcv39/y+3bt0/1ax9//HHLWm9at26d5VBreF26dLGstUN9LsXye1H27Nkt689IoMl9+joVDH0stWaG8NJpyFrz018z8VKxYkXL1PwAAAAAIA5wMgUAAAAAPsR8zU83Qatevbrl+++/37JusJspUybLY8eOtayTwgYPHmxZNwP0qvl99dVXoS47YVxwwQWW582bd8af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AOADm/YCAdx5552W33rrrbDc5+rVqy3XrVvX8oYNG8Jy/wCQTDp16mS5Z8+elnWz0lq1aln++uuvo7MwAEmFK1MAAAAA4AMnUwAAAADgAzU/JLWrr77a8nXXXWe5V69elk+cOBGW73X55ZdbfvXVVy23a9fO8k8//RSW7wVEWvbs2S2PHz/ecokSJSxXqlQpqmtCYrrqqqsst23b1nLLli0ta7VPVatWzTI1P4RC37Pnz59v+dxzz7W8ZcsWy08//bTlESNGWD5+/HiklogYwZUpAAAAAPCBkykAAAAA8CGuan6NGze23LVrV8tXXHGF5ZSUlKiuKdHdcsstlufMmWO5Xr16zjnnZs6cGfU1na3SpUtbHj16tOVLL700amu4/vrrA66Hmt+ZLr74YssPPvig5SuvvDLg8T///LPl4cOHW162bFkEVpe87rjjDss6nfKrr75Ki+UgwdSuXdvy2LFjLRcoUCAtloMkkSHDPx+Ln3/+ecuFCxe2rNX/ggULWh46dKjlvXv3Wn799dfDvs5EcujQIcsPPPCA5VmzZln+8ssvLZcsWTIq6woFV6YAAAAAwAdOpgAAAADAh5iv+elGfJozZcpk2WuKD87ehRdeaFkf527dujnn4rPmlz9/fsvRrPZ50UloF1xwgeWdO3emxXJiwqBBgyzfd999lvPly2dZH5906dJZrlq1quWiRYtarlGjRriXmdS05qePf6Jr3bq1ZX0+qokTJ1revHlzqvepr0mtWrUKaT06KWzw4MEhfW2s0fqzPoa5c+cO6X62b99u+dNPPz37hSFpVK5c2XL16tUDHrN06VLLffv2tfzMM89Y7t+/v+XPPvvMMlX+M2m1Tz8Pqdtuu82yPp65cuWK3MJCwJUpAAAAAPCBkykAAAAA8CEma37du3e37FXt++KLLyzrBBX9Wr0sqHbt2mW5X79+lvXSLf5djhw50noJvm3dutWyTojRjSGjKWfOnJaTqS7lnHPFihWzPHv2bMvlypWz/MMPP1h+7LHHLH/44YeWM2fObFl/jsuUKRO+xeK01+NTEz2dO70CrFWXeKabbt57772Ws2XLZtnr57V3796WQ930WzdDDtVNN91kuVatWr7vJ6189NFHloOp7+smvDVr1rT8559/hndhEdKhQwfLw4YNs6zPqx9//NHyokWLLC9evNjy8uXLLesmsl527Nhh2auqqtPrKlSoYPmtt96yfPTo0VS/VyLSKX+6ma/WAvU9LFzVvmuvvdayPsfXrl0blvuPJq326bRDr9fUNWvWWJ4+fbrl5s2bR2B1oePKFAAAAAD4wMkUAAAAAPgQkzW/p59+2rLXpX6dYNSnTx/LusFnMDUBrUJMmzbNstYFdRPQZFOlSpWAty9ZsiTKKwkfveSu/+ZpVfNLZo0aNbKsm2+3b9/esm7YeeTIkYD3065dO8t58+a1/MYbb4RlncnsvPPOs9ypUyfLWscYNWqUZa1gxAOt4+jG5Oeee67lUOu3WbNm9b0era+uW7fOstZgtdalDhw44Pv7RpNuuqk1qWB8//33luOx2qd0cplu/tq5c2fLOuFVs0451ednMJ979PlTqVKlVI/X+0+f/p//B5+Im9FqdTRUmzZtsvz777/7vp/bb7/d8kMPPWRZ3yPvuusuy/FS81u9erXlN9980/f96K9nUPMDAAAAgDjGyRQAAAAA+BAzNb+6deuGdLxX/UytWrXKsm7cp7UV/b4NGjSwrDXCxo0bh7S2RKK1STV16tQoryTtHDp0yHKvXr0sz507N+DxOqVG62c6cQ5/001GQ91wVGtYOuVv3759lrUCnAx0I12dfnQ2NRCdXKWby+rGqKNHj/Z9/2lB6zIffPCB5QIFCqT6tb/88ovlhQsX+l6DVlB1quWUKVMsHzx40Pf9xxqdUti1a1fLWl1T+/fvt/zkk09a1hppPFb71J49eyzrBMiZM2cGPP6///2vZX0Oa22ybNmylnVSrNKNaYOpBapY2Og+WvS9P0uWLJavvPJKy/pZSCcyBkOnb+pnC/031Fql1v/i5Vct9DWsS5culvfu3ZsWy4kYrkwBAAAAgA+cTAEAAACAD2la89ONEHUqjF7W9NrwUC8Rvvrqq5YfffTRsKxt48aNlrt162ZZKwkjR460vHLlyrB831ig09Dy5MljefPmzZYTcYNj/Ttt27bNsm4k+fLLL6d6Pw8//LBlnRB4zTXXnO0Sk16JEiUsz5s3z/L5559v+cEHH7ScDJM49TmmFbG//vor4DH62ublnHPOsazVQa0EPfHEE5bj7fVPX9O9qn3r16+3fOedd1rW10GtOuJM119/vWWdUHfbbbel+rVazR8yZEh4FxbjVqxYEdLtKnfu3JYzZAjtI57WyPRzlU5RnTRpUkj3GW+0XqrvJa+99prlatWqWdZNj3Uz5IwZM1rWqZP169e33LRpU8spKSkB16PTK7VifOzYsX/5W8QO/ayun6WUvr7++uuvlr/44ouAx+vjHyu4MgUAAAAAPnAyBQAAAAA+RL3mp9Og2rZta1nrI1rt040KBw0aZFk3+wxXtU/17dvXsk5o0Sl/Ov1P/17xTh9bnRKk/xaJMonlk08+sawb+GrFJ5p0EmD//v3TZA2xRidK6uSkSy65xHLPnj0tx9tkubP1+OOPW9bX0VCndGm179133031PvXnJR5oZcdrQqtOUZs8ebJlrZ7s3LkzAqtLTLohslbIvGjFX2uBCN7u3btDOl6rgC1atLCsG/VOnDjR8jfffHMWq0sMWpsuVaqU5SZNmgTMwWyMrHSyrX7+1IpxvNDXVK/Nz/Xv+/nnn1vW12l9LalTp044lxgWXJkCAAAAAB84mXzeaf0AACAASURBVAIAAAAAH6Je83vxxRctB7Px7rPPPmtZNyn77LPPwruw/0MvlWfKlCngMVmzZo3oGtKK1qcSnde0mLSiE6ySmW7Iu2zZMsu5cuWyvGDBAsvjxo2zHC9TjkKlm43rRrpe0/a0HhLMBL+KFSta1k0ptZrRrFkzy8FsmKrVwTZt2lh++umnU/3acNNNUb20atXKsk5DRPB0yqNWK4OpnerPcTDP2WCUKVPGsv4M6STGL7/8MizfKx6VL1/esk6c1X8v/XdJJvqaqDJnzmxZ34f0M6HXJEWdjKi/TqLTE7VKHO/vZ14bUGv1UTct96JTKnPkyHH2CwszrkwBAAAAgA+cTAEAAACAD1Gp+f3nP/+xXKNGjVSPnzt3ruWvvvoqImtC6D788MO0XkJcGDhwoGWtTeikKi+rV6+OyJpildYldJLUiBEjLGvd5KWXXrLcqVOnCK8utowfP96yVx1HN3gMpkpXunRpy7pxut7n9OnTA2YvXlMB16xZk+rXRtKePXss6xqVvj/pND/8u6JFi1q+7777LHttiKxVJ52UqK+dR48eDWkNOnm2Q4cOlrUGq8foxuz62qObgScq3VC2e/fuAY955513LC9evDjia4oV+p508803p3p8zpw5A96uk/fGjBljWZ9fS5cu9bPEmKcT+bw26u3Ro0fA2/XXf7we21jElSkAAAAA8CEqV6aKFy9uOV++fKke/9xzz1k+ePBgRNaE0+XJk8ey/pK5Pv56xRCn/7J63rx5LeseFLpnmvK6PRnoL+m+9tprlu+++27LemXklVdesaz7SSWD5cuXW9ZfhtbHZ+XKlZZD3c9E98rTqzV6/7169bJ84MABy/rL/NWqVbOs/8dR998LdW3hplf2nnrqqYDHXHvttZZnzJhh+fDhw5FbWAJo2rSpZX1eeNGrUZdeeqnv7zt06FDL9957r2X9ZXUv+nx/4YUXLCfDlSkdMqVX7nbs2GG5X79+UV1TrNDXBt1DKhi//PKLZb3KvWHDhrNeVzzZtGmTZb0KrYOlvN4PDh06ZFk/J/3xxx+W9XkazDlFNHBlCgAAAAB84GQKAAAAAHyISs1P9ynR7OWTTz6J5HJC5rXmRx55JMoriRz9RUut/OkvEq5fvz6qa4pFHTt2tKx7RJzNvgc6KGDfvn2+7ydenH/++Zbr1KmT6vG6P9ENN9xgWQca6H50Wo07fvy432XGBP076t5PWsPTIRL6dx89enTA+9R6k/7yud6nZq0C1qtXz3KJEiUsa51P92eqXbt2wDWkhd9++82y/v309V33RdL9d3QfoqlTp1rWvbbWrl0bvsXGAf23DWbYiVb7tFoWjLp161ru3LmzZX09CKY6rUOA9PhghgMlEn291Of/N998Y/m7776L6pqiTYeRzJ4923IwtVOtO2fLls2y7n+abNU+recNHjzYsr7W6v6IhQsXDng/+jlTf81Eq4O6Dxc1PwAAAACIY5xMAQAAAIAPUan56TQoveSnYmFyzMUXX2z5mWeesaxr1trbDz/8EJ2FRcE999wT8PYvvvgiyiuJDRdeeKFlrZj06dPHcpYsWUK6z2XLllm+9dZbLWu1TyffJCrdC0mrVLVq1bJctWpVyw0bNrSsP6OatX7Wu3dvy/379w/DitOOTtbU1xudJKnT07QKOHLkSMtetTav25W+NmudS2tz06ZNs6zVt1gybtw4y/r80sdS6V5emh966CHL27dvtxzqnohvvPGGZZ2UqpOq4oXX+7pq3LixZa9KpFavtF765JNPWtZalVb1glmD1/Fa2U5U+p6mtX6dVKk1rER1qp78wQcf2G1eU/v2799v+YknnrCskyP1NTeZabVvxYoVlnXS8fXXX5/q/eg+XykpKZZ1+t8FF1zge52RwpUpAAAAAPCBkykAAAAA8CFiNT+9pK+Xl5VeXo6FSUi6WZ9Oqtq7d69lrRAtXLgwOgtLQ7t27UrrJUTUFVdcYVk3RdVNHLNnzx6W7zVr1izLoVZ5dDPRiy66KKSvHTt2bEjHR5NOPNLNeTU3b97csm7427VrV8s68U8rO/qY66SqeKQVO3189HmrdUel09O8NufVep7W9nQqoL5O60SreKPTzObMmWN54sSJlrXiU6hQoYD3o49lzZo1LXtVKZUer+89TZo0saxTq+Kd1vP0NVUf5xYtWliO9Abd7733nuX58+dH9HvFguHDhwe8XSdVat00kbRr187yqeeVbiCrunXrZlmn/GkFtVy5cpb1dfPll18+67XGqy1btgS8XSvV+nrpRavTR48etVy5cuWzWF3kcWUKAAAAAHzgZAoAAAAAfIhYzU8rOJkyZQp4zI8//mh58uTJkVrKGXSDyUaNGlnWqVhLliyxnKjVPq1M6d9dJx5Nnz49qmuKBq2djho1yrLWpSL9fb02VPWi08QSqeYXKt3Eb8KECZb19UZrQ7qRYCLRaolWlDRrleq6666zXLBgQcuLFi2yrBugJrqffvopYG7atKllnZ5YtmzZgPejGyZ7TUTV11mtjyudrqYbWevEv1hTv379kI7X6Wlan9LNfHVT9GCm84Xq008/tawT2Xbv3h327xUL9D1Hq+I6NTYWJilHglbKHnvsMcun6n1bt2612zp16mRZK876WUgnz+qUuZ9//tlysk4//jdXXXVVqsesW7fO8ttvv205Y8aMlmNpA/hAuDIFAAAAAD5wMgUAAAAAPkSs5qdT0rwu10dzQ02dxKJTfLwqU5s2bbKcSNU+pZueao1lyJAhluN9AlogCxYssFy0aNGofV+dVKX1AQRP62o60U6rVGPGjLGs9YFkoxP8LrnkEsv6epyINd6zMXPmzIC3BzNt1qsuVbx4ccsffvihZa1g/fHHH5Y/++yzVL9XLNCJhV4bPnu5/fbbA96ePv0//383mNdIPf6XX36xrNXmRK2xBUP/7rrJvG4g//7770d1TdGitWX9/HeK/ixOmTIl1fvTz7Q40+rVqwPerr9K42XYsGGW9T1Jq5rBbPiblrgyBQAAAAA+cDIFAAAAAD5ErOYX6uX6cOnSpYtlvSzbrFmzVL9W16xTfxKVbk6ndCPVRKR/v2jW/OCPTlkcP368Za1PvfPOO5YfeOCB6Cwsxum0Q30NXrlypeVYnhaX1nQaYp48eQIeo9Mi//rrL8taT9Hnr9cG9nv27LEcL6+/OgFNNyFv0KCBZZ0SGwx9ngYzzU83XH788ccte1WOksFll11m+dZbb7Wsj2erVq2iuqa0sGvXLsv6axunpvnp1DgvOq1TJ30ePnzYcp8+fc5mmQnjk08+sayfpfPmzRvweJ2iql+rz9MePXqEc4kRxZUpAAAAAPCBkykAAAAA8CFiNb9QL9efDd1MbfDgwQG/r9caVq1aZblu3bqWt2zZEs4lxiSvjSgTfQJakyZNLI8YMcJyrG8Kl+hO1S+cc65NmzaWdcNFndqn1T6t+OiGlMlGJ/h5vQbrRr26+S9OpzVS3WT2/PPPt7xx40bLumFyvXr1LBcqVCjg/R8/ftxyMNPEYs2BAwcs66bZe/futayVW60+hurrr7+2rNUffczxt0cffdRytmzZLH///feWv/vuu6iuKS18+eWXlnUj91P0c+O3335rOVOmTJYnT55sWX8lQB8/3Yw6mWm1z2u657Zt2yxXr17dstYwdWpfu3btwrnEiOLKFAAAAAD4wMkUAAAAAPgQsZrfr7/+arlEiRJhv//KlStbnjp1aqrHa/VAp9hpfUM3TkxUWrXwmlC1ZMmSaC0nTWzevNly+/btLWutR6dQ6aZzAwcOtKwVQb2fs6Hfd+LEib7vJ5Yn2mlVTydu6kabOkVJKxpPPPGE5UGDBllO5mqfqlatmmWviao//PBDVNcUr3SjXt3cXV8DOnToYLlt27ap3qf+OwwYMMBy7969fa8z1uhGsbNmzbKsE+SCeb3UWlr9+vUt62cL/C1z5syW9bORiscq6dnYuXOnZa3jntrAXKfwBTORTyeftm7d2nI0p1XHshYtWlgeN26c5bvvvtuy1nV3795tWc8Rhg8fbjljxozhXmbEcGUKAAAAAHzgZAoAAAAAfIhYzU8rDC+99JLllJQUy7lz5w7pPkuWLGn59ddft1ykSBHLOhXkq6++sjx06FDLCxcuDOn7JpLt27db1k3tvvnmG8v79u2L6prSklb+NC9dutSyTvRRFSpUCPt6gvm+8W7UqFGW77nnnoDH6M+u1gf0eYozTZs2zfJDDz0U8PZgatHwpjXx0aNHW9ZJil50SqxuqpyotNbTsWPHgBlnTyfRXnrppQGP0c9hyaZ///6WT004vOaaawIee+zYMct33XWX5ffff9+ybtqLv2XJkiXg7Z9++mnA2ytVqmRZf6XhggsuCO/CooQrUwAAAADgAydTAAAAAOBDxGp+Wn/QDSNz5Mjh+z43bNhgWTem00lLQ4YM8X3/yWz69OmWmU6DSCpVqpRlndil0/nGjx8f1TUlisWLF1vWSjUi46effrKsz18gmpo3b25ZP2/pZrR79uyJ6ppiib4uXnfddWm4ksSlE4R1iufvv/9uuWbNmpbHjBljuXDhwhFeXeRxZQoAAAAAfOBkCgAAAAB8iFjNT7366qthv8+5c+eG/T6TTdmyZdN6CUhCXlOUAADho78acfTo0bRbCBJemTJlLOsmycmCK1MAAAAA4AMnUwAAAADgQ1RqfgAAAIgeNugGooMrUwAAAADgAydTAAAAAOADNT8AAIA4dccdd6T1EoCkxpUpAAAAAPCBkykAAAAA8IGaHwAAAJBA0qVLl9ZLSBjnFCzs7mza2vPPuTIFAAAAAD5wMgUAAAAAPnAyBQAAAAA+cDIFAAAAAD5wMgUAAAAAPjDNDwAApIn8+fNb7tu3r+X69etbfu+99yy3bNkyOgsDgCBxZQoAAAAAfOBkCgAAAAB8oOYHAACiJn36f/4/7ksvvWT5rrvuCnj8t99+G/E1AYBfXJkCAAAAAB84mQIAAAAAH2Km5qeX/atUqWL57rvvtrxu3TrLL774omWdAKT5+PHjYV8nkps+T6+88krLTZo0sVy+fHnLv/zyi+XmzZtb/u677yx/+OGHAb/X5MmTLS9fvtwyz2sA8ezRRx+17FXtU9T8AMQyrkwBAAAAgA+cTAEAAACADzFT89M6X//+/S2XLFky4PE7duywfOutt1rOmTOn5TJlyljWytT27dstr1ixwvIff/wR4qoT06uvvmr5iiuusHzHHXdY3rx5c1TXFA2ZMmWyXK1aNcsXX3yx5Tp16liuXbt2qvd53XXXWT558qRlfW5qVh07drRcuXJlyytXrkz1+yaDLl26BLxdH7fzzjsv4DFa1/zqq68sP/vss5bfeuuts11i1Onr5WeffWa5cOHClrVi9cILL4R9DRky/PO20qpVK8tffvml5VWrVlk+duxY2NeA2NOzZ0/LTz75ZMBjfvzxR8vdunWzvGDBgsgtDAkvX758lk9VRs8991y7Td+bvbzyyiuWH3nkEcsHDhwIxxIR57gyBQAAAAA+cDIFAAAAAD6kac3v5ptvtqx1kxkzZlj+4IMPLGslr3Tp0pZHjx5tWSs+WuW56aabAq5BKz61atWy/Ndff6X+F0hQ+phcfvnlluvVq2f55ZdfjuqaouHzzz+3XK5cuTRcyZm0YplINT+dfFisWDHLXbt2texV1dPjvWoaXrefOHHCslZZx4wZY/n888+3PGDAgID3E2u0zleoUCHL+jjMnTs3omvQap9uyKq0jrhp06aIrgdpRyvS/fr1s+z1c6nVvpkzZ0ZuYUkiXbp0lp966inL9913n2X9WdTXxUSivxYyadIk59zpVT2tGr/22muW9XNmy5YtLeuvlujr3fz588O04sSUkpJiWR//mjVrWr7kkkssZ82a1fKQIUMsDxo0yPLhw4fDvk4/uDIFAAAAAD5wMgUAAAAAPqRpze/OO++0nD17dsutW7e2PGHCBMsbNmwImIsXL275qquusqyXYu+//37LOsWlQoUKlrW6ppuwJtsmqfo4XHvttZZ1k9pEpLWSIkWKBDxGN8/VutTEiRN9f1+ttPXq1SvgMVqHi2X58+e3rBtre1X1tGKSN29eyzpZMVSrV6+2vHfv3lSPr1ixYsDv26ZNG8uxXPPLli2bZZ3Up958803Luvl5JOjESyS3Bg0aWNbKmdL6+KxZsyK+pmTSu3dvy/reMnToUMta7dPXYH2/1/e9PXv2hH2d0fT4448755z77bff7DatkF199dWW9fOkTt3VOvjs2bMt65RK/RwVj4+ZVvJC/QycO3duy/qe1LBhQ8taAd66davlbdu2BTymb9++li+88ELL7du3t3zw4MGQ1hlOXJkCAAAAAB84mQIAAAAAH6Je86tRo4ZlvbyvVRWdiKKVnWDoxpCadcO1kSNHWtYqoNYOp02bZvntt98OaQ2JSjc7TkR6GVlzJBQsWNByMNNodJPTWDZ27FjLwdS9tPrjNeFLJ2vqBomLFi2yrPWghQsXBvxade+991oeMWJEquuMZVoT1ddU9e6770Z0DfoY3nLLLZb131TrhcHUL2OV1l/y5MljWavBWiuPtOeee86y1lx0glkwm5KGS6lSpSz36NEj4Br2799v+aefforOwpKE1vm0dqZVvY0bN1rWz0lly5a1nDFjRstHjx613K5dO8v6eh8vTk3u06pe9erVLd92222WX3/9dcs6AbFatWqWdWLpE088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W9aFr1qH2r59u2WtAc2bNy/CZxf/dDpV165dLev0OV00rTW/d955x/Krr75qWafgaK0yT548lmvUqOF4Pno7fletWjXLH3zwgWV9zF50Uer//UfrGJrTpUuX1lOMurZt21rOmDGjZX1e1MlJwdDn4EaNGll2ey7UqV6RrnLEgv5za549e3YsTicp6PTegQMHhv32x44da7l+/fqW463m5zYZLVb0NUotWLDAcqJU+5S+Butrrb4O5cyZ0/F7teY3Y8YMy0eOHAnnKcaNNm3aWNbq/KpVqxyPr169uuWUlBTL06ZNs6yTErVq+uWXX1oeMWKEZX3+GDlypGV9fxDtCYpcmQIAAAAAD/gwBQAAAAAeRKXmd9VVV1kuUaKE4zE6Oemee+6xnJalsNmyZbPcunXrVI/XJWvPPPOM558bb7ROed1111muWbOm4/GzZs2yPGzYsMidmE9ozUyn/uTLly+k29GqqWadYKVT5nRRov4O6SSsw4cPh3QO8UyXcjdu3Nhy5cqVLesl/VAnJBUrVsxylSpVLH/00Uch3U40aSVZKwz6710fD270eVeroW7VR61vaNX31KlTqf4sv9HXHq3s5M+f37JOhNNJcbly5XK8zWCmz/nd6tWrLbtN43WjS6H1Mai1XK08K63tuRkwYIBlfR/g5tNPP031mESi09l69epl2W0BqtatEt369est6yJznc7nJnPmzBE5p3iir0M63TVU11xzjWVdlq4yZMhgWSvm2bNnt/zoo49a3rhxo+fzSSuuTAEAAACAB3yYAgAAAAAPIlbz04rEDTfckOrxOjlp8+bNETmn1GzYsMHy+fPnY3IO4aLVCZ3aN2XKFMu6oFKX7ybqFJpQ3HnnnZa19hiJy/haa9Wsjh49alknUr377rthP5948NVXXzlmna6kU4Xq1q1rWesDSr+uU5cqVqxoOd6WIE+dOtWyLifs1KmTZbdznj9/vuW+ffta1imRbhYtWmRZ61yJSGt+Ws/r0aOH5e7du1vWCqRO8VRafxk8eHBYzjPe6LQsrc1efPHFqX6vPs/t2LHDslbyzp075/i9V199tWW3CZTB0PcczZo183w7fqGVKa2saeVcK8P6nKELhRNd6dKlLQdT7VP6OpSov/fhkpb3mS1atLCsk/30fay+h9fHfqRwZQoAAAAAPODDFAAAAAB4ELGan1ZqSpUq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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "model.eval()\n", "order(model, data)\n", "# Pretty-good for a second of training!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Take a look inside the model's _mind_ (it's weights)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "visualize_weights(model)" ] } ], "metadata": { "kernelspec": { "display_name": "Python [conda env:magnet]", "language": "python", "name": "conda-env-magnet-py" }, "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.6.6" } }, "nbformat": 4, "nbformat_minor": 2 } ================================================ FILE: Tutorials/MNIST-Quickstart/mnist_quickstart.py ================================================ import magnet as mag from magnet.utils.images import show_images import torch @mag.eval def order(model, data, c=10, n=5): x, y = next(iter(data(mode='val'))) channels, rows, cols = x.shape[1:] images = torch.zeros(n, c, channels, rows, cols) images_gathered = [0] * c correct = 0 dl = iter(data(shuffle=True, mode='val')) for i in range(len(dl)): x, y_true = next(dl) y = model(x)[0].max(0)[1].item() n_y = images_gathered[y] if n_y >= n: continue if y == y_true.item(): correct += 1 else: x *= -1 images[n_y, y] = x[0] images_gathered[y] += 1 show_images(images.view(-1, 1, rows, cols), pixel_range=(-1, 1), titles=f'{int(correct * 100 / (c * n))}%') def visualize_weights(model): show_images(model.layer.weight.view(10, -1, 28, 28), cmap='seismic') ================================================ FILE: arghandle/README.md ================================================ `arghandle` is a small tool used to separate handling of arguments in functions from function logic. Suppose you have a module `module.py` which defines an `add()` method for `int` or `float` numbers. In addition, `int` is converted to `float` Originally, you would write something as follows. ```python # module.py def add(x, y): for arg in (x, y): if not isinstance(arg, (int, float)): raise TypeError(f'Argument needs to be int or float.') if isinstance(x, int): x = float(x) if isinstance(y, int): y = float(y) return x + y ``` This pollutes the function because the main logic is obscured. `arghandle` allows you to do the following: * Create a separate module with the desired function in a folder called `__arghandle__`. Define your handling in that module. ```python # __arghandle__/module.py import arghandle from arghandle.handlers import typecheck def add(x, y): typecheck(x=x, y=y, include=(int, float)) if isinstance(x, int): x = float(x) if isinstance(y, int): y = float(y) return arghandle.args() ``` * Now, your main function can be written as follows with just the function logic. ```python # module.py from arghandle import arghandle @arghandle def add(x, y): return x + y ``` ================================================ FILE: arghandle/__init__.py ================================================ from arghandle.core import arghandle, args ================================================ FILE: arghandle/core.py ================================================ import inspect, importlib.util from pathlib import Path from functools import wraps def arghandle(fn): handler_fn = __get_handler(fn) @wraps(fn) def new_fn(*args, **kwargs): args, kwargs = handler_fn(*args, **kwargs) return fn(*args, **kwargs) return new_fn def args(): frame = inspect.currentframe().f_back fn = frame.f_globals[frame.f_code.co_name] arg_specs = inspect.getfullargspec(fn) local = frame.f_locals varargs = local[arg_specs.varargs] if arg_specs.varargs is not None else [] kwargs = local[arg_specs.varkw] if arg_specs.varkw is not None else {} if arg_specs.args is not None: kwargs.update({arg: local[arg] for arg in arg_specs.args}) return varargs, kwargs def __get_handler(fn): filepath = Path(inspect.getsourcefile(fn)) new_filepath = filepath.parent / '__arghandle__' / filepath.name spec = importlib.util.spec_from_file_location(filepath.name, new_filepath) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) handler_fn = getattr(module, fn.__name__) return handler_fn ================================================ FILE: arghandle/handlers.py ================================================ def checkif(arg, types, exclude=False, name=None): if name is None: name = 'One of the arguments' def error_message(): negation = 'NOT ' if exclude else '' got_type = type(arg).__name__ if len(types) > 1: arg_string = 'one of (' + ', '.join(str(t.__name__) for t in types) + ')' else: arg_string = str(types[0].__name__) return f'{name} should ' + negation + f'be ' + arg_string + f'. Got {got_type}' if not isinstance(types, (tuple, list)): types = (types, ) if None in types: if arg is None: return types = tuple(typ for typ in types if typ is not None) if exclude: if isinstance(arg, types): raise TypeError(error_message()) else: if not isinstance(arg, types): raise TypeError(error_message()) def typecheck(include=None, exclude=None, **kwargs): if len(kwargs) > 1: for k, v in kwargs.items(): typecheck(**{k: v}, include=include, exclude=exclude) return name, val = tuple(kwargs.items())[0] if include is not None: checkif(val, include, name=name) if exclude is not None: checkif(val, exclude, exclude=True, name=name) ================================================ FILE: docs/Makefile ================================================ # Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = MagNet SOURCEDIR = source BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ================================================ FILE: docs/make.bat ================================================ @ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=source set BUILDDIR=build set SPHINXPROJ=MagNet if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end popd ================================================ FILE: docs/requirements.txt ================================================ sphinx -e git://github.com/snide/sphinx_rtd_theme.git#egg=sphinx_rtd_theme sphinxcontrib.katex ================================================ FILE: docs/source/_static/css/magnet-theme.css ================================================ /* Use white for docs background */ .wy-side-nav-search { background-color: #fff; } .wy-nav-content-wrap, .wy-menu li.current > a { background-color: #fff; } @media screen and (min-width: 1400px) { .wy-nav-content-wrap { background-color: rgba(0, 0, 0, 0.0470588); } .wy-nav-content { background-color: #fff; } } /* Fixes for mobile */ .wy-nav-top { background-color: #fff; background-image: url('../img/logo.png'); background-repeat: no-repeat; background-position: center; padding: 0; margin: 0.4045em 0.809em; color: #333; } .wy-nav-top > a { display: none; } @media screen and (max-width: 768px) { .wy-side-nav-search>a img.logo { height: 60px; } } /* This is needed to ensure that logo above search scales properly */ .wy-side-nav-search a { display: block; } /* This ensures that multiple constructors will remain in separate lines. */ .rst-content dl:not(.docutils) dt { display: table; } /* Use our red for literals (it's very similar to the original color) */ .rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { color: #F05732; } .rst-content tt.xref, a .rst-content tt, .rst-content tt.xref, .rst-content code.xref, a .rst-content tt, a .rst-content code { color: #404040; } /* Change link colors (except for the menu) */ a { color: #F05732; } a:hover { color: #F05732; } a:visited { color: #D44D2C; } .wy-menu a { color: #b3b3b3; } .wy-menu a:hover { color: #b3b3b3; } /* Default footer text is quite big */ footer { font-size: 80%; } footer .rst-footer-buttons { font-size: 125%; /* revert footer settings - 1/80% = 125% */ } footer p { font-size: 100%; } /* For hidden headers that appear in TOC tree */ /* see http://stackoverflow.com/a/32363545/3343043 */ .rst-content .hidden-section { display: none; } nav .hidden-section { display: inherit; } .wy-side-nav-search>div.version { color: #000; } ================================================ FILE: docs/source/_templates/footer.html ================================================ {% extends "!footer.html" %} {% block extrafooter %}

Created my free logo at LogoMakr.com

{{ super() }} {% endblock %} ================================================ FILE: docs/source/conf.py ================================================ # -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # from pathlib import Path import sys sys.path.insert(0, str(Path(__file__).resolve().parents[2])) # -- Imports ----------------------------------------------------------------- import sphinx_rtd_theme from magnet.debug import Babysitter # Needed to avoid _tkinter imports import matplotlib matplotlib.use('agg') # -- Project information ----------------------------------------------------- project = 'MagNet' copyright = '2018, Vaisakh' author = 'Vaisakh' # The short X.Y version version = '' # The full version, including alpha/beta/rc tags release = '0.1' # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.napoleon', 'sphinx.ext.viewcode', 'sphinxcontrib.katex', ] # katex (mathjax replacement) macros # # katex_macros = r''' "\\op": "\\operatorname{{#1}}", "\\i": "\\mathrm{i}", "\\e": "\\mathrm{e}^{#1}", "\\w": "\\omega", "\\vec": "\\mathbf{#1}", "\\x": "\\vec{x}", "\\d": "\\operatorname{d}\\!{}", "\\dirac": "\\operatorname{\\delta}\\left(#1\\right)", "\\scalarprod": "\\left\\langle#1,#2\\right\\rangle", ''' # katex options # # katex_options = r''' delimiters : [ {left: "$$", right: "$$", display: true}, {left: "\\(", right: "\\)", display: true}, {left: "\\[", right: "\\]", display: true} ], strict : false ''' napoleon_use_ivar = True # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path . exclude_patterns = [] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # Disable docstring inheritance autodoc_inherit_docstrings = False autodoc_default_options = { 'member-order': 'bysource', } # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = { 'canonical_url': 'https://magnet-dl.readthedocs.io/en/latest/', 'collapse_navigation': False, 'display_version': True, 'logo_only': True, } html_logo = '_static/img/logo.png' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". hhtml_static_path = ['_static', '_images'] html_style_path = 'css/magnet-theme.css' html_context = { 'css_files': [ 'https://fonts.googleapis.com/css?family=Lato', '_static/css/magnet-theme.css', 'https://cdn.jsdelivr.net/npm/katex@0.10.0-beta/dist/katex.min.css', ], } # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = 'MagNetdoc' # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'MagNet.tex', 'MagNet Documentation', 'Vaisakh', 'manual'), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'magnet', 'MagNet Documentation', [author], 1) ] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'MagNet', 'MagNet Documentation', author, 'MagNet', 'One line description of project.', 'Miscellaneous'), ] # -- Extension configuration ------------------------------------------------- # -- Options for intersphinx extension --------------------------------------- # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('https://docs.python.org/', None), 'numpy': ('http://docs.scipy.org/doc/numpy/', None), 'torch': ('https://pytorch.org/docs/stable/', None), } ================================================ FILE: docs/source/data.rst ================================================ magnet.data =================================== Data ---- .. automodule:: magnet.data .. autoclass:: Data :members: __call__ Core Datasets ------------- .. automodule:: magnet.data.core .. autofunction:: MNIST Transforms ---------- .. automodule:: magnet.data.transforms :members: ================================================ FILE: docs/source/debug.rst ================================================ Debugging =================================== .. automodule:: magnet.debug :members: overfit, check_flow, Babysitter, shape :member-order: bysource ================================================ FILE: docs/source/index.rst ================================================ .. MagNet documentation master file, created by sphinx-quickstart on Thu Aug 23 10:42:23 2018. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. :github_url: https://github.com/svaisakh/magnet Welcome to MagNet's documentation! ================================== .. toctree:: :maxdepth: 4 :caption: Package Reference magnet magnet.data magnet.nodes magnet.training magnet.debug magnet.utils Indices and tables ================== * :ref:`genindex` * :ref:`modindex` ================================================ FILE: docs/source/magnet.rst ================================================ magnet =================================== .. automodule:: magnet .. autofunction:: eval ================================================ FILE: docs/source/nodes.rst ================================================ Nodes =================================== .. automodule:: magnet.nodes Node ---------- .. autoclass:: Node :members: build, _mul_list :member-order: bysource Core ---------------------------------- .. autoclass:: Lambda .. autoclass:: Conv .. autoclass:: Linear .. autoclass:: RNN .. autoclass:: LSTM .. autoclass:: GRU .. autoclass:: BatchNorm ================================================ FILE: docs/source/training.rst ================================================ magnet.training =================================== .. automodule:: magnet.training Trainer ^^^^^^^^^^^^^^^^^ .. autoclass:: Trainer :members: optimize, train, mock, epochs, register_parameter :member-order: bysource SupervisedTrainer ^^^^^^^^^^^^^^^^^ .. autoclass:: SupervisedTrainer .. autofunction:: finish_training magnet.training.callbacks =================================== .. automodule:: magnet.training.callbacks CallbackQueue ^^^^^^^^^^^^^^^^^ .. autoclass:: CallbackQueue :members: __call__, find Monitor ^^^^^^^^^^^^^^^^^ .. autoclass:: Monitor :members: __call__, show Validate ^^^^^^^^^^^^^^^^^ .. autoclass:: Validate :members: __call__ Checkpoint ^^^^^^^^^^^^^^^^^ .. autoclass:: Checkpoint :members: __call__ ColdStart ^^^^^^^^^^^^^^^^^ .. autoclass:: ColdStart :members: __call__ LRScheduler ^^^^^^^^^^^^^^^^^ .. autoclass:: LRScheduler :members: __call__ magnet.training.history =================================== .. automodule:: magnet.training.history .. autoclass:: History :members: append, flush, show, find :member-order: bysource .. autoclass:: SnapShot :members: append, flush, show :member-order: bysource magnet.training.utils =================================== .. automodule:: magnet.training.utils :members: ================================================ FILE: docs/source/utils.rst ================================================ magnet.utils =================================== .. automodule:: magnet.utils .. autofunction:: summarize magnet.utils.images =================================== .. automodule:: magnet.utils.images .. autofunction:: show_images magnet.utils.plot =================================== .. automodule:: magnet.utils.plot .. autofunction:: smooth_plot magnet.utils.varseq =================================== .. automodule:: magnet.utils.varseq :members: pack, unpack, sort, unsort :member-order: bysource ================================================ FILE: environment.yml ================================================ name: magnet channels: - pytorch - defaults dependencies: - scikit-image=0.14.0 - pytorch=0.4.1 - torchvision=0.2.1 - pip: - beautifultable==0.5.2 - matplotlib==2.2.2 - scipy==1.1.0 - tqdm==4.23.4 prefix: /home/vaisakh/anaconda3/envs/magnet ================================================ FILE: magnet/__init__.py ================================================ from ._autograd import eval, device, build_lock def __print_init_message(): from magnet.utils.misc import in_notebook if not in_notebook: print('MagNet Inside') return from torch.cuda import get_device_name if device.type == 'cpu': print("Running your code on a boring CPU.") else: print('Accelerating your code on a shiney new', get_device_name(0), '.') __print_init_message() ================================================ FILE: magnet/_autograd.py ================================================ import torch from contextlib import contextmanager device = 'cuda' if torch.cuda.is_available() else 'cpu' device = torch.device(device) build_lock = True def eval(*modules): r"""A Context Manger that makes it easy to run computations in ``eval`` mode. It sets modules in their ``eval`` mode and ensures that gradients are not computed. This is a more wholesome option than :py:meth:`torch.no_grad` since many Modules (BatchNorm, Dropout etc.) behave differently while training and testing. Examples:: >>> import magnet as mag >>> import magnet.nodes as mn >>> import torch >>> model = mn.Linear(10) >>> x = torch.randn(4, 3) >>> # Using eval() as context manager >>> with mag.eval(model): >>> model(x) >>> # Use as decorator >>> @mag.eval(model) >>> def foo(): >>> return model(x) >>> foo() >>> # The modules can also be given at runtime by specifying no arguments >>> @mag.eval >>> def foo(model): >>> return model(x) >>> foo() >>> # The method then takes modules from the arguments >>> # to the decorated function. """ from inspect import isfunction # Check if called as decorator if not isfunction(modules[0]) or len(modules) > 1: return _eval_context_manager(*modules) from functools import wraps fn = modules[0] # The decorated function @wraps(fn) def new_fn(*args, **kwargs): from torch.nn import Module arg_list = list(args) + list(kwargs.values()) modules = [a for a in arg_list if isinstance(a, Module)] with _eval_context_manager(*modules): return fn(*args, **kwargs) return new_fn @contextmanager def _eval_context_manager(*modules): states = [] modules = [module for module in modules if module.training] for module in modules: states.append(module.training) module.eval() with torch.no_grad(): try: yield finally: for module, state in zip(modules, states): module.train(state) ================================================ FILE: magnet/data/__init__.py ================================================ from .data import DIR_DATA, Data ================================================ FILE: magnet/data/core.py ================================================ from . import data from .transforms import image_transforms def MNIST(val_split=0.2, path=None, **kwargs): r"""The MNIST Dataset. Args: val_split (float): The fraction of training data to hold out as validation if validation set is not given. Default: ``0.2`` path (pathlib.Path or str): The path to save the dataset to. Default: Magnet Datapath Keyword Args: (): See ``Data`` for more details. """ from torchvision.datasets import mnist if path is None: path = data.DIR_DATA dataset = {mode: mnist.MNIST(path, train=(mode == 'train'), download=True) for mode in ('train', 'test')} transforms = kwargs.pop('transforms', image_transforms()) return data.Data(**dataset, val_split=val_split, transforms=transforms) ================================================ FILE: magnet/data/data.py ================================================ def _get_data_dir(): import os, warnings from pathlib import Path DIR_DATA = os.environ.get('MAGNET_DATAPATH', '~/.data') if DIR_DATA is None: warnings.warn('You need to have an environment variable called MAGNET_DATAPATH. Add this to your .bashrc file:\nexport MAGNET_DATAPATH=\n' 'Where is the desired path where all MagNet datasets are stored by default.', RuntimeError) DIR_DATA = Path(DIR_DATA).expanduser() DIR_DATA.mkdir(parents=True, exist_ok=True) return DIR_DATA DIR_DATA = _get_data_dir() from . import core wiki = {'mnist': core.MNIST} class Data: r"""A container which holds the Training, Validation and Test Sets and provides DataLoaders on call. This is a convenient abstraction which is used downstream with the Trainer and various debuggers. It works in tandem with the custom Dataset, DataLoader and Sampler sub-classes that MagNet defines. Args: train (``Dataset``): The training set val (``Dataset``): The validation set. Default: ``None`` test (``Dataset``): The test set. Default: ``None`` val_split (float): The fraction of training data to hold out as validation if validation set is not given. Default: ``0.2`` Keyword Args: num_workers (int): how many subprocesses to use for data loading. 0 means that the data will be loaded in the main process. Default: ``0`` collate_fn (callable): merges a list of samples to form a mini-batch Default: :py:meth:`pack_collate` pin_memory (bool): If ``True``, the data loader will copy tensors into CUDA pinned memory before returning them. Default: ``False`` timeout (numeric): if positive, the timeout value for collecting a batch from workers. Should always be non-negative. Default: ``0`` worker_init_fn (callable): If not ``None``, this will be called on each worker subprocess with the worker id (an int in ``[0, num_workers - 1]``) as input, after seeding and before data loading. Default: ``None`` transforms (list or callable): A list of transforms to be applied to each datapoint. Default: ``None`` fetch_fn (callable): A function which is applied to each datapoint before collating. Default: ``None`` """ def __init__(self, train, val=None, test=None, val_split=0.2, **kwargs): from .dataloader import pack_collate if not hasattr(self, '_name'): self._name = self.__class__.__name__ self._dataset = {'train': train, 'val': val, 'test': test} self._dataset = {k: v for k, v in self._dataset.items() if v is not None} if 'val' not in self._dataset.keys(): self._split_val(val_split) self.num_workers = kwargs.pop('num_workers', 0) self.collate_fn = kwargs.pop('collate_fn', pack_collate) self.pin_memory = kwargs.pop('pin_memory', False) self.timeout = kwargs.pop('timeout', 0) self.worker_init_fn = kwargs.pop('worker_init_fn', None) self.transforms = kwargs.pop('transforms', None) self.fetch_fn = kwargs.pop('fetch_fn', None) def __getitem__(self, args): if isinstance(args, int): return self['train'][args] elif isinstance(args, str): try: return self._dataset[args] except KeyError as err: if args == 'val': err_msg = "This dataset has no validation set held out! If the constructor has a val_split attribute, consider setting that." elif args == 'test': err_msg = 'This dataset has no test set.' else: err_msg = "The only keys are 'train', 'val', and 'test'." raise KeyError(err_msg) from err mode = args[1] index = args[0] return self[mode][index] def __setitem__(self, mode, dataset): self._dataset[mode] = dataset def __len__(self): return len(self['train']) def _split_val(self, val_split): if isinstance(val_split, int): len_val = val_split dataset_len = len(self) val_ids = list(range(dataset_len - len_val, dataset_len)) return self._split_val(val_ids) elif isinstance(val_split, float) and val_split >= 0 and val_split < 1: num_val = int(val_split * len(self)) return self._split_val(num_val) from torch.utils.data.dataset import Subset val_ids = set(val_split) if len(val_ids) != len(val_split): raise ValueError("The indices in val_split should be unique. If you're not super" "pushy, pass in a fraction to split the dataset.") total_ids = set(range(len(self['train']))) train_ids = list(total_ids - val_ids) self['val'] = Subset(self['train'], val_split) self['train'] = Subset(self['train'], train_ids) def __call__(self, batch_size=1, shuffle=False, replace=False, probabilities=None, sample_space=None, mode='train'): r"""Returns a MagNet DataLoader that iterates over the dataset. Args: batch_size (int): How many samples per batch to load. Default: ``1`` shuffle (bool): Set to ``True`` to have the data reshuffled at every epoch. Default: ``False`` replace (bool): If ``True`` every datapoint can be resampled per epoch. Default: ``False`` probabilities (list or numpy.ndarray): An array of probabilities of drawing each member of the dataset. Default: ``None`` sample_space (float or int or list): The fraction / length / indices of the sample to draw from. Default: ``None`` mode (str): One of [``'train'``, ``'val'``, ``'test'``]. Default: ``'train'`` """ from .dataloader import TransformedDataset, DataLoader from .sampler import OmniSampler dataset = TransformedDataset(self._dataset[mode], self.transforms, self.fetch_fn) sampler = OmniSampler(dataset, shuffle, replace, probabilities, sample_space) shuffle = False batch_sampler = None drop_last = False num_workers = self.num_workers collate_fn = self.collate_fn pin_memory = self.pin_memory timeout = self.timeout worker_init_fn = self.worker_init_fn return DataLoader(dataset, batch_size, shuffle, sampler, batch_sampler, num_workers, collate_fn, pin_memory, drop_last, timeout, worker_init_fn) @staticmethod def get(name): try: return wiki[name.lower()]() except KeyError as err: raise KeyError('No such dataset.') from err ================================================ FILE: magnet/data/dataloader.py ================================================ import torch, collections from torch.utils.data.dataloader import DataLoader as DataLoaderPyTorch from torch.utils.data.dataloader import default_collate from torch.utils.data import Dataset import magnet as mag from magnet.utils.varseq import pack class TransformedDataset(Dataset): def __init__(self, dataset, transforms=None, fetch_fn=None): self.dataset = dataset self.transforms = transforms self.fetch_fn = fetch_fn def __getitem__(self, index): x = list(self.dataset[index]) x = self._apply_transforms(x) if self.fetch_fn is not None: x = self.fetch_fn(x) return x def __len__(self): return len(self.dataset) def _apply_transforms(self, x): transforms = self.transforms if transforms is None: return x if not isinstance(transforms, (tuple, list)): transforms = [transforms] if len(transforms) > len(x): raise ValueError('Provide a single transform for the first datapoint or a' 'tuple with each transform applied to the respective datapoint.') for i, transform in enumerate(transforms): if not isinstance(transform, (tuple, list)): x[i] = transform(x[i]) continue x_i = x[i] for t in transform: x_i = t(x_i) x[i] = x_i return x class DataLoader(DataLoaderPyTorch): def __init__(self, dataset, batch_size=1, shuffle=False, sampler=None, batch_sampler=None, num_workers=0, collate_fn=default_collate, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None, buffer_size='full'): super().__init__(dataset, batch_size, shuffle, sampler, batch_sampler, num_workers, collate_fn, pin_memory, drop_last, timeout, worker_init_fn) self.shuffle = shuffle if buffer_size == 'full': buffer_size = len(self) self.buffer_size = buffer_size if len(self) == 0: raise RuntimeError(f"Batch size too high. Either need more data / sample space or less batch size.\nMaximum allowed batch size is {len(self.sampler)}") def state_dict(self): sampler = self.sampler if sampler.shuffle and sampler.replace: return None static = {k: getattr(self.sampler, k) for k in ('shuffle', 'replace', 'sample_space')} static['batch_size'] = self.batch_size return {'indices': sampler.indices, 'pos': sampler.pos, 'static': static} def save_state_dict(self, path): import pickle from pathlib import Path with open(Path(path), 'wb') as f: pickle.dump(self.state_dict(), f) def load_state_dict(self, state_dict): if not isinstance(state_dict, dict): import pickle from pathlib import Path path = Path(state_dict) if path.exists(): with open(path, 'rb') as f: state_dict = pickle.load(f) else: return if not self.compatible_with(state_dict): return self.sampler.indices = state_dict['indices'] self.sampler.pos = state_dict['pos'] def compatible_with(self, state_dict): return all(getattr(self, k) == v for k, v in state_dict['static'].items()) def __next__(self): return next(iter(self)) def __len__(self): return int(len(self.sampler) // self.batch_size) def pack_collate(batch, pack_dims=None): def len_tensor(tensor): if len(tensor.shape) == 0: return 1 return len(tensor) if torch.is_tensor(batch[0]): if pack_dims is True: batch, order = pack(batch) return batch.to(mag.device), order return default_collate(batch).to(mag.device) if pack_dims == 'all': pack_dims = list(range(len_tensor(batch[0]))) elif pack_dims is None: pack_dims = [] if isinstance(batch[0], collections.Mapping): return {key: pack_collate([d[key] for d in batch], i in pack_dims) for i, key in enumerate(batch[0])} elif isinstance(batch[0], collections.Sequence): transposed = zip(*batch) return [pack_collate(samples, i in pack_dims) for i, samples in enumerate(transposed)] return default_collate(batch) ================================================ FILE: magnet/data/sampler.py ================================================ import numpy as np from torch.utils.data.sampler import Sampler class OmniSampler(Sampler): def __init__(self, dataset, shuffle=False, replace=False, probabilities=None, sample_space=None): self.dataset = dataset self.shuffle = shuffle self.replace = replace self.probabilities = probabilities self.sample_space = sample_space self._begin(-1) def _begin(self, pos): if self.sample_space is None: self.indices = list(range(len(self.dataset))) elif isinstance(self.sample_space, (list, tuple)): self.indices = self.sample_space elif isinstance(self.sample_space, int): self.indices = list(range(self.sample_space)) elif isinstance(self.sample_space, float): self.indices = list(range(int(self.sample_space * len(self.dataset)))) if self.shuffle: self.indices = np.random.choice(self.indices, len(self), self.replace, self.probabilities) self.pos = pos def __next__(self): self.pos += 1 if self.pos >= len(self): self._begin(0) return self.indices[self.pos] def __iter__(self): return self def __len__(self): return len(self.indices) ================================================ FILE: magnet/data/transforms.py ================================================ def augmented_image_transforms(d=0, t=0, s=0, sh=0, ph=0, pv=0, resample=2): r"""Returns a list of augmented transforms to be applied to natural images. Args: d (sequence or float or int): Range of degrees to select from. Default: ``0`` t (tuple): Tuple of maximum absolute fraction for horizontal and vertical translations. Default: ``0`` s (tuple, optional): Scaling factor interval. Default: ``0`` sh (sequence or float or int, optional): Range of shear. Default: ``0`` ph (float): The probability of flipping the image horizontally. Default: ``0`` pv (float): The probability of flipping the image vertically. Default: ``0`` resample (int): An optional resampling filter. Default: ``2`` See :py:class:`torchvision.transforms` for more details. """ from torchvision import transforms degrees = d translate = None if t == 0 else (t, t) scale = None if s == 0 else (1 - s, 1 + s) shear = None if sh == 0 else sh return transforms.Compose([transforms.RandomAffine(degrees, translate, scale, shear, resample), transforms.RandomHorizontalFlip(ph), transforms.RandomVerticalFlip(pv), transforms.ToTensor(), transforms.Normalize(*[[0.5] * 3] * 2)]) def image_transforms(augmentation=0, direction='horizontal'): r"""Returns a list of transforms to be applied to natural images. Args: augmentation (float): The percentage of augmentation to be applied. Default: ``0`` direction (str): The direction to flip the image at random. Default: ``'horizontal'`` """ x = augmentation if direction == 'horizontal': ph = 0.25 * x; pv = 0 elif direction == 'vertical': ph = 0; pv = 0.25 * x elif direction == 'both': ph = 0.25 * x; pv = 0.25 * x return augmented_image_transforms(d=45 * x, t=0.25 * x, s=0.13 * x, sh=6 * x, ph=ph, pv=pv) ================================================ FILE: magnet/debug.py ================================================ import sys, inspect, torch from contextlib import contextmanager def overfit(trainer, data, batch_size, epochs=1, metric='loss', **kwargs): r"""Runs training on small samples of the dataset in order to overfit. If you can't overfit a small sample, you can't model the data well. This debugger tries to overfit on multple small samples of the data. The sample size and batch sizes are varied and the training is done for a fixed number of epochs. This usually gives an insight on what to expect from the actual training. Args: trainer (magnet.training.Trainer): The Trainer object data (magnet.data.Data): The data object used for training batch_size (int): The intended batch size epochs (float): The expected epochs for convergence for 1% of the data. Default: ``1`` metric (str): The metric to plot. Default: ``'loss'`` .. note:: The maximum sample size is 1% of the size of the dataset. Examples:: >>> import magnet as mag >>> import magnet.nodes as mn >>> import magnet.debug as mdb >>> from magnet.data import Data >>> from magnet.training import SupervisedTrainer >>> data = Data.get('mnist') >>> model = mn.Linear(10) >>> with mag.eval(model): model(next(data())[0]) >>> trainer = SupervisedTrainer(model) >>> mdb.overfit(trainer, data, batch_size=64) .. image:: _static/img/overfit-fail.png :: >>> # Oops! Looks like there was something wrong. >>> # Loss does not considerable decrease for samples sizes >= 4. >>> # Of course, the activation was 'relu'. >>> model = mn.Linear(10, act=None) >>> with mag.eval(model): model(next(data())[0]) >>> trainer = SupervisedTrainer(model) >>> mdb.overfit(trainer, data, batch_size=64) >>> # Should be much better now. .. image:: _static/img/overfit-pass.png """ from matplotlib import pyplot as plt from magnet.training.callbacks import Monitor sample_space = kwargs.pop('sample_space', None) ax = kwargs.pop('ax', None) if sample_space is None: _, ax = plt.subplots() epochs *= 100 # First fit for small samples with batch size 1 for sample_space in (1, 2, 4, 8, 16): overfit(trainer, data, batch_size=1, epochs=epochs, metric=metric, sample_space=sample_space, ax=ax) # Fit with sample size 16 and batch size 16 if batch_size >= 16: overfit(trainer, data, batch_size=16, epochs=epochs, metric=metric, sample_space=16, ax=ax) # Fit with 1% of the data at given batch size sample_length = int(len(data) * 0.01) bs = min(batch_size, sample_length) if sample_length > 16: overfit(trainer, data, bs, epochs, metric, sample_space=sample_length, ax=ax) plt.show() return with trainer.mock(): trainer.train(data(batch_size, sample_space=sample_space, shuffle=True), epochs, callbacks=[Monitor(frequency=10 / epochs)]) trainer.callbacks[0].history.show(metric, x_key='epochs', validation=False, ax=ax, log=True, legend=f'{batch_size}, {sample_space}', smoothen=False) def check_flow(trainer, data): r"""Checks if any trainable parameter is not receiving gradients. Super useful for large architectures that use the :py:meth:`detach` function Args: trainer (magnet.trainer.Trainer): The Trainer object data (magnet.data.Data): The data object used for training """ broken_parameters = set() def callback(trainer, signal, **kwargs): # This callback reacts to the 'gradient' signal and logs any parameters # that require gradient but have not accumulated any. if signal == 'gradient': for model in kwargs.pop('models'): broken_parameters.update(set(name for name, p in model.named_parameters(prefix=model.__class__.__name__) if p.requires_grad and p.grad is None)) callback.name = 'check_flow' # Run the trainer for one iteration with the callback. with trainer.mock(): trainer.train(data(), callbacks=[callback], iterations=1) if len(broken_parameters) == 0: print('No breakage detected') else: raise RuntimeError('Breaks in the following parameters: ' + ', '.join(broken_parameters)) class Babysitter: r"""A callback which monitors the mean relative gradients for all parameters. Args: frequency (int): Then number of times per epoch to monitor. Default: :math:`10` Keyword Args: name (str): Name of this callback. Default: ``'babysitter'`` """ def __init__(self, frequency=10, **kwargs): from magnet.training.history import History self.name = kwargs.pop('name', 'babysitter') self.frequency = frequency self.history = History() def __call__(self, trainer, signal, **kwargs): r""" Responds to the following signals: * ``'gradient'``: Called after gradients have accumulated. Logs the mean relative gradients for each parameter. * ``'load'``: Loads the state of this callback from :attr:`path`. * ``'save'``: Saves the state of this callback to :attr:`path`. """ if signal == 'gradient': batches_per_epoch = len(trainer.dataloader) if trainer.iterations % int(batches_per_epoch // self.frequency): return self.append(trainer, kwargs.pop('models')) elif signal == 'load': self.load(kwargs.pop('path')) elif signal == 'save': self.save(kwargs.pop('path')) def append(self, trainer, models): stamps = {'iterations': trainer.iterations, 'epochs': trainer.epochs()} for model in models: for name, p in model.named_parameters(): v = torch.abs(p.grad / p) v[v != v] = 0 # Ignore NaN self.history.append(name, v.mean().item(), **stamps) def load(self, path): from magnet.training.utils import load_object self.history = load_object(path / self.name / 'history.p', default=self.history) def save(self, path): from magnet.training.utils import save_object save_object(self.history, path / self.name / 'history.p') @contextmanager def shape(debug=True): r"""The shapes of every tensor is printed out if a module is called within this context manager. Useful for debugging the flow of tensors through layers and finding the values of various hyperparameters. Args: debug (bool or str): If ``str``, only the tensor with this name is tracked. If ``True``, all tensors are tracked. Else, nothing is tracked. """ with _SetTrace(_Monitor(debug)): yield class _SetTrace(object): def __init__(self, func): self.func = func def __enter__(self): print(sys.gettrace()) sys.settrace(self.func) return self def __exit__(self, ext_type, exc_value, traceback): sys.settrace(None) class _Monitor: def __init__(self, names=True): if isinstance(names, str): names = (names, ) self.names = names def init(self, frameinfo): self.filename = frameinfo.filename.strip() self.stackdepth = len(inspect.stack()) self.lineno = frameinfo.lineno def is_same(self, frame): frameinfo = inspect.getframeinfo(frame) return frameinfo.function.strip() == 'forward' and len(inspect.stack()) == self.stackdepth def __call__(self, frame, event, arg): frameinfo = inspect.getframeinfo(frame) if not hasattr(self, 'filename') and frameinfo.function.strip() == 'forward': self.init(frameinfo) if not self.is_same(frame): return if event not in ("line", "return"): return self.__call__ if self.names is True: shape_dict = {n: tuple(v.shape) for n, v in frame.f_locals.items() if torch.is_tensor(v)} elif isinstance(self.names, (tuple, list)): shape_dict = {n: tuple(v.shape) for n, v in frame.f_locals.items() if torch.is_tensor(v) and n in self.names} if len(shape_dict) != 0: print(shape_dict) lineno = frameinfo.lineno - self.lineno if event != "return" else 'return' print(f'{lineno}.', frameinfo.code_context[0].strip(), '\n') return self.__call__ ================================================ FILE: magnet/nodes/__init__.py ================================================ from .nodes import Node from .core import * ================================================ FILE: magnet/nodes/core.py ================================================ # coding=utf-8 import torch.nn.functional as F from torch import nn from .nodes import Node class Lambda(Node): r"""Wraps a Node around any function. Args: fn (callable): The function which gets called in the forward pass Examples:: >>> import magnet.nodes as mn >>> import torch >>> model = mn.Lambda(lambda x: x.mean()) >>> model(torch.arange(5, dtype=torch.float)).item() 2.0 >>> def subtract(x, y): >>> return x - y >>> model = mn.Lambda(subtract) >>> model(2 * torch.ones(1), torch.ones(1)).item() 1.0 """ def __init__(self, fn, **kwargs): super().__init__(fn, **kwargs) # If a name is not supplied, get the function name instead # of the class (Lambda) name. if self.name == self.__class__.__name__: self.name = self._args['fn'].__name__ def forward(self, *args, **kwargs): return self._args['fn'](*args, **kwargs) class Conv(Node): r"""Applies a convolution over an input tensor. Args: c (int): Number of channels produced by the convolution. Default: Inferred k (int or tuple): Size of the convolving kernel. Default: ``3`` p (int, tuple or str): Zero-padding added to both sides of the input. Default: ``'half'`` s (int or tuple): Stride of the convolution. Default: ``1`` d (int or tuple): Spacing between kernel elements. Default: ``1`` g (int): Number of blocked connections from input channels to output channels. Default: ``1`` b (bool): If ``True``, adds a learnable bias to the output. Default: ``True`` ic (int): Number of channels in the input image. Default: Inferred act (str or None): The activation function to use. Default: ``'relu'`` * :attr:`p` can be conveniently used for ``'half'``, ``'same'`` or ``'double'`` padding to half, same or double the image size respectively. The arguments are accordingly inferred at runtime. For ``'half'`` padding, the output channels (if not provided) are set to twice the input channels to make up for the lost information and vice-versa for the double padding. For ``'same'`` padding, the output channels are kept equal to the input channels. In all three cases, the dilation is set to ``1`` and the stride is modified as required. * :attr:`c` is inferred from the second dimension of the input tensor. * :attr:`act` is set to ``'relu'`` by default unlike the PyTorch implementation where activation functions need to be seperately defined. Take caution to manually set the activation to ``None``, where needed. .. note:: The dimensions (1, 2 or 3) of the convolutional kernels are inferred from the corresponding shape of the input tensor. .. note:: One can also create multiple Nodes using the convinient multiplication (``*``) operation. Multiplication with an integer :math:`n`, gives :math:`n` copies of the Node. Multiplication with a list or tuple of integers, :math:`(c_1, c_2, ..., c_n)` gives :math:`n` copies of the Node with :attr:`c` set to :math:`c_i` Shape: - Input: :math:`(N, C_{in}, *)` where `*` is any non-zero number of trailing dimensions. - Output: :math:`(N, C_{out}, *)` Attributes: layer (nn.Module): The Conv module built from torch.nn Examples:: >>> import torch >>> from torch import nn >>> import magnet.nodes as mn >>> from magnet.utils import summarize >>> # A Conv layer with 32 channels and half padding >>> model = mn.Conv(32) >>> model(torch.randn(4, 16, 28, 28)).shape torch.Size([4, 32, 14, 14]) >>> # Alternatively, the 32 in the constructor may be omitted >>> # since it is inferred on runtime. >>> # The same conv layer with 'double' padding >>> model = mn.Conv(p='double') >>> model(torch.randn(4, 16, 28, 28)).shape torch.Size([4, 8, 56, 56]) >>> layers = mn.Conv() * 3 [Conv(), Conv(), Conv()] >>> model = nn.Sequential(*layers) >>> summarize(model) +-------+------------+----------------------+ | Node | Shape | Trainable Parameters | +-------+------------+----------------------+ | input | 16, 28, 28 | 0 | +-------+------------+----------------------+ | Conv | 32, 14, 14 | 4,640 | +-------+------------+----------------------+ | Conv | 64, 7, 7 | 18,496 | +-------+------------+----------------------+ | Conv | 128, 4, 4 | 73,856 | +-------+------------+----------------------+ Total Trainable Parameters: 96,992 """ def __init__(self, c=None, k=3, p='half', s=1, d=1, g=1, b=True, ic=None, act='relu', bn=False, **kwargs): super().__init__(c, k, p, s, d, g, b, ic, act, bn, **kwargs) def build(self, x): from magnet.nodes.functional import wiki self._set_padding(x) # Handle 'half', 'same' and 'double' padding # Infer the input shape if not given if self._args['ic'] is None: self._args['ic'] = x.shape[1] self._activation = wiki['activations'][self._args['act']] layer_class = self._find_layer(x) # Infer the layer (Conv1D, 2D or 3D) self.layer = layer_class(kernel_size=self._args['k'], out_channels=self._args['c'], stride=self._args['s'], padding=self._args['p'], dilation=self._args['d'], groups=self._args['g'], bias=self._args['b'], in_channels=self._args['ic']) if self._args['bn']: self._batch_norm = BatchNorm() super().build(x) def forward(self, x): if hasattr(self, '_upsample'): x = F.interpolate(x, scale_factor=self._upsample) x = self._activation(self.layer(x)) if self._args['bn']: x = self._batch_norm(x) return x @staticmethod def _find_layer(x): shape_dict = [nn.Conv1d, nn.Conv2d, nn.Conv3d] ndim = len(x.shape) - 2 return shape_dict[ndim - 1] def _set_padding(self, x): in_shape = x.shape p = self._args['p'] if p == 'half': f = 0.5 elif p == 'same': f = 1 elif p == 'double': self._upsample = 2 if self._args['c'] is None: self._args['c'] = in_shape[1] // 2 f = 1 else: return s = 1 / f self._args['d'] = 1 self._args['s'] = int(s) self._args['p'] = int(self._args['k'] // 2) if self._args['c'] is None: self._args['c'] = self._args['s'] * in_shape[1] def _mul_list(self, n): convs = [self] self._args['c'] = n[0] kwargs = self._args.copy() for c in n[1:]: kwargs['c'] = c convs.append(self.__class__(**kwargs)) return convs class Linear(Node): r"""Applies a linear transformation to the incoming tensor Args: o (int or tuple): Output dimensions. Default: :math:`1` b (bool): Whether to include a bias term. Default: ``True`` flat (bool): Whether to flatten out the input to 2 dimensions. Default: ``True`` i (int): Input dimensions. Default: Inferred act (str or None): The activation function to use. Default: ``'relu'`` bn (bool): Whether to use Batch Normalization immediately after the layer. Default: ``False`` * :attr:`flat` is used by default to flatten the input to a vector. This is useful, say in the case of CNNs where an 3-D image based output with multiple channels needs to be fed to several dense layers. * :attr:`o` is inferred from the last dimension of the input tensor. * :attr:`act` is set to 'relu' by default unlike the PyTorch implementation where activation functions need to be seperately defined. Take caution to manually set the activation to None, where needed. .. note:: One can also create multiple Nodes using the convinient multiplication (*) operation. Multiplication with an integer :math:`n`, gives :math:`n` copies of the Node. Multiplication with a list or tuple of integers, :math:`(o_1, o_2, ..., o_n)` gives :math:`n` copies of the Node with :attr:`o` set to :math:`o_i` .. note:: If :attr:`o` is a tuple, the output features are its product and the output is inflated to this shape. Shape: If :attr:`flat` is True - Input: :math:`(N, *)` where :math:`*` means any number of trailing dimensions - Output: :math:`(N, *)` Else - Input: :math:`(N, *, in\_features)` where :math:`*` means any number of trailing dimensions - Output: :math:`(N, *, out\_features)` where all but the last dimension are the same shape as the input. Attributes: layer (nn.Module): The Linear module built from torch.nn Examples:: >>> import torch >>> from torch import nn >>> import magnet.nodes as mn >>> from magnet.utils import summarize >>> # A Linear mapping to 10-dimensional space >>> model = mn.Linear(10) >>> model(torch.randn(64, 3, 28, 28)).shape torch.Size([64, 10]) >>> # Don't flatten the input >>> model = mn.Linear(10, flat=False) >>> model(torch.randn(64, 3, 28, 28)).shape torch.Size([64, 3, 28, 10]) >>> # Make a Deep Neural Network >>> # Don't forget to turn the activation to None in the final layer >>> layers = mn.Linear() * (10, 50) + [mn.Linear(10, act=None)] [Linear(), Linear(), Linear()] >>> model = nn.Sequential(*layers) >>> summarize(model) +------+---------+--------------------+----------------------------------------------------+ | Node | Shape |Trainable Parameters| Arguments | +------+---------+--------------------+----------------------------------------------------+ |input |3, 28, 28| 0 | | +------+---------+--------------------+----------------------------------------------------+ |Linear| 10 | 23,530 |bn=False, act=relu, i=2352, flat=True, b=True, o=10 | +------+---------+--------------------+----------------------------------------------------+ |Linear| 50 | 550 |bn=False, act=relu, i=10, flat=True, b=True, o=50 | +------+---------+--------------------+----------------------------------------------------+ |Linear| 10 | 510 |bn=False, act=None, i=50, flat=True, b=True, o=10 | +------+---------+--------------------+----------------------------------------------------+ Total Trainable Parameters: 24,590 """ def __init__(self, o=1, b=True, flat=True, i=None, act='relu', bn=False, **kwargs): super().__init__(o, b, flat, i, act, bn, **kwargs) def build(self, x): from numpy import prod from magnet.nodes.functional import wiki # Infer the input shape if not given if self._args['i'] is None: self._args['i'] = prod(x.shape[1:]) if self._args['flat'] else x.shape[-1] # If a tuple is given as output shape, inflate to that tuple if isinstance(self._args['o'], (list, tuple)): self._inflate_shape = self._args['o'] self._args['o'] = prod(self._args['o']) else: self._inflate_shape = None self._activation = wiki['activations'][self._args['act']] self.layer = nn.Linear(*[self._args[k] for k in ('i', 'o', 'b')]) if self._args['bn']: self._batch_norm = BatchNorm() super().build(x) def forward(self, x): if self._args['flat']: x = x.view(x.size(0), -1) x = self._activation(self.layer(x)) if self._args['bn']: x = self._batch_norm(x) if self._inflate_shape is not None: x = x.view(-1, *self._inflate_shape) return x def _mul_list(self, n): lins = [self] self._args['o'] = n[0] kwargs = self._args.copy() for o in n[1:]: kwargs['o'] = o lins.append(self.__class__(**kwargs)) return lins class _RNNBase(Node): def __init__(self, mode, h, n=1, b=False, bi=False, act='tanh', d=0, batch_first=False, i=None, **kwargs): self.layer = mode super().__init__(h, n, b, bi, act, d, batch_first, i, **kwargs) def build(self, x, h=None): # Infer the input shape if not given if self._args['i'] is None: self._args['i'] = x.shape[-1] self.layer = {'rnn': nn.RNN, 'lstm': nn.LSTM, 'gru': nn.GRU}[self.layer.lower()] kwargs = {'nonlinearity': self._args['act'], 'bias': self._args['b'], 'batch_first': self._args['batch_first'], 'dropout': self._args['d'], 'bidirectional': self._args['bi']} # The 'nonlinearity' / 'act' argument is not a part of LSTM and GRU if not isinstance(self.layer, nn.RNN): kwargs.pop('nonlinearity') self.layer = self.layer(*[self._args[k] for k in ('i', 'h', 'n')], **kwargs) super().build(x, h) def forward(self, x, h=None): return self.layer(x, h) def _mul_list(self, n): rnns = [self] self._args['h'] = n[0] kwargs = self._args.copy() for h in n[1:]: kwargs['h'] = h print(self.__class__, kwargs) rnns.append(self.__class__(**kwargs)) return rnns class RNN(_RNNBase): r"""Applies a multi-layer RNN with to an input tensor. Args: h (int, Required): The number of features in the hidden state `h` n (int): Number of layers. Default: ``1`` b (bool): Whether to include a bias term. Default: ``True`` bi (bool): If ``True``, becomes a bidirectional RNN. Default: ``False`` act (str or None): The activation function to use. Default: ``'tanh'`` d (int): The dropout probability of the outputs of each layer. Default: ``0`` batch_first (False): If ``True``, then the input and output tensors are provided as ``(batch, seq, feature)``. Default: ``False`` i (int): Input dimensions. Default: Inferred * :attr:`i` is inferred from the last dimension of the input tensor. .. note:: One can also create multiple Nodes using the convinient multiplication (*) operation. Multiplication with an integer :math:`n`, gives :math:`n` copies of the Node. Multiplication with a list or tuple of integers, :math:`(h_1, h_2, ..., h_n)` gives :math:`n` copies of the Node with :attr:`h` set to :math:`h_i` Attributes: layer (nn.Module): The RNN module built from torch.nn Examples:: >>> import torch >>> from torch import nn >>> import magnet.nodes as mn >>> from magnet.utils import summarize >>> # A recurrent layer with 32 hidden dimensions >>> model = mn.RNN(32) >>> model(torch.randn(7, 4, 300))[0].shape torch.Size([7, 4, 32]) >>> # Attach a linear head >>> model = nn.Sequential(model, mn.Linear(1000, act=None)) """ def __init__(self, h, n=1, b=False, bi=False, act='tanh', d=0, batch_first=False, i=None, **kwargs): mode = kwargs.pop('mode', 'rnn') super().__init__(mode, h, n, b, bi, act, d, batch_first, i, **kwargs) class LSTM(_RNNBase): r"""Applies a multi-layer LSTM with to an input tensor. See mn.RNN for more details """ def __init__(self, h, n=1, b=False, bi=False, d=0, batch_first=False, i=None, **kwargs): act = kwargs.pop('act', None) mode = kwargs.pop('mode', 'lstm') super().__init__(mode, h, n, b, bi, act, d, batch_first, i, **kwargs) class GRU(_RNNBase): r"""Applies a multi-layer GRU with to an input tensor. See mn.RNN for more details """ def __init__(self, h, n=1, b=False, bi=False, d=0, batch_first=False, i=None, **kwargs): act = kwargs.pop('act', None) mode = kwargs.pop('mode', 'gru') super().__init__(mode, h, n, b, bi, act, d, batch_first, i, **kwargs) class BatchNorm(Node): r"""Applies Batch Normalization to the input tensor e=1e-05, m=0.1, a=True, track=True, i=None Args: e (float): A small value added to the denominator for numerical stability. Default: ``1e-5`` m (float or None): The value used for the running_mean and running_var computation. Can be set to ``None`` for cumulative moving average (i.e. simple average). Default: ``0.1`` a (bool): Whether to have learnable affine parameters. Default: ``True`` track (bool): Whether to track the running mean and variance. Default: ``True`` i (int): Input channels. Default: Inferred * :attr:`i` is inferred from the second dimension of the input tensor. .. note:: The dimensions (1, 2 or 3) of the running mean and variance are inferred from the corresponding shape of the input tensor. .. note:: One can also create multiple Nodes using the convinient multiplication (*) operation. Multiplication with an integer :math:`n`, gives :math:`n` copies of the Node. Multiplication with a list or tuple of integers, :math:`(i_1, i_2, ..., i_n)` gives :math:`n` copies of the Node with :attr:`i` set to :math:`i_i` Shape: - Input: :math:`(N, C, *)` where :math:`*` means any number of trailing dimensions - Output: :math:`(N, C, *)` (same shape as input) Attributes: layer (nn.Module): The BatchNorm module built from :py:class:`torch.nn` Examples:: >>> import torch >>> from torch import nn >>> import magnet.nodes as mn >>> from magnet.utils import summarize >>> # A Linear mapping to 10-dimensional space >>> model = mn.Linear(10) >>> model(torch.randn(64, 3, 28, 28)).shape torch.Size([64, 10]) >>> # Don't flatten the input >>> model = mn.Linear(10, flat=False) >>> model(torch.randn(64, 3, 28, 28)).shape torch.Size([64, 3, 28, 10]) >>> # Make a Deep Neural Network >>> # Don't forget to turn the activation to None in the final layer >>> layers = mn.Linear() * (10, 50) + [mn.Linear(10, act=None)] [Linear(), Linear(), Linear()] >>> model = nn.Sequential(*layers) >>> summarize(model) +------+---------+--------------------+----------------------------------------------------+ | Node | Shape |Trainable Parameters| Arguments | +------+---------+--------------------+----------------------------------------------------+ |input |3, 28, 28| 0 | | +------+---------+--------------------+----------------------------------------------------+ |Linear| 10 | 23,530 |bn=False, act=relu, i=2352, flat=True, b=True, o=10 | +------+---------+--------------------+----------------------------------------------------+ |Linear| 50 | 550 |bn=False, act=relu, i=10, flat=True, b=True, o=50 | +------+---------+--------------------+----------------------------------------------------+ |Linear| 10 | 510 |bn=False, act=None, i=50, flat=True, b=True, o=10 | +------+---------+--------------------+----------------------------------------------------+ Total Trainable Parameters: 24,590 """ def __init__(self, e=1e-05, m=0.1, a=True, track=True, i=None, **kwargs): super().__init__(e, m, a, track, i, **kwargs) def build(self, x): # Infer the input shape if not given self._args['i'] = x.shape[1] layer_class = self._find_layer(x) # Infer the layer (BatchNorm1D, 2D or 3D) self.layer = layer_class(*[self._args[k] for k in ('i', 'e', 'm', 'a', 'track')]) super().build(x) def forward(self, x): return self.layer(x) @staticmethod def _find_layer(x): shape_dict = [nn.BatchNorm1d, nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d] ndim = len(x.shape) - 1 return shape_dict[ndim - 1] ================================================ FILE: magnet/nodes/functional/__init__.py ================================================ from .functional import * ================================================ FILE: magnet/nodes/functional/activations.py ================================================ from functools import partial from torch.nn.functional import relu, leaky_relu from torch import sigmoid, tanh wiki = {'relu': relu, 'sigmoid': sigmoid, 'tanh': tanh, 'lrelu': partial(leaky_relu, negative_slope=0.2), None: lambda x: x} ================================================ FILE: magnet/nodes/functional/functional.py ================================================ from torch.nn import functional as F from magnet.nodes.functional import activations, losses, metrics dimensional_function = lambda f_list, *args, **kwargs: f_list[len(args[0].size()) - 3](*args, **kwargs) adaptive_avg_pool = lambda x, output_size: dimensional_function([F.adaptive_avg_pool1d, F.adaptive_avg_pool2d, F.adaptive_avg_pool3d], x, output_size) global_avg_pool = lambda x: adaptive_avg_pool(x, 1).squeeze() wiki = {'global_avg_pool': global_avg_pool, 'activations': activations.wiki, 'losses': losses.wiki, 'metrics': metrics.wiki} ================================================ FILE: magnet/nodes/functional/losses.py ================================================ from torch.nn.functional import cross_entropy wiki = {'cross_entropy': cross_entropy} ================================================ FILE: magnet/nodes/functional/metrics.py ================================================ def accuracy(scores, y): y_pred = scores.max(1)[1] return (y_pred == y).float().mean() wiki = {'accuracy': accuracy} ================================================ FILE: magnet/nodes/nodes.py ================================================ # coding=utf-8 import torch import magnet as mag from torch import nn from magnet.utils.misc import caller_locals class Node(nn.Module): r"""Abstract base class that defines MagNet's Node implementation. A Node is a *'self-aware Module'*. It can dynamically parametrize itself in runtime. For instance, a ``Linear`` Node can infer the input features automatically when first called; a ``Conv`` Node can infer the dimensionality (1, 2, 3) of the input automatically. MagNet's Nodes strive to help the developer as much as possible by finding the right hyperparameter values automatically. Ideally, the developer shouldn't need to define anything except the basic architecture and the inputs and outputs. The arguments passed to the constructor are stored in a ``_args`` attribute as a dictionary. This is later modified by the :py:meth:`build` method which gets automatically called on the first forward pass. Keyword Args: name (str) - A printable name for this node. Default: Class Name """ def __init__(self, *args, **kwargs): super().__init__() self._parse_args() self._built = False def build(self, *args, **kwargs): r"""Builds the Node. Ideally, should not be called manually. When an unbuilt module is first called, this method gets invoked. """ self._built = True self.to(mag.device) def __call__(self, *args, **kwargs): if not (self._built and mag.build_lock): self.build(*args, **kwargs) return super().__call__(*args, **kwargs) def _parse_args(self): """ A Helper Method to get all the constructor arguments and store them into _args. This will help modify these arguments at runtime. Additionally, this method also captures the name of the Node, if given (default is the class name). """ args = caller_locals(ancestor=True) args.update(args.pop('kwargs', {})) self.name = args.pop('name', self.__class__.__name__) if self.name is None or self.name == '': raise ValueError(f"""One of the {self.__class__.__name__} Node's names is {self.name}""") self._args = args def get_args(self): """ Returns a nicely formatted string describing the argumens """ return ', '.join(str(k) + '=' + str(v) for k, v in self._args.items()) def to(self, *args, **kwargs): super().to(*args, **kwargs) # Additionally, set a convinient device attribute try: self.device = next(self.parameters())[0].device except StopIteration: pass return self def load_state_dict(self, f): from pathlib import Path # Handle a path being given instead of a file. (preferred since it # automatically maps to the correct device) if isinstance(f, (str, Path)): device = self.device.type if device == 'cuda': device = 'cuda:0' return super().load_state_dict(torch.load(f, map_location=device)) else: return super().load_state_dict(f) def _mul_int(self, n): return [self] + [self.__class__(**self._args) for _ in range(n - 1)] def _mul_list(self, n): r"""A useful overload of the * operator that can create similar copies of the node. Args: n (tuple or list) - The modifier supplied The modifier n should be used to change the arguments of the node in a meaningful way. For instance, in the case of a Linear node, the items in n can be interpreted as the output dimensions of each layer. """ raise NotImplementedError def __mul__(self, n): if isinstance(n, int) or (isinstance(n, float) and n.is_integer()): return self._mul_int(n) if isinstance(n, (tuple, list)): return self._mul_list(n) ================================================ FILE: magnet/training/__init__.py ================================================ from magnet.training.train import * ================================================ FILE: magnet/training/callbacks.py ================================================ import magnet as mag import torch from time import time class Monitor: r"""Allows easy monitoring of the training process. Stores any metric / quantity broadcast using the ``'write_stats'`` signal. Also adds a nice progress bar! Args: frequency (int): Then number of times per epoch to flush the buffer. Default: 10 show_progress (bool): If ``True``, adds a progress bar. Default: ``True`` Keyword Args: name (str): Name of this callback. Default: ``'monitor'`` * :attr:`frequency` is useful only if there are buffered metrics. Examples:: >>> import torch >>> import magnet as mag >>> import magnet.nodes as mn >>> from magnet.training import callbacks, SupervisedTrainer >>> model = mn.Linear(10, act=None) >>> with mag.eval(model): model(torch.randn(4, 1, 28, 28)) >>> trainer = SupervisedTrainer(model) >>> callbacks = callbacks.CallbackQueue([callbacks.Monitor()]) >>> callbacks(signal='write_stats', trainer=trainer, key='loss', value=0.1) >>> callbacks[0].history {'loss': [{'val': 0.1}]} """ def __init__(self, frequency=10, show_progress=True, **kwargs): from magnet.training.history import History self.name = kwargs.pop('name', 'monitor') self.frequency = frequency self.show_progress = show_progress self.history = History() def __call__(self, trainer, signal, **kwargs): r""" Responds to the following signals: * ``'write_stats'``: Any keyword arguments will be passed to the :py:meth:`History.append` method. * ``'on_training_start'``: To be called before start of training. Initializes the progress bar. * ``'on_batch_start'``: Called before the training loop. Updates the progress bar. * ``'on_batch_end'``: Called after the training loop. Flushes the history buffer if needed and sets the progress bar description. * ``'on_training_end'``: To be called after training. Closes the progress bar. * ``'load_state'``: Loads the state of this callback from :attr:`path`. * ``'save_state'``: Saves the state of this callback to :attr:`path`. """ if signal == 'on_training_start': from magnet.utils.misc import get_tqdm; tqdm = get_tqdm() if self.show_progress: self.progress_bar = tqdm(total=kwargs.pop('total_iterations'), unit_scale=True, unit_divisor=len(trainer.dataloader), leave=False) elif signal == 'on_batch_start': if self.show_progress: self.progress_bar.update() self.progress_bar.refresh() elif signal == 'write_stats': self.history.append(**kwargs) elif signal == 'on_batch_end' and trainer.iterations != 0: batches_per_epoch = len(trainer.dataloader) if trainer.iterations % int(batches_per_epoch // self.frequency): return self.history.flush(iterations=trainer.iterations, epochs=trainer.epochs()) if not self.show_progress or 'loss' not in self.history.keys(): return if 'val_loss' in self.history.keys(): description = f"{self.history['loss'][-1]:.2f}, {self.history['val_loss'][-1]:.2f}" else: description = f"{self.history['loss'][-1]:.2f}" self.progress_bar.set_description(description, refresh=False) elif signal == 'on_training_end' and self.show_progress: self.progress_bar.close() self.progress_bar = None elif signal == 'load_state': self.load_state(kwargs.pop('path')) elif signal == 'save_state': self.save_state(kwargs.pop('path')) def show(self, metric=None, log=False, x_key='epochs', **kwargs): r"""Calls the corresponding :py:meth:`History.show` method. """ self.history.show(metric, log, x_key, **kwargs) def __repr__(self): self.show() return '' def load_state(self, path): from magnet.training.utils import load_object self.history = load_object(path / self.name / 'history.p', default=self.history) def save_state(self, path): from magnet.training.utils import save_object save_object(self.history, path / self.name / 'history.p') class Validate: r"""Runs a validation function over a dataset during the course of training. Most Machine Learning research uses a held out validation set as a proxy for the test set / real-life data. Hyperparameters are usually tuned on the validation set. Often, this is done during training in order to view the simultaneous learning on the validation set and catch any overfitting / underfitting. This callback enables you to run a custom ``validate`` function over a :attr:`dataloader`. Args: dataloader (``DataLoader``): DataLoader containing the validation set validate (bool): A callable that does the validation frequency (int): Then number of times per epoch to run the function. Default: :math:`10` batches (int or None): The number of times / batches to call the validate function in each run. Default: ``None`` drop_last (bool): If ``True``, the last batch is not run. Default: ``False`` Keyword Args: name (str): Name of this callback. Default: ``'validate'`` * :attr:`validate` is a function which takes two arguments: (trainer, dataloader). * :attr:`batches` defaults to a value which ensures that an epoch of the validation set matches an epoch of the training set. For instance, if the training set has :math:`80` datapoints and the validation set has :math:`20` and the batch size is :math:`1` for both, an epoch consists of :math:`80` iterations for the training set and :math:`20` for the validation set. If the validate function is run :math:`10` times(:attr:`frequency`) per epoch of the training set, then :attr:`batches` must be :math:`2`. """ def __init__(self, dataloader, validate, frequency=10, batches=None, drop_last=False, **kwargs): self.name = kwargs.pop('name', 'validate') self.dataloader = dataloader self.frequency = frequency self.batches = batches self.drop_last = drop_last self.validate = validate def __call__(self, trainer, signal, **kwargs): r""" Responds to the following signals: * ``'on_training_start'``: To be called before start of training. Automatically finds the number of batches per run. * ``'on_batch_end'``: Called after the training loop. Calls the :attr:`validate` function. * ``'on_training_end'``: To be called after training. If :attr:`drop_last`, calls the :attr:`validate` function. * ``'load_state'``: Loads the state of this callback from :attr:`path`. * ``'save_state'``: Saves the state of this callback to :attr:`path`. """ if signal == 'on_training_start': if self.batches is None: self.batches = int(len(self.dataloader) // self.frequency) elif signal == 'on_batch_end' and trainer.iterations != 0: batches_per_epoch = len(trainer.dataloader) if not trainer.iterations % int(batches_per_epoch // self.frequency): self.validate_batch(trainer) elif signal == 'on_training_end': if not self.drop_last: self.validate_batch(trainer) elif signal == 'load_state': self.load_state(kwargs.pop('path')) elif signal == 'save_state': self.save_state(kwargs.pop('path')) def validate_batch(self, trainer): with mag.eval(*trainer.models): for _ in range(self.batches): self.validate(trainer, self.dataloader) def load_state(self, path): from magnet.training.utils import load_object state_dict = load_object(path / self.name / 'dataloader.p', default=None) if state_dict is not None: self.dataloader.load_state_dict(state_dict) def save_state(self, path): from magnet.training.utils import save_object save_object(self.dataloader.state_dict(), path / self.name / 'dataloader.p') class Checkpoint: r"""Serializes stateful objects during the training process. For many practical Deep Learning projects, training takes many hours, even days. As such, it is only natural that you'd want to save the progress every once in a while. This callback saves the models, optimizers, schedulers and the trainer itself periodically and automatically loads from those states if found. Args: path (pathlib.Path): The root path to save to interval (str): The time between checkpoints. Default: '5 m' Keyword Args: name (str): Name of this callback. Default: ``'checkpoint'`` * :attr:`interval` should be a string of the form ``'{duration} {unit}'``. Valid units are: ``'us'`` (microseconds), ``'ms'`` (milliseconds), ``'s'`` (seconds), ``'m'`` (minutes)', ``'h'`` (hours), ``'d'`` (days). """ def __init__(self, path, interval='5 m', **kwargs): self.name = kwargs.pop('name', 'checkpoint') self.path = path self.interval = self.parse_duration(interval) @staticmethod def parse_duration(interval): interval, multiplier = interval.split(' ') interval = float(interval); multiplier = multiplier.lower() multiplier_dict = {'m': 60, 's': 1, 'h': 3600, 'ms': 1e-3, 'us': 1e-6, 'd': 24 * 3600} multiplier = multiplier_dict[multiplier] return interval * multiplier def __call__(self, trainer, signal, **kwargs): r""" Responds to the following signals: * ``'on_training_start'``: To be called before start of training. Creates the path if it doesn't exist and loads from it if it does. Also sets the starting time. * ``'on_batch_end'``: Called after the training loop. Checkpoints if the interval is crossed and resets the clock. * ``'on_training_end'``: To be called after training. Checkpoints one last time. * ``'load_state'``: Loads the state of this callback from :attr:`path`. * ``'save_state'``: Saves the state of this callback to :attr:`path`. """ if signal == 'on_training_start': self.path.mkdir(parents=True, exist_ok=True) trainer.load_state(self.path) self.start_time = time() elif signal == 'on_batch_end' and trainer.iterations != 0 and time() - self.start_time > self.interval: trainer.save_state(self.path) self.start_time = time() elif signal == 'on_training_end': trainer.save_state(self.path) elif signal == 'load_state': self.load_state(trainer, kwargs.pop('path')) elif signal == 'save_state': self.save_state(trainer, kwargs.pop('path')) def clear_state(self): from shutil import rmtree rmtree(self.path) def load_state(self, trainer, path): from magnet.training.utils import load_object state_dict = load_object(path / self.name / 'dataloader.p', default=None) if state_dict is not None: trainer.dataloader.load_state_dict(state_dict) def save_state(self, trainer, path): from magnet.training.utils import save_object save_object(trainer.dataloader.state_dict(), path / self.name / 'dataloader.p') class ColdStart: r"""Starts the trainer in ``eval`` mode for a few iterations. Sometimes, you may want to find out how the model performs prior to any training. This callback freezes the training initially. Args: epochs (float): The number of epochs to freeze the trainer. Default: :math:`0.1` Keyword Args: name (str): Name of this callback. Default: ``'coldstart'`` """ def __init__(self, epochs=0.1, **kwargs): self.name = kwargs.pop('name', 'coldstart') self.epochs = epochs self.iterations = kwargs.pop('iterations', None) def __call__(self, trainer, signal, **kwargs): r""" Responds to the following signals: * ``'on_training_start'``: To be called before start of training. Sets the models in ``eval`` mode. * ``'on_batch_end'``: Called after the training loop. If the :attr:`epochs` is exhausted, unfreezes the trainer and removes this callback from the queue. """ if signal == 'on_training_start': torch.no_grad() for model in trainer.models: model.eval() if self.iterations is None: self.iterations = int(self.epochs * len(trainer.dataloader)) elif signal == 'on_batch_end' and trainer.iterations == self.iterations - 1: torch.enable_grad() for model in trainer.models: model.train() trainer.callbacks.remove(self) class LRScheduler: r"""A helper callback to add in optimizer schedulers. Args: scheduler (``LRScheduler``): The scheduler. Keyword Args: name (str): Name of this callback. Default: ``'lr_scheduler'`` """ def __init__(self, scheduler, **kwargs): self.name = kwargs.pop('name', 'lr_scheduler') self.scheduler = scheduler def __call__(self, trainer, signal, **kwargs): r""" Responds to the following signals: * ``'on_batch_start'``: Called before the training loop. If it is the start of an epoch, steps the scheduler. """ if signal == 'on_batch_start' and trainer.epochs('start'): self.scheduler.step() elif signal == 'load_state': self.load_state(kwargs.pop('path')) elif signal == 'save_state': self.save_state(kwargs.pop('path')) def load_state(self, path): from magnet.training.utils import load_state load_state(self.scheduler, path / self.name, alternative_name='scheduler') def save_state(self, path): from magnet.training.utils import save_state save_state(self.scheduler, path / self.name, alternative_name='scheduler') class CallbackQueue(list): r"""A container for multiple callbacks that can be called in parallel. If multiple callbacks need to be called together (as intended), they can be registered via this class. Since callbacks need to be unique (by their name), this class also ensures that there are no duplicates. """ def append(self, callback): if not self.exists(callback.name): super().append(callback) def extend(self, callbacks): super().extend([callback for callback in callbacks if not self.exists(callback.name)]) def find(self, name): r"""Scans through the registered list and finds the callback with :attr:`name`. If not found, returns None. Raises: RuntimeError: If multiple callbacks are found. """ callbacks = [callback for callback in self if callback.name == name] if len(callbacks) == 0: return None if len(callbacks) == 1: return callbacks[0] raise RuntimeError('Multiple callbacks with the same name found!') def exists(self, name): return self.find(name) is not None def __call__(self, signal, *args, **kwargs): r"""Broadcasts a signal to all registered callbacks along with payload arguments. Args: signal (object): Any object that is broadcast as a signal. .. note:: Any other arguments will be sent as-is to the callbacks. """ for callback in self: callback(*args, **kwargs, signal=signal) ================================================ FILE: magnet/training/history.py ================================================ from magnet.utils.plot import smooth_plot class History(dict): r"""A dictionary-like repository which is used to store several metrics of interest in training in the form of snapshots. This object can be utilized to collect, store and analyze training metrics against a variety of features of interest (epochs, iterations, time etc.) Since this is a subclass of ``dict``, it can be used as such. However, it is prefered to operate it using the class-specific methods. Examples:: >>> history = History() >>> # Add a simple value with a time stamp. >>> # This is like the statement: history['loss'] = 69 >>> # However, any additional stamps can also be attached. >>> history.append('loss', 69, time=time()) {'loss': [{'val': 69, 'time': 1535095251.6717412}]} >>> history.clear() >>> # Use a small buffer-size of 10. >>> # This means that only the latest 10 values are kept. >>> for i in range(100): history.append('loss', i, buffer_size=10) >>> # Flush the buffer with a time stamp. >>> history.flush(time=time()) >>> # The mean of the last 10 values is now stored. {'loss': [{'val': 94.5, 'time': 1535095320.9745226}]} """ def find(self, key): r"""A helper method that returns a filtered dictionary with a search key. Args: key (str): The filter key Examples:: >>> # Assume the history is empty with keys: ['loss', 'val_loss', >>> # 'encoder_loss', 'accuracy', 'wierd-metric'] >>> history.find('loss') {'loss': [], 'val_loss': [], 'encoder_loss': []} """ return {k: self[k] for k in self.keys() if key in k} def append(self, key, value, validation=False, buffer_size=None, **stamps): r"""Append a new snapshot to the history. Args: key (str): The dictionary key / name of the object value (object): The actual object valdiation (bool): Whether this is a validation metric. Default: ``False`` buffer_size (int or None): The size of the buffer of the key. Default: ``None`` * :attr:`validation` is just a convinient key-modifier. It appends ``'val_'`` to the key. * :attr:`buffer_size` defines the size of the storage buffer for the specific :attr:`key`. The latest :attr:`buffer_size` snapshots are stored. If None, the :attr:`key` is stored as is. .. note:: Any further keyword arguments define :attr:`stamps` that are essentially the signatures for the snapshot. """ if validation: key = 'val_' + key try: self[key].append(value, buffer=(buffer_size is not None), **stamps) except KeyError: # If key does not exist, add it as new. self[key] = SnapShot(buffer_size) self[key].append(value, buffer=(buffer_size is not None), **stamps) def show(self, key=None, log=False, x_key=None, validation=True, legend=None, **kwargs): r""" Plot the snapshots for a key against a stamp. Args: key (str): The key of the record log (bool): If ``True``, the y-axis will be log-scaled. Default: ``False`` x_key (str or None): The stamp to use as the x-axis. Default: ``None`` validation (bool): Whether to plot the validation records (if they exist) as well. Default: ``True`` legend (str or None): The legend entry. Default: ``None`` Keyword Args: ax (pyplot axes object): The axis to plot into. Default: ``None`` smoothen (bool): If ``True``, smoothens the plot. Default: ``True`` window_fraction (float): How much of the plot to use as a window for smoothing. Default: :math:`0.3` gain (float): How much more dense to make the plot. Default: :math:`10` replace_outliers (bool): If ``True``, replaces outlier datapoints by a sensible value. Default: ``True`` * :attr:`key` can be ``None``, in which case this method is successively called for all existing keys. The :attr:`log` attribute is overriden, however. It is only set to ``True`` for any key with ``'loss'`` in it. * :attr:`legend` can be ``None``, in which case the default legends ``'training'`` and ``'validation'`` are applied respectively. """ from matplotlib import pyplot as plt ax = kwargs.pop('ax', None) if key is None: for k in self.keys(): if 'val_' in k: continue self.show(k, 'loss' in k, x_key, validation, **kwargs) plt.show() return if ax is None: _, ax = plt.subplots() label = 'training' if legend is None else legend self[key].show(ax, x_key, label=label, **kwargs) if validation: try: label = 'validation' if legend is None else legend self['val_' + key].show(ax, x_key, label=label) except KeyError: pass if log: plt.yscale('log') plt.ylabel(key.title()) if isinstance(x_key, str): plt.xlabel(x_key) plt.title(f'{key.title()} vs {x_key.title()}') elif isinstance(x_key, str): plt.xlabel(x_key) plt.title(f'{key.title()} vs {x_key.title()}') else: plt.title(key.title()) plt.legend() def flush(self, key=None, **stamps): r""" Flush the buffer (if exists) and append the mean. Args: key (str or None): The key to flush. Default: ``None`` * :attr:`key` can be None, in which case this method is successively called for all existing keys. .. note:: Any further keyword arguments define :attr:`stamps` that are essentially the signatures for the snapshot. """ if key is None: for k in self.keys(): self.flush(k, **stamps) return self[key].flush(**stamps) class SnapShot: r""" A list of stamped values (snapshots). This is used by the History object to store a repository of training metrics. Args: buffer_size (int): The size of the buffer. Default: :math:`-1` * If :attr:`buffer_size` is negative, then the snapshots are stored as is. """ def __init__(self, buffer_size=-1): self._snaps = [] if buffer_size is not None: self._buffer_size = buffer_size self._buffer = SnapShot(buffer_size=None) def append(self, value, buffer=False, **stamps): r""" Add a new snapshot. Args: value (object): The value to add buffer (bool): If ``True``, adds to the buffer instead. Default: ``False`` .. note:: Any further keyword arguments define :attr:`stamps` that are essentially the signatures for the snapshot. """ if buffer: self._buffer.append(value, **stamps) # Remove the first value if buffer overflowed. if self._buffer_size > 0 and len(self._buffer) > self._buffer_size: self._buffer._pop(0) return self._snaps.append(dict(val=value, **stamps)) def flush(self, **stamps): r""" Flush the buffer (if exists) and append the mean. .. note:: Any keyword arguments define :attr:`stamps` that are essentially the signatures for the snapshot. """ if not hasattr(self, '_buffer') or len(self._buffer) == 0: return values = self._buffer._retrieve() value = sum(values) / len(values) self.append(value, **stamps) # Clear the entire buffer if the buffer size is not finite. if self._buffer_size < 0: self._buffer._clear() def _retrieve(self, key='val', stamp=None): if stamp is None: return [snap[key] for snap in self._snaps] return list(zip(*[(snap[stamp], snap[key]) for snap in self._snaps if stamp in snap.keys()])) def _pop(self, index): self._snaps.pop(index) def _clear(self): self._snaps = [] def __len__(self): return len(self._snaps) def __getitem__(self, index): return self._snaps[index]['val'] def __repr__(self): return repr(self._snaps) def show(self, ax, x=None, label=None, **kwargs): r""" Plot the snapshots against a stamp. Args: ax (pyplot axes object): The axis to plot into x (str or None): The stamp to use as the x-axis. Default: ``None`` label (str or None): The label for the line. Default: ``None`` * :attr:`key` can be None, in which case this method is successively called for all existing keys. The :attr:`log` attribute is overriden, however. It is only set to ``True`` for any key with ``'loss'`` in it. * :attr:`legend` can be ``None``, in which case the default legends ``'training'`` and ``'validation'`` are applied respectively. Keyword Args: (): See :py:meth:`History.show` for more details. .. note:: Any further keyword arguments are passed to the plot function. """ if x is None: x = list(range(len(self))) y = self._retrieve() else: x, y = self._retrieve(stamp=x) if len(x) != 0: window_fraction = kwargs.pop('window_fraction', 0.3) gain = kwargs.pop('gain', 10) replace_outliers = kwargs.pop('replace_outliers', True) if kwargs.pop('smoothen', True): line, = ax.plot(x, y, alpha=0.3) smooth_plot(x, y, label=label, ax=ax, c=line.get_color(), window_fraction=window_fraction, gain=gain, replace_outliers=replace_outliers, **kwargs) else: ax.plot(x, y, label=label, **kwargs) ================================================ FILE: magnet/training/train.py ================================================ from torch import optim from contextlib import contextmanager class Trainer: r"""Abstract base class for training models. The Trainer class makes it incredibly simple and convinient to train, monitor, debug and checkpoint entire Deep Learning projects. Simply define your training loop by implementing the :py:meth:`optimize` method. Args: models (list of :py:class:`nn.Module`): All the models that need to be trained optimizers (list of :py:class:`optim.Optimizer`): Any optimizers that are used .. note:: If any model is in eval() model, the trainer is *set off*. This means that as per protocol, *all* models will not train. Attributes: callbacks (list): A list of callbacks attached to the trainer. Take a look at :py:class:`SupervisedTrainer` for an idea on how to extend this class. """ def __init__(self, models, optimizers): self.models = models self.optimizers = optimizers self.parameters = set() self.register_parameter('iterations', 0) def optimize(self): r""" Defines the core optimization loop. This method is called on each iteration. Two quick protocols that one needs to follow are: 1. **Do NOT** actually backpropagate or step() the optimizers if the trainer is not training. Use the :py:meth:`is_training` method to find out. This is essential since this will ensure that the trainer behaves as expected when :py:meth:`is_training` is ``False``. Useful, for example, in cases like :py:class:`callbacks.ColdStart` 2. Send a callback the signal ``'gradient'`` with a keyword argument ``'models'`` that is the list of models that accumulate a gradient. Usually, it's all the modules (``self.modules``). Any callbacks that listen to this signal are interested in the gradient information (eg. ``callbacks.Babysitter``). """ raise NotImplementedError def train(self, dataloader, epochs=1, callbacks=None, **kwargs): r"""Starts the training process. Args: dataloader (``DataLoader``): The MagNet dataloader that iterates over the training set epochs (float or int): The number of epochs to train for. Default: ``1`` callbacks (list): Any callbacks to be attached. Default: ``None`` Keyword Args: iterations (int): The number of iterations to train for. Overrides :attr:`epochs`. .. note:: PyTorch ``DataLoader`` s are not supported. Ideally, encapsulate your dataset in the ``Data`` class. """ from magnet.training.callbacks import CallbackQueue self.dataloader = dataloader if callbacks is None: callbacks = [] self.callbacks = CallbackQueue(callbacks) total_iterations = kwargs.get('iterations', int(epochs * len(dataloader))) self.callbacks('on_training_start', trainer=self, total_iterations=total_iterations) for self.iterations in range(self.iterations, self.iterations + total_iterations): next(self) self.callbacks('on_training_end', trainer=self) def __iter__(self): return self def __next__(self): self.callbacks('on_batch_start', trainer=self) self.optimize() self.callbacks('on_batch_end', trainer=self) @contextmanager def mock(self, path=None): r"""A context manager that creates a temporary *'safe'* scope for training. All impact to stateful objects (models, optimizers and the trainer itself) are forgotten once out of this scope. This is very useful if you need to try out *what-if experiments*. Args: path (pathlib.Path): The path to save temporary states into Default: ``{System temp directory}/.mock_trainer`` """ from shutil import rmtree if path is None: from pathlib import Path from tempfile import gettempdir path = Path(gettempdir()) / '.mock_trainer' rmtree(path, ignore_errors=True) # Remove any existing directory self.save_state(path) try: yield finally: self.load_state(path) rmtree(path) def epochs(self, mode=None): r"""The number of epochs completed. Args: mode (str or None): If the mode is ``'start'`` or ``'end'``, a boolean is returned signalling if it's the start or end of an epoch """ if mode is None: return self.iterations / len(self.dataloader) if mode == 'start': return (self.iterations / len(self.dataloader)).is_integer() if mode == 'end': return ((self.iterations + 1) / len(self.dataloader)).is_integer() def is_training(self): return all(model.training for model in self.models) def load_state(self, path): from magnet.training.utils import load_state, load_object for i, model in enumerate(self.models): load_state(model, path / 'models', alternative_name=str(i)) for i, optimizer in enumerate(self.optimizers): load_state(optimizer, path / 'optimizers', alternative_name=str(i)) state_dict = load_object(path / 'state.p', default={}) for attr, val in state_dict.items(): self.register_parameter(attr, val) try: self.callbacks('load_state', trainer=self, path=path / 'callbacks') except AttributeError: pass try: self.dataloader.load_state_dict(path / 'dataloader.p') except AttributeError: pass def save_state(self, path): from magnet.training.utils import save_state, save_object for i, model in enumerate(self.models): save_state(model, path / 'models', alternative_name=str(i)) for i, optimizer in enumerate(self.optimizers): save_state(optimizer, path / 'optimizers', alternative_name=str(i)) state_dict = {attr: getattr(self, attr) for attr in self.parameters} save_object(state_dict, path / 'state.p') try: self.callbacks('save_state', trainer=self, path=path / 'callbacks') except AttributeError: pass try: self.dataloader.save_state_dict(path / 'dataloader.p') except AttributeError: pass def register_parameter(self, name, value): r"""Use this to register *'stateful'* parameters that are serialized """ setattr(self, name, value) self.parameters.add(name) class SupervisedTrainer(Trainer): r"""A simple trainer that implements a supervised approach where a simple model :math:`\hat{y} = f(x)` is trained to map :math:`\hat{y}` to ground-truth :math:`y` according to some specified loss. This is the training routine that most high-level deep learning frameworks implement. Args: model (``nn.Module``): The model that needs to be trained optimizer (str or optim.Optimzer): The optimizer used to train the model. Default: ``'adam'`` loss (str or ``callable``): A loss function that gives the objective to be minimized. Default: ``'cross_entropy'`` metrics (list): Any other metrics that need to be monitored. Default: ``None`` * :attr:`optimizer` can be an actual ``optim.Optimizer`` instance or the name of a popular optimzizer (eg. ``'adam'``). * :attr:`loss` can be a function or the name of a popular loss function (eg. ``'cross_entropy'``). It should accept 2 arguments (:math:`\hat{y}`, :math:`y`). * :attr:`metrics` should contain a list of functions which accept 2 arguments (:math:`\hat{y}`, :math:`y`), like the loss function. .. note:: A static :py:meth:`validate` function is provided for the validation callback .. note:: The :attr:`metrics` is of no use unless there is some callback (eg.``callbacks.Monitor``) to receive the metrics Examples:: >>> import magnet as mag >>> import magnet.nodes as mn >>> from magnet.data import Data >>> from magnet.training import callbacks, SupervisedTrainer >>> data = Data.get('mnist') >>> model = mn.Linear(10, act=None) >>> model.build(x=next(data())[0]) >>> trainer = SupervisedTrainer(model) >>> callbacks=[callbacks.Monitor(), callbacks.Validate(data(64, mode='val'), SupervisedTrainer.validate)] >>> trainer.train(data(64, shuffle=True), 1, callbacks) """ def __init__(self, model, optimizer='adam', loss='cross_entropy', metrics=None): from magnet.nodes.functional import wiki if isinstance(optimizer, str): optimizer = optimizer_wiki[optimizer.lower()](model.parameters()) if isinstance(loss, str): loss = wiki['losses'][loss.lower()] if metrics is None: metrics = [] if not isinstance(metrics, (tuple, list)): metrics = [metrics] for i, metric in enumerate(metrics): if isinstance(metric, str): metrics[i] = (metric, wiki['metrics'][metric.lower()]) super().__init__([model], [optimizer]) self.loss = loss self.metrics = metrics def optimize(self): optimizer = self.optimizers[0] loss = self.get_loss(self.dataloader) # Protocol 1: Backprop and step() only if trainer is training if self.is_training(): loss.backward() # Protocol 2: Broadcast the models that accumulate the gradient # using signal 'gradient' before clearing them. self.callbacks('gradient', trainer=self, models=self.models) optimizer.step() optimizer.zero_grad() @staticmethod def validate(trainer, dataloader): r"""Static helper method to validate models in :attr:`trainer` against data in :attr:`dataloader`. Can be passed to ``callbacks.Validate()``. """ trainer.get_loss(dataloader, validation=True) def get_loss(self, dataloader, validation=False): r"""Utility function that returns the loss and broadcasts metrics. """ def write_stats(key, value): self.callbacks('write_stats', trainer=self, key=key, value=value, validation=validation, buffer_size=len(dataloader)) model = self.models[0] x, y = next(dataloader) y_pred = model(x) loss = self.loss(y_pred, y) # Broadcast the loss and any other metrics using the 'write_stats' signal. write_stats('loss', loss.item()) for metric in self.metrics: write_stats(metric[0], metric[1](y_pred, y).item()) return loss def finish_training(path, names=None): r""" A helper function for cleaning up the training logs and other checkpoints and retaining only the state_dicts of the trained models. Args: path (pathlib.Path): The path where the trainer was checkpointed names (list): The names of the models in the order given to the trainer. Default: ``None`` * :attr:`names` can be used if the models themselves did not have names prior to training. The checkpoints default to an ordered naming scheme. If passed, the files are additionally renamed to these names. .. note:: Does nothing / fails silently if the path does not exist. Example:: >>> # Assume that we've defined two models - encoder and decoder, >>> # and a suitable trainer. The models do not have a 'name' attribute. >>> trainer.save_state(checkpoint_path / 'my-trainer') >>> # Suppose the checkpoint directory contains the following files: >>> # my-trainer/ >>> # models/ >>> # 0.pt >>> # 1.pt >>> # callbacks/ >>> # monitor/ >>> # babysitter/ >>> # state.p >>> finish_training(path, names=['encoder', 'decoder']) >>> # Now the directory contains these files: >>> # encoder.pt >>> # decoder.pt """ if not path.exists(): return import shutil if isinstance(names, str): names = [names] filenames = list((path / 'models').glob('*.pt')) if names is None: names = [filename.stem for filename in filenames] for name, filename in zip(names, filenames): shutil.move(filename, path.parent / (name + '.pt')) shutil.rmtree(path) optimizer_wiki = {'adam': optim.Adam} ================================================ FILE: magnet/training/utils.py ================================================ import torch, pickle import magnet as mag def load_state(module, path, alternative_name=None): r"""Loads the state_dict of a PyTorch object from a specified path. This is a more robust version of the of the PyTorch way in the sense that the device mapping is automatically handled. Args: module (object): Any PyTorch object that has a state_dict path (pathlib.Path): The path to folder containing the state_dict file alternative_name (str or None): A fallback name for the file if the module object does not have a name attribute. Default: ``None`` Raises: RuntimeError: If no :attr:`alternative_name` is provided and the module does not have a name. .. note:: If you already know the file name, set :attr:`alternative_name` to that. This is just a convinience method that assumes that the file name will be the same as the name of the module (if there is one). """ name = alternative_name if not hasattr(module, 'name') else module.name if name is None: raise RuntimeError('Module Name is None!') filepath = path / (name + '.pt') device = 'cuda:0' if mag.device.type == 'cuda' else 'cpu' # Needed patch if filepath.exists(): module.load_state_dict(torch.load(filepath, map_location=device)) def save_state(module, path, alternative_name=None): r"""Saves the state_dict of a PyTorch object to a specified path. Args: module (object): Any PyTorch object that has a state_dict path (pathlib.Path): The path to a folder to save the state_dict to alternative_name (str or None): A fallback name for the file if the module object does not have a name attribute. Default: ``None`` Raises: RuntimeError: If no :attr:`alternative_name` is provided and the module does not have a name. """ name = alternative_name if not hasattr(module, 'name') else module.name if name is None: raise RuntimeError('Module Name is None!') path.mkdir(parents=True, exist_ok=True) filepath = path / (name + '.pt') torch.save(module.state_dict(), filepath) def load_object(path, **kwargs): r"""A convinience method to unpickle a file. Args: path (pathlib.Path): The path to the pickle file Keyword Args: default (object): A default value to be returned if the file does not exist. Default: ``None`` Raises: RuntimeError: If a default keyword argument is not provided and the file is not found. """ if path.exists(): with open(path, 'rb') as f: return pickle.load(f) elif 'default' in kwargs.keys(): return kwargs['default'] else: raise RuntimeError(f'The path {path} does not exist. No default provided either.') def save_object(obj, path): r"""A convinience method to pickle an object. Args: obj (object): The object to pickle path (pathlib.Path): The path to save to .. note:: If the :attr:`path` does not exists, it is created. """ path.parent.mkdir(parents=True, exist_ok=True) with open(path, 'wb') as f: pickle.dump(obj, f) ================================================ FILE: magnet/utils/__arghandle__/__init__.py ================================================ ================================================ FILE: magnet/utils/__arghandle__/images.py ================================================ import arghandle import numpy as np, matplotlib.pyplot as plt from arghandle.handlers import typecheck from pathlib import Path from torch import is_tensor def show_images(images, titles=None, pixel_range='auto', cmap='gray', shape='square', resize='smean', merge=True, retain=False, savepath=None, **kwargs): images = __handle_image_type(images) images = __handle_image_dimensions(images) n_images = len(images) if titles is None and not merge: titles = [None] * n_images typecheck(pixel_range=pixel_range, include=(str, tuple, list, np.ndarray)) if pixel_range == 'auto': pixel_range = (min(image.min() for image in images), max(image.max() for image in images)) elif isinstance(pixel_range, str): raise ValueError(f"pixel_range should be either a (min, max) tuple or 'auto'\nGot {pixel_range}") shape = __handle_shape(n_images, shape) if isinstance(resize, str): resize = __handle_resize(images, resize) typecheck(savepath=savepath, include=(Path, str, None)) return arghandle.args() def _show_image(image, title=None, cmap='gray', ax=None, pixel_range='auto', retain=False): if image.shape[-1] == 1: image = image.squeeze(-1) if ax is None: ax = plt.subplots()[1] return arghandle.args() def __handle_shape(n_images, shape): typecheck(shape=shape, include=(str, tuple, list)) # String shapes if isinstance(shape, str): return __handle_string_shape(n_images, shape) # Shapes have to be positive integers if not all(isinstance(s, int) and s > 0 for s in shape): raise ValueError('All shape elements need to be positive integers') # Shape mismatch with number of images n_shape = np.prod(shape) if n_shape != n_images: if n_images == 1: error_msg = f'is just one image!' else: error_msg = f'are {n_images} images!' error_msg = f"""The shape {shape} has {n_shape} cells. But there """ + error_msg + """ \nLet it be the default ('square') if you're unsure.""" raise ValueError(error_msg) return shape def __handle_string_shape(n_images, shape): if shape == 'row': return 1, n_images if shape == 'column': return n_images, 1 if shape == 'square': return __square_factors(n_images) raise ValueError(f"`shape` needs to be one of 'square', 'row' or 'column'. Got {shape}") def __handle_resize(images, size='smean'): shapes = np.array([image.shape[:-1] for image in images]) # Make all the shapes square if size[0] == 's': shapes = np.array([[int(np.sqrt(np.prod(s)))] * 2 for s in shapes]) size = size[1:] if size == 'min': size = shapes.min(0) elif size == 'max': size = shapes.max(0) elif size == 'mean': size = shapes.mean(0) size = size.astype(np.uint) return size def __square_factors(x): if x == 1: return 1, 1 if x == 2: return 1, 2 factors = [i for i in range(2, int(np.sqrt(x)) + 1) if x % i == 0] # x is prime if len(factors) == 0: return 1, x return factors[-1], x // factors[-1] def __handle_image_dimensions(images, stacked=True): if isinstance(images, (list, tuple)): return [__handle_image_dimensions(image, stacked=False) for image in images] if stacked and isinstance(images, np.ndarray): return images if len(images.shape) == 2: return np.repeat(np.expand_dims(images, -1), 3, -1) error_msg = f'Incorrect image dimensions.\nGot {images.shape}' if len(images.shape) in (3, 4): if images.shape[-1] == 1: return np.repeat(images, 3, -1) elif images.shape[-1] != 3: raise ValueError(error_msg) return images raise ValueError(error_msg) def __handle_image_type(image): if __is_generator(image): image = list(image) if isinstance(image, (list, tuple)): return [__handle_image_type(img) for img in image] if isinstance(image, np.ndarray): return image if isinstance(image, str): image = Path(str) if isinstance(image, Path): if not image.exists(): raise RuntimeError(f'No such file exists: {image}') return plt.imread(image) if is_tensor(image): if len(image.shape) == 4: return image.permute(0, 2, 3, 1).detach().cpu().numpy() return image.permute(1, 2, 0).detach().cpu().numpy() def __is_generator(iterable): return hasattr(iterable,'__iter__') and not hasattr(iterable,'__len__') ================================================ FILE: magnet/utils/__init__.py ================================================ from ._node import summarize ================================================ FILE: magnet/utils/_node.py ================================================ import magnet as mag def summarize(module, x, parameters='trainable', arguments=False, batch=False, max_width=120): r"""Prints a pretty picture of how a one-input one output sequential model works. Similar to ``Model.summarize`` found in Keras. Args: module (``nn.Module``): The module to summarize x (``torch.Tensor``): A sample tensor sent as input to the :attr:`module`. parameters (str or True): Which kind of parameters to enumerate. Default: ``'trainable'`` arguments (bool): Whether to show the arguments to a node. Default: ``False`` batch (bool): Whether to show the batch dimension in the shape. Default: ``False`` max_width (int): The maximum width of the table. Default: ``120`` * :attr:`parameters` is one of [``'trainable'``, ``'non-trainable'``, ``'all'``, ``True``]. `'trainable'` parameters are the ones which require gradients and can be optimized by SGD. Setting this to ``True`` will print both types as a tuple. """ from torch.nn import Sequential from beautifultable import BeautifulTable from magnet.nodes import Node from magnet.utils.misc import num_params def _handle_parameter_output(mode, node=None): str_dict = {'trainable': 'Trainable', 'non-trainable': 'NON-Trainable', 'all': '', True: '(Trainable, NON-Trainable)'} if mode == 'col': return str_dict[parameters] + ' Parameters' def _get_num_params(module): n = num_params(module) if module is not None else (0, 0) n_dict = {'trainable': n[0], 'non-trainable': n[1], 'all': sum(n), True: n} n = n_dict[parameters] return ', '.join(['{:,}'] * len(n)).format(*n) if isinstance(n, tuple) else '{:,}'.format(n) if mode == 'row': return _get_num_params(node) print('Total ' + str_dict[parameters] + ' Parameters:', _get_num_params(module)) _start_idx = 0 if batch else 1 shape_sequence = [x.shape] children = list(module.children()) if isinstance(module, Sequential) else [module] for m in children: with mag.eval(m): x = m(x) shape_sequence.append(x.shape) shape_sequence = [', '.join(str(i) for i in s[_start_idx:]) for s in shape_sequence] table = BeautifulTable(max_width=max_width) column_headers = ['Node', 'Shape'] if parameters is not False: column_headers.append(_handle_parameter_output('col')) if arguments: column_headers.append('Arguments') table.column_headers = column_headers row = ['input', shape_sequence[0]] if parameters is not False: row.append(_handle_parameter_output('row')) if arguments: row.append('') table.append_row(row) for node, shape in zip(children, shape_sequence[1:]): name = node.name if hasattr(node, 'name') else str(node).split('(')[0] row = [name, shape] if parameters is not False: row.append(_handle_parameter_output('row', node)) if arguments: if isinstance(node, Node):row.append(node.get_args()) else: row.append('') table.append_row(row) print(table) if parameters is not False: _handle_parameter_output('total') ================================================ FILE: magnet/utils/images.py ================================================ import numpy as np import matplotlib.pyplot as plt from skimage.transform import resize as imresize from arghandle import arghandle @arghandle def show_images(images, **kwargs): r"""A nifty helper function to show images represented by tensors. Args: images (list or numpy.ndarray or str or torch.Tensor): The images to show * :attr:`images` can be anything which from you could conceivable harvest an image. If it's a :py:class:`torch.Tensor`, it is converted to a :py:class:`numpy.ndarray`. The first dimension of the tensor is treated as a batch dimension. If it's a ``str``, it is treated as a glob path from which all images are extracted. More commonly, a list of numpy arrays can be given. Keyword Arguments: pixel_range (tuple or ``'auto'``): The range of pixel values to be expected. Default: ``'auto'`` cmap (str or None): The color map for the plots. Default: ``'gray'`` merge (bool): If ``True``, all images are merged into one giant image. Default: ``True`` titles (list or None): The titles for each image. Default: ``None`` shape (str): The shape of the merge tile. Default: ``'square'`` resize (str): The common shape to which images are resized. Default: ``'smean'`` retain (bool): If ``True``, the plot is retained. Default: ``False`` savepath (str or None): If given, the image is saved to this path. Default: ``None`` * :attr:`pixel_range` default to the range in the image. * :attr:`titles` should only be given if :attr:`merge` is ``True``. .. note:: The merge shape is controlled by :attr:`shape` which can be either ``'square'``, ``'row'``, ``'column'`` or a ``tuple`` which explicitly specifies this shape. ``'square'`` automatically finds a shape with least difference between the number of rows and columns. This is aesthetically pleasing. In the explicit case, the product of the tuple needs to equal the number of images. """ titles = kwargs.pop('titles', None) pixel_range = kwargs.pop('pixel_range', 'auto') cmap = kwargs.pop('cmap', 'gray') shape = kwargs.pop('shape', 'square') resize = kwargs.pop('resize', 'smean') merge = kwargs.pop('merge', True) retain = kwargs.pop('retain', False) savepath = kwargs.pop('savepath', None) images = _resize(images, resize) if merge: _show_image(_merge(images, shape), titles, cmap, None, pixel_range, retain) return fig, axes = plt.subplots(shape[0], shape[1]) for ax, title, image in zip(axes.flat, titles, images): _show_image(image, title, cmap, ax, pixel_range, retain=True) fig.tight_layout() if not retain: plt.show() if savepath is not None: plt.savefig(Path(savepath), dpi=400, bbox_inches='tight') def _resize(images, size='smean'): return np.stack([imresize(image, size, order=1, mode='constant', anti_aliasing=False, preserve_range=True) for image in images]) def _merge(images, shape): images = images.reshape((*shape, *images.shape[1:])) for _ in range(2): images = np.concatenate([img for img in images], axis=1) return images @arghandle def _show_image(image, title=None, cmap='gray', ax=None, pixel_range='auto', retain=False): image = (image - pixel_range[0]) * 255 / (pixel_range[1] - pixel_range[0]) ax.imshow(image.astype(np.uint8), cmap) ax.set_xticks([]); ax.set_yticks([]); ax.grid(False) if title is not None: ax.set_title(title) if not retain: plt.show() ================================================ FILE: magnet/utils/misc.py ================================================ try: get_ipython() except NameError: in_notebook = False else: in_notebook = True def caller_locals(ancestor=False): """Print the local variables in the caller's frame.""" import inspect frame = inspect.currentframe().f_back.f_back try: l = frame.f_locals if ancestor: f_class = l.pop('__class__', None) caller = l.pop('self') while f_class is not None and isinstance(caller, f_class): l.pop('args', None) args = frame.f_locals.pop('args', None) l.update(frame.f_locals) if args is not None: l['args'] = args l.pop('self', None) frame = frame.f_back f_class = frame.f_locals.pop('__class__', None) l.pop('self', None) l.pop('__class__', None) return l finally: del frame def num_params(module): from numpy import prod trainable, non_trainable = 0, 0 for p in module.parameters(): n = prod(p.size()) if p.requires_grad: trainable += n else: non_trainable += n return trainable, non_trainable def get_tqdm(): r"""Returns a flexible tqdm object according to the environment of execution. """ import tqdm mode = 'tqdm_notebook' if in_notebook else 'tqdm' return getattr(tqdm, mode) ================================================ FILE: magnet/utils/plot.py ================================================ import numpy as np import matplotlib.pyplot as plt from .statistical import smoothen, _spline_interpolate, find_outliers def smooth_plot(*args, **kwargs): r"""Same as the plot function from matplotlib... only smoother! This function plots a modified, smoothened version of the data. Useful when data is jagged and one is interested in the average trends. Keyword Args: window_fraction (float): The fraction of the data to use as window to the smoothener. Default: :math:`0.3` gain (float): The amount of artificial datapoints inserted per raw datapoint. Default: :math:`10` replace_outliers (bool): If ``True``, replaces outlier datapoints by a sensible value. Default: ``True`` ax (Pyplot axes object): The axis to plot onto. Default: ``None`` .. note:: Uses a Savitzky Golay filter to smoothen out the data. """ ax = kwargs.pop('ax', None) window_fraction = kwargs.pop('window_fraction', 0.3) gain = kwargs.pop('gain', 10) replace_outliers = kwargs.pop('replace_outliers', True) lines = plt.plot(*args, **kwargs) if ax is None else ax.plot(*args, **kwargs) def _smoothen_line(line): x, y = line.get_data() x_new = np.linspace(x.min(), x.max(), int(gain * len(x))) if replace_outliers: outlier_mask = find_outliers(y) y = y[~outlier_mask] x = x[~outlier_mask] y = smoothen(y, window_fraction, outlier_mask=None) if len(x) > 1: y_new = _spline_interpolate(x, y, x_new) line.set_data(x_new, y_new) else: line.set_data(x, y) for l in lines: _smoothen_line(l) return lines ================================================ FILE: magnet/utils/statistical.py ================================================ import warnings import numpy as np from scipy.signal import savgol_filter from scipy import interpolate def find_outliers(data, threshold=3.5, window_fraction=0.15): """Based on http://www.itl.nist.gov/div898/handbook/eda/section3 /eda35h.htm """ def _handle_args(): if not isinstance(data, np.ndarray) and not isinstance(data, list): raise TypeError('data needs to be a list or numpy array. Got {}'.format(type(data))) if len(data) == 0: raise ValueError('data is empty!') if len(data.shape) == 1: return find_outliers(np.expand_dims(data, -1), threshold, window_fraction) if window_fraction < 0 or window_fraction > 1: raise ValueError('window_fraction should be a fraction (duh!). But got {}'.format(window_fraction)) if np.isinf(window_fraction) or np.isnan(window_fraction): raise ValueError('window_fraction should be a finite number but got {}'.format(window_fraction)) if threshold < 0: raise ValueError( 'threshold should be non negative but got {}'.format( threshold)) elif np.isinf(threshold) or np.isnan(threshold): raise ValueError( 'threshold should be a finite number but got {}'.format( threshold)) arg_err = _handle_args() if arg_err is not None: return arg_err # Subdivide data into small windows window_length = max(int(len(data) * window_fraction), 1) if len(data) - window_length >= 1: split_data = np.stack([data[i:i + window_length] for i in range(len(data) - window_length + 1)]) else: split_data = np.expand_dims(data, 0) def _find_outliers(x): outlier_factor = 0.6745 median = np.median(x, axis=0) distances = np.linalg.norm(x - median, axis=-1) median_deviation = np.median(distances) # No deviation. All values are same. No outlier if median_deviation == 0: return np.array([False] * len(x)) modified_z_scores = outlier_factor * distances / median_deviation outlier_mask = modified_z_scores > threshold return outlier_mask outlier_idx = np.concatenate([np.arange(i, i + window_length)[_find_outliers(d)] for i, d in enumerate(split_data)]) return np.array([i in np.unique(outlier_idx) for i in range(len(data))]) def smoothen(data, window_fraction=0.3, **kwargs): order = kwargs.pop('order', 3) outlier_mask = kwargs.pop('outlier_mask', find_outliers) interpolate_fn = kwargs.pop('interpolate_fn', _spline_interpolate) def _handle_args(): nonlocal data if not isinstance(data, np.ndarray) and not isinstance(data, list): raise TypeError('data needs to be a list or numpy array. Got {}'.format(type(data))) if len(data) == 0: raise ValueError('data is empty!') if np.any(np.isnan(data)) or np.any(np.isinf(data)): raise ValueError('some of the data is either nan or inf') if len(data.shape) > 1: raise ValueError('data needs to be 1-dimensional for now') if not isinstance(window_fraction, float): raise TypeError('window_fraction should be a fraction (duh!). But got {}'.format(type(window_fraction))) if window_fraction < 0 or window_fraction > 1: raise ValueError('window_fraction should be a fraction (duh!). But got {}'.format(window_fraction)) if np.isinf(window_fraction) or np.isnan(window_fraction): raise ValueError('window_fraction should be a finite number but got {}'.format(window_fraction)) if not isinstance(order, int): raise TypeError('order needs to be a non-negative integer but got {}'.format(type(order))) if order < 0: raise ValueError('order needs to be a non-negative integer but got {}'.format(order)) # Replace Outliers if outlier_mask is not None: if interpolate_fn is None: raise ValueError('if outlier_mask is not None, need interpolate_fn') outliers = outlier_mask(data) new_data = data.copy() if len(np.where(outliers)[0]) != 0 and len(np.where(~outliers)[0]) > 1: new_data[outliers] = interpolate_fn(np.where(~outliers)[0], data[~outliers], np.where(outliers)[0]) data = new_data _handle_args() window_length = int(len(data) * window_fraction) # savgol_filter needs an odd window_length if window_length % 2 == 0: window_length = max(window_length - 1, 1) if window_length <= order: warnings.warn('window_fraction ({}) too low for order ({}) and length ({}) of data' '\nReturning raw data'.format(window_fraction, order, len(data)), RuntimeWarning) return data return savgol_filter(data, window_length, order) def _spline_interpolate(x, y, x_new, **kwargs): s = kwargs.pop('s', 0) k = kwargs.pop('k', 3) extrapolate = kwargs.pop('extrapolate', True) def _handle_args(): nonlocal x, y # Sort the data in ascending order order_idx = np.argsort(x) x = x[order_idx] y = y[order_idx] _handle_args() t, c, k = interpolate.splrep(x, y, s=s, k=k) spline = interpolate.BSpline(t, c, k, extrapolate=extrapolate) return spline(x_new) ================================================ FILE: magnet/utils/varseq.py ================================================ import torch, numpy as np from torch.nn.utils.rnn import pack_sequence, pad_packed_sequence, pack_padded_sequence def pack(sequences, lengths=None): r"""Packs a list of variable length Tensors Args: sequences (list or torch.Tensor): The list of Tensors to pack lengths (list): list of lengths of each tensor. Default: ``None`` .. note:: If :attr:`sequences` is a tensor, :attr:`lengths` needs to be provided. .. note:: The packed sequence that is returned has a convinient :py:meth:`unpack` method as well as ``shape`` and ``order`` attributes. The ``order`` attribute stores the sorting order which should be used for unpacking. Shapes: :attr:`sequences` should be a list of Tensors of size L x *, where L is the length of a sequence and * is any number of trailing dimensions, including zero. """ from types import MethodType n = len(sequences) if isinstance(sequences, (tuple, list)) else len(sequences[0]) shape = sequences[0].shape[1:] if isinstance(sequences, (tuple, list)) else sequences.shape[2:] # Check if a batched Tensor is provided (lengths is None) # or an explicit list of Tensors if lengths is None: lengths = list(map(len, sequences)) order = np.argsort(lengths)[::-1] sequences = [sequences[i] for i in order] sequences = pack_sequence(sequences) sequences.order = order else: order = np.argsort(lengths)[::-1].copy() sequences = sequences[:, order] lengths = lengths[order] sequences = pack_padded_sequence(sequences, torch.tensor(lengths)) sequences.order = order sequences.unpack = MethodType(lambda self, as_list=False: unpack(self, as_list), sequences) sequences.shape = torch.Size([-1, n] + list(shape)) return sequences def unpack(sequence, as_list=False): r"""Unpacks a ``PackedSequence`` object. Args: sequence (``PackedSequence``): The tensor to unpack. as_list (bool): If ``True``, returns a list of tensors. Default: ``False`` .. note:: The sequence should have an ``order`` attribute that stores the sorting order. """ order = sequence.order sequences, lengths = pad_packed_sequence(sequence) order = np.argsort(order) sequences = sequences[:, order]; lengths = lengths[order] if not as_list: return sequences, lengths return [sequence[:l.item()] for sequence, l in zip(sequences.transpose(0, 1), lengths)] def sort(sequences, order, dim=0): r"""Sorts a tensor in a certain order along a certain dimension. Args: sequences (torch.Tensor): The tensor to sort order (numpy.ndarray): The sorting order dim (int): The dimension to sort. Default ``0`` """ return torch.index_select(sequences, dim, torch.tensor(order.copy(), device=sequences.device)) def unsort(sequences, order, dim=0): r"""Unsorts a tensor in a certain order along a certain dimension. Args: sequences (torch.Tensor): The tensor to unsort order (numpy.ndarray): The sorting order dim (int): The dimension to unsort. Default ``0`` """ return torch.index_select(sequences, dim, torch.tensor(np.argsort(order.copy()), device=sequences.device)) ================================================ FILE: readthedocs.yml ================================================ # .readthedocs.yml build: image: latest python: version: 3.6 setup_py_install: true ================================================ FILE: setup.py ================================================ #!/usr/bin/env python # -*- coding: utf-8 -*- from setuptools import setup setup( name='MagNet', version='0.1', description='MagNet makes it stupid simple to create Deep Learning projects', author='Vaisakh', author_email='svaisakh1994@gmail.com', url='https://github.com/svaisakh/magnet', packages=['magnet', 'arghandle'], license='MIT license', zip_safe=False, classifiers=[ 'Development Status :: 2 - Pre-Alpha', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Programming Language :: Python :: 3.6', ], install_requires=[ 'torch==0.4.1', 'torchvision==0.2.1', 'matplotlib==2.2.2', 'beautifultable==0.5.2', 'tqdm==4.23.4', 'scikit-image==0.14.0', 'scipy==1.1.0', 'pytest==3.7.4', 'pytest-cov==2.5.1' ] ) ================================================ FILE: tests/data/test_dataloader.py ================================================ import pytest from magnet.data import Data class TestDataLoader: def test_batch_size_cannnot_be_too_high(self): data = Data.get('mnist') with pytest.raises(RuntimeError): data(batch_size=10000000) ================================================ FILE: tests/nodes/test_core.py ================================================ import torch from torch import nn import magnet as mag from magnet.nodes.core import Lambda, Conv, Linear, RNN, LSTM, GRU, BatchNorm torch.no_grad() class TestLambda: def test_lambda_function_has_name_lambda(self): fn = lambda x: x ** 2 node = Lambda(fn) assert node.name == '' def test_function_name_transferred(self): def fn(x): return x**2 node = Lambda(fn) assert node.name == 'fn' def test_square(self): x = torch.ones(4, 1, 28, 28, device=mag.device) node = Lambda(lambda x: x ** 2).eval() assert torch.all(node(x) == x ** 2) class TestConv: def test_half_padding_args(self): x = torch.ones(4, 1, 28, 28) conv_half = Conv().eval() conv_half(x) conv = Conv(2, p=1, s=2).eval() conv(x) assert conv._args == conv_half._args def test_half_padding(self): conv = Conv().eval() assert conv(torch.ones(4, 1, 28, 28)).shape == (4, 2, 14, 14) def test_same_padding(self): conv = Conv(p='same').eval() assert conv(torch.ones(4, 1, 28, 28)).shape == (4, 1, 28, 28) def test_double_padding(self): conv = Conv(p='double').eval() assert conv(torch.ones(4, 2, 28, 28)).shape == (4, 1, 56, 56) def test_conv_1d(self): conv = Conv().eval() conv(torch.randn(1, 2, 3)) assert isinstance(conv.layer, nn.Conv1d) def test_conv_2d(self): conv = Conv().eval() conv(torch.randn(1, 2, 3, 4)) assert isinstance(conv.layer, nn.Conv2d) def test_conv_3d(self): conv = Conv().eval() conv(torch.randn(1, 2, 3, 4, 5)) assert isinstance(conv.layer, nn.Conv3d) def test_mul_list(self): conv_layer = Conv().eval() cs = (5, 3, 2) convs = conv_layer * cs assert convs[0] is conv_layer assert all(conv._args[k] == conv_layer._args[k] for k in conv_layer._args.keys() if k != 'c' for conv in convs) assert all(conv._args['c'] == c for conv, c in zip(convs, cs)) class TestLinear: def test_flatten(self): linear = Linear() y = linear(torch.ones(4, 1, 28, 28)) assert linear.layer.weight.shape == (1, 784) assert y.shape == (4, 1) def test_inflate(self): linear = Linear((1, 28, 28)) y = linear(torch.ones(4, 1)) assert linear.layer.weight.shape == (784, 1) assert y.shape == (4, 1, 28, 28) def test_mul_list(self): lin_layer = Linear().eval() os = (50, 30, 20) lins = lin_layer * os assert lins[0] is lin_layer assert all(lin._args[k] == lin_layer._args[k] for k in lin_layer._args.keys() if k != 'o' for lin in lins) assert all(lin._args['o'] == o for lin, o in zip(lins, os)) class TestRNN: base = RNN def test_shape(self): node = self.base(300).eval() x, h = node(torch.ones(7, 4, 100)) assert x.shape == (7, 4, 300) if not isinstance(h, tuple): h = (h, ) for h_i in h: assert h_i.shape == (1, 4, 300) def test_mul_list(self): rnn_layer = self.base(300).eval() hs = (300, 500, 200) rnns = rnn_layer * hs assert rnns[0] is rnn_layer assert all(rnn._args[k] == rnn_layer._args[k] for k in rnn_layer._args.keys() if k != 'h' for rnn in rnns) assert all(rnn._args['h'] == h for rnn, h in zip(rnns, hs)) class TestLSTM(TestRNN): base = LSTM class TestGRU(TestRNN): base = GRU class TestBatchNorm: def test_bn_1d(self): bn = BatchNorm().eval() bn(torch.randn(4, 2)) assert isinstance(bn.layer, nn.BatchNorm1d) bn(torch.randn(4, 2, 3)) assert isinstance(bn.layer, nn.BatchNorm1d) def test_bn_2d(self): bn = BatchNorm().eval() bn(torch.randn(4, 2, 3, 4)) assert isinstance(bn.layer, nn.BatchNorm2d) def test_bn_3d(self): bn = BatchNorm().eval() bn(torch.randn(4, 2, 3, 4, 5)) assert isinstance(bn.layer, nn.BatchNorm3d) ================================================ FILE: tests/nodes/test_nodes.py ================================================ import pytest from magnet.nodes import Node class TestNode: def test_not_built(self): node = Node() assert not node._built def test_store_arguments(self): args = [4, 2, 3] name = 'some_node' kwargs = {'r': 2, 'k': 4, 'tf': 34} node = Node(*args, name=name,**kwargs) assert node._args == {'args': tuple(args), **kwargs} assert node.name == name def test_name_is_not_senseless(self): with pytest.raises(ValueError): Node(name=None) Node(name='') def test_mul_int(self): n = 5 node = Node(5, 2, a=1) nodes = node * n assert nodes[0] is node assert all(nodes[i]._args == node._args for i in range(1, n)) def test_print_args(self): node = Node(5, 2, a=1) assert node.get_args() == 'args=(5, 2), a=1' def test_cannot_mul_list(self): with pytest.raises(NotImplementedError): node = Node() * (4, 2) ================================================ FILE: tests/test_debug.py ================================================ import pytest import matplotlib matplotlib.use('agg') from torch import nn import magnet as mag import magnet.nodes as mn import magnet.debug as mdb from magnet.data.core import MNIST from magnet.training import SupervisedTrainer def test_overfit(): data, model, trainer = get_obj() mdb.overfit(trainer, data, batch_size=64) class TestFlow: def test_ok(self): data, _, trainer = get_obj() mdb.check_flow(trainer, data) def test_broken(self): data, _, trainer = get_obj(broken=True) with pytest.raises(RuntimeError): mdb.check_flow(trainer, data) class TestBabysitter: def test_accumulating(self): data, model, trainer = get_obj() trainer.train(data(), callbacks=[mdb.Babysitter()]) history = trainer.callbacks[0].history assert len(history['layer.weight']) == 10 def get_obj(broken=False): data = MNIST(val_split=0.99) if broken: model = BrokenModel() else: model = mn.Linear(10, act=None) with mag.eval(model): model(next(data())[0]) trainer = SupervisedTrainer(model) return data, model, trainer class BrokenModel(nn.Module): def __init__(self): super().__init__() self.fc1 = mn.Linear() self.fc2 = mn.Linear(10, act=None) def forward(self, x): x = self.fc1(x).detach() x = self.fc2(x) return x def sample(self, x): x = self.fc1(x) return x ================================================ FILE: tests/training/test_callbacks.py ================================================ import torch import pytest import matplotlib matplotlib.use('agg') from torch.optim.lr_scheduler import ExponentialLR from pathlib import Path from shutil import rmtree import magnet as mag import magnet.nodes as mn import magnet.debug as mdb from magnet.data import Data from magnet.training import SupervisedTrainer, callbacks class TestCheckpoint: @staticmethod def get_callbacks(data, trainer, path): return [callbacks.Validate(data(mode='val'), trainer.validate), callbacks.Monitor(), callbacks.LRScheduler(ExponentialLR(trainer.optimizers[0], gamma=0.1)), mdb.Babysitter(), callbacks.Checkpoint(path)] def test_start_from_checkpoint(self): data, model, trainer = get_obj() save_path = Path.cwd() / '.mock_trainer' trainer.train(data(sample_space=0.01), callbacks=self.get_callbacks(data, trainer, save_path)) weight_before = copy_tensor(model.layer.weight.data.detach()) data, model, trainer = get_obj() trainer.train(data(sample_space=0.01), iterations=0, callbacks=self.get_callbacks(data, trainer, save_path)) assert torch.all(model.layer.weight.data.detach() == weight_before) rmtree(save_path) class TestColdStart: def test_not_trained(self): data, model, trainer = get_obj() model.eval() weight_before = copy_tensor(model.layer.weight.data.detach()) trainer.train(data(), epochs=0.1, callbacks=[callbacks.ColdStart()]) assert torch.all(model.layer.weight.data.detach() == weight_before) class TestLRScheduler: def test_lr_decay(self): data, _, trainer = get_obj() scheduler = ExponentialLR(trainer.optimizers[0], gamma=0.1) trainer.train(data(sample_space=0.01), callbacks=[callbacks.LRScheduler(scheduler)]) assert trainer.optimizers[0].param_groups[0]['lr'] == 1e-3 class TestCallbackQueue: def test_exists(self): queue = callbacks.CallbackQueue([callbacks.Monitor()]) assert queue.exists('monitor') assert not queue.exists('einstein') def test_multiple_callbacks_error(self): queue = callbacks.CallbackQueue([callbacks.Monitor() for _ in range(2)]) with pytest.raises(RuntimeError): queue.exists('monitor') def test_cannot_add_same_name(self): queue = callbacks.CallbackQueue([callbacks.Monitor()]) queue.append(callbacks.Monitor()) assert len(queue) == 1 queue.extend([callbacks.Monitor()]) assert len(queue) == 1 def get_obj(): data = Data.get('mnist') model = mn.Linear(10, act=None) with mag.eval(model): model(next(data())[0]) trainer = SupervisedTrainer(model) return data, model, trainer def copy_tensor(x): return torch.zeros_like(x).copy_(x) ================================================ FILE: tests/training/test_history.py ================================================ from time import time from magnet.training.history import History class TestHistory: def test_can_show(self): history = History() for _ in range(5): for i in range(100): history.append('loss', i, buffer_size=10) history.flush(time=time()) history.show() ================================================ FILE: tests/training/test_train.py ================================================ import torch import pytest from torch import optim from pathlib import Path from shutil import rmtree import magnet as mag import magnet.nodes as mn from magnet.data import Data from magnet.training import (Trainer, SupervisedTrainer, callbacks, finish_training) class TestTrainer: def test_cannot_call(self): data, model, _ = get_obj() trainer = Trainer([model], [optim.Adam(model.parameters())]) with pytest.raises(NotImplementedError): trainer.train(data(), iterations=1) class TestSupervisedTrainer: def test_iterations(self): data, _, trainer = get_obj() trainer.train(data(), iterations=100) assert trainer.iterations == 99 def test_epochs(self): data, model, trainer = get_obj() trainer.train(data(), epochs=0.01) assert trainer.iterations == int(len(data) * 0.01) - 1 def test_epoch_start(self): data, model, trainer = get_obj() trainer.train(data(), iterations=0) assert trainer.epochs('start') def test_epoch_end(self): data, model, trainer = get_obj() trainer.train(data(sample_space=0.01), iterations=int(len(data) * 0.01)) assert trainer.epochs('end') def test_less_loss(self): data, model, trainer = get_obj() cbacks = [callbacks.Validate(data(mode='val', sample_space=0.01), SupervisedTrainer.validate), callbacks.Monitor()] trainer.train(data(sample_space=0.01), epochs=0.3, callbacks=cbacks) losses = trainer.callbacks[1].history['loss'] assert losses[0] > losses[1] val_losses = trainer.callbacks[1].history['val_loss'] assert val_losses[0] > val_losses[1] def test_not_training_when_eval(self): data, model, trainer = get_obj() model.eval() weight_before = copy_tensor(model.layer.weight.data.detach()) trainer.train(data(), iterations=10) assert torch.all(model.layer.weight.data.detach() == weight_before) def test_mocking(self): data, model, trainer = get_obj() weight_before = copy_tensor(model.layer.weight.data.detach()) with trainer.mock(): trainer.train(data(), iterations=10) assert torch.all(model.layer.weight.data.detach() == weight_before) def test_change_batch_size(self): data, model, trainer = get_obj() save_path = Path.cwd() / '.mock_trainer' trainer.train(data(), iterations=10, callbacks=[callbacks.Checkpoint(save_path)]) trainer.train(data(batch_size=16), iterations=10, callbacks=[callbacks.Checkpoint(save_path)]) rmtree(save_path) def test_finish_training(): data, model, trainer = get_obj() save_path = Path.cwd() / '.mock_trainer' / 'trainer' trainer.train(data(), iterations=10, callbacks=[callbacks.Checkpoint(save_path)]) finish_training(save_path, names=['my_model']) files = list(save_path.parent.glob('*')) assert len(files) == 1 assert files[0].name == 'my_model.pt' rmtree(save_path.parent) def get_obj(): data = Data.get('mnist') model = mn.Linear(10, act=None) with mag.eval(model): model(next(data())[0]) trainer = SupervisedTrainer(model) return data, model, trainer def copy_tensor(x): return torch.zeros_like(x).copy_(x) ================================================ FILE: tests/utils/test__node.py ================================================ import torch from torch import nn import magnet.nodes as mn from magnet.utils import summarize def test_summarize_node(): model = mn.Linear(10, act=None) summarize(model, torch.randn(1, 1, 28, 28), arguments=True) def test_summarize_module(): model = nn.Linear(784, 10) summarize(model, torch.randn(1, 784), arguments=True) ================================================ FILE: tests/utils/test_images.py ================================================ import pytest import numpy as np import matplotlib matplotlib.use('agg') import torch from magnet.utils.images import show_images class TestShowImages: def test_pass_numpy_array(self): show_images(np.random.randn(64, 28, 28)) show_images(np.random.randn(64, 28, 28, 1)) show_images(np.random.randn(16, 28, 28, 3)) def test_torch_tensor(self): show_images(torch.randn(4, 1, 28, 28)) def test_cannot_mix_inputs(self): with pytest.raises(TypeError): show_images([np.random.randn(28, 28), './images/']) def test_pixel_range_string(self): with pytest.raises(ValueError): show_images([np.random.randn(28, 28)], pixel_range='min') def test_pixel_range_integer(self): with pytest.raises(TypeError): show_images([np.random.randn(28, 28)], pixel_range=2) def test_bad_merge_shape(self): with pytest.raises(ValueError): show_images([np.random.randn(28, 28)], shape=(2, 1)) def test_shape_negative(self): with pytest.raises(ValueError): show_images(np.random.randn(3, 28, 28), shape=(-4, 2)) def test_shape_row_column(self): for shape in ('row', 'column'): show_images([np.random.randn(28, 28)], shape=shape) def test_shape_dict(self): with pytest.raises(TypeError): show_images([np.random.randn(28, 28)], shape={}) def test_shape_evil(self): with pytest.raises(ValueError): show_images([np.random.randn(28, 28)], shape='churchill') def test_resize_negative(self): with pytest.raises(ValueError): show_images(np.random.randn(3, 28, 28), resize=(-4, 2)) def test_savepath_not_string(self): with pytest.raises(TypeError): show_images([np.random.randn(28, 28)], savepath=True) def test_can_plot_seperately(self): show_images([np.random.randn(28, 28, 3) for _ in range(4)], merge=False) ================================================ FILE: tests/utils/test_plot.py ================================================ import numpy as np from magnet.utils.plot import smooth_plot class TestSmoothenPlot: def test_get_gained_points_back(self): x = np.linspace(0, 1, 100) y = np.linspace(1, 2, 100) gain = 10 smooth_lines = smooth_plot(x, y, gain=gain) assert int(len(x) * gain) >= len(smooth_lines[0].get_xdata()) ================================================ FILE: tests/utils/test_statistical.py ================================================ import numpy as np import pytest import matplotlib matplotlib.use('agg') from magnet.utils.statistical import find_outliers, smoothen class TestRemoveOutlier: def test_data_can_be_1d(self): find_outliers(np.zeros(5)) def test_data_can_be_linear(self): find_outliers(np.linspace(0, 5, 100)) def test_cannot_send_none(self): with pytest.raises(Exception): find_outliers(None) def test_cannot_send_empty(self): with pytest.raises(ValueError): find_outliers([]) with pytest.raises(ValueError): find_outliers(np.array([])) def test_threshold_not_negative(self): with pytest.raises(ValueError): find_outliers(np.zeros(5), -1) def test_threshold_not_none(self): with pytest.raises(TypeError): find_outliers(np.zeros(5), None) def test_threshold_not_inf(self): with pytest.raises(ValueError): find_outliers(np.zeros(5), np.inf) def test_window_fraction_is_fraction(self): window_fraction = 2 with pytest.raises(ValueError): find_outliers(np.zeros(5), window_fraction=window_fraction) class TestSmoothen: def test_cannot_send_none(self): with pytest.raises(TypeError): smoothen(None) with pytest.raises(TypeError): smoothen(np.zeros(5), None) with pytest.raises(TypeError): smoothen(np.zeros(5), order=None) def test_cannot_send_empty(self): with pytest.raises(ValueError): smoothen([]) with pytest.raises(ValueError): smoothen(np.array([])) def test_cannot_send_2d(self): with pytest.raises(ValueError): smoothen(np.ones((4, 3))) def test_cannot_send_illegal(self): data = np.ones(100) with pytest.raises(ValueError): data[np.random.randint(0, len(data))] = np.nan smoothen(data) data = np.ones(10) with pytest.raises(ValueError): data[np.random.randint(0, len(data))] = np.inf smoothen(data) def test_window_fraction_is_fraction(self): window_fraction = 2.0 with pytest.raises(ValueError): smoothen(np.zeros(5), window_fraction=window_fraction) def test_window_fraction_too_low_warning(self): with pytest.warns(RuntimeWarning): smoothen(np.zeros(5), window_fraction=0.01) def test_order_cannot_be_negative(self): with pytest.raises(ValueError): smoothen(np.zeros(5), order=-1) def test_interpolate_fn_cannot_be_none(self): with pytest.raises(ValueError): smoothen(np.zeros(5), interpolate_fn=None) def test_returns_same_shape(self): data = np.ones(3) window_fraction = 0.3 window_length = int(len(data) * window_fraction) if window_length % 2 == 0: window_length = max(1, window_length - 1) order = 1 assert len(smoothen(data, window_fraction, order=order)) == len(data) ================================================ FILE: tests/utils/test_varseq.py ================================================ import torch import numpy as np from magnet.utils.varseq import pack, unpack def test_pack_unpack(): x = [torch.arange(i) for i in range(1, 6)] x_packed = pack(x) assert all(torch.all(x_unpacked_i[:len(x_i)] == x_i) for x_unpacked_i, x_i in zip(unpack(x_packed)[0].t(), x)) assert all(torch.all(x_unpacked_i == x_i) for x_unpacked_i, x_i in zip(unpack(x_packed, as_list=True), x)) def test_pack_padded(): x = torch.zeros(6, 6) for i in range(6): x[i, i:] = i x_packed = pack(x, lengths=np.arange(1, 7)) assert torch.all(unpack(x_packed)[0] == x)