diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..592fbba --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +name: ci +on: + push: + branches: + - master + - main + - simple_dataloaders +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v4 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - run: pip install mkdocs-material + - run: pip install mkdocs-material-extensions + - run: pip install mkdocs-jupyter + - run: pip install mkdocs-redirects + - run: pip install mkdocs-autorefs + - run: pip install mkdocs-awesome-pages-plugin + - run: pip install mkdocstrings + - run: pip install mkdocstrings-python + - run: pip install mknotebooks + - run: mkdocs gh-deploy --force \ No newline at end of file diff --git a/README.md b/README.md index 7a58a07..07ae2a6 100644 --- a/README.md +++ b/README.md @@ -11,23 +11,58 @@ PyPi link https://pypi.org/project/openml-pytorch/ #### Usage Import openML libraries ```python -import openml -import openml_pytorch -import openml_pytorch.layers +import torch.nn +import torch.optim + import openml_pytorch.config +import openml +import logging + +from openml_pytorch.trainer import OpenMLTrainerModule +from openml_pytorch.trainer import OpenMLDataModule +from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor, Lambda +import torchvision +from openml_pytorch.trainer import convert_to_rgb ``` -Create a torch model +Create a pytorch model and get a task from openML ```python -model = torch.nn.Sequential( - processing_net, - features_net, - results_net +model = torchvision.models.efficientnet_b0(num_classes=200) +# Download the OpenML task for tiniest imagenet +task = openml.tasks.get_task(362127) +``` +Download the task from openML and define Data and Trainer configuration +```python +transform = Compose( + [ + ToPILImage(), # Convert tensor to PIL Image to ensure PIL Image operations can be applied. + Lambda( + convert_to_rgb + ), # Convert PIL Image to RGB if it's not already. + Resize( + (64, 64) + ), # Resize the image. + ToTensor(), # Convert the PIL Image back to a tensor. + ] +) +data_module = OpenMLDataModule( + type_of_data="image", + file_dir="datasets", + filename_col="image_path", + target_mode="categorical", + target_column="Class_encoded", + batch_size = 64, + transform=transform +) +trainer = OpenMLTrainerModule( + data_module=data_module, + verbose = True, + epoch_count = 1, ) +openml_pytorch.config.trainer = trainer ``` -Download the task from openML and run the model on task. +Run the model on the task ```python -task = openml.tasks.get_task(3573) run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False) run.publish() print('URL for run: %s/run/%d' % (openml.config.server, run.run_id)) diff --git a/docs/API reference/Callbacks.md b/docs/API reference/Callbacks.md new file mode 100644 index 0000000..3399127 --- /dev/null +++ b/docs/API reference/Callbacks.md @@ -0,0 +1,6 @@ +# Callbacks +Callbacks module contains classes and functions for handling callback functions during an event-driven process. This makes it easier to customize the behavior of the training loop and add additional functionality to the training process without modifying the core code. + +To use a callback, create a class that inherits from the Callback class and implement the necessary methods. Callbacks can be used to perform actions at different stages of the training process, such as at the beginning or end of an epoch, batch, or fitting process. Then pass the callback object to the Trainer. + +::: callbacks \ No newline at end of file diff --git a/docs/API reference/Custom Datasets.md b/docs/API reference/Custom Datasets.md new file mode 100644 index 0000000..68d3d14 --- /dev/null +++ b/docs/API reference/Custom Datasets.md @@ -0,0 +1,4 @@ +# Custom Datasets +This module contains custom dataset classes for handling image and tabular data from OpenML in PyTorch. To add support for new data types, new classes can be added to this module. + +::: custom_datasets \ No newline at end of file diff --git a/docs/API reference/Metrics.md b/docs/API reference/Metrics.md new file mode 100644 index 0000000..31f6b0a --- /dev/null +++ b/docs/API reference/Metrics.md @@ -0,0 +1,5 @@ +# Metrics +This module provides utility functions for evaluating model performance and activation functions. +It includes functions to compute the accuracy, top-k accuracy of model predictions, and the sigmoid function. + +::: metrics \ No newline at end of file diff --git a/docs/API reference/OpenML Connection.md b/docs/API reference/OpenML Connection.md new file mode 100644 index 0000000..051f9aa --- /dev/null +++ b/docs/API reference/OpenML Connection.md @@ -0,0 +1,5 @@ +# OpenML Connection + +This module defines the Pytorch wrapper for OpenML-python. + +::: extension \ No newline at end of file diff --git a/docs/API reference/Trainer.md b/docs/API reference/Trainer.md new file mode 100644 index 0000000..ba4e82f --- /dev/null +++ b/docs/API reference/Trainer.md @@ -0,0 +1,10 @@ +# Trainer + +This module provides classes and methods to facilitate the configuration, data handling, training, and evaluation of machine learning models using PyTorch and OpenML datasets. The functionalities include: +- Generation of default configurations for models. +- Handling of image and tabular data. +- Training and evaluating machine learning models. +- Exporting trained models to ONNX format. +- Managing data transformations and loaders. + +::: trainer \ No newline at end of file diff --git a/docs/Examples/Create Dataset and Task.ipynb b/docs/Examples/Create Dataset and Task.ipynb new file mode 100644 index 0000000..af746d6 --- /dev/null +++ b/docs/Examples/Create Dataset and Task.ipynb @@ -0,0 +1,269 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create dataset and task - tiniest imagenet\n", + "- An example of how to create a custom dataset and task using the OpenML API and upload it to the OpenML server.\n", + "- Note that you must have an API key from the OpenML website to upload datasets and tasks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import openml\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import sklearn.datasets\n", + "\n", + "import openml\n", + "from openml.datasets.functions import create_dataset\n", + "import os\n", + "import requests\n", + "import zipfile\n", + "import glob" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create dataset on OpenML\n", + "- Instead of making our own, we obtain a subset of the ImageNet dataset from Stanford. This dataset has 200 classes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def create_tiny_imagenet():\n", + " dir_name = \"datasets\"\n", + " os.makedirs(dir_name, exist_ok=True)\n", + "\n", + " # download the dataset\n", + " url = \"http://cs231n.stanford.edu/tiny-imagenet-200.zip\"\n", + " r = requests.get(url, stream=True)\n", + "\n", + " if not os.path.exists(f\"{dir_name}/tiny-imagenet-200.zip\"):\n", + " with open(f\"{dir_name}/tiny-imagenet-200.zip\", \"wb\") as f:\n", + " f.write(r.content)\n", + "\n", + " with zipfile.ZipFile(f\"{dir_name}/tiny-imagenet-200.zip\", 'r') as zip_ref:\n", + " zip_ref.extractall(f\"{dir_name}/\")\n", + " ## recusively find all the images\n", + " image_paths = glob.glob(f\"{dir_name}/tiny-imagenet-200/train/*/*/*.JPEG\")\n", + " ## remove the first part of the path\n", + " image_paths = [path.split(\"/\", 1)[-1] for path in image_paths]\n", + " ## create a dataframe with the image path and the label\n", + " label_func = lambda x: x.split(\"/\")[2]\n", + " df = pd.DataFrame(image_paths, columns=[\"image_path\"])\n", + " df[\"label\"] = df[\"image_path\"].apply(label_func)\n", + " ## encode the labels as integers\n", + " df[\"Class_encoded\"] = pd.factorize(df[\"label\"])[0]\n", + "\n", + " ## encode types\n", + " df[\"image_path\"] = df[\"image_path\"].astype(\"string\")\n", + " df[\"label\"] = df[\"label\"].astype(\"string\")\n", + " df[\"Class_encoded\"] = df[\"Class_encoded\"].astype(\"int\")\n", + "\n", + "\n", + " name = \"tiny-imagenet-200\"\n", + " attribute_names = df.columns\n", + " description = \"Tiny ImageNet contains 100000 images of 200 classes (500 for each class) downsized to 64 x 64 colored images. Each class has 500 training images, 50 validation images, and 50 test images. The dataset here just contains links to the images and the labels. The dataset can be downloaded from the official website ![here](http://cs231n.stanford.edu/tiny-imagenet-200.zip). /n Link to the paper - [Tiny ImageNet Classification with CNN](https://cs231n.stanford.edu/reports/2017/pdfs/930.pdf)\"\n", + " paper_url = \"https://cs231n.stanford.edu/reports/2017/pdfs/930.pdf\"\n", + " citation = (\"Wu, J., Zhang, Q., & Xu, G. (2017). Tiny imagenet challenge. Technical report.\")\n", + "\n", + " tinyim = create_dataset(\n", + " name = name,\n", + " description = description,\n", + " creator= \"Jiayu Wu, Qixiang Zhang, Guoxi Xu\",\n", + " contributor = \"Jiayu Wu, Qixiang Zhang, Guoxi Xu\",\n", + " collection_date = \"2017\",\n", + " language= \"English\",\n", + " licence=\"DbCL v1.0\",\n", + " default_target_attribute=\"Class_encoded\",\n", + " attributes=\"auto\",\n", + " data=df,\n", + " citation=citation,\n", + " ignore_attribute=None\n", + " )\n", + " openml.config.apikey = ''\n", + " tinyim.publish()\n", + " print(f\"URL for dataset: {tinyim.openml_url}\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "create_tiny_imagenet()\n", + "# https://www.openml.org/d/46338" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Another, even tinier dataset\n", + "- We subset the previous dataset to 20 images per class." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "URL for dataset: https://www.openml.org/d/46339\n" + ] + } + ], + "source": [ + "def create_tiniest_imagenet():\n", + " dir_name = \"datasets\"\n", + " os.makedirs(dir_name, exist_ok=True)\n", + "\n", + " # download the dataset\n", + " url = \"http://cs231n.stanford.edu/tiny-imagenet-200.zip\"\n", + " r = requests.get(url, stream=True)\n", + "\n", + " if not os.path.exists(f\"{dir_name}/tiny-imagenet-200.zip\"):\n", + " with open(f\"{dir_name}/tiny-imagenet-200.zip\", \"wb\") as f:\n", + " f.write(r.content)\n", + "\n", + " with zipfile.ZipFile(f\"{dir_name}/tiny-imagenet-200.zip\", 'r') as zip_ref:\n", + " zip_ref.extractall(f\"{dir_name}/\")\n", + " ## recusively find all the images\n", + " image_paths = glob.glob(f\"{dir_name}/tiny-imagenet-200/train/*/*/*.JPEG\")\n", + " ## remove the first part of the path\n", + " image_paths = [path.split(\"/\", 1)[-1] for path in image_paths]\n", + " image_paths[-1]\n", + " ## create a dataframe with the image path and the label\n", + " label_func = lambda x: x.split(\"/\")[2]\n", + " df = pd.DataFrame(image_paths, columns=[\"image_path\"])\n", + " df[\"label\"] = df[\"image_path\"].apply(label_func)\n", + " ## encode the labels as integers\n", + " df[\"Class_encoded\"] = pd.factorize(df[\"label\"])[0]\n", + "\n", + " ## encode types\n", + " df[\"image_path\"] = df[\"image_path\"].astype(\"string\")\n", + " df[\"label\"] = df[\"label\"].astype(\"string\")\n", + " df[\"Class_encoded\"] = df[\"Class_encoded\"].astype(\"int\")\n", + "\n", + " # keep only first 20 images for each label\n", + " df = df.groupby(\"label\").head(20)\n", + "\n", + "\n", + " name = \"tiniest-imagenet-200\"\n", + " attribute_names = df.columns\n", + " description = \"Tiny ImageNet contains 100000 images of 200 classes (500 for each class) downsized to 64 x 64 colored images. !!! This dataset only links to 20 images per class (instead of the usual 500) and is ONLY for quickly testing a framework. !!! Each class has 500 training images, 50 validation images, and 50 test images. The dataset here just contains links to the images and the labels. The dataset can be downloaded from the official website ![here](http://cs231n.stanford.edu/tiny-imagenet-200.zip). /n Link to the paper - [Tiny ImageNet Classification with CNN](https://cs231n.stanford.edu/reports/2017/pdfs/930.pdf)\"\n", + " paper_url = \"https://cs231n.stanford.edu/reports/2017/pdfs/930.pdf\"\n", + " citation = (\"Wu, J., Zhang, Q., & Xu, G. (2017). Tiny imagenet challenge. Technical report.\")\n", + "\n", + " tinyim = create_dataset(\n", + " name = name,\n", + " description = description,\n", + " creator= \"Jiayu Wu, Qixiang Zhang, Guoxi Xu\",\n", + " contributor = \"Jiayu Wu, Qixiang Zhang, Guoxi Xu\",\n", + " collection_date = \"2017\",\n", + " language= \"English\",\n", + " licence=\"DbCL v1.0\",\n", + " default_target_attribute=\"Class_encoded\",\n", + " attributes=\"auto\",\n", + " data=df,\n", + " citation=citation,\n", + " ignore_attribute=None\n", + " )\n", + " openml.config.apikey = ''\n", + " tinyim.publish()\n", + " print(f\"URL for dataset: {tinyim.openml_url}\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "create_tiniest_imagenet()\n", + "# https://www.openml.org/d/46339" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create task on OpenML\n", + "- Now to actually use the OpenML Pytorch API, we need to have a task associated with the dataset. This is how we create it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "URL for task: https://www.openml.org/t/362127\n" + ] + } + ], + "source": [ + "def create_task():\n", + " # openml.config.apikey = 'KEY'\n", + " # Define task parameters\n", + " task_type = openml.tasks.TaskType.SUPERVISED_CLASSIFICATION\n", + " dataset_id = 46339 # Obtained from the dataset creation step\n", + " evaluation_measure = 'predictive_accuracy'\n", + " target_name = 'Class_encoded'\n", + " class_labels = list(map(str, range(200)))\n", + " cost_matrix = None\n", + "\n", + " # Create the task\n", + " new_task = openml.tasks.create_task(\n", + " task_type=task_type,\n", + " dataset_id=dataset_id, \n", + " estimation_procedure_id = 1,\n", + " evaluation_measure=evaluation_measure,\n", + " target_name=target_name,\n", + " class_labels=class_labels,\n", + " cost_matrix=cost_matrix\n", + " )\n", + " openml.config.apikey = ''\n", + " new_task.publish()\n", + " print(f\"URL for task: {new_task.openml_url}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "create_task()\n", + "# https://www.openml.org/t/362127" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/Examples/Image Classification Task.ipynb b/docs/Examples/Image Classification Task.ipynb new file mode 100644 index 0000000..39f91fe --- /dev/null +++ b/docs/Examples/Image Classification Task.ipynb @@ -0,0 +1,269 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Image classification task\n", + "- Image classification on OpenML Task (362127), tiniest ImageNet dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch.nn\n", + "import torch.optim\n", + "\n", + "import openml_pytorch.config\n", + "import openml\n", + "import logging\n", + "import warnings\n", + "\n", + "# Suppress FutureWarning messages\n", + "warnings.simplefilter(action='ignore')\n", + "\n", + "############################################################################\n", + "# Enable logging in order to observe the progress while running the example.\n", + "openml.config.logger.setLevel(logging.DEBUG)\n", + "openml_pytorch.config.logger.setLevel(logging.DEBUG)\n", + "############################################################################\n", + "\n", + "############################################################################\n", + "from openml_pytorch.trainer import OpenMLTrainerModule\n", + "from openml_pytorch.trainer import OpenMLDataModule\n", + "from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor, Lambda\n", + "import torchvision\n", + "\n", + "from openml_pytorch.trainer import convert_to_rgb" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define the Model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model = torchvision.models.efficientnet_b0(num_classes=200)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure the Data Module" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "transform = Compose(\n", + " [\n", + " ToPILImage(), # Convert tensor to PIL Image to ensure PIL Image operations can be applied.\n", + " Lambda(\n", + " convert_to_rgb\n", + " ), # Convert PIL Image to RGB if it's not already.\n", + " Resize(\n", + " (64, 64)\n", + " ), # Resize the image.\n", + " ToTensor(), # Convert the PIL Image back to a tensor.\n", + " ]\n", + ")\n", + "data_module = OpenMLDataModule(\n", + " type_of_data=\"image\",\n", + " file_dir=\"datasets\",\n", + " filename_col=\"image_path\",\n", + " target_mode=\"categorical\",\n", + " target_column=\"Class_encoded\",\n", + " batch_size = 64,\n", + " transform=transform\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure the Trainer Module" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trainer = OpenMLTrainerModule(\n", + " data_module=data_module,\n", + " verbose = True,\n", + " epoch_count = 1,\n", + " callbacks=[],\n", + ")\n", + "openml_pytorch.config.trainer = trainer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Download the task" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Download the OpenML task for tiniest imagenet\n", + "task = openml.tasks.get_task(362127)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the model on the task" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View loss" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "trainer.runner.cbs[1].plot_loss()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View learning rate" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "trainer.runner.cbs[1].plot_lr()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View the classes in the model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n", + " 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,\n", + " 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\n", + " 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\n", + " 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,\n", + " 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,\n", + " 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,\n", + " 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,\n", + " 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n", + " 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,\n", + " 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,\n", + " 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,\n", + " 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,\n", + " 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,\n", + " 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,\n", + " 195, 196, 197, 198, 199], dtype=uint8)" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "trainer.learn.model_classes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Publish the run to OpenML" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "run.publish()" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/Examples/Pretrained Transformer Image Classification Task.ipynb b/docs/Examples/Pretrained Transformer Image Classification Task.ipynb new file mode 100644 index 0000000..9a4b17f --- /dev/null +++ b/docs/Examples/Pretrained Transformer Image Classification Task.ipynb @@ -0,0 +1,268 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Pretrained Image classification example - Transformer\n", + "- Pretrained image classification using a Transformer architecture, \"custom\" Optimizer for OpenML Task (362127) , tiniest ImageNet dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch.nn\n", + "import torch.optim\n", + "\n", + "import openml\n", + "import openml_pytorch\n", + "import openml_pytorch.layers\n", + "import openml_pytorch.config\n", + "from openml import OpenMLTask\n", + "import logging\n", + "import warnings\n", + "from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor, Lambda\n", + "from openml_pytorch.trainer import convert_to_rgb\n", + "# Suppress FutureWarning messages\n", + "warnings.simplefilter(action='ignore')\n", + "\n", + "############################################################################\n", + "# Enable logging in order to observe the progress while running the example.\n", + "openml.config.logger.setLevel(logging.DEBUG)\n", + "openml_pytorch.config.logger.setLevel(logging.DEBUG)\n", + "############################################################################\n", + "\n", + "############################################################################\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# openml.config.apikey = 'key'\n", + "from openml_pytorch.trainer import OpenMLTrainerModule\n", + "from openml_pytorch.trainer import OpenMLDataModule\n", + "from openml_pytorch.trainer import Callback" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define the Model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Example model. You can do better :)\n", + "import torchvision.models as models\n", + "\n", + "# Load the pre-trained ResNet model\n", + "model = models.efficientnet_b0(pretrained=True)\n", + "\n", + "# Modify the last fully connected layer to the required number of classes\n", + "num_classes = 200\n", + "in_features = model.classifier[-1].in_features\n", + "# model.fc = nn.Linear(in_features, num_classes)\n", + "model.classifier = nn.Sequential(\n", + " nn.Dropout(p=0.2, inplace=True),\n", + " nn.Linear(in_features, num_classes),\n", + ")\n", + "\n", + "# Optional: If you're fine-tuning, you may want to freeze the pre-trained layers\n", + "# for param in model.parameters():\n", + "# param.requires_grad = False\n", + "\n", + "# # If you want to train the last layer only (the newly added layer)\n", + "# for param in model.fc.parameters():\n", + "# param.requires_grad = True" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure the Data Module" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "transform = Compose(\n", + " [\n", + " ToPILImage(), # Convert tensor to PIL Image to ensure PIL Image operations can be applied.\n", + " Lambda(\n", + " convert_to_rgb\n", + " ), # Convert PIL Image to RGB if it's not already.\n", + " Resize(\n", + " (64, 64)\n", + " ), # Resize the image.\n", + " ToTensor(), # Convert the PIL Image back to a tensor.\n", + " ]\n", + ")\n", + "data_module = OpenMLDataModule(\n", + " type_of_data=\"image\",\n", + " file_dir=\"datasets\",\n", + " filename_col=\"image_path\",\n", + " target_mode=\"categorical\",\n", + " target_column=\"Class_encoded\",\n", + " batch_size = 64,\n", + " transform=transform\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure the Trainer Module" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def custom_optimizer_gen(model: torch.nn.Module, task: OpenMLTask) -> torch.optim.Optimizer:\n", + " return torch.optim.Adam(model.fc.parameters())\n", + "\n", + "trainer = OpenMLTrainerModule(\n", + " data_module=data_module,\n", + " verbose = True,\n", + " epoch_count = 1,\n", + " optimizer = custom_optimizer_gen,\n", + " callbacks=[],\n", + ")\n", + "openml_pytorch.config.trainer = trainer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Download the task" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Download the OpenML task for tiniest imagenet\n", + "task = openml.tasks.get_task(362127)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the model on the task" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# Run the model on the task (requires an API key).m\n", + "run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View loss" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGdCAYAAADAAnMpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB0z0lEQVR4nO2deZhcZZn279q6eqvqvdNJd9LZw5KNPWE1bMaIIIIg86GgiMo4jo7Op4JLxkHhm0EHUXFldNA4UUQDiIAgIoQlIWzZCImErJ1O73tXd23n+6Pqfat6qz7n1Dl1zqm6f9dVV5LuWt6u7nTd9Tz3cz8uAAoIIYQQQizCbfUBCCGEEFLYUIwQQgghxFIoRgghhBBiKRQjhBBCCLEUihFCCCGEWArFCCGEEEIshWKEEEIIIZZCMUIIIYQQS/FafQC1zJo1CwMDA1YfgxBCCCEaCAQCOHbsWMbrOEKMzJo1Cy0tLVYfgxBCCCE6aGxszChIHCFGREWksbGR1RFCCCHEIQQCAbS0tEz72u0IMSIYGBigGCGEEELyDBpYCSGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoQQQgghlkIxQgghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoSYTuWMelzyqY+h8YTFVh+FEEKIDaEYIaZzwY3/gLWfvhmf/939+MSP78ais063+kiEEEJshNfqA5D8J1BTLf++5JxVWHLOKhzZvQfP/OLX2PHUM1DicQtPRwghxGpYGSGmU1xeBgD48w/vw/P/+zuEQyOYffKJ+Mi3v4kvP/pbrL7mSnj9fotPSQghxCooRojpFJeXAwBa972NTXf+F7556fvx5x/eh6GeXtTObsLVX/sivvrnP+Cim2+Ax+ez+LSEEEJyDcUIMR1RGRkZHAIADPX24ckf/Te++e4rsenO76C7pRWBmmqs++dP4dzrrrbyqIQQQiyAYoSYzngxIgiHRvD8/z6IO9/7Qbz66BMAxvpLCCGEFAYUI8R0RJsmNDg46efjsRi6jrQAAHwlxTk7FyGEEHtAMUJMxeVywV9WCgAYmUKMAEB4ZAQAUFRMMUIIIYUGxQgxlaLSErjdiR+zkcHhKa8XSYoRXzGnagghpNCgGCGmUpJs0UQjEURHR6e8XjiU+BwrI4QQUnhQjBBT8Qvz6sDULRogrTJCzwghhBQcFCPEVERlZGRoKOP16BkhhJDChWKEmEpxQFRGMosRekYIIaRwoRghplJclhQj01VG6BkhhJCChWKEmEpxINmmyTDWC9AzQgghhQzFCDEVWRmZrk0zysoIIYQUKhQjxFRkZWTaNg09I4QQUqhQjBBTKdY62uv3w+XmjyUhhBQS/K1PTCW1JC+zGBGjvUBCkBBCCCkcKEaIqYgleZmi4AEgOhqWf2erhhBCCguKEWIqaisjiqJI3whNrIQQUlhQjBBTSYmRzAZWgMFnhBBSqFCMEFNJtWkyV0aAtEh4Zo0QQkhBQTFCTEVURkKqKiOJrBEf2zSEEFJQUIwQUxFiZFSFGKFnhBBCChOKEWIaHp9PjumGVLRpUp4RihFCCCkkKEaIaYiqCACMDmUe7QXSPSM0sBJCSCFBMUJMQ5pXh4agxOPTXp+VEUIIKUwoRohplATUj/UCQHiEy/IIIaQQoRghpuEv0yZGIiFWRgghpBChGCGmURJQnzECAJHRZGWEOSOEEFJQUIwQ05CekQG1bRomsBJCSCFCMUJMo7i8FEDCwKqGCHNGCCGkIKEYIaaRqoyoa9OEZQIrKyOEEFJIaBIj69evh6IoYy579uyZ8vrPPPPMhOsrioJHH30064MT+1Os1cDK0V5CCClIvFpvsGvXLlx88cXy39FodMrrfuADH0BRUZH8d01NDbZv347f/e53Wh+WOJDiQCpnRA0y9IxihBBCCgrNYiQajaKtrU3VdXt6esb8+0Mf+hCGh4cpRgoEkcCqtk2TGu1lm4YQQgoJzZ6RRYsWoaWlBfv378eGDRswe/Zs1be96aab8Jvf/AbDw5mjwYuKihAIBMZciPOQYkR1ZYShZ4QQUohoEiNbt27FjTfeiLVr1+KWW27BvHnzsHnzZpQnjYqZOOOMM7Bs2TLcd99901731ltvRX9/v7y0tLRoOSaxCVoNrNIzwpwRQggpKDSJkSeeeAIPPvggdu7ciSeffBLr1q1DZWUlrrnmmmlve9NNN2HHjh3Ytm3btNe98847EQwG5aWxsVHLMYlNkJUR1XHw9IwQQkghotkzkk5fXx/27duHhQsXZrxeaWkpPvShD+HrX/+6qvsNh8MIh8PZHI3YAM1ihJ4RQggpSLLKGSkrK8OCBQvQ2tqa8Xof/OAH4ff7sWHDhmwejjgM0aYJqY2DZ2WEEEIKEk1i5K677sL555+P5uZmrF69Gps2bUIsFsPGjRsBAPfffz/uuOOOCbe76aab8NBDD6G7u9uYUxPb43K54C9LJrCqFCMy9IyeEUIIKSg0tWmampqwceNG1NTUoKOjA88//zxWrVqFzs5OAMCcOXMQj8fH3Gbx4sU477zzcMkllxh3amJ7ikpL4HYntO7IYObpKYGojHh9Pri9HsSjMdPORwghxD5oEiPXXXddxs+vWbNmwsf27dsHl8ul7VTE8ZQkWzTRSATR5Dbe6YiMpK7n8/sxGlUnYgghhDgb7qYhpuBPmldHVZpXASAaDsvKGn0jhBBSOFCMEFMo0WheFTBrhBBCCg+KEWIKxQERBa++MgKkxntZGSGEkMKBYoSYgtzYqzIKXiB8Iz4/s0YIIaRQoBghpiA39mps04TZpiGEkIKDYoSYgqyMaGzTpILPWBkhuackGMC//mED1n7mE1YfhZCCgmKEmIKsjGhs08jKCD0jxALmrlyOmYsW4Iwr3mv1UQgpKChGiCnIvTQqN/YKIqGEZ4QGVmIFFfW1AIBgbQ3cHo/FpyGkcKAYIaYgxYjeygg9I8QCgrU1AAC3xyP/TggxH4oRYgpiSZ5+zwjFCMk9gbpa+ffKhhkWnoSQwoJihJiCrIzonaahgZVYQMUYMVJv4UkIKSwoRogppMSIxsoIPSPEQgJ1qdYMKyOE5A6KEWIKsk3DnBHiICrq6lJ/Z2WEkJxBMUJMQVRGQlorI/SMEItwud0or6mS/2ZlhJDcQTFCTKFYx9ZeIC0Onp4RkmPKqyrh8Xrlv+kZISR3UIwQw/H4fHK3jNatvWFWRohFBNPMqwArI4TkEooRYjiiKgIAo0PDmm4rKyP0jJAcI8yrPa3HASQyRzw+n5VHIqRgoBghhiPNq0NDUOJxTbdlZYRYhRjrPf72O1IUV8yoy3QTQohBUIwQwykJ6BvrBYBIKDlN46dnhOQWEXjW396J3uNtANiqISRXUIwQw/GX6RcjDD0jViEqI30dneg93g6AJlZCcgXFCDGckoC+jBEgbbSXnhGSY4JJz0h/Ryd625KVkRkUI4TkAooRYjh699IAQFiO9lKMkNwSTAaeDXR2pVVG2KYhJBd4p78KIdooLi8FoH1jL5DyjNDASnKNqIz0tXeivJqVEUJyCcUIMZxUZUR7m4aeEWIFLpcLgZqEGBno6ERvVQUAVkYIyRUUI8RwirMwsArPiMfrhcfrRSwaNfRshExGWVUlPL7Er8P+ri4UHw8AoIGVkFxBzwgxnOJAKmdEK6IyAjD4jOSOQG2yKtLVjXg0Jkd7y6oqWaUjJAdQjBDDEQmseto08WgMsUiiGkLfCMkVFfXJjJGOTgCJn10hpivoGyHEdChGiOFIMaKjMgKk+0YoRkhuCNYmxUhnl/yYmKipom+EENOhGCGGk42BFQAio4nx3qISlsdJbhB7aQY6UmKkT6awsjJCiNlQjBDDkZURHQZWIGViZWWE5IqK+kTGSF9Hh/yYqIxUsDJCiOlQjBDDyVaMhJk1QnKMNLB2pLdpWBkhJFdQjBDDEW2akI44eAByYyorIyRXyL007Z3yY0xhJSR3UIwQQ3G5XPCXJRNYdYqRMPfTkBwjPCP9nWlihPtpCMkZFCPEUIpKS+B2J36sRgaHdd2H9Iz4aWAluSGYrIz0T1YZoRghxHQoRoihlCRbNNFIBNHkVIxWhGeEYVMkF5RVVsDr8wFILMkTCDFSEgzAX1pqydkIKRQoRoih+JPm1VGd5lUg5RmhgZXkgkCyKjLU0ztm/UA4FMJwfz8AmlgJMRuKEWIoJVmaV4G00DN6RkgOkObVjs4Jn6OJlZDcQDFCDKU4IKLgs6mMcLSX5I5gXWpb73g43ktIbqAYIYYiN/bqjIIH0uPg6Rkh5hOsE4FnrIwQYhUUI8RQ5MbeLNo0kRA9IyR3iMpIf1rgmSBVGaEYIcRMKEaIoaT20mRfGWHOCMkFIn21P2NlhG0aQsyEYoQYSrYbewHupiG5ReylmVyMsDJCSC6gGCGGIsWIzo29QFplhJ4RkgMm20sjkMvy8iD4bM3HrsfKd19k9TEImRSv1Qcg+YUxlRHupiG5o6JejPZ2TPhcX1tCjPhLS1ASDCKUzB1xGlWzGnDZv3wao8PD2P7kX6EoitVHImQMrIwQQzHCMxJhzgjJESXBILxFRQCAgc7uCZ+PhsMY6Ep83Mm+kbLKCgCAv7Q0L6o8JP+gGCGGIisjWYWecZqG5AZRFRnq7UM0HJ70Or1tzh/v9SdH7gGgrnm2hSchZHIoRoihpMRIFpUR7qYhOSI11jvRvCoQrRonL8wrLkvt1qmlGCE2hGKEGIps0xgQB8/KCDGbQG1yW28GMZIP473+NDHCygixIxQjxFBEZSSU1aI8VkZIbhBtmskCzwT5MN7rL021aWrnUIwQ+0ExQgyl2ICtvWHmjJAcIcd6O/O7MlJczsoIsTcUI8QwPD4ffP5ENSObrb0iDt7tdstJB0LMQASe9bVnEiN5UBlJM7DWNDXC7fFYeBpCJkIxQgxDVEUAYHRoWPf9REZH5d9ZHSFmEhRR8J3Tt2kqZtTl5Exm4C9NVUY8Pi+qZjZYeBpCJkIxQgxDmleHhqDE47rvJx6LyTHLohL6Roh5BIVnJENlpK+9A/F4HD6/H+XVVbk6mqGkG1gBTtQQ+0ExQgyjJJD9WK+AvhGSC4JimiaDZyQejWEgWTlxqm8kvWoJ0DdC7IcmMbJ+/XooijLmsmfPnoy3qaiowA9+8AMcO3YMIyMj2Lt3L97znvdkdWhiT0Rf2ggxInwjHO8lZlEcKJcTW5mmaYB0E6szfSOiTdPXnoi8pxghdkPzbppdu3bh4osvlv+ORqNTXtfn8+Gpp55Ce3s7rr76arS0tKC5uRm9vb26DkvsTUkg+4wRAbNGiNlU1CWqIsP9/Yim+ZQmo/d4G5qXn+zYyoho07Ts2YeK+jqO9xLboVmMRKNRtLW1qbruxz72MVRXV+Pss8+WouXQoUNaH5I4BCP20gi4n4aYTbBu+owRgYyEn+HMyoho0xzdsxcnXXAO6uZSjBB7odkzsmjRIrS0tGD//v3YsGEDZs+e+of68ssvx0svvYR7770Xx48fx86dO3HrrbfC7c78sEVFRQgEAmMuxP6ILINsNvYKInI/DQ2sxBxSYmRqv4ggNd7r0MpIsk1z9M23AABVMxvg8XJpO7EPmsTI1q1bceONN2Lt2rW45ZZbMG/ePGzevBnlyXfE45k/fz6uvvpqeDwerFu3Drfffju+8IUv4Ktf/WrGx7n11lvR398vLy0tLVqOSSwiVRkxrk1DAysxCzV7aQR9bQmvhVM33oo2TeehIxgZGoLb40HN7EaLT0VICk1i5IknnsCDDz6InTt34sknn8S6detQWVmJa665ZvI7d7vR3t6OT3ziE3jttdfwwAMP4Fvf+hY+9alPZXycO++8E8FgUF4aG/mfxgkUCwOroZURihFiDgFdlRFntmmEGBkdGkbnoaMAaGIl9iKrOl1fXx/27duHhQsXTvr51tZWRCIRxNMyJ/bs2YOZM2fC5/MhEolMertwOIzwFOu8iX0plgZWA0d76RkhJlGhxTMigs/q6+Byu7PK0ck13qIieH0+AMDI8DA6Dh1G00lLaGIltiKrnJGysjIsWLAAra2tk37+hRdewMKFC+FyueTHFi9ejGPHjk0pRIhzESY5I9o0ETlNQ88IMYeAhjZNf0cXYtEoPD4vAjXVZh/NUNIDz0aHhtF5OFEZYfAZsROaxMhdd92F888/H83NzVi9ejU2bdqEWCyGjRs3AgDuv/9+3HHHHfL6P/rRj1BdXY177rkHixYtwrp163Dbbbfh3nvvNfarILZAihED2jThED0jxFwq6hLx7mrEiBKPy+s5zcQqWzTDISjxODoOHQEA1LEyQmyEpjZNU1MTNm7ciJqaGnR0dOD555/HqlWr0JlML5wzZ86YlszRo0fx7ne/G3fffTd27NiBlpYW3HPPPfiP//gPY78KYguMNLAKz4iPlRFiEmJjr5o2DZAIPqua2YDKhhk4vPNNM49mKGKSZnQ4sS+q49BhAOB4L7EVmsTIddddl/Hza9asmfCxLVu2YPXq1dpORRyJrIwY6BmhgZWYQXF5GfylJQCAgQxR8Ok41cQq/l+OJv9fdiYrI5UNM+Ar9kvhT4iVcDcNMQwjxUiEo73ERETGSGhgULYEpyMVCe/MNs1IsjIy3NeP4b5+AEDN7CbLzkVIOhQjxDBEmyZkRBx8iAZWYh6pFo26qgjg4MpIaWqsVyB9IzSxEptAMUIMweVypYxyRlZGONpLTKCiXn3GiEBWRhwWfJaeMSKQvhGKEWITKEaIIRSVlsiY/5AhnhGGnhHzCNbqESPOrIz4hWckbcpNjvdyoobYBIoRYgglyRZNNBKZdgOqGugZIWYSrFcfeCboTS4IDdTVwO31mHIuMxBtmpG0ykgn2zTEZlCMEEPwj3PsZ0vKM0IxQownKDwjKidpAGCouxfRSARut1tmlDgBf5mojExs0zD4jNgFihFiCCUGmleB9MoIDay5pKapER9c/2Xc+fIzeM8/Z94h5WSC9cnAs3b1YkRRFPS1JXwjTlqY5y8fmzMCpAyswdqaMQmthFgFd0gTQygOiCh4YyojkWSrp4gG1pwwY/5cXHTzDTjlPZfA7Um0IC6++QbsfWEL3nn1DWsPZwKpyoj6Ng2QMLHWNDU6arxXtmnSqpajQ8MY6OpGoKYadc2zcfTNvVYdjxAArIwQgzByYy/AOPhc0XjiYtzwX3fgiw9vxGmXrYXb48GezS9i59PPAgA+uP7L8BYVWXxK45F7ado7NN3OiSbWydo0ANBxMNmqoYmV2ABWRoghpDb2GtWm4TSNmcxdsQwXf/JGnHje2fJjO556Bk/fdz+OvrkXxYFyzFl2EurnNeOST30Mj3/vxxae1lj8paVSPGsxsALODD5L7aYZK0Y6Dx/F/NNW0jdCbAErI8QQ5F4aowysaZ6R9K3P+UjTSUtw2+O/x8q1F5v+WGVVlfjUz76Pz2z4KU4872zEYzG8+ugT+M/3/wPu//xtslw/MjCIP3zrOwCANR/9P5i5eKHpZ8sVoioyMjiEcCik6bZOrIzIquW4/5tcmEfsBMUIMQQjo+CBlIEVyH8T68lrzkdN0yysuPRC0x9r+cVrsGjV6YhGItj6+0fw/973Ifzvrd9A2/4DE66766/PYvuTf4XH68W1/36b9JI4nYo67RkjAkdXRobGV0Y43kvsA8UIMQQpRgzY2AtgzPIunz+/xYh4YSurrjT9sSoaElMkW3//CB74tzvRdeRoxutvuuM7GO7vx+yTT8T5119r+vlygdhLo9W8CjizMpJq04yvjHC8l9gHihFiCFKMGGRgVRRFCpJ8N7GKF7ZAdbXpjyWSR/tUGjcHurrxx7u+DwB496dvRk1To2lnyxXSvKqrMpIMPquphsfnM/RcZuGfZDcNkEphLausQGlFMOfnIiQdihFiCNIzYtBoL5DyjeT7eK/YdVJWVWn6Y4nk0QENxs2XH3oU+7ZsQ1FJMT64/stmHS1niMAyPWJkuK9fTno5YUeN2+OR/3/Gt1AjI6PoTeamsDpCrIZihBhCyjNiTJsGKJzgM1EZKausMN2XIfI1+jS+EP/uG/8P4dAIFq06HWde+T4zjpYzgnKsV7sYAdJbNfYXI+mBZuMrI0BqvJcmVmI1FCPEEIw2sAKFEQlfWhEcU/kpq6ww9fGCOs2b3UeP4Ykf/BQAcPm/fgaBpKhxItl4RgCgry3R4nKCb0S0aKLhMGLR6ITPy4V5rIwQi6EYIYaQGu01sjKS/56R8S9oZdVVpj2Wx+tFoCbhS9HTotj86wdweNebKAkG8IHbvmD08XKGFCMaA88EYmGeI8TIFJM0Ai7MI3aBYoQYgtEGVqAwPCPjX9DKTfSNCCESi0Qx3Nun+fbxWAwPrL8DsUgUyy9Zg2UXXWD0EXNCtpURI8d73R6PqUbY6f5fdiTHe1kZIVbDBFZiCKnRXuPESMozks9iZOwLWrmJlRFhXu3v7ISiKLruo3Xffvz1F7/CJZ/4KD7wlX/F29teQ6h/wMhjmkpRSbH8WdVTHQJSnpFsl+UVB8rxpYc3IlhXi4GubvS2taOvrR19bR3oPd6O3rY29B1vR29bB7qPtuj6nk01SSOgZ4TYBYoRkjUen09mgRi1tRdIq4zksYF1QmXExKyRlF9EX0VA8Jef/A9WXHIh6uc149JP3YSH//O7BpwuNwSSo82jw8NTvkBPh1EG1sYTFsvvSaCmGoGaasw+6YRJr7v7mc34+T9/UfNjTNem6Tp6DPFYDMXlZQjUVGOgq1vzYxBiBBQjJGtKkntpgKl/6emhEDwjVTMTYiQej8PtdqPcxKwRvebV8UTDYfz53p/hw9/+JuaessyIo+WMivrsBZnIaKmor8vqLOL7cfCNnXjw9v9E5Yx6VDTUo7KhPvH3GfWonjUTtXOasODMU3U9xnRtmlgkgp7WNtQ0zUJt82yKEWIZFCMka/xpG3uVeNyw+5XL8vLYM1KRfHfdeegI6uc1m5o1YpQYAYD2ZHm/amZD1veVS8RoczbPgRgJLq+ugsfrnXRKRctZuo+1onXf22jd9/aE65RWBHH7839GcVkZ3F4P4tGYpseYrk0DAJ2HDqOmaRbq5szGgde2a7p/QoyCBlaSNSUB48d6gfRlefkrRipnJCojR998C4C5BlYjxUhP63EAifaCk3JggvX6A88EQ719iEYiAFKmYF1nUfH9CKWtVygNak9Jna5NAwAdHO8lNoBihGSNf4qtoNkSyfOcEZfLhYoZiRfHI0KMmGlgzTLsK51Q/4D8fjupOmJEZQQABpKTOIGkoNB1luT3I1MarhKPS4NwSTCg+TGKk2JkZDhTZYTjvcR6KEZI1gjPiJEZI0B6ZcQ577y1UF5TDa/Ph3gshta9iRK9uWIkNU1jBKI64igxYoBnJP32QlDoQQTHTff9GO7vBwBd+2PEG4XRDG8UuDCP2AGKEZI1ZuylAVKjvfnqGRGTNP2dXfKdei48I30GVEYAoOdYUozMcpAYqTVGkA0kbx/MqjKiThgNZ1EZUdWmOZRs08xugsvl0vwYhBgBxQjJmuLyZCnYwMAzAAiLaRp/flZGxGho7/E2DPb0Akjup/Eav5/G7fVIf8OAzrCv8TixMhIwqFUlBF1WYkRlyyjUp78yoqZN03OsFbFIFEUlxVlPCBGiF4oRkjWpyoixbRrhGclXA6uojPQeb8dwXz/iscSkRFmF8ftp0tNXh5LCJ1t6jrUCACpn2j8WXVBhkIlXpLcGde7o8fr9stIxXRKsqIzoMrCWJts0GSoj8VgM3S3HALBVQ6yDYoRkjRQjhldG8tvAml4ZUeJxDCUj2strjPeNBOsS73gHurp0p6+Op6c1Ef7llDaNrzhNAGRrYO3IrjIivCaRkdFpRfywqIzoadOIquU05vKOQ4yFJ9ZCMUKyxoyNvUBaHHxJvrZpUpURALJiUV5lhhhJvPgZ5RcBnNemEX6RcGgk659V4fMI6DSwprwr07fMhBgp0dWmSVZGMrRpgNSOGk7UEKugGCFZk9pLY/Q0TTL0zILKyPJLL8Ttz/8ZK959kWmPkV4ZAYDB7h4A5phYxTv4AYMmaYCUgbWivg5uj/E+F6NJ382TLeI+KrKsjKjx74SyatMIA2tm8SXHe7mjJifUzmnCnGUnWX0MW0ExQrLGjI29gHWekYoZdbjm325FaUUQKy690LTHGV8ZESZWM8Z7jZ6kARIvpNFwGB6v1xHGx8YTFgNILYfLhvQUVpdb+69Rmfmiol00nIWBVUzTjAxOUxlhmyan3Pzju/FP9/8ElVkuW8wnKEZI1phlYLXKM3LtN26T2Sl1c+eY8hhuj0eaH8dXRswQI9K4adAkDQAoiiKFlBN8I80rlgIADm7flfV9Dfb0Ih6Lwe3x6Pp+BWpExoiaykiyTaPRM+JyueQbhdFhdZWRmtmNjqhyORmXy4Xqxlnw+LyYd+oKq49jGyhGSNaY5RkJW+AZWXX1FVhyziq5b6RuzmxTsheCdbVwezyIRiIYTC4nGzJRjMgWhYGVESDVqnHCRE3z8oQYOWSAGFHicblUTk/wmZZofr2VkaKSEvn36RZY9h5vQ2R0FF6fzxHfSyfjLyuFO1lNm7P8ZItPYx8oRkjWmG1gzVVlpGpWA973r58BADz23R8hGonAV+w35Zez2Nbb19Yhp1tk1ogZnhGDwr7G03PcGSbWQE01appmIR6P4/DO3YbcpxzvrdPeogqoiIIXyNFejWJEtGjisZhcOjkViqKg60gLAPpGzCa9wtW8jGJEQDFCska0aUIGx8GLX6DeoiLTS8culwvX/vtXUFxWhv2vvo5nf7kRnckFYvVzmw1/POkXaWuTH5NtGjPEiMmVEbu3aUSLpm3/gWmrBGoZyCISPqgyCh5IhZ5pbdNo9XLRN5IbSgKp72PjiYvh8fksPI19oBghWeFyuVKR04a3aVLv5sxOYT372g9g0VmnY3Q4hN9+9VtQFEUaHc3wjchJmtY0MWKSgdXt9chqi+GVkeR4b7XNKyMpv8hOw+6zr6MDgL6sEbVR8EBqN43X5xvTepmO1CSNOvGV64V5Xr+/IP0p6aLSW1SExhMWWXga+0AxQrKiqLRE9j9DBouR6GiaGDHRN1Izuwnv/ZdPAwD+dPe96DqaKFd3HDwEAKifZ2JlJGkABczzjARqquF2uxGLRjHU3WvofacqIzMNvV+jEX6Rw9uNadEAaZURjSmsbo82cRgOjSAaiQDQFnymZi9NOiJrJBeVkaqZDbj10d/iCw/+suD24aRXRoDUz2ahQzFCsqIk2aKJRiJjxINRjA6HAJjnG3G5XPjQ7V+Bv7QEf9/6Cl787R/k59pFZcSEX87jM0aAVJumtCJo6H4a4RcZ6DQufVUgDawN9jU9ur0ezD75RADGVkb0bu4t1yEO9QSfaRYjOaqMeIuKcMPdd6CyYQYaFs6X24sLhfGCkibWBBQjJCv85dOvKM8GmcJqkhg57/prMf+0lRgZGsJvv/6tMS/WHQfMa9NUTFIZGbOfprLSsMeSfhEVLQGt9La1Ix6Po6ik2JQpICOYtXghikqKMdzfb0jGiKBfbu7VZmAVlZTBrh7V4jAVfKa+MiLSV9V6RtrefgfxWAy1s5swd+Vy1Y+jlQ985V+lOASAmqZZpj2WHSkOJt7AiUmqZooRABQjJEtKTDKvCszMGqmbOwfr/vlTAIA/fvv78l2+oD3Zpqma2YCiEmMfX4QdpVdGFEVJ7aeprjTsseQkTdLjYCSxSESmiNq1OiJbNDveNLQypLcyIv0iGvw7esZ7tVZGhnr7sPUPfwQAvO8L/6T6cbSw6uorcNYH3od4LIbetoQQr25qNOWx7IpI0t23ZRvi8ThqmhptK+RzCcUIyYrigIiCN6sykmj9+IqN9Yy43G5c982vwVfsx94XtmDLgw9PuM5wX78UB7UGjjt6i4rkFt10MQKkB59VG/Z4ZlZGgLQdNTadqBHm1UMGtmiAlLgL1NRo8j2k0lfVfz9COsZ7pRiZZi9NOn/+4X0YHQ5h7splWHbRBapvp4bZS0/Clbd+HgDw+Pd/ij3PvQig8CojIlCx59hxtL9zEAAwhyO+FCMkO7SWgrUSNqlN864b/wHNK5YiNDCIB9bfOeX1RFm/3sBWTUWyKhIOjch3vILUsrxKwx5PtAX6stxUOxV2H++VYWc7jDOvAsBAVzfi8Tg8Pi9KKytU307LWK9AekY07KdJRcGr/7850NmFZ3+5EQCw7rO3GOZdKq+uwo133wFvURF2/OVv+Ot//1IaxWsKrDIipmlC/QM4vPNNAMCc5dxTQzFCsqI4qfJHTGrTiP00RQZWRurnNWPtp28GADz8H3fLcvFkiFZNnYETNZOZVwVmLMsTlZEBs8SIjbf3lldXoXZOEwDgkEFhZ4J4NCbFo5ZWTUAsLdRQGdHTppEbezXmqvztF7/GQFc36uc146wPXK7ptpPh9njw4btuR2XDDLQfOITffPV2AEDX0WMACrEykhIjh3Yk0oA5UUMxQrJE7qUx28BqoGfjtPe9B96iIux9YQu2PfxYxuuaURlJBZ5NFEEya6TGuB6y8IyYXRmptmFlRJgDj7/9juG7k4DU1l0tJlZ9bRrtwWd62jTi+k/9+OcAgHf/48dlXole1n32Fiw88zSMDA3hfz73ZSmOupOVkepCEyOiMjIwIKt1c5aepGvhYj5R2F89yRqzouAFIvjMSAOreDF4e9vr01633YSJGjWVkfIqA8VIvfZ34lqQbZqZ9ssamWNSi0agx8SqJ5pfBJ9p8oxoDD1L56UHH0LHoSMI1FTjghuu03x7wfJLL8Saj/4fAMBvv/YttCU9EgDQdbQVAFBRX2e4J8zOCM/IcP9AIhF4eBjF5WWm5Bk5CYoRkhVSjJjwrhMwZ7RXONfFC38mRPCZsWJk4livwOjNvelbZftMmKYBUm0asxasebxeXPHFz2Hx6jM033auSeZVgRjPFAJDDXoqI8O6Rnu1e0YE8WgMj93zIwAJf5UwXGthxoJ5+NDtXwEAPPPzDdjx1DNjPh/q75fG3Gqbh+YZiaiMjAwMIh6L4cjutwBwTw3FCMmKeackVmCr2T6qh3DI+NFeUXVQI0Y6j7QgHouhuKxMV+z3ZIgleZNVRow2sOoJ2NKKECNllRWa4srVcsJ5q3H+h6/Fdd/6uqb4cLfHg9lLE8ZA8yojImtEXWXE5XIhUCOW5OkwsGqpjIgMII1tGsGOp57Boe274C8txaW33KTptsXlZbjx7jvhLy3F37e8gse+9+NJryd8I4U03is8I6LadTjpGyn08DOKEaKbBaefgqaTliAcGsHrjz9lymPIaRoD4+BlZaRnejESi0TQ3ZIoJxtVHVFTGTHKwFohzJJd3YanrwpGh4blL1YzJmoq6hN+jGBdrabqSMPC+fCXliA0MIi2/QcMPxeQ2tyrNkW0tLICHp8XQOJ7opZU6Flu2jSCR+++FwBw1lWXq/759xX78Q93/hvq5zWjp/U4fvXFr8kwv/GkJmoKwzfi8flkZlEoWU0+tCMxUVPo4WcUI0Q3F3wk0Uve9vCfJoyoGoWImDe0MqKhTQOkJmqM2t4rA89aj0/4nGzTGGRgTbUEzKlcCcwc701/oT/98nWqbyfyRQ7v3G2aEBPPqxBM0yG+H4PdPYhFo6ofR07T6DCwjmQhRt559Q3sfmYzPF4v1n32lmmvP2vJInzuN7/Aye86F9FwGPf/y22y2jcZ3XKipjAqIyXJ9NV4PC5Tqw8np7waFs43pbLoFChGiC5qm2fj5DXnAQCe2/Bb0x4nLEPPjBEjRSUl8p3JYJc6MSK3987LvjLiLy2VPePJKiPiF3dp0Jj9NGLKw3QxYuJ4b7pfYemF58tx8ukwK18kHWEKVlsZSZlXtZmJUzkjAdVTF8LPNZplBtCfvvtDxGMxLL/4XVPGxLtcLpz/4Q/hs/97HxoWzENfewd+dsvncWT3noz3nWrTFIZnRFS2RgYHpUDu7+hET+vxRFvx5BOsPJ6lUIwQXVzw4Q8BAHY/s1muHjeDiMGeEVFxCIdGEA6FVN3GyIV5YpIm1D8waS/f6P00esySejBzvDdQmxIjPr8fKy69UNXtzDavAilTsFrPiLie1syX0MCA/HuJSjEm2jTZVEYAoO2dg3h506MAgMs+/+kJnw/UVOPmH/0XrvjiZ+EtKsKuZ57Dd676MN5++dVp79tpwWdnXXU5Lv7EjbpvL4S0aLsJUuFnhduqoRghmimrrJDl8r8l0xrNIpXAaoxnRBhD1bZoAKDjgHFtmkwZI8D4/TTZt2rkHpRctWnMqIwko/EPvL4DAHCGilZNWWWF9DiInrwZDHQmfB8+v19VBkhAVkbU+0WAxHSLmIpRM97r9fvh8Sa8KdlWRoBETHw4NIJ5pyzH0gtTMfEnnn8OvvD7X2HJOasQDo3gwX//T/zin78kf4anQ1ZGGu3vGfF4vbjqK/8X7/nMJ1ExQ9tyREGpTF8dO314aDvDzzSJkfXr10NRlDGXPXumLsPdcMMNE64fUvlulNiXVR98P4pKinHkzbfwzivTZ3VkgxjtNWpRndj5osa8KhCr1asbZ8Lj82X1+JkyRgRGjvfmTIwkv55KE8RIebJN8+wvNyIei2HeqStQM7sp423Ero/2A4dkYJgZRMNh2UJRM20lKyMaMkYEwzL4bHoxIsZ6ASA8nP3v3P6OTjz7q8Qbj/d+7hb4S0tx5W1fwMfv/TYCNdVoeWsf7r72Rrz0u02a7re39TjisRj8pSWGBv2ZQVXjTGk+1jPqDIxNX01H+EYK2cSquTKya9cuNDQ0yMu5556b8fp9fX1jrt/cXNjBLk7H4/Ph3OuuBgA8Z3JVBDDeM6LVvAokfhGPDA3B7fGgdnZ25eRMkzQCU8RIu3MNrGKXS8uevdj30jYAwOmXvyfjbZpXJt5hHjSxRSNIjfeqESP6lxaG+tQvy/On7Ywyyrz7zM83YLC7B/XzmnHb4w/K3wPP/nIj7vmHj6M9WUHUQiwalf8X7N6qEWsFAKC0Qv0uonTS01fTObpnL2KRKIJ1tbbdfm02msVINBpFW1ubvHR1Zf5PpSjKmOu3t0/9S5jYn1PXXYJgXS1629rxxp+fNv3xjM4Z0SNGgDQTa5atmpQYmboyYmTWSM6maVpbk49XK9sDRuAvK5UtuoGubrzySCK+/7TL1mbclJsL86pAmFGDKkys4h21VgMroC2FVVRGshnrHc/o0DCe+kkiJr68ugr9nV346Sc/h0fu+h5ikYju+3XKeG9tWjWuTMNixHSmqoxERkZx7O9vAyhc34hmMbJo0SK0tLRg//792LBhA2bPzmzqKy8vx8GDB3H48GE89NBDOOkkbid0Mucnx3mf//UDiEcnzw4wkojRnpGa7MRIfZYTNak2zfSVkbLqyqwey+3xyBaH2WJksKsHkZFRuN1uVCS/RiMQUyojg0OIjIxi51+fQ2hgEDVNszDvtJWT3sbldmPOsmTYWS4qI+3qg8+yaZtpGe/1myBGAOClBx7Ca3/6M7Y9/Bi+c9WHsffFrVnfp8jxsXvwWXplpKwq28rIxMTqwzsKu1WjSYxs3boVN954I9auXYtbbrkF8+bNw+bNm1FePrm7e+/evfjYxz6GK664Atdffz3cbjdefPFFNDZm/qErKipCIBAYcyHWs2jVGZi1eCFGh4ex5feP5OQxTTOwqhzrFciJmiyDz9RURuSyvCzbNOXVVTJ9dTBD1oNRmDHeKyoJIiAsOjqK7cmK3FRG1oaF81BcVoaRoSEcf9ucsLN0xI6ZgIo2jRBXeto00jOipk0jJ2mM3RkVi0bx6y//G37z1ds1C/qpcEplpCatRau7TSP30kz0MYkqXqHGwmsSI0888QQefPBB7Ny5E08++STWrVuHyspKXHPNNZNef8uWLfjVr36F7du347nnnsMHPvABdHR04JOf/GTGx7n11lvR398vLy0tLVqOSUzigo8kxnlf3vTohDKjWUgDq9FtGo0vzkZN1FTM0GBgzXJZnngXPtjVAyUez+q+1CDEiJHjvUKMDKallb7yx8cBAMsvXTOpsVm0aI7s3JOTr1sIi4ppxIi/rBT+0kSolR4Da0jDfppUxoixlREzcErw2Zg2jc4WavpemvEcSsbCN510giEZQ04jq9Hevr4+7Nu3DwsXLlR1/Wg0itdff33a6995550IBoPyMl0lhZjPjPlzceJ5ZyMej2Pzhgdy9rjhkPUGVsCYykhJMChfjHrbpl5alxIjlbofC0iJEbMW5I2nt9X4iRpZSUjzWBx4bTs6jxxFcVkZll50wYTbiOTVgzvMb9EAqcyQwDRtGvH9GBkckl4oLcg2jSoDa7JNo3MvTS5xQmXE7fGgOu18ZRp2BKUjxMjwJG/mOg8dwXBfP3zFfsxarO41NZ/ISoyUlZVhwYIFaE2a16Z9MLcby5Ytm/b64XAYAwMDYy7EWs5Phpzt+utz8pdHLjCtMtKtLeeh83BivLesskK3eU0syBvs7pEx95MxZFCbJlif3EtjcuCZoNvENs148fjqI4nqyGStmrkrlgEADm0337wKpBtYM1dGgrXZmYlFZURNnokRe2lyhcgaCdbXwVtUZPFpJqeyoR7etLH+Ur0G1immaQSH5Ihv4eWNaBIjd911F84//3w0Nzdj9erV2LRpE2KxGDZuTIx43n///bjjjjvk9b/2ta/hkksuwbx583DKKadgw4YNaG5uxn333WfsV0FMpby6Cqe9by0A4Nn7zR/nTUd4Rjw+ryGlSy0be8ecIzQi2xB6J2rUjPWmny1bA6t48esz2bwqMGO8d6rpE9GqWXjW6WMCqEqCQdTPS3x/xDZUs+lTaWCV5lUdkzRAuoFVfWVEBKXZmaGe3sTovNttymi4EaSbVwH96cglUySwCoSJdU4B+kY0iZGmpiZs3LgRe/fuxQMPPICuri6sWrUKncn+55w5czBzZmrHQFVVFX72s59hz549eOyxxxAMBnH22WdnDEoj9uPsa66Ez+/HoR27cfCNHTl97EhaOTvb6khJMCBDiwa7ezXfXk7U6GzVpCZpJi7IS0eIkdJgMKsx2VRlJEdixMzKyLgNt90trdj/yutwu9047bK18uPNyxNTNB2HjqhOAc0W4f/wl5bKisRkBHRGwQukZ0TNaK/wjDigTQOk+0bs2aqpaUqIESEkSyv1tWmEkJxSjOwUYqTwpk41iZHrrrsOjY2NKC4uxuzZs3HdddfhnXfekZ9fs2YNPvrRj8p/f/7zn8fcuXNRXFyMmTNn4rLLLsMbb7xh2OGJ+XiLinD2h64CkJuQs/HEolG53TRb34hoe4QGBnXlIqR8I/p21KitjIT6B+TXrNcoBwAVySV5uauMJNqvVTNnZMwA0UL5uGmadF55OJE5kr7JV+aLbM9NVQRIVM1EBUIIwMnQuyRPkL4sbzqc1KYB7B8LLyojQizoadW6XC4pEqcWI4nVBfXzmlUl7eYT3E1DMnLqe9+NQE01uo+1Ysdf/mbJGSJJf0W2lRG95lVBtsFnaqLggbH7abIRI4EcLckT9LV3IB6LwVtUJEVEtogleQOTvIBvf+qvCIdGMGP+XMxemngnKcyrh3LUohHIFNYMwWfZLi3UY2B1QpsGsP/CvNo5iXMdTu458peWava3+MtK4fYkWs2T5YwAie+x+D1TaNURihGSETHOu/nXD8htsrkmIiLhs9xPY5wY0dumUVcZAVIm1kAW+zoqZMBWbqZp4tEY+toTj2VU7398zkg6o0PD2PXXZwEAZ1yxDi6XS/bac1kZAdRFwqcqI/oqVSKbwuf3w+vPnLvj1DZNtV3bNMmx3qN79sqqpVYTq0hfjYyMIhoOT3m9QwUafkYxQqZkyTmr0LBwPkYGh/DyH/5o2TlSkfDZBZ9lK0baDyayRmrnNMl3OFpQWxkB0kysOrNG3B6P/HpzVRkBUuO9RvhGigPl8PlFFPzk37NtyVbNyrUXY9YJi1ASKMfocAitf9+f9eNrQbReMo33pjwj+r4fo0PDqRfCaaojzmvT2He81+VyyYwRMX4LaG/VTDdJI5C+EYoRQhKc938+CADYuumPlpZ7U5HwBlVGNGzsTae3tQ2RkVF4fT5UzZo5/Q3ScLlcaYFn01dGsl2WV15dBbfHg3gsZlhSphqMNLGKqkhoYHDKUei/b30FvW3tKKuswHs+kwhTPLJ7T86reKk2TYbKiAF7gtQGn5kVB28WXTYOPgvW18JX7EcsEkVP6/FUC1VzZUSkr2YWI6LFWGhJrBQjZFKqZjZgyTmrAAAvbPy9pWcJG5Q1km1lRFEUdCTzRrRO1JRXV8Hr8yEej6sKIct2WZ5cVd/VnZMUUkG3geO9skWTwfCpxON47dEnAAAnnnc2gNy3aIBUtaNiCgOr1++XkxR6DayAet+I9IwYHAdvFmIsvLi8THeOj1mIFk33sVbEYzEM9fYC0NGmSX7/J0tfTefYvrcRGRlFaUUQtc36zPJOhGKETMpZV10Ot9uNfVu2oevIUUvPYrhnRONemnSkb0TjwjzhFxno6FK1YHAgy6yRYHKSxuwFeeMxtDKSNIMOTBNQ90oyAE2Qa/MqkLafZgoDazBpxI2Mjma1SkHteG9xmXPi4AEgGg6jty1RMbTbwjzZokn+Hhzu1demKZXpqxP30qQTj8Zw9M23ABRW+BnFCJmA2+PBmVdeBgDY8uDDFp/GPpURIOUb0bqjRotfBACGkjkoAZ1tmmwnN/RiZPCZMO9OJx7b3jmIw7velP+2ojKSCj6bvDIizatZfj/ksrw8a9MA9vWNiLHeriOJ8w3rbNMUBzMHnqWTSmItnFYNxQiZwEkXnIOK+joMdHVj19PPWn0cGXzmm2aCYDqMECMdB/RN1MhJmrbp/SJAytei18Cazar6bEhljRghRpKVERVtDVEd6TxyNKceGcGAjISfvDIizatZtGgAdSmsbq9H/l8ZcZAYsevCPCFGOg8nKiN62zQy8GyaNg2QmqgpJBOr/nhHkres+uD7AQDbHnpUuvetRFRGfCVZipGk/0Lrxt502nWmsKbGetVVRrJdlifFSHtuxnoF4usrCZSjOFA+bX88E5nGesez9Q9/RM3sRux7cavux8sGIfpKggH4iv2ytSgwShzK/TQVU1dG/KVl8u+jw87wjADpJlabVUZmjxcjOqdppomCT0fEws9atHDSn6d8hJURMoaqWQ1YcvZZAIAtv7dunDcd8R8xmzaN2+OR72S0LslLpyPZpgnW1cpSuBpSbRp1lZFsl+VluwdFL+HQiDy7WAyoF+kZUfE1REdH8ch/3oO3nt+S1WPqJX0T72QTNcFJtg/rQU1lpLg88XMZGRlV5U+yC6JNY7eskZrZiUqN8M6Jyoju0V4VYqT3eBu6j7XC4/PijCveq+lxnArFCBmDNK6+9LLlxlVB2IDR3tLKINxuN+LxuDSg6WFkcEi+oGjxjVTO1FYZEbkaJcGArv00wjMivAy5JLW9V9v483jKk56RqTJG7IYwsU62ME+Iw6zbNCpGe/1J86pTJmkE3Ufs16Ypr65CcXkZ4vG4rNykPCOVmu5LhJ6pNTD/7Re/BgBc8qmPoShL874ToBghErfXgzPfnzCuvmQD46ogEsrewFpenSj5D/f2ZZ1B0aFjR43WNs3IQNp+Gh3VkdSLX+7FiFEmVi1tGjvQnxR+gUlMrEZF86sZ7S0WgWcOSV8ViMpIZUO9IRu6jUC0aHqPt8l9VqJNo3VZntrQM8GWBx9G55GjCNbW4Lzrr9X0WE6EYoRITjr/XGlc3f3X56w+jsQIz0jAAPOqQOuOGrfHI8v0Pa3qxEj6fhqtvhGX2y1fyK2ojBg13qsmZ8RO9GcwsabaNEZ5RqZ+IZSTNIPOEiMDXd0Ih0bg9nhQ1WDc5udsqBGTNIdb5Mdkm6bCnNAzQSwaxRM/+BkAYM1Hr1e1k8jJUIwYwCnvuQSf/Ok9uvv7dmHVB68AALy8yR7GVYERnpEyA8yrgg6NJtZgXS3cHg+ikQgGNbzLT6WwVmo6n1XpqwIjKiMlwYBcRGbF16AHYU6dLPhM+l+Mqoxk8Iz4k3tpRhxkXhXI8d7Z9vCNyEmatJa1aNOUBAOaKjiiMqLF1P3G40+h5a19KAmU46KP36D6dk6EYsQA3v2PH8fi1Wfi1Pe+2+qj6CbduLr1949YfJqxyNCzrNo0xlVG2jUuzBMtmr62DiiKovpxRNaIVpErXgxznb4q6DWgMiKqIsP9/RmXitkJUcEJjDOwjt0TlF1lZLgv8UKoqk3joLFeQWphnj18I+PHeoFEZSOe/H+lpVohPCPThZ6loygKHrvnRwCAc667CpXJlRJaKKuqRMOiBZpvl2soRrIkUFsjX5ScHFCz6qor4Ha7sffFrfLdiV0wIvRMmCGNESOJiZq65jlwuVzTXl9O0rSpa9EI9GaNBGqtmaQRpNo0+qdphBjJJi031wg/yHgDa3l1VcI8HYtlXZkTbZriQPmUP3upNo0DKyMt9hrvFWbadDGixOPy+6C2VePx+aQJVU3OSDpvPb8Fb297DT6/H5f+48c13bZqVgP+9Q8b8PkH/seQ7B8zoRjJkgWnnyL/3rzCmdG9bq+9ElfHEzHAM2JkZaS75RhikSiKSorl8rtMyMqIyrFegd6sEVEZ6bfALwKk2jTBulrZatGK08yrANCf3Dk0PoXVyD1Bwm/gdrtRnPQgjCfVpnFuZcQuEzWTtWmAtIkalf83S5Lpq/F4XJdI/NN3fwgAOOOKdaifp86rVhwox8fv/Q6CtTXweL22r45QjGRJuhipmtmAYH2dhafRx8kXnItgXS36O7uw6xn7GFcFRlRGAgbspRHEozFZPapXsaNGaxS8YFBn1ohRZkm9DPX2YXQ4BCD1tWtFS8aIXZCVkXEGViMrVbFIRD63U0XCO7lN0yXbNNZXRkqCQZkl0j2uWizM5aUqKyPC4zMyOKipVSs4vGM3dj79LNwej9xOnQm314MbvvMtNCycLz9WbcCKBjOhGMmS+UkxIsZFndiqWXX1+wEkjKt2DEmScfBZGViTYqTHmLK/bNWomKhJjfXqrIxoNLAKQWxVZQRIa9XM0pc1Uu7Iykji+S6rqoTH55Mfl5URg/YEhfozm1iduJdGYKf9NLXJsLO+9g4ZaCcYkpURdWKkWEP66lQ8/v2fIB6LYfklazBn2UkZr3v1V7+IxavPxOjwMPZt2QYglXVkVyhGsqC8ugoNC+YBAHY89QwA521ZrG6cicVnnwkA2PoHexlXBWEDpmmMbNMAqR01aiZq9FZGhqQYqdZ0O6PSPrMh2/HeoKyMOEeMDPelzLbp1RGj9wQNT7O5V4gRp4WeAYkWKJAQWtMtAzSbqVo0QMpIrDaFtVSmr+pfj9C2/wBe+WNiB9N7P/ePU15vzceux1lXXY54LIZf/d+vY8/mFwEYsy/KTChGsmD+aSsBAMf2vY03n0t8w+c6zDdy1gcSiat7X9gi+7V2Q3pGiu3hGQG0TdTorowk2zRq+9KCoMWeEQDoTeap6B3vTaWvOkeMACkBGEgzsRotDlPjvVO0aZIJrE6sjERGRqVos7o6MlnGiGCoR1ubRmv66lT8+d77EA2HsfDM0+T0YzrLL70Ql/3LpwEAD/3Hd7HnuRdS/xcpRvIX4Rd555XXcWhHYm1500kn6IrvtoJ046qdElfHIz0jOiORvUVFMnDIsMqIbNNkFiMen0+aMTV7RnQaWFPr6i1s0xzLrjLitMAzgXjO0/fTBGX6qkGVkaQYmSr4zMltGiDdN2KtiVW0adInaQRa2zRa01enovd4G174ze8BAOs+e8uYiarmFUvxD3d8HQDw3K9+ixc2Pggg+/+LuYJiJAuEX2T/K6+j89ARDPX2wVfsx6wliyw+mTpOftd50ri6+2+brT7OlEjPiF9fZUS8mMci0azfmQhEZaR61syMFRuRCxAZGZW/wNQymMwZKQkGxngQMuFyuxGoTbyQWypGWlsB6B/vlQZWp1VGJhnvFQZWo4RVSO6nyVcxYg/fiNzWm6lNk+PKCAA8/bP7MTI4hKaTlmDFpRcCSBh+P3rPf8Dn92P3M5vxyLe/J6/fczwhRgJ1NbZ+o0wxopPSiiBmLV4IAHjn1TcAQFZHmlc4w8S6+upU4qodjasCURlxezyqX5TTKUsaQI0yrwKJrboivKh2ztQ7arQuyEtnzH4aldWR8qpKS9NXBdmksLpcrlRbzWFiRAiOYL35lZEpPSOlzvWMAPYZ75VtmknEiNhMXarSM5KqjOj3jMjH7u3DM/+TWKK39jOfRHl1FT5+73cQqKnGkTffwoYvrR8zQj7Y1YPI6CjcbjcqdE635QKKEZ0Iv8jx/QfkL/1D24UYWWbVsVRT3TQLS85ZhXg8jq2/t2+LBgAio6Py73paNcIAavSLszCxilaN2Akza8kinHDuKpz5/suw6qrLAWj3iwDJ/TTJX3oBleO94kVwsLsn64WA2SDESOWMGXC5tf2aKQkG4E2KzgGHRMELJmvTiCpPtkvyBHI/zVSekXLnekaAtDZNY3Zbn7PBX1oqvT6dRybxjCQFoVoDa2ovjf6N4ek898vfYKCrG3XNs/GFB3+JGfPnovd4G37+T/8X4VBowvWlb6TBvhM19q3Z2Jz5aX4RwaEduwE4Y7z3rCvfBwDY9+LL6G5ptfg0mYlHY4hGIvD6fPAVF2sudRptXhW0HzyM5hVL8f4vfQ7v/9LnUF5dNWUZtOPwEV2PMdjTi2BdrerKiHgR7LOwRSMePxaJwuPzIlhXg762DtW3lVHwff1yU6pTGN+mKausSAkrow2seesZEW0a6yojNUm/yGB3z6S7ZMSbBNViRMdemkyEQyE89ZNf4AO3fQHBulqMDA3hvk9/YcrqW0/rcdTNnYNKG/tGKEZ0suC0lF9EcHjnbsTjcdQ0NaK8psrWUdYnrzkPAPDKI49ZfBJ1REIj8Pp8KNIxUWPkxt50juzegzOuWIeKtKC7eDyOoZ5e9Hd0or+zCwOdXeg93o6XHtik6zG0Zo2IyohRmRZ6UeJx9La1o6ZpFqpmztQkRkTGiJWjyXqRKaxJURhIjvUO9fQatnxS5oxMIkZcLpfz2zTJ8d6qmQ2y5ZhrhBiZzC8CpC3LqwjC5XZPm6wrxIjajb1q2PK7h3DudVejpqkRv/zCV9G6b/+U1+3JcrotFxS8GAnW1Wru5RYHyjHrhIRJNV2MjA4No23/AcxctADNy5di9zP2NIUG6+swc9ECxONx7H1xq9XHUUV4ZAQlwYCu4DOzKiNbfvcQeo+3IR6NYaCrC/0dXYa3R7RmjYhMi74O9S/+ZtF7vC0hRmY14OAbO1TfTpTHneYXAVKVETHaa0bmiyj1T9amKSotkX93amWkv70T0XAY3qIiVMyoky2/XDLZgrx0RHXK7XajJFAu/z0VRk3TpBOLRvG9629GcVmZzPWZCpn7Y+M2TcF6RtweD26699v42l8eVp31L5h3ygq43W50HDw8ofR6cPtOAPbOG1mSDDk7smvPtP+J7ILY3KvHMyINrMnpFKOIRaPY/cxm7Nn8Io6+uRf9HZ2Gv4vTmjUixIjVlREgfaRQ2y9AJ6avCkQEf3l1Fdwej+GBZ0DmNo3wi8QiUcdsOx6PoiiydWxVq0ZM0nRN4hcBEv/3hRlVjYm1xIAE1skI9Q9MK0SAtE3aNq6MFKwYicdiUGJxuN1urP7glZpuu+D0iS0aweHtCd/IHBsnsYqwHKdURYCUiVVPCqtZlZFcoDVrpKLOHp4RQH8Ka7BWZIw4T4wMdSfaMW63G+U11WmTNEZWRpIG1sDEyoho0Yw6cEleOlaP92ZKXxWI8d7yyspp70+MYRstRtTS7YCskYIVIwBkeMwZV6zT9I5bipFXJ4oRURmZffKJcHs8BpzSWFxuNxavTlRG9r7gHDESzmI/jaPFiFiWV6NumiYg96DYQIwcS2aNaJyKcHJlRFEU6RUL1takLfwzvjLiLy2ZMOruT6avjujYDGsnrA4+m65NA6Qty5umMuJyuWTFyioxIqZpKtmmsSf7XnoZnYePoiQYwCnrLlV1G39pKRpPXAwAeGfbRDHScfAwhvv74S8twUwbrmxuOukElFVWIDQwiMM7d1t9HNVE5OZe7QbWlBhx3oub9IxUqRMjFXUJM22fhVHwgo5DiQmiGfPnarqdTF/tsr7VpAfh1wnW1aa1aYz7WkYHhxBPGibHR8LLsV5WRnTj9fvli3aXCjFSVjn5VJPAX1Yq35gakTOih962dsTjcRSVFGteL5ErClqMKIqCF3/7BwDAOddepeo2c09ZDo/Xi66jLehtm5gdoSgKDu94E0AintduLDkn0aL5+9ZXLM2h0IoIPvPp8IwETMoZyQWpaZrpxYjL7ZYVFDtMorT+PeHur541U75IqiFQ48z0VcFA2nivGQZWRVFSKazjfCOyTeNQ86rAyuCzmmQlL9Q/kDE1eViKkcqM9yfaaZGRUct8PLFIRPob7dqqKWgxAgAvP/QnREZG0XjiYlXiIZNfRCCTWG3oGznBgX4RIM3AqrFNU1RSIuPajTaw5gItBtbyqkp4vF7E43FbTKKE+gekYG9YqL5KKCojdvga9CCER3plxOgdO1OKEZkx4vQ2jXWVETV+ESBtWd40bRozJmn0kPJw2bNVU/BiJNTfj9cffwoAcM6Hpq+OLDhjYtjZeFJJrPYSI8XlZZiTDGTb+8IWi0+jDb2eEVEpCIdGJk0mtDuiMlISKJ82Cl+88FmdvppO6763AUB1y9LlcqVVdxwqRkQKa11tWvqqsW0zuSxv3H6a4jKRMeL0ykjCb1RWVampqmYEqRj4ySdpBENiP810YkSmr1orRlKbtK1Lts1EwYsRIGVkXXHphRnL4UUlxZh90okAMldGDu9KtGnqmmerTujLBQvPPB0erxftBw5ZMrufDXo9I042rwKJd8CxSCIsa7rgM+lPsIFfRCBaNTMXqxMjpRVBmWLrRI8PkKqM1DXPhj+Z+2GkZwSYerxXGFid3qYZHR6WbbrqxtxWR+SCvAx+ESDVppm+MpL4HhmVvqoXuaKBlRH7cvTNt3B455vwFhXhzCsvm/J6c1cug8fnRU/r8YwR6qH+ARzffwCAvUZ8hV/EaS0aIM0zolGMmJW+mkuGensBTG9iFXk5/QZObmSLECMNi+arur6oJAz19Np6eWMmhBhsPCFhdB8ZGjK8KheaIvjMX+bs9NV0Ur6RHIsRtW2aXpWVkaCxe2n00pNc1knPiM0R1ZHVH7xyysVe81X4RQSHxZ4aG23wlfkiDhrpFQjPiOY2TR6IETUmVq/fj/M/8iEA9mrBiYjqWYsWqrp+wMFjvQLRkhFCwYwAuuEpPCPFDt9Lk05Xi1iYZ5EYUVkZmV6MGLuXRi96QwhzBcVIkjf+/DSGevtQ3TgTJ5539qTXEftoMvlFBDKJdbk9NvjWNs9GTdMsRMNh7H/lNauPoxnhGdFqYC1LVhMGexwsRoSJNUOb5uxrr0TljHr0tB7HS7+zzxbm9gOHEItGURIMoHLG9OvLZcaIQ/0iwMTJGTMmm8S77PGjvfliYAXSKiOzczdR4/F6ZeVgOjGiNmdETNNY7RnRG0KYKyhGkkRHR/HypkcBAGd/6AMTPu/1+zFn2UkA1FVGxAbf2ctO1LxC3QxOSLZoDry2Q76wO4mIztFeYYbMi8rIFG0af2kpLrrpIwCAJ3/0c1ttuo1FIug4eBgA0KDCNxIQ6asO9YsAiSmgeNriNKPNq8D0nhGnG1iB9OCz3FVGqmYllvONDoemnYAS7dOyisxipNQm0zS9yTZNeXWV5nZ3LrD+VdJGvPTAJsTjcZx47uoJ8+3Ny0+Gt6gIfe0d0ypmAGjbfwAjg0MoLitDw8J5Zh1ZNUvOXgUA2PuS81o0QMozotXAKj0jNt6gPB3TtWnO+/C1KK+uQsfBw7bcwixNrComavKhTROPxcaIXzMqI2K0t2SqNo3DQ8+AtPHeHLZpRItGPHYmhnoTgtDj82ac+CkWe2n6rBUjof4Bmcxrx+oIxUgaXUdbZL999TVj99WIfBE1LRogsUJdTNVYnTfi8fmw4IxTATjTLwKkVUYK0DMyJCLhJ8kaKa0I4l03/AMA4Ikf/NQ2I73pCN+IOjEi4tOtD23LhnSfiBnR/LIyMm4/jQw9c3gcPJBq01Q3zcpZdVmtXwRIVNNHhxPG5EytGrmXxmLPCJBq1dgxFp5iZBwv/CaRyHrmlZfB60+9C0+Fnb2h+r7skjcy75Tl8JeWoL+zS+Y+OI1wSF/oWT6IEXH2yTwjaz52PUoC5Wh5ax+2P/nXHJ9MHXoqI04NPBOkTzQZPdYLZGrT5EfOCJCIMB8ZHILX58tZdblGbOtVIUaA1LK8TCmsqY291m9I77Hx9l6KkXG89fxL6G5pRVllBU5ZexGARGVBVDe0mD+lGLG4MiJGeve9+DIURbH0LHoRW3u1VkZEcqmjDazJ5NjxbZpgXS3Ove6DAIDHv/cT235vW/+eEMD18+fC7c28PFKIEacGngnSBYipbZqpdtPkgRhR4nGZZj13xfKcPKbMGJlmrFcwnGzVZNpPk0pgtb4yIoPP2KaxP0o8jhcfSFRHzk7uq5mz7CT4iv0Y6OpG+4FDqu9L/EeaMX/uhKTEXLJktcgXsc/Ip1Zk6JkGA6vL5ZKmTydXRoZ6JjewXvyJG1FUUowDr+/Ans0vWnE0VfQcOy7f4dbPbc54XWFgza/KiHltmgk5I6X54xkBgINvJKcSV+ZmKlFLmwZImVgztWnENI1VG3vTsfNEDcXIJLy86VFEw2HMWXYSZp98Ysov8uobmu5nuK9fThKISZxcU15TJbcM73tpmyVnMIJUHLx6A2txIACPT6R59ppxrJwwMImBtbpxJs666nIAwOPf+7El59LC8bffAZC5VeNyu2Uly8kGVmBsCq4pbZrkC5vH65WtGSCtTZMHnhEgt2LE5XbLyZ3pouAFQyqW5dllNw0A9CQrI3ZMYaUYmYShnl688eenASTGfNUsx5sKMeI71yLfiKiKHHnzLUdXB1Jx8OorI4HkWG8iUt0+465aEQbW4vIyuZ/m0ltugtfnw94Xt+r6ucw1qSTWqcVIWWVFatGfg9tqQEqAREZHTfEKREdHZRCg8I0UlRTLVfX50KYBgMM7dyMej6N2TpMc0zeLyoZ6eH0+RMPhSTeyT4aoUE0VfObx+WQ11+qcESA9+IyVEccgEllPWXsJ5q5M9Cv1/NIX4WfNy61JYpUR8A6dohGEdUzT5IN5FZi4n2bG/Lk47bK1ABJeESegZmGeCDwb7u1zbBS8QIyGZlobkS0y+CwpRkSLJh6PO3Ip5GSMDA7JqtrcFeZWR2rnzAaQyDdR0nJiMiHeKIw3EgtEFHw8HrfFhFOvmKaZUW+L/Kt07HUaG3F4x24cfXMvfMV+FJUUY6i3D23J/xRa7wcA5iw7GS6Xy+hjZsTlcmHx6jMBAPscuI8mHfEusKikWPXzmDKv9pp0qtwhKgXl1VV496dvhtvjwY6//A1Hdu+x+GTqUDNRkw8ZI4LWfW/jN1+9HRtv+3fTHkNO1CT9aP48ioJPR7ZqzBYjKhfkpSPbNJOM3QMpv8jI4KAtDOZ9HZ2IRaPw+LwI1tVYfZwxUIxk4MXf/l7+/Z1X39D1w9T69/0YHQ6hJBiQi8xyxawTFiFQU42RoSH5H9qppKfGev1Fqm6TL5URIPUO7IRzVmPFpRciHo/jiR/81NpDaUCIkerGmVMGRMn01TwQIwCw7eHHTBWLojIigs/8eRR4lk6ufCMidl7tJA2QJkamSGGVfpF+6ydpgMSARl9bBwCgqsFerRqKkQy8/vhT0gGtty8fj8XkL6Rmk5X9eETq6v6XX0MsGs3pYxuNGO0F1PtG8mFjr0B8DRfdfAMA4LU//Rltyc3QTiDUPyD78A0LJ6+OBKrzY5ImV4jfTSJuvLgsf8Z60xFipOnkE6Rnygxk+qqGyohcllc1hRix0SSNwK5ZIxQjGQiHRvDQf3wXe1/citcefUL3/aTyRnLrG5F+EYe3aICEopdZI351EzXCg5AXYiRZGfGXliAWieLJH/63tQfSwXStmkBtomxsRi5HPjI++Myfp2Kk68hRDHR1w+f3y8lAM5BjvSonaYDpl+XZZS9NOjKF1WYTNRQj0/DKI4/hp5/8nPyh04PIG8llEqu/tFSWNd9yuHlVIHwjapflpdo0zn+nnS6otv7hEVW7M+zGcRELP8XCvHxJX80V44PPUumr1hsljUaGn5nYqhH7yLo0tWl6AUzdppF7aexYGbHZRA3FSA6Q4WcL5mVcqGQkC844FV6fD51Hjmr6z2VnwhrHe6WB1cEZIwIhRiIjo3jqp/9j7WF0ciyZxNqwaP6knxej2E5PX80VhWJgBcw3sZZXV6GopBjxeFyOv6pBJLCKQYfx2GkvjcCuKaxeqw9QCAx29aDraAtqmhrxjWcfQ2RkFJFwGNHRMCKjo/LPyOgo+to78ND/+27W2QT5MtKbTiSkbbw3nwysf9+yDeGbb8STP7oP/e0dVh9HF9MtzBNtGlZG1CE9I8k2Tb56RgDzxYhYHDfQ0aXJXzc6PIxoJAKvz4fSiooxRnsgfS+NjSojx/KgTbN+/XooijLmsmePOrf4tddeC0VRsGnTJl0HdTqv/elJAIC3qAglwQCCtTWobpyJGfPnovHExZi7chkWnXU6Tn/fe7D84guyfrwlZ+ePX0QgKyMl6jwj+WRgPbzzTdy26iI884tfW30U3bQfOIRYNIrSYBCVM+onfL5c7qWhZ0QN4yPh83WaBgCO7H4LsUgUFTPqTHlHX5V8Ye45rr4qIhCTbpMFn9kpfVVg1zaN5srIrl27cPHFF8t/R1WoyObmZnz729/Gc889p/Xh8oYnfvBTPPvL38BfUgyvvwi+Yj+8RX74iv3wFRXB6y/CudddjcWrz5TvEPVS3TQLdc2zEYtE8fbLrxr0FViP9IyoqIy4PZ60No3zxQgA1UFMdiUWiaDj4GE0LJyPhsULxqRcutxulIvvFysjqphoYM2vKPh0oqOjOLpnL5qXn4y5K5fJF1SjqEy+MIsWhhaG+/pRUV836URNarTXPmKk93jiaywJlKO4vMw2Py+aPSPRaBRtbW3y0tWV+V2M2+3Gr3/9a6xfvx7vvKM9NCyfCPX3o7etHZ2Hj6J1334c2fUm3nnldex9cSt2P7MZh3clqkzjt7NqRVRFDu7YmVclWy2eEfEuJR6PZ2U+JsYy1URNWVUF3B4Pv18aGB5nYC0uzV/PCJBKszbDxCorIzrESCqF1RmVkXBoRJ7ZTuO9msXIokWL0NLSgv3792PDhg2YPXt2xut//etfR3t7O37+85+rfoyioiIEAoExl0JA/ICUT5Hmp5b5p60EAOx78eXsDmQztFRGypKCbri3z/EVhXxiKjESqElUA4d6ehGPOTsKPldMqIwkzfGjw/Z4p2s0wjfSbIoYSVZG9LRpMqSwCs+IHfbSpNMtxnttFHymSYxs3boVN954I9auXYtbbrkF8+bNw+bNm1FeXj7p9c855xzcdNNNuPnmmzUd6tZbb0V/f7+8tLQ4b4xRD2IEtTwZ/qSXYF0tAKDz0JGsz2QnIho8I/nkF8knpjKx5lMUfK4QJvfisjK4vZ60Nk1+VkYOJSsjsxYvRFFJiaH3LcycWiZpBHJZ3iT7aURlZMQmCawC0Y6qdmpl5IknnsCDDz6InTt34sknn8S6detQWVmJa665ZsJ1y8vL8atf/Qo333zztK2c8dx5550IBoPy0tjYqOn2TkW8cGa7nVL+Ys+zF2Ity/LyaZImn2hNjvfWz58Lt9cjPy5/ZmleVU36uGhpMJjWpsnPykhfWwe6j7XC4/Vi9tITDb1vURnJqk0zmYE1WdUfNmFzczbYcaImq9Hevr4+7Nu3DwsXLpzwuQULFmDevHn44x//KD/mTm4JjEQiWLJkyZQeknA4jHA4nM3RHMlAV2oZWjbIF+I8e5eZWpY3/bsiihF70nPsOEYGh1BcXob6uc1yI6swbbMyoh4lHkeofwAlwQBKK4JpbZr8rIwAwKE3dqJ61kzMXbkM+7e9Zsh9ev1+KYZ1iZG+yds0LpcrNdpro5wRIDU1ZKeJmqxCz8rKyrBgwQK0tk5ck/3WW29h6dKlWLlypbw88sgjeOaZZ7By5UocOZJfLQQjSB8R07vh1+31SPNmvr0Qi3XswhOTCYoR+yIESHqrJpW+yu+XFuSyvGAA/lKRwJq/YsQME2vljDoACRGnJ99JBJ+Nb9MUlZbA7UlU/+w0TQPYM/hMkxi56667cP7556O5uRmrV6/Gpk2bEIvFsHHjRgDA/fffjzvuuAMAMDo6it27d4+59Pb2YmBgALt370YkEjH+q3E4Qoy4PR5pStNKeVXiRTgWjcpeZr7wxuNPIR6PY+EZp6K6cWbG65ZVVwJI7XQh9kGYWBvSxUgt2zR6SE9hLRY5IzYZ1TSDg28kY+FXLNP9hm082bRogKnbNCJ9NTI6iqjNKv2iTeNYMdLU1ISNGzdi7969eOCBB9DV1YVVq1ahs7MTADBnzhzMnJn5RYJMTbqA0NuqEe8wh3p6oSiKYWezA71t7Xh76ysAgNPf956M15UGVr7Tth2TTdTQwKoPuZ+mIpDXcfCCY/v+jnBoBKUVQdTNnWPIfQrfhJ6MESCtTVNZOebjdtxLIxBtmkBdDTxeewSxazrFddddl/Hza9asyfj5j370o1oeriAZ7O5BaUUQ5dVVaHvnoObb53t7Ytsjj2Hx6jNx+hXr8NRPfjGl4BITSfmwJC/faN2XMLGmi5FyKUZYGdGCePMSrKmBt6gIADCSx56ReDSGw7vexMIzTsXclcvRfuBQ1vcpKyM6xnqBRHwAAJRWjq1mpzb22ssvAiTepEVGR+Hz+1HRUI/uo8esPhIX5dkNISLKdFZGhBjJ13eYu55+FiNDQ6hpasS8U1dMeb18F2VORlRGqhtnysWRrIzoQ+RXpIdXhYdDVh0nJ8g9NQb5RqQY0THWC6RyRorLyuDx+eTH7Zi+mo70jTTYY6KGYsRmiBfPQJZtmnx9EQ6HRrD9z38FAJx++boprydFWZ4+D04m1D8go+AbFi4YE91PMaINURkRL6ijw6G8D42T4Wcrlhpyf9m2aUYGBuVznr6fxo7pq+nIHTWz7GGtoBixGTJrhJWRKXnlkccAACsuvXDStd3eoiL5jnuIBlZbku4bKauqhNvtRjwWw1APo+C1EBpXGcnnsV7B4R0JE2vDgnkoCeoz+qcjKgM9x/WJEUVRZHWkdDIxYtPKiDDs2iVrhGLEZmQtRvK8MgIAB17bjs4jR1FcXoalF03ccCzi9GORqG1/ERQ6x0US6+IFqWpeTy+j+zUyoTKSx+ZVwVBvn/SKNK84Oev7S1VG9C/fkyms6WIkYF/PCJCqjFTbZKKGYsRmiFHUyfYcqEGkt+Zb4Fk6iqLg1UceBwCcMUmrRj4HeSzInE5qvHc+01ezQLwIytjxPE1fHY9RvpHy6ir4/H7E43H0tXXovh9hYk0XI8LAarf0VYEQX6yMkEnJNhI+UJ2fUfDjeeWPCTGy8KzTUTmjfsznaF61P8fSJmpE+mo+C2izGB/SVQiVEQA4+MYOAIm8kWyoTLZoBjq6EItGdd/PUG8vgLFtGjHaa7e9NIJum2WNUIzYDPELOaBzWV6qMpLfL8TdLa14e9trcLvdOG1c5gjHeu1P+4FDiEWjKA0G0XTSEgBAfye/X1oZ/667cMRIojIyZ9nJMuVUD8Jro3esVzDUO7FNI0LP7LaxV2C3FFaKEZthlIG1EN5lCiPr6ZePEyPJFhfTV+1LLBJBx8HDAIDFq88EUBg/s0YT6hv7QlcIBlYgIWaH+/vhLy3BzMULpr/BFIgXYr2TNILJ2jSpvTQ2FSNt7YjH4/AV+7Peh2YEFCM2Q7yAllYEx2w1VUNJMABvcs69EF6Idzz5DEaHQ6if14w5y1NGNrZpnIHwjcyYPxdAfk+AmcX4yshIHkfBp6MoCg5tT0bDr1yu+36EX0JvxohAtGnSU1jtPk0Ti0SkT6vSBlkjFCM2Y7ivP21mvVLTbcWLcKh/wHa7EMxgdHgYO//yNwDAGVe8V36cBlZnIMSIgOmr2gmHRhBN2/NVKG0aADgoxYh+30i2Y70C0aZJT2FNTdPYU4wA6Vkj1rdqKEZshhKPy5l1raWzfA88mwzRqlm59iIZh13OvTSO4PgEMcLvlx7SF2IWSpsGAA6JiZosTKxGjPUCaZWRCufkjAD28o1QjNgQmcKqcaKmEALPxvP2y6+ip/U4SoNBnLzmPABMX3UKEyojHO3VxRgxUkCVkcM730Q8FkN140wE6+t03Ue2G3sF0jOS9Kt5fD4ZyGjXnBHAXtt7KUZsiNxPU8XKyHQoiiLHfM+4IpE5In4hDPUUzvPgRHqOHR/jcSgkEW0k6e+8C8UzAiSqQK3J8Ly5OqLhvX6//J2ZrRgZGrcsrySYMK/G43GM2FmMHLdPCivFiA3RO1FTiJURAHglGYC25OyzEKitkWPRhSTKnIiiKDj+9jsAgFg0Kt9dEm0UapsGAA5u1x9+VtmQyCcaHR6ekNeiFSlGgkG4PR7pFxkZHJxys7gdkJURekbIZOgWIwVYGQGAzkNHcPCNnXB7PDj7mivhK/YDKLznwYmIVs1gd4+tf2nbmfTKyGiBJLAKsgk/M6pFA4z9HpRWBNP8IvatigBpBlZO05DJ0Lu5t5BHWrc9/CcAwDnXXQ0gsb00HBqx8khEBVKM0Lyqm/TKyMhggVVGkibWxpOWSAO7WuQkTZbmVQCIx2JyzLq0IpiapLGxeRVIfe3l1VWTLh3NJRQjNkTup6mu1HS7QIG2aQDgjT8/jcjoqAwdKkRB5kTefPZ59La1Y/tTf7X6KI4lvcUwOlxYlZHullYMdvfA6/OhYeE8TbdNTdJkXxkBIDdOl1VVyr00dh7rBYCRgUHpM7I6a4RixIaId4ls06hnZGAQu/76nPz3UAGEvuUDPceO4/aLr8DTP7vf6qM4lvTgs0KaphEc2/t3AEDjCYs13S7Vpsm+MgKMTWEVe2nsXhkBUl8/xQiZAA2s+tj28GPy74UoyEhhUqijvYKWtxJiZJZGMWJ4ZUSYWCsq5F4aO4/1CuwSfEYxYkPEgjctYsRbVCR3IRTqC/G+l15GX3tiDXihPgek8EhfxDZSkGJkH4AsKiNZpq8KhmTWSEVqL40TKiM2yRqhGLEhwjNSXFYGr9+v6jZCuETDYVvPtZuJEo9jy4MPA0itqCck3xGVkWg4jFhaNHyhcCwpRmYtWQiXy6XqNi6XS472Zpu+KhjuS4qRiorUNI3NPSMA0HvcHimsXksfnUzKyMAgopEIvD4fyqsq5Q9LJgox8Gwynvrxz7HvpW04sutNq49CSE7obW1DPBYzZETVibQfPIxwaAT+0lLUzGlC56Ej096mrLoSPr8f8XgcfW0dhpwj3cDqLysF4JDKSKs9gs9YGbEpWn0jhe4XESiKgoNv7EAsGrX6KITkhP6OTvzopn/Cf//Tv1p9FEtQ4nE5Iq62VVPVkKgC9Hd0Gva7YqgvlcLqpMoI2zQkI3KiRuV+GlZGCClc3nn1DXQcPGz1MSxDq2/EaPMqkDZNU5HyjAw7oDIi2lSVM+rhclsnCShGbIrYq1Kucj+NEC0UI4SQQuOYnKhZpOr6Ro/1Aqk4gbKqSlkZGbF5AisA9CWrQx6fF8G6GsvOQTFiUwbYpiGEEFW0vLUXgLWVkaG+iQmsw1nuvMkFSppvRrSvrIAGVpui1TMi2zSM1SaEFBitf9+PeCyGYG0NArU1GOjsynh9o8d6gVRlpLQiKD/mhJwRAHjpd5vg9fnQ35X5eTMTihGbotvA2s3KCCGksIiMjKL94GE0LJiHxhMW4a3npxMjojJiXJtGeEbcHo/8mBOmaQDgr//9K6uPwDaNXRnq7gUAlKvcT1POygghpIA5Jk2sS6a9bqVckmdcZSQWjWIkbWtyZHQU0XDYsPvPdyhGbAo9I4QQop4WlSZWr98v29pGGliBVNYI4JyqiF2gGLEpWto0Lrcb5VWVY25HCCGFhNrxXpG8OjI0ZLhgECmsgHP8InaBYsSmaNlPU1oRlH1KbqslhBQiok1T1zwb/tLSKa8nzKtGTtIIhG8EYGVEKxQjNkWICp/fn/E/FpASLEM9vYjHYmYfjRBCbMdQb59cnTFrycIpr1cl/CIGTtKkn0HghPRVO0ExYlPCoRGMDocATF8dEf3PAbZoCCEFTMo3MnWrpmqWeZWRIVZGdEMxYmOkb2SaSHghVgZpXiWEFDBqfCMi8Mxo8yowvjJCz4gWKEZsjFoTK/fSEEJIyjeSaaJGpIya7RlxQvqqnaAYsTFSjCQnZaaCY72EEJKqjMxcOB9ur2fS68jKiMmeESfspbETFCM2RphYy6urM16PlRFCCAG6W1oR6h+At6gIM+bPnfB5l8slR3t7jrUa/vhDYyoj9IxogWLExqgd72VlhBBCErTsTZhYJ0tiLauuhM/vRzweR197h+GPPcxpGt1QjNiYAbUGVlZGCCEEQGYTq/CL9Hd0Ih41PgaB0zT6oRixMVo9IxQjhJBC51iGWHgzx3oBYKi3V/6dlRFtUIzYmNSyPLZpCCFEDS1v7QUANC6ZKEbMHOsFEtuDxRTNQCd/H2vBa/UByNSoGe0tKimBv7QkcX1u7CWEFDht7xxENBxGSTCA6saZ6G5JGVXNHOsVbPjiegRrq9Hf0WnaY+QjFCM2RnhGyqoq4XK5oCjKhOsIP8nocAjhUCin5yOEELsRj8bQ+vY7mH3SCWg8YfEYMWLmWK9g7wtbTLvvfIZtGhszlBQjHq8XxYHApNfhWC8hhIzl2BSx8FVCjBwzp01D9EMxYmNi0ah0ZAemmKhhFDwhhIxlqomaygZzPSNEPxQjNmc63wgrI4QQMpZjUoykTKxev1/+vuw1sU1D9EExYnOmEyOcpCGEkLEc2/s2gEQlpKyyAkCqRTMyNMQMEBtCMWJz0k2sk8GMEUIIGcvo8DA6Dh0BkPKNCDFi5iQN0Q/FiM0R+2kCbNMQQohqxvtGKpNjvWZO0hD9UIzYHNmmqZl8WR7bNIQQMhExUSN8I6yM2BuKEZsz3bI87qUhhJCJiCRW0aap5FivraEYsTkiVXUqz0iAlRFCCJlAy55Em6Z+7hz4iv0yfbXnOMWIHaEYsTmDSc/IZJURt9cjRQorI4QQkmKgqxv9nV1wezyYuWiBrIywTWNPNImR9evXQ1GUMZc9e/ZMef0rr7wS27ZtQ09PDwYHB/H666/j+uuvz/rQhYQQGZMZWMsqKwEA8VgMw2mrqwkhhKSZWE9ckkpfZeCZLdG8m2bXrl24+OKL5b+j0eiU1+3u7sa3vvUtvPXWWwiHw7jsssvwi1/8Au3t7XjyySf1nbjAGEwb7XV7PIjHYvJzcpKmp3fSvTWEEFLIHHvr7zjx3NU44Zyz4C0qQjweR197h9XHIpOgWYxEo1G0takrcz377LNj/v29730PN9xwA84991yKEZUM9fYhHo/D7XajtDI4ZjMvo+AJIWRqRGVk8eqzAAD9HZ2IR2OZbkIsQrNnZNGiRWhpacH+/fuxYcMGzJ49W/VtL7zwQixZsgTPPfdcxusVFRUhEAiMuRQqSjwuWzDl1WPHe8XGXvpFCCFkIkKMFJUUA6BfxM5oEiNbt27FjTfeiLVr1+KWW27BvHnzsHnzZpSXl095m2AwiIGBAYTDYfzpT3/CZz7zGfzlL3/J+Di33nor+vv75aWlpUXLMfOOqXwjgWqO9RJCyFR0HT6K0eFh+e+eY60WnoZkQpMYeeKJJ/Dggw9i586dePLJJ7Fu3TpUVlbimmuumfI2AwMDWLlyJc444wx85StfwX/913/hggsuyPg4d955J4LBoLw0NjZqOWbeMdV+GlEZ4VgvIYRMRFEUuacGYPqqndHsGUmnr68P+/btw8KFC6e8jqIo2L9/PwBg+/btOPHEE3HrrbdO8JOkEw6HEQ6HszlaXjE4xX4aRsETQkhmWt7ah3mnLAfANo2dySpnpKysDAsWLEBrq/rSl9vtht/vz+ZhCw6ZNVIzrjLCwDNCCMnIsaRvBAB6KEZsi6bKyF133YU//vGPOHToEGbNmoVvfOMbiMVi2LhxIwDg/vvvR0tLC2677TYAwJe//GW88sor2L9/P/x+P9atW4cPf/jDuOWWW4z/SvKYqds0ycpIFysjhBAyGS1jxAgzRuyKJjHS1NSEjRs3oqamBh0dHXj++eexatUqdHZ2AgDmzJmDeDwur19WVoYf/vCHaGpqQigUwltvvYXrr78eDzzwgLFfRZ4jxMZEAysrI4QQkonjbx/AyOAQPD4vuluOWX0cMgWaxMh1112X8fNr1qwZ8++vfe1r+NrXvqb9VGQMYlleWdXkbRp6RgghZHKi4TB+dNOn4S3yY3RoePobEEvIysBKcsNk+2mKA+XwFhUlPk8xQgghU3L0zb1WH4FMAxflOYDJPCPi76GBQUQ5eUQIIcTBUIw4ACFGSgLl8Ph8ADjWSwghJH+gGHEAof4BxCKJhYTl1ZXJP7mXhhBCSH5AMeIQBnvGtmpEZWSAlRFCCCEOh2LEIaR8I9XJP1kZIYQQkh9QjDiE8SZWekYIIYTkCxQjDkGKkeR+GkbBE0IIyRcoRhzC+P00DDwjhBCSL1CMOAQRCc82DSGEkHyDYsQhjPeMsE1DCCEkX6AYcQgpz0gVvEVFKAkGxnycEEIIcSoUIw4hPWdEmFijkQhC/QMWnooQQgjJHooRh5DepimnX4QQQkgeQTHiEISBtaikGDWzGwHQL0IIISQ/oBhxCOFQCOHQCACgYcE8AKyMEEIIyQ8oRhyE8I00LFqQ+DcrI4QQQvIAihEHISohMxfOT/y7i5URQgghzodixEEIMVIzp2nMvwkhhBAnQzHiIIT4cLsT3zYaWAkhhOQDFCMOYqi7d8y/WRkhhBCSD1CMOIjx4oOVEUIIIfkAxYiDGBgnRlgZIYQQkg9QjDiI8eJDjPoSQgghToZixEEMpYmPod4+xKMxC09DCCGEGAPFiINIzxVhi4YQQki+QDHiIAZ7euXfaV4lhBCSL1CMOIhoOIzQwCAAVkYIIYTkDxQjDmMoWR3hXhpCCCH5AsWIwxAVkfFjvoQQQohToRhxGN3HWgEAPS2tFp+EEEIIMQav1Qcg2njsnh/hwGvbsf3Jv1p9FEIIIcQQKEYcRs+x43jxt3+w+hiEEEKIYbBNQwghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoQQQgghlkIxQgghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRRHbe0NBAJWH4EQQgghKlH7uu0IMSK+mJaWFotPQgghhBCtBAIBDAwMTPl5FwAld8fRz6xZszJ+IXoIBAJoaWlBY2Oj4fdNUvB5zh18rnMDn+fcwOc5N5j9PAcCARw7dizjdRxRGQEw7ReSDQMDA/xBzwF8nnMHn+vcwOc5N/B5zg1mPc9q7pMGVkIIIYRYCsUIIYQQQiyloMXI6Ogo/u3f/g2jo6NWHyWv4fOcO/hc5wY+z7mBz3NusMPz7BgDKyGEEELyk4KujBBCCCHEeihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYSkGLkX/8x3/EgQMHEAqFsGXLFpxxxhlWH8nRnHfeeXjkkUfQ0tICRVFwxRVXTLjON77xDRw7dgzDw8N46qmnsHDhQgtO6my+/OUv4+WXX0Z/fz/a2tqwadMmLF68eMx1/H4/fvCDH6CzsxMDAwN48MEHUV9fb9GJncmnPvUpbN++HX19fejr68OLL76ItWvXys/zOTaHL33pS1AUBXfffbf8GJ/r7Fm/fj0URRlz2bNnj/y8HZ5jpRAv11xzjTIyMqLceOONyoknnqj85Cc/Ubq7u5W6ujrLz+bUy9q1a5Xbb79def/7368oiqJcccUVYz7/xS9+Uenp6VEuv/xyZdmyZcpDDz2k7N+/X/H7/Zaf3UmXxx9/XLnhhhuUk046SVm+fLny6KOPKgcPHlRKS0vldX74wx8qhw4dUtasWaOceuqpyosvvqg8//zzlp/dSZfLLrtMec973qMsXLhQWbRokfLNb35TGR0dVU466SQ+xyZdTj/9dOWdd95R3njjDeXuu++WH+dznf1l/fr1ys6dO5UZM2bIS01NjZ2eY+ufJCsuW7ZsUb7//e/Lf7tcLuXo0aPKl770JcvPlg+XycTIsWPHlC984Qvy38FgUAmFQsq1115r+XmdfKmtrVUURVHOO+88+byOjo4qV111lbzOkiVLFEVRlLPOOsvy8zr50tXVpXzsYx/jc2zCpaysTNm7d69y0UUXKc8884wUI3yujbmsX79eef311yf9nB2e44Js0/h8Ppx22mn4y1/+Ij+mKAr+8pe/YPXq1RaeLH+ZN28eZs6cOeY57+/vx9atW/mcZ0lFRQUAoLu7GwBw2mmnoaioaMxzvXfvXhw6dIjPtU7cbjeuvfZalJWV4aWXXuJzbAL33nsv/vSnP+Hpp58e83E+18axaNEitLS0YP/+/diwYQNmz54NwB7PsWMW5RlJbW0tvF4v2traxny8ra0NJ5xwgkWnym8aGhoAYNLnXHyOaMflcuG73/0unn/+eezevRtA4rkeHR1FX1/fmOvyudbO0qVL8dJLL6G4uBiDg4O48sorsWfPHqxcuZLPsYFce+21OPXUUyf17fHn2Ri2bt2KG2+8EXv37sXMmTOxfv16bN68GUuXLrXFc1yQYoSQfOHee+/F0qVLce6551p9lLxk7969WLlyJSoqKnD11Vfj/vvvxwUXXGD1sfKKpqYm3HPPPbjkkksY+24iTzzxhPz7zp07sXXrVhw6dAjXXHMNQqGQhSdLUJBtms7OTkSjUcyYMWPMx2fMmIHjx49bdKr8RjyvfM6N4/vf/z4uu+wyrFmzBi0tLfLjx48fh9/vl+0bAZ9r7UQiEezfvx+vvfYabrvtNmzfvh2f/exn+RwbyGmnnYYZM2bgtddeQyQSQSQSwbve9S788z//MyKRCNra2vhcm0BfXx/27duHhQsX2uLnuSDFSCQSwauvvoqLLrpIfszlcuGiiy7CSy+9ZOHJ8pcDBw6gtbV1zHMeCARw1lln8TnXwfe//31ceeWVuPDCC3Hw4MExn3v11VcRDofHPNeLFy9Gc3Mzn+sscbvd8Pv9fI4N5Omnn8bSpUuxcuVKedm2bRt+/etfY+XKlXjllVf4XJtAWVkZFixYgNbWVtv8PFvu8rXics011yihUEj5yEc+opxwwgnKj3/8Y6W7u1upr6+3/GxOvZSVlSkrVqxQVqxYoSiKonzuc59TVqxYocyePVsBEqO93d3dyvve9z5l6dKlyqZNmzjaq+Ny7733Kj09Pcr5558/ZkyvuLhYXueHP/yhcvDgQeVd73qXcuqppyovvPCC8sILL1h+didd7rjjDuW8885TmpublaVLlyp33HGHEovFlIsvvpjPscmX9GkaPtfGXO666y7l/PPPV5qbm5XVq1crTz75pNLe3q7U1tba5Tm2/kmy6vLpT39aOXjwoDIyMqJs2bJFOfPMMy0/k5MvF1xwgTIZv/jFL+R1vvGNbyitra1KKBRSnnrqKWXRokWWn9tpl6m44YYb5HX8fr/ygx/8QOnq6lIGBweV3//+98qMGTMsP7uTLvfdd59y4MABZWRkRGlra1OeeuopKUT4HJt7GS9G+Fxnf9m4caPS0tKijIyMKEeOHFE2btyozJ8/3zbPsSv5F0IIIYQQSyhIzwghhBBC7APFCCGEEEIshWKEEEIIIZZCMUIIIYQQS6EYIYQQQoilUIwQQgghxFIoRgghhBBiKRQjhBBCCLEUihFCCCGEWArFCCGEEEIshWKEEEIIIZZCMUIIIYQQS/n/y9BnUZXaKWAAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "trainer.runner.cbs[1].plot_loss()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View learning rate" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "trainer.runner.cbs[1].plot_lr()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Publish the run to OpenML" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "run.publish()" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/Examples/Sequential Classification Task.ipynb b/docs/Examples/Sequential Classification Task.ipynb new file mode 100644 index 0000000..597ac77 --- /dev/null +++ b/docs/Examples/Sequential Classification Task.ipynb @@ -0,0 +1,422 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Sequential classification\n", + "- Sequential classification of a tabular MNIST dataset (Task 3573) using a simple neural network." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import torch.nn\n", + "import torch.optim\n", + "\n", + "import openml_pytorch.config\n", + "import openml\n", + "import logging\n", + "import warnings\n", + "\n", + "# Suppress FutureWarning messages\n", + "warnings.simplefilter(action='ignore')\n", + "\n", + "############################################################################\n", + "# Enable logging in order to observe the progress while running the example.\n", + "openml.config.logger.setLevel(logging.DEBUG)\n", + "openml_pytorch.config.logger.setLevel(logging.DEBUG)\n", + "############################################################################" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from openml_pytorch.trainer import OpenMLTrainerModule\n", + "from openml_pytorch.trainer import OpenMLDataModule" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define the Model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "############################################################################\n", + "# Define a sequential network that does the initial image reshaping\n", + "# and normalization model.\n", + "processing_net = torch.nn.Sequential(\n", + " openml_pytorch.layers.Functional(function=torch.Tensor.reshape,\n", + " shape=(-1, 1, 28, 28)),\n", + " torch.nn.BatchNorm2d(num_features=1)\n", + ")\n", + "############################################################################\n", + "\n", + "############################################################################\n", + "# Define a sequential network that does the extracts the features from the\n", + "# image.\n", + "features_net = torch.nn.Sequential(\n", + " torch.nn.Conv2d(in_channels=1, out_channels=32, kernel_size=5),\n", + " torch.nn.LeakyReLU(),\n", + " torch.nn.MaxPool2d(kernel_size=2),\n", + " torch.nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5),\n", + " torch.nn.LeakyReLU(),\n", + " torch.nn.MaxPool2d(kernel_size=2),\n", + ")\n", + "############################################################################\n", + "\n", + "############################################################################\n", + "# Define a sequential network that flattens the features and compiles the\n", + "# results into probabilities for each digit.\n", + "results_net = torch.nn.Sequential(\n", + " openml_pytorch.layers.Functional(function=torch.Tensor.reshape,\n", + " shape=(-1, 4 * 4 * 64)),\n", + " torch.nn.Linear(in_features=4 * 4 * 64, out_features=256),\n", + " torch.nn.LeakyReLU(),\n", + " torch.nn.Dropout(),\n", + " torch.nn.Linear(in_features=256, out_features=10),\n", + ")\n", + "############################################################################\n", + "# openml.config.apikey = 'key'\n", + "\n", + "############################################################################\n", + "# The main network, composed of the above specified networks.\n", + "model = torch.nn.Sequential(\n", + " processing_net,\n", + " features_net,\n", + " results_net\n", + ")\n", + "############################################################################\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure the Data Module" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data_module = OpenMLDataModule(\n", + " type_of_data=\"dataframe\",\n", + " filename_col=\"class\",\n", + " target_mode=\"categorical\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure the Trainer Module" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "trainer = OpenMLTrainerModule(\n", + " data_module=data_module,\n", + " verbose = True,\n", + " epoch_count = 1,\n", + " callbacks=[],\n", + ")\n", + "openml_pytorch.config.trainer = trainer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Download the task" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Download the OpenML task for the mnist 784 dataset.\n", + "task = openml.tasks.get_task(3573)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the model on the task" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.32331635113536156, tensor(0.9008, device='mps:0')]\n", + "valid: [0.06406866648840526, tensor(0.9811, device='mps:0')]\n", + "Loss tensor(0.0628, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.38453052662037035, tensor(0.8769, device='mps:0')]\n", + "valid: [0.07353694370814733, tensor(0.9784, device='mps:0')]\n", + "Loss tensor(0.2696, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.32017667686287477, tensor(0.9007, device='mps:0')]\n", + "valid: [0.059844534737723214, tensor(0.9830, device='mps:0')]\n", + "Loss tensor(0.1902, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.3072006930665785, tensor(0.9049, device='mps:0')]\n", + "valid: [0.05989732045975942, tensor(0.9832, device='mps:0')]\n", + "Loss tensor(0.1913, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.35497158151455027, tensor(0.8902, device='mps:0')]\n", + "valid: [0.0839210437593006, tensor(0.9757, device='mps:0')]\n", + "Loss tensor(0.2628, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.36122630070546735, tensor(0.8852, device='mps:0')]\n", + "valid: [0.0754026867094494, tensor(0.9811, device='mps:0')]\n", + "Loss tensor(0.0035, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.31011446621472666, tensor(0.9039, device='mps:0')]\n", + "valid: [0.06878100198412698, tensor(0.9811, device='mps:0')]\n", + "Loss tensor(0.0127, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.3331792190255732, tensor(0.8969, device='mps:0')]\n", + "valid: [0.07425410679408483, tensor(0.9798, device='mps:0')]\n", + "Loss tensor(0.0351, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.3379972373787478, tensor(0.8956, device='mps:0')]\n", + "valid: [0.0701195562453497, tensor(0.9797, device='mps:0')]\n", + "Loss tensor(0.1058, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.35787033592372136, tensor(0.8865, device='mps:0')]\n", + "valid: [0.06584922669425844, tensor(0.9830, device='mps:0')]\n", + "Loss tensor(0.2519, device='mps:0')\n" + ] + } + ], + "source": [ + "run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View loss" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "trainer.runner.cbs[1].plot_loss()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View learning rate" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "trainer.runner.cbs[1].plot_lr()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Publish the run to OpenML" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "run.publish()" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/Examples/index.md b/docs/Examples/index.md new file mode 100644 index 0000000..9888d03 --- /dev/null +++ b/docs/Examples/index.md @@ -0,0 +1,3 @@ +# Examples + +This folder contains examples of how to use the `openml-pytorch` extension for different types of data. \ No newline at end of file diff --git a/docs/Limitations of the API.md b/docs/Limitations of the API.md new file mode 100644 index 0000000..afc22de --- /dev/null +++ b/docs/Limitations of the API.md @@ -0,0 +1,3 @@ +# Limitations +- Image datasets are supported as a workaround by using a CSV file with image paths. This is not ideal and might eventually be replaced by something else. At the moment, the focus is on tabular data. +- Many features (like custom metrics, models etc) are still dependant on the OpenML Python API, which is in the middle of a major rewrite. Until that is complete, this package will not be able to provide all the features it aims to. \ No newline at end of file diff --git a/docs/Philosophy behind the API Design.md b/docs/Philosophy behind the API Design.md new file mode 100644 index 0000000..bdc69e9 --- /dev/null +++ b/docs/Philosophy behind the API Design.md @@ -0,0 +1,9 @@ +# Philosophy behind the API design +This API is designed to make it easier to use PyTorch with OpenML and has been heavily inspired by the current state of the art Deep Learning frameworks like FastAI and PyTorch Lightning. + +To make the library as modular as possible, callbacks are used throughout the training loop. This allows for easy customization of the training loop without having to modify the core code. + +## Separation of Concerns +Here, we focus on the data, model and training as separate blocks that can be strung together in a pipeline. This makes it easier to experiment with different models, data and training strategies. + +That being the case, the OpenMLDataModule and OpenMLTrainerModule are designed to handle the data and training respectively. This might seem a bit verbose at first, but it makes it easier to understand what is happening at each step of the process and allows for easier customization. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..da96599 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,81 @@ +# Pytorch extension for OpenML python + +Pytorch extension for [openml-python API](https://github.com/openml/openml-python). + +#### Installation Instructions: + +`pip install openml-pytorch` + +PyPi link https://pypi.org/project/openml-pytorch/ + +## Usage +To use this extension, you need to have a task from OpenML. You can either browse the [OpenML website](https://openml.org/search?type=task&sort=runs) to find a task (and get it's ID), or follow the [example](./Examples/Create%20Dataset%20and%20Task.ipynb) to create a task from a custom dataset. + +Then, follow one of the examples in the [Examples](./Examples) folder to see how to use this extension for your type of data. + +Import openML libraries +```python +import torch.nn +import torch.optim + +import openml_pytorch.config +import openml +import logging + +from openml_pytorch.trainer import OpenMLTrainerModule +from openml_pytorch.trainer import OpenMLDataModule +from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor, Lambda +import torchvision +from openml_pytorch.trainer import convert_to_rgb + +``` +Create a pytorch model and get a task from openML +```python +model = torchvision.models.efficientnet_b0(num_classes=200) +# Download the OpenML task for tiniest imagenet +task = openml.tasks.get_task(362127) +``` +Download the task from openML and define Data and Trainer configuration +```python +transform = Compose( + [ + ToPILImage(), # Convert tensor to PIL Image to ensure PIL Image operations can be applied. + Lambda( + convert_to_rgb + ), # Convert PIL Image to RGB if it's not already. + Resize( + (64, 64) + ), # Resize the image. + ToTensor(), # Convert the PIL Image back to a tensor. + ] +) +data_module = OpenMLDataModule( + type_of_data="image", + file_dir="datasets", + filename_col="image_path", + target_mode="categorical", + target_column="Class_encoded", + batch_size = 64, + transform=transform +) +trainer = OpenMLTrainerModule( + data_module=data_module, + verbose = True, + epoch_count = 1, +) +openml_pytorch.config.trainer = trainer +``` +Run the model on the task +```python +run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False) +run.publish() +print('URL for run: %s/run/%d' % (openml.config.server, run.run_id)) +``` +Note: The input layer of the network should be compatible with OpenML data output shape. Please check [examples](/examples/) for more information. + +Additionally, if you want to publish the run with onnx file, then you must call ```openml_pytorch.add_onnx_to_run()``` immediately before ```run.publish()```. + +```python +run = openml_pytorch.add_onnx_to_run(run) +``` + diff --git a/examples/create_new_task.py b/examples/create_new_task.py deleted file mode 100644 index 1aac8c1..0000000 --- a/examples/create_new_task.py +++ /dev/null @@ -1,38 +0,0 @@ -import openml -from openml.tasks import OpenMLClassificationTask - -task = openml.tasks.get_task(361175) -# openml.config.apikey = 'KEY' -# Define task parameters -task_type = openml.tasks.TaskType.SUPERVISED_CLASSIFICATION -evaluation_measure = 'predictive_accuracy' -estimation_procedure = { - 'type': 'crossvalidation', - 'parameters': { - 'number_repeats': '1', - 'number_folds': '10', - 'percentage': '', - 'stratified_sampling': 'true' - }, - 'data_splits_url': 'https://api.openml.org/api_splits/get/361175/Task_361175_splits.arff' -} -target_name = 'CATEGORY' -class_labels = ['Adrenal_gland', 'Bile-duct', 'Bladder', 'Breast', 'Cervix', 'Colon', 'Esophagus', 'HeadNeck', 'Kidney', 'Liver', 'Lung', 'Ovarian', 'Pancreatic', 'Prostate', 'Skin', 'Stomach', 'Testis', 'Thyroid', 'Uterus'] -cost_matrix = None - -# 'split': - -# Create the task -new_task = openml.tasks.create_task( - task_type=task_type, - dataset_id=task.dataset_id, - estimation_procedure_id = task.estimation_procedure_id, - # estimation_procedure=estimation_procedure, - target_name=target_name, - class_labels=class_labels, - cost_matrix=cost_matrix -) - -print(new_task) - -new_task.publish() diff --git a/examples/pytorch_IndoorScenes_classification.py b/examples/pytorch_IndoorScenes_classification.py deleted file mode 100644 index 1a3b9fc..0000000 --- a/examples/pytorch_IndoorScenes_classification.py +++ /dev/null @@ -1,65 +0,0 @@ -import torch -import torch.nn as nn -import torch.nn.functional as F -import openml_pytorch -import openml -import warnings - -# warnings.simplefilter(action='ignore', category=FutureWarning) -warnings.simplefilter(action='ignore') - - -def evaluate_torch_model(model): - # Download CV splits - task = openml.tasks.get_task(362070) - # Evaluate model - run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False) - # Publish - run = openml_pytorch.add_onnx_to_run(run) # Optional, to inspect afterward - run.publish() - return run - -from torchvision import models -from torchvision.transforms import v2 - -class Model2(nn.Module): - def __init__(self, num_classes=67): - super(Model2, self).__init__() - self.conv1 = nn.Conv2d(3, 6, 5) - self.pool = nn.MaxPool2d(2, 2) - self.conv2 = nn.Conv2d(6, 16, 5) - self.fc1 = nn.Linear(13456, 120) - self.fc2 = nn.Linear(120, 84) - self.fc3 = nn.Linear(84, num_classes) - - def forward(self, x): - x = self.pool(F.relu(self.conv1(x))) - x = self.pool(F.relu(self.conv2(x))) - x = torch.flatten(x, 1) # flatten all dimensions except batch - x = F.relu(self.fc1(x)) - x = F.relu(self.fc2(x)) - x = self.fc3(x) - return x - -# Training parameters -openml_pytorch.config.batch_size = 32 -openml_pytorch.config.epoch_count = 1 -openml_pytorch.config.image_size = 128 - -transforms = v2.Compose([ - v2.RandomResizedCrop(size=(224, 224), antialias=True), - v2.RandomHorizontalFlip(p=0.5), - v2.ToDtype(torch.float32, scale=True), - v2.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), -]) - -openml_pytorch.config.data_augmentation = transforms -openml_pytorch.config.perform_validation = True - -openml.config.apikey = 'key' -openml_pytorch.config.file_dir = openml.config.get_cache_directory()+'/datasets/45923/Images/' -openml_pytorch.config.filename_col = "Filename" - -# Run -run = evaluate_torch_model(Model2()) # Replace with your model -print('URL for run: %s/run/%d?api_key=%s' % (openml.config.server, run.run_id, openml.config.apikey)) \ No newline at end of file diff --git a/examples/pytorch_image_classification_example.py b/examples/pytorch_image_classification_example.py deleted file mode 100644 index ba2451e..0000000 --- a/examples/pytorch_image_classification_example.py +++ /dev/null @@ -1,100 +0,0 @@ -""" -PyTorch image classification model example -================== - -An example of a pytorch network that classifies meta album images. -""" - -import torch.nn -import torch.optim - -import openml -import openml_pytorch -import openml_pytorch.layers -import openml_pytorch.config -import logging - -import warnings -import pandas as pd - -# Suppress FutureWarning messages -warnings.simplefilter(action='ignore') - -############################################################################ -# Enable logging in order to observe the progress while running the example. -openml.config.logger.setLevel(logging.DEBUG) -openml_pytorch.config.logger.setLevel(logging.DEBUG) -############################################################################ - -############################################################################ -import torch.nn as nn -import torch.nn.functional as F - -# Example model. You can do better :) -class Net(nn.Module): - def __init__(self): - super().__init__() - self.conv1 = nn.Conv2d(3, 6, 5) - self.pool = nn.MaxPool2d(2, 2) - self.conv2 = nn.Conv2d(6, 16, 5) - self.fc1 = nn.Linear(13456, 120) - self.fc2 = nn.Linear(120, 84) - self.fc3 = nn.Linear(84, 19) # To user - Remember to set correct size of last layer. - - def forward(self, x): - x = self.pool(F.relu(self.conv1(x))) - x = self.pool(F.relu(self.conv2(x))) - x = torch.flatten(x, 1) # flatten all dimensions except batch - x = F.relu(self.fc1(x)) - x = F.relu(self.fc2(x)) - x = self.fc3(x) - return x - -net = Net() - -############################################################################ -openml.config.apikey = 'key' -openml_pytorch.config.file_dir = openml.config.get_cache_directory()+'/datasets/44312/PNU_Micro/images/' -openml_pytorch.config.filename_col = "FILE_NAME" -openml_pytorch.config.perform_validation = False -#You can set the device type here, -# alternatively config auto selects it for you depending on the device availability. -openml_pytorch.config.device = torch.device("cpu") -############################################################################ -# The main network, composed of the above specified networks. -model = net - -############################################################################ -# Download the OpenML task for the Meta_Album_PNU_Micro dataset. -task = openml.tasks.get_task(361987) - -############################################################################ -# Run the model on the task (requires an API key).m -run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False) - -# If you want to publish the run with the onnx file, -# then you must call openml_pytorch.add_onnx_to_run() immediately before run.publish(). -# When you publish, onnx file of last trained model is uploaded. -# Careful to not call this function when another run_model_on_task is called in between, -# as during publish later, only the last trained model (from last run_model_on_task call) is uploaded. -run = openml_pytorch.add_onnx_to_run(run) -run.publish() - -print('URL for run: %s/run/%d' % (openml.config.server, run.run_id)) -############################################################################ - -# Visualize model in netron - -from urllib.request import urlretrieve - -published_run = openml.runs.get_run(run.run_id) -url = 'https://api.openml.org/data/download/{}/model.onnx'.format(published_run.output_files['onnx_model']) - -file_path, _ = urlretrieve(url, 'model.onnx') - -import netron -# Visualize the ONNX model using Netron -netron.start(file_path) - - - diff --git a/examples/pytorch_pretrained_image_classification_example.py b/examples/pytorch_pretrained_image_classification_example.py deleted file mode 100644 index c10e499..0000000 --- a/examples/pytorch_pretrained_image_classification_example.py +++ /dev/null @@ -1,89 +0,0 @@ -""" -PyTorch image classification model using pre-trained ResNet model example -================== - -An example of a pytorch network that classifies meta album images. -""" - -import torch.nn -import torch.optim - -import openml -import openml_pytorch -import openml_pytorch.layers -import openml_pytorch.config -import logging - -############################################################################ -# Enable logging in order to observe the progress while running the example. -openml.config.logger.setLevel(logging.DEBUG) -openml_pytorch.config.logger.setLevel(logging.DEBUG) -############################################################################ - -############################################################################ -import torch.nn as nn -import torch.nn.functional as F - -# Example model. You can do better :) -import torchvision.models as models - -# Load the pre-trained ResNet model -model = models.resnet50(pretrained=True) - -# Modify the last fully connected layer to the required number of classes -num_classes = 20 -in_features = model.fc.in_features -model.fc = nn.Linear(in_features, num_classes) - -# Optional: If you're fine-tuning, you may want to freeze the pre-trained layers -for param in model.parameters(): - param.requires_grad = False - -# If you want to train the last layer only (the newly added layer) -for param in model.fc.parameters(): - param.requires_grad = True - -############################################################################ -# Setting an appropriate optimizer -from openml import OpenMLTask - -def custom_optimizer_gen(model: torch.nn.Module, task: OpenMLTask) -> torch.optim.Optimizer: - return torch.optim.Adam(model.fc.parameters()) - -openml_pytorch.config.optimizer_gen = custom_optimizer_gen - -############################################################################ - -openml.config.apikey = 'KEY' -openml_pytorch.config.filename_col = "FILE_NAME" -openml_pytorch.config.perform_validation = False - -############################################################################ -# Download the OpenML task for the Meta_Album_PNU_Micro dataset. -task = openml.tasks.get_task(361152) - -############################################################################ -# Run the model on the task (requires an API key).m -run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False) - -# Publish the experiment on OpenML (optional, requires an API key). -run.publish() - -print('URL for run: %s/run/%d' % (openml.config.server, run.run_id)) - -############################################################################ - -# Visualize model in netron -import netron - -# Define input size -input_size = (32,3,128,128) - -# Create a dummy input with the specified size -dummy_input = torch.randn(input_size) - -# Export the model to ONNX -torch.onnx.export(model, dummy_input, "model.onnx", verbose=True) - -# Visualize the ONNX model using Netron -netron.start("model.onnx") \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..483a917 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,50 @@ +site_name: OpenML PyTorch Extension +theme: + name: material + features: + - content.code.copy + palette: + # Light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: indigo + accent: indigo + toggle: + icon: material/toggle-switch-off-outline + name: Switch to dark mode + + # Dark mode + - media: "(prefers-color-scheme: dark)" + primary: indigo + accent: indigo + scheme: slate + toggle: + icon: material/toggle-switch + name: Switch to light mode + +markdown_extensions: + - admonition + - codehilite + - attr_list + - pymdownx.details + - pymdownx.superfences + - pymdownx.highlight: + linenums: true + - pymdownx.inlinehilite + - toc: + permalink: true +plugins: + - search + - mkdocs-jupyter + # - mknotebooks: + # execute: false + - mkdocstrings: + default_handler: python + handlers: + python: + paths: [openml_pytorch] + load_external_modules: true + show_source: true + options: + docstring_section_style: table + show_docstring_functions: true \ No newline at end of file diff --git a/openml_pytorch/callbacks.py b/openml_pytorch/callbacks.py index a2a794c..23cd989 100644 --- a/openml_pytorch/callbacks.py +++ b/openml_pytorch/callbacks.py @@ -1,3 +1,9 @@ +""" +Callbacks module contains classes and functions for handling callback functions during an event-driven process. This makes it easier to customize the behavior of the training loop and add additional functionality to the training process without modifying the core code. + +To use a callback, create a class that inherits from the Callback class and implement the necessary methods. Callbacks can be used to perform actions at different stages of the training process, such as at the beginning or end of an epoch, batch, or fitting process. Then pass the callback object to the Trainer. +""" + from functools import partial import math import re diff --git a/openml_pytorch/custom_datasets.py b/openml_pytorch/custom_datasets.py index bcb9259..4fa1b1b 100644 --- a/openml_pytorch/custom_datasets.py +++ b/openml_pytorch/custom_datasets.py @@ -1,3 +1,6 @@ +""" +This module contains custom dataset classes for handling image and tabular data from OpenML in PyTorch. To add support for new data types, new classes can be added to this module. +""" import os from typing import Any import pandas as pd diff --git a/openml_pytorch/extension.py b/openml_pytorch/extension.py index 376f219..40d0826 100644 --- a/openml_pytorch/extension.py +++ b/openml_pytorch/extension.py @@ -1,3 +1,6 @@ +""" +This module defines the Pytorch extension for OpenML-python. +""" from collections import OrderedDict # noqa: F401 import copy from distutils.version import LooseVersion diff --git a/openml_pytorch/metrics.py b/openml_pytorch/metrics.py index 2719dd4..7cf8089 100644 --- a/openml_pytorch/metrics.py +++ b/openml_pytorch/metrics.py @@ -1,17 +1,22 @@ +""" +This module provides utility functions for evaluating model performance and activation functions. +It includes functions to compute the accuracy, top-k accuracy of model predictions, and the sigmoid function. +""" import torch import numpy as np def accuracy(out, yb): """ - Calculates the accuracy of model predictions. + + Computes the accuracy of model predictions. Parameters: - out: A tensor containing the model's predicted outputs. - yb: A tensor containing the actual labels. + out (Tensor): The output tensor from the model, containing predicted class scores. + yb (Tensor): The ground truth labels tensor. Returns: - The proportion of correct predictions as a float. + Tensor: The mean accuracy of the predictions, computed as a float tensor. """ return (torch.argmax(out, dim=1) == yb.long()).float().mean() diff --git a/openml_pytorch/trainer.py b/openml_pytorch/trainer.py index 029caa9..6ae6a89 100644 --- a/openml_pytorch/trainer.py +++ b/openml_pytorch/trainer.py @@ -1,3 +1,12 @@ +""" +This module provides classes and methods to facilitate the configuration, data handling, training, and evaluation of machine learning models using PyTorch and OpenML datasets. The functionalities include: +- Generation of default configurations for models. +- Handling of image and tabular data. +- Training and evaluating machine learning models. +- Exporting trained models to ONNX format. +- Managing data transformations and loaders. +""" + import gc import logging import re @@ -697,7 +706,7 @@ def run_training(self, task, X_train, y_train, X_test): return data, model_classes def add_callbacks(self): - if self.callbacks is not None: + if self.callbacks is not None and len(self.callbacks) > 0: for callback in self.callbacks: if callback not in self.cbfs: self.cbfs.append(callback) diff --git a/poetry.lock b/poetry.lock index 0055464..e8114b7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -11,6 +11,17 @@ files = [ {file = "absl_py-2.1.0-py3-none-any.whl", hash = "sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308"}, ] +[[package]] +name = "appnope" +version = "0.1.4" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = ">=3.6" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] + [[package]] name = "argon2-cffi" version = "23.1.0" @@ -68,6 +79,107 @@ cffi = ">=1.0.1" dev = ["cogapp", "pre-commit", "pytest", "wheel"] tests = ["pytest"] +[[package]] +name = "asttokens" +version = "2.4.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, +] + +[package.dependencies] +six = ">=1.12.0" + +[package.extras] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] + +[[package]] +name = "attrs" +version = "24.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + +[[package]] +name = "babel" +version = "2.16.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "bleach" +version = "6.1.0" +description = "An easy safelist-based HTML-sanitizing tool." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, + {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, +] + +[package.dependencies] +six = ">=1.9.0" +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0,<1.3)"] + +[[package]] +name = "bracex" +version = "2.5.post1" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, +] + [[package]] name = "certifi" version = "2024.8.30" @@ -257,6 +369,20 @@ files = [ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -268,6 +394,23 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "comm" +version = "0.2.2" +description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +optional = false +python-versions = ">=3.8" +files = [ + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, +] + +[package.dependencies] +traitlets = ">=4" + +[package.extras] +test = ["pytest"] + [[package]] name = "contourpy" version = "1.3.0" @@ -367,6 +510,59 @@ files = [ docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] tests = ["pytest", "pytest-cov", "pytest-xdist"] +[[package]] +name = "debugpy" +version = "1.8.6" +description = "An implementation of the Debug Adapter Protocol for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "debugpy-1.8.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:30f467c5345d9dfdcc0afdb10e018e47f092e383447500f125b4e013236bf14b"}, + {file = "debugpy-1.8.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d73d8c52614432f4215d0fe79a7e595d0dd162b5c15233762565be2f014803b"}, + {file = "debugpy-1.8.6-cp310-cp310-win32.whl", hash = "sha256:e3e182cd98eac20ee23a00653503315085b29ab44ed66269482349d307b08df9"}, + {file = "debugpy-1.8.6-cp310-cp310-win_amd64.whl", hash = "sha256:e3a82da039cfe717b6fb1886cbbe5c4a3f15d7df4765af857f4307585121c2dd"}, + {file = "debugpy-1.8.6-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:67479a94cf5fd2c2d88f9615e087fcb4fec169ec780464a3f2ba4a9a2bb79955"}, + {file = "debugpy-1.8.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fb8653f6cbf1dd0a305ac1aa66ec246002145074ea57933978346ea5afdf70b"}, + {file = "debugpy-1.8.6-cp311-cp311-win32.whl", hash = "sha256:cdaf0b9691879da2d13fa39b61c01887c34558d1ff6e5c30e2eb698f5384cd43"}, + {file = "debugpy-1.8.6-cp311-cp311-win_amd64.whl", hash = "sha256:43996632bee7435583952155c06881074b9a742a86cee74e701d87ca532fe833"}, + {file = "debugpy-1.8.6-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:db891b141fc6ee4b5fc6d1cc8035ec329cabc64bdd2ae672b4550c87d4ecb128"}, + {file = "debugpy-1.8.6-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:567419081ff67da766c898ccf21e79f1adad0e321381b0dfc7a9c8f7a9347972"}, + {file = "debugpy-1.8.6-cp312-cp312-win32.whl", hash = "sha256:c9834dfd701a1f6bf0f7f0b8b1573970ae99ebbeee68314116e0ccc5c78eea3c"}, + {file = "debugpy-1.8.6-cp312-cp312-win_amd64.whl", hash = "sha256:e4ce0570aa4aca87137890d23b86faeadf184924ad892d20c54237bcaab75d8f"}, + {file = "debugpy-1.8.6-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:df5dc9eb4ca050273b8e374a4cd967c43be1327eeb42bfe2f58b3cdfe7c68dcb"}, + {file = "debugpy-1.8.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a85707c6a84b0c5b3db92a2df685b5230dd8fb8c108298ba4f11dba157a615a"}, + {file = "debugpy-1.8.6-cp38-cp38-win32.whl", hash = "sha256:538c6cdcdcdad310bbefd96d7850be1cd46e703079cc9e67d42a9ca776cdc8a8"}, + {file = "debugpy-1.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:22140bc02c66cda6053b6eb56dfe01bbe22a4447846581ba1dd6df2c9f97982d"}, + {file = "debugpy-1.8.6-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:c1cef65cffbc96e7b392d9178dbfd524ab0750da6c0023c027ddcac968fd1caa"}, + {file = "debugpy-1.8.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1e60bd06bb3cc5c0e957df748d1fab501e01416c43a7bdc756d2a992ea1b881"}, + {file = "debugpy-1.8.6-cp39-cp39-win32.whl", hash = "sha256:f7158252803d0752ed5398d291dee4c553bb12d14547c0e1843ab74ee9c31123"}, + {file = "debugpy-1.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:3358aa619a073b620cd0d51d8a6176590af24abcc3fe2e479929a154bf591b51"}, + {file = "debugpy-1.8.6-py2.py3-none-any.whl", hash = "sha256:b48892df4d810eff21d3ef37274f4c60d32cdcafc462ad5647239036b0f0649f"}, + {file = "debugpy-1.8.6.zip", hash = "sha256:c931a9371a86784cee25dec8d65bc2dc7a21f3f1552e3833d9ef8f919d22280a"}, +] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + [[package]] name = "einops" version = "0.8.0" @@ -378,6 +574,48 @@ files = [ {file = "einops-0.8.0.tar.gz", hash = "sha256:63486517fed345712a8385c100cb279108d9d47e6ae59099b07657e983deae85"}, ] +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "executing" +version = "2.1.0" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.8" +files = [ + {file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"}, + {file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + +[[package]] +name = "fastjsonschema" +version = "2.20.0" +description = "Fastest Python implementation of JSON schema" +optional = false +python-versions = "*" +files = [ + {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, + {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, +] + +[package.extras] +devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] + [[package]] name = "filelock" version = "3.15.4" @@ -498,6 +736,69 @@ test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe, test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] tqdm = ["tqdm"] +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + +[[package]] +name = "gitdb" +version = "4.0.11" +description = "Git Object Database" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, + {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, +] + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.43" +description = "GitPython is a Python library used to interact with Git repositories" +optional = false +python-versions = ">=3.7" +files = [ + {file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"}, + {file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"}, +] + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[package.extras] +doc = ["sphinx (==4.3.2)", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "sphinxcontrib-applehelp (>=1.0.2,<=1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (>=2.0.0,<=2.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)"] +test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions"] + +[[package]] +name = "griffe" +version = "1.3.1" +description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +optional = false +python-versions = ">=3.8" +files = [ + {file = "griffe-1.3.1-py3-none-any.whl", hash = "sha256:940aeb630bc3054b4369567f150b6365be6f11eef46b0ed8623aea96e6d17b19"}, + {file = "griffe-1.3.1.tar.gz", hash = "sha256:3f86a716b631a4c0f96a43cb75d05d3c85975003c20540426c0eba3b0581c56a"}, +] + +[package.dependencies] +colorama = ">=0.4" + [[package]] name = "grpcio" version = "1.66.1" @@ -601,6 +902,96 @@ files = [ {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] +[[package]] +name = "ipykernel" +version = "6.29.5" +description = "IPython Kernel for Jupyter" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "platform_system == \"Darwin\""} +comm = ">=0.1.1" +debugpy = ">=1.6.5" +ipython = ">=7.23.1" +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +matplotlib-inline = ">=0.1" +nest-asyncio = "*" +packaging = "*" +psutil = "*" +pyzmq = ">=24" +tornado = ">=6.1" +traitlets = ">=5.4.0" + +[package.extras] +cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] +pyqt5 = ["pyqt5"] +pyside6 = ["pyside6"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "ipython" +version = "8.27.0" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.10" +files = [ + {file = "ipython-8.27.0-py3-none-any.whl", hash = "sha256:f68b3cb8bde357a5d7adc9598d57e22a45dfbea19eb6b98286fa3b288c9cd55c"}, + {file = "ipython-8.27.0.tar.gz", hash = "sha256:0b99a2dc9f15fd68692e898e5568725c6d49c527d36a9fb5960ffbdeaa82ff7e"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} +prompt-toolkit = ">=3.0.41,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5.13.0" +typing-extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} + +[package.extras] +all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] +black = ["black"] +doc = ["docrepr", "exceptiongroup", "intersphinx-registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli", "typing-extensions"] +kernel = ["ipykernel"] +matplotlib = ["matplotlib"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["packaging", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "ipython[test]", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"] + +[[package]] +name = "jedi" +version = "0.19.1" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + [[package]] name = "jinja2" version = "3.1.4" @@ -629,6 +1020,123 @@ files = [ {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, ] +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "jupyter-client" +version = "8.6.3" +description = "Jupyter protocol implementation and client libraries" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f"}, + {file = "jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419"}, +] + +[package.dependencies] +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +python-dateutil = ">=2.8.2" +pyzmq = ">=23.0" +tornado = ">=6.2" +traitlets = ">=5.3" + +[package.extras] +docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +description = "Jupyter core package. A base package on which Jupyter projects rely." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, +] + +[package.dependencies] +platformdirs = ">=2.5" +pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +traitlets = ">=5.3" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +description = "Pygments theme using JupyterLab CSS variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, + {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, +] + +[[package]] +name = "jupytext" +version = "1.16.4" +description = "Jupyter notebooks as Markdown documents, Julia, Python or R scripts" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupytext-1.16.4-py3-none-any.whl", hash = "sha256:76989d2690e65667ea6fb411d8056abe7cd0437c07bd774660b83d62acf9490a"}, + {file = "jupytext-1.16.4.tar.gz", hash = "sha256:28e33f46f2ce7a41fb9d677a4a2c95327285579b64ca104437c4b9eb1e4174e9"}, +] + +[package.dependencies] +markdown-it-py = ">=1.0" +mdit-py-plugins = "*" +nbformat = "*" +packaging = "*" +pyyaml = "*" +tomli = {version = "*", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["autopep8", "black", "flake8", "gitpython", "ipykernel", "isort", "jupyter-fs (>=1.0)", "jupyter-server (!=2.11)", "nbconvert", "pre-commit", "pytest", "pytest-cov (>=2.6.1)", "pytest-randomly", "pytest-xdist", "sphinx-gallery (<0.8)"] +docs = ["myst-parser", "sphinx", "sphinx-copybutton", "sphinx-rtd-theme"] +test = ["pytest", "pytest-randomly", "pytest-xdist"] +test-cov = ["ipykernel", "jupyter-server (!=2.11)", "nbconvert", "pytest", "pytest-cov (>=2.6.1)", "pytest-randomly", "pytest-xdist"] +test-external = ["autopep8", "black", "flake8", "gitpython", "ipykernel", "isort", "jupyter-fs (>=1.0)", "jupyter-server (!=2.11)", "nbconvert", "pre-commit", "pytest", "pytest-randomly", "pytest-xdist", "sphinx-gallery (<0.8)"] +test-functional = ["pytest", "pytest-randomly", "pytest-xdist"] +test-integration = ["ipykernel", "jupyter-server (!=2.11)", "nbconvert", "pytest", "pytest-randomly", "pytest-xdist"] +test-ui = ["calysto-bash"] + [[package]] name = "kiwisolver" version = "1.4.7" @@ -777,6 +1285,30 @@ files = [ docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" version = "2.1.5" @@ -896,53 +1428,440 @@ files = [ ] [package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -kiwisolver = ">=1.3.1" -numpy = ">=1.23" -packaging = ">=20.0" -pillow = ">=8" -pyparsing = ">=2.3.1" -python-dateutil = ">=2.7" +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] + +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.8" +files = [ + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, +] + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +description = "Collection of plugins for markdown-it-py" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636"}, + {file = "mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5"}, +] + +[package.dependencies] +markdown-it-py = ">=1.0.0,<4.0.0" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["myst-parser", "sphinx-book-theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "minio" +version = "7.2.8" +description = "MinIO Python SDK for Amazon S3 Compatible Cloud Storage" +optional = false +python-versions = ">3.8" +files = [ + {file = "minio-7.2.8-py3-none-any.whl", hash = "sha256:aa3b485788b63b12406a5798465d12a57e4be2ac2a58a8380959b6b748e64ddd"}, + {file = "minio-7.2.8.tar.gz", hash = "sha256:f8af2dafc22ebe1aef3ac181b8e217037011c430aa6da276ed627e55aaf7c815"}, +] + +[package.dependencies] +argon2-cffi = "*" +certifi = "*" +pycryptodome = "*" +typing-extensions = "*" +urllib3 = "*" + +[[package]] +name = "mistune" +version = "3.0.2" +description = "A sane and fast Markdown parser with useful plugins and renderers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, + {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"}, + {file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +jinja2 = ">=2.11.1" +markdown = ">=3.3.6" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +mkdocs-get-deps = ">=0.2.0" +packaging = ">=20.5" +pathspec = ">=0.11.1" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-autorefs" +version = "1.2.0" +description = "Automatically link across pages in MkDocs." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_autorefs-1.2.0-py3-none-any.whl", hash = "sha256:d588754ae89bd0ced0c70c06f58566a4ee43471eeeee5202427da7de9ef85a2f"}, + {file = "mkdocs_autorefs-1.2.0.tar.gz", hash = "sha256:a86b93abff653521bda71cf3fc5596342b7a23982093915cb74273f67522190f"}, +] + +[package.dependencies] +Markdown = ">=3.3" +markupsafe = ">=2.0.1" +mkdocs = ">=1.1" + +[[package]] +name = "mkdocs-awesome-pages-plugin" +version = "2.9.3" +description = "An MkDocs plugin that simplifies configuring page titles and their order" +optional = false +python-versions = ">=3.8.1" +files = [ + {file = "mkdocs_awesome_pages_plugin-2.9.3-py3-none-any.whl", hash = "sha256:1ba433d4e7edaf8661b15b93267f78f78e2e06ca590fc0e651ea36b191d64ae4"}, + {file = "mkdocs_awesome_pages_plugin-2.9.3.tar.gz", hash = "sha256:bdf6369871f41bb17f09c3cfb573367732dfcceb5673d7a2c5c76ac2567b242f"}, +] + +[package.dependencies] +mkdocs = ">=1" +natsort = ">=8.1.0" +wcmatch = ">=7" + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, + {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, +] + +[package.dependencies] +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" + +[[package]] +name = "mkdocs-jupyter" +version = "0.25.0" +description = "Use Jupyter in mkdocs websites" +optional = false +python-versions = ">=3.9" +files = [ + {file = "mkdocs_jupyter-0.25.0-py3-none-any.whl", hash = "sha256:d83d71deef19f0401505945bf92ec3bd5b40615af89308e72d5112929f8ee00b"}, + {file = "mkdocs_jupyter-0.25.0.tar.gz", hash = "sha256:e26c1d341916bc57f96ea3f93d8d0a88fc77c87d4cee222f66d2007798d924f5"}, +] + +[package.dependencies] +ipykernel = ">6.0.0,<7.0.0" +jupytext = ">1.13.8,<2" +mkdocs = ">=1.4.0,<2" +mkdocs-material = ">9.0.0" +nbconvert = ">=7.2.9,<8" +pygments = ">2.12.0" + +[[package]] +name = "mkdocs-material" +version = "9.5.39" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material-9.5.39-py3-none-any.whl", hash = "sha256:0f2f68c8db89523cb4a59705cd01b4acd62b2f71218ccb67e1e004e560410d2b"}, + {file = "mkdocs_material-9.5.39.tar.gz", hash = "sha256:25faa06142afa38549d2b781d475a86fb61de93189f532b88e69bf11e5e5c3be"}, +] + +[package.dependencies] +babel = ">=2.10,<3.0" +colorama = ">=0.4,<1.0" +jinja2 = ">=3.0,<4.0" +markdown = ">=3.2,<4.0" +mkdocs = ">=1.6,<2.0" +mkdocs-material-extensions = ">=1.3,<2.0" +paginate = ">=0.5,<1.0" +pygments = ">=2.16,<3.0" +pymdown-extensions = ">=10.2,<11.0" +regex = ">=2022.4" +requests = ">=2.26,<3.0" + +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] +recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, +] + +[[package]] +name = "mkdocs-redirects" +version = "1.2.1" +description = "A MkDocs plugin for dynamic page redirects to prevent broken links." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mkdocs-redirects-1.2.1.tar.gz", hash = "sha256:9420066d70e2a6bb357adf86e67023dcdca1857f97f07c7fe450f8f1fb42f861"}, + {file = "mkdocs_redirects-1.2.1-py3-none-any.whl", hash = "sha256:497089f9e0219e7389304cffefccdfa1cac5ff9509f2cb706f4c9b221726dffb"}, +] + +[package.dependencies] +mkdocs = ">=1.1.1" + +[package.extras] +dev = ["autoflake", "black", "isort", "pytest", "twine (>=1.13.0)"] +release = ["twine (>=1.13.0)"] +test = ["autoflake", "black", "isort", "pytest"] + +[[package]] +name = "mkdocstrings" +version = "0.26.1" +description = "Automatic documentation from sources, for MkDocs." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocstrings-0.26.1-py3-none-any.whl", hash = "sha256:29738bfb72b4608e8e55cc50fb8a54f325dc7ebd2014e4e3881a49892d5983cf"}, + {file = "mkdocstrings-0.26.1.tar.gz", hash = "sha256:bb8b8854d6713d5348ad05b069a09f3b79edbc6a0f33a34c6821141adb03fe33"}, +] + +[package.dependencies] +click = ">=7.0" +Jinja2 = ">=2.11.1" +Markdown = ">=3.6" +MarkupSafe = ">=1.1" +mkdocs = ">=1.4" +mkdocs-autorefs = ">=1.2" +platformdirs = ">=2.2" +pymdown-extensions = ">=6.3" + +[package.extras] +crystal = ["mkdocstrings-crystal (>=0.3.4)"] +python = ["mkdocstrings-python (>=0.5.2)"] +python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] + +[[package]] +name = "mkdocstrings-python" +version = "1.11.1" +description = "A Python handler for mkdocstrings." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocstrings_python-1.11.1-py3-none-any.whl", hash = "sha256:a21a1c05acef129a618517bb5aae3e33114f569b11588b1e7af3e9d4061a71af"}, + {file = "mkdocstrings_python-1.11.1.tar.gz", hash = "sha256:8824b115c5359304ab0b5378a91f6202324a849e1da907a3485b59208b797322"}, +] + +[package.dependencies] +griffe = ">=0.49" +mkdocs-autorefs = ">=1.2" +mkdocstrings = ">=0.26" + +[[package]] +name = "mknotebooks" +version = "0.8.0" +description = "Plugin for mkdocs to generate markdown documents from jupyter notebooks." +optional = false +python-versions = "*" +files = [ + {file = "mknotebooks-0.8.0-py3-none-any.whl", hash = "sha256:4a9b998260c09bcc311455a19a44cc395a30ee82dc1e86e3316dd09f2445ebd3"}, +] + +[package.dependencies] +gitpython = "*" +jupyter-client = "*" +markdown = ">=3.3.3" +mkdocs = ">=1.5.0" +nbconvert = ">=6.0.0" + +[[package]] +name = "mpmath" +version = "1.3.0" +description = "Python library for arbitrary-precision floating-point arithmetic" +optional = false +python-versions = "*" +files = [ + {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, + {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, +] + +[package.extras] +develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] +docs = ["sphinx"] +gmpy = ["gmpy2 (>=2.1.0a4)"] +tests = ["pytest (>=4.6)"] + +[[package]] +name = "natsort" +version = "8.4.0" +description = "Simple yet flexible natural sorting in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c"}, + {file = "natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581"}, +] + +[package.extras] +fast = ["fastnumbers (>=2.0.0)"] +icu = ["PyICU (>=1.0.0)"] + +[[package]] +name = "nbclient" +version = "0.10.0" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "nbclient-0.10.0-py3-none-any.whl", hash = "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f"}, + {file = "nbclient-0.10.0.tar.gz", hash = "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09"}, +] + +[package.dependencies] +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +nbformat = ">=5.1" +traitlets = ">=5.4" [package.extras] -dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] +dev = ["pre-commit"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] -name = "minio" -version = "7.2.8" -description = "MinIO Python SDK for Amazon S3 Compatible Cloud Storage" +name = "nbconvert" +version = "7.16.4" +description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." optional = false -python-versions = ">3.8" +python-versions = ">=3.8" files = [ - {file = "minio-7.2.8-py3-none-any.whl", hash = "sha256:aa3b485788b63b12406a5798465d12a57e4be2ac2a58a8380959b6b748e64ddd"}, - {file = "minio-7.2.8.tar.gz", hash = "sha256:f8af2dafc22ebe1aef3ac181b8e217037011c430aa6da276ed627e55aaf7c815"}, + {file = "nbconvert-7.16.4-py3-none-any.whl", hash = "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3"}, + {file = "nbconvert-7.16.4.tar.gz", hash = "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4"}, ] [package.dependencies] -argon2-cffi = "*" -certifi = "*" -pycryptodome = "*" -typing-extensions = "*" -urllib3 = "*" +beautifulsoup4 = "*" +bleach = "!=5.0.0" +defusedxml = "*" +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<4" +nbclient = ">=0.5.0" +nbformat = ">=5.7" +packaging = "*" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +tinycss2 = "*" +traitlets = ">=5.1" + +[package.extras] +all = ["flaky", "ipykernel", "ipython", "ipywidgets (>=7.5)", "myst-parser", "nbsphinx (>=0.2.12)", "playwright", "pydata-sphinx-theme", "pyqtwebengine (>=5.15)", "pytest (>=7)", "sphinx (==5.0.2)", "sphinxcontrib-spelling", "tornado (>=6.1)"] +docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] +qtpdf = ["pyqtwebengine (>=5.15)"] +qtpng = ["pyqtwebengine (>=5.15)"] +serve = ["tornado (>=6.1)"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] +webpdf = ["playwright"] [[package]] -name = "mpmath" -version = "1.3.0" -description = "Python library for arbitrary-precision floating-point arithmetic" +name = "nbformat" +version = "5.10.4" +description = "The Jupyter Notebook format" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, - {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, + {file = "nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"}, + {file = "nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"}, ] +[package.dependencies] +fastjsonschema = ">=2.15" +jsonschema = ">=2.6" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +traitlets = ">=5.1" + [package.extras] -develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] -docs = ["sphinx"] -gmpy = ["gmpy2 (>=2.1.0a4)"] -tests = ["pytest (>=4.6)"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["pep440", "pre-commit", "pytest", "testpath"] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] [[package]] name = "networkx" @@ -1232,6 +2151,21 @@ files = [ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] +[[package]] +name = "paginate" +version = "0.5.7" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"}, + {file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"}, +] + +[package.extras] +dev = ["pytest", "tox"] +lint = ["black"] + [[package]] name = "pandas" version = "2.2.2" @@ -1305,6 +2239,57 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] +[[package]] +name = "pandocfilters" +version = "1.5.1" +description = "Utilities for writing pandoc filters in python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, + {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, +] + +[[package]] +name = "parso" +version = "0.8.4" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, + {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, +] + +[package.extras] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["docopt", "pytest"] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + [[package]] name = "pillow" version = "10.4.0" @@ -1402,6 +2387,36 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa typing = ["typing-extensions"] xmp = ["defusedxml"] +[[package]] +name = "platformdirs" +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.48" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, + {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, +] + +[package.dependencies] +wcwidth = "*" + [[package]] name = "protobuf" version = "5.28.0" @@ -1422,6 +2437,60 @@ files = [ {file = "protobuf-5.28.0.tar.gz", hash = "sha256:dde74af0fa774fa98892209992295adbfb91da3fa98c8f67a88afe8f5a349add"}, ] +[[package]] +name = "psutil" +version = "6.0.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, + {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, +] + +[package.extras] +tests = ["pytest"] + [[package]] name = "pyarrow" version = "17.0.0" @@ -1525,6 +2594,38 @@ files = [ {file = "pycryptodome-3.20.0.tar.gz", hash = "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7"}, ] +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pymdown-extensions" +version = "10.11.1" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pymdown_extensions-10.11.1-py3-none-any.whl", hash = "sha256:a2b28f5786e041f19cb5bb30a1c2c853668a7099da8e3dd822a5ad05f2e855e3"}, + {file = "pymdown_extensions-10.11.1.tar.gz", hash = "sha256:a8836e955851542fa2625d04d59fdf97125ca001377478ed5618e04f9183a59a"}, +] + +[package.dependencies] +markdown = ">=3.6" +pyyaml = "*" + +[package.extras] +extra = ["pygments (>=2.12)"] + [[package]] name = "pyparsing" version = "3.1.4" @@ -1564,6 +2665,29 @@ files = [ {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + [[package]] name = "pyyaml" version = "6.0.2" @@ -1626,6 +2750,156 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "pyzmq" +version = "26.2.0" +description = "Python bindings for 0MQ" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyzmq-26.2.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ddf33d97d2f52d89f6e6e7ae66ee35a4d9ca6f36eda89c24591b0c40205a3629"}, + {file = "pyzmq-26.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dacd995031a01d16eec825bf30802fceb2c3791ef24bcce48fa98ce40918c27b"}, + {file = "pyzmq-26.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89289a5ee32ef6c439086184529ae060c741334b8970a6855ec0b6ad3ff28764"}, + {file = "pyzmq-26.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5506f06d7dc6ecf1efacb4a013b1f05071bb24b76350832c96449f4a2d95091c"}, + {file = "pyzmq-26.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ea039387c10202ce304af74def5021e9adc6297067f3441d348d2b633e8166a"}, + {file = "pyzmq-26.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a2224fa4a4c2ee872886ed00a571f5e967c85e078e8e8c2530a2fb01b3309b88"}, + {file = "pyzmq-26.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:28ad5233e9c3b52d76196c696e362508959741e1a005fb8fa03b51aea156088f"}, + {file = "pyzmq-26.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1c17211bc037c7d88e85ed8b7d8f7e52db6dc8eca5590d162717c654550f7282"}, + {file = "pyzmq-26.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b8f86dd868d41bea9a5f873ee13bf5551c94cf6bc51baebc6f85075971fe6eea"}, + {file = "pyzmq-26.2.0-cp310-cp310-win32.whl", hash = "sha256:46a446c212e58456b23af260f3d9fb785054f3e3653dbf7279d8f2b5546b21c2"}, + {file = "pyzmq-26.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:49d34ab71db5a9c292a7644ce74190b1dd5a3475612eefb1f8be1d6961441971"}, + {file = "pyzmq-26.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:bfa832bfa540e5b5c27dcf5de5d82ebc431b82c453a43d141afb1e5d2de025fa"}, + {file = "pyzmq-26.2.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:8f7e66c7113c684c2b3f1c83cdd3376103ee0ce4c49ff80a648643e57fb22218"}, + {file = "pyzmq-26.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3a495b30fc91db2db25120df5847d9833af237546fd59170701acd816ccc01c4"}, + {file = "pyzmq-26.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77eb0968da535cba0470a5165468b2cac7772cfb569977cff92e240f57e31bef"}, + {file = "pyzmq-26.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ace4f71f1900a548f48407fc9be59c6ba9d9aaf658c2eea6cf2779e72f9f317"}, + {file = "pyzmq-26.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92a78853d7280bffb93df0a4a6a2498cba10ee793cc8076ef797ef2f74d107cf"}, + {file = "pyzmq-26.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:689c5d781014956a4a6de61d74ba97b23547e431e9e7d64f27d4922ba96e9d6e"}, + {file = "pyzmq-26.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0aca98bc423eb7d153214b2df397c6421ba6373d3397b26c057af3c904452e37"}, + {file = "pyzmq-26.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f3496d76b89d9429a656293744ceca4d2ac2a10ae59b84c1da9b5165f429ad3"}, + {file = "pyzmq-26.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5c2b3bfd4b9689919db068ac6c9911f3fcb231c39f7dd30e3138be94896d18e6"}, + {file = "pyzmq-26.2.0-cp311-cp311-win32.whl", hash = "sha256:eac5174677da084abf378739dbf4ad245661635f1600edd1221f150b165343f4"}, + {file = "pyzmq-26.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:5a509df7d0a83a4b178d0f937ef14286659225ef4e8812e05580776c70e155d5"}, + {file = "pyzmq-26.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:c0e6091b157d48cbe37bd67233318dbb53e1e6327d6fc3bb284afd585d141003"}, + {file = "pyzmq-26.2.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:ded0fc7d90fe93ae0b18059930086c51e640cdd3baebdc783a695c77f123dcd9"}, + {file = "pyzmq-26.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17bf5a931c7f6618023cdacc7081f3f266aecb68ca692adac015c383a134ca52"}, + {file = "pyzmq-26.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55cf66647e49d4621a7e20c8d13511ef1fe1efbbccf670811864452487007e08"}, + {file = "pyzmq-26.2.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4661c88db4a9e0f958c8abc2b97472e23061f0bc737f6f6179d7a27024e1faa5"}, + {file = "pyzmq-26.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea7f69de383cb47522c9c208aec6dd17697db7875a4674c4af3f8cfdac0bdeae"}, + {file = "pyzmq-26.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:7f98f6dfa8b8ccaf39163ce872bddacca38f6a67289116c8937a02e30bbe9711"}, + {file = "pyzmq-26.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e3e0210287329272539eea617830a6a28161fbbd8a3271bf4150ae3e58c5d0e6"}, + {file = "pyzmq-26.2.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6b274e0762c33c7471f1a7471d1a2085b1a35eba5cdc48d2ae319f28b6fc4de3"}, + {file = "pyzmq-26.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:29c6a4635eef69d68a00321e12a7d2559fe2dfccfa8efae3ffb8e91cd0b36a8b"}, + {file = "pyzmq-26.2.0-cp312-cp312-win32.whl", hash = "sha256:989d842dc06dc59feea09e58c74ca3e1678c812a4a8a2a419046d711031f69c7"}, + {file = "pyzmq-26.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:2a50625acdc7801bc6f74698c5c583a491c61d73c6b7ea4dee3901bb99adb27a"}, + {file = "pyzmq-26.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:4d29ab8592b6ad12ebbf92ac2ed2bedcfd1cec192d8e559e2e099f648570e19b"}, + {file = "pyzmq-26.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9dd8cd1aeb00775f527ec60022004d030ddc51d783d056e3e23e74e623e33726"}, + {file = "pyzmq-26.2.0-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:28c812d9757fe8acecc910c9ac9dafd2ce968c00f9e619db09e9f8f54c3a68a3"}, + {file = "pyzmq-26.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d80b1dd99c1942f74ed608ddb38b181b87476c6a966a88a950c7dee118fdf50"}, + {file = "pyzmq-26.2.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c997098cc65e3208eca09303630e84d42718620e83b733d0fd69543a9cab9cb"}, + {file = "pyzmq-26.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ad1bc8d1b7a18497dda9600b12dc193c577beb391beae5cd2349184db40f187"}, + {file = "pyzmq-26.2.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:bea2acdd8ea4275e1278350ced63da0b166421928276c7c8e3f9729d7402a57b"}, + {file = "pyzmq-26.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:23f4aad749d13698f3f7b64aad34f5fc02d6f20f05999eebc96b89b01262fb18"}, + {file = "pyzmq-26.2.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:a4f96f0d88accc3dbe4a9025f785ba830f968e21e3e2c6321ccdfc9aef755115"}, + {file = "pyzmq-26.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ced65e5a985398827cc9276b93ef6dfabe0273c23de8c7931339d7e141c2818e"}, + {file = "pyzmq-26.2.0-cp313-cp313-win32.whl", hash = "sha256:31507f7b47cc1ead1f6e86927f8ebb196a0bab043f6345ce070f412a59bf87b5"}, + {file = "pyzmq-26.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:70fc7fcf0410d16ebdda9b26cbd8bf8d803d220a7f3522e060a69a9c87bf7bad"}, + {file = "pyzmq-26.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:c3789bd5768ab5618ebf09cef6ec2b35fed88709b104351748a63045f0ff9797"}, + {file = "pyzmq-26.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:034da5fc55d9f8da09015d368f519478a52675e558c989bfcb5cf6d4e16a7d2a"}, + {file = "pyzmq-26.2.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:c92d73464b886931308ccc45b2744e5968cbaade0b1d6aeb40d8ab537765f5bc"}, + {file = "pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:794a4562dcb374f7dbbfb3f51d28fb40123b5a2abadee7b4091f93054909add5"}, + {file = "pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aee22939bb6075e7afededabad1a56a905da0b3c4e3e0c45e75810ebe3a52672"}, + {file = "pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ae90ff9dad33a1cfe947d2c40cb9cb5e600d759ac4f0fd22616ce6540f72797"}, + {file = "pyzmq-26.2.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:43a47408ac52647dfabbc66a25b05b6a61700b5165807e3fbd40063fcaf46386"}, + {file = "pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:25bf2374a2a8433633c65ccb9553350d5e17e60c8eb4de4d92cc6bd60f01d306"}, + {file = "pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:007137c9ac9ad5ea21e6ad97d3489af654381324d5d3ba614c323f60dab8fae6"}, + {file = "pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:470d4a4f6d48fb34e92d768b4e8a5cc3780db0d69107abf1cd7ff734b9766eb0"}, + {file = "pyzmq-26.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b55a4229ce5da9497dd0452b914556ae58e96a4381bb6f59f1305dfd7e53fc8"}, + {file = "pyzmq-26.2.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9cb3a6460cdea8fe8194a76de8895707e61ded10ad0be97188cc8463ffa7e3a8"}, + {file = "pyzmq-26.2.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8ab5cad923cc95c87bffee098a27856c859bd5d0af31bd346035aa816b081fe1"}, + {file = "pyzmq-26.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ed69074a610fad1c2fda66180e7b2edd4d31c53f2d1872bc2d1211563904cd9"}, + {file = "pyzmq-26.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cccba051221b916a4f5e538997c45d7d136a5646442b1231b916d0164067ea27"}, + {file = "pyzmq-26.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:0eaa83fc4c1e271c24eaf8fb083cbccef8fde77ec8cd45f3c35a9a123e6da097"}, + {file = "pyzmq-26.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9edda2df81daa129b25a39b86cb57dfdfe16f7ec15b42b19bfac503360d27a93"}, + {file = "pyzmq-26.2.0-cp37-cp37m-win32.whl", hash = "sha256:ea0eb6af8a17fa272f7b98d7bebfab7836a0d62738e16ba380f440fceca2d951"}, + {file = "pyzmq-26.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4ff9dc6bc1664bb9eec25cd17506ef6672d506115095411e237d571e92a58231"}, + {file = "pyzmq-26.2.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:2eb7735ee73ca1b0d71e0e67c3739c689067f055c764f73aac4cc8ecf958ee3f"}, + {file = "pyzmq-26.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a534f43bc738181aa7cbbaf48e3eca62c76453a40a746ab95d4b27b1111a7d2"}, + {file = "pyzmq-26.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:aedd5dd8692635813368e558a05266b995d3d020b23e49581ddd5bbe197a8ab6"}, + {file = "pyzmq-26.2.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8be4700cd8bb02cc454f630dcdf7cfa99de96788b80c51b60fe2fe1dac480289"}, + {file = "pyzmq-26.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fcc03fa4997c447dce58264e93b5aa2d57714fbe0f06c07b7785ae131512732"}, + {file = "pyzmq-26.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:402b190912935d3db15b03e8f7485812db350d271b284ded2b80d2e5704be780"}, + {file = "pyzmq-26.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8685fa9c25ff00f550c1fec650430c4b71e4e48e8d852f7ddcf2e48308038640"}, + {file = "pyzmq-26.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:76589c020680778f06b7e0b193f4b6dd66d470234a16e1df90329f5e14a171cd"}, + {file = "pyzmq-26.2.0-cp38-cp38-win32.whl", hash = "sha256:8423c1877d72c041f2c263b1ec6e34360448decfb323fa8b94e85883043ef988"}, + {file = "pyzmq-26.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:76589f2cd6b77b5bdea4fca5992dc1c23389d68b18ccc26a53680ba2dc80ff2f"}, + {file = "pyzmq-26.2.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:b1d464cb8d72bfc1a3adc53305a63a8e0cac6bc8c5a07e8ca190ab8d3faa43c2"}, + {file = "pyzmq-26.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4da04c48873a6abdd71811c5e163bd656ee1b957971db7f35140a2d573f6949c"}, + {file = "pyzmq-26.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d049df610ac811dcffdc147153b414147428567fbbc8be43bb8885f04db39d98"}, + {file = "pyzmq-26.2.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05590cdbc6b902101d0e65d6a4780af14dc22914cc6ab995d99b85af45362cc9"}, + {file = "pyzmq-26.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c811cfcd6a9bf680236c40c6f617187515269ab2912f3d7e8c0174898e2519db"}, + {file = "pyzmq-26.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6835dd60355593de10350394242b5757fbbd88b25287314316f266e24c61d073"}, + {file = "pyzmq-26.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc6bee759a6bddea5db78d7dcd609397449cb2d2d6587f48f3ca613b19410cfc"}, + {file = "pyzmq-26.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c530e1eecd036ecc83c3407f77bb86feb79916d4a33d11394b8234f3bd35b940"}, + {file = "pyzmq-26.2.0-cp39-cp39-win32.whl", hash = "sha256:367b4f689786fca726ef7a6c5ba606958b145b9340a5e4808132cc65759abd44"}, + {file = "pyzmq-26.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:e6fa2e3e683f34aea77de8112f6483803c96a44fd726d7358b9888ae5bb394ec"}, + {file = "pyzmq-26.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:7445be39143a8aa4faec43b076e06944b8f9d0701b669df4af200531b21e40bb"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:706e794564bec25819d21a41c31d4df2d48e1cc4b061e8d345d7fb4dd3e94072"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b435f2753621cd36e7c1762156815e21c985c72b19135dac43a7f4f31d28dd1"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:160c7e0a5eb178011e72892f99f918c04a131f36056d10d9c1afb223fc952c2d"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4a71d5d6e7b28a47a394c0471b7e77a0661e2d651e7ae91e0cab0a587859ca"}, + {file = "pyzmq-26.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:90412f2db8c02a3864cbfc67db0e3dcdbda336acf1c469526d3e869394fe001c"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2ea4ad4e6a12e454de05f2949d4beddb52460f3de7c8b9d5c46fbb7d7222e02c"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fc4f7a173a5609631bb0c42c23d12c49df3966f89f496a51d3eb0ec81f4519d6"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:878206a45202247781472a2d99df12a176fef806ca175799e1c6ad263510d57c"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17c412bad2eb9468e876f556eb4ee910e62d721d2c7a53c7fa31e643d35352e6"}, + {file = "pyzmq-26.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:0d987a3ae5a71c6226b203cfd298720e0086c7fe7c74f35fa8edddfbd6597eed"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:39887ac397ff35b7b775db7201095fc6310a35fdbae85bac4523f7eb3b840e20"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fdb5b3e311d4d4b0eb8b3e8b4d1b0a512713ad7e6a68791d0923d1aec433d919"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:226af7dcb51fdb0109f0016449b357e182ea0ceb6b47dfb5999d569e5db161d5"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bed0e799e6120b9c32756203fb9dfe8ca2fb8467fed830c34c877e25638c3fc"}, + {file = "pyzmq-26.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:29c7947c594e105cb9e6c466bace8532dc1ca02d498684128b339799f5248277"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cdeabcff45d1c219636ee2e54d852262e5c2e085d6cb476d938aee8d921356b3"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35cffef589bcdc587d06f9149f8d5e9e8859920a071df5a2671de2213bef592a"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18c8dc3b7468d8b4bdf60ce9d7141897da103c7a4690157b32b60acb45e333e6"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7133d0a1677aec369d67dd78520d3fa96dd7f3dcec99d66c1762870e5ea1a50a"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6a96179a24b14fa6428cbfc08641c779a53f8fcec43644030328f44034c7f1f4"}, + {file = "pyzmq-26.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4f78c88905461a9203eac9faac157a2a0dbba84a0fd09fd29315db27be40af9f"}, + {file = "pyzmq-26.2.0.tar.gz", hash = "sha256:070672c258581c8e4f640b5159297580a9974b026043bd4ab0470be9ed324f1f"}, +] + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} + +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "regex" version = "2024.9.11" @@ -1750,6 +3024,118 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "rpds-py" +version = "0.20.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, + {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, + {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, + {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, + {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, + {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, + {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, + {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, + {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, + {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, + {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, + {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, + {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, + {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, +] + [[package]] name = "safetensors" version = "0.4.5" @@ -2008,6 +3394,47 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "smmap" +version = "5.0.1" +description = "A pure Python implementation of a sliding window memory map manager" +optional = false +python-versions = ">=3.7" +files = [ + {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, + {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, +] + +[[package]] +name = "soupsieve" +version = "2.6" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + [[package]] name = "sympy" version = "1.13.2" @@ -2085,6 +3512,24 @@ files = [ {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, ] +[[package]] +name = "tinycss2" +version = "1.3.0" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tinycss2-1.3.0-py3-none-any.whl", hash = "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7"}, + {file = "tinycss2-1.3.0.tar.gz", hash = "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d"}, +] + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["pytest", "ruff"] + [[package]] name = "tokenizers" version = "0.19.1" @@ -2202,6 +3647,17 @@ dev = ["tokenizers[testing]"] docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"] testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"] +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + [[package]] name = "torch" version = "2.4.1" @@ -2294,6 +3750,26 @@ torch = "2.4.1" gdown = ["gdown (>=4.7.3)"] scipy = ["scipy"] +[[package]] +name = "tornado" +version = "6.4.1" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, + {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, + {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, + {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, +] + [[package]] name = "tqdm" version = "4.66.5" @@ -2314,6 +3790,21 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] +[[package]] +name = "traitlets" +version = "5.14.3" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] + [[package]] name = "transformers" version = "4.44.2" @@ -2443,6 +3934,84 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "watchdog" +version = "5.0.3" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.9" +files = [ + {file = "watchdog-5.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:85527b882f3facda0579bce9d743ff7f10c3e1e0db0a0d0e28170a7d0e5ce2ea"}, + {file = "watchdog-5.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:53adf73dcdc0ef04f7735066b4a57a4cd3e49ef135daae41d77395f0b5b692cb"}, + {file = "watchdog-5.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e25adddab85f674acac303cf1f5835951345a56c5f7f582987d266679979c75b"}, + {file = "watchdog-5.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f01f4a3565a387080dc49bdd1fefe4ecc77f894991b88ef927edbfa45eb10818"}, + {file = "watchdog-5.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:91b522adc25614cdeaf91f7897800b82c13b4b8ac68a42ca959f992f6990c490"}, + {file = "watchdog-5.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d52db5beb5e476e6853da2e2d24dbbbed6797b449c8bf7ea118a4ee0d2c9040e"}, + {file = "watchdog-5.0.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d11b07c64f63f49876e0ab8042ae034674c8653bfcdaa8c4b32e71cfff87e8"}, + {file = "watchdog-5.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:349c9488e1d85d0a58e8cb14222d2c51cbc801ce11ac3936ab4c3af986536926"}, + {file = "watchdog-5.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:53a3f10b62c2d569e260f96e8d966463dec1a50fa4f1b22aec69e3f91025060e"}, + {file = "watchdog-5.0.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:950f531ec6e03696a2414b6308f5c6ff9dab7821a768c9d5788b1314e9a46ca7"}, + {file = "watchdog-5.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6deb336cba5d71476caa029ceb6e88047fc1dc74b62b7c4012639c0b563906"}, + {file = "watchdog-5.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1021223c08ba8d2d38d71ec1704496471ffd7be42cfb26b87cd5059323a389a1"}, + {file = "watchdog-5.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:752fb40efc7cc8d88ebc332b8f4bcbe2b5cc7e881bccfeb8e25054c00c994ee3"}, + {file = "watchdog-5.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a2e8f3f955d68471fa37b0e3add18500790d129cc7efe89971b8a4cc6fdeb0b2"}, + {file = "watchdog-5.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b8ca4d854adcf480bdfd80f46fdd6fb49f91dd020ae11c89b3a79e19454ec627"}, + {file = "watchdog-5.0.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:90a67d7857adb1d985aca232cc9905dd5bc4803ed85cfcdcfcf707e52049eda7"}, + {file = "watchdog-5.0.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:720ef9d3a4f9ca575a780af283c8fd3a0674b307651c1976714745090da5a9e8"}, + {file = "watchdog-5.0.3-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:223160bb359281bb8e31c8f1068bf71a6b16a8ad3d9524ca6f523ac666bb6a1e"}, + {file = "watchdog-5.0.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:560135542c91eaa74247a2e8430cf83c4342b29e8ad4f520ae14f0c8a19cfb5b"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dd021efa85970bd4824acacbb922066159d0f9e546389a4743d56919b6758b91"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_armv7l.whl", hash = "sha256:78864cc8f23dbee55be34cc1494632a7ba30263951b5b2e8fc8286b95845f82c"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_i686.whl", hash = "sha256:1e9679245e3ea6498494b3028b90c7b25dbb2abe65c7d07423ecfc2d6218ff7c"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_ppc64.whl", hash = "sha256:9413384f26b5d050b6978e6fcd0c1e7f0539be7a4f1a885061473c5deaa57221"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:294b7a598974b8e2c6123d19ef15de9abcd282b0fbbdbc4d23dfa812959a9e05"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_s390x.whl", hash = "sha256:26dd201857d702bdf9d78c273cafcab5871dd29343748524695cecffa44a8d97"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:0f9332243355643d567697c3e3fa07330a1d1abf981611654a1f2bf2175612b7"}, + {file = "watchdog-5.0.3-py3-none-win32.whl", hash = "sha256:c66f80ee5b602a9c7ab66e3c9f36026590a0902db3aea414d59a2f55188c1f49"}, + {file = "watchdog-5.0.3-py3-none-win_amd64.whl", hash = "sha256:f00b4cf737f568be9665563347a910f8bdc76f88c2970121c86243c8cfdf90e9"}, + {file = "watchdog-5.0.3-py3-none-win_ia64.whl", hash = "sha256:49f4d36cb315c25ea0d946e018c01bb028048023b9e103d3d3943f58e109dd45"}, + {file = "watchdog-5.0.3.tar.gz", hash = "sha256:108f42a7f0345042a854d4d0ad0834b741d421330d5f575b81cb27b883500176"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[[package]] +name = "wcmatch" +version = "10.0" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, +] + +[package.dependencies] +bracex = ">=2.1.1" + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + [[package]] name = "werkzeug" version = "3.0.4" @@ -2474,4 +4043,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "8aaefe8626545311c017994cff09317d044cf35d2d883c42d2123189891360ef" +content-hash = "145da8824edabaab01f586ccdc7a2b87d3fa9ad1153b302354e5d5daf71c97e0" diff --git a/pyproject.toml b/pyproject.toml index d4a98ff..2291711 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,14 @@ matplotlib = "^3.9.2" tensorboard = "^2.17.1" tab-transformer-pytorch = "^0.3.0" transformers = "^4.44.2" +mkdocs-material = "^9.5.39" +mkdocs-autorefs = "^1.2.0" +mkdocs-redirects = "^1.2.1" +mkdocs-jupyter = "^0.25.0" +mkdocs-awesome-pages-plugin = "^2.9.3" +mkdocstrings = "^0.26.1" +mkdocstrings-python = "^1.11.1" +mknotebooks = "^0.8.0" [build-system] diff --git a/test_new_dataloader.ipynb b/test_new_dataloader.ipynb index 8012dbc..a83445e 100644 --- a/test_new_dataloader.ipynb +++ b/test_new_dataloader.ipynb @@ -24,13 +24,18 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Create dataset - tiniest imagenet" + "# Create dataset and task - tiniest imagenet" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2024-09-23T12:00:58.228952Z", + "start_time": "2024-09-23T12:00:56.493507Z" + } + }, "outputs": [], "source": [ "import openml\n", @@ -51,17 +56,14 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "URL for dataset: https://www.openml.org/d/46338\n" - ] + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2024-09-23T12:01:03.002048Z", + "start_time": "2024-09-23T12:01:02.996616Z" } - ], + }, + "outputs": [], "source": [ "def create_tiny_imagenet():\n", " dir_name = \"datasets\"\n", @@ -81,7 +83,6 @@ " image_paths = glob.glob(f\"{dir_name}/tiny-imagenet-200/train/*/*/*.JPEG\")\n", " ## remove the first part of the path\n", " image_paths = [path.split(\"/\", 1)[-1] for path in image_paths]\n", - " image_paths[-1]\n", " ## create a dataframe with the image path and the label\n", " label_func = lambda x: x.split(\"/\")[2]\n", " df = pd.DataFrame(image_paths, columns=[\"image_path\"])\n", @@ -251,14 +252,17 @@ { "cell_type": "code", "execution_count": 3, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2024-09-23T12:01:33.514283Z", + "start_time": "2024-09-23T12:01:32.116044Z" + } + }, "outputs": [], "source": [ "import torch.nn\n", "import torch.optim\n", "\n", - "import openml_pytorch\n", - "import openml_pytorch.layers\n", "import openml_pytorch.config\n", "import openml\n", "import logging\n", @@ -274,25 +278,23 @@ "############################################################################\n", "\n", "############################################################################\n", - "import torch.nn as nn\n", - "import torch.nn.functional as F\n", "from openml_pytorch.trainer import OpenMLTrainerModule\n", "from openml_pytorch.trainer import OpenMLDataModule\n", "from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor, Lambda\n", - "from openml_pytorch.trainer import convert_to_rgb\n", "import torchvision\n", "\n", - "# openml.config.apikey = 'key'\n", - "from openml_pytorch.trainer import OpenMLTrainerModule\n", - "from openml_pytorch.trainer import OpenMLDataModule\n", - "from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor, Lambda\n", "from openml_pytorch.trainer import convert_to_rgb" ] }, { "cell_type": "code", "execution_count": 4, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2024-09-23T12:01:39.788930Z", + "start_time": "2024-09-23T12:01:34.041129Z" + } + }, "outputs": [ { "name": "stderr", @@ -302,156 +304,32 @@ ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.801479914158951, tensor(0.0025, device='mps:0')]\n", - "valid: [5.3148078070746525, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.3340, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.808862606095679, tensor(0.0059, device='mps:0')]\n", - "valid: [5.316546630859375, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.2711, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.8101200810185185, tensor(0.0046, device='mps:0')]\n", - "valid: [5.312864176432291, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.3351, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.768438946759259, tensor(0.0025, device='mps:0')]\n", - "valid: [5.313296169704861, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.3264, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.8355655623070986, tensor(0.0034, device='mps:0')]\n", - "valid: [5.318412950303819, tensor(0.0028, device='mps:0')]\n", - "Loss tensor(5.3641, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.822142047646605, tensor(0.0015, device='mps:0')]\n", - "valid: [5.307448662651909, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.3678, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.817600429205247, tensor(0.0031, device='mps:0')]\n", - "valid: [5.311541408962674, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.2996, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.824053578317901, tensor(0.0037, device='mps:0')]\n", - "valid: [5.316675143771701, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.3310, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.760664424189815, tensor(0.0043, device='mps:0')]\n", - "valid: [5.313508097330729, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.3941, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.834643856095679, tensor(0.0052, device='mps:0')]\n", - "valid: [5.319950697157118, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.3501, device='mps:0')\n" + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[4], line 33\u001b[0m\n\u001b[1;32m 26\u001b[0m trainer \u001b[38;5;241m=\u001b[39m OpenMLTrainerModule(\n\u001b[1;32m 27\u001b[0m data_module\u001b[38;5;241m=\u001b[39mdata_module,\n\u001b[1;32m 28\u001b[0m verbose \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[1;32m 29\u001b[0m epoch_count \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m,\n\u001b[1;32m 30\u001b[0m \u001b[38;5;66;03m# optimizer_gen = torch.optim.AdamW\u001b[39;00m\n\u001b[1;32m 31\u001b[0m )\n\u001b[1;32m 32\u001b[0m openml_pytorch\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39mtrainer \u001b[38;5;241m=\u001b[39m trainer\n\u001b[0;32m---> 33\u001b[0m run \u001b[38;5;241m=\u001b[39m \u001b[43mopenml\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mruns\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_model_on_task\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/openml/runs/functions.py:165\u001b[0m, in \u001b[0;36mrun_model_on_task\u001b[0;34m(model, task, avoid_duplicate_runs, flow_tags, seed, add_local_measures, upload_flow, return_flow, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 161\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _task\n\u001b[1;32m 163\u001b[0m task \u001b[38;5;241m=\u001b[39m get_task_and_type_conversion(task)\n\u001b[0;32m--> 165\u001b[0m run \u001b[38;5;241m=\u001b[39m \u001b[43mrun_flow_on_task\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 166\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 167\u001b[0m \u001b[43m \u001b[49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 168\u001b[0m \u001b[43m \u001b[49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 169\u001b[0m \u001b[43m \u001b[49m\u001b[43mflow_tags\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow_tags\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 170\u001b[0m \u001b[43m \u001b[49m\u001b[43mseed\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mseed\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 171\u001b[0m \u001b[43m \u001b[49m\u001b[43madd_local_measures\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43madd_local_measures\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 172\u001b[0m \u001b[43m \u001b[49m\u001b[43mupload_flow\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mupload_flow\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 173\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 174\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 175\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 176\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m return_flow:\n\u001b[1;32m 177\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m run, flow\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/openml/runs/functions.py:308\u001b[0m, in \u001b[0;36mrun_flow_on_task\u001b[0;34m(flow, task, avoid_duplicate_runs, flow_tags, seed, add_local_measures, upload_flow, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 300\u001b[0m warnings\u001b[38;5;241m.\u001b[39mwarn(\n\u001b[1;32m 301\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe model is already fitted!\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 302\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m This might cause inconsistency in comparison of results.\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 303\u001b[0m \u001b[38;5;167;01mRuntimeWarning\u001b[39;00m,\n\u001b[1;32m 304\u001b[0m stacklevel\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m2\u001b[39m,\n\u001b[1;32m 305\u001b[0m )\n\u001b[1;32m 307\u001b[0m \u001b[38;5;66;03m# execute the run\u001b[39;00m\n\u001b[0;32m--> 308\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43m_run_task_get_arffcontent\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 309\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 310\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 311\u001b[0m \u001b[43m \u001b[49m\u001b[43mextension\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mextension\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 312\u001b[0m \u001b[43m \u001b[49m\u001b[43madd_local_measures\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43madd_local_measures\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 313\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 314\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 315\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 317\u001b[0m data_content, trace, fold_evaluations, sample_evaluations \u001b[38;5;241m=\u001b[39m res\n\u001b[1;32m 318\u001b[0m fields \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m*\u001b[39mrun_environment, time\u001b[38;5;241m.\u001b[39mstrftime(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%c\u001b[39;00m\u001b[38;5;124m\"\u001b[39m), \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCreated by run_flow_on_task\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/openml/runs/functions.py:559\u001b[0m, in \u001b[0;36m_run_task_get_arffcontent\u001b[0;34m(model, task, extension, add_local_measures, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 545\u001b[0m \u001b[38;5;66;03m# Execute runs in parallel\u001b[39;00m\n\u001b[1;32m 546\u001b[0m \u001b[38;5;66;03m# assuming the same number of tasks as workers (n_jobs), the total compute time for this\u001b[39;00m\n\u001b[1;32m 547\u001b[0m \u001b[38;5;66;03m# statement will be similar to the slowest run\u001b[39;00m\n\u001b[1;32m 548\u001b[0m \u001b[38;5;66;03m# TODO(eddiebergman): Simplify this\u001b[39;00m\n\u001b[1;32m 549\u001b[0m job_rvals: \u001b[38;5;28mlist\u001b[39m[\n\u001b[1;32m 550\u001b[0m \u001b[38;5;28mtuple\u001b[39m[\n\u001b[1;32m 551\u001b[0m np\u001b[38;5;241m.\u001b[39mndarray,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 557\u001b[0m ],\n\u001b[1;32m 558\u001b[0m ]\n\u001b[0;32m--> 559\u001b[0m job_rvals \u001b[38;5;241m=\u001b[39m \u001b[43mParallel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# type: ignore\u001b[39;49;00m\n\u001b[1;32m 560\u001b[0m \u001b[43m \u001b[49m\u001b[43mdelayed\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_run_task_get_arffcontent_parallel_helper\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 561\u001b[0m \u001b[43m \u001b[49m\u001b[43mextension\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mextension\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 562\u001b[0m \u001b[43m \u001b[49m\u001b[43mfold_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfold_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 563\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 564\u001b[0m \u001b[43m \u001b[49m\u001b[43mrep_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrep_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 565\u001b[0m \u001b[43m \u001b[49m\u001b[43msample_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msample_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 566\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 567\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 568\u001b[0m \u001b[43m \u001b[49m\u001b[43mconfiguration\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_config\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 569\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 570\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m_n_fit\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrep_no\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfold_no\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msample_no\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mjobs\u001b[49m\n\u001b[1;32m 571\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# job_rvals contain the output of all the runs with one-to-one correspondence with `jobs`\u001b[39;00m\n\u001b[1;32m 573\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m n_fit, rep_no, fold_no, sample_no \u001b[38;5;129;01min\u001b[39;00m jobs:\n\u001b[1;32m 574\u001b[0m pred_y, proba_y, test_indices, test_y, inner_trace, user_defined_measures_fold \u001b[38;5;241m=\u001b[39m job_rvals[\n\u001b[1;32m 575\u001b[0m n_fit \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 576\u001b[0m ]\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/joblib/parallel.py:1918\u001b[0m, in \u001b[0;36mParallel.__call__\u001b[0;34m(self, iterable)\u001b[0m\n\u001b[1;32m 1916\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_sequential_output(iterable)\n\u001b[1;32m 1917\u001b[0m \u001b[38;5;28mnext\u001b[39m(output)\n\u001b[0;32m-> 1918\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m output \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreturn_generator \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43moutput\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1920\u001b[0m \u001b[38;5;66;03m# Let's create an ID that uniquely identifies the current call. If the\u001b[39;00m\n\u001b[1;32m 1921\u001b[0m \u001b[38;5;66;03m# call is interrupted early and that the same instance is immediately\u001b[39;00m\n\u001b[1;32m 1922\u001b[0m \u001b[38;5;66;03m# re-used, this id will be used to prevent workers that were\u001b[39;00m\n\u001b[1;32m 1923\u001b[0m \u001b[38;5;66;03m# concurrently finalizing a task from the previous call to run the\u001b[39;00m\n\u001b[1;32m 1924\u001b[0m \u001b[38;5;66;03m# callback.\u001b[39;00m\n\u001b[1;32m 1925\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock:\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/joblib/parallel.py:1847\u001b[0m, in \u001b[0;36mParallel._get_sequential_output\u001b[0;34m(self, iterable)\u001b[0m\n\u001b[1;32m 1845\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_dispatched_batches \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 1846\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_dispatched_tasks \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m-> 1847\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1848\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_completed_tasks \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 1849\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprint_progress()\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/openml/runs/functions.py:800\u001b[0m, in \u001b[0;36m_run_task_get_arffcontent_parallel_helper\u001b[0;34m(extension, fold_no, model, rep_no, sample_no, task, dataset_format, configuration)\u001b[0m\n\u001b[1;32m 784\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(task\u001b[38;5;241m.\u001b[39mtask_type)\n\u001b[1;32m 786\u001b[0m config\u001b[38;5;241m.\u001b[39mlogger\u001b[38;5;241m.\u001b[39minfo(\n\u001b[1;32m 787\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGoing to run model \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m on dataset \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m for repeat \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m fold \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m sample \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\n\u001b[1;32m 788\u001b[0m \u001b[38;5;28mstr\u001b[39m(model),\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 793\u001b[0m ),\n\u001b[1;32m 794\u001b[0m )\n\u001b[1;32m 795\u001b[0m (\n\u001b[1;32m 796\u001b[0m pred_y,\n\u001b[1;32m 797\u001b[0m proba_y,\n\u001b[1;32m 798\u001b[0m user_defined_measures_fold,\n\u001b[1;32m 799\u001b[0m trace,\n\u001b[0;32m--> 800\u001b[0m ) \u001b[38;5;241m=\u001b[39m \u001b[43mextension\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_model_on_fold\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 801\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 802\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 803\u001b[0m \u001b[43m \u001b[49m\u001b[43mX_train\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtrain_x\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 804\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# TODO(eddiebergman): Likely should not be ignored\u001b[39;49;00m\n\u001b[1;32m 805\u001b[0m \u001b[43m \u001b[49m\u001b[43my_train\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtrain_y\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# type: ignore\u001b[39;49;00m\n\u001b[1;32m 806\u001b[0m \u001b[43m \u001b[49m\u001b[43mrep_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrep_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 807\u001b[0m \u001b[43m \u001b[49m\u001b[43mfold_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfold_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 808\u001b[0m \u001b[43m \u001b[49m\u001b[43mX_test\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtest_x\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 809\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 810\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m pred_y, proba_y, test_indices, test_y, trace, user_defined_measures_fold\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:1048\u001b[0m, in \u001b[0;36mPytorchExtension._run_model_on_fold\u001b[0;34m(self, model, task, X_train, rep_no, fold_no, y_train, X_test)\u001b[0m\n\u001b[1;32m 1046\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mAttributeError\u001b[39;00m:\n\u001b[1;32m 1047\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mTrainer not set to config. Please use openml_pytorch.config.trainer = trainer to set the trainer.\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m-> 1048\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtrainer\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_model_on_fold\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrep_no\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfold_no\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX_test\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/trainer.py:517\u001b[0m, in \u001b[0;36mOpenMLTrainerModule.run_model_on_fold\u001b[0;34m(self, model, task, X_train, rep_no, fold_no, y_train, X_test)\u001b[0m\n\u001b[1;32m 515\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel \u001b[38;5;241m=\u001b[39m copy\u001b[38;5;241m.\u001b[39mdeepcopy(model)\n\u001b[1;32m 516\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 517\u001b[0m data, model_classes \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_training\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX_test\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 519\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mAttributeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 520\u001b[0m \u001b[38;5;66;03m# typically happens when training a regressor8 on classification task\u001b[39;00m\n\u001b[1;32m 521\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m PyOpenMLError(\u001b[38;5;28mstr\u001b[39m(e))\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/trainer.py:652\u001b[0m, in \u001b[0;36mOpenMLTrainerModule.run_training\u001b[0;34m(self, task, X_train, y_train, X_test)\u001b[0m\n\u001b[1;32m 650\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrunner \u001b[38;5;241m=\u001b[39m ModelRunner(cb_funcs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcbfs)\n\u001b[1;32m 651\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlearn\u001b[38;5;241m.\u001b[39mmodel\u001b[38;5;241m.\u001b[39mtrain()\n\u001b[0;32m--> 652\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrunner\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mepochs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mepoch_count\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlearn\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlearn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 653\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlearn\u001b[38;5;241m.\u001b[39mmodel\u001b[38;5;241m.\u001b[39meval()\n\u001b[1;32m 655\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mLoss\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrunner\u001b[38;5;241m.\u001b[39mloss)\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/trainer.py:412\u001b[0m, in \u001b[0;36mModelRunner.fit\u001b[0;34m(self, epochs, learn)\u001b[0m\n\u001b[1;32m 410\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mepoch \u001b[38;5;241m=\u001b[39m epoch\n\u001b[1;32m 411\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbegin_epoch\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m--> 412\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mall_batches\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtrain_dl\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 413\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m torch\u001b[38;5;241m.\u001b[39mno_grad():\n\u001b[1;32m 414\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbegin_validate\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/trainer.py:399\u001b[0m, in \u001b[0;36mModelRunner.all_batches\u001b[0;34m(self, dl)\u001b[0m\n\u001b[1;32m 397\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 398\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m xb, yb \u001b[38;5;129;01min\u001b[39;00m tqdm(dl, leave\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m):\n\u001b[0;32m--> 399\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mone_batch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mxb\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43myb\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 400\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m CancelEpochException:\n\u001b[1;32m 401\u001b[0m \u001b[38;5;28mself\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mafter_cancel_epoch\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/trainer.py:387\u001b[0m, in \u001b[0;36mModelRunner.one_batch\u001b[0;34m(self, xb, yb)\u001b[0m\n\u001b[1;32m 385\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mloss\u001b[38;5;241m.\u001b[39mbackward()\n\u001b[1;32m 386\u001b[0m \u001b[38;5;28mself\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mafter_backward\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 387\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mopt\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 388\u001b[0m \u001b[38;5;28mself\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mafter_step\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 389\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mopt\u001b[38;5;241m.\u001b[39mzero_grad()\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/torch/optim/optimizer.py:484\u001b[0m, in \u001b[0;36mOptimizer.profile_hook_step..wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 479\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 480\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\n\u001b[1;32m 481\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfunc\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m must return None or a tuple of (new_args, new_kwargs), but got \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mresult\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 482\u001b[0m )\n\u001b[0;32m--> 484\u001b[0m out \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 485\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_optimizer_step_code()\n\u001b[1;32m 487\u001b[0m \u001b[38;5;66;03m# call optimizer step post hooks\u001b[39;00m\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/torch/optim/optimizer.py:89\u001b[0m, in \u001b[0;36m_use_grad_for_differentiable.._use_grad\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 87\u001b[0m torch\u001b[38;5;241m.\u001b[39mset_grad_enabled(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefaults[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdifferentiable\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n\u001b[1;32m 88\u001b[0m torch\u001b[38;5;241m.\u001b[39m_dynamo\u001b[38;5;241m.\u001b[39mgraph_break()\n\u001b[0;32m---> 89\u001b[0m ret \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 90\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 91\u001b[0m torch\u001b[38;5;241m.\u001b[39m_dynamo\u001b[38;5;241m.\u001b[39mgraph_break()\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/torch/optim/adam.py:226\u001b[0m, in \u001b[0;36mAdam.step\u001b[0;34m(self, closure)\u001b[0m\n\u001b[1;32m 214\u001b[0m beta1, beta2 \u001b[38;5;241m=\u001b[39m group[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbetas\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 216\u001b[0m has_complex \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_init_group(\n\u001b[1;32m 217\u001b[0m group,\n\u001b[1;32m 218\u001b[0m params_with_grad,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 223\u001b[0m state_steps,\n\u001b[1;32m 224\u001b[0m )\n\u001b[0;32m--> 226\u001b[0m \u001b[43madam\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 227\u001b[0m \u001b[43m \u001b[49m\u001b[43mparams_with_grad\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 228\u001b[0m \u001b[43m \u001b[49m\u001b[43mgrads\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 229\u001b[0m \u001b[43m \u001b[49m\u001b[43mexp_avgs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 230\u001b[0m \u001b[43m \u001b[49m\u001b[43mexp_avg_sqs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 231\u001b[0m \u001b[43m \u001b[49m\u001b[43mmax_exp_avg_sqs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 232\u001b[0m \u001b[43m \u001b[49m\u001b[43mstate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 233\u001b[0m \u001b[43m \u001b[49m\u001b[43mamsgrad\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mamsgrad\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 234\u001b[0m \u001b[43m \u001b[49m\u001b[43mhas_complex\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mhas_complex\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 235\u001b[0m \u001b[43m \u001b[49m\u001b[43mbeta1\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbeta1\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 236\u001b[0m \u001b[43m \u001b[49m\u001b[43mbeta2\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbeta2\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 237\u001b[0m \u001b[43m \u001b[49m\u001b[43mlr\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mlr\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 238\u001b[0m \u001b[43m \u001b[49m\u001b[43mweight_decay\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mweight_decay\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 239\u001b[0m \u001b[43m \u001b[49m\u001b[43meps\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43meps\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 240\u001b[0m \u001b[43m \u001b[49m\u001b[43mmaximize\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmaximize\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 241\u001b[0m \u001b[43m \u001b[49m\u001b[43mforeach\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mforeach\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 242\u001b[0m \u001b[43m \u001b[49m\u001b[43mcapturable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcapturable\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 243\u001b[0m \u001b[43m \u001b[49m\u001b[43mdifferentiable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdifferentiable\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 244\u001b[0m \u001b[43m \u001b[49m\u001b[43mfused\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroup\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfused\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 245\u001b[0m \u001b[43m \u001b[49m\u001b[43mgrad_scale\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mgrad_scale\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 246\u001b[0m \u001b[43m \u001b[49m\u001b[43mfound_inf\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfound_inf\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 247\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 249\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m loss\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/torch/optim/optimizer.py:161\u001b[0m, in \u001b[0;36m_disable_dynamo_if_unsupported..wrapper..maybe_fallback\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m disabled_func(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 160\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 161\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/torch/optim/adam.py:766\u001b[0m, in \u001b[0;36madam\u001b[0;34m(params, grads, exp_avgs, exp_avg_sqs, max_exp_avg_sqs, state_steps, foreach, capturable, differentiable, fused, grad_scale, found_inf, has_complex, amsgrad, beta1, beta2, lr, weight_decay, eps, maximize)\u001b[0m\n\u001b[1;32m 763\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 764\u001b[0m func \u001b[38;5;241m=\u001b[39m _single_tensor_adam\n\u001b[0;32m--> 766\u001b[0m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 767\u001b[0m \u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 768\u001b[0m \u001b[43m \u001b[49m\u001b[43mgrads\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 769\u001b[0m \u001b[43m \u001b[49m\u001b[43mexp_avgs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 770\u001b[0m \u001b[43m \u001b[49m\u001b[43mexp_avg_sqs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 771\u001b[0m \u001b[43m \u001b[49m\u001b[43mmax_exp_avg_sqs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 772\u001b[0m \u001b[43m \u001b[49m\u001b[43mstate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 773\u001b[0m \u001b[43m \u001b[49m\u001b[43mamsgrad\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mamsgrad\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 774\u001b[0m \u001b[43m \u001b[49m\u001b[43mhas_complex\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mhas_complex\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 775\u001b[0m \u001b[43m \u001b[49m\u001b[43mbeta1\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbeta1\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 776\u001b[0m \u001b[43m \u001b[49m\u001b[43mbeta2\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbeta2\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 777\u001b[0m \u001b[43m \u001b[49m\u001b[43mlr\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlr\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 778\u001b[0m \u001b[43m \u001b[49m\u001b[43mweight_decay\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mweight_decay\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 779\u001b[0m \u001b[43m \u001b[49m\u001b[43meps\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43meps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 780\u001b[0m \u001b[43m \u001b[49m\u001b[43mmaximize\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmaximize\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 781\u001b[0m \u001b[43m \u001b[49m\u001b[43mcapturable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcapturable\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 782\u001b[0m \u001b[43m \u001b[49m\u001b[43mdifferentiable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdifferentiable\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 783\u001b[0m \u001b[43m \u001b[49m\u001b[43mgrad_scale\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgrad_scale\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 784\u001b[0m \u001b[43m \u001b[49m\u001b[43mfound_inf\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfound_inf\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 785\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/venv/lib/python3.11/site-packages/torch/optim/adam.py:433\u001b[0m, in \u001b[0;36m_single_tensor_adam\u001b[0;34m(params, grads, exp_avgs, exp_avg_sqs, max_exp_avg_sqs, state_steps, grad_scale, found_inf, amsgrad, has_complex, beta1, beta2, lr, weight_decay, eps, maximize, capturable, differentiable)\u001b[0m\n\u001b[1;32m 430\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 431\u001b[0m denom \u001b[38;5;241m=\u001b[39m (exp_avg_sq\u001b[38;5;241m.\u001b[39msqrt() \u001b[38;5;241m/\u001b[39m bias_correction2_sqrt)\u001b[38;5;241m.\u001b[39madd_(eps)\n\u001b[0;32m--> 433\u001b[0m \u001b[43mparam\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43maddcdiv_\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexp_avg\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdenom\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[43mstep_size\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 435\u001b[0m \u001b[38;5;66;03m# Lastly, switch back to complex view\u001b[39;00m\n\u001b[1;32m 436\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m amsgrad \u001b[38;5;129;01mand\u001b[39;00m torch\u001b[38;5;241m.\u001b[39mis_complex(params[i]):\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } ], @@ -583,12 +461,13 @@ "import torch.nn\n", "import torch.optim\n", "\n", - "import openml\n", - "import openml_pytorch\n", - "import openml_pytorch.layers\n", "import openml_pytorch.config\n", + "import openml\n", "import logging\n", + "import warnings\n", "\n", + "# Suppress FutureWarning messages\n", + "warnings.simplefilter(action='ignore')\n", "\n", "############################################################################\n", "# Enable logging in order to observe the progress while running the example.\n", @@ -604,8 +483,7 @@ "outputs": [], "source": [ "from openml_pytorch.trainer import OpenMLTrainerModule\n", - "from openml_pytorch.trainer import OpenMLDataModule\n", - "from openml_pytorch.trainer import Callback" + "from openml_pytorch.trainer import OpenMLDataModule" ] }, { @@ -922,7 +800,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -935,7 +813,8 @@ "import openml_pytorch.config\n", "import logging\n", "import warnings\n", - "\n", + "from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor, Lambda\n", + "from openml_pytorch.trainer import convert_to_rgb\n", "# Suppress FutureWarning messages\n", "warnings.simplefilter(action='ignore')\n", "\n", @@ -952,7 +831,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -964,7 +843,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -1001,13 +880,14 @@ " data_module=data_module,\n", " verbose = True,\n", " epoch_count = 1,\n", + " optimizer = custom_optimizer_gen\n", ")\n", "openml_pytorch.config.trainer = trainer" ] }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -1037,7 +917,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -1051,187 +931,73 @@ "name": "stdout", "output_type": "stream", "text": [ - "train: [5.502246696566358, tensor(0.0049, device='mps:0')]\n", - "valid: [5.4443077935112845, tensor(0.0222, device='mps:0')]\n", - "Loss tensor(5.4364, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.490761839313271, tensor(0.0037, device='mps:0')]\n", - "valid: [5.370191786024305, tensor(0.0139, device='mps:0')]\n", - "Loss tensor(5.3194, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.515043885030864, tensor(0.0037, device='mps:0')]\n", - "valid: [6.001016574435764, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.6311, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.503954475308642, tensor(0.0065, device='mps:0')]\n", - "valid: [5.516939968532986, tensor(0.0056, device='mps:0')]\n", - "Loss tensor(5.4652, device='mps:0')\n" + "train: [5.488128134645062, tensor(0.0056, device='mps:0')]\n", + "valid: [5.460971408420139, tensor(0.0111, device='mps:0')]\n", + "Loss tensor(5.2636, device='mps:0')\n" ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[21], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# Run the model on the task (requires an API key).m\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m run \u001b[38;5;241m=\u001b[39m \u001b[43mopenml\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mruns\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_model_on_task\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:165\u001b[0m, in \u001b[0;36mrun_model_on_task\u001b[0;34m(model, task, avoid_duplicate_runs, flow_tags, seed, add_local_measures, upload_flow, return_flow, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 161\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _task\n\u001b[1;32m 163\u001b[0m task \u001b[38;5;241m=\u001b[39m get_task_and_type_conversion(task)\n\u001b[0;32m--> 165\u001b[0m run \u001b[38;5;241m=\u001b[39m \u001b[43mrun_flow_on_task\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 166\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 167\u001b[0m \u001b[43m \u001b[49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 168\u001b[0m \u001b[43m \u001b[49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 169\u001b[0m \u001b[43m \u001b[49m\u001b[43mflow_tags\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow_tags\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 170\u001b[0m \u001b[43m \u001b[49m\u001b[43mseed\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mseed\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 171\u001b[0m \u001b[43m \u001b[49m\u001b[43madd_local_measures\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43madd_local_measures\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 172\u001b[0m \u001b[43m \u001b[49m\u001b[43mupload_flow\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mupload_flow\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 173\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 174\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 175\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 176\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m return_flow:\n\u001b[1;32m 177\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m run, flow\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:308\u001b[0m, in \u001b[0;36mrun_flow_on_task\u001b[0;34m(flow, task, avoid_duplicate_runs, flow_tags, seed, add_local_measures, upload_flow, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 300\u001b[0m warnings\u001b[38;5;241m.\u001b[39mwarn(\n\u001b[1;32m 301\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe model is already fitted!\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 302\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m This might cause inconsistency in comparison of results.\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 303\u001b[0m \u001b[38;5;167;01mRuntimeWarning\u001b[39;00m,\n\u001b[1;32m 304\u001b[0m stacklevel\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m2\u001b[39m,\n\u001b[1;32m 305\u001b[0m )\n\u001b[1;32m 307\u001b[0m \u001b[38;5;66;03m# execute the run\u001b[39;00m\n\u001b[0;32m--> 308\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43m_run_task_get_arffcontent\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 309\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 310\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 311\u001b[0m \u001b[43m \u001b[49m\u001b[43mextension\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mextension\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 312\u001b[0m \u001b[43m \u001b[49m\u001b[43madd_local_measures\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43madd_local_measures\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 313\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 314\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 315\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 317\u001b[0m data_content, trace, fold_evaluations, sample_evaluations \u001b[38;5;241m=\u001b[39m res\n\u001b[1;32m 318\u001b[0m fields \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m*\u001b[39mrun_environment, time\u001b[38;5;241m.\u001b[39mstrftime(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%c\u001b[39;00m\u001b[38;5;124m\"\u001b[39m), \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCreated by run_flow_on_task\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:559\u001b[0m, in \u001b[0;36m_run_task_get_arffcontent\u001b[0;34m(model, task, extension, add_local_measures, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 545\u001b[0m \u001b[38;5;66;03m# Execute runs in parallel\u001b[39;00m\n\u001b[1;32m 546\u001b[0m \u001b[38;5;66;03m# assuming the same number of tasks as workers (n_jobs), the total compute time for this\u001b[39;00m\n\u001b[1;32m 547\u001b[0m \u001b[38;5;66;03m# statement will be similar to the slowest run\u001b[39;00m\n\u001b[1;32m 548\u001b[0m \u001b[38;5;66;03m# TODO(eddiebergman): Simplify this\u001b[39;00m\n\u001b[1;32m 549\u001b[0m job_rvals: \u001b[38;5;28mlist\u001b[39m[\n\u001b[1;32m 550\u001b[0m \u001b[38;5;28mtuple\u001b[39m[\n\u001b[1;32m 551\u001b[0m np\u001b[38;5;241m.\u001b[39mndarray,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 557\u001b[0m ],\n\u001b[1;32m 558\u001b[0m ]\n\u001b[0;32m--> 559\u001b[0m job_rvals \u001b[38;5;241m=\u001b[39m \u001b[43mParallel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# type: ignore\u001b[39;49;00m\n\u001b[1;32m 560\u001b[0m \u001b[43m \u001b[49m\u001b[43mdelayed\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_run_task_get_arffcontent_parallel_helper\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 561\u001b[0m \u001b[43m \u001b[49m\u001b[43mextension\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mextension\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 562\u001b[0m \u001b[43m \u001b[49m\u001b[43mfold_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfold_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 563\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 564\u001b[0m \u001b[43m \u001b[49m\u001b[43mrep_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrep_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 565\u001b[0m \u001b[43m \u001b[49m\u001b[43msample_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msample_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 566\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 567\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 568\u001b[0m \u001b[43m \u001b[49m\u001b[43mconfiguration\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_config\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 569\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 570\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m_n_fit\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrep_no\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfold_no\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msample_no\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mjobs\u001b[49m\n\u001b[1;32m 571\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# job_rvals contain the output of all the runs with one-to-one correspondence with `jobs`\u001b[39;00m\n\u001b[1;32m 573\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m n_fit, rep_no, fold_no, sample_no \u001b[38;5;129;01min\u001b[39;00m jobs:\n\u001b[1;32m 574\u001b[0m pred_y, proba_y, test_indices, test_y, inner_trace, user_defined_measures_fold \u001b[38;5;241m=\u001b[39m job_rvals[\n\u001b[1;32m 575\u001b[0m n_fit \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 576\u001b[0m ]\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/joblib/parallel.py:1918\u001b[0m, in \u001b[0;36mParallel.__call__\u001b[0;34m(self, iterable)\u001b[0m\n\u001b[1;32m 1916\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_sequential_output(iterable)\n\u001b[1;32m 1917\u001b[0m \u001b[38;5;28mnext\u001b[39m(output)\n\u001b[0;32m-> 1918\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m output \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreturn_generator \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43moutput\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1920\u001b[0m \u001b[38;5;66;03m# Let's create an ID that uniquely identifies the current call. If the\u001b[39;00m\n\u001b[1;32m 1921\u001b[0m \u001b[38;5;66;03m# call is interrupted early and that the same instance is immediately\u001b[39;00m\n\u001b[1;32m 1922\u001b[0m \u001b[38;5;66;03m# re-used, this id will be used to prevent workers that were\u001b[39;00m\n\u001b[1;32m 1923\u001b[0m \u001b[38;5;66;03m# concurrently finalizing a task from the previous call to run the\u001b[39;00m\n\u001b[1;32m 1924\u001b[0m \u001b[38;5;66;03m# callback.\u001b[39;00m\n\u001b[1;32m 1925\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock:\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/joblib/parallel.py:1847\u001b[0m, in \u001b[0;36mParallel._get_sequential_output\u001b[0;34m(self, iterable)\u001b[0m\n\u001b[1;32m 1845\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_dispatched_batches \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 1846\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_dispatched_tasks \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m-> 1847\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1848\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_completed_tasks \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 1849\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprint_progress()\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:800\u001b[0m, in \u001b[0;36m_run_task_get_arffcontent_parallel_helper\u001b[0;34m(extension, fold_no, model, rep_no, sample_no, task, dataset_format, configuration)\u001b[0m\n\u001b[1;32m 784\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(task\u001b[38;5;241m.\u001b[39mtask_type)\n\u001b[1;32m 786\u001b[0m config\u001b[38;5;241m.\u001b[39mlogger\u001b[38;5;241m.\u001b[39minfo(\n\u001b[1;32m 787\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGoing to run model \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m on dataset \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m for repeat \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m fold \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m sample \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\n\u001b[1;32m 788\u001b[0m \u001b[38;5;28mstr\u001b[39m(model),\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 793\u001b[0m ),\n\u001b[1;32m 794\u001b[0m )\n\u001b[1;32m 795\u001b[0m (\n\u001b[1;32m 796\u001b[0m pred_y,\n\u001b[1;32m 797\u001b[0m proba_y,\n\u001b[1;32m 798\u001b[0m user_defined_measures_fold,\n\u001b[1;32m 799\u001b[0m trace,\n\u001b[0;32m--> 800\u001b[0m ) \u001b[38;5;241m=\u001b[39m \u001b[43mextension\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_model_on_fold\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 801\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 802\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 803\u001b[0m \u001b[43m \u001b[49m\u001b[43mX_train\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtrain_x\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 804\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# TODO(eddiebergman): Likely should not be ignored\u001b[39;49;00m\n\u001b[1;32m 805\u001b[0m \u001b[43m \u001b[49m\u001b[43my_train\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtrain_y\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# type: ignore\u001b[39;49;00m\n\u001b[1;32m 806\u001b[0m \u001b[43m \u001b[49m\u001b[43mrep_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrep_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 807\u001b[0m \u001b[43m \u001b[49m\u001b[43mfold_no\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfold_no\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 808\u001b[0m \u001b[43m \u001b[49m\u001b[43mX_test\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtest_x\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 809\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 810\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m pred_y, proba_y, test_indices, test_y, trace, user_defined_measures_fold\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:1048\u001b[0m, in \u001b[0;36mPytorchExtension._run_model_on_fold\u001b[0;34m(self, model, task, X_train, rep_no, fold_no, y_train, X_test)\u001b[0m\n\u001b[1;32m 1046\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mAttributeError\u001b[39;00m:\n\u001b[1;32m 1047\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mTrainer not set to config. Please use openml_pytorch.config.trainer = trainer to set the trainer.\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m-> 1048\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtrainer\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_model_on_fold\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrep_no\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfold_no\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX_test\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/trainer.py:527\u001b[0m, in \u001b[0;36mOpenMLTrainerModule.run_model_on_fold\u001b[0;34m(self, model, task, X_train, rep_no, fold_no, y_train, X_test)\u001b[0m\n\u001b[1;32m 524\u001b[0m pred_y, proba_y \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrun_evaluation(task, data, model_classes)\n\u001b[1;32m 526\u001b[0m \u001b[38;5;66;03m# Convert model to onnx\u001b[39;00m\n\u001b[0;32m--> 527\u001b[0m onnx_ \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_onnx_export(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel)\n\u001b[1;32m 529\u001b[0m \u001b[38;5;28;01mglobal\u001b[39;00m last_models\n\u001b[1;32m 530\u001b[0m last_models \u001b[38;5;241m=\u001b[39m onnx_\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/trainer.py:572\u001b[0m, in \u001b[0;36mrun_evaluation\u001b[0;34m(self, task, data, model_classes)\u001b[0m\n\u001b[1;32m 0\u001b[0m \n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/trainer.py:669\u001b[0m, in \u001b[0;36mpred_test\u001b[0;34m(self, task, model_copy, test_loader, predict_func)\u001b[0m\n\u001b[1;32m 667\u001b[0m inputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39msanitize(inputs)\n\u001b[1;32m 668\u001b[0m \u001b[38;5;66;03m# if torch.cuda.is_available():\u001b[39;00m\n\u001b[0;32m--> 669\u001b[0m inputs \u001b[38;5;241m=\u001b[39m inputs\u001b[38;5;241m.\u001b[39mto(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39mdevice)\n\u001b[1;32m 671\u001b[0m \u001b[38;5;66;03m# Perform inference on the batch\u001b[39;00m\n\u001b[1;32m 672\u001b[0m pred_y_batch \u001b[38;5;241m=\u001b[39m model_copy(inputs)\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/torch/utils/data/dataloader.py:630\u001b[0m, in \u001b[0;36m_BaseDataLoaderIter.__next__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 627\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_sampler_iter \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 628\u001b[0m \u001b[38;5;66;03m# TODO(https://github.com/pytorch/pytorch/issues/76750)\u001b[39;00m\n\u001b[1;32m 629\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_reset() \u001b[38;5;66;03m# type: ignore[call-arg]\u001b[39;00m\n\u001b[0;32m--> 630\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_next_data\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 631\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_yielded \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 632\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_dataset_kind \u001b[38;5;241m==\u001b[39m _DatasetKind\u001b[38;5;241m.\u001b[39mIterable \u001b[38;5;129;01mand\u001b[39;00m \\\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_IterableDataset_len_called \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \\\n\u001b[1;32m 634\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_yielded \u001b[38;5;241m>\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_IterableDataset_len_called:\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/torch/utils/data/dataloader.py:673\u001b[0m, in \u001b[0;36m_SingleProcessDataLoaderIter._next_data\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 671\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_next_data\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[1;32m 672\u001b[0m index \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_next_index() \u001b[38;5;66;03m# may raise StopIteration\u001b[39;00m\n\u001b[0;32m--> 673\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_dataset_fetcher\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfetch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindex\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# may raise StopIteration\u001b[39;00m\n\u001b[1;32m 674\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pin_memory:\n\u001b[1;32m 675\u001b[0m data \u001b[38;5;241m=\u001b[39m _utils\u001b[38;5;241m.\u001b[39mpin_memory\u001b[38;5;241m.\u001b[39mpin_memory(data, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pin_memory_device)\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/torch/utils/data/_utils/fetch.py:52\u001b[0m, in \u001b[0;36m_MapDatasetFetcher.fetch\u001b[0;34m(self, possibly_batched_index)\u001b[0m\n\u001b[1;32m 50\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39m__getitems__(possibly_batched_index)\n\u001b[1;32m 51\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 52\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43midx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mpossibly_batched_index\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 53\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 54\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[possibly_batched_index]\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/torch/utils/data/_utils/fetch.py:52\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 50\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39m__getitems__(possibly_batched_index)\n\u001b[1;32m 51\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 52\u001b[0m data \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m idx \u001b[38;5;129;01min\u001b[39;00m possibly_batched_index]\n\u001b[1;32m 53\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 54\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[possibly_batched_index]\n", + "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/custom_datasets.py:25\u001b[0m, in \u001b[0;36mOpenMLImageDataset.__getitem__\u001b[0;34m(self, idx)\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__getitem__\u001b[39m(\u001b[38;5;28mself\u001b[39m, idx):\n\u001b[0;32m---> 25\u001b[0m img_name \u001b[38;5;241m=\u001b[39m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mimage_dir, \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mX\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43miloc\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m)\n\u001b[1;32m 26\u001b[0m image \u001b[38;5;241m=\u001b[39m read_image(img_name)\n\u001b[1;32m 27\u001b[0m image \u001b[38;5;241m=\u001b[39m image\u001b[38;5;241m.\u001b[39mfloat()\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/pandas/core/indexing.py:1183\u001b[0m, in \u001b[0;36m_LocationIndexer.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 1181\u001b[0m key \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mtuple\u001b[39m(com\u001b[38;5;241m.\u001b[39mapply_if_callable(x, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mobj) \u001b[38;5;28;01mfor\u001b[39;00m x \u001b[38;5;129;01min\u001b[39;00m key)\n\u001b[1;32m 1182\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_is_scalar_access(key):\n\u001b[0;32m-> 1183\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mobj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_value\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtakeable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_takeable\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1184\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_getitem_tuple(key)\n\u001b[1;32m 1185\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 1186\u001b[0m \u001b[38;5;66;03m# we by definition only have the 0th axis\u001b[39;00m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/pandas/core/frame.py:4211\u001b[0m, in \u001b[0;36mDataFrame._get_value\u001b[0;34m(self, index, col, takeable)\u001b[0m\n\u001b[1;32m 4192\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 4193\u001b[0m \u001b[38;5;124;03mQuickly retrieve single value at passed column and index.\u001b[39;00m\n\u001b[1;32m 4194\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 4208\u001b[0m \u001b[38;5;124;03m`self.columns._index_as_unique`; Caller is responsible for checking.\u001b[39;00m\n\u001b[1;32m 4209\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 4210\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m takeable:\n\u001b[0;32m-> 4211\u001b[0m series \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_ixs\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcol\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4212\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m series\u001b[38;5;241m.\u001b[39m_values[index]\n\u001b[1;32m 4214\u001b[0m series \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_item_cache(col)\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/pandas/core/frame.py:4008\u001b[0m, in \u001b[0;36mDataFrame._ixs\u001b[0;34m(self, i, axis)\u001b[0m\n\u001b[1;32m 4004\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n\u001b[1;32m 4006\u001b[0m \u001b[38;5;66;03m# icol\u001b[39;00m\n\u001b[1;32m 4007\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 4008\u001b[0m label \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcolumns\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 4010\u001b[0m col_mgr \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_mgr\u001b[38;5;241m.\u001b[39miget(i)\n\u001b[1;32m 4011\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_box_col_values(col_mgr, i)\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/pandas/core/indexes/base.py:5373\u001b[0m, in \u001b[0;36mIndex.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 5369\u001b[0m \u001b[38;5;129m@final\u001b[39m\n\u001b[1;32m 5370\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__setitem__\u001b[39m(\u001b[38;5;28mself\u001b[39m, key, value) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 5371\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIndex does not support mutable operations\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m-> 5373\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__getitem__\u001b[39m(\u001b[38;5;28mself\u001b[39m, key):\n\u001b[1;32m 5374\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 5375\u001b[0m \u001b[38;5;124;03m Override numpy.ndarray's __getitem__ method to work as desired.\u001b[39;00m\n\u001b[1;32m 5376\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 5382\u001b[0m \n\u001b[1;32m 5383\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m 5384\u001b[0m getitem \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_data\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__getitem__\u001b[39m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] - }, + } + ], + "source": [ + "#\n", + "# Run the model on the task (requires an API key).m\n", + "run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.52061149691358, tensor(0.0056, device='mps:0')]\n", - "valid: [5.950181070963541, tensor(0.0028, device='mps:0')]\n", - "Loss tensor(5.5258, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.516010802469136, tensor(0.0049, device='mps:0')]\n", - "valid: [5.995764838324653, tensor(0.0083, device='mps:0')]\n", - "Loss tensor(6.7012, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.513693576388889, tensor(0.0059, device='mps:0')]\n", - "valid: [6.028563774956597, tensor(0.0083, device='mps:0')]\n", - "Loss tensor(5.3737, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.52438331886574, tensor(0.0043, device='mps:0')]\n", - "valid: [5.413638305664063, tensor(0., device='mps:0')]\n", - "Loss tensor(5.2557, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.520927372685185, tensor(0.0080, device='mps:0')]\n", - "valid: [5.540195041232639, tensor(0.0139, device='mps:0')]\n", - "Loss tensor(5.5892, device='mps:0')\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - " \r" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: [5.478434847608025, tensor(0.0065, device='mps:0')]\n", - "valid: [5.5816396077473955, tensor(0.0083, device='mps:0')]\n", - "Loss tensor(5.5443, device='mps:0')\n" - ] - } - ], - "source": [ - "#\n", - "# Run the model on the task (requires an API key).m\n", - "run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGdCAYAAADAAnMpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB0z0lEQVR4nO2deZhcZZn279q6eqvqvdNJd9LZw5KNPWE1bMaIIIIg86GgiMo4jo7Op4JLxkHhm0EHUXFldNA4UUQDiIAgIoQlIWzZCImErJ1O73tXd23n+6Pqfat6qz7n1Dl1zqm6f9dVV5LuWt6u7nTd9Tz3cz8uAAoIIYQQQizCbfUBCCGEEFLYUIwQQgghxFIoRgghhBBiKRQjhBBCCLEUihFCCCGEWArFCCGEEEIshWKEEEIIIZZCMUIIIYQQS/FafQC1zJo1CwMDA1YfgxBCCCEaCAQCOHbsWMbrOEKMzJo1Cy0tLVYfgxBCCCE6aGxszChIHCFGREWksbGR1RFCCCHEIQQCAbS0tEz72u0IMSIYGBigGCGEEELyDBpYCSGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoQQQgghlkIxQgghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoSYTuWMelzyqY+h8YTFVh+FEEKIDaEYIaZzwY3/gLWfvhmf/939+MSP78ais063+kiEEEJshNfqA5D8J1BTLf++5JxVWHLOKhzZvQfP/OLX2PHUM1DicQtPRwghxGpYGSGmU1xeBgD48w/vw/P/+zuEQyOYffKJ+Mi3v4kvP/pbrL7mSnj9fotPSQghxCooRojpFJeXAwBa972NTXf+F7556fvx5x/eh6GeXtTObsLVX/sivvrnP+Cim2+Ax+ez+LSEEEJyDcUIMR1RGRkZHAIADPX24ckf/Te++e4rsenO76C7pRWBmmqs++dP4dzrrrbyqIQQQiyAYoSYzngxIgiHRvD8/z6IO9/7Qbz66BMAxvpLCCGEFAYUI8R0RJsmNDg46efjsRi6jrQAAHwlxTk7FyGEEHtAMUJMxeVywV9WCgAYmUKMAEB4ZAQAUFRMMUIIIYUGxQgxlaLSErjdiR+zkcHhKa8XSYoRXzGnagghpNCgGCGmUpJs0UQjEURHR6e8XjiU+BwrI4QQUnhQjBBT8Qvz6sDULRogrTJCzwghhBQcFCPEVERlZGRoKOP16BkhhJDChWKEmEpxQFRGMosRekYIIaRwoRghplJclhQj01VG6BkhhJCChWKEmEpxINmmyTDWC9AzQgghhQzFCDEVWRmZrk0zysoIIYQUKhQjxFRkZWTaNg09I4QQUqhQjBBTKdY62uv3w+XmjyUhhBQS/K1PTCW1JC+zGBGjvUBCkBBCCCkcKEaIqYgleZmi4AEgOhqWf2erhhBCCguKEWIqaisjiqJI3whNrIQQUlhQjBBTSYmRzAZWgMFnhBBSqFCMEFNJtWkyV0aAtEh4Zo0QQkhBQTFCTEVURkKqKiOJrBEf2zSEEFJQUIwQUxFiZFSFGKFnhBBCChOKEWIaHp9PjumGVLRpUp4RihFCCCkkKEaIaYiqCACMDmUe7QXSPSM0sBJCSCFBMUJMQ5pXh4agxOPTXp+VEUIIKUwoRohplATUj/UCQHiEy/IIIaQQoRghpuEv0yZGIiFWRgghpBChGCGmURJQnzECAJHRZGWEOSOEEFJQUIwQ05CekQG1bRomsBJCSCFCMUJMo7i8FEDCwKqGCHNGCCGkIKEYIaaRqoyoa9OEZQIrKyOEEFJIaBIj69evh6IoYy579uyZ8vrPPPPMhOsrioJHH30064MT+1Os1cDK0V5CCClIvFpvsGvXLlx88cXy39FodMrrfuADH0BRUZH8d01NDbZv347f/e53Wh+WOJDiQCpnRA0y9IxihBBCCgrNYiQajaKtrU3VdXt6esb8+0Mf+hCGh4cpRgoEkcCqtk2TGu1lm4YQQgoJzZ6RRYsWoaWlBfv378eGDRswe/Zs1be96aab8Jvf/AbDw5mjwYuKihAIBMZciPOQYkR1ZYShZ4QQUohoEiNbt27FjTfeiLVr1+KWW27BvHnzsHnzZpQnjYqZOOOMM7Bs2TLcd99901731ltvRX9/v7y0tLRoOSaxCVoNrNIzwpwRQggpKDSJkSeeeAIPPvggdu7ciSeffBLr1q1DZWUlrrnmmmlve9NNN2HHjh3Ytm3btNe98847EQwG5aWxsVHLMYlNkJUR1XHw9IwQQkghotkzkk5fXx/27duHhQsXZrxeaWkpPvShD+HrX/+6qvsNh8MIh8PZHI3YAM1ihJ4RQggpSLLKGSkrK8OCBQvQ2tqa8Xof/OAH4ff7sWHDhmwejjgM0aYJqY2DZ2WEEEIKEk1i5K677sL555+P5uZmrF69Gps2bUIsFsPGjRsBAPfffz/uuOOOCbe76aab8NBDD6G7u9uYUxPb43K54C9LJrCqFCMy9IyeEUIIKSg0tWmampqwceNG1NTUoKOjA88//zxWrVqFzs5OAMCcOXMQj8fH3Gbx4sU477zzcMkllxh3amJ7ikpL4HYntO7IYObpKYGojHh9Pri9HsSjMdPORwghxD5oEiPXXXddxs+vWbNmwsf27dsHl8ul7VTE8ZQkWzTRSATR5Dbe6YiMpK7n8/sxGlUnYgghhDgb7qYhpuBPmldHVZpXASAaDsvKGn0jhBBSOFCMEFMo0WheFTBrhBBCCg+KEWIKxQERBa++MgKkxntZGSGEkMKBYoSYgtzYqzIKXiB8Iz4/s0YIIaRQoBghpiA39mps04TZpiGEkIKDYoSYgqyMaGzTpILPWBkhuackGMC//mED1n7mE1YfhZCCgmKEmIKsjGhs08jKCD0jxALmrlyOmYsW4Iwr3mv1UQgpKChGiCnIvTQqN/YKIqGEZ4QGVmIFFfW1AIBgbQ3cHo/FpyGkcKAYIaYgxYjeygg9I8QCgrU1AAC3xyP/TggxH4oRYgpiSZ5+zwjFCMk9gbpa+ffKhhkWnoSQwoJihJiCrIzonaahgZVYQMUYMVJv4UkIKSwoRogppMSIxsoIPSPEQgJ1qdYMKyOE5A6KEWIKsk3DnBHiICrq6lJ/Z2WEkJxBMUJMQVRGQlorI/SMEItwud0or6mS/2ZlhJDcQTFCTKFYx9ZeIC0Onp4RkmPKqyrh8Xrlv+kZISR3UIwQw/H4fHK3jNatvWFWRohFBNPMqwArI4TkEooRYjiiKgIAo0PDmm4rKyP0jJAcI8yrPa3HASQyRzw+n5VHIqRgoBghhiPNq0NDUOJxTbdlZYRYhRjrPf72O1IUV8yoy3QTQohBUIwQwykJ6BvrBYBIKDlN46dnhOQWEXjW396J3uNtANiqISRXUIwQw/GX6RcjDD0jViEqI30dneg93g6AJlZCcgXFCDGckoC+jBEgbbSXnhGSY4JJz0h/Ryd625KVkRkUI4TkAooRYjh699IAQFiO9lKMkNwSTAaeDXR2pVVG2KYhJBd4p78KIdooLi8FoH1jL5DyjNDASnKNqIz0tXeivJqVEUJyCcUIMZxUZUR7m4aeEWIFLpcLgZqEGBno6ERvVQUAVkYIyRUUI8RwirMwsArPiMfrhcfrRSwaNfRshExGWVUlPL7Er8P+ri4UHw8AoIGVkFxBzwgxnOJAKmdEK6IyAjD4jOSOQG2yKtLVjXg0Jkd7y6oqWaUjJAdQjBDDEQmseto08WgMsUiiGkLfCMkVFfXJjJGOTgCJn10hpivoGyHEdChGiOFIMaKjMgKk+0YoRkhuCNYmxUhnl/yYmKipom+EENOhGCGGk42BFQAio4nx3qISlsdJbhB7aQY6UmKkT6awsjJCiNlQjBDDkZURHQZWIGViZWWE5IqK+kTGSF9Hh/yYqIxUsDJCiOlQjBDDyVaMhJk1QnKMNLB2pLdpWBkhJFdQjBDDEW2akI44eAByYyorIyRXyL007Z3yY0xhJSR3UIwQQ3G5XPCXJRNYdYqRMPfTkBwjPCP9nWlihPtpCMkZFCPEUIpKS+B2J36sRgaHdd2H9Iz4aWAluSGYrIz0T1YZoRghxHQoRoihlCRbNNFIBNHkVIxWhGeEYVMkF5RVVsDr8wFILMkTCDFSEgzAX1pqydkIKRQoRoih+JPm1VGd5lUg5RmhgZXkgkCyKjLU0ztm/UA4FMJwfz8AmlgJMRuKEWIoJVmaV4G00DN6RkgOkObVjs4Jn6OJlZDcQDFCDKU4IKLgs6mMcLSX5I5gXWpb73g43ktIbqAYIYYiN/bqjIIH0uPg6Rkh5hOsE4FnrIwQYhUUI8RQ5MbeLNo0kRA9IyR3iMpIf1rgmSBVGaEYIcRMKEaIoaT20mRfGWHOCMkFIn21P2NlhG0aQsyEYoQYSrYbewHupiG5ReylmVyMsDJCSC6gGCGGIsWIzo29QFplhJ4RkgMm20sjkMvy8iD4bM3HrsfKd19k9TEImRSv1Qcg+YUxlRHupiG5o6JejPZ2TPhcX1tCjPhLS1ASDCKUzB1xGlWzGnDZv3wao8PD2P7kX6EoitVHImQMrIwQQzHCMxJhzgjJESXBILxFRQCAgc7uCZ+PhsMY6Ep83Mm+kbLKCgCAv7Q0L6o8JP+gGCGGIisjWYWecZqG5AZRFRnq7UM0HJ70Or1tzh/v9SdH7gGgrnm2hSchZHIoRoihpMRIFpUR7qYhOSI11jvRvCoQrRonL8wrLkvt1qmlGCE2hGKEGIps0xgQB8/KCDGbQG1yW28GMZIP473+NDHCygixIxQjxFBEZSSU1aI8VkZIbhBtmskCzwT5MN7rL021aWrnUIwQ+0ExQgyl2ICtvWHmjJAcIcd6O/O7MlJczsoIsTcUI8QwPD4ffP5ENSObrb0iDt7tdstJB0LMQASe9bVnEiN5UBlJM7DWNDXC7fFYeBpCJkIxQgxDVEUAYHRoWPf9REZH5d9ZHSFmEhRR8J3Tt2kqZtTl5Exm4C9NVUY8Pi+qZjZYeBpCJkIxQgxDmleHhqDE47rvJx6LyTHLohL6Roh5BIVnJENlpK+9A/F4HD6/H+XVVbk6mqGkG1gBTtQQ+0ExQgyjJJD9WK+AvhGSC4JimiaDZyQejWEgWTlxqm8kvWoJ0DdC7IcmMbJ+/XooijLmsmfPnoy3qaiowA9+8AMcO3YMIyMj2Lt3L97znvdkdWhiT0Rf2ggxInwjHO8lZlEcKJcTW5mmaYB0E6szfSOiTdPXnoi8pxghdkPzbppdu3bh4osvlv+ORqNTXtfn8+Gpp55Ce3s7rr76arS0tKC5uRm9vb26DkvsTUkg+4wRAbNGiNlU1CWqIsP9/Yim+ZQmo/d4G5qXn+zYyoho07Ts2YeK+jqO9xLboVmMRKNRtLW1qbruxz72MVRXV+Pss8+WouXQoUNaH5I4BCP20gi4n4aYTbBu+owRgYyEn+HMyoho0xzdsxcnXXAO6uZSjBB7odkzsmjRIrS0tGD//v3YsGEDZs+e+of68ssvx0svvYR7770Xx48fx86dO3HrrbfC7c78sEVFRQgEAmMuxP6ILINsNvYKInI/DQ2sxBxSYmRqv4ggNd7r0MpIsk1z9M23AABVMxvg8XJpO7EPmsTI1q1bceONN2Lt2rW45ZZbMG/ePGzevBnlyXfE45k/fz6uvvpqeDwerFu3Drfffju+8IUv4Ktf/WrGx7n11lvR398vLy0tLVqOSSwiVRkxrk1DAysxCzV7aQR9bQmvhVM33oo2TeehIxgZGoLb40HN7EaLT0VICk1i5IknnsCDDz6InTt34sknn8S6detQWVmJa665ZvI7d7vR3t6OT3ziE3jttdfwwAMP4Fvf+hY+9alPZXycO++8E8FgUF4aG/mfxgkUCwOroZURihFiDgFdlRFntmmEGBkdGkbnoaMAaGIl9iKrOl1fXx/27duHhQsXTvr51tZWRCIRxNMyJ/bs2YOZM2fC5/MhEolMertwOIzwFOu8iX0plgZWA0d76RkhJlGhxTMigs/q6+Byu7PK0ck13qIieH0+AMDI8DA6Dh1G00lLaGIltiKrnJGysjIsWLAAra2tk37+hRdewMKFC+FyueTHFi9ejGPHjk0pRIhzESY5I9o0ETlNQ88IMYeAhjZNf0cXYtEoPD4vAjXVZh/NUNIDz0aHhtF5OFEZYfAZsROaxMhdd92F888/H83NzVi9ejU2bdqEWCyGjRs3AgDuv/9+3HHHHfL6P/rRj1BdXY177rkHixYtwrp163Dbbbfh3nvvNfarILZAihED2jThED0jxFwq6hLx7mrEiBKPy+s5zcQqWzTDISjxODoOHQEA1LEyQmyEpjZNU1MTNm7ciJqaGnR0dOD555/HqlWr0JlML5wzZ86YlszRo0fx7ne/G3fffTd27NiBlpYW3HPPPfiP//gPY78KYguMNLAKz4iPlRFiEmJjr5o2DZAIPqua2YDKhhk4vPNNM49mKGKSZnQ4sS+q49BhAOB4L7EVmsTIddddl/Hza9asmfCxLVu2YPXq1dpORRyJrIwY6BmhgZWYQXF5GfylJQCAgQxR8Ok41cQq/l+OJv9fdiYrI5UNM+Ar9kvhT4iVcDcNMQwjxUiEo73ERETGSGhgULYEpyMVCe/MNs1IsjIy3NeP4b5+AEDN7CbLzkVIOhQjxDBEmyZkRBx8iAZWYh6pFo26qgjg4MpIaWqsVyB9IzSxEptAMUIMweVypYxyRlZGONpLTKCiXn3GiEBWRhwWfJaeMSKQvhGKEWITKEaIIRSVlsiY/5AhnhGGnhHzCNbqESPOrIz4hWckbcpNjvdyoobYBIoRYgglyRZNNBKZdgOqGugZIWYSrFcfeCboTS4IDdTVwO31mHIuMxBtmpG0ykgn2zTEZlCMEEPwj3PsZ0vKM0IxQownKDwjKidpAGCouxfRSARut1tmlDgBf5mojExs0zD4jNgFihFiCCUGmleB9MoIDay5pKapER9c/2Xc+fIzeM8/Z94h5WSC9cnAs3b1YkRRFPS1JXwjTlqY5y8fmzMCpAyswdqaMQmthFgFd0gTQygOiCh4YyojkWSrp4gG1pwwY/5cXHTzDTjlPZfA7Um0IC6++QbsfWEL3nn1DWsPZwKpyoj6Ng2QMLHWNDU6arxXtmnSqpajQ8MY6OpGoKYadc2zcfTNvVYdjxAArIwQgzByYy/AOPhc0XjiYtzwX3fgiw9vxGmXrYXb48GezS9i59PPAgA+uP7L8BYVWXxK45F7ado7NN3OiSbWydo0ANBxMNmqoYmV2ABWRoghpDb2GtWm4TSNmcxdsQwXf/JGnHje2fJjO556Bk/fdz+OvrkXxYFyzFl2EurnNeOST30Mj3/vxxae1lj8paVSPGsxsALODD5L7aYZK0Y6Dx/F/NNW0jdCbAErI8QQ5F4aowysaZ6R9K3P+UjTSUtw2+O/x8q1F5v+WGVVlfjUz76Pz2z4KU4872zEYzG8+ugT+M/3/wPu//xtslw/MjCIP3zrOwCANR/9P5i5eKHpZ8sVoioyMjiEcCik6bZOrIzIquW4/5tcmEfsBMUIMQQjo+CBlIEVyH8T68lrzkdN0yysuPRC0x9r+cVrsGjV6YhGItj6+0fw/973Ifzvrd9A2/4DE66766/PYvuTf4XH68W1/36b9JI4nYo67RkjAkdXRobGV0Y43kvsA8UIMQQpRgzY2AtgzPIunz+/xYh4YSurrjT9sSoaElMkW3//CB74tzvRdeRoxutvuuM7GO7vx+yTT8T5119r+vlygdhLo9W8CjizMpJq04yvjHC8l9gHihFiCFKMGGRgVRRFCpJ8N7GKF7ZAdbXpjyWSR/tUGjcHurrxx7u+DwB496dvRk1To2lnyxXSvKqrMpIMPquphsfnM/RcZuGfZDcNkEphLausQGlFMOfnIiQdihFiCNIzYtBoL5DyjeT7eK/YdVJWVWn6Y4nk0QENxs2XH3oU+7ZsQ1FJMT64/stmHS1niMAyPWJkuK9fTno5YUeN2+OR/3/Gt1AjI6PoTeamsDpCrIZihBhCyjNiTJsGKJzgM1EZKausMN2XIfI1+jS+EP/uG/8P4dAIFq06HWde+T4zjpYzgnKsV7sYAdJbNfYXI+mBZuMrI0BqvJcmVmI1FCPEEIw2sAKFEQlfWhEcU/kpq6ww9fGCOs2b3UeP4Ykf/BQAcPm/fgaBpKhxItl4RgCgry3R4nKCb0S0aKLhMGLR6ITPy4V5rIwQi6EYIYaQGu01sjKS/56R8S9oZdVVpj2Wx+tFoCbhS9HTotj86wdweNebKAkG8IHbvmD08XKGFCMaA88EYmGeI8TIFJM0Ai7MI3aBYoQYgtEGVqAwPCPjX9DKTfSNCCESi0Qx3Nun+fbxWAwPrL8DsUgUyy9Zg2UXXWD0EXNCtpURI8d73R6PqUbY6f5fdiTHe1kZIVbDBFZiCKnRXuPESMozks9iZOwLWrmJlRFhXu3v7ISiKLruo3Xffvz1F7/CJZ/4KD7wlX/F29teQ6h/wMhjmkpRSbH8WdVTHQJSnpFsl+UVB8rxpYc3IlhXi4GubvS2taOvrR19bR3oPd6O3rY29B1vR29bB7qPtuj6nk01SSOgZ4TYBYoRkjUen09mgRi1tRdIq4zksYF1QmXExKyRlF9EX0VA8Jef/A9WXHIh6uc149JP3YSH//O7BpwuNwSSo82jw8NTvkBPh1EG1sYTFsvvSaCmGoGaasw+6YRJr7v7mc34+T9/UfNjTNem6Tp6DPFYDMXlZQjUVGOgq1vzYxBiBBQjJGtKkntpgKl/6emhEDwjVTMTYiQej8PtdqPcxKwRvebV8UTDYfz53p/hw9/+JuaessyIo+WMivrsBZnIaKmor8vqLOL7cfCNnXjw9v9E5Yx6VDTUo7KhPvH3GfWonjUTtXOasODMU3U9xnRtmlgkgp7WNtQ0zUJt82yKEWIZFCMka/xpG3uVeNyw+5XL8vLYM1KRfHfdeegI6uc1m5o1YpQYAYD2ZHm/amZD1veVS8RoczbPgRgJLq+ugsfrnXRKRctZuo+1onXf22jd9/aE65RWBHH7839GcVkZ3F4P4tGYpseYrk0DAJ2HDqOmaRbq5szGgde2a7p/QoyCBlaSNSUB48d6gfRlefkrRipnJCojR998C4C5BlYjxUhP63EAifaCk3JggvX6A88EQ719iEYiAFKmYF1nUfH9CKWtVygNak9Jna5NAwAdHO8lNoBihGSNf4qtoNkSyfOcEZfLhYoZiRfHI0KMmGlgzTLsK51Q/4D8fjupOmJEZQQABpKTOIGkoNB1luT3I1MarhKPS4NwSTCg+TGKk2JkZDhTZYTjvcR6KEZI1gjPiJEZI0B6ZcQ577y1UF5TDa/Ph3gshta9iRK9uWIkNU1jBKI64igxYoBnJP32QlDoQQTHTff9GO7vBwBd+2PEG4XRDG8UuDCP2AGKEZI1ZuylAVKjvfnqGRGTNP2dXfKdei48I30GVEYAoOdYUozMcpAYqTVGkA0kbx/MqjKiThgNZ1EZUdWmOZRs08xugsvl0vwYhBgBxQjJmuLyZCnYwMAzAAiLaRp/flZGxGho7/E2DPb0Akjup/Eav5/G7fVIf8OAzrCv8TixMhIwqFUlBF1WYkRlyyjUp78yoqZN03OsFbFIFEUlxVlPCBGiF4oRkjWpyoixbRrhGclXA6uojPQeb8dwXz/iscSkRFmF8ftp0tNXh5LCJ1t6jrUCACpn2j8WXVBhkIlXpLcGde7o8fr9stIxXRKsqIzoMrCWJts0GSoj8VgM3S3HALBVQ6yDYoRkjRQjhldG8tvAml4ZUeJxDCUj2strjPeNBOsS73gHurp0p6+Op6c1Ef7llDaNrzhNAGRrYO3IrjIivCaRkdFpRfywqIzoadOIquU05vKOQ4yFJ9ZCMUKyxoyNvUBaHHxJvrZpUpURALJiUV5lhhhJvPgZ5RcBnNemEX6RcGgk659V4fMI6DSwprwr07fMhBgp0dWmSVZGMrRpgNSOGk7UEKugGCFZk9pLY/Q0TTL0zILKyPJLL8Ttz/8ZK959kWmPkV4ZAYDB7h4A5phYxTv4AYMmaYCUgbWivg5uj/E+F6NJ382TLeI+KrKsjKjx74SyatMIA2tm8SXHe7mjJifUzmnCnGUnWX0MW0ExQrLGjI29gHWekYoZdbjm325FaUUQKy690LTHGV8ZESZWM8Z7jZ6kARIvpNFwGB6v1xHGx8YTFgNILYfLhvQUVpdb+69Rmfmiol00nIWBVUzTjAxOUxlhmyan3Pzju/FP9/8ElVkuW8wnKEZI1phlYLXKM3LtN26T2Sl1c+eY8hhuj0eaH8dXRswQI9K4adAkDQAoiiKFlBN8I80rlgIADm7flfV9Dfb0Ih6Lwe3x6Pp+BWpExoiaykiyTaPRM+JyueQbhdFhdZWRmtmNjqhyORmXy4Xqxlnw+LyYd+oKq49jGyhGSNaY5RkJW+AZWXX1FVhyziq5b6RuzmxTsheCdbVwezyIRiIYTC4nGzJRjMgWhYGVESDVqnHCRE3z8oQYOWSAGFHicblUTk/wmZZofr2VkaKSEvn36RZY9h5vQ2R0FF6fzxHfSyfjLyuFO1lNm7P8ZItPYx8oRkjWmG1gzVVlpGpWA973r58BADz23R8hGonAV+w35Zez2Nbb19Yhp1tk1ogZnhGDwr7G03PcGSbWQE01appmIR6P4/DO3YbcpxzvrdPeogqoiIIXyNFejWJEtGjisZhcOjkViqKg60gLAPpGzCa9wtW8jGJEQDFCska0aUIGx8GLX6DeoiLTS8culwvX/vtXUFxWhv2vvo5nf7kRnckFYvVzmw1/POkXaWuTH5NtGjPEiMmVEbu3aUSLpm3/gWmrBGoZyCISPqgyCh5IhZ5pbdNo9XLRN5IbSgKp72PjiYvh8fksPI19oBghWeFyuVKR04a3aVLv5sxOYT372g9g0VmnY3Q4hN9+9VtQFEUaHc3wjchJmtY0MWKSgdXt9chqi+GVkeR4b7XNKyMpv8hOw+6zr6MDgL6sEbVR8EBqN43X5xvTepmO1CSNOvGV64V5Xr+/IP0p6aLSW1SExhMWWXga+0AxQrKiqLRE9j9DBouR6GiaGDHRN1Izuwnv/ZdPAwD+dPe96DqaKFd3HDwEAKifZ2JlJGkABczzjARqquF2uxGLRjHU3WvofacqIzMNvV+jEX6Rw9uNadEAaZURjSmsbo82cRgOjSAaiQDQFnymZi9NOiJrJBeVkaqZDbj10d/iCw/+suD24aRXRoDUz2ahQzFCsqIk2aKJRiJjxINRjA6HAJjnG3G5XPjQ7V+Bv7QEf9/6Cl787R/k59pFZcSEX87jM0aAVJumtCJo6H4a4RcZ6DQufVUgDawN9jU9ur0ezD75RADGVkb0bu4t1yEO9QSfaRYjOaqMeIuKcMPdd6CyYQYaFs6X24sLhfGCkibWBBQjJCv85dOvKM8GmcJqkhg57/prMf+0lRgZGsJvv/6tMS/WHQfMa9NUTFIZGbOfprLSsMeSfhEVLQGt9La1Ix6Po6ik2JQpICOYtXghikqKMdzfb0jGiKBfbu7VZmAVlZTBrh7V4jAVfKa+MiLSV9V6RtrefgfxWAy1s5swd+Vy1Y+jlQ985V+lOASAmqZZpj2WHSkOJt7AiUmqZooRABQjJEtKTDKvCszMGqmbOwfr/vlTAIA/fvv78l2+oD3Zpqma2YCiEmMfX4QdpVdGFEVJ7aeprjTsseQkTdLjYCSxSESmiNq1OiJbNDveNLQypLcyIv0iGvw7esZ7tVZGhnr7sPUPfwQAvO8L/6T6cbSw6uorcNYH3od4LIbetoQQr25qNOWx7IpI0t23ZRvi8ThqmhptK+RzCcUIyYrigIiCN6sykmj9+IqN9Yy43G5c982vwVfsx94XtmDLgw9PuM5wX78UB7UGjjt6i4rkFt10MQKkB59VG/Z4ZlZGgLQdNTadqBHm1UMGtmiAlLgL1NRo8j2k0lfVfz9COsZ7pRiZZi9NOn/+4X0YHQ5h7splWHbRBapvp4bZS0/Clbd+HgDw+Pd/ij3PvQig8CojIlCx59hxtL9zEAAwhyO+FCMkO7SWgrUSNqlN864b/wHNK5YiNDCIB9bfOeX1RFm/3sBWTUWyKhIOjch3vILUsrxKwx5PtAX6stxUOxV2H++VYWc7jDOvAsBAVzfi8Tg8Pi9KKytU307LWK9AekY07KdJRcGr/7850NmFZ3+5EQCw7rO3GOZdKq+uwo133wFvURF2/OVv+Ot//1IaxWsKrDIipmlC/QM4vPNNAMCc5dxTQzFCsqI4qfJHTGrTiP00RQZWRurnNWPtp28GADz8H3fLcvFkiFZNnYETNZOZVwVmLMsTlZEBs8SIjbf3lldXoXZOEwDgkEFhZ4J4NCbFo5ZWTUAsLdRQGdHTppEbezXmqvztF7/GQFc36uc146wPXK7ptpPh9njw4btuR2XDDLQfOITffPV2AEDX0WMACrEykhIjh3Yk0oA5UUMxQrJE7qUx28BqoGfjtPe9B96iIux9YQu2PfxYxuuaURlJBZ5NFEEya6TGuB6y8IyYXRmptmFlRJgDj7/9juG7k4DU1l0tJlZ9bRrtwWd62jTi+k/9+OcAgHf/48dlXole1n32Fiw88zSMDA3hfz73ZSmOupOVkepCEyOiMjIwIKt1c5aepGvhYj5R2F89yRqzouAFIvjMSAOreDF4e9vr01633YSJGjWVkfIqA8VIvfZ34lqQbZqZ9ssamWNSi0agx8SqJ5pfBJ9p8oxoDD1L56UHH0LHoSMI1FTjghuu03x7wfJLL8Saj/4fAMBvv/YttCU9EgDQdbQVAFBRX2e4J8zOCM/IcP9AIhF4eBjF5WWm5Bk5CYoRkhVSjJjwrhMwZ7RXONfFC38mRPCZsWJk4livwOjNvelbZftMmKYBUm0asxasebxeXPHFz2Hx6jM033auSeZVgRjPFAJDDXoqI8O6Rnu1e0YE8WgMj93zIwAJf5UwXGthxoJ5+NDtXwEAPPPzDdjx1DNjPh/q75fG3Gqbh+YZiaiMjAwMIh6L4cjutwBwTw3FCMmKeackVmCr2T6qh3DI+NFeUXVQI0Y6j7QgHouhuKxMV+z3ZIgleZNVRow2sOoJ2NKKECNllRWa4srVcsJ5q3H+h6/Fdd/6uqb4cLfHg9lLE8ZA8yojImtEXWXE5XIhUCOW5OkwsGqpjIgMII1tGsGOp57Boe274C8txaW33KTptsXlZbjx7jvhLy3F37e8gse+9+NJryd8I4U03is8I6LadTjpGyn08DOKEaKbBaefgqaTliAcGsHrjz9lymPIaRoD4+BlZaRnejESi0TQ3ZIoJxtVHVFTGTHKwFohzJJd3YanrwpGh4blL1YzJmoq6hN+jGBdrabqSMPC+fCXliA0MIi2/QcMPxeQ2tyrNkW0tLICHp8XQOJ7opZU6Flu2jSCR+++FwBw1lWXq/759xX78Q93/hvq5zWjp/U4fvXFr8kwv/GkJmoKwzfi8flkZlEoWU0+tCMxUVPo4WcUI0Q3F3wk0Uve9vCfJoyoGoWImDe0MqKhTQOkJmqM2t4rA89aj0/4nGzTGGRgTbUEzKlcCcwc701/oT/98nWqbyfyRQ7v3G2aEBPPqxBM0yG+H4PdPYhFo6ofR07T6DCwjmQhRt559Q3sfmYzPF4v1n32lmmvP2vJInzuN7/Aye86F9FwGPf/y22y2jcZ3XKipjAqIyXJ9NV4PC5Tqw8np7waFs43pbLoFChGiC5qm2fj5DXnAQCe2/Bb0x4nLEPPjBEjRSUl8p3JYJc6MSK3987LvjLiLy2VPePJKiPiF3dp0Jj9NGLKw3QxYuJ4b7pfYemF58tx8ukwK18kHWEKVlsZSZlXtZmJUzkjAdVTF8LPNZplBtCfvvtDxGMxLL/4XVPGxLtcLpz/4Q/hs/97HxoWzENfewd+dsvncWT3noz3nWrTFIZnRFS2RgYHpUDu7+hET+vxRFvx5BOsPJ6lUIwQXVzw4Q8BAHY/s1muHjeDiMGeEVFxCIdGEA6FVN3GyIV5YpIm1D8waS/f6P00esySejBzvDdQmxIjPr8fKy69UNXtzDavAilTsFrPiLie1syX0MCA/HuJSjEm2jTZVEYAoO2dg3h506MAgMs+/+kJnw/UVOPmH/0XrvjiZ+EtKsKuZ57Dd676MN5++dVp79tpwWdnXXU5Lv7EjbpvL4S0aLsJUuFnhduqoRghmimrrJDl8r8l0xrNIpXAaoxnRBhD1bZoAKDjgHFtmkwZI8D4/TTZt2rkHpRctWnMqIwko/EPvL4DAHCGilZNWWWF9DiInrwZDHQmfB8+v19VBkhAVkbU+0WAxHSLmIpRM97r9fvh8Sa8KdlWRoBETHw4NIJ5pyzH0gtTMfEnnn8OvvD7X2HJOasQDo3gwX//T/zin78kf4anQ1ZGGu3vGfF4vbjqK/8X7/nMJ1ExQ9tyREGpTF8dO314aDvDzzSJkfXr10NRlDGXPXumLsPdcMMNE64fUvlulNiXVR98P4pKinHkzbfwzivTZ3VkgxjtNWpRndj5osa8KhCr1asbZ8Lj82X1+JkyRgRGjvfmTIwkv55KE8RIebJN8+wvNyIei2HeqStQM7sp423Ero/2A4dkYJgZRMNh2UJRM20lKyMaMkYEwzL4bHoxIsZ6ASA8nP3v3P6OTjz7q8Qbj/d+7hb4S0tx5W1fwMfv/TYCNdVoeWsf7r72Rrz0u02a7re39TjisRj8pSWGBv2ZQVXjTGk+1jPqDIxNX01H+EYK2cSquTKya9cuNDQ0yMu5556b8fp9fX1jrt/cXNjBLk7H4/Ph3OuuBgA8Z3JVBDDeM6LVvAokfhGPDA3B7fGgdnZ25eRMkzQCU8RIu3MNrGKXS8uevdj30jYAwOmXvyfjbZpXJt5hHjSxRSNIjfeqESP6lxaG+tQvy/On7Ywyyrz7zM83YLC7B/XzmnHb4w/K3wPP/nIj7vmHj6M9WUHUQiwalf8X7N6qEWsFAKC0Qv0uonTS01fTObpnL2KRKIJ1tbbdfm02msVINBpFW1ubvHR1Zf5PpSjKmOu3t0/9S5jYn1PXXYJgXS1629rxxp+fNv3xjM4Z0SNGgDQTa5atmpQYmboyYmTWSM6maVpbk49XK9sDRuAvK5UtuoGubrzySCK+/7TL1mbclJsL86pAmFGDKkys4h21VgMroC2FVVRGshnrHc/o0DCe+kkiJr68ugr9nV346Sc/h0fu+h5ikYju+3XKeG9tWjWuTMNixHSmqoxERkZx7O9vAyhc34hmMbJo0SK0tLRg//792LBhA2bPzmzqKy8vx8GDB3H48GE89NBDOOkkbid0Mucnx3mf//UDiEcnzw4wkojRnpGa7MRIfZYTNak2zfSVkbLqyqwey+3xyBaH2WJksKsHkZFRuN1uVCS/RiMQUyojg0OIjIxi51+fQ2hgEDVNszDvtJWT3sbldmPOsmTYWS4qI+3qg8+yaZtpGe/1myBGAOClBx7Ca3/6M7Y9/Bi+c9WHsffFrVnfp8jxsXvwWXplpKwq28rIxMTqwzsKu1WjSYxs3boVN954I9auXYtbbrkF8+bNw+bNm1FePrm7e+/evfjYxz6GK664Atdffz3cbjdefPFFNDZm/qErKipCIBAYcyHWs2jVGZi1eCFGh4ex5feP5OQxTTOwqhzrFciJmiyDz9RURuSyvCzbNOXVVTJ9dTBD1oNRmDHeKyoJIiAsOjqK7cmK3FRG1oaF81BcVoaRoSEcf9ucsLN0xI6ZgIo2jRBXeto00jOipk0jJ2mM3RkVi0bx6y//G37z1ds1C/qpcEplpCatRau7TSP30kz0MYkqXqHGwmsSI0888QQefPBB7Ny5E08++STWrVuHyspKXHPNNZNef8uWLfjVr36F7du347nnnsMHPvABdHR04JOf/GTGx7n11lvR398vLy0tLVqOSUzigo8kxnlf3vTohDKjWUgDq9FtGo0vzkZN1FTM0GBgzXJZnngXPtjVAyUez+q+1CDEiJHjvUKMDKallb7yx8cBAMsvXTOpsVm0aI7s3JOTr1sIi4ppxIi/rBT+0kSolR4Da0jDfppUxoixlREzcErw2Zg2jc4WavpemvEcSsbCN510giEZQ04jq9Hevr4+7Nu3DwsXLlR1/Wg0itdff33a6995550IBoPyMl0lhZjPjPlzceJ5ZyMej2Pzhgdy9rjhkPUGVsCYykhJMChfjHrbpl5alxIjlbofC0iJEbMW5I2nt9X4iRpZSUjzWBx4bTs6jxxFcVkZll50wYTbiOTVgzvMb9EAqcyQwDRtGvH9GBkckl4oLcg2jSoDa7JNo3MvTS5xQmXE7fGgOu18ZRp2BKUjxMjwJG/mOg8dwXBfP3zFfsxarO41NZ/ISoyUlZVhwYIFaE2a16Z9MLcby5Ytm/b64XAYAwMDYy7EWs5Phpzt+utz8pdHLjCtMtKtLeeh83BivLesskK3eU0syBvs7pEx95MxZFCbJlif3EtjcuCZoNvENs148fjqI4nqyGStmrkrlgEADm0337wKpBtYM1dGgrXZmYlFZURNnokRe2lyhcgaCdbXwVtUZPFpJqeyoR7etLH+Ur0G1immaQSH5Ihv4eWNaBIjd911F84//3w0Nzdj9erV2LRpE2KxGDZuTIx43n///bjjjjvk9b/2ta/hkksuwbx583DKKadgw4YNaG5uxn333WfsV0FMpby6Cqe9by0A4Nn7zR/nTUd4Rjw+ryGlSy0be8ecIzQi2xB6J2rUjPWmny1bA6t48esz2bwqMGO8d6rpE9GqWXjW6WMCqEqCQdTPS3x/xDZUs+lTaWCV5lUdkzRAuoFVfWVEBKXZmaGe3sTovNttymi4EaSbVwH96cglUySwCoSJdU4B+kY0iZGmpiZs3LgRe/fuxQMPPICuri6sWrUKncn+55w5czBzZmrHQFVVFX72s59hz549eOyxxxAMBnH22WdnDEoj9uPsa66Ez+/HoR27cfCNHTl97EhaOTvb6khJMCBDiwa7ezXfXk7U6GzVpCZpJi7IS0eIkdJgMKsx2VRlJEdixMzKyLgNt90trdj/yutwu9047bK18uPNyxNTNB2HjqhOAc0W4f/wl5bKisRkBHRGwQukZ0TNaK/wjDigTQOk+0bs2aqpaUqIESEkSyv1tWmEkJxSjOwUYqTwpk41iZHrrrsOjY2NKC4uxuzZs3HdddfhnXfekZ9fs2YNPvrRj8p/f/7zn8fcuXNRXFyMmTNn4rLLLsMbb7xh2OGJ+XiLinD2h64CkJuQs/HEolG53TRb34hoe4QGBnXlIqR8I/p21KitjIT6B+TXrNcoBwAVySV5uauMJNqvVTNnZMwA0UL5uGmadF55OJE5kr7JV+aLbM9NVQRIVM1EBUIIwMnQuyRPkL4sbzqc1KYB7B8LLyojQizoadW6XC4pEqcWI4nVBfXzmlUl7eYT3E1DMnLqe9+NQE01uo+1Ysdf/mbJGSJJf0W2lRG95lVBtsFnaqLggbH7abIRI4EcLckT9LV3IB6LwVtUJEVEtogleQOTvIBvf+qvCIdGMGP+XMxemngnKcyrh3LUohHIFNYMwWfZLi3UY2B1QpsGsP/CvNo5iXMdTu458peWava3+MtK4fYkWs2T5YwAie+x+D1TaNURihGSETHOu/nXD8htsrkmIiLhs9xPY5wY0dumUVcZAVIm1kAW+zoqZMBWbqZp4tEY+toTj2VU7398zkg6o0PD2PXXZwEAZ1yxDi6XS/bac1kZAdRFwqcqI/oqVSKbwuf3w+vPnLvj1DZNtV3bNMmx3qN79sqqpVYTq0hfjYyMIhoOT3m9QwUafkYxQqZkyTmr0LBwPkYGh/DyH/5o2TlSkfDZBZ9lK0baDyayRmrnNMl3OFpQWxkB0kysOrNG3B6P/HpzVRkBUuO9RvhGigPl8PlFFPzk37NtyVbNyrUXY9YJi1ASKMfocAitf9+f9eNrQbReMo33pjwj+r4fo0PDqRfCaaojzmvT2He81+VyyYwRMX4LaG/VTDdJI5C+EYoRQhKc938+CADYuumPlpZ7U5HwBlVGNGzsTae3tQ2RkVF4fT5UzZo5/Q3ScLlcaYFn01dGsl2WV15dBbfHg3gsZlhSphqMNLGKqkhoYHDKUei/b30FvW3tKKuswHs+kwhTPLJ7T86reKk2TYbKiAF7gtQGn5kVB28WXTYOPgvW18JX7EcsEkVP6/FUC1VzZUSkr2YWI6LFWGhJrBQjZFKqZjZgyTmrAAAvbPy9pWcJG5Q1km1lRFEUdCTzRrRO1JRXV8Hr8yEej6sKIct2WZ5cVd/VnZMUUkG3geO9skWTwfCpxON47dEnAAAnnnc2gNy3aIBUtaNiCgOr1++XkxR6DayAet+I9IwYHAdvFmIsvLi8THeOj1mIFk33sVbEYzEM9fYC0NGmSX7/J0tfTefYvrcRGRlFaUUQtc36zPJOhGKETMpZV10Ot9uNfVu2oevIUUvPYrhnRONemnSkb0TjwjzhFxno6FK1YHAgy6yRYHKSxuwFeeMxtDKSNIMOTBNQ90oyAE2Qa/MqkLafZgoDazBpxI2Mjma1SkHteG9xmXPi4AEgGg6jty1RMbTbwjzZokn+Hhzu1demKZXpqxP30qQTj8Zw9M23ABRW+BnFCJmA2+PBmVdeBgDY8uDDFp/GPpURIOUb0bqjRotfBACGkjkoAZ1tmmwnN/RiZPCZMO9OJx7b3jmIw7velP+2ojKSCj6bvDIizatZfj/ksrw8a9MA9vWNiLHeriOJ8w3rbNMUBzMHnqWTSmItnFYNxQiZwEkXnIOK+joMdHVj19PPWn0cGXzmm2aCYDqMECMdB/RN1MhJmrbp/SJAytei18Cazar6bEhljRghRpKVERVtDVEd6TxyNKceGcGAjISfvDIizatZtGgAdSmsbq9H/l8ZcZAYsevCPCFGOg8nKiN62zQy8GyaNg2QmqgpJBOr/nhHkres+uD7AQDbHnpUuvetRFRGfCVZipGk/0Lrxt502nWmsKbGetVVRrJdlifFSHtuxnoF4usrCZSjOFA+bX88E5nGesez9Q9/RM3sRux7cavux8sGIfpKggH4iv2ytSgwShzK/TQVU1dG/KVl8u+jw87wjADpJlabVUZmjxcjOqdppomCT0fEws9atHDSn6d8hJURMoaqWQ1YcvZZAIAtv7dunDcd8R8xmzaN2+OR72S0LslLpyPZpgnW1cpSuBpSbRp1lZFsl+VluwdFL+HQiDy7WAyoF+kZUfE1REdH8ch/3oO3nt+S1WPqJX0T72QTNcFJtg/rQU1lpLg88XMZGRlV5U+yC6JNY7eskZrZiUqN8M6Jyoju0V4VYqT3eBu6j7XC4/PijCveq+lxnArFCBmDNK6+9LLlxlVB2IDR3tLKINxuN+LxuDSg6WFkcEi+oGjxjVTO1FYZEbkaJcGArv00wjMivAy5JLW9V9v483jKk56RqTJG7IYwsU62ME+Iw6zbNCpGe/1J86pTJmkE3Ufs16Ypr65CcXkZ4vG4rNykPCOVmu5LhJ6pNTD/7Re/BgBc8qmPoShL874ToBghErfXgzPfnzCuvmQD46ogEsrewFpenSj5D/f2ZZ1B0aFjR43WNs3IQNp+Gh3VkdSLX+7FiFEmVi1tGjvQnxR+gUlMrEZF86sZ7S0WgWcOSV8ViMpIZUO9IRu6jUC0aHqPt8l9VqJNo3VZntrQM8GWBx9G55GjCNbW4Lzrr9X0WE6EYoRITjr/XGlc3f3X56w+jsQIz0jAAPOqQOuOGrfHI8v0Pa3qxEj6fhqtvhGX2y1fyK2ojBg13qsmZ8RO9GcwsabaNEZ5RqZ+IZSTNIPOEiMDXd0Ih0bg9nhQ1WDc5udsqBGTNIdb5Mdkm6bCnNAzQSwaxRM/+BkAYM1Hr1e1k8jJUIwYwCnvuQSf/Ok9uvv7dmHVB68AALy8yR7GVYERnpEyA8yrgg6NJtZgXS3cHg+ikQgGNbzLT6WwVmo6n1XpqwIjKiMlwYBcRGbF16AHYU6dLPhM+l+Mqoxk8Iz4k3tpRhxkXhXI8d7Z9vCNyEmatJa1aNOUBAOaKjiiMqLF1P3G40+h5a19KAmU46KP36D6dk6EYsQA3v2PH8fi1Wfi1Pe+2+qj6CbduLr1949YfJqxyNCzrNo0xlVG2jUuzBMtmr62DiiKovpxRNaIVpErXgxznb4q6DWgMiKqIsP9/RmXitkJUcEJjDOwjt0TlF1lZLgv8UKoqk3joLFeQWphnj18I+PHeoFEZSOe/H+lpVohPCPThZ6loygKHrvnRwCAc667CpXJlRJaKKuqRMOiBZpvl2soRrIkUFsjX5ScHFCz6qor4Ha7sffFrfLdiV0wIvRMmCGNESOJiZq65jlwuVzTXl9O0rSpa9EI9GaNBGqtmaQRpNo0+qdphBjJJi031wg/yHgDa3l1VcI8HYtlXZkTbZriQPmUP3upNo0DKyMt9hrvFWbadDGixOPy+6C2VePx+aQJVU3OSDpvPb8Fb297DT6/H5f+48c13bZqVgP+9Q8b8PkH/seQ7B8zoRjJkgWnnyL/3rzCmdG9bq+9ElfHEzHAM2JkZaS75RhikSiKSorl8rtMyMqIyrFegd6sEVEZ6bfALwKk2jTBulrZatGK08yrANCf3Dk0PoXVyD1Bwm/gdrtRnPQgjCfVpnFuZcQuEzWTtWmAtIkalf83S5Lpq/F4XJdI/NN3fwgAOOOKdaifp86rVhwox8fv/Q6CtTXweL22r45QjGRJuhipmtmAYH2dhafRx8kXnItgXS36O7uw6xn7GFcFRlRGAgbspRHEozFZPapXsaNGaxS8YFBn1ohRZkm9DPX2YXQ4BCD1tWtFS8aIXZCVkXEGViMrVbFIRD63U0XCO7lN0yXbNNZXRkqCQZkl0j2uWizM5aUqKyPC4zMyOKipVSs4vGM3dj79LNwej9xOnQm314MbvvMtNCycLz9WbcCKBjOhGMmS+UkxIsZFndiqWXX1+wEkjKt2DEmScfBZGViTYqTHmLK/bNWomKhJjfXqrIxoNLAKQWxVZQRIa9XM0pc1Uu7Iykji+S6rqoTH55Mfl5URg/YEhfozm1iduJdGYKf9NLXJsLO+9g4ZaCcYkpURdWKkWEP66lQ8/v2fIB6LYfklazBn2UkZr3v1V7+IxavPxOjwMPZt2QYglXVkVyhGsqC8ugoNC+YBAHY89QwA521ZrG6cicVnnwkA2PoHexlXBWEDpmmMbNMAqR01aiZq9FZGhqQYqdZ0O6PSPrMh2/HeoKyMOEeMDPelzLbp1RGj9wQNT7O5V4gRp4WeAYkWKJAQWtMtAzSbqVo0QMpIrDaFtVSmr+pfj9C2/wBe+WNiB9N7P/ePU15vzceux1lXXY54LIZf/d+vY8/mFwEYsy/KTChGsmD+aSsBAMf2vY03n0t8w+c6zDdy1gcSiat7X9gi+7V2Q3pGiu3hGQG0TdTorowk2zRq+9KCoMWeEQDoTeap6B3vTaWvOkeMACkBGEgzsRotDlPjvVO0aZIJrE6sjERGRqVos7o6MlnGiGCoR1ubRmv66lT8+d77EA2HsfDM0+T0YzrLL70Ql/3LpwEAD/3Hd7HnuRdS/xcpRvIX4Rd555XXcWhHYm1500kn6IrvtoJ046qdElfHIz0jOiORvUVFMnDIsMqIbNNkFiMen0+aMTV7RnQaWFPr6i1s0xzLrjLitMAzgXjO0/fTBGX6qkGVkaQYmSr4zMltGiDdN2KtiVW0adInaQRa2zRa01enovd4G174ze8BAOs+e8uYiarmFUvxD3d8HQDw3K9+ixc2Pggg+/+LuYJiJAuEX2T/K6+j89ARDPX2wVfsx6wliyw+mTpOftd50ri6+2+brT7OlEjPiF9fZUS8mMci0azfmQhEZaR61syMFRuRCxAZGZW/wNQymMwZKQkGxngQMuFyuxGoTbyQWypGWlsB6B/vlQZWp1VGJhnvFQZWo4RVSO6nyVcxYg/fiNzWm6lNk+PKCAA8/bP7MTI4hKaTlmDFpRcCSBh+P3rPf8Dn92P3M5vxyLe/J6/fczwhRgJ1NbZ+o0wxopPSiiBmLV4IAHjn1TcAQFZHmlc4w8S6+upU4qodjasCURlxezyqX5TTKUsaQI0yrwKJrboivKh2ztQ7arQuyEtnzH4aldWR8qpKS9NXBdmksLpcrlRbzWFiRAiOYL35lZEpPSOlzvWMAPYZ75VtmknEiNhMXarSM5KqjOj3jMjH7u3DM/+TWKK39jOfRHl1FT5+73cQqKnGkTffwoYvrR8zQj7Y1YPI6CjcbjcqdE635QKKEZ0Iv8jx/QfkL/1D24UYWWbVsVRT3TQLS85ZhXg8jq2/t2+LBgAio6Py73paNcIAavSLszCxilaN2Akza8kinHDuKpz5/suw6qrLAWj3iwDJ/TTJX3oBleO94kVwsLsn64WA2SDESOWMGXC5tf2aKQkG4E2KzgGHRMELJmvTiCpPtkvyBHI/zVSekXLnekaAtDZNY3Zbn7PBX1oqvT6dRybxjCQFoVoDa2ovjf6N4ek898vfYKCrG3XNs/GFB3+JGfPnovd4G37+T/8X4VBowvWlb6TBvhM19q3Z2Jz5aX4RwaEduwE4Y7z3rCvfBwDY9+LL6G5ptfg0mYlHY4hGIvD6fPAVF2sudRptXhW0HzyM5hVL8f4vfQ7v/9LnUF5dNWUZtOPwEV2PMdjTi2BdrerKiHgR7LOwRSMePxaJwuPzIlhXg762DtW3lVHwff1yU6pTGN+mKausSAkrow2seesZEW0a6yojNUm/yGB3z6S7ZMSbBNViRMdemkyEQyE89ZNf4AO3fQHBulqMDA3hvk9/YcrqW0/rcdTNnYNKG/tGKEZ0suC0lF9EcHjnbsTjcdQ0NaK8psrWUdYnrzkPAPDKI49ZfBJ1REIj8Pp8KNIxUWPkxt50juzegzOuWIeKtKC7eDyOoZ5e9Hd0or+zCwOdXeg93o6XHtik6zG0Zo2IyohRmRZ6UeJx9La1o6ZpFqpmztQkRkTGiJWjyXqRKaxJURhIjvUO9fQatnxS5oxMIkZcLpfz2zTJ8d6qmQ2y5ZhrhBiZzC8CpC3LqwjC5XZPm6wrxIjajb1q2PK7h3DudVejpqkRv/zCV9G6b/+U1+3JcrotFxS8GAnW1Wru5RYHyjHrhIRJNV2MjA4No23/AcxctADNy5di9zP2NIUG6+swc9ECxONx7H1xq9XHUUV4ZAQlwYCu4DOzKiNbfvcQeo+3IR6NYaCrC/0dXYa3R7RmjYhMi74O9S/+ZtF7vC0hRmY14OAbO1TfTpTHneYXAVKVETHaa0bmiyj1T9amKSotkX93amWkv70T0XAY3qIiVMyoky2/XDLZgrx0RHXK7XajJFAu/z0VRk3TpBOLRvG9629GcVmZzPWZCpn7Y+M2TcF6RtweD26699v42l8eVp31L5h3ygq43W50HDw8ofR6cPtOAPbOG1mSDDk7smvPtP+J7ILY3KvHMyINrMnpFKOIRaPY/cxm7Nn8Io6+uRf9HZ2Gv4vTmjUixIjVlREgfaRQ2y9AJ6avCkQEf3l1Fdwej+GBZ0DmNo3wi8QiUcdsOx6PoiiydWxVq0ZM0nRN4hcBEv/3hRlVjYm1xIAE1skI9Q9MK0SAtE3aNq6MFKwYicdiUGJxuN1urP7glZpuu+D0iS0aweHtCd/IHBsnsYqwHKdURYCUiVVPCqtZlZFcoDVrpKLOHp4RQH8Ka7BWZIw4T4wMdSfaMW63G+U11WmTNEZWRpIG1sDEyoho0Yw6cEleOlaP92ZKXxWI8d7yyspp70+MYRstRtTS7YCskYIVIwBkeMwZV6zT9I5bipFXJ4oRURmZffKJcHs8BpzSWFxuNxavTlRG9r7gHDESzmI/jaPFiFiWV6NumiYg96DYQIwcS2aNaJyKcHJlRFEU6RUL1takLfwzvjLiLy2ZMOruT6avjujYDGsnrA4+m65NA6Qty5umMuJyuWTFyioxIqZpKtmmsSf7XnoZnYePoiQYwCnrLlV1G39pKRpPXAwAeGfbRDHScfAwhvv74S8twUwbrmxuOukElFVWIDQwiMM7d1t9HNVE5OZe7QbWlBhx3oub9IxUqRMjFXUJM22fhVHwgo5DiQmiGfPnarqdTF/tsr7VpAfh1wnW1aa1aYz7WkYHhxBPGibHR8LLsV5WRnTj9fvli3aXCjFSVjn5VJPAX1Yq35gakTOih962dsTjcRSVFGteL5ErClqMKIqCF3/7BwDAOddepeo2c09ZDo/Xi66jLehtm5gdoSgKDu94E0AintduLDkn0aL5+9ZXLM2h0IoIPvPp8IwETMoZyQWpaZrpxYjL7ZYVFDtMorT+PeHur541U75IqiFQ48z0VcFA2nivGQZWRVFSKazjfCOyTeNQ86rAyuCzmmQlL9Q/kDE1eViKkcqM9yfaaZGRUct8PLFIRPob7dqqKWgxAgAvP/QnREZG0XjiYlXiIZNfRCCTWG3oGznBgX4RIM3AqrFNU1RSIuPajTaw5gItBtbyqkp4vF7E43FbTKKE+gekYG9YqL5KKCojdvga9CCER3plxOgdO1OKEZkx4vQ2jXWVETV+ESBtWd40bRozJmn0kPJw2bNVU/BiJNTfj9cffwoAcM6Hpq+OLDhjYtjZeFJJrPYSI8XlZZiTDGTb+8IWi0+jDb2eEVEpCIdGJk0mtDuiMlISKJ82Cl+88FmdvppO6763AUB1y9LlcqVVdxwqRkQKa11tWvqqsW0zuSxv3H6a4jKRMeL0ykjCb1RWVampqmYEqRj4ySdpBENiP810YkSmr1orRlKbtK1Lts1EwYsRIGVkXXHphRnL4UUlxZh90okAMldGDu9KtGnqmmerTujLBQvPPB0erxftBw5ZMrufDXo9I042rwKJd8CxSCIsa7rgM+lPsIFfRCBaNTMXqxMjpRVBmWLrRI8PkKqM1DXPhj+Z+2GkZwSYerxXGFid3qYZHR6WbbrqxtxWR+SCvAx+ESDVppm+MpL4HhmVvqoXuaKBlRH7cvTNt3B455vwFhXhzCsvm/J6c1cug8fnRU/r8YwR6qH+ARzffwCAvUZ8hV/EaS0aIM0zolGMmJW+mkuGensBTG9iFXk5/QZObmSLECMNi+arur6oJAz19Np6eWMmhBhsPCFhdB8ZGjK8KheaIvjMX+bs9NV0Ur6RHIsRtW2aXpWVkaCxe2n00pNc1knPiM0R1ZHVH7xyysVe81X4RQSHxZ4aG23wlfkiDhrpFQjPiOY2TR6IETUmVq/fj/M/8iEA9mrBiYjqWYsWqrp+wMFjvQLRkhFCwYwAuuEpPCPFDt9Lk05Xi1iYZ5EYUVkZmV6MGLuXRi96QwhzBcVIkjf+/DSGevtQ3TgTJ5539qTXEftoMvlFBDKJdbk9NvjWNs9GTdMsRMNh7H/lNauPoxnhGdFqYC1LVhMGexwsRoSJNUOb5uxrr0TljHr0tB7HS7+zzxbm9gOHEItGURIMoHLG9OvLZcaIQ/0iwMTJGTMmm8S77PGjvfliYAXSKiOzczdR4/F6ZeVgOjGiNmdETNNY7RnRG0KYKyhGkkRHR/HypkcBAGd/6AMTPu/1+zFn2UkA1FVGxAbf2ctO1LxC3QxOSLZoDry2Q76wO4mIztFeYYbMi8rIFG0af2kpLrrpIwCAJ3/0c1ttuo1FIug4eBgA0KDCNxIQ6asO9YsAiSmgeNriNKPNq8D0nhGnG1iB9OCz3FVGqmYllvONDoemnYAS7dOyisxipNQm0zS9yTZNeXWV5nZ3LrD+VdJGvPTAJsTjcZx47uoJ8+3Ny0+Gt6gIfe0d0ypmAGjbfwAjg0MoLitDw8J5Zh1ZNUvOXgUA2PuS81o0QMozotXAKj0jNt6gPB3TtWnO+/C1KK+uQsfBw7bcwixNrComavKhTROPxcaIXzMqI2K0t2SqNo3DQ8+AtPHeHLZpRItGPHYmhnoTgtDj82ac+CkWe2n6rBUjof4Bmcxrx+oIxUgaXUdbZL999TVj99WIfBE1LRogsUJdTNVYnTfi8fmw4IxTATjTLwKkVUYK0DMyJCLhJ8kaKa0I4l03/AMA4Ikf/NQ2I73pCN+IOjEi4tOtD23LhnSfiBnR/LIyMm4/jQw9c3gcPJBq01Q3zcpZdVmtXwRIVNNHhxPG5EytGrmXxmLPCJBq1dgxFp5iZBwv/CaRyHrmlZfB60+9C0+Fnb2h+r7skjcy75Tl8JeWoL+zS+Y+OI1wSF/oWT6IEXH2yTwjaz52PUoC5Wh5ax+2P/nXHJ9MHXoqI04NPBOkTzQZPdYLZGrT5EfOCJCIMB8ZHILX58tZdblGbOtVIUaA1LK8TCmsqY291m9I77Hx9l6KkXG89fxL6G5pRVllBU5ZexGARGVBVDe0mD+lGLG4MiJGeve9+DIURbH0LHoRW3u1VkZEcqmjDazJ5NjxbZpgXS3Ove6DAIDHv/cT235vW/+eEMD18+fC7c28PFKIEacGngnSBYipbZqpdtPkgRhR4nGZZj13xfKcPKbMGJlmrFcwnGzVZNpPk0pgtb4yIoPP2KaxP0o8jhcfSFRHzk7uq5mz7CT4iv0Y6OpG+4FDqu9L/EeaMX/uhKTEXLJktcgXsc/Ip1Zk6JkGA6vL5ZKmTydXRoZ6JjewXvyJG1FUUowDr+/Ans0vWnE0VfQcOy7f4dbPbc54XWFgza/KiHltmgk5I6X54xkBgINvJKcSV+ZmKlFLmwZImVgztWnENI1VG3vTsfNEDcXIJLy86VFEw2HMWXYSZp98Ysov8uobmu5nuK9fThKISZxcU15TJbcM73tpmyVnMIJUHLx6A2txIACPT6R59ppxrJwwMImBtbpxJs666nIAwOPf+7El59LC8bffAZC5VeNyu2Uly8kGVmBsCq4pbZrkC5vH65WtGSCtTZMHnhEgt2LE5XbLyZ3pouAFQyqW5dllNw0A9CQrI3ZMYaUYmYShnl688eenASTGfNUsx5sKMeI71yLfiKiKHHnzLUdXB1Jx8OorI4HkWG8iUt0+465aEQbW4vIyuZ/m0ltugtfnw94Xt+r6ucw1qSTWqcVIWWVFatGfg9tqQEqAREZHTfEKREdHZRCg8I0UlRTLVfX50KYBgMM7dyMej6N2TpMc0zeLyoZ6eH0+RMPhSTeyT4aoUE0VfObx+WQ11+qcESA9+IyVEccgEllPWXsJ5q5M9Cv1/NIX4WfNy61JYpUR8A6dohGEdUzT5IN5FZi4n2bG/Lk47bK1ABJeESegZmGeCDwb7u1zbBS8QIyGZlobkS0y+CwpRkSLJh6PO3Ip5GSMDA7JqtrcFeZWR2rnzAaQyDdR0nJiMiHeKIw3EgtEFHw8HrfFhFOvmKaZUW+L/Kt07HUaG3F4x24cfXMvfMV+FJUUY6i3D23J/xRa7wcA5iw7GS6Xy+hjZsTlcmHx6jMBAPscuI8mHfEusKikWPXzmDKv9pp0qtwhKgXl1VV496dvhtvjwY6//A1Hdu+x+GTqUDNRkw8ZI4LWfW/jN1+9HRtv+3fTHkNO1CT9aP48ioJPR7ZqzBYjKhfkpSPbNJOM3QMpv8jI4KAtDOZ9HZ2IRaPw+LwI1tVYfZwxUIxk4MXf/l7+/Z1X39D1w9T69/0YHQ6hJBiQi8xyxawTFiFQU42RoSH5H9qppKfGev1Fqm6TL5URIPUO7IRzVmPFpRciHo/jiR/81NpDaUCIkerGmVMGRMn01TwQIwCw7eHHTBWLojIigs/8eRR4lk6ufCMidl7tJA2QJkamSGGVfpF+6ydpgMSARl9bBwCgqsFerRqKkQy8/vhT0gGtty8fj8XkL6Rmk5X9eETq6v6XX0MsGs3pYxuNGO0F1PtG8mFjr0B8DRfdfAMA4LU//Rltyc3QTiDUPyD78A0LJ6+OBKrzY5ImV4jfTSJuvLgsf8Z60xFipOnkE6Rnygxk+qqGyohcllc1hRix0SSNwK5ZIxQjGQiHRvDQf3wXe1/citcefUL3/aTyRnLrG5F+EYe3aICEopdZI351EzXCg5AXYiRZGfGXliAWieLJH/63tQfSwXStmkBtomxsRi5HPjI++Myfp2Kk68hRDHR1w+f3y8lAM5BjvSonaYDpl+XZZS9NOjKF1WYTNRQj0/DKI4/hp5/8nPyh04PIG8llEqu/tFSWNd9yuHlVIHwjapflpdo0zn+nnS6otv7hEVW7M+zGcRELP8XCvHxJX80V44PPUumr1hsljUaGn5nYqhH7yLo0tWl6AUzdppF7aexYGbHZRA3FSA6Q4WcL5mVcqGQkC844FV6fD51Hjmr6z2VnwhrHe6WB1cEZIwIhRiIjo3jqp/9j7WF0ciyZxNqwaP6knxej2E5PX80VhWJgBcw3sZZXV6GopBjxeFyOv6pBJLCKQYfx2GkvjcCuKaxeqw9QCAx29aDraAtqmhrxjWcfQ2RkFJFwGNHRMCKjo/LPyOgo+to78ND/+27W2QT5MtKbTiSkbbw3nwysf9+yDeGbb8STP7oP/e0dVh9HF9MtzBNtGlZG1CE9I8k2Tb56RgDzxYhYHDfQ0aXJXzc6PIxoJAKvz4fSiooxRnsgfS+NjSojx/KgTbN+/XooijLmsmePOrf4tddeC0VRsGnTJl0HdTqv/elJAIC3qAglwQCCtTWobpyJGfPnovHExZi7chkWnXU6Tn/fe7D84guyfrwlZ+ePX0QgKyMl6jwj+WRgPbzzTdy26iI884tfW30U3bQfOIRYNIrSYBCVM+onfL5c7qWhZ0QN4yPh83WaBgCO7H4LsUgUFTPqTHlHX5V8Ye45rr4qIhCTbpMFn9kpfVVg1zaN5srIrl27cPHFF8t/R1WoyObmZnz729/Gc889p/Xh8oYnfvBTPPvL38BfUgyvvwi+Yj+8RX74iv3wFRXB6y/CudddjcWrz5TvEPVS3TQLdc2zEYtE8fbLrxr0FViP9IyoqIy4PZ60No3zxQgA1UFMdiUWiaDj4GE0LJyPhsULxqRcutxulIvvFysjqphoYM2vKPh0oqOjOLpnL5qXn4y5K5fJF1SjqEy+MIsWhhaG+/pRUV836URNarTXPmKk93jiaywJlKO4vMw2Py+aPSPRaBRtbW3y0tWV+V2M2+3Gr3/9a6xfvx7vvKM9NCyfCPX3o7etHZ2Hj6J1334c2fUm3nnldex9cSt2P7MZh3clqkzjt7NqRVRFDu7YmVclWy2eEfEuJR6PZ2U+JsYy1URNWVUF3B4Pv18aGB5nYC0uzV/PCJBKszbDxCorIzrESCqF1RmVkXBoRJ7ZTuO9msXIokWL0NLSgv3792PDhg2YPXt2xut//etfR3t7O37+85+rfoyioiIEAoExl0JA/ICUT5Hmp5b5p60EAOx78eXsDmQztFRGypKCbri3z/EVhXxiKjESqElUA4d6ehGPOTsKPldMqIwkzfGjw/Z4p2s0wjfSbIoYSVZG9LRpMqSwCs+IHfbSpNMtxnttFHymSYxs3boVN954I9auXYtbbrkF8+bNw+bNm1FeXj7p9c855xzcdNNNuPnmmzUd6tZbb0V/f7+8tLQ4b4xRD2IEtTwZ/qSXYF0tAKDz0JGsz2QnIho8I/nkF8knpjKx5lMUfK4QJvfisjK4vZ60Nk1+VkYOJSsjsxYvRFFJiaH3LcycWiZpBHJZ3iT7aURlZMQmCawC0Y6qdmpl5IknnsCDDz6InTt34sknn8S6detQWVmJa665ZsJ1y8vL8atf/Qo333zztK2c8dx5550IBoPy0tjYqOn2TkW8cGa7nVL+Ys+zF2Ity/LyaZImn2hNjvfWz58Lt9cjPy5/ZmleVU36uGhpMJjWpsnPykhfWwe6j7XC4/Vi9tITDb1vURnJqk0zmYE1WdUfNmFzczbYcaImq9Hevr4+7Nu3DwsXLpzwuQULFmDevHn44x//KD/mTm4JjEQiWLJkyZQeknA4jHA4nM3RHMlAV2oZWjbIF+I8e5eZWpY3/bsiihF70nPsOEYGh1BcXob6uc1yI6swbbMyoh4lHkeofwAlwQBKK4JpbZr8rIwAwKE3dqJ61kzMXbkM+7e9Zsh9ev1+KYZ1iZG+yds0LpcrNdpro5wRIDU1ZKeJmqxCz8rKyrBgwQK0tk5ck/3WW29h6dKlWLlypbw88sgjeOaZZ7By5UocOZJfLQQjSB8R07vh1+31SPNmvr0Qi3XswhOTCYoR+yIESHqrJpW+yu+XFuSyvGAA/lKRwJq/YsQME2vljDoACRGnJ99JBJ+Nb9MUlZbA7UlU/+w0TQPYM/hMkxi56667cP7556O5uRmrV6/Gpk2bEIvFsHHjRgDA/fffjzvuuAMAMDo6it27d4+59Pb2YmBgALt370YkEjH+q3E4Qoy4PR5pStNKeVXiRTgWjcpeZr7wxuNPIR6PY+EZp6K6cWbG65ZVVwJI7XQh9kGYWBvSxUgt2zR6SE9hLRY5IzYZ1TSDg28kY+FXLNP9hm082bRogKnbNCJ9NTI6iqjNKv2iTeNYMdLU1ISNGzdi7969eOCBB9DV1YVVq1ahs7MTADBnzhzMnJn5RYJMTbqA0NuqEe8wh3p6oSiKYWezA71t7Xh76ysAgNPf956M15UGVr7Tth2TTdTQwKoPuZ+mIpDXcfCCY/v+jnBoBKUVQdTNnWPIfQrfhJ6MESCtTVNZOebjdtxLIxBtmkBdDTxeewSxazrFddddl/Hza9asyfj5j370o1oeriAZ7O5BaUUQ5dVVaHvnoObb53t7Ytsjj2Hx6jNx+hXr8NRPfjGl4BITSfmwJC/faN2XMLGmi5FyKUZYGdGCePMSrKmBt6gIADCSx56ReDSGw7vexMIzTsXclcvRfuBQ1vcpKyM6xnqBRHwAAJRWjq1mpzb22ssvAiTepEVGR+Hz+1HRUI/uo8esPhIX5dkNISLKdFZGhBjJ13eYu55+FiNDQ6hpasS8U1dMeb18F2VORlRGqhtnysWRrIzoQ+RXpIdXhYdDVh0nJ8g9NQb5RqQY0THWC6RyRorLyuDx+eTH7Zi+mo70jTTYY6KGYsRmiBfPQJZtmnx9EQ6HRrD9z38FAJx++boprydFWZ4+D04m1D8go+AbFi4YE91PMaINURkRL6ijw6G8D42T4Wcrlhpyf9m2aUYGBuVznr6fxo7pq+nIHTWz7GGtoBixGTJrhJWRKXnlkccAACsuvXDStd3eoiL5jnuIBlZbku4bKauqhNvtRjwWw1APo+C1EBpXGcnnsV7B4R0JE2vDgnkoCeoz+qcjKgM9x/WJEUVRZHWkdDIxYtPKiDDs2iVrhGLEZmQtRvK8MgIAB17bjs4jR1FcXoalF03ccCzi9GORqG1/ERQ6x0US6+IFqWpeTy+j+zUyoTKSx+ZVwVBvn/SKNK84Oev7S1VG9C/fkyms6WIkYF/PCJCqjFTbZKKGYsRmiFHUyfYcqEGkt+Zb4Fk6iqLg1UceBwCcMUmrRj4HeSzInE5qvHc+01ezQLwIytjxPE1fHY9RvpHy6ir4/H7E43H0tXXovh9hYk0XI8LAarf0VYEQX6yMkEnJNhI+UJ2fUfDjeeWPCTGy8KzTUTmjfsznaF61P8fSJmpE+mo+C2izGB/SVQiVEQA4+MYOAIm8kWyoTLZoBjq6EItGdd/PUG8vgLFtGjHaa7e9NIJum2WNUIzYDPELOaBzWV6qMpLfL8TdLa14e9trcLvdOG1c5gjHeu1P+4FDiEWjKA0G0XTSEgBAfye/X1oZ/667cMRIojIyZ9nJMuVUD8Jro3esVzDUO7FNI0LP7LaxV2C3FFaKEZthlIG1EN5lCiPr6ZePEyPJFhfTV+1LLBJBx8HDAIDFq88EUBg/s0YT6hv7QlcIBlYgIWaH+/vhLy3BzMULpr/BFIgXYr2TNILJ2jSpvTQ2FSNt7YjH4/AV+7Peh2YEFCM2Q7yAllYEx2w1VUNJMABvcs69EF6Idzz5DEaHQ6if14w5y1NGNrZpnIHwjcyYPxdAfk+AmcX4yshIHkfBp6MoCg5tT0bDr1yu+36EX0JvxohAtGnSU1jtPk0Ti0SkT6vSBlkjFCM2Y7ivP21mvVLTbcWLcKh/wHa7EMxgdHgYO//yNwDAGVe8V36cBlZnIMSIgOmr2gmHRhBN2/NVKG0aADgoxYh+30i2Y70C0aZJT2FNTdPYU4wA6Vkj1rdqKEZshhKPy5l1raWzfA88mwzRqlm59iIZh13OvTSO4PgEMcLvlx7SF2IWSpsGAA6JiZosTKxGjPUCaZWRCufkjAD28o1QjNgQmcKqcaKmEALPxvP2y6+ip/U4SoNBnLzmPABMX3UKEyojHO3VxRgxUkCVkcM730Q8FkN140wE6+t03Ue2G3sF0jOS9Kt5fD4ZyGjXnBHAXtt7KUZsiNxPU8XKyHQoiiLHfM+4IpE5In4hDPUUzvPgRHqOHR/jcSgkEW0k6e+8C8UzAiSqQK3J8Ly5OqLhvX6//J2ZrRgZGrcsrySYMK/G43GM2FmMHLdPCivFiA3RO1FTiJURAHglGYC25OyzEKitkWPRhSTKnIiiKDj+9jsAgFg0Kt9dEm0UapsGAA5u1x9+VtmQyCcaHR6ekNeiFSlGgkG4PR7pFxkZHJxys7gdkJURekbIZOgWIwVYGQGAzkNHcPCNnXB7PDj7mivhK/YDKLznwYmIVs1gd4+tf2nbmfTKyGiBJLAKsgk/M6pFA4z9HpRWBNP8IvatigBpBlZO05DJ0Lu5t5BHWrc9/CcAwDnXXQ0gsb00HBqx8khEBVKM0Lyqm/TKyMhggVVGkibWxpOWSAO7WuQkTZbmVQCIx2JyzLq0IpiapLGxeRVIfe3l1VWTLh3NJRQjNkTup6mu1HS7QIG2aQDgjT8/jcjoqAwdKkRB5kTefPZ59La1Y/tTf7X6KI4lvcUwOlxYlZHullYMdvfA6/OhYeE8TbdNTdJkXxkBIDdOl1VVyr00dh7rBYCRgUHpM7I6a4RixIaId4ls06hnZGAQu/76nPz3UAGEvuUDPceO4/aLr8DTP7vf6qM4lvTgs0KaphEc2/t3AEDjCYs13S7Vpsm+MgKMTWEVe2nsXhkBUl8/xQiZAA2s+tj28GPy74UoyEhhUqijvYKWtxJiZJZGMWJ4ZUSYWCsq5F4aO4/1CuwSfEYxYkPEgjctYsRbVCR3IRTqC/G+l15GX3tiDXihPgek8EhfxDZSkGJkH4AsKiNZpq8KhmTWSEVqL40TKiM2yRqhGLEhwjNSXFYGr9+v6jZCuETDYVvPtZuJEo9jy4MPA0itqCck3xGVkWg4jFhaNHyhcCwpRmYtWQiXy6XqNi6XS472Zpu+KhjuS4qRiorUNI3NPSMA0HvcHimsXksfnUzKyMAgopEIvD4fyqsq5Q9LJgox8Gwynvrxz7HvpW04sutNq49CSE7obW1DPBYzZETVibQfPIxwaAT+0lLUzGlC56Ej096mrLoSPr8f8XgcfW0dhpwj3cDqLysF4JDKSKs9gs9YGbEpWn0jhe4XESiKgoNv7EAsGrX6KITkhP6OTvzopn/Cf//Tv1p9FEtQ4nE5Iq62VVPVkKgC9Hd0Gva7YqgvlcLqpMoI2zQkI3KiRuV+GlZGCClc3nn1DXQcPGz1MSxDq2/EaPMqkDZNU5HyjAw7oDIi2lSVM+rhclsnCShGbIrYq1Kucj+NEC0UI4SQQuOYnKhZpOr6Ro/1Aqk4gbKqSlkZGbF5AisA9CWrQx6fF8G6GsvOQTFiUwbYpiGEEFW0vLUXgLWVkaG+iQmsw1nuvMkFSppvRrSvrIAGVpui1TMi2zSM1SaEFBitf9+PeCyGYG0NArU1GOjsynh9o8d6gVRlpLQiKD/mhJwRAHjpd5vg9fnQ35X5eTMTihGbotvA2s3KCCGksIiMjKL94GE0LJiHxhMW4a3npxMjojJiXJtGeEbcHo/8mBOmaQDgr//9K6uPwDaNXRnq7gUAlKvcT1POygghpIA5Jk2sS6a9bqVckmdcZSQWjWIkbWtyZHQU0XDYsPvPdyhGbAo9I4QQop4WlSZWr98v29pGGliBVNYI4JyqiF2gGLEpWto0Lrcb5VWVY25HCCGFhNrxXpG8OjI0ZLhgECmsgHP8InaBYsSmaNlPU1oRlH1KbqslhBQiok1T1zwb/tLSKa8nzKtGTtIIhG8EYGVEKxQjNkWICp/fn/E/FpASLEM9vYjHYmYfjRBCbMdQb59cnTFrycIpr1cl/CIGTtKkn0HghPRVO0ExYlPCoRGMDocATF8dEf3PAbZoCCEFTMo3MnWrpmqWeZWRIVZGdEMxYmOkb2SaSHghVgZpXiWEFDBqfCMi8Mxo8yowvjJCz4gWKEZsjFoTK/fSEEJIyjeSaaJGpIya7RlxQvqqnaAYsTFSjCQnZaaCY72EEJKqjMxcOB9ur2fS68jKiMmeESfspbETFCM2RphYy6urM16PlRFCCAG6W1oR6h+At6gIM+bPnfB5l8slR3t7jrUa/vhDYyoj9IxogWLExqgd72VlhBBCErTsTZhYJ0tiLauuhM/vRzweR197h+GPPcxpGt1QjNiYAbUGVlZGCCEEQGYTq/CL9Hd0Ih41PgaB0zT6oRixMVo9IxQjhJBC51iGWHgzx3oBYKi3V/6dlRFtUIzYmNSyPLZpCCFEDS1v7QUANC6ZKEbMHOsFEtuDxRTNQCd/H2vBa/UByNSoGe0tKimBv7QkcX1u7CWEFDht7xxENBxGSTCA6saZ6G5JGVXNHOsVbPjiegRrq9Hf0WnaY+QjFCM2RnhGyqoq4XK5oCjKhOsIP8nocAjhUCin5yOEELsRj8bQ+vY7mH3SCWg8YfEYMWLmWK9g7wtbTLvvfIZtGhszlBQjHq8XxYHApNfhWC8hhIzl2BSx8FVCjBwzp01D9EMxYmNi0ah0ZAemmKhhFDwhhIxlqomaygZzPSNEPxQjNmc63wgrI4QQMpZjUoykTKxev1/+vuw1sU1D9EExYnOmEyOcpCGEkLEc2/s2gEQlpKyyAkCqRTMyNMQMEBtCMWJz0k2sk8GMEUIIGcvo8DA6Dh0BkPKNCDFi5iQN0Q/FiM0R+2kCbNMQQohqxvtGKpNjvWZO0hD9UIzYHNmmqZl8WR7bNIQQMhExUSN8I6yM2BuKEZsz3bI87qUhhJCJiCRW0aap5FivraEYsTkiVXUqz0iAlRFCCJlAy55Em6Z+7hz4iv0yfbXnOMWIHaEYsTmDSc/IZJURt9cjRQorI4QQkmKgqxv9nV1wezyYuWiBrIywTWNPNImR9evXQ1GUMZc9e/ZMef0rr7wS27ZtQ09PDwYHB/H666/j+uuvz/rQhYQQGZMZWMsqKwEA8VgMw2mrqwkhhKSZWE9ckkpfZeCZLdG8m2bXrl24+OKL5b+j0eiU1+3u7sa3vvUtvPXWWwiHw7jsssvwi1/8Au3t7XjyySf1nbjAGEwb7XV7PIjHYvJzcpKmp3fSvTWEEFLIHHvr7zjx3NU44Zyz4C0qQjweR197h9XHIpOgWYxEo1G0takrcz377LNj/v29730PN9xwA84991yKEZUM9fYhHo/D7XajtDI4ZjMvo+AJIWRqRGVk8eqzAAD9HZ2IR2OZbkIsQrNnZNGiRWhpacH+/fuxYcMGzJ49W/VtL7zwQixZsgTPPfdcxusVFRUhEAiMuRQqSjwuWzDl1WPHe8XGXvpFCCFkIkKMFJUUA6BfxM5oEiNbt27FjTfeiLVr1+KWW27BvHnzsHnzZpSXl095m2AwiIGBAYTDYfzpT3/CZz7zGfzlL3/J+Di33nor+vv75aWlpUXLMfOOqXwjgWqO9RJCyFR0HT6K0eFh+e+eY60WnoZkQpMYeeKJJ/Dggw9i586dePLJJ7Fu3TpUVlbimmuumfI2AwMDWLlyJc444wx85StfwX/913/hggsuyPg4d955J4LBoLw0NjZqOWbeMdV+GlEZ4VgvIYRMRFEUuacGYPqqndHsGUmnr68P+/btw8KFC6e8jqIo2L9/PwBg+/btOPHEE3HrrbdO8JOkEw6HEQ6HszlaXjE4xX4aRsETQkhmWt7ah3mnLAfANo2dySpnpKysDAsWLEBrq/rSl9vtht/vz+ZhCw6ZNVIzrjLCwDNCCMnIsaRvBAB6KEZsi6bKyF133YU//vGPOHToEGbNmoVvfOMbiMVi2LhxIwDg/vvvR0tLC2677TYAwJe//GW88sor2L9/P/x+P9atW4cPf/jDuOWWW4z/SvKYqds0ycpIFysjhBAyGS1jxAgzRuyKJjHS1NSEjRs3oqamBh0dHXj++eexatUqdHZ2AgDmzJmDeDwur19WVoYf/vCHaGpqQigUwltvvYXrr78eDzzwgLFfRZ4jxMZEAysrI4QQkonjbx/AyOAQPD4vuluOWX0cMgWaxMh1112X8fNr1qwZ8++vfe1r+NrXvqb9VGQMYlleWdXkbRp6RgghZHKi4TB+dNOn4S3yY3RoePobEEvIysBKcsNk+2mKA+XwFhUlPk8xQgghU3L0zb1WH4FMAxflOYDJPCPi76GBQUQ5eUQIIcTBUIw4ACFGSgLl8Ph8ADjWSwghJH+gGHEAof4BxCKJhYTl1ZXJP7mXhhBCSH5AMeIQBnvGtmpEZWSAlRFCCCEOh2LEIaR8I9XJP1kZIYQQkh9QjDiE8SZWekYIIYTkCxQjDkGKkeR+GkbBE0IIyRcoRhzC+P00DDwjhBCSL1CMOAQRCc82DSGEkHyDYsQhjPeMsE1DCCEkX6AYcQgpz0gVvEVFKAkGxnycEEIIcSoUIw4hPWdEmFijkQhC/QMWnooQQgjJHooRh5DepimnX4QQQkgeQTHiEISBtaikGDWzGwHQL0IIISQ/oBhxCOFQCOHQCACgYcE8AKyMEEIIyQ8oRhyE8I00LFqQ+DcrI4QQQvIAihEHISohMxfOT/y7i5URQgghzodixEEIMVIzp2nMvwkhhBAnQzHiIIT4cLsT3zYaWAkhhOQDFCMOYqi7d8y/WRkhhBCSD1CMOIjx4oOVEUIIIfkAxYiDGBgnRlgZIYQQkg9QjDiI8eJDjPoSQgghToZixEEMpYmPod4+xKMxC09DCCGEGAPFiINIzxVhi4YQQki+QDHiIAZ7euXfaV4lhBCSL1CMOIhoOIzQwCAAVkYIIYTkDxQjDmMoWR3hXhpCCCH5AsWIwxAVkfFjvoQQQohToRhxGN3HWgEAPS2tFp+EEEIIMQav1Qcg2njsnh/hwGvbsf3Jv1p9FEIIIcQQKEYcRs+x43jxt3+w+hiEEEKIYbBNQwghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoQQQgghlkIxQgghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRRHbe0NBAJWH4EQQgghKlH7uu0IMSK+mJaWFotPQgghhBCtBAIBDAwMTPl5FwAld8fRz6xZszJ+IXoIBAJoaWlBY2Oj4fdNUvB5zh18rnMDn+fcwOc5N5j9PAcCARw7dizjdRxRGQEw7ReSDQMDA/xBzwF8nnMHn+vcwOc5N/B5zg1mPc9q7pMGVkIIIYRYCsUIIYQQQiyloMXI6Ogo/u3f/g2jo6NWHyWv4fOcO/hc5wY+z7mBz3NusMPz7BgDKyGEEELyk4KujBBCCCHEeihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYSkGLkX/8x3/EgQMHEAqFsGXLFpxxxhlWH8nRnHfeeXjkkUfQ0tICRVFwxRVXTLjON77xDRw7dgzDw8N46qmnsHDhQgtO6my+/OUv4+WXX0Z/fz/a2tqwadMmLF68eMx1/H4/fvCDH6CzsxMDAwN48MEHUV9fb9GJncmnPvUpbN++HX19fejr68OLL76ItWvXys/zOTaHL33pS1AUBXfffbf8GJ/r7Fm/fj0URRlz2bNnj/y8HZ5jpRAv11xzjTIyMqLceOONyoknnqj85Cc/Ubq7u5W6ujrLz+bUy9q1a5Xbb79def/7368oiqJcccUVYz7/xS9+Uenp6VEuv/xyZdmyZcpDDz2k7N+/X/H7/Zaf3UmXxx9/XLnhhhuUk046SVm+fLny6KOPKgcPHlRKS0vldX74wx8qhw4dUtasWaOceuqpyosvvqg8//zzlp/dSZfLLrtMec973qMsXLhQWbRokfLNb35TGR0dVU466SQ+xyZdTj/9dOWdd95R3njjDeXuu++WH+dznf1l/fr1ys6dO5UZM2bIS01NjZ2eY+ufJCsuW7ZsUb7//e/Lf7tcLuXo0aPKl770JcvPlg+XycTIsWPHlC984Qvy38FgUAmFQsq1115r+XmdfKmtrVUURVHOO+88+byOjo4qV111lbzOkiVLFEVRlLPOOsvy8zr50tXVpXzsYx/jc2zCpaysTNm7d69y0UUXKc8884wUI3yujbmsX79eef311yf9nB2e44Js0/h8Ppx22mn4y1/+Ij+mKAr+8pe/YPXq1RaeLH+ZN28eZs6cOeY57+/vx9atW/mcZ0lFRQUAoLu7GwBw2mmnoaioaMxzvXfvXhw6dIjPtU7cbjeuvfZalJWV4aWXXuJzbAL33nsv/vSnP+Hpp58e83E+18axaNEitLS0YP/+/diwYQNmz54NwB7PsWMW5RlJbW0tvF4v2traxny8ra0NJ5xwgkWnym8aGhoAYNLnXHyOaMflcuG73/0unn/+eezevRtA4rkeHR1FX1/fmOvyudbO0qVL8dJLL6G4uBiDg4O48sorsWfPHqxcuZLPsYFce+21OPXUUyf17fHn2Ri2bt2KG2+8EXv37sXMmTOxfv16bN68GUuXLrXFc1yQYoSQfOHee+/F0qVLce6551p9lLxk7969WLlyJSoqKnD11Vfj/vvvxwUXXGD1sfKKpqYm3HPPPbjkkksY+24iTzzxhPz7zp07sXXrVhw6dAjXXHMNQqGQhSdLUJBtms7OTkSjUcyYMWPMx2fMmIHjx49bdKr8RjyvfM6N4/vf/z4uu+wyrFmzBi0tLfLjx48fh9/vl+0bAZ9r7UQiEezfvx+vvfYabrvtNmzfvh2f/exn+RwbyGmnnYYZM2bgtddeQyQSQSQSwbve9S788z//MyKRCNra2vhcm0BfXx/27duHhQsX2uLnuSDFSCQSwauvvoqLLrpIfszlcuGiiy7CSy+9ZOHJ8pcDBw6gtbV1zHMeCARw1lln8TnXwfe//31ceeWVuPDCC3Hw4MExn3v11VcRDofHPNeLFy9Gc3Mzn+sscbvd8Pv9fI4N5Omnn8bSpUuxcuVKedm2bRt+/etfY+XKlXjllVf4XJtAWVkZFixYgNbWVtv8PFvu8rXics011yihUEj5yEc+opxwwgnKj3/8Y6W7u1upr6+3/GxOvZSVlSkrVqxQVqxYoSiKonzuc59TVqxYocyePVsBEqO93d3dyvve9z5l6dKlyqZNmzjaq+Ny7733Kj09Pcr5558/ZkyvuLhYXueHP/yhcvDgQeVd73qXcuqppyovvPCC8sILL1h+didd7rjjDuW8885TmpublaVLlyp33HGHEovFlIsvvpjPscmX9GkaPtfGXO666y7l/PPPV5qbm5XVq1crTz75pNLe3q7U1tba5Tm2/kmy6vLpT39aOXjwoDIyMqJs2bJFOfPMMy0/k5MvF1xwgTIZv/jFL+R1vvGNbyitra1KKBRSnnrqKWXRokWWn9tpl6m44YYb5HX8fr/ygx/8QOnq6lIGBweV3//+98qMGTMsP7uTLvfdd59y4MABZWRkRGlra1OeeuopKUT4HJt7GS9G+Fxnf9m4caPS0tKijIyMKEeOHFE2btyozJ8/3zbPsSv5F0IIIYQQSyhIzwghhBBC7APFCCGEEEIshWKEEEIIIZZCMUIIIYQQS6EYIYQQQoilUIwQQgghxFIoRgghhBBiKRQjhBBCCLEUihFCCCGEWArFCCGEEEIshWKEEEIIIZZCMUIIIYQQS/n/y9BnUZXaKWAAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "trainer.runner.cbs[1].plot_loss()" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "trainer.runner.cbs[1].plot_loss()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ { "data": { "image/png": "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", @@ -1265,15 +1031,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# [Pretrained Image classification example - Hugging face( Does not work rn)](#toc0_) " + "# Tabular classification (Runs but openml evaluation fails)" ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ + "\n", "import torch.nn\n", "import torch.optim\n", "\n", @@ -1282,71 +1049,67 @@ "import openml_pytorch.layers\n", "import openml_pytorch.config\n", "import logging\n", - "import warnings\n", "\n", - "# Suppress FutureWarning messages\n", - "warnings.simplefilter(action='ignore')\n", "\n", "############################################################################\n", "# Enable logging in order to observe the progress while running the example.\n", "openml.config.logger.setLevel(logging.DEBUG)\n", "openml_pytorch.config.logger.setLevel(logging.DEBUG)\n", - "############################################################################\n", - "\n", - "############################################################################\n", - "import torch.nn as nn\n", - "import torch.nn.functional as F" + "############################################################################" ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ - "# openml.config.apikey = 'key'\n", "from openml_pytorch.trainer import OpenMLTrainerModule\n", "from openml_pytorch.trainer import OpenMLDataModule\n", - "from openml_pytorch.trainer import Callback" + "from openml_pytorch.trainer import Callback\n", + "import torchvision" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/IPython/core/interactiveshell.py:3577: FutureWarning: Starting from Version 0.15.0 `download_splits` will default to ``False`` instead of ``True`` and be independent from `download_data`. To disable this message until version 0.15 explicitly set `download_splits` to a bool.\n", + " exec(code_obj, self.user_global_ns, self.user_ns)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/functions.py:442: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " dataset = get_dataset(task.dataset_id, *dataset_args, **get_dataset_kwargs)\n" + ] + } + ], + "source": [ + "# supervised credit-g classification\n", + "task = openml.tasks.get_task(31)" ] }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "from openml import OpenMLTask\n", - "from torchvision.transforms import Compose, Resize, ToPILImage, ToTensor, Lambda\n", - "from openml_pytorch.trainer import convert_to_rgb\n", - "\n", - "def custom_optimizer_gen(model: torch.nn.Module, task: OpenMLTask) -> torch.optim.Optimizer:\n", - " return torch.optim.Adam(model.fc.parameters())\n", - "\n", - "############################################################################\n", - "transform = Compose(\n", - " [\n", - " ToPILImage(), # Convert tensor to PIL Image to ensure PIL Image operations can be applied.\n", - " Lambda(\n", - " convert_to_rgb\n", - " ), # Convert PIL Image to RGB if it's not already.\n", - " Resize(\n", - " (64, 64)\n", - " ), # Resize the image.\n", - " ToTensor(), # Convert the PIL Image back to a tensor.\n", - " ]\n", - ")\n", "data_module = OpenMLDataModule(\n", - " type_of_data=\"image\",\n", - " file_dir=\"datasets\",\n", - " filename_col=\"image_path\",\n", + " type_of_data=\"dataframe\",\n", + " target_column=\"class\",\n", " target_mode=\"categorical\",\n", - " target_column=\"Class_encoded\",\n", - " batch_size = 64,\n", - " transform=transform\n", - ")\n", - "# Download the OpenML task for tiniest imagenet\n", - "task = openml.tasks.get_task(362127)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ "\n", "trainer = OpenMLTrainerModule(\n", " data_module=data_module,\n", @@ -1358,233 +1121,707 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "Some weights of ViTForImageClassification were not initialized from the model checkpoint at google/vit-base-patch16-224-in21k and are newly initialized: ['classifier.bias', 'classifier.weight']\n", - "You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n" - ] - } - ], - "source": [ - "# hf model \n", - "from transformers import ViTForImageClassification\n", - "model = ViTForImageClassification.from_pretrained(\"google/vit-base-patch16-224-in21k\")" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "(ViTConfig {\n \"_name_or_path\": \"google/vit-base-patch16-224-in21k\",\n \"architectures\": [\n \"ViTModel\"\n ],\n \"attention_probs_dropout_prob\": 0.0,\n \"encoder_stride\": 16,\n \"hidden_act\": \"gelu\",\n \"hidden_dropout_prob\": 0.0,\n \"hidden_size\": 768,\n \"image_size\": 224,\n \"initializer_range\": 0.02,\n \"intermediate_size\": 3072,\n \"layer_norm_eps\": 1e-12,\n \"model_type\": \"vit\",\n \"num_attention_heads\": 12,\n \"num_channels\": 3,\n \"num_hidden_layers\": 12,\n \"patch_size\": 16,\n \"qkv_bias\": true,\n \"transformers_version\": \"4.44.2\"\n}\n, )", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[34], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# Run the model on the task (requires an API key).m\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m run \u001b[38;5;241m=\u001b[39m \u001b[43mopenml\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mruns\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_model_on_task\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:142\u001b[0m, in \u001b[0;36mrun_model_on_task\u001b[0;34m(model, task, avoid_duplicate_runs, flow_tags, seed, add_local_measures, upload_flow, return_flow, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 137\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m extension \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 138\u001b[0m \u001b[38;5;66;03m# This should never happen and is only here to please mypy will be gone soon once the\u001b[39;00m\n\u001b[1;32m 139\u001b[0m \u001b[38;5;66;03m# whole function is removed\u001b[39;00m\n\u001b[1;32m 140\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(extension)\n\u001b[0;32m--> 142\u001b[0m flow \u001b[38;5;241m=\u001b[39m \u001b[43mextension\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel_to_flow\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 144\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_task_and_type_conversion\u001b[39m(_task: \u001b[38;5;28mint\u001b[39m \u001b[38;5;241m|\u001b[39m \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m|\u001b[39m OpenMLTask) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m OpenMLTask:\n\u001b[1;32m 145\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Retrieve an OpenMLTask object from either an integer or string ID,\u001b[39;00m\n\u001b[1;32m 146\u001b[0m \u001b[38;5;124;03m or directly from an OpenMLTask object.\u001b[39;00m\n\u001b[1;32m 147\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 156\u001b[0m \u001b[38;5;124;03m The OpenMLTask object.\u001b[39;00m\n\u001b[1;32m 157\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:281\u001b[0m, in \u001b[0;36mPytorchExtension.model_to_flow\u001b[0;34m(self, model, custom_name)\u001b[0m\n\u001b[1;32m 270\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Transform a Pytorch model to a flow for uploading it to OpenML.\u001b[39;00m\n\u001b[1;32m 271\u001b[0m \n\u001b[1;32m 272\u001b[0m \u001b[38;5;124;03mParameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 278\u001b[0m \u001b[38;5;124;03mOpenMLFlow\u001b[39;00m\n\u001b[1;32m 279\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 280\u001b[0m \u001b[38;5;66;03m# Necessary to make pypy not complain about all the different possible return types\u001b[39;00m\n\u001b[0;32m--> 281\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_serialize_pytorch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcustom_name\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:287\u001b[0m, in \u001b[0;36mPytorchExtension._serialize_pytorch\u001b[0;34m(self, o, parent_model, custom_name)\u001b[0m\n\u001b[1;32m 284\u001b[0m rval \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;66;03m# type: Any\u001b[39;00m\n\u001b[1;32m 285\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mis_estimator(o):\n\u001b[1;32m 286\u001b[0m \u001b[38;5;66;03m# is the main model or a submodel\u001b[39;00m\n\u001b[0;32m--> 287\u001b[0m rval \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_serialize_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mo\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcustom_name\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 288\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(o, (\u001b[38;5;28mlist\u001b[39m, \u001b[38;5;28mtuple\u001b[39m)):\n\u001b[1;32m 289\u001b[0m rval \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_serialize_pytorch(element, parent_model) \u001b[38;5;28;01mfor\u001b[39;00m element \u001b[38;5;129;01min\u001b[39;00m o]\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:387\u001b[0m, in \u001b[0;36mPytorchExtension._serialize_model\u001b[0;34m(self, model, custom_name)\u001b[0m\n\u001b[1;32m 370\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Create an OpenMLFlow.\u001b[39;00m\n\u001b[1;32m 371\u001b[0m \n\u001b[1;32m 372\u001b[0m \u001b[38;5;124;03mCalls `pytorch_to_flow` recursively to properly serialize the\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 382\u001b[0m \n\u001b[1;32m 383\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 385\u001b[0m \u001b[38;5;66;03m# Get all necessary information about the model objects itself\u001b[39;00m\n\u001b[1;32m 386\u001b[0m parameters, parameters_meta_info, subcomponents, subcomponents_explicit \u001b[38;5;241m=\u001b[39m \\\n\u001b[0;32m--> 387\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_extract_information_from_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 389\u001b[0m \u001b[38;5;66;03m# Check that a component does not occur multiple times in a flow as this\u001b[39;00m\n\u001b[1;32m 390\u001b[0m \u001b[38;5;66;03m# is not supported by OpenML\u001b[39;00m\n\u001b[1;32m 391\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_multiple_occurence_of_component_in_flow(model, subcomponents)\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:588\u001b[0m, in \u001b[0;36mPytorchExtension._extract_information_from_model\u001b[0;34m(self, model)\u001b[0m\n\u001b[1;32m 586\u001b[0m model_parameters \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_module_descriptors(model, deep\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m 587\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28msorted\u001b[39m(model_parameters\u001b[38;5;241m.\u001b[39mitems(), key\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mlambda\u001b[39;00m t: t[\u001b[38;5;241m0\u001b[39m]):\n\u001b[0;32m--> 588\u001b[0m rval \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_serialize_pytorch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mv\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 590\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mflatten_all\u001b[39m(list_):\n\u001b[1;32m 591\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\" Flattens arbitrary depth lists of lists (e.g. [[1,2],[3,[1]]] -> [1,2,3,1]). \"\"\"\u001b[39;00m\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:321\u001b[0m, in \u001b[0;36mPytorchExtension._serialize_pytorch\u001b[0;34m(self, o, parent_model, custom_name)\u001b[0m\n\u001b[1;32m 319\u001b[0m rval \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_serialize_methoddescriptor(o)\n\u001b[1;32m 320\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 321\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(o, \u001b[38;5;28mtype\u001b[39m(o))\n\u001b[1;32m 322\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m rval\n", - "\u001b[0;31mTypeError\u001b[0m: (ViTConfig {\n \"_name_or_path\": \"google/vit-base-patch16-224-in21k\",\n \"architectures\": [\n \"ViTModel\"\n ],\n \"attention_probs_dropout_prob\": 0.0,\n \"encoder_stride\": 16,\n \"hidden_act\": \"gelu\",\n \"hidden_dropout_prob\": 0.0,\n \"hidden_size\": 768,\n \"image_size\": 224,\n \"initializer_range\": 0.02,\n \"intermediate_size\": 3072,\n \"layer_norm_eps\": 1e-12,\n \"model_type\": \"vit\",\n \"num_attention_heads\": 12,\n \"num_channels\": 3,\n \"num_hidden_layers\": 12,\n \"patch_size\": 16,\n \"qkv_bias\": true,\n \"transformers_version\": \"4.44.2\"\n}\n, )" + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n" ] } ], "source": [ - "#\n", - "# Run the model on the task (requires an API key).m\n", - "run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False)" + "data = task.get_dataset().get_data()[0]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGdCAYAAADAAnMpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB0z0lEQVR4nO2deZhcZZn279q6eqvqvdNJd9LZw5KNPWE1bMaIIIIg86GgiMo4jo7Op4JLxkHhm0EHUXFldNA4UUQDiIAgIoQlIWzZCImErJ1O73tXd23n+6Pqfat6qz7n1Dl1zqm6f9dVV5LuWt6u7nTd9Tz3cz8uAAoIIYQQQizCbfUBCCGEEFLYUIwQQgghxFIoRgghhBBiKRQjhBBCCLEUihFCCCGEWArFCCGEEEIshWKEEEIIIZZCMUIIIYQQS/FafQC1zJo1CwMDA1YfgxBCCCEaCAQCOHbsWMbrOEKMzJo1Cy0tLVYfgxBCCCE6aGxszChIHCFGREWksbGR1RFCCCHEIQQCAbS0tEz72u0IMSIYGBigGCGEEELyDBpYCSGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoQQQgghlkIxQgghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoSYTuWMelzyqY+h8YTFVh+FEEKIDaEYIaZzwY3/gLWfvhmf/939+MSP78ais063+kiEEEJshNfqA5D8J1BTLf++5JxVWHLOKhzZvQfP/OLX2PHUM1DicQtPRwghxGpYGSGmU1xeBgD48w/vw/P/+zuEQyOYffKJ+Mi3v4kvP/pbrL7mSnj9fotPSQghxCooRojpFJeXAwBa972NTXf+F7556fvx5x/eh6GeXtTObsLVX/sivvrnP+Cim2+Ax+ez+LSEEEJyDcUIMR1RGRkZHAIADPX24ckf/Te++e4rsenO76C7pRWBmmqs++dP4dzrrrbyqIQQQiyAYoSYzngxIgiHRvD8/z6IO9/7Qbz66BMAxvpLCCGEFAYUI8R0RJsmNDg46efjsRi6jrQAAHwlxTk7FyGEEHtAMUJMxeVywV9WCgAYmUKMAEB4ZAQAUFRMMUIIIYUGxQgxlaLSErjdiR+zkcHhKa8XSYoRXzGnagghpNCgGCGmUpJs0UQjEURHR6e8XjiU+BwrI4QQUnhQjBBT8Qvz6sDULRogrTJCzwghhBQcFCPEVERlZGRoKOP16BkhhJDChWKEmEpxQFRGMosRekYIIaRwoRghplJclhQj01VG6BkhhJCChWKEmEpxINmmyTDWC9AzQgghhQzFCDEVWRmZrk0zysoIIYQUKhQjxFRkZWTaNg09I4QQUqhQjBBTKdY62uv3w+XmjyUhhBQS/K1PTCW1JC+zGBGjvUBCkBBCCCkcKEaIqYgleZmi4AEgOhqWf2erhhBCCguKEWIqaisjiqJI3whNrIQQUlhQjBBTSYmRzAZWgMFnhBBSqFCMEFNJtWkyV0aAtEh4Zo0QQkhBQTFCTEVURkKqKiOJrBEf2zSEEFJQUIwQUxFiZFSFGKFnhBBCChOKEWIaHp9PjumGVLRpUp4RihFCCCkkKEaIaYiqCACMDmUe7QXSPSM0sBJCSCFBMUJMQ5pXh4agxOPTXp+VEUIIKUwoRohplATUj/UCQHiEy/IIIaQQoRghpuEv0yZGIiFWRgghpBChGCGmURJQnzECAJHRZGWEOSOEEFJQUIwQ05CekQG1bRomsBJCSCFCMUJMo7i8FEDCwKqGCHNGCCGkIKEYIaaRqoyoa9OEZQIrKyOEEFJIaBIj69evh6IoYy579uyZ8vrPPPPMhOsrioJHH30064MT+1Os1cDK0V5CCClIvFpvsGvXLlx88cXy39FodMrrfuADH0BRUZH8d01NDbZv347f/e53Wh+WOJDiQCpnRA0y9IxihBBCCgrNYiQajaKtrU3VdXt6esb8+0Mf+hCGh4cpRgoEkcCqtk2TGu1lm4YQQgoJzZ6RRYsWoaWlBfv378eGDRswe/Zs1be96aab8Jvf/AbDw5mjwYuKihAIBMZciPOQYkR1ZYShZ4QQUohoEiNbt27FjTfeiLVr1+KWW27BvHnzsHnzZpQnjYqZOOOMM7Bs2TLcd99901731ltvRX9/v7y0tLRoOSaxCVoNrNIzwpwRQggpKDSJkSeeeAIPPvggdu7ciSeffBLr1q1DZWUlrrnmmmlve9NNN2HHjh3Ytm3btNe98847EQwG5aWxsVHLMYlNkJUR1XHw9IwQQkghotkzkk5fXx/27duHhQsXZrxeaWkpPvShD+HrX/+6qvsNh8MIh8PZHI3YAM1ihJ4RQggpSLLKGSkrK8OCBQvQ2tqa8Xof/OAH4ff7sWHDhmwejjgM0aYJqY2DZ2WEEEIKEk1i5K677sL555+P5uZmrF69Gps2bUIsFsPGjRsBAPfffz/uuOOOCbe76aab8NBDD6G7u9uYUxPb43K54C9LJrCqFCMy9IyeEUIIKSg0tWmampqwceNG1NTUoKOjA88//zxWrVqFzs5OAMCcOXMQj8fH3Gbx4sU477zzcMkllxh3amJ7ikpL4HYntO7IYObpKYGojHh9Pri9HsSjMdPORwghxD5oEiPXXXddxs+vWbNmwsf27dsHl8ul7VTE8ZQkWzTRSATR5Dbe6YiMpK7n8/sxGlUnYgghhDgb7qYhpuBPmldHVZpXASAaDsvKGn0jhBBSOFCMEFMo0WheFTBrhBBCCg+KEWIKxQERBa++MgKkxntZGSGEkMKBYoSYgtzYqzIKXiB8Iz4/s0YIIaRQoBghpiA39mps04TZpiGEkIKDYoSYgqyMaGzTpILPWBkhuackGMC//mED1n7mE1YfhZCCgmKEmIKsjGhs08jKCD0jxALmrlyOmYsW4Iwr3mv1UQgpKChGiCnIvTQqN/YKIqGEZ4QGVmIFFfW1AIBgbQ3cHo/FpyGkcKAYIaYgxYjeygg9I8QCgrU1AAC3xyP/TggxH4oRYgpiSZ5+zwjFCMk9gbpa+ffKhhkWnoSQwoJihJiCrIzonaahgZVYQMUYMVJv4UkIKSwoRogppMSIxsoIPSPEQgJ1qdYMKyOE5A6KEWIKsk3DnBHiICrq6lJ/Z2WEkJxBMUJMQVRGQlorI/SMEItwud0or6mS/2ZlhJDcQTFCTKFYx9ZeIC0Onp4RkmPKqyrh8Xrlv+kZISR3UIwQw/H4fHK3jNatvWFWRohFBNPMqwArI4TkEooRYjiiKgIAo0PDmm4rKyP0jJAcI8yrPa3HASQyRzw+n5VHIqRgoBghhiPNq0NDUOJxTbdlZYRYhRjrPf72O1IUV8yoy3QTQohBUIwQwykJ6BvrBYBIKDlN46dnhOQWEXjW396J3uNtANiqISRXUIwQw/GX6RcjDD0jViEqI30dneg93g6AJlZCcgXFCDGckoC+jBEgbbSXnhGSY4JJz0h/Ryd625KVkRkUI4TkAooRYjh699IAQFiO9lKMkNwSTAaeDXR2pVVG2KYhJBd4p78KIdooLi8FoH1jL5DyjNDASnKNqIz0tXeivJqVEUJyCcUIMZxUZUR7m4aeEWIFLpcLgZqEGBno6ERvVQUAVkYIyRUUI8RwirMwsArPiMfrhcfrRSwaNfRshExGWVUlPL7Er8P+ri4UHw8AoIGVkFxBzwgxnOJAKmdEK6IyAjD4jOSOQG2yKtLVjXg0Jkd7y6oqWaUjJAdQjBDDEQmseto08WgMsUiiGkLfCMkVFfXJjJGOTgCJn10hpivoGyHEdChGiOFIMaKjMgKk+0YoRkhuCNYmxUhnl/yYmKipom+EENOhGCGGk42BFQAio4nx3qISlsdJbhB7aQY6UmKkT6awsjJCiNlQjBDDkZURHQZWIGViZWWE5IqK+kTGSF9Hh/yYqIxUsDJCiOlQjBDDyVaMhJk1QnKMNLB2pLdpWBkhJFdQjBDDEW2akI44eAByYyorIyRXyL007Z3yY0xhJSR3UIwQQ3G5XPCXJRNYdYqRMPfTkBwjPCP9nWlihPtpCMkZFCPEUIpKS+B2J36sRgaHdd2H9Iz4aWAluSGYrIz0T1YZoRghxHQoRoihlCRbNNFIBNHkVIxWhGeEYVMkF5RVVsDr8wFILMkTCDFSEgzAX1pqydkIKRQoRoih+JPm1VGd5lUg5RmhgZXkgkCyKjLU0ztm/UA4FMJwfz8AmlgJMRuKEWIoJVmaV4G00DN6RkgOkObVjs4Jn6OJlZDcQDFCDKU4IKLgs6mMcLSX5I5gXWpb73g43ktIbqAYIYYiN/bqjIIH0uPg6Rkh5hOsE4FnrIwQYhUUI8RQ5MbeLNo0kRA9IyR3iMpIf1rgmSBVGaEYIcRMKEaIoaT20mRfGWHOCMkFIn21P2NlhG0aQsyEYoQYSrYbewHupiG5ReylmVyMsDJCSC6gGCGGIsWIzo29QFplhJ4RkgMm20sjkMvy8iD4bM3HrsfKd19k9TEImRSv1Qcg+YUxlRHupiG5o6JejPZ2TPhcX1tCjPhLS1ASDCKUzB1xGlWzGnDZv3wao8PD2P7kX6EoitVHImQMrIwQQzHCMxJhzgjJESXBILxFRQCAgc7uCZ+PhsMY6Ep83Mm+kbLKCgCAv7Q0L6o8JP+gGCGGIisjWYWecZqG5AZRFRnq7UM0HJ70Or1tzh/v9SdH7gGgrnm2hSchZHIoRoihpMRIFpUR7qYhOSI11jvRvCoQrRonL8wrLkvt1qmlGCE2hGKEGIps0xgQB8/KCDGbQG1yW28GMZIP473+NDHCygixIxQjxFBEZSSU1aI8VkZIbhBtmskCzwT5MN7rL021aWrnUIwQ+0ExQgyl2ICtvWHmjJAcIcd6O/O7MlJczsoIsTcUI8QwPD4ffP5ENSObrb0iDt7tdstJB0LMQASe9bVnEiN5UBlJM7DWNDXC7fFYeBpCJkIxQgxDVEUAYHRoWPf9REZH5d9ZHSFmEhRR8J3Tt2kqZtTl5Exm4C9NVUY8Pi+qZjZYeBpCJkIxQgxDmleHhqDE47rvJx6LyTHLohL6Roh5BIVnJENlpK+9A/F4HD6/H+XVVbk6mqGkG1gBTtQQ+0ExQgyjJJD9WK+AvhGSC4JimiaDZyQejWEgWTlxqm8kvWoJ0DdC7IcmMbJ+/XooijLmsmfPnoy3qaiowA9+8AMcO3YMIyMj2Lt3L97znvdkdWhiT0Rf2ggxInwjHO8lZlEcKJcTW5mmaYB0E6szfSOiTdPXnoi8pxghdkPzbppdu3bh4osvlv+ORqNTXtfn8+Gpp55Ce3s7rr76arS0tKC5uRm9vb26DkvsTUkg+4wRAbNGiNlU1CWqIsP9/Yim+ZQmo/d4G5qXn+zYyoho07Ts2YeK+jqO9xLboVmMRKNRtLW1qbruxz72MVRXV+Pss8+WouXQoUNaH5I4BCP20gi4n4aYTbBu+owRgYyEn+HMyoho0xzdsxcnXXAO6uZSjBB7odkzsmjRIrS0tGD//v3YsGEDZs+e+of68ssvx0svvYR7770Xx48fx86dO3HrrbfC7c78sEVFRQgEAmMuxP6ILINsNvYKInI/DQ2sxBxSYmRqv4ggNd7r0MpIsk1z9M23AABVMxvg8XJpO7EPmsTI1q1bceONN2Lt2rW45ZZbMG/ePGzevBnlyXfE45k/fz6uvvpqeDwerFu3Drfffju+8IUv4Ktf/WrGx7n11lvR398vLy0tLVqOSSwiVRkxrk1DAysxCzV7aQR9bQmvhVM33oo2TeehIxgZGoLb40HN7EaLT0VICk1i5IknnsCDDz6InTt34sknn8S6detQWVmJa665ZvI7d7vR3t6OT3ziE3jttdfwwAMP4Fvf+hY+9alPZXycO++8E8FgUF4aG/mfxgkUCwOroZURihFiDgFdlRFntmmEGBkdGkbnoaMAaGIl9iKrOl1fXx/27duHhQsXTvr51tZWRCIRxNMyJ/bs2YOZM2fC5/MhEolMertwOIzwFOu8iX0plgZWA0d76RkhJlGhxTMigs/q6+Byu7PK0ck13qIieH0+AMDI8DA6Dh1G00lLaGIltiKrnJGysjIsWLAAra2tk37+hRdewMKFC+FyueTHFi9ejGPHjk0pRIhzESY5I9o0ETlNQ88IMYeAhjZNf0cXYtEoPD4vAjXVZh/NUNIDz0aHhtF5OFEZYfAZsROaxMhdd92F888/H83NzVi9ejU2bdqEWCyGjRs3AgDuv/9+3HHHHfL6P/rRj1BdXY177rkHixYtwrp163Dbbbfh3nvvNfarILZAihED2jThED0jxFwq6hLx7mrEiBKPy+s5zcQqWzTDISjxODoOHQEA1LEyQmyEpjZNU1MTNm7ciJqaGnR0dOD555/HqlWr0JlML5wzZ86YlszRo0fx7ne/G3fffTd27NiBlpYW3HPPPfiP//gPY78KYguMNLAKz4iPlRFiEmJjr5o2DZAIPqua2YDKhhk4vPNNM49mKGKSZnQ4sS+q49BhAOB4L7EVmsTIddddl/Hza9asmfCxLVu2YPXq1dpORRyJrIwY6BmhgZWYQXF5GfylJQCAgQxR8Ok41cQq/l+OJv9fdiYrI5UNM+Ar9kvhT4iVcDcNMQwjxUiEo73ERETGSGhgULYEpyMVCe/MNs1IsjIy3NeP4b5+AEDN7CbLzkVIOhQjxDBEmyZkRBx8iAZWYh6pFo26qgjg4MpIaWqsVyB9IzSxEptAMUIMweVypYxyRlZGONpLTKCiXn3GiEBWRhwWfJaeMSKQvhGKEWITKEaIIRSVlsiY/5AhnhGGnhHzCNbqESPOrIz4hWckbcpNjvdyoobYBIoRYgglyRZNNBKZdgOqGugZIWYSrFcfeCboTS4IDdTVwO31mHIuMxBtmpG0ykgn2zTEZlCMEEPwj3PsZ0vKM0IxQownKDwjKidpAGCouxfRSARut1tmlDgBf5mojExs0zD4jNgFihFiCCUGmleB9MoIDay5pKapER9c/2Xc+fIzeM8/Z94h5WSC9cnAs3b1YkRRFPS1JXwjTlqY5y8fmzMCpAyswdqaMQmthFgFd0gTQygOiCh4YyojkWSrp4gG1pwwY/5cXHTzDTjlPZfA7Um0IC6++QbsfWEL3nn1DWsPZwKpyoj6Ng2QMLHWNDU6arxXtmnSqpajQ8MY6OpGoKYadc2zcfTNvVYdjxAArIwQgzByYy/AOPhc0XjiYtzwX3fgiw9vxGmXrYXb48GezS9i59PPAgA+uP7L8BYVWXxK45F7ado7NN3OiSbWydo0ANBxMNmqoYmV2ABWRoghpDb2GtWm4TSNmcxdsQwXf/JGnHje2fJjO556Bk/fdz+OvrkXxYFyzFl2EurnNeOST30Mj3/vxxae1lj8paVSPGsxsALODD5L7aYZK0Y6Dx/F/NNW0jdCbAErI8QQ5F4aowysaZ6R9K3P+UjTSUtw2+O/x8q1F5v+WGVVlfjUz76Pz2z4KU4872zEYzG8+ugT+M/3/wPu//xtslw/MjCIP3zrOwCANR/9P5i5eKHpZ8sVoioyMjiEcCik6bZOrIzIquW4/5tcmEfsBMUIMQQjo+CBlIEVyH8T68lrzkdN0yysuPRC0x9r+cVrsGjV6YhGItj6+0fw/973Ifzvrd9A2/4DE66766/PYvuTf4XH68W1/36b9JI4nYo67RkjAkdXRobGV0Y43kvsA8UIMQQpRgzY2AtgzPIunz+/xYh4YSurrjT9sSoaElMkW3//CB74tzvRdeRoxutvuuM7GO7vx+yTT8T5119r+vlygdhLo9W8CjizMpJq04yvjHC8l9gHihFiCFKMGGRgVRRFCpJ8N7GKF7ZAdbXpjyWSR/tUGjcHurrxx7u+DwB496dvRk1To2lnyxXSvKqrMpIMPquphsfnM/RcZuGfZDcNkEphLausQGlFMOfnIiQdihFiCNIzYtBoL5DyjeT7eK/YdVJWVWn6Y4nk0QENxs2XH3oU+7ZsQ1FJMT64/stmHS1niMAyPWJkuK9fTno5YUeN2+OR/3/Gt1AjI6PoTeamsDpCrIZihBhCyjNiTJsGKJzgM1EZKausMN2XIfI1+jS+EP/uG/8P4dAIFq06HWde+T4zjpYzgnKsV7sYAdJbNfYXI+mBZuMrI0BqvJcmVmI1FCPEEIw2sAKFEQlfWhEcU/kpq6ww9fGCOs2b3UeP4Ykf/BQAcPm/fgaBpKhxItl4RgCgry3R4nKCb0S0aKLhMGLR6ITPy4V5rIwQi6EYIYaQGu01sjKS/56R8S9oZdVVpj2Wx+tFoCbhS9HTotj86wdweNebKAkG8IHbvmD08XKGFCMaA88EYmGeI8TIFJM0Ai7MI3aBYoQYgtEGVqAwPCPjX9DKTfSNCCESi0Qx3Nun+fbxWAwPrL8DsUgUyy9Zg2UXXWD0EXNCtpURI8d73R6PqUbY6f5fdiTHe1kZIVbDBFZiCKnRXuPESMozks9iZOwLWrmJlRFhXu3v7ISiKLruo3Xffvz1F7/CJZ/4KD7wlX/F29teQ6h/wMhjmkpRSbH8WdVTHQJSnpFsl+UVB8rxpYc3IlhXi4GubvS2taOvrR19bR3oPd6O3rY29B1vR29bB7qPtuj6nk01SSOgZ4TYBYoRkjUen09mgRi1tRdIq4zksYF1QmXExKyRlF9EX0VA8Jef/A9WXHIh6uc149JP3YSH//O7BpwuNwSSo82jw8NTvkBPh1EG1sYTFsvvSaCmGoGaasw+6YRJr7v7mc34+T9/UfNjTNem6Tp6DPFYDMXlZQjUVGOgq1vzYxBiBBQjJGtKkntpgKl/6emhEDwjVTMTYiQej8PtdqPcxKwRvebV8UTDYfz53p/hw9/+JuaessyIo+WMivrsBZnIaKmor8vqLOL7cfCNnXjw9v9E5Yx6VDTUo7KhPvH3GfWonjUTtXOasODMU3U9xnRtmlgkgp7WNtQ0zUJt82yKEWIZFCMka/xpG3uVeNyw+5XL8vLYM1KRfHfdeegI6uc1m5o1YpQYAYD2ZHm/amZD1veVS8RoczbPgRgJLq+ugsfrnXRKRctZuo+1onXf22jd9/aE65RWBHH7839GcVkZ3F4P4tGYpseYrk0DAJ2HDqOmaRbq5szGgde2a7p/QoyCBlaSNSUB48d6gfRlefkrRipnJCojR998C4C5BlYjxUhP63EAifaCk3JggvX6A88EQ719iEYiAFKmYF1nUfH9CKWtVygNak9Jna5NAwAdHO8lNoBihGSNf4qtoNkSyfOcEZfLhYoZiRfHI0KMmGlgzTLsK51Q/4D8fjupOmJEZQQABpKTOIGkoNB1luT3I1MarhKPS4NwSTCg+TGKk2JkZDhTZYTjvcR6KEZI1gjPiJEZI0B6ZcQ577y1UF5TDa/Ph3gshta9iRK9uWIkNU1jBKI64igxYoBnJP32QlDoQQTHTff9GO7vBwBd+2PEG4XRDG8UuDCP2AGKEZI1ZuylAVKjvfnqGRGTNP2dXfKdei48I30GVEYAoOdYUozMcpAYqTVGkA0kbx/MqjKiThgNZ1EZUdWmOZRs08xugsvl0vwYhBgBxQjJmuLyZCnYwMAzAAiLaRp/flZGxGho7/E2DPb0Akjup/Eav5/G7fVIf8OAzrCv8TixMhIwqFUlBF1WYkRlyyjUp78yoqZN03OsFbFIFEUlxVlPCBGiF4oRkjWpyoixbRrhGclXA6uojPQeb8dwXz/iscSkRFmF8ftp0tNXh5LCJ1t6jrUCACpn2j8WXVBhkIlXpLcGde7o8fr9stIxXRKsqIzoMrCWJts0GSoj8VgM3S3HALBVQ6yDYoRkjRQjhldG8tvAml4ZUeJxDCUj2strjPeNBOsS73gHurp0p6+Op6c1Ef7llDaNrzhNAGRrYO3IrjIivCaRkdFpRfywqIzoadOIquU05vKOQ4yFJ9ZCMUKyxoyNvUBaHHxJvrZpUpURALJiUV5lhhhJvPgZ5RcBnNemEX6RcGgk659V4fMI6DSwprwr07fMhBgp0dWmSVZGMrRpgNSOGk7UEKugGCFZk9pLY/Q0TTL0zILKyPJLL8Ttz/8ZK959kWmPkV4ZAYDB7h4A5phYxTv4AYMmaYCUgbWivg5uj/E+F6NJ382TLeI+KrKsjKjx74SyatMIA2tm8SXHe7mjJifUzmnCnGUnWX0MW0ExQrLGjI29gHWekYoZdbjm325FaUUQKy690LTHGV8ZESZWM8Z7jZ6kARIvpNFwGB6v1xHGx8YTFgNILYfLhvQUVpdb+69Rmfmiol00nIWBVUzTjAxOUxlhmyan3Pzju/FP9/8ElVkuW8wnKEZI1phlYLXKM3LtN26T2Sl1c+eY8hhuj0eaH8dXRswQI9K4adAkDQAoiiKFlBN8I80rlgIADm7flfV9Dfb0Ih6Lwe3x6Pp+BWpExoiaykiyTaPRM+JyueQbhdFhdZWRmtmNjqhyORmXy4Xqxlnw+LyYd+oKq49jGyhGSNaY5RkJW+AZWXX1FVhyziq5b6RuzmxTsheCdbVwezyIRiIYTC4nGzJRjMgWhYGVESDVqnHCRE3z8oQYOWSAGFHicblUTk/wmZZofr2VkaKSEvn36RZY9h5vQ2R0FF6fzxHfSyfjLyuFO1lNm7P8ZItPYx8oRkjWmG1gzVVlpGpWA973r58BADz23R8hGonAV+w35Zez2Nbb19Yhp1tk1ogZnhGDwr7G03PcGSbWQE01appmIR6P4/DO3YbcpxzvrdPeogqoiIIXyNFejWJEtGjisZhcOjkViqKg60gLAPpGzCa9wtW8jGJEQDFCska0aUIGx8GLX6DeoiLTS8culwvX/vtXUFxWhv2vvo5nf7kRnckFYvVzmw1/POkXaWuTH5NtGjPEiMmVEbu3aUSLpm3/gWmrBGoZyCISPqgyCh5IhZ5pbdNo9XLRN5IbSgKp72PjiYvh8fksPI19oBghWeFyuVKR04a3aVLv5sxOYT372g9g0VmnY3Q4hN9+9VtQFEUaHc3wjchJmtY0MWKSgdXt9chqi+GVkeR4b7XNKyMpv8hOw+6zr6MDgL6sEbVR8EBqN43X5xvTepmO1CSNOvGV64V5Xr+/IP0p6aLSW1SExhMWWXga+0AxQrKiqLRE9j9DBouR6GiaGDHRN1Izuwnv/ZdPAwD+dPe96DqaKFd3HDwEAKifZ2JlJGkABczzjARqquF2uxGLRjHU3WvofacqIzMNvV+jEX6Rw9uNadEAaZURjSmsbo82cRgOjSAaiQDQFnymZi9NOiJrJBeVkaqZDbj10d/iCw/+suD24aRXRoDUz2ahQzFCsqIk2aKJRiJjxINRjA6HAJjnG3G5XPjQ7V+Bv7QEf9/6Cl787R/k59pFZcSEX87jM0aAVJumtCJo6H4a4RcZ6DQufVUgDawN9jU9ur0ezD75RADGVkb0bu4t1yEO9QSfaRYjOaqMeIuKcMPdd6CyYQYaFs6X24sLhfGCkibWBBQjJCv85dOvKM8GmcJqkhg57/prMf+0lRgZGsJvv/6tMS/WHQfMa9NUTFIZGbOfprLSsMeSfhEVLQGt9La1Ix6Po6ik2JQpICOYtXghikqKMdzfb0jGiKBfbu7VZmAVlZTBrh7V4jAVfKa+MiLSV9V6RtrefgfxWAy1s5swd+Vy1Y+jlQ985V+lOASAmqZZpj2WHSkOJt7AiUmqZooRABQjJEtKTDKvCszMGqmbOwfr/vlTAIA/fvv78l2+oD3Zpqma2YCiEmMfX4QdpVdGFEVJ7aeprjTsseQkTdLjYCSxSESmiNq1OiJbNDveNLQypLcyIv0iGvw7esZ7tVZGhnr7sPUPfwQAvO8L/6T6cbSw6uorcNYH3od4LIbetoQQr25qNOWx7IpI0t23ZRvi8ThqmhptK+RzCcUIyYrigIiCN6sykmj9+IqN9Yy43G5c982vwVfsx94XtmDLgw9PuM5wX78UB7UGjjt6i4rkFt10MQKkB59VG/Z4ZlZGgLQdNTadqBHm1UMGtmiAlLgL1NRo8j2k0lfVfz9COsZ7pRiZZi9NOn/+4X0YHQ5h7splWHbRBapvp4bZS0/Clbd+HgDw+Pd/ij3PvQig8CojIlCx59hxtL9zEAAwhyO+FCMkO7SWgrUSNqlN864b/wHNK5YiNDCIB9bfOeX1RFm/3sBWTUWyKhIOjch3vILUsrxKwx5PtAX6stxUOxV2H++VYWc7jDOvAsBAVzfi8Tg8Pi9KKytU307LWK9AekY07KdJRcGr/7850NmFZ3+5EQCw7rO3GOZdKq+uwo133wFvURF2/OVv+Ot//1IaxWsKrDIipmlC/QM4vPNNAMCc5dxTQzFCsqI4qfJHTGrTiP00RQZWRurnNWPtp28GADz8H3fLcvFkiFZNnYETNZOZVwVmLMsTlZEBs8SIjbf3lldXoXZOEwDgkEFhZ4J4NCbFo5ZWTUAsLdRQGdHTppEbezXmqvztF7/GQFc36uc146wPXK7ptpPh9njw4btuR2XDDLQfOITffPV2AEDX0WMACrEykhIjh3Yk0oA5UUMxQrJE7qUx28BqoGfjtPe9B96iIux9YQu2PfxYxuuaURlJBZ5NFEEya6TGuB6y8IyYXRmptmFlRJgDj7/9juG7k4DU1l0tJlZ9bRrtwWd62jTi+k/9+OcAgHf/48dlXole1n32Fiw88zSMDA3hfz73ZSmOupOVkepCEyOiMjIwIKt1c5aepGvhYj5R2F89yRqzouAFIvjMSAOreDF4e9vr01633YSJGjWVkfIqA8VIvfZ34lqQbZqZ9ssamWNSi0agx8SqJ5pfBJ9p8oxoDD1L56UHH0LHoSMI1FTjghuu03x7wfJLL8Saj/4fAMBvv/YttCU9EgDQdbQVAFBRX2e4J8zOCM/IcP9AIhF4eBjF5WWm5Bk5CYoRkhVSjJjwrhMwZ7RXONfFC38mRPCZsWJk4livwOjNvelbZftMmKYBUm0asxasebxeXPHFz2Hx6jM033auSeZVgRjPFAJDDXoqI8O6Rnu1e0YE8WgMj93zIwAJf5UwXGthxoJ5+NDtXwEAPPPzDdjx1DNjPh/q75fG3Gqbh+YZiaiMjAwMIh6L4cjutwBwTw3FCMmKeackVmCr2T6qh3DI+NFeUXVQI0Y6j7QgHouhuKxMV+z3ZIgleZNVRow2sOoJ2NKKECNllRWa4srVcsJ5q3H+h6/Fdd/6uqb4cLfHg9lLE8ZA8yojImtEXWXE5XIhUCOW5OkwsGqpjIgMII1tGsGOp57Boe274C8txaW33KTptsXlZbjx7jvhLy3F37e8gse+9+NJryd8I4U03is8I6LadTjpGyn08DOKEaKbBaefgqaTliAcGsHrjz9lymPIaRoD4+BlZaRnejESi0TQ3ZIoJxtVHVFTGTHKwFohzJJd3YanrwpGh4blL1YzJmoq6hN+jGBdrabqSMPC+fCXliA0MIi2/QcMPxeQ2tyrNkW0tLICHp8XQOJ7opZU6Flu2jSCR+++FwBw1lWXq/759xX78Q93/hvq5zWjp/U4fvXFr8kwv/GkJmoKwzfi8flkZlEoWU0+tCMxUVPo4WcUI0Q3F3wk0Uve9vCfJoyoGoWImDe0MqKhTQOkJmqM2t4rA89aj0/4nGzTGGRgTbUEzKlcCcwc701/oT/98nWqbyfyRQ7v3G2aEBPPqxBM0yG+H4PdPYhFo6ofR07T6DCwjmQhRt559Q3sfmYzPF4v1n32lmmvP2vJInzuN7/Aye86F9FwGPf/y22y2jcZ3XKipjAqIyXJ9NV4PC5Tqw8np7waFs43pbLoFChGiC5qm2fj5DXnAQCe2/Bb0x4nLEPPjBEjRSUl8p3JYJc6MSK3987LvjLiLy2VPePJKiPiF3dp0Jj9NGLKw3QxYuJ4b7pfYemF58tx8ukwK18kHWEKVlsZSZlXtZmJUzkjAdVTF8LPNZplBtCfvvtDxGMxLL/4XVPGxLtcLpz/4Q/hs/97HxoWzENfewd+dsvncWT3noz3nWrTFIZnRFS2RgYHpUDu7+hET+vxRFvx5BOsPJ6lUIwQXVzw4Q8BAHY/s1muHjeDiMGeEVFxCIdGEA6FVN3GyIV5YpIm1D8waS/f6P00esySejBzvDdQmxIjPr8fKy69UNXtzDavAilTsFrPiLie1syX0MCA/HuJSjEm2jTZVEYAoO2dg3h506MAgMs+/+kJnw/UVOPmH/0XrvjiZ+EtKsKuZ57Dd676MN5++dVp79tpwWdnXXU5Lv7EjbpvL4S0aLsJUuFnhduqoRghmimrrJDl8r8l0xrNIpXAaoxnRBhD1bZoAKDjgHFtmkwZI8D4/TTZt2rkHpRctWnMqIwko/EPvL4DAHCGilZNWWWF9DiInrwZDHQmfB8+v19VBkhAVkbU+0WAxHSLmIpRM97r9fvh8Sa8KdlWRoBETHw4NIJ5pyzH0gtTMfEnnn8OvvD7X2HJOasQDo3gwX//T/zin78kf4anQ1ZGGu3vGfF4vbjqK/8X7/nMJ1ExQ9tyREGpTF8dO314aDvDzzSJkfXr10NRlDGXPXumLsPdcMMNE64fUvlulNiXVR98P4pKinHkzbfwzivTZ3VkgxjtNWpRndj5osa8KhCr1asbZ8Lj82X1+JkyRgRGjvfmTIwkv55KE8RIebJN8+wvNyIei2HeqStQM7sp423Ero/2A4dkYJgZRMNh2UJRM20lKyMaMkYEwzL4bHoxIsZ6ASA8nP3v3P6OTjz7q8Qbj/d+7hb4S0tx5W1fwMfv/TYCNdVoeWsf7r72Rrz0u02a7re39TjisRj8pSWGBv2ZQVXjTGk+1jPqDIxNX01H+EYK2cSquTKya9cuNDQ0yMu5556b8fp9fX1jrt/cXNjBLk7H4/Ph3OuuBgA8Z3JVBDDeM6LVvAokfhGPDA3B7fGgdnZ25eRMkzQCU8RIu3MNrGKXS8uevdj30jYAwOmXvyfjbZpXJt5hHjSxRSNIjfeqESP6lxaG+tQvy/On7Ywyyrz7zM83YLC7B/XzmnHb4w/K3wPP/nIj7vmHj6M9WUHUQiwalf8X7N6qEWsFAKC0Qv0uonTS01fTObpnL2KRKIJ1tbbdfm02msVINBpFW1ubvHR1Zf5PpSjKmOu3t0/9S5jYn1PXXYJgXS1629rxxp+fNv3xjM4Z0SNGgDQTa5atmpQYmboyYmTWSM6maVpbk49XK9sDRuAvK5UtuoGubrzySCK+/7TL1mbclJsL86pAmFGDKkys4h21VgMroC2FVVRGshnrHc/o0DCe+kkiJr68ugr9nV346Sc/h0fu+h5ikYju+3XKeG9tWjWuTMNixHSmqoxERkZx7O9vAyhc34hmMbJo0SK0tLRg//792LBhA2bPzmzqKy8vx8GDB3H48GE89NBDOOkkbid0Mucnx3mf//UDiEcnzw4wkojRnpGa7MRIfZYTNak2zfSVkbLqyqwey+3xyBaH2WJksKsHkZFRuN1uVCS/RiMQUyojg0OIjIxi51+fQ2hgEDVNszDvtJWT3sbldmPOsmTYWS4qI+3qg8+yaZtpGe/1myBGAOClBx7Ca3/6M7Y9/Bi+c9WHsffFrVnfp8jxsXvwWXplpKwq28rIxMTqwzsKu1WjSYxs3boVN954I9auXYtbbrkF8+bNw+bNm1FePrm7e+/evfjYxz6GK664Atdffz3cbjdefPFFNDZm/qErKipCIBAYcyHWs2jVGZi1eCFGh4ex5feP5OQxTTOwqhzrFciJmiyDz9RURuSyvCzbNOXVVTJ9dTBD1oNRmDHeKyoJIiAsOjqK7cmK3FRG1oaF81BcVoaRoSEcf9ucsLN0xI6ZgIo2jRBXeto00jOipk0jJ2mM3RkVi0bx6y//G37z1ds1C/qpcEplpCatRau7TSP30kz0MYkqXqHGwmsSI0888QQefPBB7Ny5E08++STWrVuHyspKXHPNNZNef8uWLfjVr36F7du347nnnsMHPvABdHR04JOf/GTGx7n11lvR398vLy0tLVqOSUzigo8kxnlf3vTohDKjWUgDq9FtGo0vzkZN1FTM0GBgzXJZnngXPtjVAyUez+q+1CDEiJHjvUKMDKallb7yx8cBAMsvXTOpsVm0aI7s3JOTr1sIi4ppxIi/rBT+0kSolR4Da0jDfppUxoixlREzcErw2Zg2jc4WavpemvEcSsbCN510giEZQ04jq9Hevr4+7Nu3DwsXLlR1/Wg0itdff33a6995550IBoPyMl0lhZjPjPlzceJ5ZyMej2Pzhgdy9rjhkPUGVsCYykhJMChfjHrbpl5alxIjlbofC0iJEbMW5I2nt9X4iRpZSUjzWBx4bTs6jxxFcVkZll50wYTbiOTVgzvMb9EAqcyQwDRtGvH9GBkckl4oLcg2jSoDa7JNo3MvTS5xQmXE7fGgOu18ZRp2BKUjxMjwJG/mOg8dwXBfP3zFfsxarO41NZ/ISoyUlZVhwYIFaE2a16Z9MLcby5Ytm/b64XAYAwMDYy7EWs5Phpzt+utz8pdHLjCtMtKtLeeh83BivLesskK3eU0syBvs7pEx95MxZFCbJlif3EtjcuCZoNvENs148fjqI4nqyGStmrkrlgEADm0337wKpBtYM1dGgrXZmYlFZURNnokRe2lyhcgaCdbXwVtUZPFpJqeyoR7etLH+Ur0G1immaQSH5Ihv4eWNaBIjd911F84//3w0Nzdj9erV2LRpE2KxGDZuTIx43n///bjjjjvk9b/2ta/hkksuwbx583DKKadgw4YNaG5uxn333WfsV0FMpby6Cqe9by0A4Nn7zR/nTUd4Rjw+ryGlSy0be8ecIzQi2xB6J2rUjPWmny1bA6t48esz2bwqMGO8d6rpE9GqWXjW6WMCqEqCQdTPS3x/xDZUs+lTaWCV5lUdkzRAuoFVfWVEBKXZmaGe3sTovNttymi4EaSbVwH96cglUySwCoSJdU4B+kY0iZGmpiZs3LgRe/fuxQMPPICuri6sWrUKncn+55w5czBzZmrHQFVVFX72s59hz549eOyxxxAMBnH22WdnDEoj9uPsa66Ez+/HoR27cfCNHTl97EhaOTvb6khJMCBDiwa7ezXfXk7U6GzVpCZpJi7IS0eIkdJgMKsx2VRlJEdixMzKyLgNt90trdj/yutwu9047bK18uPNyxNTNB2HjqhOAc0W4f/wl5bKisRkBHRGwQukZ0TNaK/wjDigTQOk+0bs2aqpaUqIESEkSyv1tWmEkJxSjOwUYqTwpk41iZHrrrsOjY2NKC4uxuzZs3HdddfhnXfekZ9fs2YNPvrRj8p/f/7zn8fcuXNRXFyMmTNn4rLLLsMbb7xh2OGJ+XiLinD2h64CkJuQs/HEolG53TRb34hoe4QGBnXlIqR8I/p21KitjIT6B+TXrNcoBwAVySV5uauMJNqvVTNnZMwA0UL5uGmadF55OJE5kr7JV+aLbM9NVQRIVM1EBUIIwMnQuyRPkL4sbzqc1KYB7B8LLyojQizoadW6XC4pEqcWI4nVBfXzmlUl7eYT3E1DMnLqe9+NQE01uo+1Ysdf/mbJGSJJf0W2lRG95lVBtsFnaqLggbH7abIRI4EcLckT9LV3IB6LwVtUJEVEtogleQOTvIBvf+qvCIdGMGP+XMxemngnKcyrh3LUohHIFNYMwWfZLi3UY2B1QpsGsP/CvNo5iXMdTu458peWava3+MtK4fYkWs2T5YwAie+x+D1TaNURihGSETHOu/nXD8htsrkmIiLhs9xPY5wY0dumUVcZAVIm1kAW+zoqZMBWbqZp4tEY+toTj2VU7398zkg6o0PD2PXXZwEAZ1yxDi6XS/bac1kZAdRFwqcqI/oqVSKbwuf3w+vPnLvj1DZNtV3bNMmx3qN79sqqpVYTq0hfjYyMIhoOT3m9QwUafkYxQqZkyTmr0LBwPkYGh/DyH/5o2TlSkfDZBZ9lK0baDyayRmrnNMl3OFpQWxkB0kysOrNG3B6P/HpzVRkBUuO9RvhGigPl8PlFFPzk37NtyVbNyrUXY9YJi1ASKMfocAitf9+f9eNrQbReMo33pjwj+r4fo0PDqRfCaaojzmvT2He81+VyyYwRMX4LaG/VTDdJI5C+EYoRQhKc938+CADYuumPlpZ7U5HwBlVGNGzsTae3tQ2RkVF4fT5UzZo5/Q3ScLlcaYFn01dGsl2WV15dBbfHg3gsZlhSphqMNLGKqkhoYHDKUei/b30FvW3tKKuswHs+kwhTPLJ7T86reKk2TYbKiAF7gtQGn5kVB28WXTYOPgvW18JX7EcsEkVP6/FUC1VzZUSkr2YWI6LFWGhJrBQjZFKqZjZgyTmrAAAvbPy9pWcJG5Q1km1lRFEUdCTzRrRO1JRXV8Hr8yEej6sKIct2WZ5cVd/VnZMUUkG3geO9skWTwfCpxON47dEnAAAnnnc2gNy3aIBUtaNiCgOr1++XkxR6DayAet+I9IwYHAdvFmIsvLi8THeOj1mIFk33sVbEYzEM9fYC0NGmSX7/J0tfTefYvrcRGRlFaUUQtc36zPJOhGKETMpZV10Ot9uNfVu2oevIUUvPYrhnRONemnSkb0TjwjzhFxno6FK1YHAgy6yRYHKSxuwFeeMxtDKSNIMOTBNQ90oyAE2Qa/MqkLafZgoDazBpxI2Mjma1SkHteG9xmXPi4AEgGg6jty1RMbTbwjzZokn+Hhzu1demKZXpqxP30qQTj8Zw9M23ABRW+BnFCJmA2+PBmVdeBgDY8uDDFp/GPpURIOUb0bqjRotfBACGkjkoAZ1tmmwnN/RiZPCZMO9OJx7b3jmIw7velP+2ojKSCj6bvDIizatZfj/ksrw8a9MA9vWNiLHeriOJ8w3rbNMUBzMHnqWTSmItnFYNxQiZwEkXnIOK+joMdHVj19PPWn0cGXzmm2aCYDqMECMdB/RN1MhJmrbp/SJAytei18Cazar6bEhljRghRpKVERVtDVEd6TxyNKceGcGAjISfvDIizatZtGgAdSmsbq9H/l8ZcZAYsevCPCFGOg8nKiN62zQy8GyaNg2QmqgpJBOr/nhHkres+uD7AQDbHnpUuvetRFRGfCVZipGk/0Lrxt502nWmsKbGetVVRrJdlifFSHtuxnoF4usrCZSjOFA+bX88E5nGesez9Q9/RM3sRux7cavux8sGIfpKggH4iv2ytSgwShzK/TQVU1dG/KVl8u+jw87wjADpJlabVUZmjxcjOqdppomCT0fEws9atHDSn6d8hJURMoaqWQ1YcvZZAIAtv7dunDcd8R8xmzaN2+OR72S0LslLpyPZpgnW1cpSuBpSbRp1lZFsl+VluwdFL+HQiDy7WAyoF+kZUfE1REdH8ch/3oO3nt+S1WPqJX0T72QTNcFJtg/rQU1lpLg88XMZGRlV5U+yC6JNY7eskZrZiUqN8M6Jyoju0V4VYqT3eBu6j7XC4/PijCveq+lxnArFCBmDNK6+9LLlxlVB2IDR3tLKINxuN+LxuDSg6WFkcEi+oGjxjVTO1FYZEbkaJcGArv00wjMivAy5JLW9V9v483jKk56RqTJG7IYwsU62ME+Iw6zbNCpGe/1J86pTJmkE3Ufs16Ypr65CcXkZ4vG4rNykPCOVmu5LhJ6pNTD/7Re/BgBc8qmPoShL874ToBghErfXgzPfnzCuvmQD46ogEsrewFpenSj5D/f2ZZ1B0aFjR43WNs3IQNp+Gh3VkdSLX+7FiFEmVi1tGjvQnxR+gUlMrEZF86sZ7S0WgWcOSV8ViMpIZUO9IRu6jUC0aHqPt8l9VqJNo3VZntrQM8GWBx9G55GjCNbW4Lzrr9X0WE6EYoRITjr/XGlc3f3X56w+jsQIz0jAAPOqQOuOGrfHI8v0Pa3qxEj6fhqtvhGX2y1fyK2ojBg13qsmZ8RO9GcwsabaNEZ5RqZ+IZSTNIPOEiMDXd0Ih0bg9nhQ1WDc5udsqBGTNIdb5Mdkm6bCnNAzQSwaxRM/+BkAYM1Hr1e1k8jJUIwYwCnvuQSf/Ok9uvv7dmHVB68AALy8yR7GVYERnpEyA8yrgg6NJtZgXS3cHg+ikQgGNbzLT6WwVmo6n1XpqwIjKiMlwYBcRGbF16AHYU6dLPhM+l+Mqoxk8Iz4k3tpRhxkXhXI8d7Z9vCNyEmatJa1aNOUBAOaKjiiMqLF1P3G40+h5a19KAmU46KP36D6dk6EYsQA3v2PH8fi1Wfi1Pe+2+qj6CbduLr1949YfJqxyNCzrNo0xlVG2jUuzBMtmr62DiiKovpxRNaIVpErXgxznb4q6DWgMiKqIsP9/RmXitkJUcEJjDOwjt0TlF1lZLgv8UKoqk3joLFeQWphnj18I+PHeoFEZSOe/H+lpVohPCPThZ6loygKHrvnRwCAc667CpXJlRJaKKuqRMOiBZpvl2soRrIkUFsjX5ScHFCz6qor4Ha7sffFrfLdiV0wIvRMmCGNESOJiZq65jlwuVzTXl9O0rSpa9EI9GaNBGqtmaQRpNo0+qdphBjJJi031wg/yHgDa3l1VcI8HYtlXZkTbZriQPmUP3upNo0DKyMt9hrvFWbadDGixOPy+6C2VePx+aQJVU3OSDpvPb8Fb297DT6/H5f+48c13bZqVgP+9Q8b8PkH/seQ7B8zoRjJkgWnnyL/3rzCmdG9bq+9ElfHEzHAM2JkZaS75RhikSiKSorl8rtMyMqIyrFegd6sEVEZ6bfALwKk2jTBulrZatGK08yrANCf3Dk0PoXVyD1Bwm/gdrtRnPQgjCfVpnFuZcQuEzWTtWmAtIkalf83S5Lpq/F4XJdI/NN3fwgAOOOKdaifp86rVhwox8fv/Q6CtTXweL22r45QjGRJuhipmtmAYH2dhafRx8kXnItgXS36O7uw6xn7GFcFRlRGAgbspRHEozFZPapXsaNGaxS8YFBn1ohRZkm9DPX2YXQ4BCD1tWtFS8aIXZCVkXEGViMrVbFIRD63U0XCO7lN0yXbNNZXRkqCQZkl0j2uWizM5aUqKyPC4zMyOKipVSs4vGM3dj79LNwej9xOnQm314MbvvMtNCycLz9WbcCKBjOhGMmS+UkxIsZFndiqWXX1+wEkjKt2DEmScfBZGViTYqTHmLK/bNWomKhJjfXqrIxoNLAKQWxVZQRIa9XM0pc1Uu7Iykji+S6rqoTH55Mfl5URg/YEhfozm1iduJdGYKf9NLXJsLO+9g4ZaCcYkpURdWKkWEP66lQ8/v2fIB6LYfklazBn2UkZr3v1V7+IxavPxOjwMPZt2QYglXVkVyhGsqC8ugoNC+YBAHY89QwA521ZrG6cicVnnwkA2PoHexlXBWEDpmmMbNMAqR01aiZq9FZGhqQYqdZ0O6PSPrMh2/HeoKyMOEeMDPelzLbp1RGj9wQNT7O5V4gRp4WeAYkWKJAQWtMtAzSbqVo0QMpIrDaFtVSmr+pfj9C2/wBe+WNiB9N7P/ePU15vzceux1lXXY54LIZf/d+vY8/mFwEYsy/KTChGsmD+aSsBAMf2vY03n0t8w+c6zDdy1gcSiat7X9gi+7V2Q3pGiu3hGQG0TdTorowk2zRq+9KCoMWeEQDoTeap6B3vTaWvOkeMACkBGEgzsRotDlPjvVO0aZIJrE6sjERGRqVos7o6MlnGiGCoR1ubRmv66lT8+d77EA2HsfDM0+T0YzrLL70Ql/3LpwEAD/3Hd7HnuRdS/xcpRvIX4Rd555XXcWhHYm1500kn6IrvtoJ046qdElfHIz0jOiORvUVFMnDIsMqIbNNkFiMen0+aMTV7RnQaWFPr6i1s0xzLrjLitMAzgXjO0/fTBGX6qkGVkaQYmSr4zMltGiDdN2KtiVW0adInaQRa2zRa01enovd4G174ze8BAOs+e8uYiarmFUvxD3d8HQDw3K9+ixc2Pggg+/+LuYJiJAuEX2T/K6+j89ARDPX2wVfsx6wliyw+mTpOftd50ri6+2+brT7OlEjPiF9fZUS8mMci0azfmQhEZaR61syMFRuRCxAZGZW/wNQymMwZKQkGxngQMuFyuxGoTbyQWypGWlsB6B/vlQZWp1VGJhnvFQZWo4RVSO6nyVcxYg/fiNzWm6lNk+PKCAA8/bP7MTI4hKaTlmDFpRcCSBh+P3rPf8Dn92P3M5vxyLe/J6/fczwhRgJ1NbZ+o0wxopPSiiBmLV4IAHjn1TcAQFZHmlc4w8S6+upU4qodjasCURlxezyqX5TTKUsaQI0yrwKJrboivKh2ztQ7arQuyEtnzH4aldWR8qpKS9NXBdmksLpcrlRbzWFiRAiOYL35lZEpPSOlzvWMAPYZ75VtmknEiNhMXarSM5KqjOj3jMjH7u3DM/+TWKK39jOfRHl1FT5+73cQqKnGkTffwoYvrR8zQj7Y1YPI6CjcbjcqdE635QKKEZ0Iv8jx/QfkL/1D24UYWWbVsVRT3TQLS85ZhXg8jq2/t2+LBgAio6Py73paNcIAavSLszCxilaN2Akza8kinHDuKpz5/suw6qrLAWj3iwDJ/TTJX3oBleO94kVwsLsn64WA2SDESOWMGXC5tf2aKQkG4E2KzgGHRMELJmvTiCpPtkvyBHI/zVSekXLnekaAtDZNY3Zbn7PBX1oqvT6dRybxjCQFoVoDa2ovjf6N4ek898vfYKCrG3XNs/GFB3+JGfPnovd4G37+T/8X4VBowvWlb6TBvhM19q3Z2Jz5aX4RwaEduwE4Y7z3rCvfBwDY9+LL6G5ptfg0mYlHY4hGIvD6fPAVF2sudRptXhW0HzyM5hVL8f4vfQ7v/9LnUF5dNWUZtOPwEV2PMdjTi2BdrerKiHgR7LOwRSMePxaJwuPzIlhXg762DtW3lVHwff1yU6pTGN+mKausSAkrow2seesZEW0a6yojNUm/yGB3z6S7ZMSbBNViRMdemkyEQyE89ZNf4AO3fQHBulqMDA3hvk9/YcrqW0/rcdTNnYNKG/tGKEZ0suC0lF9EcHjnbsTjcdQ0NaK8psrWUdYnrzkPAPDKI49ZfBJ1REIj8Pp8KNIxUWPkxt50juzegzOuWIeKtKC7eDyOoZ5e9Hd0or+zCwOdXeg93o6XHtik6zG0Zo2IyohRmRZ6UeJx9La1o6ZpFqpmztQkRkTGiJWjyXqRKaxJURhIjvUO9fQatnxS5oxMIkZcLpfz2zTJ8d6qmQ2y5ZhrhBiZzC8CpC3LqwjC5XZPm6wrxIjajb1q2PK7h3DudVejpqkRv/zCV9G6b/+U1+3JcrotFxS8GAnW1Wru5RYHyjHrhIRJNV2MjA4No23/AcxctADNy5di9zP2NIUG6+swc9ECxONx7H1xq9XHUUV4ZAQlwYCu4DOzKiNbfvcQeo+3IR6NYaCrC/0dXYa3R7RmjYhMi74O9S/+ZtF7vC0hRmY14OAbO1TfTpTHneYXAVKVETHaa0bmiyj1T9amKSotkX93amWkv70T0XAY3qIiVMyoky2/XDLZgrx0RHXK7XajJFAu/z0VRk3TpBOLRvG9629GcVmZzPWZCpn7Y+M2TcF6RtweD26699v42l8eVp31L5h3ygq43W50HDw8ofR6cPtOAPbOG1mSDDk7smvPtP+J7ILY3KvHMyINrMnpFKOIRaPY/cxm7Nn8Io6+uRf9HZ2Gv4vTmjUixIjVlREgfaRQ2y9AJ6avCkQEf3l1Fdwej+GBZ0DmNo3wi8QiUcdsOx6PoiiydWxVq0ZM0nRN4hcBEv/3hRlVjYm1xIAE1skI9Q9MK0SAtE3aNq6MFKwYicdiUGJxuN1urP7glZpuu+D0iS0aweHtCd/IHBsnsYqwHKdURYCUiVVPCqtZlZFcoDVrpKLOHp4RQH8Ka7BWZIw4T4wMdSfaMW63G+U11WmTNEZWRpIG1sDEyoho0Yw6cEleOlaP92ZKXxWI8d7yyspp70+MYRstRtTS7YCskYIVIwBkeMwZV6zT9I5bipFXJ4oRURmZffKJcHs8BpzSWFxuNxavTlRG9r7gHDESzmI/jaPFiFiWV6NumiYg96DYQIwcS2aNaJyKcHJlRFEU6RUL1takLfwzvjLiLy2ZMOruT6avjujYDGsnrA4+m65NA6Qty5umMuJyuWTFyioxIqZpKtmmsSf7XnoZnYePoiQYwCnrLlV1G39pKRpPXAwAeGfbRDHScfAwhvv74S8twUwbrmxuOukElFVWIDQwiMM7d1t9HNVE5OZe7QbWlBhx3oub9IxUqRMjFXUJM22fhVHwgo5DiQmiGfPnarqdTF/tsr7VpAfh1wnW1aa1aYz7WkYHhxBPGibHR8LLsV5WRnTj9fvli3aXCjFSVjn5VJPAX1Yq35gakTOih962dsTjcRSVFGteL5ErClqMKIqCF3/7BwDAOddepeo2c09ZDo/Xi66jLehtm5gdoSgKDu94E0AintduLDkn0aL5+9ZXLM2h0IoIPvPp8IwETMoZyQWpaZrpxYjL7ZYVFDtMorT+PeHur541U75IqiFQ48z0VcFA2nivGQZWRVFSKazjfCOyTeNQ86rAyuCzmmQlL9Q/kDE1eViKkcqM9yfaaZGRUct8PLFIRPob7dqqKWgxAgAvP/QnREZG0XjiYlXiIZNfRCCTWG3oGznBgX4RIM3AqrFNU1RSIuPajTaw5gItBtbyqkp4vF7E43FbTKKE+gekYG9YqL5KKCojdvga9CCER3plxOgdO1OKEZkx4vQ2jXWVETV+ESBtWd40bRozJmn0kPJw2bNVU/BiJNTfj9cffwoAcM6Hpq+OLDhjYtjZeFJJrPYSI8XlZZiTDGTb+8IWi0+jDb2eEVEpCIdGJk0mtDuiMlISKJ82Cl+88FmdvppO6763AUB1y9LlcqVVdxwqRkQKa11tWvqqsW0zuSxv3H6a4jKRMeL0ykjCb1RWVampqmYEqRj4ySdpBENiP810YkSmr1orRlKbtK1Lts1EwYsRIGVkXXHphRnL4UUlxZh90okAMldGDu9KtGnqmmerTujLBQvPPB0erxftBw5ZMrufDXo9I042rwKJd8CxSCIsa7rgM+lPsIFfRCBaNTMXqxMjpRVBmWLrRI8PkKqM1DXPhj+Z+2GkZwSYerxXGFid3qYZHR6WbbrqxtxWR+SCvAx+ESDVppm+MpL4HhmVvqoXuaKBlRH7cvTNt3B455vwFhXhzCsvm/J6c1cug8fnRU/r8YwR6qH+ARzffwCAvUZ8hV/EaS0aIM0zolGMmJW+mkuGensBTG9iFXk5/QZObmSLECMNi+arur6oJAz19Np6eWMmhBhsPCFhdB8ZGjK8KheaIvjMX+bs9NV0Ur6RHIsRtW2aXpWVkaCxe2n00pNc1knPiM0R1ZHVH7xyysVe81X4RQSHxZ4aG23wlfkiDhrpFQjPiOY2TR6IETUmVq/fj/M/8iEA9mrBiYjqWYsWqrp+wMFjvQLRkhFCwYwAuuEpPCPFDt9Lk05Xi1iYZ5EYUVkZmV6MGLuXRi96QwhzBcVIkjf+/DSGevtQ3TgTJ5539qTXEftoMvlFBDKJdbk9NvjWNs9GTdMsRMNh7H/lNauPoxnhGdFqYC1LVhMGexwsRoSJNUOb5uxrr0TljHr0tB7HS7+zzxbm9gOHEItGURIMoHLG9OvLZcaIQ/0iwMTJGTMmm8S77PGjvfliYAXSKiOzczdR4/F6ZeVgOjGiNmdETNNY7RnRG0KYKyhGkkRHR/HypkcBAGd/6AMTPu/1+zFn2UkA1FVGxAbf2ctO1LxC3QxOSLZoDry2Q76wO4mIztFeYYbMi8rIFG0af2kpLrrpIwCAJ3/0c1ttuo1FIug4eBgA0KDCNxIQ6asO9YsAiSmgeNriNKPNq8D0nhGnG1iB9OCz3FVGqmYllvONDoemnYAS7dOyisxipNQm0zS9yTZNeXWV5nZ3LrD+VdJGvPTAJsTjcZx47uoJ8+3Ny0+Gt6gIfe0d0ypmAGjbfwAjg0MoLitDw8J5Zh1ZNUvOXgUA2PuS81o0QMozotXAKj0jNt6gPB3TtWnO+/C1KK+uQsfBw7bcwixNrComavKhTROPxcaIXzMqI2K0t2SqNo3DQ8+AtPHeHLZpRItGPHYmhnoTgtDj82ac+CkWe2n6rBUjof4Bmcxrx+oIxUgaXUdbZL999TVj99WIfBE1LRogsUJdTNVYnTfi8fmw4IxTATjTLwKkVUYK0DMyJCLhJ8kaKa0I4l03/AMA4Ikf/NQ2I73pCN+IOjEi4tOtD23LhnSfiBnR/LIyMm4/jQw9c3gcPJBq01Q3zcpZdVmtXwRIVNNHhxPG5EytGrmXxmLPCJBq1dgxFp5iZBwv/CaRyHrmlZfB60+9C0+Fnb2h+r7skjcy75Tl8JeWoL+zS+Y+OI1wSF/oWT6IEXH2yTwjaz52PUoC5Wh5ax+2P/nXHJ9MHXoqI04NPBOkTzQZPdYLZGrT5EfOCJCIMB8ZHILX58tZdblGbOtVIUaA1LK8TCmsqY291m9I77Hx9l6KkXG89fxL6G5pRVllBU5ZexGARGVBVDe0mD+lGLG4MiJGeve9+DIURbH0LHoRW3u1VkZEcqmjDazJ5NjxbZpgXS3Ove6DAIDHv/cT235vW/+eEMD18+fC7c28PFKIEacGngnSBYipbZqpdtPkgRhR4nGZZj13xfKcPKbMGJlmrFcwnGzVZNpPk0pgtb4yIoPP2KaxP0o8jhcfSFRHzk7uq5mz7CT4iv0Y6OpG+4FDqu9L/EeaMX/uhKTEXLJktcgXsc/Ip1Zk6JkGA6vL5ZKmTydXRoZ6JjewXvyJG1FUUowDr+/Ans0vWnE0VfQcOy7f4dbPbc54XWFgza/KiHltmgk5I6X54xkBgINvJKcSV+ZmKlFLmwZImVgztWnENI1VG3vTsfNEDcXIJLy86VFEw2HMWXYSZp98Ysov8uobmu5nuK9fThKISZxcU15TJbcM73tpmyVnMIJUHLx6A2txIACPT6R59ppxrJwwMImBtbpxJs666nIAwOPf+7El59LC8bffAZC5VeNyu2Uly8kGVmBsCq4pbZrkC5vH65WtGSCtTZMHnhEgt2LE5XbLyZ3pouAFQyqW5dllNw0A9CQrI3ZMYaUYmYShnl688eenASTGfNUsx5sKMeI71yLfiKiKHHnzLUdXB1Jx8OorI4HkWG8iUt0+465aEQbW4vIyuZ/m0ltugtfnw94Xt+r6ucw1qSTWqcVIWWVFatGfg9tqQEqAREZHTfEKREdHZRCg8I0UlRTLVfX50KYBgMM7dyMej6N2TpMc0zeLyoZ6eH0+RMPhSTeyT4aoUE0VfObx+WQ11+qcESA9+IyVEccgEllPWXsJ5q5M9Cv1/NIX4WfNy61JYpUR8A6dohGEdUzT5IN5FZi4n2bG/Lk47bK1ABJeESegZmGeCDwb7u1zbBS8QIyGZlobkS0y+CwpRkSLJh6PO3Ip5GSMDA7JqtrcFeZWR2rnzAaQyDdR0nJiMiHeKIw3EgtEFHw8HrfFhFOvmKaZUW+L/Kt07HUaG3F4x24cfXMvfMV+FJUUY6i3D23J/xRa7wcA5iw7GS6Xy+hjZsTlcmHx6jMBAPscuI8mHfEusKikWPXzmDKv9pp0qtwhKgXl1VV496dvhtvjwY6//A1Hdu+x+GTqUDNRkw8ZI4LWfW/jN1+9HRtv+3fTHkNO1CT9aP48ioJPR7ZqzBYjKhfkpSPbNJOM3QMpv8jI4KAtDOZ9HZ2IRaPw+LwI1tVYfZwxUIxk4MXf/l7+/Z1X39D1w9T69/0YHQ6hJBiQi8xyxawTFiFQU42RoSH5H9qppKfGev1Fqm6TL5URIPUO7IRzVmPFpRciHo/jiR/81NpDaUCIkerGmVMGRMn01TwQIwCw7eHHTBWLojIigs/8eRR4lk6ufCMidl7tJA2QJkamSGGVfpF+6ydpgMSARl9bBwCgqsFerRqKkQy8/vhT0gGtty8fj8XkL6Rmk5X9eETq6v6XX0MsGs3pYxuNGO0F1PtG8mFjr0B8DRfdfAMA4LU//Rltyc3QTiDUPyD78A0LJ6+OBKrzY5ImV4jfTSJuvLgsf8Z60xFipOnkE6Rnygxk+qqGyohcllc1hRix0SSNwK5ZIxQjGQiHRvDQf3wXe1/citcefUL3/aTyRnLrG5F+EYe3aICEopdZI351EzXCg5AXYiRZGfGXliAWieLJH/63tQfSwXStmkBtomxsRi5HPjI++Myfp2Kk68hRDHR1w+f3y8lAM5BjvSonaYDpl+XZZS9NOjKF1WYTNRQj0/DKI4/hp5/8nPyh04PIG8llEqu/tFSWNd9yuHlVIHwjapflpdo0zn+nnS6otv7hEVW7M+zGcRELP8XCvHxJX80V44PPUumr1hsljUaGn5nYqhH7yLo0tWl6AUzdppF7aexYGbHZRA3FSA6Q4WcL5mVcqGQkC844FV6fD51Hjmr6z2VnwhrHe6WB1cEZIwIhRiIjo3jqp/9j7WF0ciyZxNqwaP6knxej2E5PX80VhWJgBcw3sZZXV6GopBjxeFyOv6pBJLCKQYfx2GkvjcCuKaxeqw9QCAx29aDraAtqmhrxjWcfQ2RkFJFwGNHRMCKjo/LPyOgo+to78ND/+27W2QT5MtKbTiSkbbw3nwysf9+yDeGbb8STP7oP/e0dVh9HF9MtzBNtGlZG1CE9I8k2Tb56RgDzxYhYHDfQ0aXJXzc6PIxoJAKvz4fSiooxRnsgfS+NjSojx/KgTbN+/XooijLmsmePOrf4tddeC0VRsGnTJl0HdTqv/elJAIC3qAglwQCCtTWobpyJGfPnovHExZi7chkWnXU6Tn/fe7D84guyfrwlZ+ePX0QgKyMl6jwj+WRgPbzzTdy26iI884tfW30U3bQfOIRYNIrSYBCVM+onfL5c7qWhZ0QN4yPh83WaBgCO7H4LsUgUFTPqTHlHX5V8Ye45rr4qIhCTbpMFn9kpfVVg1zaN5srIrl27cPHFF8t/R1WoyObmZnz729/Gc889p/Xh8oYnfvBTPPvL38BfUgyvvwi+Yj+8RX74iv3wFRXB6y/CudddjcWrz5TvEPVS3TQLdc2zEYtE8fbLrxr0FViP9IyoqIy4PZ60No3zxQgA1UFMdiUWiaDj4GE0LJyPhsULxqRcutxulIvvFysjqphoYM2vKPh0oqOjOLpnL5qXn4y5K5fJF1SjqEy+MIsWhhaG+/pRUV836URNarTXPmKk93jiaywJlKO4vMw2Py+aPSPRaBRtbW3y0tWV+V2M2+3Gr3/9a6xfvx7vvKM9NCyfCPX3o7etHZ2Hj6J1334c2fUm3nnldex9cSt2P7MZh3clqkzjt7NqRVRFDu7YmVclWy2eEfEuJR6PZ2U+JsYy1URNWVUF3B4Pv18aGB5nYC0uzV/PCJBKszbDxCorIzrESCqF1RmVkXBoRJ7ZTuO9msXIokWL0NLSgv3792PDhg2YPXt2xut//etfR3t7O37+85+rfoyioiIEAoExl0JA/ICUT5Hmp5b5p60EAOx78eXsDmQztFRGypKCbri3z/EVhXxiKjESqElUA4d6ehGPOTsKPldMqIwkzfGjw/Z4p2s0wjfSbIoYSVZG9LRpMqSwCs+IHfbSpNMtxnttFHymSYxs3boVN954I9auXYtbbrkF8+bNw+bNm1FeXj7p9c855xzcdNNNuPnmmzUd6tZbb0V/f7+8tLQ4b4xRD2IEtTwZ/qSXYF0tAKDz0JGsz2QnIho8I/nkF8knpjKx5lMUfK4QJvfisjK4vZ60Nk1+VkYOJSsjsxYvRFFJiaH3LcycWiZpBHJZ3iT7aURlZMQmCawC0Y6qdmpl5IknnsCDDz6InTt34sknn8S6detQWVmJa665ZsJ1y8vL8atf/Qo333zztK2c8dx5550IBoPy0tjYqOn2TkW8cGa7nVL+Ys+zF2Ity/LyaZImn2hNjvfWz58Lt9cjPy5/ZmleVU36uGhpMJjWpsnPykhfWwe6j7XC4/Vi9tITDb1vURnJqk0zmYE1WdUfNmFzczbYcaImq9Hevr4+7Nu3DwsXLpzwuQULFmDevHn44x//KD/mTm4JjEQiWLJkyZQeknA4jHA4nM3RHMlAV2oZWjbIF+I8e5eZWpY3/bsiihF70nPsOEYGh1BcXob6uc1yI6swbbMyoh4lHkeofwAlwQBKK4JpbZr8rIwAwKE3dqJ61kzMXbkM+7e9Zsh9ev1+KYZ1iZG+yds0LpcrNdpro5wRIDU1ZKeJmqxCz8rKyrBgwQK0tk5ck/3WW29h6dKlWLlypbw88sgjeOaZZ7By5UocOZJfLQQjSB8R07vh1+31SPNmvr0Qi3XswhOTCYoR+yIESHqrJpW+yu+XFuSyvGAA/lKRwJq/YsQME2vljDoACRGnJ99JBJ+Nb9MUlZbA7UlU/+w0TQPYM/hMkxi56667cP7556O5uRmrV6/Gpk2bEIvFsHHjRgDA/fffjzvuuAMAMDo6it27d4+59Pb2YmBgALt370YkEjH+q3E4Qoy4PR5pStNKeVXiRTgWjcpeZr7wxuNPIR6PY+EZp6K6cWbG65ZVVwJI7XQh9kGYWBvSxUgt2zR6SE9hLRY5IzYZ1TSDg28kY+FXLNP9hm082bRogKnbNCJ9NTI6iqjNKv2iTeNYMdLU1ISNGzdi7969eOCBB9DV1YVVq1ahs7MTADBnzhzMnJn5RYJMTbqA0NuqEe8wh3p6oSiKYWezA71t7Xh76ysAgNPf956M15UGVr7Tth2TTdTQwKoPuZ+mIpDXcfCCY/v+jnBoBKUVQdTNnWPIfQrfhJ6MESCtTVNZOebjdtxLIxBtmkBdDTxeewSxazrFddddl/Hza9asyfj5j370o1oeriAZ7O5BaUUQ5dVVaHvnoObb53t7Ytsjj2Hx6jNx+hXr8NRPfjGl4BITSfmwJC/faN2XMLGmi5FyKUZYGdGCePMSrKmBt6gIADCSx56ReDSGw7vexMIzTsXclcvRfuBQ1vcpKyM6xnqBRHwAAJRWjq1mpzb22ssvAiTepEVGR+Hz+1HRUI/uo8esPhIX5dkNISLKdFZGhBjJ13eYu55+FiNDQ6hpasS8U1dMeb18F2VORlRGqhtnysWRrIzoQ+RXpIdXhYdDVh0nJ8g9NQb5RqQY0THWC6RyRorLyuDx+eTH7Zi+mo70jTTYY6KGYsRmiBfPQJZtmnx9EQ6HRrD9z38FAJx++boprydFWZ4+D04m1D8go+AbFi4YE91PMaINURkRL6ijw6G8D42T4Wcrlhpyf9m2aUYGBuVznr6fxo7pq+nIHTWz7GGtoBixGTJrhJWRKXnlkccAACsuvXDStd3eoiL5jnuIBlZbku4bKauqhNvtRjwWw1APo+C1EBpXGcnnsV7B4R0JE2vDgnkoCeoz+qcjKgM9x/WJEUVRZHWkdDIxYtPKiDDs2iVrhGLEZmQtRvK8MgIAB17bjs4jR1FcXoalF03ccCzi9GORqG1/ERQ6x0US6+IFqWpeTy+j+zUyoTKSx+ZVwVBvn/SKNK84Oev7S1VG9C/fkyms6WIkYF/PCJCqjFTbZKKGYsRmiFHUyfYcqEGkt+Zb4Fk6iqLg1UceBwCcMUmrRj4HeSzInE5qvHc+01ezQLwIytjxPE1fHY9RvpHy6ir4/H7E43H0tXXovh9hYk0XI8LAarf0VYEQX6yMkEnJNhI+UJ2fUfDjeeWPCTGy8KzTUTmjfsznaF61P8fSJmpE+mo+C2izGB/SVQiVEQA4+MYOAIm8kWyoTLZoBjq6EItGdd/PUG8vgLFtGjHaa7e9NIJum2WNUIzYDPELOaBzWV6qMpLfL8TdLa14e9trcLvdOG1c5gjHeu1P+4FDiEWjKA0G0XTSEgBAfye/X1oZ/667cMRIojIyZ9nJMuVUD8Jro3esVzDUO7FNI0LP7LaxV2C3FFaKEZthlIG1EN5lCiPr6ZePEyPJFhfTV+1LLBJBx8HDAIDFq88EUBg/s0YT6hv7QlcIBlYgIWaH+/vhLy3BzMULpr/BFIgXYr2TNILJ2jSpvTQ2FSNt7YjH4/AV+7Peh2YEFCM2Q7yAllYEx2w1VUNJMABvcs69EF6Idzz5DEaHQ6if14w5y1NGNrZpnIHwjcyYPxdAfk+AmcX4yshIHkfBp6MoCg5tT0bDr1yu+36EX0JvxohAtGnSU1jtPk0Ti0SkT6vSBlkjFCM2Y7ivP21mvVLTbcWLcKh/wHa7EMxgdHgYO//yNwDAGVe8V36cBlZnIMSIgOmr2gmHRhBN2/NVKG0aADgoxYh+30i2Y70C0aZJT2FNTdPYU4wA6Vkj1rdqKEZshhKPy5l1raWzfA88mwzRqlm59iIZh13OvTSO4PgEMcLvlx7SF2IWSpsGAA6JiZosTKxGjPUCaZWRCufkjAD28o1QjNgQmcKqcaKmEALPxvP2y6+ip/U4SoNBnLzmPABMX3UKEyojHO3VxRgxUkCVkcM730Q8FkN140wE6+t03Ue2G3sF0jOS9Kt5fD4ZyGjXnBHAXtt7KUZsiNxPU8XKyHQoiiLHfM+4IpE5In4hDPUUzvPgRHqOHR/jcSgkEW0k6e+8C8UzAiSqQK3J8Ly5OqLhvX6//J2ZrRgZGrcsrySYMK/G43GM2FmMHLdPCivFiA3RO1FTiJURAHglGYC25OyzEKitkWPRhSTKnIiiKDj+9jsAgFg0Kt9dEm0UapsGAA5u1x9+VtmQyCcaHR6ekNeiFSlGgkG4PR7pFxkZHJxys7gdkJURekbIZOgWIwVYGQGAzkNHcPCNnXB7PDj7mivhK/YDKLznwYmIVs1gd4+tf2nbmfTKyGiBJLAKsgk/M6pFA4z9HpRWBNP8IvatigBpBlZO05DJ0Lu5t5BHWrc9/CcAwDnXXQ0gsb00HBqx8khEBVKM0Lyqm/TKyMhggVVGkibWxpOWSAO7WuQkTZbmVQCIx2JyzLq0IpiapLGxeRVIfe3l1VWTLh3NJRQjNkTup6mu1HS7QIG2aQDgjT8/jcjoqAwdKkRB5kTefPZ59La1Y/tTf7X6KI4lvcUwOlxYlZHullYMdvfA6/OhYeE8TbdNTdJkXxkBIDdOl1VVyr00dh7rBYCRgUHpM7I6a4RixIaId4ls06hnZGAQu/76nPz3UAGEvuUDPceO4/aLr8DTP7vf6qM4lvTgs0KaphEc2/t3AEDjCYs13S7Vpsm+MgKMTWEVe2nsXhkBUl8/xQiZAA2s+tj28GPy74UoyEhhUqijvYKWtxJiZJZGMWJ4ZUSYWCsq5F4aO4/1CuwSfEYxYkPEgjctYsRbVCR3IRTqC/G+l15GX3tiDXihPgek8EhfxDZSkGJkH4AsKiNZpq8KhmTWSEVqL40TKiM2yRqhGLEhwjNSXFYGr9+v6jZCuETDYVvPtZuJEo9jy4MPA0itqCck3xGVkWg4jFhaNHyhcCwpRmYtWQiXy6XqNi6XS472Zpu+KhjuS4qRiorUNI3NPSMA0HvcHimsXksfnUzKyMAgopEIvD4fyqsq5Q9LJgox8Gwynvrxz7HvpW04sutNq49CSE7obW1DPBYzZETVibQfPIxwaAT+0lLUzGlC56Ej096mrLoSPr8f8XgcfW0dhpwj3cDqLysF4JDKSKs9gs9YGbEpWn0jhe4XESiKgoNv7EAsGrX6KITkhP6OTvzopn/Cf//Tv1p9FEtQ4nE5Iq62VVPVkKgC9Hd0Gva7YqgvlcLqpMoI2zQkI3KiRuV+GlZGCClc3nn1DXQcPGz1MSxDq2/EaPMqkDZNU5HyjAw7oDIi2lSVM+rhclsnCShGbIrYq1Kucj+NEC0UI4SQQuOYnKhZpOr6Ro/1Aqk4gbKqSlkZGbF5AisA9CWrQx6fF8G6GsvOQTFiUwbYpiGEEFW0vLUXgLWVkaG+iQmsw1nuvMkFSppvRrSvrIAGVpui1TMi2zSM1SaEFBitf9+PeCyGYG0NArU1GOjsynh9o8d6gVRlpLQiKD/mhJwRAHjpd5vg9fnQ35X5eTMTihGbotvA2s3KCCGksIiMjKL94GE0LJiHxhMW4a3npxMjojJiXJtGeEbcHo/8mBOmaQDgr//9K6uPwDaNXRnq7gUAlKvcT1POygghpIA5Jk2sS6a9bqVckmdcZSQWjWIkbWtyZHQU0XDYsPvPdyhGbAo9I4QQop4WlSZWr98v29pGGliBVNYI4JyqiF2gGLEpWto0Lrcb5VWVY25HCCGFhNrxXpG8OjI0ZLhgECmsgHP8InaBYsSmaNlPU1oRlH1KbqslhBQiok1T1zwb/tLSKa8nzKtGTtIIhG8EYGVEKxQjNkWICp/fn/E/FpASLEM9vYjHYmYfjRBCbMdQb59cnTFrycIpr1cl/CIGTtKkn0HghPRVO0ExYlPCoRGMDocATF8dEf3PAbZoCCEFTMo3MnWrpmqWeZWRIVZGdEMxYmOkb2SaSHghVgZpXiWEFDBqfCMi8Mxo8yowvjJCz4gWKEZsjFoTK/fSEEJIyjeSaaJGpIya7RlxQvqqnaAYsTFSjCQnZaaCY72EEJKqjMxcOB9ur2fS68jKiMmeESfspbETFCM2RphYy6urM16PlRFCCAG6W1oR6h+At6gIM+bPnfB5l8slR3t7jrUa/vhDYyoj9IxogWLExqgd72VlhBBCErTsTZhYJ0tiLauuhM/vRzweR197h+GPPcxpGt1QjNiYAbUGVlZGCCEEQGYTq/CL9Hd0Ih41PgaB0zT6oRixMVo9IxQjhJBC51iGWHgzx3oBYKi3V/6dlRFtUIzYmNSyPLZpCCFEDS1v7QUANC6ZKEbMHOsFEtuDxRTNQCd/H2vBa/UByNSoGe0tKimBv7QkcX1u7CWEFDht7xxENBxGSTCA6saZ6G5JGVXNHOsVbPjiegRrq9Hf0WnaY+QjFCM2RnhGyqoq4XK5oCjKhOsIP8nocAjhUCin5yOEELsRj8bQ+vY7mH3SCWg8YfEYMWLmWK9g7wtbTLvvfIZtGhszlBQjHq8XxYHApNfhWC8hhIzl2BSx8FVCjBwzp01D9EMxYmNi0ah0ZAemmKhhFDwhhIxlqomaygZzPSNEPxQjNmc63wgrI4QQMpZjUoykTKxev1/+vuw1sU1D9EExYnOmEyOcpCGEkLEc2/s2gEQlpKyyAkCqRTMyNMQMEBtCMWJz0k2sk8GMEUIIGcvo8DA6Dh0BkPKNCDFi5iQN0Q/FiM0R+2kCbNMQQohqxvtGKpNjvWZO0hD9UIzYHNmmqZl8WR7bNIQQMhExUSN8I6yM2BuKEZsz3bI87qUhhJCJiCRW0aap5FivraEYsTkiVXUqz0iAlRFCCJlAy55Em6Z+7hz4iv0yfbXnOMWIHaEYsTmDSc/IZJURt9cjRQorI4QQkmKgqxv9nV1wezyYuWiBrIywTWNPNImR9evXQ1GUMZc9e/ZMef0rr7wS27ZtQ09PDwYHB/H666/j+uuvz/rQhYQQGZMZWMsqKwEA8VgMw2mrqwkhhKSZWE9ckkpfZeCZLdG8m2bXrl24+OKL5b+j0eiU1+3u7sa3vvUtvPXWWwiHw7jsssvwi1/8Au3t7XjyySf1nbjAGEwb7XV7PIjHYvJzcpKmp3fSvTWEEFLIHHvr7zjx3NU44Zyz4C0qQjweR197h9XHIpOgWYxEo1G0takrcz377LNj/v29730PN9xwA84991yKEZUM9fYhHo/D7XajtDI4ZjMvo+AJIWRqRGVk8eqzAAD9HZ2IR2OZbkIsQrNnZNGiRWhpacH+/fuxYcMGzJ49W/VtL7zwQixZsgTPPfdcxusVFRUhEAiMuRQqSjwuWzDl1WPHe8XGXvpFCCFkIkKMFJUUA6BfxM5oEiNbt27FjTfeiLVr1+KWW27BvHnzsHnzZpSXl095m2AwiIGBAYTDYfzpT3/CZz7zGfzlL3/J+Di33nor+vv75aWlpUXLMfOOqXwjgWqO9RJCyFR0HT6K0eFh+e+eY60WnoZkQpMYeeKJJ/Dggw9i586dePLJJ7Fu3TpUVlbimmuumfI2AwMDWLlyJc444wx85StfwX/913/hggsuyPg4d955J4LBoLw0NjZqOWbeMdV+GlEZ4VgvIYRMRFEUuacGYPqqndHsGUmnr68P+/btw8KFC6e8jqIo2L9/PwBg+/btOPHEE3HrrbdO8JOkEw6HEQ6HszlaXjE4xX4aRsETQkhmWt7ah3mnLAfANo2dySpnpKysDAsWLEBrq/rSl9vtht/vz+ZhCw6ZNVIzrjLCwDNCCMnIsaRvBAB6KEZsi6bKyF133YU//vGPOHToEGbNmoVvfOMbiMVi2LhxIwDg/vvvR0tLC2677TYAwJe//GW88sor2L9/P/x+P9atW4cPf/jDuOWWW4z/SvKYqds0ycpIFysjhBAyGS1jxAgzRuyKJjHS1NSEjRs3oqamBh0dHXj++eexatUqdHZ2AgDmzJmDeDwur19WVoYf/vCHaGpqQigUwltvvYXrr78eDzzwgLFfRZ4jxMZEAysrI4QQkonjbx/AyOAQPD4vuluOWX0cMgWaxMh1112X8fNr1qwZ8++vfe1r+NrXvqb9VGQMYlleWdXkbRp6RgghZHKi4TB+dNOn4S3yY3RoePobEEvIysBKcsNk+2mKA+XwFhUlPk8xQgghU3L0zb1WH4FMAxflOYDJPCPi76GBQUQ5eUQIIcTBUIw4ACFGSgLl8Ph8ADjWSwghJH+gGHEAof4BxCKJhYTl1ZXJP7mXhhBCSH5AMeIQBnvGtmpEZWSAlRFCCCEOh2LEIaR8I9XJP1kZIYQQkh9QjDiE8SZWekYIIYTkCxQjDkGKkeR+GkbBE0IIyRcoRhzC+P00DDwjhBCSL1CMOAQRCc82DSGEkHyDYsQhjPeMsE1DCCEkX6AYcQgpz0gVvEVFKAkGxnycEEIIcSoUIw4hPWdEmFijkQhC/QMWnooQQgjJHooRh5DepimnX4QQQkgeQTHiEISBtaikGDWzGwHQL0IIISQ/oBhxCOFQCOHQCACgYcE8AKyMEEIIyQ8oRhyE8I00LFqQ+DcrI4QQQvIAihEHISohMxfOT/y7i5URQgghzodixEEIMVIzp2nMvwkhhBAnQzHiIIT4cLsT3zYaWAkhhOQDFCMOYqi7d8y/WRkhhBCSD1CMOIjx4oOVEUIIIfkAxYiDGBgnRlgZIYQQkg9QjDiI8eJDjPoSQgghToZixEEMpYmPod4+xKMxC09DCCGEGAPFiINIzxVhi4YQQki+QDHiIAZ7euXfaV4lhBCSL1CMOIhoOIzQwCAAVkYIIYTkDxQjDmMoWR3hXhpCCCH5AsWIwxAVkfFjvoQQQohToRhxGN3HWgEAPS2tFp+EEEIIMQav1Qcg2njsnh/hwGvbsf3Jv1p9FEIIIcQQKEYcRs+x43jxt3+w+hiEEEKIYbBNQwghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYCsUIIYQQQiyFYoQQQgghlkIxQgghhBBLoRghhBBCiKVQjBBCCCHEUihGCCGEEGIpFCOEEEIIsRRHbe0NBAJWH4EQQgghKlH7uu0IMSK+mJaWFotPQgghhBCtBAIBDAwMTPl5FwAld8fRz6xZszJ+IXoIBAJoaWlBY2Oj4fdNUvB5zh18rnMDn+fcwOc5N5j9PAcCARw7dizjdRxRGQEw7ReSDQMDA/xBzwF8nnMHn+vcwOc5N/B5zg1mPc9q7pMGVkIIIYRYCsUIIYQQQiyloMXI6Ogo/u3f/g2jo6NWHyWv4fOcO/hc5wY+z7mBz3NusMPz7BgDKyGEEELyk4KujBBCCCHEeihGCCGEEGIpFCOEEEIIsRSKEUIIIYRYSkGLkX/8x3/EgQMHEAqFsGXLFpxxxhlWH8nRnHfeeXjkkUfQ0tICRVFwxRVXTLjON77xDRw7dgzDw8N46qmnsHDhQgtO6my+/OUv4+WXX0Z/fz/a2tqwadMmLF68eMx1/H4/fvCDH6CzsxMDAwN48MEHUV9fb9GJncmnPvUpbN++HX19fejr68OLL76ItWvXys/zOTaHL33pS1AUBXfffbf8GJ/r7Fm/fj0URRlz2bNnj/y8HZ5jpRAv11xzjTIyMqLceOONyoknnqj85Cc/Ubq7u5W6ujrLz+bUy9q1a5Xbb79def/7368oiqJcccUVYz7/xS9+Uenp6VEuv/xyZdmyZcpDDz2k7N+/X/H7/Zaf3UmXxx9/XLnhhhuUk046SVm+fLny6KOPKgcPHlRKS0vldX74wx8qhw4dUtasWaOceuqpyosvvqg8//zzlp/dSZfLLrtMec973qMsXLhQWbRokfLNb35TGR0dVU466SQ+xyZdTj/9dOWdd95R3njjDeXuu++WH+dznf1l/fr1ys6dO5UZM2bIS01NjZ2eY+ufJCsuW7ZsUb7//e/Lf7tcLuXo0aPKl770JcvPlg+XycTIsWPHlC984Qvy38FgUAmFQsq1115r+XmdfKmtrVUURVHOO+88+byOjo4qV111lbzOkiVLFEVRlLPOOsvy8zr50tXVpXzsYx/jc2zCpaysTNm7d69y0UUXKc8884wUI3yujbmsX79eef311yf9nB2e44Js0/h8Ppx22mn4y1/+Ij+mKAr+8pe/YPXq1RaeLH+ZN28eZs6cOeY57+/vx9atW/mcZ0lFRQUAoLu7GwBw2mmnoaioaMxzvXfvXhw6dIjPtU7cbjeuvfZalJWV4aWXXuJzbAL33nsv/vSnP+Hpp58e83E+18axaNEitLS0YP/+/diwYQNmz54NwB7PsWMW5RlJbW0tvF4v2traxny8ra0NJ5xwgkWnym8aGhoAYNLnXHyOaMflcuG73/0unn/+eezevRtA4rkeHR1FX1/fmOvyudbO0qVL8dJLL6G4uBiDg4O48sorsWfPHqxcuZLPsYFce+21OPXUUyf17fHn2Ri2bt2KG2+8EXv37sXMmTOxfv16bN68GUuXLrXFc1yQYoSQfOHee+/F0qVLce6551p9lLxk7969WLlyJSoqKnD11Vfj/vvvxwUXXGD1sfKKpqYm3HPPPbjkkksY+24iTzzxhPz7zp07sXXrVhw6dAjXXHMNQqGQhSdLUJBtms7OTkSjUcyYMWPMx2fMmIHjx49bdKr8RjyvfM6N4/vf/z4uu+wyrFmzBi0tLfLjx48fh9/vl+0bAZ9r7UQiEezfvx+vvfYabrvtNmzfvh2f/exn+RwbyGmnnYYZM2bgtddeQyQSQSQSwbve9S788z//MyKRCNra2vhcm0BfXx/27duHhQsX2uLnuSDFSCQSwauvvoqLLrpIfszlcuGiiy7CSy+9ZOHJ8pcDBw6gtbV1zHMeCARw1lln8TnXwfe//31ceeWVuPDCC3Hw4MExn3v11VcRDofHPNeLFy9Gc3Mzn+sscbvd8Pv9fI4N5Omnn8bSpUuxcuVKedm2bRt+/etfY+XKlXjllVf4XJtAWVkZFixYgNbWVtv8PFvu8rXics011yihUEj5yEc+opxwwgnKj3/8Y6W7u1upr6+3/GxOvZSVlSkrVqxQVqxYoSiKonzuc59TVqxYocyePVsBEqO93d3dyvve9z5l6dKlyqZNmzjaq+Ny7733Kj09Pcr5558/ZkyvuLhYXueHP/yhcvDgQeVd73qXcuqppyovvPCC8sILL1h+didd7rjjDuW8885TmpublaVLlyp33HGHEovFlIsvvpjPscmX9GkaPtfGXO666y7l/PPPV5qbm5XVq1crTz75pNLe3q7U1tba5Tm2/kmy6vLpT39aOXjwoDIyMqJs2bJFOfPMMy0/k5MvF1xwgTIZv/jFL+R1vvGNbyitra1KKBRSnnrqKWXRokWWn9tpl6m44YYb5HX8fr/ygx/8QOnq6lIGBweV3//+98qMGTMsP7uTLvfdd59y4MABZWRkRGlra1OeeuopKUT4HJt7GS9G+Fxnf9m4caPS0tKijIyMKEeOHFE2btyozJ8/3zbPsSv5F0IIIYQQSyhIzwghhBBC7APFCCGEEEIshWKEEEIIIZZCMUIIIYQQS6EYIYQQQoilUIwQQgghxFIoRgghhBBiKRQjhBBCCLEUihFCCCGEWArFCCGEEEIshWKEEEIIIZZCMUIIIYQQS/n/y9BnUZXaKWAAAAAASUVORK5CYII=", + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
checking_statusdurationcredit_historypurposecredit_amountsavings_statusemploymentinstallment_commitmentpersonal_statusother_parties...property_magnitudeageother_payment_planshousingexisting_creditsjobnum_dependentsown_telephoneforeign_workerclass
0<06critical/other existing creditradio/tv1169.0no known savings>=74male singlenone...real estate67noneown2skilled1yesyesgood
10<=X<20048existing paidradio/tv5951.0<1001<=X<42female div/dep/marnone...real estate22noneown1skilled1noneyesbad
2no checking12critical/other existing crediteducation2096.0<1004<=X<72male singlenone...real estate49noneown1unskilled resident2noneyesgood
3<042existing paidfurniture/equipment7882.0<1004<=X<72male singleguarantor...life insurance45nonefor free1skilled2noneyesgood
4<024delayed previouslynew car4870.0<1001<=X<43male singlenone...no known property53nonefor free2skilled2noneyesbad
..................................................................
995no checking12existing paidfurniture/equipment1736.0<1004<=X<73female div/dep/marnone...real estate31noneown1unskilled resident1noneyesgood
996<030existing paidused car3857.0<1001<=X<44male div/sepnone...life insurance40noneown1high qualif/self emp/mgmt1yesyesgood
997no checking12existing paidradio/tv804.0<100>=74male singlenone...car38noneown1skilled1noneyesgood
998<045existing paidradio/tv1845.0<1001<=X<44male singlenone...no known property23nonefor free1skilled1yesyesbad
9990<=X<20045critical/other existing creditused car4576.0100<=X<500unemployed3male singlenone...car27noneown1skilled1noneyesgood
\n", + "

1000 rows × 21 columns

\n", + "
" + ], "text/plain": [ - "
" + " checking_status duration credit_history \\\n", + "0 <0 6 critical/other existing credit \n", + "1 0<=X<200 48 existing paid \n", + "2 no checking 12 critical/other existing credit \n", + "3 <0 42 existing paid \n", + "4 <0 24 delayed previously \n", + ".. ... ... ... \n", + "995 no checking 12 existing paid \n", + "996 <0 30 existing paid \n", + "997 no checking 12 existing paid \n", + "998 <0 45 existing paid \n", + "999 0<=X<200 45 critical/other existing credit \n", + "\n", + " purpose credit_amount savings_status employment \\\n", + "0 radio/tv 1169.0 no known savings >=7 \n", + "1 radio/tv 5951.0 <100 1<=X<4 \n", + "2 education 2096.0 <100 4<=X<7 \n", + "3 furniture/equipment 7882.0 <100 4<=X<7 \n", + "4 new car 4870.0 <100 1<=X<4 \n", + ".. ... ... ... ... \n", + "995 furniture/equipment 1736.0 <100 4<=X<7 \n", + "996 used car 3857.0 <100 1<=X<4 \n", + "997 radio/tv 804.0 <100 >=7 \n", + "998 radio/tv 1845.0 <100 1<=X<4 \n", + "999 used car 4576.0 100<=X<500 unemployed \n", + "\n", + " installment_commitment personal_status other_parties ... \\\n", + "0 4 male single none ... \n", + "1 2 female div/dep/mar none ... \n", + "2 2 male single none ... \n", + "3 2 male single guarantor ... \n", + "4 3 male single none ... \n", + ".. ... ... ... ... \n", + "995 3 female div/dep/mar none ... \n", + "996 4 male div/sep none ... \n", + "997 4 male single none ... \n", + "998 4 male single none ... \n", + "999 3 male single none ... \n", + "\n", + " property_magnitude age other_payment_plans housing existing_credits \\\n", + "0 real estate 67 none own 2 \n", + "1 real estate 22 none own 1 \n", + "2 real estate 49 none own 1 \n", + "3 life insurance 45 none for free 1 \n", + "4 no known property 53 none for free 2 \n", + ".. ... .. ... ... ... \n", + "995 real estate 31 none own 1 \n", + "996 life insurance 40 none own 1 \n", + "997 car 38 none own 1 \n", + "998 no known property 23 none for free 1 \n", + "999 car 27 none own 1 \n", + "\n", + " job num_dependents own_telephone foreign_worker \\\n", + "0 skilled 1 yes yes \n", + "1 skilled 1 none yes \n", + "2 unskilled resident 2 none yes \n", + "3 skilled 2 none yes \n", + "4 skilled 2 none yes \n", + ".. ... ... ... ... \n", + "995 unskilled resident 1 none yes \n", + "996 high qualif/self emp/mgmt 1 yes yes \n", + "997 skilled 1 none yes \n", + "998 skilled 1 yes yes \n", + "999 skilled 1 none yes \n", + "\n", + " class \n", + "0 good \n", + "1 bad \n", + "2 good \n", + "3 good \n", + "4 bad \n", + ".. ... \n", + "995 good \n", + "996 good \n", + "997 good \n", + "998 bad \n", + "999 good \n", + "\n", + "[1000 rows x 21 columns]" ] }, + "execution_count": 7, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ - "trainer.runner.cbs[1].plot_loss()" + "data" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { - "image/png": "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", "text/plain": [ - "
" + "21" ] }, + "execution_count": 8, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ - "trainer.runner.cbs[1].plot_lr()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Tabular classification" + "len(data.columns)" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ + "class TabularClassificationmodel(torch.nn.Module):\n", + " def __init__(self, input_size, output_size):\n", + " super(TabularClassificationmodel, self).__init__()\n", + " self.fc1 = torch.nn.Linear(input_size, 128)\n", + " self.fc2 = torch.nn.Linear(128, 64)\n", + " self.fc3 = torch.nn.Linear(64, output_size)\n", + " self.relu = torch.nn.ReLU()\n", + " self.softmax = torch.nn.Softmax(dim=1)\n", "\n", - "import torch.nn\n", - "import torch.optim\n", - "\n", - "import openml\n", - "import openml_pytorch\n", - "import openml_pytorch.layers\n", - "import openml_pytorch.config\n", - "import logging\n", - "\n", - "\n", - "############################################################################\n", - "# Enable logging in order to observe the progress while running the example.\n", - "openml.config.logger.setLevel(logging.DEBUG)\n", - "openml_pytorch.config.logger.setLevel(logging.DEBUG)\n", - "############################################################################" + " def forward(self, x):\n", + " x = self.fc1(x)\n", + " x = self.relu(x)\n", + " x = self.fc2(x)\n", + " x = self.relu(x)\n", + " x = self.fc3(x)\n", + " x = self.softmax(x)\n", + " return x" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ - "from openml_pytorch.trainer import OpenMLTrainerModule\n", - "from openml_pytorch.trainer import OpenMLDataModule\n", - "from openml_pytorch.trainer import Callback\n", - "import torchvision" + "model = TabularClassificationmodel(20, 2)" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/IPython/core/interactiveshell.py:3577: FutureWarning: Starting from Version 0.15.0 `download_splits` will default to ``False`` instead of ``True`` and be independent from `download_data`. To disable this message until version 0.15 explicitly set `download_splits` to a bool.\n", - " exec(code_obj, self.user_global_ns, self.user_ns)\n", - "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/functions.py:442: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", - " dataset = get_dataset(task.dataset_id, *dataset_args, **get_dataset_kwargs)\n" + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n" ] - } - ], - "source": [ - "# Download the OpenML task for the mnist 784 dataset.\n", - "task = openml.tasks.get_task(31)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "data_module = OpenMLDataModule(\n", - " type_of_data=\"dataframe\",\n", - " # file_dir=openml.config.get_cache_directory() + \"/datasets/45923/Images/\",\n", - " # file_dir=openml.config.get_cache_directory()+'/datasets/44312/PNU_Micro/images/',\n", - " # filename_col=\"FILE_NAME\",\n", - " target_column=\"class\",\n", - " target_mode=\"categorical\",\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "trainer = OpenMLTrainerModule(\n", - " data_module=data_module,\n", - " verbose = True,\n", - " epoch_count = 1,\n", - ")\n", - "openml_pytorch.config.trainer = trainer" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.6122358910831405, tensor(0.7000, device='mps:0')]\n", + "valid: [0.6156392839219835, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7782, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.6377010392554012, tensor(0.6679, device='mps:0')]\n", + "valid: [0.613304180569119, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7753, device='mps:0')\n" + ] + }, { "name": "stderr", "output_type": "stream", "text": [ "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", - " return datasets.get_dataset(self.dataset_id)\n" + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n" ] - } - ], - "source": [ - "data = task.get_dataset().get_data()[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.6358539345823688, tensor(0.6716, device='mps:0')]\n", + "valid: [0.6158585442437066, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7197, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.6139302571614583, tensor(0.7000, device='mps:0')]\n", + "valid: [0.6132626003689237, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7749, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.6127763159481096, tensor(0.7000, device='mps:0')]\n", + "valid: [0.6127421485053168, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7743, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.6308588852117091, tensor(0.6765, device='mps:0')]\n", + "valid: [0.6129144880506727, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7744, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.6361495406539351, tensor(0.6654, device='mps:0')]\n", + "valid: [0.6130077785915798, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7745, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.613462961455922, tensor(0.7000, device='mps:0')]\n", + "valid: [0.6117987314860026, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7730, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/tasks/task.py:150: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " return datasets.get_dataset(self.dataset_id)\n", + "/Users/smukherjee/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:789: FutureWarning: Starting from Version 0.15 `download_data`, `download_qualities`, and `download_features_meta_data` will all be ``False`` instead of ``True`` by default to enable lazy loading. To disable this message until version 0.15 explicitly set `download_data`, `download_qualities`, and `download_features_meta_data` to a bool while calling `get_dataset`.\n", + " openml.datasets.get_dataset(task.dataset_id).name,\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.6135622377748843, tensor(0.7000, device='mps:0')]\n", + "valid: [0.6128959655761719, tensor(0.7000, device='mps:0')]\n", + "Loss tensor(0.7746, device='mps:0')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " \r" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: [0.9189654314959491, tensor(0.3914, device='mps:0')]\n", + "valid: [0.9234729342990451, tensor(0.3667, device='mps:0')]\n", + "Loss tensor(0.7923, device='mps:0')\n" + ] + }, { "ename": "TypeError", - "evalue": "(BertConfig {\n \"_name_or_path\": \"bert-base-uncased\",\n \"architectures\": [\n \"BertForMaskedLM\"\n ],\n \"attention_probs_dropout_prob\": 0.1,\n \"classifier_dropout\": null,\n \"gradient_checkpointing\": false,\n \"hidden_act\": \"gelu\",\n \"hidden_dropout_prob\": 0.1,\n \"hidden_size\": 768,\n \"initializer_range\": 0.02,\n \"intermediate_size\": 3072,\n \"layer_norm_eps\": 1e-12,\n \"max_position_embeddings\": 512,\n \"model_type\": \"bert\",\n \"num_attention_heads\": 12,\n \"num_hidden_layers\": 12,\n \"pad_token_id\": 0,\n \"position_embedding_type\": \"absolute\",\n \"transformers_version\": \"4.44.2\",\n \"type_vocab_size\": 2,\n \"use_cache\": true,\n \"vocab_size\": 30522\n}\n, )", + "evalue": "Labels in y_true and y_pred should be of the same type. Got y_true=['bad' 'good'] and y_pred=[1]. Make sure that the predictions provided by the classifier coincides with the true labels.", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[24], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m run \u001b[38;5;241m=\u001b[39m \u001b[43mopenml\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mruns\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_model_on_task\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbase_model\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:142\u001b[0m, in \u001b[0;36mrun_model_on_task\u001b[0;34m(model, task, avoid_duplicate_runs, flow_tags, seed, add_local_measures, upload_flow, return_flow, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 137\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m extension \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 138\u001b[0m \u001b[38;5;66;03m# This should never happen and is only here to please mypy will be gone soon once the\u001b[39;00m\n\u001b[1;32m 139\u001b[0m \u001b[38;5;66;03m# whole function is removed\u001b[39;00m\n\u001b[1;32m 140\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(extension)\n\u001b[0;32m--> 142\u001b[0m flow \u001b[38;5;241m=\u001b[39m \u001b[43mextension\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel_to_flow\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 144\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_task_and_type_conversion\u001b[39m(_task: \u001b[38;5;28mint\u001b[39m \u001b[38;5;241m|\u001b[39m \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m|\u001b[39m OpenMLTask) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m OpenMLTask:\n\u001b[1;32m 145\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Retrieve an OpenMLTask object from either an integer or string ID,\u001b[39;00m\n\u001b[1;32m 146\u001b[0m \u001b[38;5;124;03m or directly from an OpenMLTask object.\u001b[39;00m\n\u001b[1;32m 147\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 156\u001b[0m \u001b[38;5;124;03m The OpenMLTask object.\u001b[39;00m\n\u001b[1;32m 157\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:281\u001b[0m, in \u001b[0;36mPytorchExtension.model_to_flow\u001b[0;34m(self, model, custom_name)\u001b[0m\n\u001b[1;32m 270\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Transform a Pytorch model to a flow for uploading it to OpenML.\u001b[39;00m\n\u001b[1;32m 271\u001b[0m \n\u001b[1;32m 272\u001b[0m \u001b[38;5;124;03mParameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 278\u001b[0m \u001b[38;5;124;03mOpenMLFlow\u001b[39;00m\n\u001b[1;32m 279\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 280\u001b[0m \u001b[38;5;66;03m# Necessary to make pypy not complain about all the different possible return types\u001b[39;00m\n\u001b[0;32m--> 281\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_serialize_pytorch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcustom_name\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:287\u001b[0m, in \u001b[0;36mPytorchExtension._serialize_pytorch\u001b[0;34m(self, o, parent_model, custom_name)\u001b[0m\n\u001b[1;32m 284\u001b[0m rval \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;66;03m# type: Any\u001b[39;00m\n\u001b[1;32m 285\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mis_estimator(o):\n\u001b[1;32m 286\u001b[0m \u001b[38;5;66;03m# is the main model or a submodel\u001b[39;00m\n\u001b[0;32m--> 287\u001b[0m rval \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_serialize_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mo\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcustom_name\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 288\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(o, (\u001b[38;5;28mlist\u001b[39m, \u001b[38;5;28mtuple\u001b[39m)):\n\u001b[1;32m 289\u001b[0m rval \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_serialize_pytorch(element, parent_model) \u001b[38;5;28;01mfor\u001b[39;00m element \u001b[38;5;129;01min\u001b[39;00m o]\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:387\u001b[0m, in \u001b[0;36mPytorchExtension._serialize_model\u001b[0;34m(self, model, custom_name)\u001b[0m\n\u001b[1;32m 370\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Create an OpenMLFlow.\u001b[39;00m\n\u001b[1;32m 371\u001b[0m \n\u001b[1;32m 372\u001b[0m \u001b[38;5;124;03mCalls `pytorch_to_flow` recursively to properly serialize the\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 382\u001b[0m \n\u001b[1;32m 383\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 385\u001b[0m \u001b[38;5;66;03m# Get all necessary information about the model objects itself\u001b[39;00m\n\u001b[1;32m 386\u001b[0m parameters, parameters_meta_info, subcomponents, subcomponents_explicit \u001b[38;5;241m=\u001b[39m \\\n\u001b[0;32m--> 387\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_extract_information_from_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 389\u001b[0m \u001b[38;5;66;03m# Check that a component does not occur multiple times in a flow as this\u001b[39;00m\n\u001b[1;32m 390\u001b[0m \u001b[38;5;66;03m# is not supported by OpenML\u001b[39;00m\n\u001b[1;32m 391\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_multiple_occurence_of_component_in_flow(model, subcomponents)\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:588\u001b[0m, in \u001b[0;36mPytorchExtension._extract_information_from_model\u001b[0;34m(self, model)\u001b[0m\n\u001b[1;32m 586\u001b[0m model_parameters \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_module_descriptors(model, deep\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m 587\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28msorted\u001b[39m(model_parameters\u001b[38;5;241m.\u001b[39mitems(), key\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mlambda\u001b[39;00m t: t[\u001b[38;5;241m0\u001b[39m]):\n\u001b[0;32m--> 588\u001b[0m rval \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_serialize_pytorch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mv\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 590\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mflatten_all\u001b[39m(list_):\n\u001b[1;32m 591\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\" Flattens arbitrary depth lists of lists (e.g. [[1,2],[3,[1]]] -> [1,2,3,1]). \"\"\"\u001b[39;00m\n", - "File \u001b[0;32m~/Documents/CODE/Github/openml-pytorch/openml_pytorch/extension.py:321\u001b[0m, in \u001b[0;36mPytorchExtension._serialize_pytorch\u001b[0;34m(self, o, parent_model, custom_name)\u001b[0m\n\u001b[1;32m 319\u001b[0m rval \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_serialize_methoddescriptor(o)\n\u001b[1;32m 320\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 321\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(o, \u001b[38;5;28mtype\u001b[39m(o))\n\u001b[1;32m 322\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m rval\n", - "\u001b[0;31mTypeError\u001b[0m: (BertConfig {\n \"_name_or_path\": \"bert-base-uncased\",\n \"architectures\": [\n \"BertForMaskedLM\"\n ],\n \"attention_probs_dropout_prob\": 0.1,\n \"classifier_dropout\": null,\n \"gradient_checkpointing\": false,\n \"hidden_act\": \"gelu\",\n \"hidden_dropout_prob\": 0.1,\n \"hidden_size\": 768,\n \"initializer_range\": 0.02,\n \"intermediate_size\": 3072,\n \"layer_norm_eps\": 1e-12,\n \"max_position_embeddings\": 512,\n \"model_type\": \"bert\",\n \"num_attention_heads\": 12,\n \"num_hidden_layers\": 12,\n \"pad_token_id\": 0,\n \"position_embedding_type\": \"absolute\",\n \"transformers_version\": \"4.44.2\",\n \"type_vocab_size\": 2,\n \"use_cache\": true,\n \"vocab_size\": 30522\n}\n, )" + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/sklearn/metrics/_classification.py:131\u001b[0m, in \u001b[0;36m_check_targets\u001b[0;34m(y_true, y_pred)\u001b[0m\n\u001b[1;32m 130\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 131\u001b[0m unique_values \u001b[38;5;241m=\u001b[39m \u001b[43m_union1d\u001b[49m\u001b[43m(\u001b[49m\u001b[43my_true\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_pred\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mxp\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 132\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 133\u001b[0m \u001b[38;5;66;03m# We expect y_true and y_pred to be of the same data type.\u001b[39;00m\n\u001b[1;32m 134\u001b[0m \u001b[38;5;66;03m# If `y_true` was provided to the classifier as strings,\u001b[39;00m\n\u001b[1;32m 135\u001b[0m \u001b[38;5;66;03m# `y_pred` given by the classifier will also be encoded with\u001b[39;00m\n\u001b[1;32m 136\u001b[0m \u001b[38;5;66;03m# strings. So we raise a meaningful error\u001b[39;00m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/sklearn/utils/_array_api.py:184\u001b[0m, in \u001b[0;36m_union1d\u001b[0;34m(a, b, xp)\u001b[0m\n\u001b[1;32m 183\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m _is_numpy_namespace(xp):\n\u001b[0;32m--> 184\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m xp\u001b[38;5;241m.\u001b[39masarray(\u001b[43mnumpy\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43munion1d\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[1;32m 185\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m a\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m==\u001b[39m b\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/numpy/lib/arraysetops.py:932\u001b[0m, in \u001b[0;36munion1d\u001b[0;34m(ar1, ar2)\u001b[0m\n\u001b[1;32m 900\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 901\u001b[0m \u001b[38;5;124;03mFind the union of two arrays.\u001b[39;00m\n\u001b[1;32m 902\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 930\u001b[0m \u001b[38;5;124;03marray([1, 2, 3, 4, 6])\u001b[39;00m\n\u001b[1;32m 931\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m--> 932\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43munique\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconcatenate\u001b[49m\u001b[43m(\u001b[49m\u001b[43m(\u001b[49m\u001b[43mar1\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mar2\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/numpy/lib/arraysetops.py:274\u001b[0m, in \u001b[0;36munique\u001b[0;34m(ar, return_index, return_inverse, return_counts, axis, equal_nan)\u001b[0m\n\u001b[1;32m 273\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m axis \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 274\u001b[0m ret \u001b[38;5;241m=\u001b[39m \u001b[43m_unique1d\u001b[49m\u001b[43m(\u001b[49m\u001b[43mar\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreturn_index\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreturn_inverse\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreturn_counts\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\n\u001b[1;32m 275\u001b[0m \u001b[43m \u001b[49m\u001b[43mequal_nan\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mequal_nan\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 276\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _unpack_tuple(ret)\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/numpy/lib/arraysetops.py:336\u001b[0m, in \u001b[0;36m_unique1d\u001b[0;34m(ar, return_index, return_inverse, return_counts, equal_nan)\u001b[0m\n\u001b[1;32m 335\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 336\u001b[0m ar\u001b[38;5;241m.\u001b[39msort()\n\u001b[1;32m 337\u001b[0m aux \u001b[38;5;241m=\u001b[39m ar\n", + "\u001b[0;31mTypeError\u001b[0m: '<' not supported between instances of 'int' and 'str'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[11], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m run \u001b[38;5;241m=\u001b[39m \u001b[43mopenml\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mruns\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_model_on_task\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:165\u001b[0m, in \u001b[0;36mrun_model_on_task\u001b[0;34m(model, task, avoid_duplicate_runs, flow_tags, seed, add_local_measures, upload_flow, return_flow, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 161\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _task\n\u001b[1;32m 163\u001b[0m task \u001b[38;5;241m=\u001b[39m get_task_and_type_conversion(task)\n\u001b[0;32m--> 165\u001b[0m run \u001b[38;5;241m=\u001b[39m \u001b[43mrun_flow_on_task\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 166\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 167\u001b[0m \u001b[43m \u001b[49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 168\u001b[0m \u001b[43m \u001b[49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mavoid_duplicate_runs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 169\u001b[0m \u001b[43m \u001b[49m\u001b[43mflow_tags\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow_tags\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 170\u001b[0m \u001b[43m \u001b[49m\u001b[43mseed\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mseed\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 171\u001b[0m \u001b[43m \u001b[49m\u001b[43madd_local_measures\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43madd_local_measures\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 172\u001b[0m \u001b[43m \u001b[49m\u001b[43mupload_flow\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mupload_flow\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 173\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 174\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 175\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 176\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m return_flow:\n\u001b[1;32m 177\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m run, flow\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:308\u001b[0m, in \u001b[0;36mrun_flow_on_task\u001b[0;34m(flow, task, avoid_duplicate_runs, flow_tags, seed, add_local_measures, upload_flow, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 300\u001b[0m warnings\u001b[38;5;241m.\u001b[39mwarn(\n\u001b[1;32m 301\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe model is already fitted!\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 302\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m This might cause inconsistency in comparison of results.\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 303\u001b[0m \u001b[38;5;167;01mRuntimeWarning\u001b[39;00m,\n\u001b[1;32m 304\u001b[0m stacklevel\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m2\u001b[39m,\n\u001b[1;32m 305\u001b[0m )\n\u001b[1;32m 307\u001b[0m \u001b[38;5;66;03m# execute the run\u001b[39;00m\n\u001b[0;32m--> 308\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43m_run_task_get_arffcontent\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 309\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 310\u001b[0m \u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 311\u001b[0m \u001b[43m \u001b[49m\u001b[43mextension\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mflow\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mextension\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 312\u001b[0m \u001b[43m \u001b[49m\u001b[43madd_local_measures\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43madd_local_measures\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 313\u001b[0m \u001b[43m \u001b[49m\u001b[43mdataset_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdataset_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 314\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 315\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 317\u001b[0m data_content, trace, fold_evaluations, sample_evaluations \u001b[38;5;241m=\u001b[39m res\n\u001b[1;32m 318\u001b[0m fields \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m*\u001b[39mrun_environment, time\u001b[38;5;241m.\u001b[39mstrftime(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%c\u001b[39;00m\u001b[38;5;124m\"\u001b[39m), \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCreated by run_flow_on_task\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:633\u001b[0m, in \u001b[0;36m_run_task_get_arffcontent\u001b[0;34m(model, task, extension, add_local_measures, dataset_format, n_jobs)\u001b[0m\n\u001b[1;32m 630\u001b[0m arff_datacontent\u001b[38;5;241m.\u001b[39mappend(arff_line)\n\u001b[1;32m 632\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m add_local_measures:\n\u001b[0;32m--> 633\u001b[0m \u001b[43m_calculate_local_measure\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 634\u001b[0m \u001b[43m \u001b[49m\u001b[43msklearn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmetrics\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43maccuracy_score\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 635\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mpredictive_accuracy\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 636\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 638\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(task, OpenMLRegressionTask):\n\u001b[1;32m 639\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m test_y \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/openml/runs/functions.py:590\u001b[0m, in \u001b[0;36m_run_task_get_arffcontent.._calculate_local_measure\u001b[0;34m(sklearn_fn, openml_name, _test_y, _pred_y, _user_defined_measures_fold)\u001b[0m\n\u001b[1;32m 583\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_calculate_local_measure\u001b[39m( \u001b[38;5;66;03m# type: ignore\u001b[39;00m\n\u001b[1;32m 584\u001b[0m sklearn_fn,\n\u001b[1;32m 585\u001b[0m openml_name,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 588\u001b[0m _user_defined_measures_fold\u001b[38;5;241m=\u001b[39muser_defined_measures_fold,\n\u001b[1;32m 589\u001b[0m ):\n\u001b[0;32m--> 590\u001b[0m _user_defined_measures_fold[openml_name] \u001b[38;5;241m=\u001b[39m \u001b[43msklearn_fn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_test_y\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m_pred_y\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/sklearn/utils/_param_validation.py:213\u001b[0m, in \u001b[0;36mvalidate_params..decorator..wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 207\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 208\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\n\u001b[1;32m 209\u001b[0m skip_parameter_validation\u001b[38;5;241m=\u001b[39m(\n\u001b[1;32m 210\u001b[0m prefer_skip_nested_validation \u001b[38;5;129;01mor\u001b[39;00m global_skip_validation\n\u001b[1;32m 211\u001b[0m )\n\u001b[1;32m 212\u001b[0m ):\n\u001b[0;32m--> 213\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 214\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m InvalidParameterError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 215\u001b[0m \u001b[38;5;66;03m# When the function is just a wrapper around an estimator, we allow\u001b[39;00m\n\u001b[1;32m 216\u001b[0m \u001b[38;5;66;03m# the function to delegate validation to the estimator, but we replace\u001b[39;00m\n\u001b[1;32m 217\u001b[0m \u001b[38;5;66;03m# the name of the estimator by the name of the function in the error\u001b[39;00m\n\u001b[1;32m 218\u001b[0m \u001b[38;5;66;03m# message to avoid confusion.\u001b[39;00m\n\u001b[1;32m 219\u001b[0m msg \u001b[38;5;241m=\u001b[39m re\u001b[38;5;241m.\u001b[39msub(\n\u001b[1;32m 220\u001b[0m \u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparameter of \u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mw+ must be\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 221\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparameter of \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfunc\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__qualname__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m must be\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 222\u001b[0m \u001b[38;5;28mstr\u001b[39m(e),\n\u001b[1;32m 223\u001b[0m )\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/sklearn/metrics/_classification.py:231\u001b[0m, in \u001b[0;36maccuracy_score\u001b[0;34m(y_true, y_pred, normalize, sample_weight)\u001b[0m\n\u001b[1;32m 229\u001b[0m xp, _, device \u001b[38;5;241m=\u001b[39m get_namespace_and_device(y_true, y_pred, sample_weight)\n\u001b[1;32m 230\u001b[0m \u001b[38;5;66;03m# Compute accuracy for each possible representation\u001b[39;00m\n\u001b[0;32m--> 231\u001b[0m y_type, y_true, y_pred \u001b[38;5;241m=\u001b[39m \u001b[43m_check_targets\u001b[49m\u001b[43m(\u001b[49m\u001b[43my_true\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_pred\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 232\u001b[0m check_consistent_length(y_true, y_pred, sample_weight)\n\u001b[1;32m 233\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m y_type\u001b[38;5;241m.\u001b[39mstartswith(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmultilabel\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.9/envs/openmlpytorch/lib/python3.11/site-packages/sklearn/metrics/_classification.py:137\u001b[0m, in \u001b[0;36m_check_targets\u001b[0;34m(y_true, y_pred)\u001b[0m\n\u001b[1;32m 131\u001b[0m unique_values \u001b[38;5;241m=\u001b[39m _union1d(y_true, y_pred, xp)\n\u001b[1;32m 132\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 133\u001b[0m \u001b[38;5;66;03m# We expect y_true and y_pred to be of the same data type.\u001b[39;00m\n\u001b[1;32m 134\u001b[0m \u001b[38;5;66;03m# If `y_true` was provided to the classifier as strings,\u001b[39;00m\n\u001b[1;32m 135\u001b[0m \u001b[38;5;66;03m# `y_pred` given by the classifier will also be encoded with\u001b[39;00m\n\u001b[1;32m 136\u001b[0m \u001b[38;5;66;03m# strings. So we raise a meaningful error\u001b[39;00m\n\u001b[0;32m--> 137\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[1;32m 138\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mLabels in y_true and y_pred should be of the same type. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 139\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGot y_true=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mxp\u001b[38;5;241m.\u001b[39munique(y_true)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m and \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 140\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124my_pred=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mxp\u001b[38;5;241m.\u001b[39munique(y_pred)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m. Make sure that the \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 141\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpredictions provided by the classifier coincides with \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 142\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mthe true labels.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 143\u001b[0m ) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[1;32m 144\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m unique_values\u001b[38;5;241m.\u001b[39mshape[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[1;32m 145\u001b[0m y_type \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmulticlass\u001b[39m\u001b[38;5;124m\"\u001b[39m\n", + "\u001b[0;31mTypeError\u001b[0m: Labels in y_true and y_pred should be of the same type. Got y_true=['bad' 'good'] and y_pred=[1]. Make sure that the predictions provided by the classifier coincides with the true labels." ] } ],