diff --git a/.gitignore b/.gitignore index 4ed315d..f93488c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ lightning_logs/ .pkl_cache/ - - +.ds/ # Distribution / packaging .Python diff --git a/mjc_notes.md b/mjc_notes.md index 7b95a48..2d54520 100644 --- a/mjc_notes.md +++ b/mjc_notes.md @@ -366,3 +366,16 @@ https://arxiv.org/pdf/2212.03827.pdf - ranking. here I do MCDropout 3 times. Then I try to rank them. There should be two similar and 2 differen't. - 1 could be a lie - 2 could be truth? + + +exp: +- [ ] try getting dual notebook working + - [x] first recache the dataset + - [ ] note dual means we pass both x0 and x1 into the model. rather than i9ndependant passes + +BUGS: +- [ ] metrics: acc is averaged over epochs, change to auroc and make per val train +- [ ] it's overfitting. maybe removing first and last layers? +- [x] 017 mjc getting hidden layers doesn't work anymore? + - [x] fix caching. ah it was just a bad test for difference fixed +- [ ] memory leak now... it just goes up... diff --git a/notebooks/017_mjc_sup_mcdrop_dm_dual_😃GOOD.ipynb b/notebooks/017_mjc_sup_mcdrop_dm_dual_😃GOOD.ipynb new file mode 100644 index 0000000..5706ad9 --- /dev/null +++ b/notebooks/017_mjc_sup_mcdrop_dm_dual_😃GOOD.ipynb @@ -0,0 +1,3449 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Lets just do supervised learning\n", + "\n", + "Since we are looking at pairs with random permuations (from dropout), we can't use CCS. This is because our probabilities do not add to one.\n", + "\n", + "People question if unsupervised learning bings anything to the table anyway, so lets start with supervised...\n", + "\n", + "\n", + "This one is `dual` in that itpasses both parts of the pair into the model at once.\n", + "\n", + "```\n", + "x = torch.concat([x0, x1], 1)\n", + "y_pred =model(x)\n", + "loss(y_pred, y)\n", + "```\n", + "as opposed to\n", + "```\n", + "logit0 = model(x0)\n", + "logit1 = model(x1)\n", + "y_pred = torch.concat([logit0, logit1])\n", + "loss(y_pred, y)\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "links:\n", + "- [loading](https://github.com/deep-diver/LLM-As-Chatbot/blob/main/models/alpaca.py)\n", + "- [dict](https://github.com/deep-diver/LLM-As-Chatbot/blob/c79e855a492a968b54bac223e66dc9db448d6eba/model_cards.json#L143)\n", + "- [prompt_format](https://github.com/deep-diver/PingPong/blob/main/src/pingpong/alpaca.py)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'4.30.1'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "import copy\n", + "import numpy as np\n", + "import pandas as pd\n", + "from matplotlib import pyplot as plt\n", + "plt.style.use('ggplot')\n", + "\n", + "import random\n", + "from typing import Optional, List, Dict, Union\n", + "\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "from torch import Tensor\n", + "from torch import optim\n", + "from torch.utils.data import random_split, DataLoader, TensorDataset\n", + "\n", + "import pickle\n", + "import hashlib\n", + "from pathlib import Path\n", + "\n", + "from datasets import load_dataset\n", + "import datasets\n", + "\n", + "from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModelForMaskedLM, AutoModelForCausalLM, AutoConfig\n", + "import transformers\n", + "from transformers.models.auto.modeling_auto import AutoModel\n", + "from transformers import LogitsProcessorList\n", + "\n", + "\n", + "import lightning.pytorch as pl\n", + "from dataclasses import dataclass\n", + "\n", + "from sklearn.linear_model import LogisticRegression\n", + "# from scipy.stats import zscore\n", + "from sklearn.metrics import f1_score, roc_auc_score, accuracy_score\n", + "from sklearn.preprocessing import RobustScaler\n", + "\n", + "from tqdm.auto import tqdm\n", + "import gc\n", + "import os\n", + "\n", + "from loguru import logger\n", + "logger.add(os.sys.stderr, format=\"{time} {level} {message}\", level=\"INFO\")\n", + "\n", + "\n", + "transformers.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from datasets import load_from_disk\n", + "f='./.ds/WizardLMWizardCoder_15B_V1.0-None-N_40-ns_3-mc_True-593d1f'\n", + "f='./.ds/WizardLMWizardCoder_15B_V1.0-None-N_4000-ns_3-mc_True-a55583_v2'\n", + "ds = load_from_disk(f)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Lightning DataModule" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def ds_info2df(ds):\n", + " d = pd.DataFrame(ds['info'])\n", + " for c in ['desired_answer', 'lie', 'true_answer']:\n", + " d[c] = d[c].map(lambda x:x.item())\n", + " return d\n", + "\n", + "class imdbHSDataModule(pl.LightningDataModule):\n", + "\n", + " def __init__(self,\n", + " ds,\n", + " batch_size=32,\n", + " ):\n", + " super().__init__()\n", + " self.save_hyperparameters(ignore=[\"ds\"])\n", + " self.ds = ds\n", + "\n", + " def setup(self, stage: str):\n", + " h = self.hparams\n", + " \n", + " # extract data set into N-Dim tensors and 1-d dataframe\n", + " self.ds_hs = (\n", + " self.ds.select_columns(['hs1', 'hs2'])\n", + " .with_format(\"numpy\")\n", + " )\n", + " \n", + " df_infos = ds_info2df(self.ds)\n", + " df_ans = self.ds.select_columns(['ans1', 'ans2', 'true']).with_format(\"numpy\").to_pandas()\n", + " self.df_infos = pd.concat([df_infos, df_ans], axis=1)\n", + " self.df_infos['dir_true'] = self.df_infos['ans2'] - self.df_infos['ans1']\n", + " self.df_infos['ans'] = (self.df_infos['ans2'] + self.df_infos['ans1']) / 2\n", + " \n", + " b = len(self.ds_hs)\n", + " self.y = self.df_infos['true_answer'].astype(np.float32).values\n", + " self.hs1 = self.ds_hs['hs1'].reshape((b, -1))#.numpy()\n", + " self.hs2 = self.ds_hs['hs2'].reshape((b, -1))#.numpy() \n", + " self.ans1 = self.df_infos['ans1'].values\n", + " self.ans2 = self.df_infos['ans2'].values\n", + " \n", + " # # in ELK they cache as a huggingface dataset\n", + " # self.hs1, self.ans1, self.hs2, self.ans2, self.y, self.infos = \n", + "\n", + " # let's create a simple 50/50 train split (the data is already randomized)\n", + " n = len(self.y)\n", + " self.val_split = vs = int(n * 0.5)\n", + " self.test_split = ts = int(n * 0.75)\n", + " hs1_train, hs2_train, y_train = self.hs1[:vs], self.hs2[:vs], self.y[:vs]\n", + " hs1_val, hs2_val, y_val = self.hs1[vs:ts], self.hs2[vs:ts], self.y[vs:ts]\n", + " hs1_test, hs2_test, y_test = self.hs1[ts:],self. hs2[ts:], self.y[ts:]\n", + "\n", + " # for simplicity we can just take the difference between positive and negative hidden states\n", + " # (concatenating also works fine)\n", + " self.x_train = hs1_train - hs2_train\n", + " self.x_val = hs1_val - hs2_val\n", + " self.x_test = hs1_test - hs2_test\n", + "\n", + " # normalize\n", + " self.scaler = RobustScaler()\n", + " self.scaler.fit(self.x_train)\n", + " self.x_train = self.scaler.transform(self.x_train)\n", + " self.x_val = self.scaler.transform(self.x_val)\n", + " self.x_test = self.scaler.transform(self.x_test)\n", + "\n", + " self.ds_train = TensorDataset(torch.from_numpy(hs1_train).float(),\n", + " torch.from_numpy(hs2_train).float(),\n", + " torch.from_numpy(y_train).float())\n", + "\n", + " self.ds_val = TensorDataset(torch.from_numpy(hs1_val).float(),\n", + " torch.from_numpy(hs2_val).float(),\n", + " torch.from_numpy(y_val).float())\n", + "\n", + " self.ds_test = TensorDataset(torch.from_numpy(hs1_test).float(),\n", + " torch.from_numpy(hs2_test).float(),\n", + " torch.from_numpy(y_test).float())\n", + "\n", + " def train_dataloader(self):\n", + " return DataLoader(self.ds_train,\n", + " batch_size=self.hparams.batch_size,\n", + " shuffle=True)\n", + "\n", + " def val_dataloader(self):\n", + " return DataLoader(self.ds_val, batch_size=self.hparams.batch_size)\n", + "\n", + " def test_dataloader(self):\n", + " return DataLoader(self.ds_test, batch_size=self.hparams.batch_size)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[tensor([[ 2.6709e-01, -1.5457e-02, -7.4463e-02, ..., 7.1191e-01,\n", + " 2.0527e+00, 1.1547e+01],\n", + " [ 7.3792e-02, -1.7075e-02, -5.1544e-02, ..., 1.6416e+00,\n", + " 6.4087e-03, 1.9391e+01],\n", + " [ 2.0581e-01, 1.8631e-02, -9.9854e-02, ..., 4.6250e+00,\n", + " -1.9219e+00, 1.6750e+01],\n", + " ...,\n", + " [ 2.3865e-01, -4.9927e-02, -3.3722e-02, ..., -3.0840e+00,\n", + " 3.6758e+00, 1.5859e+01],\n", + " [ 1.6003e-01, -2.7924e-02, -2.8290e-02, ..., -4.5410e-01,\n", + " -3.0176e+00, 1.0461e+01],\n", + " [ 2.6904e-01, -6.6986e-03, -4.1870e-02, ..., -4.8320e+00,\n", + " -4.3555e+00, 8.3359e+00]]),\n", + " tensor([[ 8.0261e-02, -1.7548e-02, -4.7943e-02, ..., -1.9355e+00,\n", + " 3.2666e-01, 1.5453e+01],\n", + " [ 3.6377e-02, -4.7272e-02, -7.0679e-02, ..., -1.5293e+00,\n", + " 3.2129e+00, 1.8844e+01],\n", + " [ 1.7456e-01, -4.3793e-02, -1.0022e-01, ..., 3.3047e+00,\n", + " -2.3145e+00, 2.3359e+01],\n", + " ...,\n", + " [ 2.3767e-01, -6.2134e-02, -8.7708e-02, ..., -1.3584e+00,\n", + " 3.2168e+00, 1.8344e+01],\n", + " [ 2.0789e-01, -1.0391e-02, -8.2153e-02, ..., -4.8145e-01,\n", + " -2.9141e+00, 1.2547e+01],\n", + " [ 6.1920e-02, -3.1952e-02, -8.6243e-02, ..., -3.4160e+00,\n", + " -6.8320e+00, 7.7969e+00]]),\n", + " tensor([0., 0., 1., 0., 1., 0., 0., 1., 0., 0., 1., 1., 1., 1., 1., 0., 1., 1.,\n", + " 0., 1., 1., 1., 1., 1., 1., 0., 0., 0., 1., 1., 0., 1.])]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "batch_size = 32\n", + "# test and cache\n", + "dm = imdbHSDataModule(ds, batch_size=batch_size)\n", + "dm.setup('train')\n", + "\n", + "dl_val = dm.val_dataloader()\n", + "dl_train = dm.train_dataloader()\n", + "b = next(iter(dl_train))\n", + "b" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "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", + "
desired_answerinputlietrue_answerans1ans2truedir_trueans
0TrueHow can anyone still feed this to children? I ...True00.5190430.5073240-0.0117190.513184
1FalseI ordered this movie from Amazon and it was gr...False00.5883790.3005370-0.2878420.444336
2TrueThis movie has the right pedigree - Coen broth...True00.2015380.1022340-0.0993040.151855
3Falseok so i got the sword and the box it came in w...False00.3662110.64355500.2773440.504883
4TrueI was anticipating the use of wireless headpho...True00.4799800.4221190-0.0578610.451172
..............................
3995FalseAs others have said, the instructions were not...False00.1799320.21179200.0318600.195801
3996TrueThis book has great potential but it doesn't l...True00.0325620.03729200.0047300.034912
3997TrueI was intending to use beta sitosterol for hai...False10.9404300.94238310.0019530.941406
3998FalseThis is really compact and comes with 3 bags t...True10.9633790.9418951-0.0214840.952637
3999TrueI bought the paperback because it sounded inte...False10.9985350.9970701-0.0014650.998047
\n", + "

4000 rows × 9 columns

\n", + "
" + ], + "text/plain": [ + " desired_answer input \n", + "0 True How can anyone still feed this to children? I ... \\\n", + "1 False I ordered this movie from Amazon and it was gr... \n", + "2 True This movie has the right pedigree - Coen broth... \n", + "3 False ok so i got the sword and the box it came in w... \n", + "4 True I was anticipating the use of wireless headpho... \n", + "... ... ... \n", + "3995 False As others have said, the instructions were not... \n", + "3996 True This book has great potential but it doesn't l... \n", + "3997 True I was intending to use beta sitosterol for hai... \n", + "3998 False This is really compact and comes with 3 bags t... \n", + "3999 True I bought the paperback because it sounded inte... \n", + "\n", + " lie true_answer ans1 ans2 true dir_true ans \n", + "0 True 0 0.519043 0.507324 0 -0.011719 0.513184 \n", + "1 False 0 0.588379 0.300537 0 -0.287842 0.444336 \n", + "2 True 0 0.201538 0.102234 0 -0.099304 0.151855 \n", + "3 False 0 0.366211 0.643555 0 0.277344 0.504883 \n", + "4 True 0 0.479980 0.422119 0 -0.057861 0.451172 \n", + "... ... ... ... ... ... ... ... \n", + "3995 False 0 0.179932 0.211792 0 0.031860 0.195801 \n", + "3996 True 0 0.032562 0.037292 0 0.004730 0.034912 \n", + "3997 False 1 0.940430 0.942383 1 0.001953 0.941406 \n", + "3998 True 1 0.963379 0.941895 1 -0.021484 0.952637 \n", + "3999 False 1 0.998535 0.997070 1 -0.001465 0.998047 \n", + "\n", + "[4000 rows x 9 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hss1 = dm.hs1\n", + "hss2 = dm.hs2\n", + "ans_1 = dm.ans1\n", + "ans_2 = dm.ans2\n", + "df_infos = dm.df_infos\n", + "df_infos" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Task results\n", + "\n", + "E.g. how well does the underlying language model do on the task" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "model acc on sentiment task\n", + "acc 0.88\n", + "acc when lie=True 0.87\n", + "acc when lie=False 0.89\n" + ] + } + ], + "source": [ + "print('model acc on sentiment task')\n", + "ans = (ans_1 + ans_2) / 2\n", + "acc=((ans>0.5)==df_infos['true_answer']).mean()\n", + "print(f\"acc {acc:2.2f}\")\n", + "\n", + "d = df_infos['lie']==True\n", + "acc = ((ans[d]>0.5)==df_infos[d]['true_answer']).mean()\n", + "print(f\"acc when lie=True {acc:2.2f}\")\n", + "\n", + "d = df_infos['lie']==False\n", + "acc = ((ans[d]>0.5)==df_infos[d]['true_answer']).mean()\n", + "print(f\"acc when lie=False {acc:2.2f}\")\n", + "# ((ans_1>0)==df_infos['desired_answer']).mean()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Data prep\n", + "\n", + "We do two inferences on the same inputs. Since we have dropout enabled, even during inference, we get two slightly different hidden states `hs1` and `hs2`, and two slightly different probabilities for our yes and no output tokens `p1` `p2`. We also have the true answer `t`\n", + "\n", + "So there are a few ways we can set up the problem. \n", + "\n", + "We can vary x:\n", + "- `model(hs1)-model(hs2)=y`\n", + "- `model(hs1-hs2)==y`\n", + "\n", + "And we can try differen't y's:\n", + "- direction with a ranked loss. This could be unsupervised.\n", + "- magnitude with a regression loss\n", + "- vector (direction and magnitude) with a regression loss" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# QC: Linear supervised probes\n", + "\n", + "\n", + "Let's verify that the model's representations are good\n", + "\n", + "Before trying CCS, let's make sure there exists a direction that classifies examples as true vs false with high accuracy; if supervised logistic regression accuracy is bad, there's no hope of unsupervised CCS doing well.\n", + "\n", + "Note that because logistic regression is supervised we expect it to do better but to have worse generalisation that equivilent unsupervised methods. However in this case CSS is using a deeper model so it is more complicated.\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Try a classification of direction to truth" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "split size 2000\n" + ] + }, + { + "data": { + "text/html": [ + "
LogisticRegression(class_weight='balanced', max_iter=380)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "LogisticRegression(class_weight='balanced', max_iter=380)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "n = len(df_infos)\n", + "\n", + "# Define X and y\n", + "X = hss1-hss2\n", + "\n", + "y = y_dir = df_infos['true_answer'] == (df_infos['dir_true']>0) # direction\n", + "\n", + "# split\n", + "n = len(y)\n", + "print('split size', n//2)\n", + "X_train, X_test = X[:n//2], X[n//2:]\n", + "y_train, y_test = y[:n//2], y[n//2:]\n", + "\n", + "# scale\n", + "scaler = RobustScaler()\n", + "scaler.fit(X_train)\n", + "X_train2 = scaler.transform(X_train)\n", + "X_test2 = scaler.transform(X_test)\n", + "\n", + "lr = LogisticRegression(class_weight=\"balanced\", penalty=\"l2\", max_iter=380)\n", + "lr.fit(X_train2, y_train>0)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Logistic cls acc: 100.00% [TRAIN]\n", + "Logistic cls acc: 65.10% [TEST]\n", + "test acc w lie 65.70%\n", + "test acc wo lie 64.50%\n" + ] + } + ], + "source": [ + "print(\"Logistic cls acc: {:2.2%} [TRAIN]\".format(lr.score(X_train2, y_train>0)))\n", + "print(\"Logistic cls acc: {:2.2%} [TEST]\".format(lr.score(X_test2, y_test>0)))\n", + "\n", + "m = df_infos['lie'][n//2:]\n", + "y_test_pred = lr.predict(X_test2)\n", + "acc_w_lie = ((y_test_pred[m]>0)==(y_test[m]>0)).mean()\n", + "acc_wo_lie = ((y_test_pred[~m]>0)==(y_test[~m]>0)).mean()\n", + "print(f'test acc w lie {acc_w_lie:2.2%}')\n", + "print(f'test acc wo lie {acc_wo_lie:2.2%}')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "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", + "
desired_answerinputlietrue_answerans1ans2truedir_trueansinner_truth
2000TrueCandy is simply a tame attempt to stay relevan...True00.4877930.70166000.2138670.594727False
2001FalseI'm going to start saying that i'm reviewing a...False00.3955080.42968800.0341800.412598True
2002TrueI am embarrased to admit that I own this book....True00.7421880.4604490-0.2817380.601562True
2003TrueIf you read \"Full Catastrophe Living\" as I did...False10.9658200.98584010.0200200.975586True
2004TrueMy daughter was so excited for this costume. I...True00.4257810.1539310-0.2719730.289795True
.................................
3995FalseAs others have said, the instructions were not...False00.1799320.21179200.0318600.195801True
3996TrueThis book has great potential but it doesn't l...True00.0325620.03729200.0047300.034912False
3997TrueI was intending to use beta sitosterol for hai...False10.9404300.94238310.0019530.941406True
3998FalseThis is really compact and comes with 3 bags t...True10.9633790.9418951-0.0214840.952637False
3999TrueI bought the paperback because it sounded inte...False10.9985350.9970701-0.0014650.998047False
\n", + "

2000 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " desired_answer input \n", + "2000 True Candy is simply a tame attempt to stay relevan... \\\n", + "2001 False I'm going to start saying that i'm reviewing a... \n", + "2002 True I am embarrased to admit that I own this book.... \n", + "2003 True If you read \"Full Catastrophe Living\" as I did... \n", + "2004 True My daughter was so excited for this costume. I... \n", + "... ... ... \n", + "3995 False As others have said, the instructions were not... \n", + "3996 True This book has great potential but it doesn't l... \n", + "3997 True I was intending to use beta sitosterol for hai... \n", + "3998 False This is really compact and comes with 3 bags t... \n", + "3999 True I bought the paperback because it sounded inte... \n", + "\n", + " lie true_answer ans1 ans2 true dir_true ans \n", + "2000 True 0 0.487793 0.701660 0 0.213867 0.594727 \\\n", + "2001 False 0 0.395508 0.429688 0 0.034180 0.412598 \n", + "2002 True 0 0.742188 0.460449 0 -0.281738 0.601562 \n", + "2003 False 1 0.965820 0.985840 1 0.020020 0.975586 \n", + "2004 True 0 0.425781 0.153931 0 -0.271973 0.289795 \n", + "... ... ... ... ... ... ... ... \n", + "3995 False 0 0.179932 0.211792 0 0.031860 0.195801 \n", + "3996 True 0 0.032562 0.037292 0 0.004730 0.034912 \n", + "3997 False 1 0.940430 0.942383 1 0.001953 0.941406 \n", + "3998 True 1 0.963379 0.941895 1 -0.021484 0.952637 \n", + "3999 False 1 0.998535 0.997070 1 -0.001465 0.998047 \n", + "\n", + " inner_truth \n", + "2000 False \n", + "2001 True \n", + "2002 True \n", + "2003 True \n", + "2004 True \n", + "... ... \n", + "3995 True \n", + "3996 False \n", + "3997 True \n", + "3998 False \n", + "3999 False \n", + "\n", + "[2000 rows x 10 columns]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_info_test = df_infos.iloc[n//2:].copy()\n", + "y_pred = lr.predict(X_test2)\n", + "df_info_test['inner_truth'] = y_pred\n", + "df_info_test" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Result, detecting deception?" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "model can detect lies with acc 52.00%\n", + "w lies 1000/2000 test rows\n" + ] + } + ], + "source": [ + "lie_pred = df_info_test['inner_truth']==df_info_test['true_answer']\n", + "lie_true = df_info_test['lie']\n", + "acc_lie = accuracy_score(lie_pred, lie_true)\n", + "print(f\"model can detect lies with acc {acc_lie:2.2%}\")\n", + "print(f\"w lies {sum(lie_true)}/{len(lie_true)} test rows\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Try a regression of the vector (magnitude and direction) vs truth" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "bool_to_switch = lambda b:b*2-1\n", + "true_answer_switch = bool_to_switch(df_infos['true_answer'])\n", + "y = y_left_more_true = df_infos['dir_true'] * true_answer_switch\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "split size 2000\n" + ] + }, + { + "data": { + "text/html": [ + "
ElasticNet()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "ElasticNet()" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Try a regression\n", + "from sklearn.linear_model import ElasticNet\n", + "\n", + "# Try a classification of direction\n", + "n = len(df_infos)\n", + "\n", + "# Define X and y\n", + "X = hss1-hss2\n", + "y = y_left_more_true * 10\n", + "\n", + "# split\n", + "# y = df_infos2['dir2'] * 100\n", + "n = len(y)\n", + "print('split size', n//2)\n", + "X_train, X_test = X[:n//2], X[n//2:]\n", + "y_train, y_test = y[:n//2], y[n//2:]\n", + "\n", + "# scale\n", + "scaler = RobustScaler()\n", + "scaler.fit(X_train)\n", + "X_train2 = scaler.transform(X_train)\n", + "X_test2 = scaler.transform(X_test)\n", + "\n", + "X_train2 = X_train\n", + "X_test2 = X_test2\n", + "\n", + "lr2 = ElasticNet(max_iter=1000,)\n", + "lr2.fit(X_train2, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "acc from train ElasticNet 0.59\n", + "acc from test ElasticNet 0.58\n" + ] + } + ], + "source": [ + "eps = 0.\n", + "acc=np.mean((lr2.predict(X_train2)>eps)==(y_train>eps))\n", + "print(f'acc from train ElasticNet {acc:2.2f}')\n", + "acc=np.mean((lr2.predict(X_test2)>eps)==(y_test>eps))\n", + "print(f'acc from test ElasticNet {acc:2.2f}')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'pred vs true on test')" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkYAAAHMCAYAAAAwHmdPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABvg0lEQVR4nO3deXxTVfo/8M+9SffSDQqllFUER0CKC6DosLmyjBb8KcgiICCD+6ioOAzgV0RAxVGHEXeQRRFBVBZlEAQ3cEDAig4uVMC2UmzTQjea3Pv74yahabab5Ga9n/fr5QxJbpJzkjT3yTnPeY4gy7IMIiIiIoIY7gYQERERRQoGRkRERERWDIyIiIiIrBgYEREREVkxMCIiIiKyYmBEREREZMXAiIiIiMiKgRERERGRFQMjIiIiIisGRkSkWocOHdChQ4dwN4OIKGgYGBFRzHjjjTcgCALeeOONcDcl6uzYsQOCIGDOnDkhf+4JEyZAEAQUFRWF/LmJmmJgRERERGTFwIiIiIjIioERUYQoKiqCIAiYMGECfvjhB9xwww3IyspCSkoKLr/8cnz88cdO92k8dbRlyxYMGDAA6enpEATBfozZbMaSJUvQt29fpKWlITk5Gb169cILL7wASZKcHlOWZbzwwgvo1q0bEhMT0aZNG9x5552orKxU3ZfffvsNBoMBvXr1cnvMddddB0EQUFhYaL/u/fffx+DBg9G6dWskJCQgNzcX/fv3x5IlS7w+54ABAzBx4kQAwMSJEyEIgv0/2xTNnDlzIAgCduzYgVWrVqFPnz5ITU215015m07ylGO1evVqDBw4EBkZGUhMTMSf/vQnPP7446ivr/fa9sZKSkpwxx13oEOHDoiPj0d2djZGjBiBvXv3Oh3b+P3fvn07BgwYgGbNmiEtLQ1Dhw7F999/r+o5J0yYgIEDBwIA5s6d6/Da7dixw+9+7tq1C8OHD0deXh4SEhKQk5ODvn37Yu7cufZjBEHAsmXLAAAdO3a0Py9z2ShcjOFuABE5OnLkCC699FL06NEDt99+O0pKSvD222/juuuuw6pVq3DzzTc73Wft2rXYsmULrrvuOkybNg2//vorAKChoQHDhw/HRx99hK5du+KWW25BYmIitm/fjrvuugu7d+/Gm2++6fBY9957L5577jm0bt0aU6dORVxcHDZs2IDdu3fjzJkziI+P99qHNm3a4Morr8THH3+Mb7/9Fj169HC4vaSkBFu3bsVFF12E7t27AwBeeukl3H777cjJycHw4cPRokULnDhxAgcPHsTrr7+O6dOne3zOCRMmICMjAxs2bMD111+P/Px8+20ZGRkOxz799NPYunUrhg8fjoEDB/oU9LkyadIkvP7668jLy8PIkSORkZGBr776CrNmzcK2bduwdetWGI3ev26PHDmCyy+/HMXFxRg0aBBGjx6NY8eO4Z133sHGjRvx7rvvYtiwYU73+/DDD7Fhwwb7+3/o0CFs2rQJX3/9NQ4dOoQWLVp4fN4bbrgBALBs2TL0798fAwYMsN/WOEDxpZ9btmzB0KFDkZaWhr/85S9o06YNysvL8f3332PJkiWYPXs2AGD27Nl47733cODAAdxzzz3296rpe0YUMjIRRYQjR47IAGQA8gMPPOBw29dffy0bjUY5IyNDrqystF//+uuvywBkQRDkzZs3Oz3m7NmzZQDynXfeKZvNZvv1ZrNZnjRpkgxAfu+99+zXf/755zIA+ZxzzpH/+OMP+/W1tbVy3759ZQBy+/btVfVn1apVMgD5/vvvd7pt4cKFMgD5ueees1934YUXyvHx8fLvv//udHxZWZmq57S9Hq+//rrL222vR3Jysrxv3z6n27dv3y4DkGfPnu3y/u3bt3fqv+05CwoK5JqaGpfP9+yzz6pq/9VXXy0DkB9//HGH6z///HPZYDDIWVlZ8qlTp5ye22AwyP/5z38c7vPwww/LAOQFCxaoem5vffe1nyNGjJAByPv373d6rKbv56233ioDkI8cOaKqrUTBxKk0ogiTnp6Of/zjHw7XXXzxxRgzZgxMJhPWr1/vdJ/rr78e1157rcN1kiTh+eefR05ODhYvXgyDwWC/zWAw4Omnn4YgCFi5cqX9+tdffx0A8OijjyIrK8t+fWJiIubPn+9TP2644Qakp6dj5cqVsFgsDrctW7YMcXFxGD16tMP1RqMRcXFxTo/lbcTDV1OnTvU4zeeLf/7znzAajXjttdeQlJTkcNusWbPQvHlzh9fYnePHj+Pjjz9Gu3btMGPGDIfbLrvsMowePRrl5eVYt26d031HjRqFwYMHO1w3depUAMCePXt87ZJL/vaz6bGA9u8nkZY4lUYUYS688EI0a9bM6foBAwZg2bJl+Oabb3Drrbc63Na7d2+n4w8fPozy8nKce+65ePzxx10+V1JSkkMeyr59+wAA/fv3dzr28ssvdwiuvElKSsJNN92El19+GR999BGGDBkCANi7dy++++47FBQUOJwgx4wZg/vvvx/nn38+Ro0ahf79+6Nfv37Izs5W/ZxquXq9/FFTU4MDBw6gRYsWePbZZ10ek5CQoCrX55tvvgEAXHHFFS6Dw0GDBmHFihX45ptvMH78eIfbLr74Yqfj27ZtCwCoqKjw+tze+NPPMWPGYN26dejTpw9uvvlmDBw4EP369UNeXl7A7SEKJgZGRBGmVatWLq/PyckBAJf5MLbbGvvjjz8AAD/++KNDsmtTp0+ftv/b9tiu2mA0Gn3+pT9hwgS8/PLLWLZsmT0wsiXaNg3u/va3v6FFixZYsmQJnnvuOTz77LMQBAH9+/fHokWLXJ78/eXq9fJHRUUFZFlGWVmZx9dYDdtr37p1a5e32643mUxOt7nKx7Hl+jQdrfOHP/0cMWIEPvzwQzz99NN47bXXsHTpUgDARRddhPnz5+Oqq64KuF1EwcCpNKII8/vvv7u8vrS0FIAy1dZU41VoNrbjCgoKIMuy2/+OHDnidB9XbTCbzTh58qRPfbnssstw7rnn4v3334fJZEJDQwNWr16NFi1a2AOlxsaPH4+vvvoKf/zxBzZu3IjbbrsNO3fuxDXXXIOysjKfntsTV68XAIii8pVoNptd3t40KLG9Xr169fL4Gsuy7LVNtseyvc9NlZSUOBwXSv72c+jQofjkk09QUVGBbdu24b777sN3332HYcOG4dChQyHvB5EaDIyIIsy+fftw6tQpp+tty6bV5sacd9559lVDDQ0Nqu5z4YUXAgA+/fRTp9s+++wzv0Yfbr31VtTV1eHtt9/Gxo0bcfLkSdxyyy0up4tsMjIyMGTIELz88suYMGECysvLsXPnTq/PZZvq83eUJDMzEwBw7Ngxp9t++uknp9G61NRUdOvWDd999x3Ky8v9ek4b2/v62WefuQzMtm/fDuDse6Q1T69doP1MSUnBoEGD8Mwzz2DmzJk4c+YMNm/erOq5iUKNgRFRhKmsrMRjjz3mcN1///tfrFy5Eunp6SgoKFD1OEajEXfddRdKSkpw9913o7a21umYkpISh1/uEyZMAADMmzfP4QRYV1eHRx55xI/eKKNAoihi+fLlWL58ucPzNLZ9+3aXIysnTpwAACQnJ3t9rubNmwMAjh496ldbzzvvPKSlpWHDhg325wWA2tpa3H333S7v87e//Q1nzpzBpEmTXE5zVVRU2HO3PMnLy8NVV12FoqIipzye3bt3Y9WqVcjMzFT9/vvK22vnaz937tzpMsCzjUY2fj8Dfd+ItMQcI6II8+c//xmvvPIKdu/ejX79+tnrGEmShKVLlyItLU31Y82aNQsHDhzAiy++iA8++ACDBg1CmzZtcOLECfz444/4/PPPMW/ePJx//vkAgH79+uGuu+7C888/j+7du+PGG2+01zHKzMx0m//iSdu2bTFw4EBs27YNRqMRPXr0cDnqVVBQgNTUVPTt2xcdOnSALMvYtWsXvv76a1x00UW48sorvT7XpZdeiuTkZDz77LP4448/7LlEd911l6opqLi4ONxzzz34v//7P/Tq1QsFBQUwm83YunUrcnNzkZub63SfSZMmYe/evViyZAnOOeccXHPNNWjXrh3Ky8tx5MgR7Ny5ExMnTsSLL77o9flffPFF9OvXDw8++CA+/vhjXHzxxfY6RqIo4vXXX3eZmK+Frl27ok2bNnjrrbcQFxeH9u3bQxAEjBs3Du3bt/e5n3fffTd+++039OvXz16scu/evfjkk0/Qvn17jBo1yv7cgwcPxqJFizBlyhSMHDkSzZo1Q0ZGBu68886g9JXIoxCVBSAiL2x1jG699Vb50KFD8l/+8hc5IyNDTkpKki+77DJ5y5YtTvfxVrdHlmVZkiR5+fLl8qBBg+TMzEw5Li5Ozs3Nlfv16yfPmzdPPnr0qNPxzz//vHzeeefJ8fHxcuvWreXp06fLJpPJZR0fNd588017jaannnrK5TH//ve/5RtuuEHu2LGjnJSUJGdmZsr5+fnyggUL5KqqKtXPtXnzZrlv375ySkqK/Tlt9XFs9Xa2b9/u9v6SJMnz58+XO3XqJMfFxclt27aVH3zwQbm6utpj/z/44AN56NChcnZ2thwXFye3atVKvuSSS+RHH31U/v7771W3//jx4/K0adPkdu3ayXFxcXLz5s3l66+/Xt6zZ4/Tsd7efwBy//79VT/3nj175EGDBslpaWmyIAguXyu1/Xz77bflUaNGyZ07d5ZTUlLkZs2ayd26dZNnzpwpnzhxwum5n376aftnDj7UyyLSmiDLKrICiSjoioqK0LFjR9x6663cHZ6IKEyYY0RERERkxcCIiIiIyIqBEREREZEVc4yIiIiIrDhiRERERGTFwIiIiIjIioERERERkRUDIyIiIiIrbgnip4qKCrc7cEea7OxsTXcmjyZ67Tv7rT967bte+w3ot+/+9ttoNNo3ivZ4nD+NIsBsNqvesTycBEEAoLRXbwsQ9dp39ltf/Qb023e99hvQb99D0W9OpRERERFZMTAiIiIismJgRERERGTFwIiIiIjIioERERERkRUDIyIiIiIrBkZEREREVgyMiIiIiKwYGBERERFZRXXl60OHDuH999/HkSNHUFFRgQceeAC9e/d2e/x3332HuXPnOl3/0ksvISMjI4gtJSLynyzL9oq/RBRcUR0Y1dfXo0OHDhg0aBCeeuop1fd79tlnkZycbL+clpYWjOYREflNrquBtH4FcGAPYDEDBiPQszfEgrEQEpO9PwAR+SWqA6NevXqhV69ePt8vPT0dKSkpQWgREVHg5LoaSPNnACXHgMb7Qe3YBOmHgxAfWcjgiChIojow8teMGTPQ0NCAtm3b4v/9v/+H8847z+2xDQ0NDpvFCoKApKQk+78jna2N0dBWrem17+x39PdbWr/COSgCAEkCSo9Dfm8lxNFT7VfHUt99odd+A/rteyj6ravAKDMzE1OmTME555yDhoYGbNu2DXPnzsW8efPQqVMnl/dZv3491q5da7/csWNHLFiwANnZ2aFqtiZycnLC3YSw0Wvf2e/oVVy4FxZ3O4dLEsTCvWjdurXTTbHQd3/otd+AfvsezH7rKjDKzc1Fbm6u/XLXrl3x+++/Y+PGjbjrrrtc3qegoADDhg2zX7ZFqWVlZTCbzcFtsAYEQUBOTg5KS0shu/uijVF67Tv7Hd39lmUZljNnPB5jqa9HcXGxw6/nWOi7r/Tab0C/fQ+k30ajUdWghq4CI1c6d+6MH374we3tcXFxiIuLc3lbNH0YZVmOqvZqSa99Z7+jmMGg6vam/YyJvvtBr/0G9Nv3YPZb93WMioqKkJmZGe5mEBGd1bM3ILr5ehZF5XYiCoqoHjGqq6tDaWmp/fKJEydQVFSE1NRUtGjRAqtWrUJ5eTnuvPNOAMDGjRvRsmVLtG3bFmfOnMEnn3yCwsJC/P3vfw9XF4iInIgFYyH9cBAoPa4kXNtvEIGcPIgFY8PXOKIYF9WB0c8//+xQsHH58uUAgP79++OOO+5ARUUFTp48ab/dbDZj+fLlKC8vR0JCAtq3b49Zs2ahe/fuIW87EZE7QmIyxEcWNqpjZFGmz1jHiCjoBFmPk5MaKCsrc1jGH6kEQUDr1q1RUlKiu3lovfad/Y69fnurfB3LffdEr/0G9Nv3QPodFxenKvla9zlGRESRTm+1aojCiYERERERkRUDIyIiIiIrBkZEREREVgyMiIiIfKSnhGe9ierl+kRERKEi19U0KqFgBgxGllCIQQyMiIiIvJDraiDNnwGUHAMajxbt2ATph4MQH1nI4ChGcCqNiIjIC2n9CuegCFAqk5ceV26nmMDAiIiIyJsDe5yDIhtJUm6nmMDAiIiIyANZlpWcIk8sFiZkxwgGRkRERB4IgqAkWntiMLBCeYxgYERERORNz96A6OaUKYrK7RQTGBgRERF5IRaMBXLynIMjUQRy8pTbKSZwuT4REZEXQmIyxEcWNqpjZAEMBtYxikEMjIiIiFQQEpNhGD0VGD0VsiwzpyhGcSqNiIjIRwyKYhcDIyKiKMYl4kTa4lQaEVGUabpnl2QwouKygZCvGQEkJIW7eURRjYEREVEUcbdn1+mN7wB7v+SeXUQB4lQaEVEU4Z5dRMHFwIiIKJpwzy6ioGJgREQUJbhnF1HwMTAiIooS3LOLKPgYGBERRRPu2UUUVAyMiIiiCPfsIgouLtcnIooi7vbsSu03CLVXF7COEVGAGBgREUWZpnt2iaKIzNatUVdSwsRrogBxKo2IKIox0ZpIWwyMiIiIiKwYGBERERFZMTAiIiIismJgRERERGQV1avSDh06hPfffx9HjhxBRUUFHnjgAfTu7bm42XfffYfly5fj2LFjaN68OUaOHIkBAwaEpsFEREQU0aJ6xKi+vh4dOnTAbbfdpur4EydO4Mknn0S3bt2wcOFCDB06FC+++CL2798f3IYSERFRVIjqEaNevXqhV69eqo//+OOP0bJlS4wfPx4AkJeXhx9++AEbN25Efn5+kFpJRERE0SKqR4x89eOPP6JHjx4O1/Xs2ROHDx8OU4uIiIgokkT1iJGvTCYT0tPTHa5LT09HbW0tzpw5g/j4eKf7NDQ0oKGhwX5ZEAQkJSXZ/x3pbG2MhrZqTa99Z7/11W9Av33Xa7+B6O67LMt+tzsU/dZVYOSP9evXY+3atfbLHTt2xIIFC5CdnR3GVvkuJycn3E0IG732nf3WH732Xa/9BqKn71JNNSqXL0Ht7p2AxQzZYERSnz8jffx0iMkpPj9eMPutq8AoIyMDlZWVDtdVVlYiKSnJ5WgRABQUFGDYsGH2y7YotaysDGazOXiN1YggCMjJyUFpaanu9lDSa9/Zb331G9Bv3/XabyC6+i7X1cDyxINAyTGgUVtPb3wHp/d+CcPMRRASk1U9ViD9NhqNqgY1dBUYnXvuufjmm28crjt48CC6dOni9j5xcXGIi4tzeVukfxgbk2U5qtqrJb32nf3WH732Xa/9BqKj75Z1bzoFRQAASQJKj8Oy7k1lU2QfBLPfUZ18XVdXh6KiIhQVFQFQluMXFRXh5MmTAIBVq1bhhRdesB9/9dVX48SJE1ixYgV+++03fPTRR/jyyy8xdOjQcDSfiIgo9h3Y4xwU2UiScnsEieoRo59//hlz5861X16+fDkAoH///rjjjjtQUVFhD5IAoGXLlnj44YexbNkybNq0Cc2bN8e0adO4VJ+IiCgIZFkGLF7STiyWgBKytRbVgVG3bt2wZs0at7ffcccdLu+zcOHCYDaLiIiIYM3LNXgJNQyGiAmKgCifSiMiotCK9HwWikA9ewOim3BDFJXbI0hUjxgREVHwyXU1kNavUHJBLGZlBKBnb4gFY1WvJqLwC9d0lVgwFtIPB4HS40pOkf0GEcjJg1gwNuRt8oSBERERuSXX1UCaP8N5VdGOTZB+OAjxkYUMjiJYJAS1QmIyxEcWNmqHBTAYIja4ZmBERERuSetXeFxqLa1f4fNSawqNSApqhcRk5XMyempEJVq7whwjIiJyL8qWWtNZaoLacIjkoAhgYERERG74stSaIhCDWr8wMCIiIpeicak1KRjU+o+BERERuRehS60j6YQeSW2xYVDrPyZfExGRW5G01LrpCivJYETFZQMhXzMCSEgKWTtctSUiSxj07A3s2OT4vtkEIaiN9KRqtRgYEREFSSycKFwutRZFIL9PSIMAdyusTm98B9j7ZUhXWEXSai9PQhHURkWA6CMGRkREGorFE4WQmKycZIGz/TqwBxIQsn5FUtmASGqLJ8GuHxQtAaKvGBgREWkkVk8UEdEvNSusQhWMRFJbvAhm/aBgBYjhHmll8jURkUYitW5MoMLdr0haYRVJbfGV5sGGhuUA5LoaWFa/BMvDkyHNmAjLw5NhWf0S5LoajRqrHgMjIiKthLluTNBOxmHuVyStsIqktoSTlgGifURy+0bgjxOAqVz5/x2bIM2fEfLgiIEREZEGwjWSINfVwLJqKYonDoflQe1/aUfMCEkklQ2IpLaEiZYBYrhHJJtiYEREpAFVJ4q6GqC+VrPntP3SlrdvhOVECWD6Q/Nf2pEyQiIWjAVy8pwDkhCXDZDragCzGYCL/kbobvFBo1WAGGEVuhkYERFpxdOJAgDqajWdGgjZL20fToDBGjmyrbDCgCFA85ZARnOgeUukDrsJhpmLQpLUbp/y2fURIFkcbzQYgCuujtoEe39oEaxGzIhkI1yVRkSkEXvdmOKj7g/Scjl3iFZHeauHI1w3EpbVLwW9REHTFVaiKCKzdWvUlZQE/cQpy7L7QFQ5ADAYdRMUAdqUA4iUEcnGGBgREWnEfqJ4YKL7KTONAhZffml7OqmoWRrt6QQoXDcS8uLZIV/KH4oTpVNNqipT1CzTDxVNygGEuEK3NwyMiIi0lJAEJCV5ziVSEbB4E8gvbX+KULo7AVpWvxQVxQ595bZ2kycavK/RzN9+R9K2MwBzjIiINKXF1IDqaSE/kl+1WBrt0PYIS5zVisdpM3cCmPKJxLpHoeIufwwDhoQlZ4sjRkREWvNjasCfURx/fmlrWa1Yq+m8iOQp4HPFjymfWNw+xl/BrNDtKwZGREQa8zVg8XfLDdsvbfm9lRAL98JSX+89+VXDhO1ITJzVgqqArzE/pnyCuc1KuAOLQIW77QyMiIg05utqnUBGcYTEZIijp6J169YoLi722K6gjPAEkDjb9Hki5YSuKuATRSAt0+9NWbXeZ4yjT9phYERE5CO1K7lUTw1oNIojCILHXJVgjPD4NTrW+AQuGoDkFKDmtHL/SDmhewv4BgyBOGqK/4GchiN3EbHJbwxhYEREpEIgv8i9JlprNIqjKoFX46XRvoyOuT2Bl5c5PmgEnNDVBHwBJVprOHIXrF3u9YqBERHFLK2mZoL5izzQURxbwFZcuBeWM2e8Tu0EY2m02tEx1Su9IuCErkXxQrePrfXIXYgKfeoFAyMiiilyXQ0s697UNNci6L/I/RzFaRywWVQGbEJiMoT75kL+51ylQrcsA4IA5LaDcM/sgEdoXNZNsgVLvqz0ioATelBXSmk0chfTKwPDhHWMiChmSDXVsDzxYEA1elzSoFaPp2kuf/ec8mevNLmuRqlU/duvynGyrPx/8VHIi2drto+bXFcDy+qXYHl4MqQZE2F56DbgVJVvDxLiPbI80Tqo0GpT3FhdGRhOHDEiophRuXyJdjV6bDlF+3cDFSc9H+zmF7navCS/p238mEIJRT6KX1WjXYnhE7qmU3URtqVGtGNgREQxo3b3Tk1yLXw+sbs4gfual+TrtI3fUyghyEfxq2p0Uzo4oWs1VRdpW2pEO06lEVFM8CVQ8ManE7ubE7g/01w2ak6Qvkyh2Pqs5Wvkka9Vo5vS4Qk9oH3zImxLjWjHESMiigmCIEDWKtdC7Ynd0wk8FCuFPE2hCCKQlAzLw5MdpvEgGjw/Zm2NsgFuAFWXYW7wfmBikvIcotiojpGs2covvYmkLTWiXdQHRlu2bMEHH3wAk8mE9u3bY9KkSejcubPLY3fs2IElS5Y4XBcXF4eVK1eGoqlEFGRJff6M0xvfCSjXQtWoiiAAWdluT+ChWinkdgpFEAHIwPEixzts3wQkJSu3yy5eIwCor4U0f4bfIw2CIAB1dd4PTGkGcf7LEVn5OtrxNQxMVAdGX3zxBZYvX44pU6bg3HPPxcaNGzFv3jw8++yzSE9Pd3mfpKQk/POf/wxxS4koFNLHT8fpvV8GlGuhaooqswUMT74S2GP4kVjcNHBwuVeaKAKVFa4DM1kCaqqBlBSg+rT7J/JnS4rGbVPTLYvF6Sqe0CkSRHVg9OGHH2Lw4MEYOHAgAGDKlCnYt28ftm/fjhtuuMHlfQRBQEZGRugaSUQhIyanwDBzUaM6Rn6u9PG2yie/T+CPobZOjZeVbU33SrOsfgn45ENPjwgkJCqvTV2t60NUTvW5bNsFlwDxCe4f20YUGQhRRIrawMhsNuOXX35xCIBEUUSPHj1w+PBht/erq6vD9OnTIcsyOnbsiNGjR6Nt27Zuj29oaEBDw9n5ckEQkJSUZP93pLO1MRraqjW99l3v/RaTUiDccjtwy+1+T80YRoyDxcMqH8OIcV4fV4vH8LayzTBzkUOwJ4oiLN985b2DFknJ8fEUvFhHdDxW3HbVtk83K1ONXgi9+gb8GfXns974MxHNU3d6/zsPZr+jNjCqqqqCJElOoz8ZGRlud5jOzc3FX//6V7Rv3x41NTV4//338fe//x3PPPMMmjdv7vI+69evx9q1a+2XO3bsiAULFiA7O1uzvoRCTk5OuJsQNnrtO/vtH9vJUvrnm6h8899KCQBzA2CMQ1KfPyN93F8hJqeoeqxAH6PixUU4XXLc7co24em/Q64+DdncgOO1NZABoNbLSA0AnDJBSEiEp/Ryob4WORnpEJKSXeYBeWybF0JqGnKnPeD2NfA1YPH2nks11ahcvgS1u3dCNp+BpbYWAgAhKfnsezJ+uur3NZLw71x7ghwpZUV9VF5ejmnTpuHxxx9Hly5d7NevWLEChw4dwhNPPOH1McxmM+677z7069cPo0aNcnmMuxGjsrIymM1ekisjgCAIyMnJQWlpacRUkA0Vvfad/fa933JdDaR1b0JuNP0m9OwNccQ4IEGbEWJ/RifMD92mVO4OF9EANEsHDCKQnKrkJ0mSMj15+pSyes3TfWXZOck7pRnEuc9DzHD8MerpPXA3BarmPZdqq73XpLKN4jUZgYtk/Dv3vd9Go1HVoEbUjhilpaVBFEWYTCaH600mk+ocIqPRiI4dO6K0tNTtMXFxcYiLi3N5WzR9GGVZjqr2akmvfWe/VR7vZkpI/uRDWHZsBpqlAcY4TZaQq2mXLYBStbIt2CQLUFmu/LvcS/XvppqlA/m9gd2fAvX1ynXxCcBF/YCERIfXwu17sGMTLCo26W36njvkPp2qAs54WSVnHYGzrHsz6nah59+59qK2wKPRaESnTp1QWFhov06SJBQWFjqMIHkiSRKOHj2KzMzMYDWTiELM1y9Lj8UcJYuywsvH/dbUBkD2fzfdV+zhyZDeetl5H61ocsoEfP2ZksckS8p/9bXAZx87vI6yLAdUDLMpe5Bl2y/PW1DU+Lma7HkXKQFHpLRDL6J2xAgAhg0bhn/961/o1KkTOnfujE2bNqG+vh4DBgwAALzwwgvIysrCLbfcAgBYu3Ytzj33XOTk5KC6uhrvv/8+ysrKMHjw4DD2gogCZRshKC7cC8uZM76tRFNbzNHLXmJq9kVzOMaac4RuFwI/FgKlvzklWCMxyZeXIbJIklK00dX1xUeV4KW+TnmtqkyaFcMMaDsSiwVSbTXk91Z63d8u2NTus0fai+rA6LLLLkNVVRXWrFkDk8mEDh06YObMmfaptJMnTzrM6Z8+fRpLly6FyWRCSkoKOnXqhMcffxx5eXlh6gERBarxNIxFxZ5kDvdVW6XZxnqSlkdNcUxIVrEvGgBI8x5QVqk1tnOL++eqqVbftmhTfFT9sb4UwwxkOxJRhPzkQ57fx4SkoK8EU7XPXlL0JYpHi6hNvg63srIyh6TsSCUIAlq3bo2SkhLdDcfqte9667dl9UvKtImrvooiMGCI0wiPw6/x8pPuq0C7IohAeobDL3hp/QqvbYDZ7D4IimaJScCZelWr0fzWvKXLgppNP+uyLEOaMREwlfv+HKII5LYDfvvVfWCVmKT8F+TRGzWfaeMtt+vq79wmkO+3uLg4VcnXUTyBTUQEdXuSNeKUg+JLUAQox5vKHfKOsP8rz23Yvxv4aodvzxMNRBG4bDCQlhHc51BZDFNVxXF3z5GTp0z9eTrZ1tU6vfdqcs585uNnmrTFwIiIwkKLX7n+7BYfUA5KU5IElBxXlq57UnFSfRJwNElKhnDdSP+CETV82MrFrmdv35LWBRHofx2Ehxf4NurlR2K4Gv58pklbUZ1jRETRJZCEUpc5JvW13gsaNt2TLJAcFJcNk7znKcXqSaz6NOSHblNGWwRBu34KgvJfbjsI98xW9dmwcbuxrjtZLWC45XYAgMXXAM/HxHA1grXPHqnHwIiIQkJVQmnTXeo9BFIArCubPBUZdJyGUfVr3NPO8+7ExSt5NrEaAHliXWWmKVlW/is+CnnxbMgePhuuViKKjyxsVMeoUnlvXGk6Tedpfzt3fEkMV0ujffbIP5xKI6KQ8LVWjVMuUJPcDumdN5TH86TJNIzfOSjepDQDWrfVru4QRwMUXj4b8vaNsJwoAUx/KJ+N7RuVzwwAw+ipMDz5CoSn3lCSqpu+Ny6m6cSCscroly/vYxBGb9y2w5+pRfIZAyMiCg0fE0q9BVLY/annEZrEJPsoVOMCijhV6f4+oqhUZ/aFKAL5fZSl3AOGAFnZgQc2ehx5cseXz4Z1lEla8LA9KVoQBKDz+UBcgjIaKIjKyrIrrnYapRQSk8++j81bqvssBGH0xqkdGc2V/x8wxGsVcAocp9KIKOhUTWGVn4Rl9Utn84327/YcSLmbHrFJTAYSktxP4TVlW5nU+Xzgs4/VTac0+gUvJCYrZQFGT1UCsHDucRZrmk5XecsTO14Eaf4MCPfNhbx4tvN7f6Ye+PGQy7v69D4aDEEbvWncDs2n6sgjBkZEFHSqprBkyZ5vhHvn+FeLpjHrFIfF2yq0hEQgNc0xd+mnQ87Ju4IAJKUoow22jVTdJY77k6tC7jWarlK9h1zJccj/nOt1+tbd3miqnic13b7JcDB5Coq4Ok17DIyIKDTUBAu2abLnHlP2KfMkIcF9YcHGCareRheSU52KBwr3zVVOqsVHlfs2WiElZjT3+gteWRl1ACj2kgNF3jVJNladJyZLZ98/V9ysKLO9t6qex2gMy0iOXFcDi79b4JBXDIyIKCRUL6NWu8qpT39lOqTkuPMqsqQUCNeNVPerv7ICUm01ROsWC3JdjfP0i5sVUk0DJKe90CgwguA62bhnb/eVoRvzdrutHlB9rcvVj+h2oftp1TCsDpPrapRFB59tBSQLHH46fPIhpN07IMx5HmJG85C2K9YwMCKikLAllErr3gR2bPa8JF7N9IAsA399GJg/w3mz0upTkGffBcx93vuvfsmibBpqHTnwunrunTcAo9HpJCpcNxLyM7OUQI200aY9hBnznUZB7EG2twDa2+dIFJSgyE0ZCbTKBVrmAieKHYOjMKwOs+fKeepz9WnIs++CvOAVjhwFgHul+Yl7pUU+vfY9GvrtNalVFL3n54gikJQMVLvYwd0mJRW46HLve5RltYBhwWsq22ZQgrrGr60oKsnernaTp8CkZSh1oi64BOKIcWdH6+pqIN0zxvuUqyd5HYAu3T3vS3bF1Urwe2APYLGEbdrK4/5pTQ0a5jZ3KtqFYq80jhgRUeh5K2CX2075Zextys1TUAQotwuA8j8evkRPnzr7Jett6s3ViViSGBQFS5VJ+f/tGyHt3AL0uwri/5ugJD2npgFVFf4/dk219zIShfuUHDQfVocFZRWZLxXb9+/WtBq33jAwIqKQc5tvZJ2iEO6ZreT5qN3WwZPCffAYFAGAueHsiSxY+35R4CwWYOcWSHs/U2oMeapJpYZk8R5slJ+EZdVSh9EqVwLZ7sYb1SvxbCSJS/wDwAKPRBRy3grYiRnNldv7X6cU5AuE2QzrsJF7cfGQJEkpCpjE3IyIV30aqPjD961bmqo0eQ+uZAn4dLNSadtaNNLpEC9V2t3dTy2fK7ZzL7WA8KcREYWFtwJ2QmIyDLfcDsvBrwMrlniqEl5HjBrOQJ4xEfKpKvc5K4KoJOtaAshpocgiS14/GgC81j1Ss91NwDk/amtjCULU7KUWqaNaHDEiorDz+OXYs7f7USNBVLXqzCtJAiorPB+bnAL0HajdfmgUXVxsTWLn43Y3/lC1j5sgAK3bRvReao2355FmTITl4cmwrH4p4FE1LfEvnIgiStOVJsJ1IwGDm68qgwg8slBZfRZs1aeAn39QlnAzONInW92jRqTaau/TcS7u5yun6ef0LAhJKUB8IpCepVw3cGhE76UW7ClHrXAqjYjc0nqo293jeUpclTe/a80TcsFiAb74BOKTr0B6YCJQX6tZW136/TfgimuAP+UD2zcFnuNC0aVJ7o5cVwP5yYe879unUc5P4+lnAMjNzUVJSQkkSYrIKammQjLlqAEGRkTkQOvVNd4ez+0mr7Z90zz9ipRlZWnyqClK0nSwAyNZBgr3Avl9vFYAoDAwGt0H0YFyUenafqL3Jgg5P40DoWgIigCom3JkYEREkcRbkOLrML2ax/P4K7L4GBAf7/lJKk5CemQKUBuiYXhTOfDJh6F5LvJNszSgthao0zhAdlfpWk1tIYMxonN+QkVVyQHrlGO4Az0GRkRkp/VQt+eg5yikByYAZ854OLnI3qcpZDmwVWu+CqTSMgWXBCAxSdvASBSB/tfZ6xjZR0D37wYqTqpokyVic35CSVXJgQgpM8DAiIjO0nqo29sv6vo639pH5IkxCKc0GcA3X0I6+LWyqezhQiXXzIdkakmSIDJh33vF+wgpM8B3ioggy7JPQ91qH9Onar1aSUxSVugEWhiSoovtxNqzt7arBmXp7OqpnVuUauy+rDATBLdBUaTuZRgsbksOhGFTXk84YkSkUy6Tor1NQfgw1O1ztV6tJCZDnP8ypLdeVlcQj6JfkxOry+1mwiW3ncNFqbYa8nsrg7J1SKSzlRw4+70Tvk15PWFgRKSxSEge9MZtUrQn/gx19+wd+kRla/Bm34+t5DiX1ccwMTsHUo+LHU6sLk++1ae0T8pW4+5/OOYlmcqd89SsixGEhxdATEoJfRtDyFvF+0jAwIhIA8HcQDIY3CZFeyIIgNkMua5GdZ/EgrGQdmwOacKykN9H+f/Gv0737wbKy0LWBgqR+ATlxLrvS0gH9jj8zTU++QKANGOi58AoPgFITVMCqSqTNsF0ZguIScnef4RYFyPID0yEpVlaRH93aCkSgyKAOUZEAYuWaq4OvCVFJyQqv7Ibs1iAzz72qU9CYjJw+VUBNNRH7pZG6yyXQzfO1MNyogQw/eH2b04QBHXTuhYzxLnPQ1z0OpDVIvC2iSLQq69vP0LO1EX+d4cOMDAiCpCaJe7h1DTBU1VStCy7zs/wo0/i/5vglGcRLGJ6OpCQBKBJwKpmWTVFP0+fT2/TwBYLpPUrlCAq0ATuxjlPamodNRUh3x16xcCIKFAh2EDSV1JNNSyrlrrcqFHVr2dzg2Z9su/xJBq8HxwgwRhvH573a7qQop+bz6dYMNb7Z3DHJlhWv6Tsz+dq9ZQgui8JIBqA9ExlReSAIRAfWaj8CPG2j5qP/aDgY44RUQAisZqrXFeD3x+7B/KxI26rTaNnb897fUlegglf+5SQFJIVQkJKqjL9kJDk3y91ig2uPp8JSUpl7MoK9/eTJOCTjZB/OAjhvrnKPn2NE7iTkoHjRW7uLAMXXgbDLbcrl9Tuo+ZrPyjoOGJEFIBIrOYqrXsT5mNFHqf2PO5YL6jYBMyfPoXgNTD/+jMsTzyo7HgejhpKFBlcfD4FQQCMcSruLCuJ0P+cC7FgLAxPvgJx4WswPPmK521nJAk4+PXZi2r3UfMkQipBay3S6zdF/YjRli1b8MEHH8BkMqF9+/aYNGkSOnfu7Pb4L7/8Em+//TbKysqQk5ODMWPG4MILLwxhiynmRFg1V/nAHg8jQcrwvAy432xTzZeWtU9qf80KgqDseRbsStfW4E9+b2V4aihR+NlyhFzxpXzE8SJI82fY9wdUOzpsr3Id6IilEDmVoLUQTSt3o3rE6IsvvsDy5ctx4403YsGCBWjfvj3mzZuHykrXc7r/+9//8M9//hODBg3CggULcMkll2DRokU4evRoiFtOsSSSqrkqX95elsZbLIHlLggiYG5wmb/k1J66GlhWvwTLw5NDN60lScD+r7SvgEzRw1pWoilVeUaNlZxNgBYEwft9qyogPzRJ+bx7yy1KSAQee8F9zpJBVEZ2Y0C0rdyN6m+NDz/8EIMHD8bAgQORl5eHKVOmID4+Htu3b3d5/KZNm5Cfn4+//OUvyMvLw6hRo9CpUyds2bIlxC2nWGJPLh4wREm8zGjukIAZyl9DytSely9vUQxsmkkQgF0fe/2Cc/oyDCTXwlemcuDaEUrAyq1B9EWW3ZeVsOUZqX4sJci2rH4JloduUz5XnkiNtg/x9nlPTQN2bHE/cmuxKDlOMSDSV+42FbXfGGazGb/88gt69Ohhv04URfTo0QOHDx92eZ/Dhw87HA8APXv2xI8//hjUtlLssxWUa5yPYBg9NSxDxIKnkRJRBPL7BDbNJFlUfcGFdVWYJAFb1kG4b66SMEv64uLzaJ/29fWzbypXgvvyMu0Kldqm2D2N3MpySFelBTXvJwJX7noStZPwVVVVkCQJGRkZDtdnZGSguLjY5X1MJhPS09MdrktPT4fJZHL7PA0NDWhoaLBfFgQBSUlJ9n9HOlsbo6GtWgtX38P9WhtGjAd+OgTz8SLHvCfr1J5hxDhIAGR3eVGCACSnArXVzvcXBPdTddYvOMG6Kgf7vwrvqjDbl21tdfjaQOFjnVKVYM27s60sS07xrQq61qspG02xS3s/93ysdTTJ1XeKL99v7nIB5boaSOvedHh9hJ69IY4Yp9mPOtXT+1DXl1B8r0dtYBQq69evx9q1a+2XO3bsiAULFiA7OzuMrfJdTk5OuJsQNnrsu/T066h889+o3b1TqUlkjENSnz8jfdxfISanQPrrg/jdTfBkbNsB2f/3L5xau8zh/om9r0Dt59sglbsvlijKFuTk5ECqqUaxycOy6BAwQIb87X8jfgUMBZGpAnLTshS2AD9EnwshMQlCWgYEi9np7/D4mXqP6z+FM/XIzc31+Pjuvt+kmmpULl+i/A1bzJANRuW5x09XvgNqqq1lPYocXh95xyYIPx1Cq6dfh5iszb5txfHx8BQaGeLjvfazqWB+r0dtYJSWlgZRFJ1Ge0wmk9Mokk1GRoZTYnZlZaXb4wGgoKAAw4YNs1+2RallZWUwu5sbjiCCICAnJwelpaW6O0Hote+2ftdfPxbCX8bYfy3WAairrAIqqwAA8oz5ENavgLx/99lfi/l9IBeMRdkZM/CXMQ73rwcgfeE6f89GMplQ/MN3kJ6dE9L90VyxQAAajfaSDrn6DNp+CBjjlKA/yOSUZjA88ZL9O6hOEOx/h7KXemGyJKGkpMTlbZ6+3+S6GlieeNBpKvv0xndweu+XMMxcpIwUNa11BgCSBPPxIhS/+JSy35wGpO4XeVy5K/W42G0/mwrke91oNKoa1IjawMhoNKJTp04oLCxE797KkkZJklBYWIhrr73W5X26dOmCb7/9FkOHDrVfd/DgQZx77rlunycuLg5xca5rX0TTyVaW5ahqr5b02vfG/XbZ/4QkiKOmAKOmOA21u9xGBPC+3FmyQPrHnUDN6YDbHxBBRQ4H6ZtkUVaGBbOEhCgC3S+EedVSp2Xqwg1jgMREoN7DxraJSZAkyeO0kavvN8u6Nz0mO1vWvek170fevxvyqClqe+qRUDAW8g8HgdLjLqf3hRvG+PwdHczv9ahNvgaAYcOGYdu2bdixYweOHz+OV155BfX19RgwYAAA4IUXXsCqVavsxw8ZMgQHDhzABx98gN9++w1r1qzBzz//7DaQItILb1+8NmLBWO+r3sIdFAFnlzr3uDjcLaFIJUna5A8JopKT56pcR6tc4H+FLpepy08+5P1vyWj0L5fGW7Lz/t2qK/ZrIZJW7qoRtSNGAHDZZZehqqoKa9asgclkQocOHTBz5kz71NjJkycdPlRdu3bF3XffjbfeegurV69G69at8eCDD6Jdu9BscEkULdwVYxNuGKMsM/a0rUIksC51FkeOh7RjU7hbQ6GS0VwJNk6f8jwSY9NwJrDnEwSgdZ7r7UN69laSp3d95HbkBrntlGBJw+KwqgpRSlLIK/bbVu5i9NSI3+YkqgMjALj22mvdjvjMmTPH6bpLL70Ul156aZBbRRS97PWHmg7F79ikDIdHQ0Vp61JnYfRUIKctUBrg1gwUBQSIC18DAEgzJqoLjPwlikBGFpDf92zlZhcnfY+FTSUJqD4FJCY7j7IKgt/FYdVuUxTOiv2RHBQBMRAYEZG2PBZjKz7qW+XgcCo/Ccub/wp7EjiFiKCMloiiGNzgXTQA/a6EeNNEl1NAtpO+qpGbygrXgVNyCoT75vo/xaQi6BELxkL64SBQctx51V6IK/ZHmqjOMSKiIPC2x5PHQCOCfgnKErDzI+CE67pmFGNkGaiyTvH27O3/psWiCPS/FrjsSiU5uynJAny+1etWFqpGbiTJ9d9abU1AVa+9bVMkXDdS+QFUVwPExSnXJyQCWdkRm/cTSgyMiMhO1a9cz4+gWVuIfCU/MgWW0uPKSjN/E4dlKD8O/ncQyM5xHWC5qaztxN/9+gKsBu0p2Vm4by7kxbOt1bxPKluXSJLy/4lJEbmpa6hxKo2I7HkRfm2ZoKWsFkB+37NJrFUV2lcepthlNgNz7g4suJcl73uiAfbVXRbA7Y7x9umqpsvUBUFZzeZp9NW6KszffBx3yc6W1S+5niqXZXuwp1X9omjFwIhIp9ytPEO3C4HPPg5OQCIa3J8MRBHI7+vwZS699bL7XAkiVwIa8fSRqdy5rteOTZB+OGifjhIfWdjo76zRirX9uz1vTVJZAemRKQ6Blr8cgis1+5YxMCKiYInUZameVp6hZa5Sf+X34iAEJDKQkgpUV8Nh2s1FwqcgCGd/cRcf1bgdRBpwV1m70ciL25EbwHPQL0v2mkeNA61AqJoqD3CkKhYwx4hIY3JdDSyrX4Ll4cmQZkyE5eHJsKx+yWOiZqh5XHl2ohg4t7tjfkJCkkZPLAE11cpGnlnZXgu92XMlEjV6fqLGRAOQlqlMa2nJTY5Q42DDbYK0q8dqks/kL7VL+fUcFAEcMSLSlKeRGK1+9WnC23D6d/tgePIV+69c1Ncq/WqaK+EPWVZWw/QdAHHUFKcvYadfqwlJSmBUF8S6NKRTMnBxP+Xv4Y8T2j60l5EXp2m28pOOy+Yb03KKK4z1i6IFAyMiDXkciYmQxEZfh9MFQQBc5UqIIlBbA9RW+94I6xe9YH0tXOY7dbtQOfa7fUClyffnIPLGFnD07K2s0vJlJZsgeD5exciLbZpNHjUF0oMTPFeU12iKy21COOsX2TEwItJSiBIbA1qt4udwetNcCdTXQnriAf8CI+DsXky20aimAeXOLf49LsU2bwGJ7XOrNsixWJRNTL/aoX6fP1FUtvMoPqrJyIsgCIDR9Wbldk2TsZNSVD++w3N5SAjnUn0FAyPSPa0SDYOd2OhuFZlfX2YBDqcLggDL+hVA6W++PW9j1uDL4m6UjcgVWVY++27/1gSgTTtlNFNNyQeDAWJSCiyJSeoCI1uRxHtmK/WAtBp58fQ3CTglYwszF/n2+I1E075l4cDAiHRJ0yDDKpiJjVrlLtm+BDUZTvdWIduTxsFXII8TLp7KDlDwucvFsd1WWwPDk68oJR9W/Nvz6GO3C5UfNd7eT0EAMlsA+X3s3xOyhiMvbv8mm2qcjP232T49hysMipwxMCLdCWqCdJASGwPJXXIXBLrbEVzNl3pAFbIbBV+BV9oOEwZF4eUtkPZlZFZQ+aMmK1tZkND4rhqOvPiajC3v3+33c5FnDIxId4KZIB20xEY/c5c8BYGyLQj040vdrwrZgqhUtm4afIWz0jZFJ18Sn7/b5/mxCq23azC9HCh/krFJe6xjRPqjJsjwk9MeRelZHuv0qOFL7lJTaoJAwM8vdV/2gRJFYOAQGJ58xV70zs62+oxIDVvis6fPnvUz5VPe3w1jPG68GqzVWq7+blUlY7PeUNDwpxrpSsgrv2rxEIHkLgVxlZxw3UjIu3cA1SoSVlvlujyxyHU1wI+Ffj2/g/gEJQD9/TfnkbpWuUD5H0A96yBFjaQU96sdW+Yqic9Pz1JGZl35sRByXY0SgHv726mrUVZ7Wcxng66aauVzFKTVWqpyHL2MYAn5fTRrDzniiBHpSrArv9qnrrZvVFaQmMrPriSZP8P/6teeRmfcDPMHMtLk9DhNr6urUVbkqAmKAKDjeS5PLFKgK9tszA0wPPoUUq4pUIpBCqLyX1yCUsW7T3//djmn0EtIVAqAutO1O8SM5kCX7u6P+b34bKVobyObdbVn/1bLTypL8BOTIDz2gusRzgCp/Y5wWxmb9YaCzqcRo0OHDvn1JOeff75f9yMKiiBWfg1W/pI/uUuBBIHeftHa+6nW3s+BiXc7X6/VijRjHGRZRv133wD1dWcfs75W2RA3qPu/kabOnPH8mbDlBHnKHWo0Gqp6tVfj+5Yeh/zeyqBspqr2O4L1hsLHp8Bo7ty5fj3J22+/7df9iIIhqJVfgzR15feXpB9BoJpVez4HNGfqnaYnNV2RltoM8voVMB8rcr//2+VXA3/K977iB1C2IUlOBir+0KZ9pB2LBZIkqRoNlSQJoru/ndOn3E+vBnOXeR++I1hvKDx8Coxmz3asmdDQ0IAVK1bgzJkzGDx4MHJzcwEAxcXF2LZtGxISEjB2LIf7KLIE65dYsPOX/PmS9CcIVJWw7WtAI0uQ3nrZ4fVVNaKVmAScqff8S18QgPy+kA/s8bzXVKP93yyrlgKfbnb/uNmtgE7nsfp2OHgKWAGlIKMowuLts1NVAfmhScpxtr9tW9V2ANKMiZ7zzoKwy3wg3xEMikLHp8Co6ZTYsmXLYDQaMW/ePMTHxzvcds0112DOnDnYv38/LrjggsBbSqShYPwSC+XO1Wofw68gcP9u779o/Vli76pOlLcRrT79gR8Pea6MnZwKXDsC2Pel5+dvdMIRR4yD9L9v3T/ub0eBYh+mCsl33pbcu9J4lNNbpWhJUvJ3ANefvTDsMs/d7aNDQNmIn332Gf785z87BUUAkJCQgCuuuAK7du0K5CmIgk7TLyE/kqSDzRYEGp58BeLC11wmlMp1NbCsfgmWhycDFSc9P6DFAlxwie/JzE1KBAAqEkxvnKBM3Q0cCmQ2d/24NaeBZ+d4b0+jE469rEKb9q6PlSUWcfTG+h4hIdG/+yenKHWt1N6/ySin28+OKy4+e2H7W43A7whyFFBgVFdXh4oK9wWoTCYT6uvrA3kKoqgS6StJ3CZaN14l4+1XvMEAccQ49SelxprUiXKq+5TR3Knuk310r9elrh9TlpWpwuRUn044QmKysp8WqZNkDWQavUfCzEVAkp9JwLU1QH5fIKWZ5+ME0WUtMCExGYaZi5A67Kaznx1Pn8cmn71w/a1G+ncEBVjHqEePHti8eTPOOecc9OnjWFPhq6++wqZNm9CzZ8+AGkgUTaJxJYnbnCJXrAGGy36KgnLyLD7mOU+kSQ5F42lNSZIguju5eSq8KUlAzSkY8zrAfLxIVT6VqgRetQwGwBgfm7WSBAG4dDCEUbdBTEpxmnr2muvjji1Q8TYyl5YBcf7LLoN6ITEZmbc/gLq/jIHFYoH80KSz02euNPrshetvNRq/I/QmoMBo8uTJmDt3Lp555hlkZmYiJycHAPD777+jvLwcOTk5mDRpkiYNJYoWUbeSRO0KsyYBhrt+Wh6erIw8udMkh6JpaQCLi2J3qpJWJRktn3oNJUufVvaRcnHCcSpDUGXy/JgGg/LaNM1jMRiA1HTAqLQV198CzL4ztgIjgwHoO1DJifluH+R/3OHyvfGa6+OJxaJsyOuJ0ahuoYGahOwmn71w/a1G3XeEzgQUGGVlZWHRokX4z3/+g2+++QYnTyq5CXl5eRg+fDiuvPJKl/lHRHoR6V94qgIOF7uKOx/SqJ8+lAhQu6Gv2qRVQ0qqfa8pp/IA7p7LHVEELr9KeV4Xv+xlWVZq3RzYA+z7wnuQFelEEUjLVPp4wSUQhtyoFPH08t74XCeoscoKICHBc5t8ybkJoEZZuP5WI/07Qo8C3hIkPj4eQ4YMwZAhQ7RoDxGFkL+7inviS4kAnwpi+rhFQtMTjk9ThgDQMhfijROUQLDJL3u5rgbykw/59niRLi0TwoJX7VOZltUvBVyIEOYG4LOt7gMmWVIqT7viR85NUGuUkW5osldaQ0MDjhw5gsrKSnTt2hVpaWlaPCwRhYLGlcB9yqHwodhdwCc9X4tSdu3u0NbGgZbPQVY0sNYHstOgEKFcVwPpp+/VjyYlJAGJidbq5QCqT0Gac7fq/Bvm75AWAg6MNm3ahHfeeQc1NcrqjlmzZqF79+6oqqrCfffdhzFjxmDQoEEBN5SIgiMYv7LV5FD4WuwukJOeX1W2d38K2TZi1JRWW5lEiqZTnBoVInR6z7xVHE9JVZbvV5mU19eWs+WqDpEbzN+hQAW0XH/79u1YtmwZ8vPz8de//tXhtrS0NHTr1g1ffPFFQA0kouBSs2Q+oMd3c2Lyp9idmppMfj9XU3W1kJ540GnjX023MokELgJgLQsR2t4zcf7LQFq654OrT3mvuu4DBkXkj4BGjD788ENcfPHFuOeee3Dq1Cmn2zt16oTNmzcH8hREFAJh+5UdymRZf1ZP/f6b08a/giAoCenRrHGitbsRNw2nWO2rAU9Vej6w4Yz724K5fxlRIwGNGJWWlqJXr15ub09NTcXp06cDeQoiCrFQ/soOZbE7nyol2zQpCmh3xsMJPBpYE609jbhp9d44FBD1uOedCBjjPD+YdfqOKJgCGjFKTk5GVVWV29uPHz+OjIyMQJ6CiGJYKJNlnZ7LbFZGMLwVGHSVS1NbrVm7wqJporULWr03qhLVbduL1NUA5R52S+A+YhQCAQVGvXr1wrZt23DNNdc43Xbs2DFs27YNAwcODOQp3Dp9+jRee+017N27F4IgoE+fPpg4cSISE93vuzNnzhwcOnTI4borr7wSU6dyaJYoXNyuaArCyEDT50J9LaQHvOyy3uRkLElSYInXgggYRCXQCMfohw/TYJpMsXpLVBdFJZ+tYKwSRGm4QpLIHwEFRqNGjcKjjz6K+++/HxdddBEAYMeOHfjkk0+we/duZGZm4sYbb9SkoU0999xzqKiowN///ndYLBYsWbIES5cuxT333OPxfoMHD8bNN99sv8wClEQRpL4WlsaVqV1VWtaIIAhAYjLQb7BPJ2NRFGHxZ2d4AMjKBvL7QLhuJOTN754duaoyeV6tpZVAVhr6ERSpSlRPy4Q4agoEQWAdIooIAVe+fvLJJ7F69Wr76rNdu3YhMTER/fr1w5gxY4JS0+j48ePYv38/5s+fj3POOQcAMGnSJMyfPx/jxo1DVlaW2/smJCRweo/IT8FMzFZbBVtrfp2Mc9sBx4t8e6K0DIjWQpmCIChJxNaRGOmRKZ63UQlEQpKy0WsY6vn4urqNdYgoEvgdGDU0NODAgQPIzs7GtGnTMG3aNFRVVUGSJKSlpXmdvw7E4cOHkZKSYg+KAGVDW0EQ8NNPP6F3b/fDrbt27cKuXbuQkZGBiy66CCNHjkSCh5L0DQ0NaGhosF8WBAFJSUn2f0c6+xdOFLRVa3rtu9b9lutqIK17E3LjE9UFl8AwcrymJypvVbDl91ZC9LAiSRAEvwI3ISkFwsxFkNavcNhjTfCwBYp47xxID09WRnvUOlOvBEC2x+/ZG+KIcRATkyH37A3Z3/3G3LEGdoaZi4CEpPBteeGpb9aK5Q4lGZJSIN5yO3DL7V7fT73+jQP67Xso+u13YGQ0GvHMM89gwoQJaN++PQCErOK1yWRyei6DwYDU1FSYTCa397v88svRokULZGVl4ddff8XKlStRXFyMBx54wO191q9fj7Vr19ovd+zYEQsWLEB2dnbA/Qgl2wa/eqTXvmvRb6mmGr8/dg/kY0WOUz3bN8Ky8yOkXH09MibdDTE5JeDnKi7cC4uHSsti4V60bt3aZRtNy5egbvdOlFin35L6/Bnp46f71q6/zQagclSsdWuYX/sAZbPvhvnXX6zBnOx5eq2u1mH7C3nHJgg/HUKrp18H/vogfv/pEMzHi1xsWGuEmJYOqbZWeY76Os/PI4gQs1shuW9/pI/7qybvTSAkd30TRRjbdkCraQ8E3Ea9/o0D+u17MPvtd2AkCAJat27tsn6Rv1auXIkNGzZ4PGbx4sV+P/6VV15p/3e7du2QmZmJxx57DKWlpW5f5IKCAgwbNsx+2faFWVZWBrMvvxbDRBAE5OTkoLS0VHfLXPXady37bVm1FPKxI65PxBYzqje/i+oDX8Mwc1FAo0eyLMPiZQm8pb4excXFDttNWNa8bt2Ly3Fl2emN7+D03i8DbpdXjz4DI5SEbOFMHSxPPKh++wtJgvl4EYpffErZ+HbGfAhNRq3Q/SIAMqTCfUBiknId4H5/MQDIagHxiZdQB6CusgqodL9yOFRc9U3I7wO5YCx+D6CNev0bB/Tb90D6bTQaVQ1qBJRjVFBQgGXLluHSSy9Fbm5uIA8FABg+fDgGDBjg8ZhWrVohIyPDqUyAxWLB6dOnfcof6ty5MwB4DIzi4uIQF+e6tkY0fRhlWY6q9mpJr33Xot+ymq0vSo/Dsu5NhyKIfrGd9L3cLsvy2Xyk4qOuj7VOvzVtV7BypARBABKSXOfHnD7lftWbJEHevxvyqCnK/UdNAUZNObtizlXOlSfWZPGI+7w36Vvj90CLtur1bxzQb9+D2e+AAqPDhw+jWbNmuP/++3H++ecjOzvbaZWXIAiYOHGiqsdLS0tTNR3XpUsXVFdX45dffkGnTp0AAIWFhZBl2R7sqFFUVAQAyMzMVH0fIr1QvfWFVhWJfai0bM9HUtEu2bYMPIgr3Rrv5+ZQDgCANMNLOQAXdZIEQVBW5/kaFEXByi295cRQ9AkoMProo4/s/y4sLHR7nNrASK28vDzk5+dj6dKlmDJlCsxmM1577TVcdtll9hVp5eXleOyxx3DnnXeic+fOKC0txWeffYYLL7wQqampOHr0KJYtW4Y//elP9hwpIjrLp/3F3Gwo6gufVoep3cTV3ADJNr2l8Uo3+zYXbgIu+2vhx55jcl0N8MU2z31MSAJSm9lHplL7DULt1QXK9UTkt4ACo7ffflurdvjs7rvvxquvvorHHnvMXuBx0qRJ9tvNZjOKi4tRX69UUTUajfj222+xadMm1NfXo3nz5ujTpw9GjBgRri4QRT61+4tpUJFY7VJtnzZxra87u1N7Y402JfV1CtDjNJergMvHPcfkuholmPOURwQAScnKxqxQaitltm6NupISXU6rEGkpoMDI5ujRo/jmm29QVlYGAGjZsiXy8/PRrl07LR7epdTUVI/FHFu2bIk1a9bYL7do0QJz584NWnuIYpF9FMddLg+gaUViNZWWfRrJkuF+1MWHKUCn0aEmK8wcHrNJwOVrnSRp/QrlWG+4PQZRUAQUGDU0NOCll17Czp07AZydO5ZlGStXrsQVV1yBadOmwWjUJP4i0kRId4+PcvZRnHfecLn6K5h5LR7fowsuUTYl9UQ0AAkJPuf3NOW28KQ7TQIun4sWqpkmbJRkzc8ykbYCilhWrlyJnTt34uqrr8Z1112HVq1aQRAElJaWYtOmTdi6dStSU1MxYcIEjZpL5B9v+SCxSKspFSExGYZx0yH/vwlBqUjsz8ldHDEO0s4tSjvcychU9iXzRMWoi6pNUJtqEnCp3XNMlmXA3ODyNgdJycD+ryDt+wIwGCH07A3prw+qbx8RuRVQYLRr1y5cccUVuO222xyuz83NxeTJk1FbW4tdu3YxMKKwCtdWE+FgCwCLC/cqdYE03E5Bkw1Fm7TT30BVSEwG+l0F7Nzi+gBRBPL7Kv8OdFNStYnejXkIuDy+bvW1wCkVNX2qTyv/WcmffIjir3dCmP0chHT3WyIRkXcB7dthNpvRpUsXt7d37doVFk+/6IhCQFr3psetJqT1K8LTMI3ZAkB5+0ZYTpQApj+U/bd2bFKur6vR7LkCDormz1Cmwv44AZjK/Wqn+P8mKHuWNd1+qNH0nlgwFsjJ83iMx7b6kujd+LGtAZevo3bS+hXO05UqyaeqIP3jTk3fZyI9Cigw6tmzJ/bv3+/29v379+OCCy4I5CmIAuaxSKEtHyQGeNtrLFICQK3aacvdwYAhQPOWQEZzGFrlQhg41D4K6OoYNG8JDBiiaqTQp0RvQAmKWuYCZjMsD0+GNGMiLA9PhmX1S+oClkA/izWnI+Z9JopWAU2ljRo1CosXL8ZTTz2Fa665xl49uqSkBB999BHKyspw33334fTp0w73S01NDeRpKYqFOllU+cXv5Re4BjV4IoKaADDQIoxa0LCdjaf3AGUav6TJkvWApwC9lSxovHt9twuBHwuBXR/5PG2ranRKELxP6+3fHRnvM1GUCigwuu+++wAoy/W//vprj8c0Fs76RxR64Ux8Vn7xe99qItqDIlUn1QgIAIPZTjXH+9N3+3L7kuOOG+kCQEozCHOUvB5BEGBZ/RJQ+ptfdZNUjU6pCYwkKezvM1E0CygwGjlyJP/4yKNISHwWevaGHGgCboRTdVKNgAAwWtrZmJCYDOG+uZBn3wXUOI5+o+Y05MWzITyyEEhMDnw0zFsxyNx2wPEizw2uqoD01ssxveKSKJgCCoxuuukmrdpBMUpNPknAm496IY4YB4sPBfailo8VlsMmWtrZiLz5XaC22sUNsv1zLI6aEvBomLdikMI9syHPucthRZoTSYrJFZdEoRJQ8jWRVxGQ+BxoAm60CHQFVqhESzsdqPgcazEa5u2zKmY0hzDneSDZS55mhCXcE0UTlqSmoImkvBcta/BEKttJVX5vJcTCvbDU1yv5VRdcAnHEuIgJAH2uBB1mvnyOtRgN8/ZZFTOaQ17wivL6eUoKj6SEe6IowsCIgiZS80m8PV80B05CYjLE0VPRKj0Nv/17kXJi/OZLSAe/jqjAI5oCVV8+x77ui+aJp9dFSEyGOGqKUvnaVO7+QSIg4Z4o2jAwouCKknySWNoyRK6rwe+P3QMcOxIVlb6j4qSt8nMc6GiYL5/DSP3hQRTtGBhRUGn5CzpYImHlnJakdW9CPlYU1oT3WOPL59jf0TC/PodR8sODKJow+ZqCKhoSn6OlYrRaSqVvL3kn5BN/P8eNgyJv24P48zmMykR2ogjHESMKuojPJ4mWitEq6KrSd4j58zn2aYrWj8+h24T7KJ0GJooEDIwopCLtZBxJK+e0oJdK3+GmOihSOTUWyOfQlnDfunVrFBcX+9wXInLEqTTStVhMYBV69naeWrFh3knI+DI1ptXnMJo+p0SRioERUYwFEuKIcTDmdWDeSbj5Wtw0xj6HRNGKgRHpXqwlsAqJyWj19OsQBg6N2IR3d7wlKEcLn4pCWsXa55AoWjHHiHQv2ioxqyEmp8AweirkUVMiPj8qkmpIafVa+TM1FoufQ6JoxMCICFGwci4AkdyXSKghFbTAzJ8aQwlJMfs5JIoWDIyImuDJKHTUJCgHsxhlMAMztUUhPQVm4CiRAwaLFAoMjIia4JdvCIW5hlQwAzM1U2ORMGIW6TyO6CWlhLt5FIMYGBEhsvJc9CIiakgFOTDzNkXra2Cmt6DdW+AozFwUvsZRzGJgRLrHX+3hEe4aUsEKzNwd7/IxVARmcsFY3QbtqmpB/W12eBpHMYuBEeleuPNcXNHNyICfm6Bq8fpoGZj5M+KoKjAzN0B64kElT0mPQbuXwFHevzu07SFdYGBEFCF7pelxOs+XXeuD8vposDu9vyOOqgKz+jqgyhRRQXuo+FMLikgLLPBIuhYpX772k+v2jcAfJwBTufL/OzZBmj8Dcl1NUJ8/XNTuWh+s10eLooq+bP3hxFu1axm+Vc+OIeGeaiX9YmBEuhYpX74BnVyjnC1B2fDkKxAXvgbDk6/AMHqqwyhLsF4ftYGZR75u/dGIt8AMiYmenzvWR0y8BI5Cfp/Qtod0gYERUSTsURXAyTVSaHGCdhuABvH1UROYuRPoiKO3wAzGOM+PHeMjJtwmhcKBOUake8J1IyF/tQOoOd3kBiEkX74RsWzdT6HIiwrldKevr68WI44el/RrkAMVzbhNCoUDAyPSNbmuBvLi2UBttfONySkQ7psb9C/fSJnO81WoyhxE/OujYfDStA++JKfHqljerociU9QGRuvWrcO+fftQVFQEo9GIN954w+t9ZFnGmjVrsG3bNlRXV+O8887D5MmT0bp16+A3mCKS29wVAKitgbz53ZCsSIvGkYGQljmI4NcnmMELR0wcMSiiUIjaHCOz2Yy+ffvi6quvVn2fDRs2YPPmzZgyZQqeeOIJJCQkYN68eThz5kwQW0oRLUJye6IylyKEr10kvz6aJHB7eXx/c6CIyHdRO2J00003AQB27Nih6nhZlrFp0yaMGDECl1xyCQDgzjvvxJQpU/D111+jX79+wWoqRahIyu2JtpGBUL92kf76hGq6hyMmRMEXtYGRr06cOAGTyYQLLrjAfl1ycjI6d+6Mw4cPuw2MGhoa0NDQYL8sCAKSkpLs/450tjZGQ1u15q3vgiBAUpG7IrpbsaYxISkF4i23A7fcHtDJNRTveTheO2+vT6R81sPx/JHS91DTa78B/fY9FP3WTWBkMpkAAOnp6Q7Xp6en229zZf369Vi7dq39cseOHbFgwQJkZ2cHo5lBk5OTE+4mhI2nvldcNhCnN77jNncltd8gZEZpDpra99zfICxSXzt+1vVHr/0G9Nv3YPY7ogKjlStXYsOGDR6PWbx4Mdq0aROiFgEFBQUYNmyY/bLtBFJWVgaz2ctUQgQQBAE5OTkoLS2N7UJwLqjpu3zNCGDvl24TZ2uvLkBdSUmIWqwNVf2uq4G07k3IjaalhJ69IY4Yp3paKtJeO37W9dd3vfYb0G/fA+m30WhUNagRUYHR8OHDMWDAAI/HtGrVyq/HzsjIAABUVlYiMzPTfn1lZSU6dOjg9n5xcXGIi3NdZE3rD2MwcxNkWdbVH09jHvuekOQxdwUJSVH7urnrt7tl9vKOTbD4ssw+Ql87ftb113e99hvQb9+D2e+ICozS0tKQlpYWlMdu2bIlMjIy8O2339oDoZqaGvz0008+rWzTmh43Do00equTouUye729dkQU+6J2uf7JkydRVFSEkydPQpIkFBUVoaioCHV1dfZj7r33XuzZoywZFgQBQ4YMwbp16/Df//4XR48exQsvvIDMzEz7KrVQ0+vGoZFMFyf2IC2z18VrR0QxL6JGjHzx9ttv49NPP7VfnjFjBgBg9uzZ6NatGwCguLgYNTVng4vrr78e9fX1WLp0KWpqanDeeedh5syZiI+PD23jrUJaII8IkVWigIgoEkVtYHTHHXfgjjvu8HjMmjVrHC4LgoCbb74ZN998czCbpp6aX+4MjDTBE70i4rfXICIKs6gNjKIdf7kHn1xXg4oXF8H8xXbmbzUWwdtrEBGFGwOjMOEv9+Cy5W+dLjkOyI0CAI03OI1G3JiUiMi9qE2+jgk9ezvv/WTDX+4BOZu/1WRUpFH+ll4Fe28vIqJoxhGjMOIv9yBi/pZHXGZPROQaA6MwivSNMaMV87d8w9eAiOgsBkZhxl/u2mP+FhER+Ys5RhGEJ2oNMX+LiIj8wMCIYpJYMBbIyXMOjpi/RUREHnAqjWKSkJgMw8xFSPp4PU5//gnzt4iISBUGRhSzhMRkZN7+AOr+MgaSJHGqkoiIvOJUGukCgyIiIlKDgRERERGRFQMjItIV2V3hTyIiMMeIiHRArqtpVEiVGwoTkXsMjIgoptk2FFb2zms0WsQNhYnIBU6lEVFMO7uhcJMpNG4oTEQuMDAiotimZkNhIiIrBkZEFLN82VCYiAhgYEREMYwbChORrxgYEVFs44bCROQDBkZEFNO4oTAR+YLL9YkopgmJyRAfWdiojhE3FCYi9xgYEVHMExKTYRg9FRg9FbIsM6eIiNziVBoR6QqDIiLyhIERERERkRUDIyIiIiIrBkZEREREVgyMiIiIiKwYGBERERFZMTAiIiIismJgRERERGTFwIiIiIjIKmorX69btw779u1DUVERjEYj3njjDa/3+de//oVPP/3U4bqePXvi0UcfDVIriYiIKJpEbWBkNpvRt29fdOnSBZ988onq++Xn52P69On2y0Zj1L4EREREpLGojQpuuukmAMCOHTt8up/RaERGRob2DSIiIqKoF7WBkb8OHTqEyZMnIyUlBd27d8eoUaPQrFmzcDeLiIiIIoCuAqP8/Hz06dMHLVu2RGlpKVavXo0nnngC8+bNgyi6zkNvaGhAQ0OD/bIgCEhKSrL/O9LZ2hgNbdWaXvvOfuur34B++67XfgP67Xso+h1RgdHKlSuxYcMGj8csXrwYbdq08evx+/XrZ/93u3bt0L59e9x111347rvv0KNHD5f3Wb9+PdauXWu/3LFjRyxYsADZ2dl+tSFccnJywt2EsNFr39lv/dFr3/Xab0C/fQ9mvyMqMBo+fDgGDBjg8ZhWrVpp9nytWrVCs2bNUFpa6jYwKigowLBhw+yXbVFqWVkZzGazZm0JFkEQkJOTg9LSUsiyHO7mhJRe+85+66vfgH77rtd+A/rteyD9NhqNqgY1IiowSktLQ1paWsie748//sDp06eRmZnp9pi4uDjExcW5vC2aPoyyLEdVe7Wk176z3/qj177rtd+AfvsezH5HbYHHkydPoqioCCdPnoQkSSgqKkJRURHq6ursx9x7773Ys2cPAKCurg5vvvkmDh8+jBMnTuDbb7/FwoULkZOTg549e4arG0RERBRBImrEyBdvv/22Q7HGGTNmAABmz56Nbt26AQCKi4tRU1MDABBFEUePHsWnn36K6upqZGVl4YILLsDNN9/sdkSIiIiI9CVqA6M77rgDd9xxh8dj1qxZY/93fHw8K1wTERGRR1E7lUZERESkNQZGRERERFYMjIiIiIisGBgRERERWTEwIiIiIrJiYERERERkxcCIiIiIyIqBEREREZEVAyMiIiIiKwZGRERERFYMjIiIiIisGBgRERERWTEwIiIiIrJiYERERERkxcCIiIiIyIqBEREREZEVAyMiIiIiKwZGRERERFYMjIiIiIisGBgRERERWTEwIiIiIrJiYERERERkxcCIiIiIyIqBEREREZEVAyMiIiIiKwZGRERERFYMjIiIiIisGBgRERERWTEwIiIiIrJiYERERERkxcCIiIiIyIqBEREREZEVAyMiIiIiK2O4G+CPEydO4N1330VhYSFMJhOysrJwxRVXYMSIETAa3XfpzJkzWL58Ob744gs0NDSgZ8+emDx5MjIyMkLXeCIiIopYURkYFRcXQ5ZlTJ06FTk5OTh27BiWLl2Kuro6jB8/3u39li1bhn379uFvf/sbkpOT8eqrr+Lpp5/G//3f/4Ww9URERBSpojIwys/PR35+vv1yq1atUFxcjI8//thtYFRTU4NPPvkE99xzD7p37w4AmD59Ou677z4cPnwYXbp0CUXTiYiIKIJFZWDkSk1NDVJTU93e/ssvv8BisaBHjx7269q0aYMWLVp4DIwaGhrQ0NBgvywIApKSkuz/jnS2NkZDW7Wm176z3/rqN6Dfvuu134B++x6KfsdEYFRaWorNmzdj3Lhxbo8xmUwwGo1ISUlxuD49PR0mk8nt/davX4+1a9faL3fs2BELFixAdnZ2wO0OpZycnHA3IWz02nf2W3/02ne99hvQb9+D2e+ICoxWrlyJDRs2eDxm8eLFaNOmjf1yeXk55s2bh0svvRRXXnml5m0qKCjAsGHD7JdtUWpZWRnMZrPmz6c1QRCQk5OD0tJSyLIc7uaElF77zn7rq9+Afvuu134D+u17IP02Go2qBjUiKjAaPnw4BgwY4PGYVq1a2f9dXl6OuXPnomvXrpg6darH+2VkZMBsNqO6utph1KiystLjqrS4uDjExcW5vC2aPoyyLEdVe7Wk176z3/qj177rtd+AfvsezH5HVGCUlpaGtLQ0VcfagqKOHTti+vTpEEXPJZk6deoEg8GAb7/9Fn379gWgrG47efIkE6+JiIgIQJQWeCwvL8ecOXPQokULjB8/HlVVVTCZTA65QuXl5bj33nvx008/AQCSk5MxaNAgLF++HIWFhfjll1+wZMkSdOnShYERERERAYiwESO1Dh48iNLSUpSWlmLatGkOt61ZswYAYDabUVxcjPr6evttt956KwRBwNNPPw2z2Wwv8EhEREQERGlgNGDAAK+5SC1btrQHSTbx8fGYPHkygyEiIiJyKSqn0oiIiIiCgYERERERkRUDIyIiIiIrBkZEREREVgyMiIiIiKwYGBERERFZMTAiIiIismJgRERERGTFwIiIiIjIioERERERkRUDIyIiIiIrBkZEREREVgyMiIiIiKwYGBERERFZMTAiIiIismJgRERERGTFwIiIiIjIioERERERkRUDIyIiIiIrBkZEREREVgyMYoQsy+FuAhERUdQzhrsB5D+5rgbS+hXAgT2AxQwYjEDP3hALxkJITA5384iIiKIOA6MoJdfVQJo/Ayg5BjQeLdqxCdIPByE+spDBERERkY84lRalpPUrnIMiAJAkoPS4cjsRERH5hIFRtDqwxzkospEk5XYiIiLyCQOjKCTLspJT5InFwoRsIiIiHzEwikKCICiJ1p4YDMpxREREpBoDo2jVszcgunn7RFG5nYiIiHzCwChKiQVjgZw85+BIFIGcPOV2IiIi8gmX60cpITEZ4iMLG9UxsgAGA+sYERERBYCBURQTEpNhGD0VGD0Vsiwzp4iIiChAnEqLEQyKiIiIAheVI0YnTpzAu+++i8LCQphMJmRlZeGKK67AiBEjYDS679KcOXNw6NAhh+uuvPJKTJ06NdhNJiIioigQlYFRcXExZFnG1KlTkZOTg2PHjmHp0qWoq6vD+PHjPd538ODBuPnmm+2X4+Pjg91cIiIiihJRGRjl5+cjPz/ffrlVq1YoLi7Gxx9/7DUwSkhIQEZGRnAbSERERFEpKgMjV2pqapCamur1uF27dmHXrl3IyMjARRddhJEjRyIhISEELSQiIqJIFxOBUWlpKTZv3oxx48Z5PO7yyy9HixYtkJWVhV9//RUrV65EcXExHnjgAbf3aWhoQENDg/2yIAhISkqy/zvS2doYDW3Vml77zn7rq9+Afvuu134D+u17KPotyBG0odbKlSuxYcMGj8csXrwYbdq0sV8uLy/H7Nmz0a1bN0ybNs2n5yssLMRjjz2G5557Djk5OS6PWbNmDdauXWu/3LFjRyxYsMCn5yEiIqLoEFGBUVVVFU6dOuXxmFatWtlXnpWXl2Pu3Lk499xzMX36dIjutshww5asPXPmTIecpcbcjRiVlZXBbPaykWsEEAQBOTk5KC0t1d2msnrtO/utr34D+u27XvsN6LfvgfTbaDQiOzvb+3H+Ni4Y0tLSkJaWpupYW1DUsWNHv4IiACgqKgIAZGZmuj0mLi4OcXFxLm+Lpg+jLMtR1V4t6bXv7Lf+6LXveu03oN++B7PfUVngsby8HHPmzEGLFi0wfvx4VFVVwWQywWQyORxz77334qeffgKg5CGtXbsWv/zyC06cOIH//ve/+Ne//oU//elPaN++fZh6QkRERJEkokaM1Dp48CBKS0tRWlrqlFe0Zs0aAIDZbEZxcTHq6+sBKENo3377LTZt2oT6+no0b94cffr0wYgRI/xqg6dCkpEo2tqrJb32nf3WH732Xa/9BvTbd3/6rfY+EZVjRERERBROUTmVRurV1tbioYceQm1tbbibEnJ67Tv7ra9+A/rtu177Dei376HoNwOjGCfLMo4cOaLb5Dw99p391le/Af32Xa/9BvTb91D0m4ERERERkRUDIyIiIiIrBkYxLi4uDjfeeKPbWkyxTK99Z7/11W9Av33Xa78B/fY9FP3mqjQiIiIiK44YEREREVkxMCIiIiKyYmBEREREZMXAiIiIiMhKn5us6FhxcTFWrFiB//3vfzCbzWjXrh1uvvlmdO/ePdxNC7p9+/Zh7dq1+PXXXxEfH48//elPmDFjRribFRINDQ2YOXMmfv31VyxcuBAdOnQId5OC6sSJE3j33XdRWFgIk8mErKwsXHHFFRgxYkTM7S21ZcsWfPDBBzCZTGjfvj0mTZqEzp07h7tZQbV+/Xrs2bMHv/32G+Lj49GlSxeMHTsWubm54W5aSL333ntYtWoVhgwZggkTJoS7OUFXXl6OFStWYP/+/aivr0dOTg6mT5+Oc845R9Pnia1vCPJqwYIFyMnJwT/+8Q/Ex8dj48aNWLBgAZ5//nlkZGSEu3lB89VXX2Hp0qUYPXo0unfvDkmScPTo0XA3K2RWrFiBrKws/Prrr+FuSkgUFxdDlmVMnToVOTk5OHbsGJYuXYq6ujqMHz8+3M3TzBdffIHly5djypQpOPfcc7Fx40bMmzcPzz77LNLT08PdvKA5dOgQrrnmGpxzzjmwWCxYvXo1Hn/8cTzzzDNITEwMd/NC4qeffsLWrVvRvn37cDclJE6fPo1Zs2ahW7dumDlzJtLS0lBSUoKUlBTNn4tTaTpSVVWFkpIS3HDDDWjfvj1at26NMWPGoL6+PqaDBIvFgjfeeAPjxo3D1VdfjdzcXOTl5eGyyy4Ld9NC4ptvvsHBgwcxbty4cDclZPLz8zF9+nT07NkTrVq1wsUXX4zhw4djz5494W6apj788EMMHjwYAwcORF5eHqZMmYL4+Hhs37493E0LqkcffRQDBgxA27Zt0aFDB9xxxx04efIkfvnll3A3LSTq6urw/PPP4/bbbw9KYBCJNmzYgObNm2P69Ono3LkzWrZsiZ49eyInJ0fz5+KIkY40a9YMubm5+PTTT9GxY0fExcVh69atSE9PR6dOncLdvKA5cuQIysvLIQgCZsyYAZPJhA4dOmDs2LFo165duJsXVCaTCUuXLsWDDz6I+Pj4cDcnrGpqapCamhruZmjGbDbjl19+wQ033GC/ThRF9OjRA4cPHw5fw8KgpqYGAGLq/fXklVdeQa9evXDBBRdg3bp14W5OSPz3v/9Fz5498cwzz+DQoUPIysrC1VdfjSuvvFLz5+KIkY4IgoBZs2ahqKgIt956K8aMGYONGzdi5syZMf2F8vvvvwMA3nnnHYwYMQIPP/wwUlJSMHfuXJw+fTrMrQseWZaxZMkSXHXVVZrPwUeb0tJSbN68OShfouFSVVUFSZKcpsAzMjJgMpnC0qZwkCQJb7zxBrp27RrzP3QA4PPPP8eRI0dwyy23hLspIXXixAls3boVOTk5ePTRR3H11Vfj9ddfx44dOzR/Lo4YxYCVK1diw4YNHo9ZvHgxcnNz8eqrryI9PR1z585FfHw8PvnkEyxYsADz589HZmZmiFqsDbX9thV3HzFiBPr27QsAmD59OqZNm4Yvv/wSV111VdDbqiW1/T5w4ABqa2tRUFAQopYFn9q+t2nTxn65vLwc8+bNw6WXXhpTgREpXn31VRw7dgyPPfZYuJsSdCdPnsQbb7yBv//977obAZYkCeecc449IOzYsSOOHj2KrVu3YsCAAZo+FwOjGDB8+HCvH4xWrVqhsLAQe/fuxeuvv47k5GQAQKdOnXDw4EF8+umnDkPy0UBtvysqKgAAeXl59uvj4uLQqlUrnDx5MphNDApf3u/Dhw87/bJ8+OGHcfnll+POO+8MYiuDQ23fbcrLyzF37lx07doVU6dODXLrQistLQ2iKDqNDplMppheSNHYq6++in379mHu3Llo3rx5uJsTdL/88gsqKyvx0EMP2a+TJAnff/89tmzZglWrVkEUY3MiKDMz0+E7HFC+03fv3q35czEwigFpaWlIS0vzelx9fT0AOP3hCIIASZKC0rZgUtvvTp06IS4uDsXFxTjvvPMAKPkZZWVlyM7ODnYzNae235MmTcKoUaPslysqKjBv3jzce++9OPfcc4PZxKBR23fgbFDUsWNHTJ8+PeZOGEajEZ06dUJhYSF69+4NQDlJFhYW4tprrw1z64JLlmW89tpr2LNnD+bMmYOWLVuGu0kh0aNHDzz11FMO1/373/9Gbm4urr/++pj7jDfWtWtXFBcXO1xXXFwclO9wBkY60qVLF6SmpuKFF17AjTfeiPj4eGzbtg0nTpzAhRdeGO7mBU1ycjKuuuoqrFmzBs2bN0d2djbef/99ALBPrcWiFi1aOFy2LWPOycmJ+V/X5eXlmDNnDrKzszF+/HhUVVXZb4ul0ZRhw4bhX//6Fzp16oTOnTtj06ZNqK+v13xqIdK8+uqr+OyzzzBjxgwkJSXZR82Sk5NjeoopKSnJKY8qISEBzZo1i/n8qqFDh2LWrFlYt24dLrvsMvz000/Ytm1bUEaCBdmWgEG68PPPP+Ott97Czz//DIvFgry8PNx4443o1atXuJsWVGazGatWrcKuXbtw5swZdO7cGRMmTEDbtm3D3bSQOXHiBO68805dFHjcsWMHlixZ4vK2NWvWhLg1wbVlyxa8//779tWWEydOjNoRQbVuuukml9dPnz495oPCpubMmYMOHTroosDj3r17sWrVKpSWlqJly5YYOnRoUPIGGRgRERERWcXuhCQRERGRjxgYEREREVkxMCIiIiKyYmBEREREZMXAiIiIiMiKgRERERGRFQMjIiIiIisGRkRERERWDIyIKKb873//w5o1a1BdXR3uphBRFGJgREQx5X//+x/Wrl3LwIiI/MLAiIh0SZIknDlzJtzNIKIIw73SiChmrFmzBmvXrnW6/oUXXsCdd96Ja665Bl26dMH69etRUlKC++67DykpKZg7dy5mz56Nbt262e9j23S36cakv/32G9566y0UFhbizJkzaNu2LW688UZcfPHFoegiEQWZMdwNICLSSp8+fVBSUoLPP/8ct956K5o1awYASEtLAwAUFhbiyy+/xLXXXotmzZqhZcuWPk25HTt2DLNmzUJWVhZuuOEGJCQk4Msvv8SiRYtw//33o3fv3kHpFxGFDgMjIooZ7du3R8eOHfH555/jkksuQcuWLR1uLy4uxtNPP428vDz7dd99953qx3/jjTfQokULzJ8/H3FxcQCAa665Bv/4xz+wcuVKBkZEMYA5RkSkG+eff75DUOSL06dPo7CwEJdeeilqa2tRVVWFqqoqnDp1Cj179kRJSQnKy8s1bjERhRpHjIhIN5qOIPmitLQUsizj7bffxttvv+3ymMrKSmRlZfn9HEQUfgyMiEg34uPjna4TBMHlsZIkubw8fPhw9OzZ0+V9cnJyAmwhEYUbAyMiiinuAh13UlJSAMApCfvkyZMOl1u1agUAMBgMuOCCCwJoIRFFMuYYEVFMSUhIAADU1NSoOj47OxuiKOL77793uP6jjz5yuJyeno5u3brhP//5DyoqKpwep6qqys8WE1Ek4YgREcWUTp06AQBWr16Nfv36wWAw4KKLLnJ7fHJyMvr27YstW7ZAEAS0atUK+/btQ2VlpdOxt912G2bNmoUHHngAgwcPRsuWLVFZWYnDhw+jvLwcixYtClq/iCg0GBgRUUzp3Lkzbr75ZmzduhX79++HLMt44YUXPN5n0qRJsFgs2Lp1K4xGIy699FKMHTsW999/v8NxeXl5ePLJJ/HOO+9gx44dOHXqFNLT09GhQweMHDkymN0iohBh5WsiIiIiK+YYEREREVkxMCIiIiKyYmBEREREZMXAiIiIiMiKgRERERGRFQMjIiIiIisGRkRERERWDIyIiIiIrBgYEREREVkxMCIiIiKyYmBEREREZMXAiIiIiMiKgRERERGR1f8H+ptnBNnwDNkAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "y_test_pred = lr2.predict(X_test)\n", + "plt.scatter(y_test, y_test_pred)\n", + "plt.xlabel('true')\n", + "plt.ylabel('pred')\n", + "plt.title('pred vs true on test')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LightningModel" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "class MLPProbe(nn.Module):\n", + " def __init__(self, d, depth=0, hs=16, dropout=0):\n", + " super().__init__()\n", + "\n", + " layers = [\n", + " nn.BatchNorm1d(d), # this will normalise the inputs\n", + " nn.Linear(d, hs),\n", + " nn.Dropout1d(dropout),\n", + " ]\n", + " for _ in range(depth):\n", + " layers += [\n", + " nn.Linear(hs, hs),\n", + " nn.ReLU(),\n", + " nn.Dropout1d(dropout),\n", + " ]\n", + " layers += [nn.Linear(hs, 2)]\n", + " self.net = nn.Sequential(*layers)\n", + "\n", + " def forward(self, x):\n", + " return self.net(x)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# logit0 = (torch.rand(5, 4)-0.5)*100\n", + "# logit1 = (torch.rand(5, 4)-0.5)*100\n", + "# ccs_squared_loss(logit0, logit1)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "from pytorch_optimizer import Ranger21\n", + "import torchmetrics\n", + "\n", + " \n", + "class CSS(pl.LightningModule):\n", + " def __init__(self, d, total_steps, lr=4e-3, weight_decay=1e-9, dropout=0):\n", + " super().__init__()\n", + " self.probe = MLPProbe(d*2, depth=1, dropout=dropout)\n", + " self.save_hyperparameters()\n", + " self.auroc = torchmetrics.Accuracy(task=\"multiclass\", num_classes=2)\n", + " \n", + " def forward(self, x):\n", + " return self.probe(x)\n", + " \n", + " def _step(self, batch, batch_idx, stage='train'):\n", + " x0, x1, y = batch\n", + " x = torch.concatenate([x0, x1], 1)\n", + " logits = self(x)\n", + " y_pred = F.softmax(logits, -1)\n", + " if stage=='pred':\n", + " return y_pred\n", + " \n", + " loss = F.cross_entropy(logits, y.long())\n", + " self.log(f\"{stage}/loss\", loss)\n", + " \n", + " self.auroc(y_pred, y.long())\n", + " self.log(f\"{stage}/acc_step\", self.auroc, on_step=False, on_epoch=True)\n", + " return loss\n", + " \n", + " def on_train_epoch_end(self):\n", + " # log epoch metric\n", + " self.log('train/acc_epoch', self.auroc)\n", + " \n", + " def training_step(self, batch, batch_idx):\n", + " return self._step(batch, batch_idx)\n", + " \n", + " def validation_step(self, batch, batch_idx=0):\n", + " return self._step(batch, batch_idx, stage='val')\n", + " \n", + " def predict_step(self, batch, batch_idx):\n", + " return self._step(batch, batch_idx, stage='pred')\n", + "\n", + " # def configure_optimizers(self):\n", + " # optimizer = optim.AdamW(self.parameters(), lr=self.hparams.lr, weight_decay=self.hparams.weight_decay)\n", + " # lr_scheduler = optim.lr_scheduler.OneCycleLR(\n", + " # optimizer, self.hparams.lr, total_steps=self.hparams.total_steps\n", + " # )\n", + " # return [optimizer], [lr_scheduler]\n", + " \n", + " def configure_optimizers(self):\n", + " \"\"\"use ranger21 from https://github.com/kozistr/pytorch_optimizer\"\"\"\n", + " optimizer = Ranger21(\n", + " self.parameters(),\n", + " lr=self.hparams.lr,\n", + " weight_decay=self.hparams.weight_decay, \n", + " num_iterations=self.hparams.total_steps,\n", + " )\n", + " return optimizer\n", + " " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Run" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# quiet please\n", + "torch.set_float32_matmul_precision('medium')\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\", \".*does not have many workers.*\")\n", + "warnings.filterwarnings(\"ignore\", \".*F-score.*\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prep dataloader/set" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮\n",
+       " in <module>:3                                                                                    \n",
+       "                                                                                                  \n",
+       "    1 # split                                                                                     \n",
+       "    2 X = hss1-hss2                                                                               \n",
+       "  3 y = (df_infos2['true_answer'] == (df_infos2['dir_true']>0)).values # direction              \n",
+       "    4 n = len(y)                                                                                  \n",
+       "    5 print('split size', n//2)                                                                   \n",
+       "    6                                                                                             \n",
+       "╰──────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "NameError: name 'df_infos2' is not defined\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[31m╭─\u001b[0m\u001b[31m──────────────────────────────\u001b[0m\u001b[31m \u001b[0m\u001b[1;31mTraceback \u001b[0m\u001b[1;2;31m(most recent call last)\u001b[0m\u001b[31m \u001b[0m\u001b[31m───────────────────────────────\u001b[0m\u001b[31m─╮\u001b[0m\n", + "\u001b[31m│\u001b[0m in \u001b[92m\u001b[0m:\u001b[94m3\u001b[0m \u001b[31m│\u001b[0m\n", + "\u001b[31m│\u001b[0m \u001b[31m│\u001b[0m\n", + "\u001b[31m│\u001b[0m \u001b[2m 1 \u001b[0m\u001b[2m# split\u001b[0m \u001b[31m│\u001b[0m\n", + "\u001b[31m│\u001b[0m \u001b[2m 2 \u001b[0mX = hss1-hss2 \u001b[31m│\u001b[0m\n", + "\u001b[31m│\u001b[0m \u001b[31m❱ \u001b[0m 3 y = (df_infos2[\u001b[33m'\u001b[0m\u001b[33mtrue_answer\u001b[0m\u001b[33m'\u001b[0m] == (df_infos2[\u001b[33m'\u001b[0m\u001b[33mdir_true\u001b[0m\u001b[33m'\u001b[0m]>\u001b[94m0\u001b[0m)).values \u001b[2m# direction\u001b[0m \u001b[31m│\u001b[0m\n", + "\u001b[31m│\u001b[0m \u001b[2m 4 \u001b[0mn = \u001b[96mlen\u001b[0m(y) \u001b[31m│\u001b[0m\n", + "\u001b[31m│\u001b[0m \u001b[2m 5 \u001b[0m\u001b[96mprint\u001b[0m(\u001b[33m'\u001b[0m\u001b[33msplit size\u001b[0m\u001b[33m'\u001b[0m, n//\u001b[94m2\u001b[0m) \u001b[31m│\u001b[0m\n", + "\u001b[31m│\u001b[0m \u001b[2m 6 \u001b[0m \u001b[31m│\u001b[0m\n", + "\u001b[31m╰──────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", + "\u001b[1;91mNameError: \u001b[0mname \u001b[32m'df_infos2'\u001b[0m is not defined\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# split\n", + "X = hss1-hss2\n", + "y = (df_infos2['true_answer'] == (df_infos2['dir_true']>0)).values # direction\n", + "n = len(y)\n", + "print('split size', n//2)\n", + "\n", + "neg_hs_train = hss1[:n//2]\n", + "pos_hs_train = hss2[:n//2]\n", + "\n", + "neg_hs_val = hss1[n//2:]\n", + "pos_hs_val = hss2[n//2:]\n", + "\n", + "y_train, y_val = y[:n//2], y[n//2:]" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "dl_train = dm.train_dataloader()\n", + "dl_val = dm.val_dataloader()\n", + "b = next(iter(dl_train))\n", + "# b" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([32, 116736])\n" + ] + }, + { + "data": { + "text/plain": [ + "CSS(\n", + " (probe): MLPProbe(\n", + " (net): Sequential(\n", + " (0): BatchNorm1d(233472, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", + " (1): Linear(in_features=233472, out_features=16, bias=True)\n", + " (2): Dropout1d(p=0.3, inplace=False)\n", + " (3): Linear(in_features=16, out_features=16, bias=True)\n", + " (4): ReLU()\n", + " (5): Dropout1d(p=0.3, inplace=False)\n", + " (6): Linear(in_features=16, out_features=2, bias=True)\n", + " )\n", + " )\n", + " (auroc): MulticlassAccuracy()\n", + ")" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# init the model\n", + "max_epochs = 53\n", + "d = b[0].shape[-1]\n", + "print(b[0].shape)\n", + "net = CSS(d=d, total_steps=max_epochs*len(dl_train), lr=4e-3, weight_decay=1e-3, dropout=0.3)\n", + "net" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[-0.0426, 0.1803],\n", + " [-0.0928, 0.2299],\n", + " [ 0.0435, 0.2111],\n", + " [-0.5698, 0.3314],\n", + " [-0.0010, -0.0035],\n", + " [ 0.0435, 0.2111],\n", + " [-0.0426, 0.1803],\n", + " [ 0.3809, 0.2565],\n", + " [ 0.0962, 0.1995],\n", + " [-0.3497, 0.0259],\n", + " [ 0.3556, 0.3710],\n", + " [ 0.0435, 0.2111],\n", + " [-0.4706, 0.3910],\n", + " [-0.0426, 0.1803],\n", + " [ 0.0435, 0.2111],\n", + " [ 0.2530, 0.0052],\n", + " [-0.5077, 0.2825],\n", + " [-0.0551, 0.2065],\n", + " [-0.0426, 0.1803],\n", + " [ 0.0435, 0.2111],\n", + " [-0.6490, 0.1017],\n", + " [ 0.0435, 0.2111],\n", + " [-0.0426, 0.1803],\n", + " [ 0.4069, 0.2679],\n", + " [ 0.0435, 0.2111],\n", + " [-0.0026, 0.3184],\n", + " [-0.4758, 0.2885],\n", + " [ 0.0435, 0.2111],\n", + " [-0.0426, 0.1803],\n", + " [-0.2854, 0.1237],\n", + " [ 0.3398, 0.3760],\n", + " [-0.5824, -0.1580]])" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with torch.no_grad():\n", + " b = next(iter(dl_train))\n", + " b2 = [bb.to(net.device) for bb in b]\n", + " x = torch.concatenate([b2[0], b2[1]], 1)\n", + " y = net(x)\n", + "y" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "# # DEBUG\n", + "# trainer = pl.Trainer(fast_dev_run=2)\n", + "# trainer.fit(model=net, train_dataloaders=dl_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/ubuntu/mambaforge/envs/dlk2/lib/python3.9/site-packages/lightning/fabric/connector.py:562: UserWarning: bf16 is supported for historical reasons but its usage is discouraged. Please set your precision to bf16-mixed instead!\n", + " rank_zero_warn(\n", + "Using bfloat16 Automatic Mixed Precision (AMP)\n", + "GPU available: True (cuda), used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "IPU available: False, using: 0 IPUs\n", + "HPU available: False, using: 0 HPUs\n", + "/home/ubuntu/mambaforge/envs/dlk2/lib/python3.9/site-packages/lightning/pytorch/trainer/connectors/logger_connector/logger_connector.py:67: UserWarning: Starting from v1.9.0, `tensorboardX` has been removed as a dependency of the `lightning.pytorch` package, due to potential conflicts with other packages in the ML ecosystem. For this reason, `logger=True` will use `CSVLogger` as the default logger, unless the `tensorboard` or `tensorboardX` packages are found. Please `pip install lightning[extra]` or one of them to enable TensorBoard support by default\n", + " warning_cache.warn(\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", + "\n", + " | Name | Type | Params\n", + "---------------------------------------------\n", + "0 | probe | MLPProbe | 4.2 M \n", + "1 | auroc | MulticlassAccuracy | 0 \n", + "---------------------------------------------\n", + "4.2 M Trainable params\n", + "0 Non-trainable params\n", + "4.2 M Total params\n", + "16.811 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d8be9da4470d41948eac0f68edcc4098", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Sanity Checking: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7393da6fed3942479bbc51d7078a9d2e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "aa43983cd98c47eaa71f845479e477f7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/ubuntu/mambaforge/envs/dlk2/lib/python3.9/site-packages/torchmetrics/utilities/prints.py:36: UserWarning: The ``compute`` method of metric MulticlassAccuracy was called before the ``update`` method which may lead to errors, as metric states have not yet been updated.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d5b6cb9f66894510a7c60e1d01a4a7df", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f72e725de73d44e59274c04bb74d29ec", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "729fd29c34c44e15bff03b826574c216", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b8d0004d1d474eba99b867ae9668d8e7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c4f1cf487f6a4c56bf335af8275aa911", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "31054a3d58b5490d9e6ea06d3887fa83", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "570f286360194989b4882fd65364eb65", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4ed3005523a8417d9b03e585ae405eca", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b1e974db44134f00837784e82515806e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "deb72812ded0415685436029a357b54c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "11ce99b84dcb49e8a77387f59cd8bd65", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "456b47c010bc41c69b3cc06ef598bdb5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "cd6a68d8c91447b8809658160bcba8ac", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0276d3c82a4f4d9c8b1c1ac665dad04b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c35390f083f44c4fa17ab38e550dc157", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "33d88c2e7cd74ce687fc082e9267ebb4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "dcad8058cb54430aa5ed1114e6a7db6e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "85f619162e2d4fb0800b850ea8314ec8", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "84808cbc98674134854bcc5afd0ebbdd", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "a6862612fd5242d29aab9d55d35b7a9c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b5b28697fe7746bd996c5bcc786ed4cf", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c9c7d57005d14aa187150cfd7e1e4833", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "fd3fafe1b55b41bb96807ae84b2878e3", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "993b78ec2788495ca8761e35eeff5238", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d53446fc4f764bc9801592e6645861c9", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9b7977b28e634648bd9217ce9dd42481", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "cef40fa1c56044aa94b8c7ae101f01ee", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "82319345b29140de9fb3c7edde522bc4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "a88f125c56cc48a4b043763b862a0440", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "858b3f7e6ed944debdcdbfd344691611", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b05bcb04d39846618c04cb520359c122", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e303d236c31b44468a51e07b18441aa0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7e75afb133324f4c91b107c6185d5097", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4b00320bb88940e7b55a01a6440a0b3b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e12c22cb7b36493e8b28a6c80a8fa2db", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "06d2ae0d21204e558821b579dd8b86f1", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "dd89af86fc004ac39198771aeb0f78a2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "85e80822bc5c457c849bf3e8ab7a6e0e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "24ff80f463954146af20b6cde5b5cadb", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "866d0ba6e33c4500961773942236c255", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1698519bd005486fba30d18086843e92", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7d5232659a264771a58c2d005dff5df2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9b608814f155483791a6720f0e45eedc", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "aeb5032877f449778886b405ca4263f7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "262fba8074f945bab7329ecccc4f08ac", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5df7b465658748ed9d73850ebcbe10aa", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ad9f0872552249ae86b74eafcb5549fd", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4ad2e43754a14e059759a00e36bd7fae", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f25dd638dce648a8be80ace1b1a1a152", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "07ad2771d8c64fc5b17522c70a13a83a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0927971228f14688bd0b5a50a289911d", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9e764f46811942aea9315c1b9d270f02", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "`Trainer.fit` stopped: `max_epochs=53` reached.\n" + ] + } + ], + "source": [ + "trainer = pl.Trainer(precision=\"bf16\",\n", + " max_epochs=max_epochs, log_every_n_steps=5)\n", + "trainer.fit(model=net, train_dataloaders=dl_train, val_dataloaders=dl_val)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Read hist" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[]\n" + ] + }, + { + "data": { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
train/lossstepval/lossval/acc_steptrain/acc_steptrain/acc_epoch
epoch
00.48498035.8571430.2945990.7693330.00.0
10.72101998.1333330.5124340.7743330.00.0
20.656908161.0000001.0447420.7876670.00.0
31.044309223.2666671.0135630.7713330.00.0
40.671938288.0000001.2925350.7900000.00.0
50.978381350.8571431.4199690.7830000.00.0
60.928060413.1333331.3738920.7996670.00.0
71.103637476.0000001.5224920.7943330.00.0
80.578082538.2666671.7997300.7963330.00.0
90.969000603.0000002.0859180.7940000.00.0
101.193389665.8571432.5882720.7950000.00.0
110.884823728.1333332.8050240.7856670.00.0
120.653900791.0000003.0955980.8003330.00.0
130.382283853.2666673.5346700.7883330.00.0
140.957174918.0000003.3771100.8036670.00.0
150.438253980.8571434.8385970.7976670.00.0
160.6537431043.1333333.8486700.8010000.00.0
170.4640061106.0000005.0162120.7963330.00.0
180.3648701168.2666674.4917410.7996670.00.0
190.5031551233.0000004.8375740.7933330.00.0
200.3557131295.8571434.9285980.8023330.00.0
210.5473631358.1333335.1894710.8010000.00.0
220.4370731421.0000004.9495280.8050000.00.0
230.6401151483.2666675.1122930.8010000.00.0
240.8649311548.0000005.7375740.7956670.00.0
250.5747181610.8571434.8452490.8103330.00.0
260.3465861673.1333335.2849120.8010000.00.0
270.4804961736.0000006.6700430.8053330.00.0
280.3873571798.2666676.3413480.7993330.00.0
291.9696721863.0000006.7659460.8060000.00.0
300.8809311925.8571438.2719260.7920000.00.0
310.7807621988.1333337.6087190.7963330.00.0
320.4149482051.0000007.8975460.7946670.00.0
330.3734882113.2666677.7292310.7973330.00.0
340.3990572178.0000007.4349920.7996670.00.0
350.4808112240.8571438.8894710.7856670.00.0
360.3339252303.1333339.5760950.8026670.00.0
370.7548122366.0000007.2456080.8093330.00.0
380.3768222428.2666677.2601800.7950000.00.0
391.7689772493.0000007.3325530.7913330.00.0
400.5016892555.8571438.7535840.8120000.00.0
410.3355342618.1333337.0598790.8000000.00.0
420.4236452681.0000007.6185350.7956670.00.0
431.0527252743.2666676.5661820.8053330.00.0
440.9536982808.0000007.2530650.8113330.00.0
450.3709622870.8571437.7416090.8070000.00.0
460.3810662933.1333339.4685350.8163330.00.0
470.5306292996.0000007.2241150.8000000.00.0
480.8084723058.2666677.4488600.8050000.00.0
490.3445763123.0000008.1066500.8013330.00.0
500.3702603185.8571437.4152670.7913330.00.0
510.3245003248.1333337.5894750.8100000.00.0
520.3701583311.0000007.3983650.8030000.00.0
\n", + "
" + ], + "text/plain": [ + " train/loss step val/loss val/acc_step train/acc_step \n", + "epoch \n", + "0 0.484980 35.857143 0.294599 0.769333 0.0 \\\n", + "1 0.721019 98.133333 0.512434 0.774333 0.0 \n", + "2 0.656908 161.000000 1.044742 0.787667 0.0 \n", + "3 1.044309 223.266667 1.013563 0.771333 0.0 \n", + "4 0.671938 288.000000 1.292535 0.790000 0.0 \n", + "5 0.978381 350.857143 1.419969 0.783000 0.0 \n", + "6 0.928060 413.133333 1.373892 0.799667 0.0 \n", + "7 1.103637 476.000000 1.522492 0.794333 0.0 \n", + "8 0.578082 538.266667 1.799730 0.796333 0.0 \n", + "9 0.969000 603.000000 2.085918 0.794000 0.0 \n", + "10 1.193389 665.857143 2.588272 0.795000 0.0 \n", + "11 0.884823 728.133333 2.805024 0.785667 0.0 \n", + "12 0.653900 791.000000 3.095598 0.800333 0.0 \n", + "13 0.382283 853.266667 3.534670 0.788333 0.0 \n", + "14 0.957174 918.000000 3.377110 0.803667 0.0 \n", + "15 0.438253 980.857143 4.838597 0.797667 0.0 \n", + "16 0.653743 1043.133333 3.848670 0.801000 0.0 \n", + "17 0.464006 1106.000000 5.016212 0.796333 0.0 \n", + "18 0.364870 1168.266667 4.491741 0.799667 0.0 \n", + "19 0.503155 1233.000000 4.837574 0.793333 0.0 \n", + "20 0.355713 1295.857143 4.928598 0.802333 0.0 \n", + "21 0.547363 1358.133333 5.189471 0.801000 0.0 \n", + "22 0.437073 1421.000000 4.949528 0.805000 0.0 \n", + "23 0.640115 1483.266667 5.112293 0.801000 0.0 \n", + "24 0.864931 1548.000000 5.737574 0.795667 0.0 \n", + "25 0.574718 1610.857143 4.845249 0.810333 0.0 \n", + "26 0.346586 1673.133333 5.284912 0.801000 0.0 \n", + "27 0.480496 1736.000000 6.670043 0.805333 0.0 \n", + "28 0.387357 1798.266667 6.341348 0.799333 0.0 \n", + "29 1.969672 1863.000000 6.765946 0.806000 0.0 \n", + "30 0.880931 1925.857143 8.271926 0.792000 0.0 \n", + "31 0.780762 1988.133333 7.608719 0.796333 0.0 \n", + "32 0.414948 2051.000000 7.897546 0.794667 0.0 \n", + "33 0.373488 2113.266667 7.729231 0.797333 0.0 \n", + "34 0.399057 2178.000000 7.434992 0.799667 0.0 \n", + "35 0.480811 2240.857143 8.889471 0.785667 0.0 \n", + "36 0.333925 2303.133333 9.576095 0.802667 0.0 \n", + "37 0.754812 2366.000000 7.245608 0.809333 0.0 \n", + "38 0.376822 2428.266667 7.260180 0.795000 0.0 \n", + "39 1.768977 2493.000000 7.332553 0.791333 0.0 \n", + "40 0.501689 2555.857143 8.753584 0.812000 0.0 \n", + "41 0.335534 2618.133333 7.059879 0.800000 0.0 \n", + "42 0.423645 2681.000000 7.618535 0.795667 0.0 \n", + "43 1.052725 2743.266667 6.566182 0.805333 0.0 \n", + "44 0.953698 2808.000000 7.253065 0.811333 0.0 \n", + "45 0.370962 2870.857143 7.741609 0.807000 0.0 \n", + "46 0.381066 2933.133333 9.468535 0.816333 0.0 \n", + "47 0.530629 2996.000000 7.224115 0.800000 0.0 \n", + "48 0.808472 3058.266667 7.448860 0.805000 0.0 \n", + "49 0.344576 3123.000000 8.106650 0.801333 0.0 \n", + "50 0.370260 3185.857143 7.415267 0.791333 0.0 \n", + "51 0.324500 3248.133333 7.589475 0.810000 0.0 \n", + "52 0.370158 3311.000000 7.398365 0.803000 0.0 \n", + "\n", + " train/acc_epoch \n", + "epoch \n", + "0 0.0 \n", + "1 0.0 \n", + "2 0.0 \n", + "3 0.0 \n", + "4 0.0 \n", + "5 0.0 \n", + "6 0.0 \n", + "7 0.0 \n", + "8 0.0 \n", + "9 0.0 \n", + "10 0.0 \n", + "11 0.0 \n", + "12 0.0 \n", + "13 0.0 \n", + "14 0.0 \n", + "15 0.0 \n", + "16 0.0 \n", + "17 0.0 \n", + "18 0.0 \n", + "19 0.0 \n", + "20 0.0 \n", + "21 0.0 \n", + "22 0.0 \n", + "23 0.0 \n", + "24 0.0 \n", + "25 0.0 \n", + "26 0.0 \n", + "27 0.0 \n", + "28 0.0 \n", + "29 0.0 \n", + "30 0.0 \n", + "31 0.0 \n", + "32 0.0 \n", + "33 0.0 \n", + "34 0.0 \n", + "35 0.0 \n", + "36 0.0 \n", + "37 0.0 \n", + "38 0.0 \n", + "39 0.0 \n", + "40 0.0 \n", + "41 0.0 \n", + "42 0.0 \n", + "43 0.0 \n", + "44 0.0 \n", + "45 0.0 \n", + "46 0.0 \n", + "47 0.0 \n", + "48 0.0 \n", + "49 0.0 \n", + "50 0.0 \n", + "51 0.0 \n", + "52 0.0 " + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# import pytorch_lightning as pl\n", + "from lightning.pytorch.loggers.csv_logs import CSVLogger\n", + "# from pytorch_lightning.loggers.csv_logs import CSVLogger as CSVLogger2\n", + "from pathlib import Path\n", + "import pandas as pd\n", + "\n", + "def read_metrics_csv(metrics_file_path):\n", + " df_hist = pd.read_csv(metrics_file_path)\n", + " df_hist[\"epoch\"] = df_hist[\"epoch\"].ffill()\n", + " df_histe = df_hist.set_index(\"epoch\").groupby(\"epoch\").mean()\n", + " return df_histe\n", + "\n", + "\n", + "def read_hist(trainer: pl.Trainer):\n", + "\n", + " ts = [t for t in trainer.loggers if isinstance(t, CSVLogger)]\n", + " print(ts)\n", + " try:\n", + " metrics_file_path = Path(ts[0].experiment.metrics_file_path)\n", + " df_histe = read_metrics_csv(metrics_file_path)\n", + " return df_histe\n", + " except Exception as e:\n", + " raise e\n", + " \n", + " \n", + "df_hist = read_hist(trainer).ffill().bfill()\n", + "df_hist\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHMCAYAAAAplYnpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA3vElEQVR4nO3de3xNV/7/8feJJIhIwrgkLg0RwYwIWve2ItqhmmpNMQbzVUo7X9P69kZbWkpLG0a11esMWmbqkq8pqtVQt5lqaFFKUEGYuLYJOQlJRE6yf3/45Xx7miDIlmR5PR8PD9lrr73P2h9Hvbv22uc4LMuyBAAAYAiv8h4AAABAWSLcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAwA22ceNGORwOvfTSS+U9FMBIhBsAAGAUwg0AADAK4QYAABiFcANAkvTRRx/pwQcfVFhYmKpXr66AgAB169ZN//jHP0rsf+bMGU2YMEGtW7eWn5+fAgMDFRUVpeeee07Z2dnX3Le0cnJy9Oqrr6pt27aqUaOG/P391aVLFy1atKhY35+vcdm8ebPuuusuBQYGqmbNmurVq5e2bdtW4mtkZmbq+eefV4sWLVStWjXVqlVLvXr10tq1ay85rjVr1ui+++5TvXr1VLVqVTVu3Fj333//JY/ZuXOn7r33XgUFBcnPz0/du3dXYmLiNdUEwEUOy7Ks8h4EgPJXvXp1/eY3v1Hr1q0VEhKi06dPa9WqVTp+/LheeOEFvfzyy+6+hw8fVo8ePfSf//xHt956q7p3767CwkIlJydr7dq12r9/v5o0aXLVfUvL6XQqJiZGO3bsUPv27dW1a1cVFhZq9erVOnTokCZMmKBXXnnF3X/jxo3q0aOHevfurfXr1+uuu+5SVFSUDh48qE8++UQ+Pj5as2aN7rjjDo/X6Natm/bu3asOHTooJiZG6enpio+P17lz5/Tee+/p0Ucf9RjXpEmTNGXKFPn7++uBBx5Q48aNdeLECSUmJqpr16766KOPPMZz7733av369erSpYvatWun1NRU/fOf/5Svr6927typFi1aXN0fIoCLLACwLOvgwYPF2vLy8qyYmBjL29vbOnbsmLu9S5culiRr2rRpxY5JS0uzcnNzr6lvaQ0bNsySZMXFxXm05+bmWr169bIcDoe1Y8cOd/uGDRssSZYka/bs2R7HLF++3JJkhYeHWwUFBe72Rx55xJJkPfLII1ZhYaG7PTk52QoICLB8fX2tw4cPu9tXr15tSbKaNm3qUasiR48eLXE8H374oUe/999/35Jk/fd///fVlATAzxBuAFzWP//5T0uSNX/+fMuyLGvbtm2WJKtt27YeYaAkV9O3tNLT060qVapYt912W4n7d+7caUmyxo4d624rChO/DDBFunfvbkmyNm7caFnWxVDn5+dn+fv7W6dPny7W/4UXXrAkWZMnT3a3xcbGWpKsTz755IrXUDSebt26Fdt34cIFy9vb27r11luveB4AJfO+sfNEACqq1NRUxcXFad26dUpNTVVubq7H/uPHj0uStmzZIknq1auXvLwuv2zvavqW1tatW1VQUHDJz4nJz8+XJO3bt6/YvjvuuKPEcURHR+tf//qXduzYoe7du2v//v3KyclRt27dVLt27WL9Y2Ji9Morr2jHjh3uti1btsjhcKh3796lvpbbbrutWJuPj4/q16+vjIyMUp8HgCfCDQClpKSoY8eOysjI0B133KHf/va3CgwMVJUqVXTkyBHNnz9feXl5ki6uRZGkhg0bXvG8V9O3tE6fPi3pYsjZunXrJfudO3euWFv9+vVL7BscHCzp4gLin/8eEhJSYv+i9qLrK/q5Vq1aql69+hWu4P8EBQWV2O7t7a2CgoJSnweAJ8INAL3++us6ffq0PvzwQz300EMe+xYtWqT58+e7t4v+QS6aybmcq+lbWoGBgZKkJ598Uq+//vpVHfvjjz+W2H7q1CmPcxf9XtT+SydPnvToJ1281tOnTys3N/eqAg6Assej4AB08OBBSdKDDz5YbN+//vUvj+3OnTtLklavXq3CwsLLnvdq+pZWx44d5eXlpa+++uqqj920aVOJ49i4caMkqV27dpKkFi1ayM/PT99//73H7EyRDRs2SJLat2/vbuvcubMsy1JCQsJVjwtA2SLcAHA/il30j3yR1atXa86cOR5tt956q7p27aqdO3cqLi6u2LlOnz6t8+fPX3Xf0qpXr56GDBmibdu26eWXXy7x9s2hQ4d0+PDhYu0HDhzQu+++69G2YsUK/etf/1J4eLj7UXBfX18NGTJEZ8+e1Ysvvljs3G+99ZZ8fHz0xz/+0d3++OOPS5KefvrpEmeqynL2CsDl8Tk3ALRr1y516NBBDodD/fv3V4MGDZSUlKSEhAQNHDhQS5Ys0aRJk9wLeA8fPqzo6Gilpqbq1ltvVXR0tCzL0oEDB7RmzRr98MMPHp9zU9q+pZWVlaVevXppy5Ytat68uW6//XbVr19fJ06c0L59+7R161YtWrRIgwYNknRtn3Nz5swZdevWTT/88IM6deqkHj16uD/n5uzZs3r77bc1evRoj3G9+OKLeuWVV1SzZk3359z8+OOP2rRpkzp37lzsc25+XtOfK6rHkSNHrqouAP6/cn1WC0CF8fXXX1s9evSwgoKCLH9/f6tbt27WsmXL3I8tT5o0yaN/enq6NW7cOCsiIsKqWrWqFRgYaEVFRVnjx4+3srOzr7lvaeXl5VmzZ8+2unTp4v7cmcaNG1sxMTHWrFmzrPT0dHffn19DYmKi1bNnT6tmzZqWv7+/dffdd1vffvttia+RkZFhjRs3zgoPD7d8fX2twMBA66677rJWr159yXF9/vnnVq9evaxatWpZvr6+VqNGjawHHnjAWrduXYnjKUloaKgVGhp6TXUBYFnM3AAw3pVmSgCYhTU3AADAKIQbAABgFD7nBkC5++ijj0q1eLZt27Z64IEHbB8PgMqNNTcAyl3R1x9cybBhw9xPHAHApRBuAACAUVhzAwAAjEK4AQAARiHcAAAAo9zUT0tlZGTI5XKV+Xnr1q2rtLS0Mj/vzY662ofa2ofa2oO62qci19bb21u1atW6cr8bMJYKy+VyKT8/v0zP6XA43OdmrXbZoa72obb2obb2oK72MaW23JYCAABGIdwAAACjEG4AAIBRCDcAAMAoN/WCYgDApblcLuXk5JT3MEqUm5urCxculPcwjFTetfXz85O39/XFE8INAKAYl8ul7Oxs1axZU15eFW+S38fHp8yfdsVF5VnbwsJCnT17VjVq1LiugFPx3rEAgHKXk5NTYYMNzOXl5aWaNWte94wh71oAQIkINigPZfG+450LAACMQrgBAABGIdwAAFCCTp066W9/+1t5D6NSS0xMVMOGDZWZmXlDX5dwAwAwRv/+/TVx4sQyOdeqVas0dOjQqz7u2LFjatasmbKzs8tkHLh6PAoOALhpWJalgoKCUj1m/Ktf/eqaXmP16tXq2rWratSocU3H4/oxcwMAMMITTzyhzZs3a+7cuWrYsKEaNmyoJUuWqGHDhlq/fr169+6tpk2b6ttvv9WRI0c0fPhwRUVFqXnz5urTp4/+/e9/e5zvl7elGjZsqIULF+rhhx9Ws2bN1K1bN61Zs6bYOFavXq27775bkrRz504NGjRIrVu3VsuWLfXggw9q9+7dHv0zMzM1btw4RUVFKSwsTDExMfryyy/d+7du3ar+/furWbNm+vWvf63BgwfL6XResR6FhYWaPXu2OnfurGbNmumuu+7SZ5995t5fdMto7dq1uuuuuxQWFqbY2Fjt27fP4zyff/65evTooaZNm6pTp056//33Pfbn5eVp6tSpuu2229S0aVN169ZNixYt8uiza9cu3XPPPWrWrJn69u2rgwcPXnH814NwAwC4LMuyZOWdL59fllXqcU6ZMkW33nqrhgwZoh07dmjHjh1q0KCBJGnatGkaP368Nm7cqFatWik7O1sxMTFasmSJVq9erejoaA0fPlzHjx+/7Gu8/vrruu+++7R27Vr17NlTjz32mDIyMtz7MzMztXXrVv32t7+VJJ07d04DBgzQ8uXLtXLlSjVt2lR//OMfde7cOUkXA8jQoUO1bds2zZ49Wxs2bNDzzz+vKlWqSJKSkpL0+9//Xs2bN9enn36qZcuW6e6771ZhYeEV6zF79mwtXbpUr732mtavX69Ro0ZpzJgx2rx5s0e/V155RRMnTtTnn3+uX/3qV/rjH//o/hC/Xbt26U9/+pP69u2rtWvX6qmnntKMGTO0ZMkS9/H/8z//o+XLl+vll1/Wxo0b9dprr8nPz8/jNeLi4jRx4kR98cUX8vb21tNPP33F8V8PbksBAC7vQp4KHxtYLi/t9Xa8VLVaqfoGBATI19dX1apVU7169STJPUMwduxY3Xnnne6+tWrV0m9+8xv39rhx45SQkKA1a9Zo+PDhl3yNgQMH6oEHHpAkPffcc5o7d6527typHj16SJLWr1+vVq1aKTg4WJJ0++23exw/ffp0tWrVSps3b9bdd9+tr776Sjt37tTGjRvVrFkzSVJoaKi7/3vvvac2bdro1Vdfdbe1aNHiirXIy8vT7NmztXjxYt12223u827dulX/+Mc/1KVLF3ffJ5980l2bN954Qx06dNAXX3yhvn376q9//atuv/12Pfnkk5KkZs2a6cCBA3r//ff1+9//XocOHdLKlSu1aNEi9zl+Pv4izz77rPs1//znP+u//uu/dP78eVWrVro/26tFuAEAGK9NmzYe29nZ2Zo5c6bWrVunn376SS6XS+fPn7/izE2rVq3cP/v5+almzZpKT093t/38lpQkpaWlafr06UpMTNTp06dVUFCg3Nxc9+vs2bNHISEh7mDzS3v27FFsbOxVX++RI0eUm5urP/zhDx7t+fn5at26tUdbUfiRLoa+Zs2auUPhgQMH1KtXL4/+HTp00Jw5c1RQUKA9e/aoSpUqHmGpJL/+9a/dP9evX1+SdPr0aTVs2PCqr600CDcAgMvzrXpxBqWcXrss/PI2yZQpU/TVV1/pxRdfVJMmTVStWjU98sgjV/zCSB8fH49th8PhvkV04cIFbdy4UY8//rh7/xNPPKGMjAxNmTJFjRo1kq+vr/r27eu+7XOlmYtrndkoelJrwYIF7lmkIr6+vtd0zpKUdnwlLeAuza21a0W4AQBclsPhKPWtofLm4+NTqn80t23bpgEDBuiee+6RdDEMHDt27Lpee/PmzQoMDPS43bV161ZNmzZNPXv2lCQdP35cZ86cce9v1aqVTp48qUOHDpU4e9OqVStt2rRJzzzzzFWNJSIiQlWrVtXx48evOKuyfft29wyK0+lUSkqKwsPDJUnNmzfX1q1bPfpv3bpVYWFhqlKlilq1aqXCwkJt3rzZ47ZfeWNBMQDAGI0bN9aOHTt09OhRnTlz5pJBp2nTpvriiy+UlJSkPXv26M9//vN1zySsWbPGvZD456/zz3/+UwcOHNB3332nxx9/3GO2o0uXLurUqZMeeeQR/fvf/1ZqaqrWr1+vDRs2SJIee+wxff/993r++ee1d+9eHTx4UPPnz/cISCXx9/fXo48+qpdeeknx8fE6cuSIdu/erXnz5ik+3nMW7o033tBXX32lH374QU8++aRq166t3r17S5IeffRRbdq0SbNmzdKhQ4cUHx+vDz/8UI8++qiki/UeMGCAnn76aSUkJCg1NVWJiYn69NNPr6uW14twAwAwxqOPPiovLy9FR0crMjLykmtoJk2apMDAQN1///166KGH3P2vx5o1azzW20jSzJkzlZmZqd69e2vMmDEaMWKE6tSp49Hnb3/7m6KiojR69Gj16NFDU6dOVUFBgaSLC3gXLlyovXv3KjY2Vn379tWaNWvcT1Ndzrhx4/TEE0/o7bffVnR0tIYMGaJ169bplltu8ej3/PPPa9KkSbrnnnuUlpamv//97+5bV5GRkXr//ff16aefqmfPnvrLX/6isWPH6ve//737+FdffVX33nuvxo8fr+7du2vs2LHKzc29phqWFYd1Nc/ZGSYtLc1937OsOBwOhYSE6OTJk1f1CCMuj7rah9rapzLXNisrSwEBAeU9jEvy8fEp8/9+X4/du3dr4MCB2rVrV7F1ORVVYmKiBgwYoL179yowMNDdXhFqe6n3n4+Pj+rWrXvF45m5AQDgOrlcLr388suVJtiYjgXFAABcp3bt2qldu3Y37PWOHz+u6OjoS+7fuHGjbY9ZVwaEGwAAKpn69euX+NUPP99/JV27dr3i5/pUVoQbAAAqGW9vbzVt2rS8h1FhseYGAAAYhXADACimsj3dBbNc7/uPcAMAKMbb21vZ2dmEHNxQlmUpOzu7xK9ruBqsuQEAFFOjRg3l5eXp7Nmz5T2UEvn6+l7xe6Bwbcq7tlWrVlXVqtf3nWKEGwBAicriHxk7VOYPR6zoTKktt6UAAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMMoN+eLMhIQErVy5Uk6nU6GhoRoxYoTCw8Mv2X/z5s1asmSJ0tLSFBwcrCFDhqh9+/Yl9v3rX/+qtWvXatiwYbr33nvtugQAAFBJ2D5zk5iYqAULFqh///6Ki4tTaGiopk6dqszMzBL779+/X2+++aZiYmIUFxenDh06aMaMGUpNTS3W99tvv9WBAwdUq1Ytuy8DAABUEraHm88++0w9e/ZUjx491KhRI40aNUq+vr7asGFDif1XrVqltm3bqm/fvmrUqJEGDRqksLAwJSQkePQ7c+aM5s2bpzFjxsjb+4ZMQAEAgErA1nDjcrmUkpKiyMjI/3tBLy9FRkYqOTm5xGOSk5M9+ktSVFSUDhw44N4uLCzU7Nmz1bdvXzVu3NiewQMAgErJ1imPrKwsFRYWKigoyKM9KChIJ06cKPEYp9OpwMBAj7bAwEA5nU739ooVK1SlShXdc889pRpHfn6+8vPz3dsOh0PVq1d3/1yWis5X1ue92VFX+1Bb+1Bbe1BX+5hS20p3PyclJUWrVq1SXFxcqYu/bNkyLV261L3dtGlTxcXFqW7dunYNU8HBwbad+2ZGXe1Dbe1Dbe1BXe1T2Wtra7gJCAiQl5eXx6yLdHF25pezOUWCgoKKLTbOzMx099+3b5+ysrI0evRo9/7CwkItWLBAq1at0jvvvFPsnP369VNsbKx7uygUpaWlyeVyXcOVXZrD4VBwcLBOnToly7LK9Nw3M+pqH2prH2prD+pqn4peW29v71JNTNgabry9vRUWFqakpCR17NhR0sUgkpSUpN69e5d4TEREhHbv3u3xWPeuXbvUvHlzSdKdd95ZbE3O1KlTdeedd6pHjx4lntPHx0c+Pj4l7rPrD8+yrAr5xqjsqKt9qK19qK09qKt9KnttbX9aKjY2VuvWrdPGjRt17NgxzZkzR3l5eYqOjpYkvf3221q4cKG7f58+ffT9999r5cqVOn78uOLj43Xo0CF3GKpZs6ZuueUWj1/e3t4KCgpSgwYN7L4cAABQwdm+5qZr167KyspSfHy8nE6nmjRpovHjx7tvM6Wnp3usnWnRooXGjBmjxYsXa9GiRQoJCdHYsWN1yy232D1UAABgAIdVmeedrlNaWprHU1RlweFwKCQkRCdPnqzUU3oVDXW1D7W1D7W1B3W1T0WvrY+PT6nW3PDdUgAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUbxvxIskJCRo5cqVcjqdCg0N1YgRIxQeHn7J/ps3b9aSJUuUlpam4OBgDRkyRO3bt5ckuVwuLV68WDt27NBPP/0kPz8/RUZGavDgwapdu/aNuBwAAFCB2T5zk5iYqAULFqh///6Ki4tTaGiopk6dqszMzBL779+/X2+++aZiYmIUFxenDh06aMaMGUpNTZUkXbhwQYcPH9aDDz6ouLg4Pf300zpx4oSmT59u96UAAIBKwPZw89lnn6lnz57q0aOHGjVqpFGjRsnX11cbNmwosf+qVavUtm1b9e3bV40aNdKgQYMUFhamhIQESZKfn59efPFFde3aVQ0aNFBERIRGjBihlJQUpaen2305AACggrM13LhcLqWkpCgyMvL/XtDLS5GRkUpOTi7xmOTkZI/+khQVFaUDBw5c8nVycnLkcDjk5+dXNgMHAACVlq1rbrKyslRYWKigoCCP9qCgIJ04caLEY5xOpwIDAz3aAgMD5XQ6S+x/4cIFffzxx+rWrdslw01+fr7y8/Pd2w6HQ9WrV3f/XJaKzlfW573ZUVf7UFv7UFt7UFf7mFLbG7Kg2C4ul0uzZs2SJI0cOfKS/ZYtW6alS5e6t5s2baq4uDjVrVvXtrEFBwfbdu6bGXW1D7W1D7W1B3W1T2Wvra3hJiAgQF5eXsVmXZxOZ7HZnCJBQUHFFhtnZmYW618UbNLT0zVx4sTL3pLq16+fYmNj3dtFiTQtLU0ul6v0F1QKDodDwcHBOnXqlCzLKtNz38yoq32orX2orT2oq30qem29vb1LNTFha7jx9vZWWFiYkpKS1LFjR0lSYWGhkpKS1Lt37xKPiYiI0O7du3Xvvfe623bt2qXmzZu7t4uCzalTpzRp0iTVrFnzsuPw8fGRj49Pifvs+sOzLKtCvjEqO+pqH2prH2prD+pqn8peW9ufloqNjdW6deu0ceNGHTt2THPmzFFeXp6io6MlSW+//bYWLlzo7t+nTx99//33WrlypY4fP674+HgdOnTIHYZcLpdef/11paSk6PHHH1dhYaGcTqecTmeZz8IAAIDKx/Y1N127dlVWVpbi4+PldDrVpEkTjR8/3n2bKT093WPhUosWLTRmzBgtXrxYixYtUkhIiMaOHatbbrlFknTmzBlt27ZNkjRu3DiP15o0aZJ+85vf2H1JAACgAnNYlXne6TqlpaV5PEVVFhwOh0JCQnTy5MlKPaVX0VBX+1Bb+1Bbe1BX+1T02vr4+JRqzQ3fLQUAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjOJ9I14kISFBK1eulNPpVGhoqEaMGKHw8PBL9t+8ebOWLFmitLQ0BQcHa8iQIWrfvr17v2VZio+P17p165Sdna2WLVtq5MiRCgkJuRGXAwAAKjDbZ24SExO1YMEC9e/fX3FxcQoNDdXUqVOVmZlZYv/9+/frzTffVExMjOLi4tShQwfNmDFDqamp7j4rVqzQF198oVGjRmnatGmqWrWqpk6dqgsXLth9OQAAoIKzfebms88+U8+ePdWjRw9J0qhRo/Tdd99pw4YNeuCBB4r1X7Vqldq2bau+fftKkgYNGqTdu3crISFBjzzyiCzL0qpVq/S73/1OHTp0kCQ99thjGjVqlLZu3apu3brZfUmXZFmWdCFPhedzZeWdv7iNsuFwUFe7UFv7UFt7UFf7lGVtfavK4XCUzbiukq3hxuVyKSUlxSPEeHl5KTIyUsnJySUek5ycrNjYWI+2qKgobd26VZL0008/yel0qk2bNu79fn5+Cg8PV3JyconhJj8/X/n5+e5th8Oh6tWru38uMxfyVPDnATpedmfEz1BX+1Bb+1Bbe1BX+5RVbau8879yVK1WRme7OraGm6ysLBUWFiooKMijPSgoSCdOnCjxGKfTqcDAQI+2wMBAOZ1O9/6itkv1+aVly5Zp6dKl7u2mTZsqLi5OdevWLf3FlELh+Vz+wgEAICk4OFhe1aqXy2vfkAXF5a1fv34es0FFszVpaWlyuVxl9jqWZcn73aWqX7++fvzxR6ZLy5DD4aCuNqG29qG29qCu9inL2p46kyGHw1k2A/v/vL29SzUxYWu4CQgIkJeXV7EZFafTWWw2p0hQUFCxxcaZmZnu/kW/Z2ZmqlatWh59mjRpUuI5fXx85OPjU+K+Mv+L4Vv1YlL1rSrxl67sOBzU1S7U1j7U1h7U1T5lXNvyCp+2Pi3l7e2tsLAwJSUludsKCwuVlJSkiIiIEo+JiIjQ7t27Pdp27dql5s2bS5Lq1aunoKAgjz45OTk6ePDgJc8JAABuHrY/Ch4bG6t169Zp48aNOnbsmObMmaO8vDxFR0dLkt5++20tXLjQ3b9Pnz76/vvvtXLlSh0/flzx8fE6dOiQevfuLenilFmfPn30ySefaNu2bUpNTdXbb7+tWrVquZ+eAgAANy/b19x07dpVWVlZio+Pl9PpVJMmTTR+/Hj37aX09HSPJ5ZatGihMWPGaPHixVq0aJFCQkI0duxY3XLLLe4+999/v/Ly8vTBBx8oJydHLVu21Pjx4+Xr62v35QAAgArOYd3Eq7HS0tI8HhEvCw6HQyEhITp58iQL3coQdbUPtbUPtbUHdbVPRa+tj49PqRYU891SAADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRvO068blz5zRv3jxt375dDodDnTp10vDhw1WtWrVLHnPhwgUtWLBAiYmJys/PV1RUlEaOHKmgoCBJ0pEjR7R8+XLt379fWVlZqlevnu6++2716dPHrssAAACVjG0zN2+99ZaOHj2qF154Qc8995z27dunDz744LLHzJ8/X9u3b9dTTz2lyZMnKyMjQzNnznTvT0lJUWBgoB5//HG9/vrr6tevnxYuXKiEhAS7LgMAAFQytoSbY8eOaefOnfrTn/6k5s2bq2XLlhoxYoQSExN15syZEo/JycnR+vXrNWzYMLVu3VphYWEaPXq09u/fr+TkZElSTEyMhg8frl//+teqX7++7rzzTkVHR+ubb76x4zIAAEAlZMttqeTkZNWoUUPNmjVzt0VGRsrhcOjgwYPq2LFjsWNSUlJUUFCgyMhId1vDhg1Vp04dJScnKyIiosTXysnJkb+//2XHk5+fr/z8fPe2w+FQ9erV3T+XpaLzlfV5b3bU1T7U1j7U1h7U1T6m1NaWcON0OhUQEODRVqVKFfn7+8vpdF7yGG9vb9WoUcOjPTAw8JLH7N+/X5s3b9Zzzz132fEsW7ZMS5cudW83bdpUcXFxqlu37pUv5hoFBwfbdu6bGXW1D7W1D7W1B3W1T2Wv7VWFm48//lgrVqy4bJ9Zs2Zd14BKKzU1VdOnT1f//v0VFRV12b79+vVTbGyse7sokaalpcnlcpXpuBwOh4KDg3Xq1ClZllWm576ZUVf7UFv7UFt7UFf7VPTaent7l2pi4qrCzX333afo6OjL9qlfv76CgoKUlZXl0V5QUKBz5865n3z6paCgILlcLmVnZ3vM3mRmZhY75tixY3r55Zd111136cEHH7ziuH18fOTj41PiPrv+8CzLqpBvjMqOutqH2tqH2tqDutqnstf2qsJNQEBAsdtNJYmIiFB2drZSUlIUFhYmSUpKSpJlWQoPDy/xmLCwMFWpUkW7d+9W586dJUknTpxQenq6x3qbo0ePasqUKerevbv+8Ic/XM3wAQDATcCWp6UaNWqktm3b6oMPPtDBgwf1ww8/aN68eeratatq164tSTpz5oyeeOIJHTx4UJLk5+enmJgYLViwQElJSUpJSdG7776riIgId7hJTU3V5MmT1aZNG8XGxsrpdMrpdBabJQIAADcv2z7Eb8yYMZo7d66mTJni/hC/ESNGuPe7XC6dOHFCeXl57rZhw4bJ4XBo5syZcrlc7g/xK7JlyxZlZWXpq6++0ldffeVur1u3rt555x27LgUAAFQiDqsy31S7TmlpaR6PiJcFh8OhkJAQnTx5slLfr6xoqKt9qK19qK09qKt9KnptfXx8SrWgmO+WAgAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACM4m3Xic+dO6d58+Zp+/btcjgc6tSpk4YPH65q1apd8pgLFy5owYIFSkxMVH5+vqKiojRy5EgFBQUV63v27FmNHTtWZ86c0YcffqgaNWrYdSkAAKASsW3m5q233tLRo0f1wgsv6LnnntO+ffv0wQcfXPaY+fPna/v27Xrqqac0efJkZWRkaObMmSX2fe+99xQaGmrH0AEAQCVmS7g5duyYdu7cqT/96U9q3ry5WrZsqREjRigxMVFnzpwp8ZicnBytX79ew4YNU+vWrRUWFqbRo0dr//79Sk5O9ui7Zs0a5eTk6L777rNj+AAAoBKz5bZUcnKyatSooWbNmrnbIiMj5XA4dPDgQXXs2LHYMSkpKSooKFBkZKS7rWHDhqpTp46Sk5MVEREh6WJwWrp0qaZNm6Yff/yxVOPJz89Xfn6+e9vhcKh69erun8tS0fnK+rw3O+pqH2prH2prD+pqH1Nqa0u4cTqdCggI8GirUqWK/P395XQ6L3mMt7d3sbUzgYGB7mPy8/P15ptvaujQoapTp06pw82yZcu0dOlS93bTpk0VFxenunXrlv6irlJwcLBt576ZUVf7UFv7UFt7UFf7VPbaXlW4+fjjj7VixYrL9pk1a9Z1DehyFi5cqIYNG+rOO++8quP69eun2NhY93ZRIk1LS5PL5SrTMTocDgUHB+vUqVOyLKtMz30zo672obb2obb2oK72qei19fb2LtXExFWFm/vuu0/R0dGX7VO/fn0FBQUpKyvLo72goEDnzp0r8cknSQoKCpLL5VJ2drbH7E1mZqb7mKSkJKWmpmrLli2S5C78ww8/rN/97ncaOHBgief28fGRj49Pifvs+sOzLKtCvjEqO+pqH2prH2prD+pqn8pe26sKNwEBAcVuN5UkIiJC2dnZSklJUVhYmKSLwcSyLIWHh5d4TFhYmKpUqaLdu3erc+fOkqQTJ04oPT3dvd7m6aef1oULF9zHHDp0SO+9956mTJmi+vXrX82lAAAAQ9my5qZRo0Zq27atPvjgA40aNUoul0vz5s1T165dVbt2bUnSmTNnNGXKFD322GMKDw+Xn5+fYmJitGDBAvn7+8vPz0/z5s1TRESEO9z88h7g2bNnJV1ceMzn3AAAAMnGD/EbM2aM5s6dqylTprg/xG/EiBHu/S6XSydOnFBeXp67bdiwYXI4HJo5c6ZcLpf7Q/wAAABKy2FV5ptq1yktLc3jEfGy4HA4FBISopMnT1bq+5UVDXW1D7W1D7W1B3W1T0WvrY+PT6kWFPPdUgAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAAAAoxBuAACAUQg3AADAKIQbAABgFMINAAAwCuEGAAAYhXADAACMQrgBAABGIdwAAACjEG4AAIBRCDcAAMAohBsAAGAUwg0AADCKd3kPoDx5e9t3+Xae+2ZGXe1Dbe1Dbe1BXe1TUWtb2nE5LMuybB4LAADADcNtqTKWm5urZ599Vrm5ueU9FKNQV/tQW/tQW3tQV/uYUlvCTRmzLEuHDx8WE2Jli7rah9rah9rag7rax5TaEm4AAIBRCDcAAMAohJsy5uPjo/79+8vHx6e8h2IU6mofamsfamsP6mofU2rL01IAAMAozNwAAACjEG4AAIBRCDcAAMAohBsAAGCUivnlEZVUQkKCVq5cKafTqdDQUI0YMULh4eHlPaxKZe/evfr00091+PBhZWRk6JlnnlHHjh3d+y3LUnx8vNatW6fs7Gy1bNlSI0eOVEhISDmOuuJbtmyZvv32Wx0/fly+vr6KiIjQ0KFD1aBBA3efCxcuaMGCBUpMTFR+fr6ioqI0cuRIBQUFld/AK4E1a9ZozZo1SktLkyQ1atRI/fv3V7t27SRR17KyfPlyLVy4UH369NFDDz0kidpeq/j4eC1dutSjrUGDBnrjjTckmVFXZm7KSGJiohYsWKD+/fsrLi5OoaGhmjp1qjIzM8t7aJVKXl6emjRpoocffrjE/StWrNAXX3yhUaNGadq0aapataqmTp2qCxcu3OCRVi579+5Vr169NHXqVL3wwgsqKCjQK6+8ovPnz7v7zJ8/X9u3b9dTTz2lyZMnKyMjQzNnzizHUVcOtWvX1uDBg/Xaa6/p1VdfVevWrTV9+nQdPXpUEnUtCwcPHtSXX36p0NBQj3Zqe+0aN26sv/71r+5fU6ZMce8zoq4WysTzzz9vzZkzx71dUFBgPfLII9ayZcvKb1CV3IABA6xvvvnGvV1YWGiNGjXKWrFihbstOzvbGjx4sLVp06byGGKllZmZaQ0YMMDas2ePZVkX6zho0CBr8+bN7j7Hjh2zBgwYYO3fv7+8hllpPfTQQ9a6deuoaxnIzc21xowZY33//ffWpEmTrA8//NCyLN6z12PJkiXWM888U+I+U+rKzE0ZcLlcSklJUWRkpLvNy8tLkZGRSk5OLseRmeWnn36S0+lUmzZt3G1+fn4KDw+nzlcpJydHkuTv7y9JSklJUUFBgcd7uGHDhqpTpw61vQqFhYX6+uuvlZeXp4iICOpaBubMmaN27dp5/L2XeM9er1OnTunRRx/VY489prfeekvp6emSzKkra27KQFZWlgoLC4vdjwwKCtKJEyfKZ1AGcjqdkqTAwECP9sDAQPc+XFlhYaE++ugjtWjRQrfccouki7X19vZWjRo1PPpS29JJTU3VhAkTlJ+fr2rVqumZZ55Ro0aNdOTIEep6Hb7++msdPnxYr776arF9vGevXfPmzTV69Gg1aNBAGRkZWrp0qSZOnKiZM2caU1fCDXCTmTt3ro4ePepxjx3Xp0GDBpoxY4ZycnK0ZcsWvfPOO5o8eXJ5D6tSS09P10cffaQXXnhBvr6+5T0coxQtdpek0NBQd9jZvHmzMbUm3JSBgIAAeXl5FUu1TqezUq0ur+iKapmZmalatWq52zMzM9WkSZPyGVQlM3fuXH333XeaPHmyfvWrX7nbg4KC5HK5lJ2d7fF/bJmZmbyHS8Hb21vBwcGSpLCwMB06dEirVq1S165dqes1SklJUWZmpp599ll3W2Fhofbt26eEhARNmDCB2paRGjVqqEGDBjp16pTatGljRF1Zc1MGvL29FRYWpqSkJHdbYWGhkpKSFBERUY4jM0u9evUUFBSk3bt3u9tycnJ08OBB6nwFlmVp7ty5+vbbbzVx4kTVq1fPY39YWJiqVKniUdsTJ04oPT2d2l6DwsJC5efnU9frEBkZqb/85S+aPn26+1ezZs10++23u3+mtmXj/PnzOnXqlIKCgox5zzJzU0ZiY2P1zjvvKCwsTOHh4Vq1apXy8vIUHR1d3kOrVIr+khX56aefdOTIEfn7+6tOnTrq06ePPvnkE4WEhKhevXpavHixatWqpQ4dOpTjqCu+uXPnatOmTRo3bpyqV6/unmX08/OTr6+v/Pz8FBMTowULFsjf319+fn6aN2+eIiIiKtV/0MrDwoUL1bZtW9WpU0fnz5/Xpk2btHfvXk2YMIG6Xofq1au714QVqVq1qmrWrOlup7bXZsGCBbrttttUp04dZWRkKD4+Xl5eXrr99tuNec/yreBlKCEhQZ9++qmcTqeaNGmi4cOHq3nz5uU9rEplz549Ja5V6N69u/785z+7P8Rv7dq1ysnJUcuWLfXwww97fBgdihs4cGCJ7aNHj3YH8KIP7vr666/lcrkq5Qd3lYf33ntPSUlJysjIkJ+fn0JDQ3X//fe7n+6hrmXnpZdeUpMmTYp9iB+1vTpvvPGG9u3bp7NnzyogIEAtW7bUoEGD3LdWTagr4QYAABiFNTcAAMAohBsAAGAUwg0AADAK4QYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgDgF+Lj4zVw4EBlZWWV91AAXAPCDQAAMArhBgAAGIVwAwAAjMK3ggMoN2fOnNHixYu1Y8cOZWdnKzg4WLGxsYqJiZH0f1+k+sQTT+jIkSPasGGDzp8/r9atW+vhhx9WnTp1PM63efNmLV++XMeOHVO1atUUFRWloUOHqnbt2h79jh8/riVLlmjPnj06f/686tSpo86dO+sPf/iDR7+cnBz9/e9/19atW2VZljp16qSHH35YVatWtbcwAK4L4QZAuXA6nZowYYIkqVevXgoICNDOnTv1/vvvKzc3V/fee6+77yeffCKHw6H7779fWVlZ+vzzz/Xyyy9rxowZ8vX1lSRt3LhR7777rpo1a6bBgwcrMzNTq1at0v79+zV9+nTVqFFDkvSf//xHEydOlLe3t3r27Kl69erp1KlT2r59e7FwM2vWLNWtW1eDBw9WSkqK1q9fr4CAAA0dOvQGVQnAtSDcACgXixcvVmFhof7yl7+oZs2akqTf/va3euONN/S///u/uvvuu919z507p1mzZql69eqSpKZNm2rWrFlau3at+vTpI5fLpY8//liNGzfW5MmT3YGnZcuWeu211/T5559r4MCBkqR58+ZJkuLi4jxmfoYMGVJsjE2aNNF///d/e4xjw4YNhBuggmPNDYAbzrIsffPNN7r11ltlWZaysrLcv9q2baucnBylpKS4+995553uYCNJnTt3Vq1atbRjxw5JUkpKijIzM9WrVy93sJGk9u3bq2HDhvruu+8kSVlZWdq3b5969OhR7JaWw+EoNs6fByzpYlg6e/ascnJyrr8IAGzDzA2AGy4rK0vZ2dlau3at1q5de8k+RbeSQkJCPPY5HA4FBwcrLS1Nkty/N2jQoNh5GjRooB9++EGS9OOPP0qSGjduXKpx/jIA+fv7S5Kys7Pl5+dXqnMAuPEINwBuOMuyJEl33HGHunfvXmKf0NBQHTt27EYOqxgvr5Int4vGD6BiItwAuOECAgJUvXp1FRYWqk2bNpfsVxRuTp486dFuWZZOnTqlW265RZJUt25dSdKJEyfUunVrj74nTpxw769fv74k6ejRo2VzIQAqJNbcALjhvLy81KlTJ33zzTdKTU0ttv+XX3vw73//W7m5ue7tLVu2KCMjQ+3atZMkhYWFKTAwUF9++aXy8/Pd/Xbs2KHjx4+rffv2ki6GqlatWmnDhg1KT0/3eA1mYwBzMHMDoFwMHjxYe/bs0YQJE9SzZ081atRI586dU0pKinbv3q0PP/zQ3dff318TJ05UdHS0MjMz9fnnnys4OFg9e/aUJHl7e2vIkCF699139dJLL6lbt25yOp364osvVLduXY/HyocPH66JEyfq2WefdT8KnpaWpu+++04zZsy44XUAUPYINwDKRVBQkKZNm6alS5fqm2++0erVq1WzZk01bty42GPZ/fr103/+8x8tX75cubm5ioyM1MiRIz0+TC86Olq+vr5asWKFPv74Y1WtWlUdOnTQ0KFD3QuTpYuPd0+dOlVLlizRl19+qQsXLqhu3brq0qXLDbt2APZyWMzFAqigij6h+KmnnlLnzp3LezgAKgnW3AAAAKMQbgAAgFEINwAAwCisuQEAAEZh5gYAABiFcAMAAIxCuAEAAEYh3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGOX/AbAci2SfVKQaAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "keys = set(s.split('/')[1] for s in df_hist.columns if '/' in s)\n", + "for k in keys: \n", + " df_hist[[c for c in df_hist.columns if c.endswith(k)]].plot(title=k)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "# df_hist[['val/acc', 'train/acc']].plot()\n", + "\n", + "# # df_hist[['val/f1', 'train/f1']].plot()\n", + "\n", + "# # df_hist[['val/roc_auc_bc', 'train/roc_auc_bc']].plot()\n", + "\n", + "# # df_hist[['val/roc_auc_mc', 'train/roc_auc_mc']].plot()\n", + "\n", + "# df_hist[['val/loss', 'train/loss']].plot()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Predict" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "2fc6345d9ee040f7bf2d8145310add00", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Predicting: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dl_test = dm.test_dataloader()\n", + "y_test_pred = trainer.predict(net, dl_test)\n", + "y_test_pred = np.concatenate(y_test_pred)\n", + "# y_test_pred" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2000, 3000)" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# y_test_pred.shape, df_test.shape\n", + "dm.val_split, dm.test_split" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "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", + "
desired_answerinputlietrue_answerans1ans2truedir_trueansprob_predllm_ans
3000FalseMy husband was very pleased with this gift to ...True10.8369140.99414110.1572270.91552710.836914
3001TrueThis is simply the best book ever written and ...False10.7148440.4719241-0.2429200.59326200.714844
3002FalseI finally found this baster and we love it. It...True10.9663090.96630910.0000000.96630910.966309
3003Truethses guys rock, and the vocals are 2nd to..we...False10.9213870.8847661-0.0366210.90332010.921387
3004FalseI bought these and wrote a review before - the...True10.5996090.3957521-0.2038570.49755900.599609
....................................
3995FalseAs others have said, the instructions were not...False00.1799320.21179200.0318600.19580100.179932
3996TrueThis book has great potential but it doesn't l...True00.0325620.03729200.0047300.03491200.032562
3997TrueI was intending to use beta sitosterol for hai...False10.9404300.94238310.0019530.94140610.940430
3998FalseThis is really compact and comes with 3 bags t...True10.9633790.9418951-0.0214840.95263710.963379
3999TrueI bought the paperback because it sounded inte...False10.9985350.9970701-0.0014650.99804710.998535
\n", + "

1000 rows × 11 columns

\n", + "
" + ], + "text/plain": [ + " desired_answer input \n", + "3000 False My husband was very pleased with this gift to ... \\\n", + "3001 True This is simply the best book ever written and ... \n", + "3002 False I finally found this baster and we love it. It... \n", + "3003 True thses guys rock, and the vocals are 2nd to..we... \n", + "3004 False I bought these and wrote a review before - the... \n", + "... ... ... \n", + "3995 False As others have said, the instructions were not... \n", + "3996 True This book has great potential but it doesn't l... \n", + "3997 True I was intending to use beta sitosterol for hai... \n", + "3998 False This is really compact and comes with 3 bags t... \n", + "3999 True I bought the paperback because it sounded inte... \n", + "\n", + " lie true_answer ans1 ans2 true dir_true ans \n", + "3000 True 1 0.836914 0.994141 1 0.157227 0.915527 \\\n", + "3001 False 1 0.714844 0.471924 1 -0.242920 0.593262 \n", + "3002 True 1 0.966309 0.966309 1 0.000000 0.966309 \n", + "3003 False 1 0.921387 0.884766 1 -0.036621 0.903320 \n", + "3004 True 1 0.599609 0.395752 1 -0.203857 0.497559 \n", + "... ... ... ... ... ... ... ... \n", + "3995 False 0 0.179932 0.211792 0 0.031860 0.195801 \n", + "3996 True 0 0.032562 0.037292 0 0.004730 0.034912 \n", + "3997 False 1 0.940430 0.942383 1 0.001953 0.941406 \n", + "3998 True 1 0.963379 0.941895 1 -0.021484 0.952637 \n", + "3999 False 1 0.998535 0.997070 1 -0.001465 0.998047 \n", + "\n", + " prob_pred llm_ans \n", + "3000 1 0.836914 \n", + "3001 0 0.714844 \n", + "3002 1 0.966309 \n", + "3003 1 0.921387 \n", + "3004 0 0.599609 \n", + "... ... ... \n", + "3995 0 0.179932 \n", + "3996 0 0.032562 \n", + "3997 1 0.940430 \n", + "3998 1 0.963379 \n", + "3999 1 0.998535 \n", + "\n", + "[1000 rows x 11 columns]" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_test = dm.df_infos.iloc[dm.test_split:].copy()\n", + "df_test['prob_pred'] = y_test_pred.argmax(-1)\n", + "df_test['llm_ans'] = (df_test['ans1']+df_test['ans1'])/2\n", + "df_test" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "y_true = dl_test.dataset.tensors[2].numpy()\n", + "assert ((df_test['true_answer'].values>0.5)==(y_true>0.5)).all(), 'check it all lines up'" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.516" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "((df_test['llm_ans']>0.5)==df_test['desired_answer']).mean()" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "lightning model acc at predicting truth: 92.80%\n" + ] + } + ], + "source": [ + "# this must be wrong\n", + "acc_truth = (df_test['prob_pred']==df_test['true_answer']).mean()\n", + "print(f\"lightning model acc at predicting truth: {acc_truth:2.2%}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "this should be 50% as we are not training it to do this\n", + "lightning model acc at predicting desired answer (including instructions to lie): 49.80%\n" + ] + } + ], + "source": [ + "acc_truth = (df_test['prob_pred']==df_test['desired_answer']).mean()\n", + "print('this should be 50% as we are not training it to do this')\n", + "print(f\"lightning model acc at predicting desired answer (including instructions to lie): {acc_truth:2.2%}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "lightning model acc at predicting the models public answer: 88.40%\n" + ] + } + ], + "source": [ + "acc_truth = (df_test['prob_pred']==(df_test['llm_ans']>0.5)).mean()\n", + "print(f\"lightning model acc at predicting the models public answer: {acc_truth:2.2%}\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OK this doesn't work because for the CSS loss to work, it must add up to 1... ours does not" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dlk2", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/020_ds.ipynb b/notebooks/020_ds.ipynb index feac8ff..f6c44e5 100644 --- a/notebooks/020_ds.ipynb +++ b/notebooks/020_ds.ipynb @@ -26,9 +26,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'4.30.1'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "\n", "import copy\n", @@ -104,18 +115,95 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "===================================BUG REPORT===================================\n", + "Welcome to bitsandbytes. For bug reports, please run\n", + "\n", + "python -m bitsandbytes\n", + "\n", + " and submit this information together with your error trace to: https://github.com/TimDettmers/bitsandbytes/issues\n", + "================================================================================\n", + "bin /home/ubuntu/mambaforge/envs/dlk2/lib/python3.9/site-packages/bitsandbytes/libbitsandbytes_cuda117.so\n", + "CUDA SETUP: CUDA runtime path found: /home/ubuntu/mambaforge/envs/dlk2/lib/libcudart.so.11.0\n", + "CUDA SETUP: Highest compute capability among GPUs detected: 8.6\n", + "CUDA SETUP: Detected CUDA version 117\n", + "CUDA SETUP: Loading binary /home/ubuntu/mambaforge/envs/dlk2/lib/python3.9/site-packages/bitsandbytes/libbitsandbytes_cuda117.so...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/ubuntu/mambaforge/envs/dlk2/lib/python3.9/site-packages/bitsandbytes/cuda_setup/main.py:149: UserWarning: Found duplicate ['libcudart.so', 'libcudart.so.11.0', 'libcudart.so.12.0'] files: {PosixPath('/home/ubuntu/mambaforge/envs/dlk2/lib/libcudart.so.11.0'), PosixPath('/home/ubuntu/mambaforge/envs/dlk2/lib/libcudart.so')}.. We'll flip a coin and try one of these, in order to fail forward.\n", + "Either way, this might cause trouble in the future:\n", + "If you get `CUDA error: invalid device function` errors, the above might be the cause and the solution is to make sure only one ['libcudart.so', 'libcudart.so.11.0', 'libcudart.so.12.0'] in the paths that we search based on your env.\n", + " warn(msg)\n" + ] + } + ], "source": [ "from peft import PeftModel" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GPTBigCodeConfig {\n", + " \"_name_or_path\": \"WizardLM/WizardCoder-15B-V1.0\",\n", + " \"activation_function\": \"gelu\",\n", + " \"architectures\": [\n", + " \"GPTBigCodeForCausalLM\"\n", + " ],\n", + " \"attention_softmax_in_fp32\": true,\n", + " \"attn_pdrop\": 0.1,\n", + " \"bos_token_id\": 0,\n", + " \"embd_pdrop\": 0.1,\n", + " \"eos_token_id\": 0,\n", + " \"inference_runner\": 0,\n", + " \"initializer_range\": 0.02,\n", + " \"layer_norm_epsilon\": 1e-05,\n", + " \"max_batch_size\": null,\n", + " \"max_sequence_length\": null,\n", + " \"model_type\": \"gpt_bigcode\",\n", + " \"multi_query\": true,\n", + " \"n_embd\": 6144,\n", + " \"n_head\": 48,\n", + " \"n_inner\": 24576,\n", + " \"n_layer\": 40,\n", + " \"n_positions\": 8192,\n", + " \"pad_key_length\": true,\n", + " \"pre_allocate_kv_cache\": false,\n", + " \"resid_pdrop\": 0.1,\n", + " \"scale_attention_softmax_in_fp32\": true,\n", + " \"scale_attn_weights\": true,\n", + " \"summary_activation\": null,\n", + " \"summary_first_dropout\": 0.1,\n", + " \"summary_proj_to_labels\": true,\n", + " \"summary_type\": \"cls_index\",\n", + " \"summary_use_proj\": true,\n", + " \"torch_dtype\": \"float16\",\n", + " \"transformers_version\": \"4.30.1\",\n", + " \"use_cache\": true,\n", + " \"validate_runner_input\": true,\n", + " \"vocab_size\": 49153\n", + "}\n", + "\n" + ] + } + ], "source": [ "# leaderboard https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard\n", "model_options = dict(\n", @@ -175,18 +263,63 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "GPTBigCodeForCausalLM(\n", + " (transformer): GPTBigCodeModel(\n", + " (wte): Embedding(49153, 6144)\n", + " (wpe): Embedding(8192, 6144)\n", + " (drop): Dropout(p=0.1, inplace=False)\n", + " (h): ModuleList(\n", + " (0-39): 40 x GPTBigCodeBlock(\n", + " (ln_1): LayerNorm((6144,), eps=1e-05, elementwise_affine=True)\n", + " (attn): GPTBigCodeAttention(\n", + " (c_attn): Linear4bit(in_features=6144, out_features=6400, bias=True)\n", + " (c_proj): Linear4bit(in_features=6144, out_features=6144, bias=True)\n", + " (attn_dropout): Dropout(p=0.1, inplace=False)\n", + " (resid_dropout): Dropout(p=0.1, inplace=False)\n", + " )\n", + " (ln_2): LayerNorm((6144,), eps=1e-05, elementwise_affine=True)\n", + " (mlp): GPTBigCodeMLP(\n", + " (c_fc): Linear4bit(in_features=6144, out_features=24576, bias=True)\n", + " (c_proj): Linear4bit(in_features=24576, out_features=6144, bias=True)\n", + " (act): GELUActivation()\n", + " (dropout): Dropout(p=0.1, inplace=False)\n", + " )\n", + " )\n", + " )\n", + " (ln_f): LayerNorm((6144,), eps=1e-05, elementwise_affine=True)\n", + " )\n", + " (lm_head): Linear(in_features=6144, out_features=49153, bias=False)\n", + ")" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "model" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "49152\n" + ] + } + ], "source": [ "# https://github.com/deep-diver/LLM-As-Chatbot/blob/main/models/falcon.py\n", "print(tokenizer.pad_token_id)\n", @@ -205,9 +338,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "40\n" + ] + }, + { + "data": { + "text/plain": [ + "((2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38), 40)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Params\n", "# N_SAMPLES = 4000\n", @@ -234,9 +385,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(15272, 18502)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# get the tokens for 0 and 1, we will use these later...\n", "# note that sentancepeice tokenizers have differen't tokens for No and \\nNo.\n", @@ -258,9 +420,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Found cached dataset amazon_polarity (/home/ubuntu/.cache/huggingface/datasets/amazon_polarity/amazon_polarity/3.0.0/a27b32b7e7b88eb274a8fa8ba0f654f1fe998a87c22547557317793b5d2772dc)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d2c6c53a68564f9a867c517a3e26719a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/2 [00:00