From 77bf491aa63874a89c86758354bce392af626c1d Mon Sep 17 00:00:00 2001 From: Felix Mucha <3016498@stud.hs-mannheim.de> Date: Mon, 27 Jan 2025 07:11:32 +0100 Subject: [PATCH] extended ml pipeline, todo: model architecture --- transformer.py => transformer_1a.py | 9 +- transformer_1b.py | 199 +++++++++++++++ transformer_evaluation.ipynb | 363 ++++++++++++++++++++++++++++ 3 files changed, 570 insertions(+), 1 deletion(-) rename transformer.py => transformer_1a.py (96%) create mode 100644 transformer_1b.py create mode 100644 transformer_evaluation.ipynb diff --git a/transformer.py b/transformer_1a.py similarity index 96% rename from transformer.py rename to transformer_1a.py index 01faaac..bc8de3e 100644 --- a/transformer.py +++ b/transformer_1a.py @@ -42,6 +42,13 @@ import time import torchvision torchvision.disable_beta_transforms_warning() + +def get_device(verbose=False): + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + if verbose: + print('Using device:', device) + return device + # Test if GPU is available DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu') print('Using device:', DEVICE) @@ -69,7 +76,7 @@ def pad_sequences(sequences, MAX_LEN): class HumorDataset(torch.utils.data.Dataset): def __init__(self, encodings, labels): self.encodings = encodings - self.labels = labels + self.labels = labels.reset_index(drop=True) def __getitem__(self, idx): item = {'input_ids': torch.tensor(self.encodings[idx], dtype=torch.float)} diff --git a/transformer_1b.py b/transformer_1b.py new file mode 100644 index 0000000..05ffd62 --- /dev/null +++ b/transformer_1b.py @@ -0,0 +1,199 @@ +""" +This file contains the transformer model. +""" + + +# TODO refactor the code +# TODO create ml helper script +# TODO create ml evaluation script + +# TODO track overfitting better +# TODO validate model in training (accuracy, loss, etc) + +# TODO set length to a constant value which is the max length of the sentences or nearly + + +# TODO user gloVe embeddings + +#TODO: add attention mask +# TODO: add positional encoding +#TODO: add dropout (if needed) + +import time +import json + +import numpy as np +import torch +import torch.nn as nn +import torch.optim as optim +from torch.utils.data import DataLoader +from transformers import AdamW + +from sklearn.metrics import accuracy_score + +import ml_helper +import ml_history + +class TransformerBinaryClassifier(nn.Module): + def __init__(self, vocab_size, embed_dim, num_heads, num_layers, hidden_dim, dropout=0.1): + super(TransformerBinaryClassifier, self).__init__() + self.embedding = nn.Embedding(vocab_size, embed_dim) + self.transformer = nn.Transformer(embed_dim, num_heads, num_layers, num_layers, hidden_dim, dropout) + self.fc = nn.Linear(embed_dim, 1) + self.sigmoid = nn.Sigmoid() + + def forward(self, input_ids): + input_ids = input_ids.long() + embedded = self.embedding(input_ids) + transformer_output = self.transformer(embedded, embedded) + pooled_output = transformer_output.mean(dim=1) + logits = self.fc(pooled_output) + return self.sigmoid(logits) + + + +if __name__ == "__main__": + + # Load the data + data_path = 'data/idx_based_padded' + + train_dataset = torch.load(data_path + '/train.pt') + test_dataset = torch.load(data_path + '/test.pt') + val_dataset = torch.load(data_path + '/val.pt') + + # +2 for padding and unk tokens + vocab_size = train_dataset.vocab_size + 2 + embed_dim = 100 #train_dataset.emb_dim + + # NOTE: Info comes from data explore notebook: 280 is max length, + # 139 contains 80% and 192 contains 95% of the data + max_len = 280 + + device = ml_helper.get_device(verbose=True) + + # Model hyperparameters + num_heads = 2 + num_layers = 2 + hidden_dim = 256 + + model = TransformerBinaryClassifier(vocab_size, embed_dim, num_heads, num_layers, hidden_dim) + + # Training parameters + epochs = 3 #3 + batch_size = 8 + learning_rate = 2e-5 + + # Optimizer and loss function + optimizer = AdamW(model.parameters(), lr=learning_rate) + criterion = nn.BCEWithLogitsLoss() + + + # Data loaders + train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) + test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False) + val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False) + + + ################################################################################################ + # Training + ################################################################################################ + + # Initialize the history + history = ml_history.History() + + # Model to device + model.to(device) + + print("Starting training...") + start_training_time = time.time() + + # Training loop + model.train() + for epoch in range(epochs): + # init batch tracking + epoch_start_time = time.time() + history.batch_reset() + + for batch in train_loader: + optimizer.zero_grad() + # prepare batch + input_ids = batch['input_ids'].to(device) + labels = batch['labels'].unsqueeze(1).to(device) + # forward pass + outputs = model(input_ids) + loss = criterion(outputs, labels) + # backward pass + loss.backward() + optimizer.step() + # calculate accuracy train + preds = outputs.round() + train_acc = accuracy_score(labels.cpu().detach().numpy(), + preds.cpu().detach().numpy()) + # update batch history + history.batch_update_train(loss.item(), train_acc) + + # calculate accuracy val + model.eval() + with torch.no_grad(): + for val_batch in val_loader: + val_input_ids = val_batch['input_ids'].to(device) + val_labels_batch = val_batch['labels'].unsqueeze(1).to(device) + val_outputs = model(val_input_ids) + val_acc = accuracy_score(val_outputs.round().cpu().numpy(), + val_labels_batch.cpu().numpy()) + history.batch_update_val(val_acc) + model.train() + + # update epoch history + history.update() + + epoch_end_time = time.time() + + print(f"Epoch {epoch + 1}/{epochs}, Time: {epoch_end_time - epoch_start_time:.2f} sec, Loss: {history.history['loss'][-1]:.4f}, Train Acc: {history.history['train_acc'][-1]:.4f}, Val Acc: {history.history['val_acc'][-1]:.4f}") + + end_training_time = time.time() + print(f"Training finished in {end_training_time - start_training_time:.2f} seconds") + + + ################################################################################################ + # Evaluation + ################################################################################################ + print("Starting evaluation...") + + model.eval() + predictions, true_labels = [], [] + with torch.no_grad(): + for batch in test_loader: + input_ids = batch['input_ids'].to(device) + labels = batch['labels'].unsqueeze(1).to(device) + + outputs = model(input_ids) + preds = outputs.round() + predictions.extend(preds.cpu().numpy()) + true_labels.extend(labels.cpu().numpy()) + + accuracy = accuracy_score(true_labels, predictions) + print(f"Accuracy: {accuracy}") + + + ################################################################################################ + # Save model and hyperparameters + ################################################################################################ + timestamp = time.strftime("%Y%m%d-%H%M%S") + + ml_helper.save_model_and_hyperparameters(model, 'transformer', accuracy, timestamp, + max_len=max_len, + vocab_size=vocab_size, + embed_dim=embed_dim, + num_heads=num_heads, + num_layers=num_layers, + hidden_dim=hidden_dim, + epochs=epochs, + batch_size=batch_size, + learning_rate=learning_rate) + + #save history + + history_path = f'models/transformer_history_{timestamp}.json' + with open(history_path, 'w') as f: + json.dump(history.get_history(), f) \ No newline at end of file diff --git a/transformer_evaluation.ipynb b/transformer_evaluation.ipynb new file mode 100644 index 0000000..412f20e --- /dev/null +++ b/transformer_evaluation.ipynb @@ -0,0 +1,363 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import json\n", + "import numpy as np\n", + "import os\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import ml_helper" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# TODO: \n", + "- clean and refactor maybe ml_plot.py whith plot functions" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading model from: models/transformer_acc_0.5056_20250127-061459.pth\n", + "Loading history from: models/transformer_history_20250127-061459.json\n", + "Loading hyperparameters from: models/transformer_para_acc_0.5056_20250127-061459.json\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\felix\\AppData\\Local\\Temp\\ipykernel_16796\\1644685603.py:5: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model = torch.load(model_path)\n" + ] + } + ], + "source": [ + "# load newest model\n", + "path = 'models/'\n", + "model_path = ml_helper.get_newest_model_path(path)\n", + "print(\"Loading model from: \", model_path)\n", + "model = torch.load(model_path)\n", + "\n", + "# load history\n", + "history_path = ml_helper.get_newest_model_path(path, name=\"history\", extension=\".json\")\n", + "print(\"Loading history from: \", history_path)\n", + "with open(history_path) as f:\n", + " history = json.load(f)\n", + "\n", + "# load hyperparameters\n", + "hyperparameters_path = ml_helper.get_newest_model_path(path, name=\"para\", extension=\".json\")\n", + "print(\"Loading hyperparameters from: \", hyperparameters_path)\n", + "with open(hyperparameters_path) as f:\n", + " params = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "History:\n", + "{\n", + " \"loss\": [\n", + " 0.6977859839254063,\n", + " 0.6934245683644947,\n", + " 0.6932587604291043\n", + " ],\n", + " \"train_acc\": [\n", + " 0.5086032388663968,\n", + " 0.5080971659919028,\n", + " 0.5063259109311741\n", + " ],\n", + " \"val_acc\": [\n", + " 0.5093117408906882,\n", + " 0.5093117408906882,\n", + " 0.5093117408906882\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "# print history\n", + "print(\"History:\")\n", + "print(json.dumps(history, indent=4))" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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SEYPPqLl8uXL+P3330s9yoMebunSpTA3N0e/fv3kLoXoiVq5ciU0Gg3/8yAT9okikpGnp6f0DLD4+HgsWrQIRkZGmDp1qtyl1Qq//vorzp07hx9++AGTJ0/W6RROVJft2bMH586dw+eff47g4GCd53/Sk8PLeUQyGjVqFP766y8kJSVBpVLB398fX3zxBTp27Ch3abWCu7s7kpOTERQUhJ9++omDDFK90b17d2m4jZ9//pnPypMJQxQRERGRHtgnioiIiEgPDFFEREREemDH8mqk1WqRmJgICwsLvZ8GTkRERE+WKIrIzs6Gi4sLFIryzzcxRFWjxMTEKnlWFBERET15169fR8OGDcudzxBVje7dKXT9+vUqeWYUERERVb+srCy4uro+8o5fhqhqdO8SnlqtZogiIiKqZR7VFYcdy4mIiIj0wBBFREREpAeGKCIiIiI9MEQRERER6YEhioiIiEgPDFFEREREemCIIiIiItIDQxQRERGRHhiiiIiIiPTAEEVERESkB4YoIiIiIj0wRBERERHpgQ8grm1EESjOk7sKIiKimsHQFHjEg4KrC0NUbVOcB3zhIncVRERENcMHiYCRmSyb5uU8IiIiIj3wTFRtY2h6N3UTERHR3e9FmTBE1TaCINtpSyIiIvoPL+cRERER6YEhioiIiEgPDFFEREREemCIIiIiItIDQxQRERGRHhiiiIiIiPTAEEVERESkB4YoIiIiIj0wRBERERHpgSGKiIiISA8MUURERER6YIgiIiIi0gNDFBEREZEeGKKIiIiI9MAQRURERKQHhigiIiIiPTBEEREREemBIYqIiIhIDwxRRERERHpgiCIiIiLSA0MUERERkR4YooiIiIj0wBBFREREpAeGKCIiIiI9MEQRERER6YEhioiIiEgPDFFEREREemCIIiIiItKD7CFq4cKFcHd3h7GxMXx9fXHo0KFyl125ciUEQdB5GRsb6ywjiiJmzJgBZ2dnmJiYIDAwEJcvX9ZZ5tixY3j++edhZWUFW1tbjBs3Djk5OTrLJCQk4KWXXoKpqSkcHBzw7rvvoqSkpOp2nIiIiGo1WUPUhg0bEBYWhpkzZ+LYsWNo164dgoKCkJKSUu46arUat27dkl7x8fE68+fMmYMFCxZg8eLFiImJgZmZGYKCglBQUAAASExMRGBgILy8vBATE4Pw8HCcPXsW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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# plot training accuracy vs validation accuracy\n", + "plt.plot(history['train_acc'], label='train_acc')\n", + "plt.plot(history['val_acc'], label='val_acc')\n", + "plt.legend()\n", + "plt.title('Training accuracy vs Validation accuracy')\n", + "plt.xlabel('Epoch')\n", + "plt.ylabel('Accuracy')\n", + "# set y-axis limits to 0-1\n", + "#plt.ylim(0, 1)\n", + "# set x-axis limits to integer steps\n", + "plt.xticks(np.arange(0, len(history['train_acc']), 1))\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(8000, 6)\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "# Load the data from csv\n", + "df = pd.read_csv('data/hack.csv')\n", + "print(df.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\felix\\AppData\\Local\\Temp\\ipykernel_16796\\4202493223.py:4: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " train_dataset = torch.load(data_path + '/train.pt')\n", + "C:\\Users\\felix\\AppData\\Local\\Temp\\ipykernel_16796\\4202493223.py:5: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " test_dataset = torch.load(data_path + '/test.pt')\n", + "C:\\Users\\felix\\AppData\\Local\\Temp\\ipykernel_16796\\4202493223.py:6: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " val_dataset = torch.load(data_path + '/val.pt')\n" + ] + } + ], + "source": [ + "# Load the data\n", + "data_path = 'data/idx_based_padded'\n", + "\n", + "train_dataset = torch.load(data_path + '/train.pt')\n", + "test_dataset = torch.load(data_path + '/test.pt') \n", + "val_dataset = torch.load(data_path + '/val.pt')" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[4679, 52, 2818, 1536, 1298, 3516, 6809, 6992, 5134, 7257, 496, 3880, 3045, 4945, 839, 3997, 2611, 7456, 5910, 599, 788, 7284, 294, 335, 4183, 645, 2612, 4222, 7133, 3622, 6766, 491, 6704, 3430, 6220, 1581, 271, 7851, 2748, 1366, 4286, 7612, 342, 7038, 1094, 896, 1755, 5683, 1095, 289, 6574, 7860, 7906, 6832, 444, 1738, 6571, 685, 464, 1684, 854, 5436, 299, 3441, 6199, 3797, 430, 6532, 6440, 3413, 5855, 173, 2945, 356, 1018, 1854, 6855, 3825, 1288, 6152, 735, 7049, 879, 2335, 6883, 321, 4095, 631, 6182, 3383, 7615, 4858, 2577, 7149, 1054, 1142, 2302, 7068, 3858, 3917, 4300, 504, 1994, 7161, 175, 1570, 4595, 5265, 7998, 2438, 7450, 3427, 5411, 7241, 2795, 2970, 6584, 6375, 3074, 6945, 4783, 4079, 3703, 7331, 4521, 5268, 2222, 3474, 1286, 3590, 1965, 2323, 1424, 2614, 5417, 118, 6754, 7114, 4898, 4767, 7341, 7314, 6039, 3560, 4557, 2651, 787, 7785, 4139, 3731, 7227, 3318, 2322, 6021, 3783, 1005, 7629, 2604, 5006, 7349, 3252, 5405, 1421, 4297, 1712, 3230, 570, 7472, 1921, 2500, 2400, 2716, 5821, 5770, 1961, 7107, 535, 2013, 4765, 5812, 4995, 1829, 7806, 6496, 5457, 5180, 2996, 708, 3562, 721, 2404, 7099, 4674, 26, 4147, 1547, 398, 7289, 575, 7447, 2387, 3892, 4706, 5032, 2693, 5541, 6982, 7807, 4502, 782, 1400, 2680, 5566, 3125, 4195, 6023, 804, 4226, 3701, 7751, 1826, 2953, 5423, 2114, 7468, 686, 5671, 5013, 4471, 3303, 7779, 7996, 5092, 4607, 1809, 2274, 6089, 252, 7677, 2870, 998, 1041, 3824, 1746, 5792, 5502, 7098, 4526, 533, 6479, 4180, 7384, 1010, 5131, 7881, 4584, 2971, 2421, 4279, 1226, 828, 7655, 53, 6655, 1893, 1210, 3359, 3800, 5328, 6912, 1272, 3058, 3971, 370, 1392, 2325, 3739, 640, 274, 861, 3732, 3656, 4323, 3602, 3604, 2790, 5453, 1901, 6834, 4169, 5995, 3158, 5540, 7360, 895, 5672, 6785, 3364, 6047, 2187, 7877, 5517, 4369, 7104, 4230, 2165, 1919, 2224, 521, 1725, 4662, 7231, 4558, 2771, 3874, 1959, 1007, 3947, 6991, 1945, 527, 1046, 1462, 2582, 1844, 6872, 7428, 2810, 2778, 5001, 2248, 5248, 7957, 1677, 4141, 6626, 5185, 6155, 1313, 7744, 1601, 3070, 4247, 2601, 7935, 5119, 4958, 6729, 2781, 7065, 280, 2410, 3040, 7196, 7146, 351, 6198, 5903, 1114, 4076, 3844, 6596, 1816, 3195, 3061, 4891, 6974, 7753, 5886, 914, 5303, 7101, 1932, 1450, 4968, 2661, 4206, 1323, 6573, 2871, 338, 471, 1834, 5165, 2496, 2066, 1623, 6697, 6549, 563, 2857, 2315, 7517, 4041, 7608, 2004, 413, 2361, 2739, 7578, 5477, 4021, 88, 7631, 6187, 6265, 3808, 4396, 7722, 1696, 1796, 868, 1719, 5290, 4979, 51, 1173, 3846, 5837, 6183, 3959, 691, 3990, 1482, 6743, 6640, 7217, 5275, 5726, 2458, 2018, 1470, 4993, 2342, 805, 5118, 293, 6826, 2815, 517, 6083, 4978, 7458, 7981, 6110, 2829, 6347, 7326, 1880, 7551, 75, 3818, 5974, 2811, 2253, 7984, 4773, 649, 5721, 2295, 2562, 1303, 2110, 4661, 3855, 2402, 3674, 408, 2766, 2607, 1886, 5998, 1045, 4592, 2622, 5673, 5982, 2154, 7294, 3047, 7976, 6273, 6784, 174, 4976, 419, 2277, 2907, 1941, 3723, 96, 2145, 1123, 3044, 6846, 6210, 5042, 3184, 3623, 1097, 6905, 5104, 4806, 5575, 4505, 461, 5031, 4889, 5569, 5985, 6814, 2494, 3270, 1192, 5396, 541, 3775, 4372, 5253, 7054, 1753, 7890, 7316, 3630, 6415, 6524, 7893, 6325, 2416, 791, 6939, 7363, 4047, 6258, 3285, 4816, 3367, 6162, 3612, 4090, 1675, 3619, 7809, 5142, 5737, 5746, 1071, 6698, 4170, 1670, 4102, 3795, 1975, 7831, 6913, 4199, 2451, 2668, 392, 1904, 425, 3745, 1827, 104, 4099, 3433, 4352, 4772, 7500, 7410, 4445, 3585, 3206, 4078, 2017, 160, 4177, 435, 810, 3981, 7882, 2553, 1408, 3845, 1477, 7662, 6173, 5712, 2469, 1356, 572, 212, 483, 2521, 1646, 607, 1543, 3979, 5946, 1236, 2626, 2896, 7453, 3282, 4975, 5140, 3241, 3097, 2289, 6748, 6003, 7011, 7936, 2456, 1944, 4729, 7115, 6142, 5452, 170, 6029, 7688, 5764, 98, 121, 1296, 584, 7846, 1277, 3678, 6838, 3436, 5213, 5623, 5948, 2793, 187, 3894, 3748, 5775, 1479, 192, 3021, 2566, 2053, 5460, 5522, 5363, 1928, 5506, 3698, 3329, 704, 2950, 6121, 1516, 3694, 3396, 2300, 6365, 7192, 2450, 2003, 7703, 6275, 3400, 6840, 520, 4888, 2974, 7509, 5227, 4810, 2430, 2436, 1653, 3470, 4293, 5596, 2380, 2000, 3599, 3676, 1988, 6291, 6296, 662, 6869, 11, 1528, 699, 2149, 1092, 3511, 7372, 5138, 7839, 7411, 3357, 5445, 3851, 4249, 2933, 6779, 6133, 4173, 312, 2391, 3390, 1982, 4233, 2667, 6776, 4787, 4273, 3912, 6836, 7771, 1857, 2372, 440, 3522, 3692, 6623, 2129, 3982, 360, 3145, 2976, 909, 2014, 5639, 3378, 2185, 3886, 660, 5641, 1812, 410, 473, 5677, 612, 7197, 4907, 3542, 3566, 6928, 5594, 2827, 7006, 2530, 2932, 2287, 1150, 7402, 4758, 3297, 6242, 2111, 715, 6463, 4067, 1568, 3742, 1059, 6107, 6287, 3726, 4332, 4793, 646, 7665, 7090, 4017, 6818, 6887, 7635, 5865, 7426, 4213, 5657, 6512, 7484, 5669, 677, 4623, 6473, 2231, 4616, 7273, 1923, 5277, 2393, 5009, 7880, 159, 4962, 6715, 2064, 7357, 6631, 3751, 5014, 4653, 5229, 5038, 4702, 2645, 7203, 0, 2557, 7080, 6527, 2216, 5375, 5486, 4050, 4508, 3514, 624, 5495, 1741, 3734, 3407, 1324, 2940, 3254, 2516, 6540, 1322, 2546, 4693, 2918, 6849, 605, 6059, 5161, 5568, 5488, 2883, 4312, 3822, 1406, 6079, 5026, 883, 1897, 1984, 3138, 5174, 80, 3746, 1129, 1057, 6866, 1216, 2365, 7442, 3275, 3095, 1409, 1222, 2646, 143, 4456, 4920, 3840, 4154, 2418, 4637, 3446, 1178, 4296, 3908, 6663, 2814, 4192, 5202, 5542, 1821, 5286, 6374, 7158, 6628, 552, 1940, 6333, 2459, 7465, 916, 120, 2329, 5767, 7094, 4346, 7919, 2999, 202, 287, 4582, 7153, 5007, 3993, 2992, 3333, 4015, 3756, 973, 3178, 45, 1063, 4681, 5256, 6284, 279, 2603, 692, 534, 7131, 2364, 548, 5081, 4028, 1776, 765, 1176, 5999, 1599, 3132, 4708, 2381, 1999, 3422, 7723, 3071, 2123, 7174, 7355, 1066, 6283, 3787, 5497, 6514, 7342, 5043, 4840, 426, 4269, 6192, 3487, 5705, 5778, 7031, 5068, 2091, 7425, 5302, 2615, 5549, 4515, 3077, 6212, 6936, 6890, 110, 4080, 4137, 357, 536, 7968, 6012, 1326, 2001, 5724, 139, 7037, 6289, 4472, 515, 5172, 4335, 4319, 3343, 7588, 7139, 6827, 5305, 1877, 625, 3476, 3557, 4589, 6870, 4356, 2285, 2670, 5388, 1795, 7255, 2807, 2207, 4101, 1602, 453, 2800, 2122, 6005, 1463, 6323, 6492, 128, 3453, 5491, 5928, 995, 6386, 5845, 4035, 667, 7154, 3092, 7254, 5310, 3039, 2535, 5315, 6707, 6070, 1360, 797, 990, 219, 877, 886, 1445, 2252, 2620, 5858, 4617, 352, 6075, 6606, 2838, 1870, 339, 7163, 4026, 2895, 6180, 4446, 878, 2321, 5835, 3276, 4731, 5273, 5711, 1553, 2659, 6307, 3399, 849, 2968, 5331, 7074, 6132, 2592, 1035, 7729, 1584, 6769, 4562, 6580, 7765, 3708, 249, 7379, 7335, 1779, 4196, 7172, 463, 1526, 5283, 3588, 5344, 3747, 6014, 1544, 6114, 7455, 2740, 7520, 4678, 3969, 4437, 1614, 5820, 3465, 3528, 7640, 1605, 3946, 4660, 6349, 4658, 6521, 6096, 2368, 2281, 420, 3790, 1524, 7202, 4251, 396, 7717, 2831, 7778, 5563, 1509, 3712, 427, 1076, 4324, 3104, 5685, 1887, 7696, 5483, 6774, 6143, 6447, 4719, 3110, 993, 3803, 6222, 3083, 2653, 5512, 412, 1373, 6798, 2010, 1852, 3188, 888, 6943, 775, 2164, 3725, 12, 5205, 5062, 2359, 6299, 2943, 1257, 1661, 4449, 6915, 3228, 2088, 2888, 4930, 710, 1435, 7144, 1269, 2821, 5372, 7800, 1438, 3773, 1782, 4651, 845, 6363, 5267, 6478, 2789, 988, 903, 4402, 5190, 549, 4887, 7300, 688, 3091, 6031, 3777, 3352, 2497, 3571, 6450, 2463, 1582, 7056, 841, 284, 5525, 7572, 6865, 907, 7715, 5757, 3888, 7234, 4082, 4061, 4350, 608, 1383, 3052, 586, 3764, 6911, 1813, 7686, 6253, 2188, 3553, 7351, 6072, 4634, 7754, 1918, 7221, 7808, 2317, 6904, 4190, 2377, 1428, 3681, 6935, 2046, 5853, 1362, 4866, 925, 329, 2642, 3269, 1472, 1025, 5094, 3202, 264, 5039, 5093, 7191, 1003, 6428, 2332, 873, 5281, 7267, 6797, 6361, 4210, 3915, 6424, 3023, 1036, 5056, 1032, 5597, 6575, 3397, 7939, 4883, 5827, 4484, 1505, 872, 6858, 3085, 3289, 3057, 2644, 5583, 7685, 3398, 6964, 5661, 7190, 7941, 1357, 967, 3547, 6122, 4517, 6882, 2559, 6821, 6041, 4311, 1750, 2873, 7768, 2100, 5838, 7600, 2975, 6926, 1672, 5097, 2171, 758, 5476, 2656, 6322, 6847, 5235, 4092, 4083, 2247, 1200, 5739, 4104, 1414, 1873, 1637, 2191, 862, 1801, 1862, 6423, 5587, 3666, 6309, 99, 4555, 3140, 6244, 7888, 1761, 7734, 7622, 3934, 1542, 1766, 298, 5410, 3382, 3652, 7815, 3283, 4232, 6400, 5723, 367, 5888, 3129, 4845, 7182, 2292, 3540, 1125, 1845, 6542, 6038, 2880, 4791, 1702, 6659, 3663, 502, 3700, 2306, 1701, 3500, 6639, 2826, 4944, 4440, 7940, 5099, 5300, 7270, 2441, 3121, 714, 3857, 4000, 7943, 7275, 576, 3546, 1864, 6161, 3488, 2969, 1728, 36, 3348, 2660, 4091, 5101, 4414, 6380, 3767, 734, 1745, 136, 6503, 4182, 451, 737, 343, 6565, 2235, 376, 4370, 955, 7076, 3654, 6373, 3702, 1068, 7937, 3704, 7533, 5072, 3966, 5440, 1267, 7775, 5429, 6353, 5077, 7735, 1103, 7847, 5404, 3518, 5688, 3009, 779, 2725, 3620, 5178, 3758, 1270, 832, 833, 5327, 6523, 3879, 3584, 5520, 7726, 5925, 4453, 2453, 3054, 1056, 4393, 4905, 585, 4171, 184, 5263, 7598, 3601, 5635, 2606, 4735, 1574, 5643, 4454, 6507, 6701, 3907, 7443, 6768, 3548, 6208, 3305, 6812, 1256, 2101, 7574, 2303, 2012, 6735, 689, 2698, 581, 4184, 373, 6825, 6388, 7046, 639, 3389, 134, 1367, 1694, 7862, 5091, 5130, 1388, 123, 3648, 7303, 6176, 4602, 4843, 3696, 4105, 6633, 6131, 5432, 3534, 668, 620, 7556, 5412, 162, 4700, 4980, 3151, 2370, 5170, 4828, 4275, 7660, 2567, 5803, 2794, 5890, 7169, 2904, 3809, 3143, 1132, 3960, 4444, 789, 740, 6272, 6922, 277, 4875, 7667, 6197, 4664, 3668, 3424, 1466, 2351, 6350, 1203, 3716, 3974, 4145, 7870, 1974, 812, 7616, 5658, 7746, 2511, 6938, 3572, 7226, 3317, 1247, 7788, 5926, 663, 189, 6637, 7749, 1325, 2291, 2262, 3478, 2549, 2635, 2911, 7694, 627, 3743, 1437, 7950, 6737, 2211, 6164, 7271, 3450, 1606, 729, 5620, 1765, 3153, 6893, 1107, 3930, 1037, 3865, 3159, 4340, 4365, 6098, 5284, 7619, 6058, 3056, 616, 4038, 4955, 7772, 1368, 866, 142, 6160, 3207, 6217, 6449, 4585, 4097, 2703, 1722, 3172, 4098, 4570, 380, 4692, 5538, 1863, 2928, 6598, 265, 5544, 7521, 5297, 6360, 5087, 5760, 6237, 2937, 5151, 6293, 2327, 5733, 4481, 5383, 7145, 7437, 4451, 2362, 947, 70, 890, 7071, 4825, 388, 2193, 4384, 4686, 6612, 2347, 416, 4361, 2726, 2786, 6420, 1353, 3035, 4046, 3260, 546, 4727, 2591, 5338, 7501, 767, 5993, 6946, 5381, 7423, 4998, 6312, 2847, 7160, 3975, 4544, 6845, 6355, 7477, 7595, 2076, 4885, 7198, 4911, 6597, 553, 6150, 7399, 4148, 7343, 2319, 1061, 3406, 1026, 4037, 4314, 5644, 6044, 5240, 4913, 5704, 4052, 2378, 5254, 177, 2956, 2426, 3885, 2009, 4309, 4533, 1888, 6102, 97, 5382, 6851, 7907, 2799, 3563, 5650, 4008, 4152, 7089, 6378, 5793, 1141, 6839, 1789, 5660, 2251, 7857, 117, 3120, 5040, 2845, 1207, 4546, 1650, 4318, 1951, 7004, 4208, 1846, 2024, 4496, 6568, 5461, 1638, 5368, 4339, 2552, 7661, 2964, 5220, 7983, 5627, 701, 7917, 1802, 6345, 4850, 1053, 2508, 5629, 6599, 5059, 5932, 1023, 1081, 2043, 770, 2564, 4881, 7403, 7020, 2373, 7474, 5744, 4175, 6027, 82, 6852, 4847, 1396, 1754, 1163, 7354, 4254, 7789, 2672, 2665, 3921, 7579, 6758, 7953, 5244, 7164, 5304, 7597, 6559, 4218, 2268, 6077, 2286, 1957, 2296, 7756, 2914, 2392, 5110, 59, 5633, 3796, 5044, 3815, 3583, 7664, 2107, 557, 3462, 4349, 6617, 6534, 2711, 6362, 2348, 5150, 2695, 4673, 1929, 4523, 2734, 6136, 591, 6541, 3111, 2217, 2960, 1278, 748, 216, 1284, 519, 6517, 1153, 7181, 4588, 3964, 7690, 7075, 7352, 4781, 4316, 638, 5323, 1649, 4935, 1453, 3901, 4127, 7836, 3860, 6238, 73, 4577, 5245, 489, 7218, 5943, 1070, 1925, 4329, 3150, 4053, 2390, 5527, 5602, 3452, 1682, 1572, 3259, 3479, 7362, 3784, 6158, 490, 2344, 2428, 4288, 4656, 1495, 6667, 5915, 4473, 2618, 6602, 1327, 6609, 2213, 7194, 1379, 1640, 5352, 30, 2634, 2691, 785, 6533, 5913, 7618, 5734, 5523, 1105, 5918, 2600, 6451, 7515, 1657, 3897, 1783, 2172, 2704, 3245, 2146, 6156, 3224, 5979, 550, 6528, 1615, 6106, 6035, 6889, 6326, 5924, 6340, 1876, 3814, 1962, 133, 2464, 822, 2260, 4385, 6467, 1664, 199, 2228, 5747, 7394, 1454, 4516, 6716, 2221, 493, 2674, 3933, 6230, 2158, 7400, 4007, 4124, 2030, 1976, 349, 6859, 4855, 2019, 3711, 4427, 439, 781, 1699, 2005, 7336, 1656, 6412, 4961, 5053, 4100, 6651, 1734, 3509, 6276, 450, 5787, 2155, 7958, 1586, 6146, 6207, 5030, 5599, 1006, 5136, 2809, 2273, 6403, 3000, 2554, 2663, 3804, 3589, 3279, 7947, 3167, 2141, 3253, 7136, 911, 6461, 6705, 2754, 5936, 5508, 2095, 1399, 7651, 2919, 2624, 3234, 4266, 428, 1021, 3780, 4808, 485, 733, 2353, 2388, 3319, 7137, 5978, 3426, 47, 6085, 7439, 1358, 6062, 3258, 7848, 800, 7066, 6876, 603, 3010, 2472, 3823, 5898, 4668, 3788, 593, 5173, 3847, 6884, 1538, 7461, 6641, 4524, 3477, 6456, 7256, 6731, 3351, 842, 5916, 1031, 2073, 295, 6052, 5050, 5482, 2913, 4830, 2346, 5431, 7790, 2495, 5463, 2079, 6491, 979, 5371, 2764, 3569, 1565, 4176, 6174, 7087, 6137, 5842, 632, 3354, 7603, 3205, 254, 2819, 4707, 5624, 1468, 562, 2007, 7466, 3468, 707, 7913, 1225, 2802, 4819, 7960, 4725, 499, 876, 6406, 7611, 3226, 492, 3781, 1122, 3810, 3127, 1102, 1217, 7490, 2069, 5212, 5717, 7084, 6305, 5012, 4974, 4910, 1591, 25, 1426, 1312, 818, 7159, 644, 5616, 6937, 337, 5931, 732, 6297, 3932, 6004, 172, 5941, 6392, 3055, 2765, 6267, 7441, 881, 2343, 3682, 5109, 4559, 7648, 3124, 1028, 7680, 506, 7887, 7507, 2176, 672, 7205, 163, 4939, 220, 3515, 5274, 140, 4723, 3635, 5152, 5408, 3506, 4261, 3152, 2858, 6711, 3685, 1, 5208, 7928, 3156, 6474, 6863, 4392, 5535, 1820, 5692, 944, 2737, 7320, 4760, 6710, 6318, 2550, 6264, 346, 1262, 2304, 5971, 3313, 4603, 7253, 5570, 6045, 2538, 268, 7531, 5689, 7875, 2198, 3268, 436, 116, 6157, 1775, 622, 929, 2234, 7979, 6459, 4131, 6518, 7825, 4869, 7659, 6324, 5621, 2844, 3046, 2057, 7243, 3658, 4492, 5699, 838, 5421, 4777, 598, 2525, 6057, 3179, 7566, 556, 3943, 3646, 6646, 2760, 1724, 942, 830, 7187, 6555, 4012, 1769, 5695, 7641, 7380, 2116, 2934, 1289, 1290, 6525, 3014, 7606, 3209, 5238, 6190, 6277, 2481, 2298, 6861, 7435, 130, 1420, 3802, 32, 5424, 4519, 7306, 2529, 5025, 5125, 1596, 2762, 5192, 6300, 7699, 1800, 6636, 4594, 1444, 5833, 7323, 5666, 7048, 821, 1193, 2363, 6285, 7508, 4064, 4853, 3445, 4733, 7587, 1473, 5782, 1692, 4065, 3929, 1551, 6033, 6427, 1154, 6410, 1104, 1134, 3806, 3665, 5648, 753, 35, 4448, 1442, 3967, 1496, 6725, 5951, 3633, 7752, 2067, 773, 6930, 4804, 1992, 441, 1618, 3379, 2028, 3849, 905, 2339, 1629, 5480, 5470, 932, 6954, 4073, 2204, 1654, 1083, 3902, 4698, 713, 5511, 5968, 5866, 573, 3344, 7123, 7361, 2731, 6914, 2510, 2035, 3222, 472, 2509, 3267, 939, 5397, 3887, 3449, 7017, 3900, 4390, 670, 4179, 1729, 6279, 7293, 885, 6965, 6235, 7527, 3998, 7522, 6537, 1954, 2768, 4214, 6567, 4572, 2750, 4630, 4231, 3882, 3467, 5246, 3850, 5218, 5938, 2102, 6020, 6086, 7155, 3384, 3064, 5574, 2573, 2201, 7095, 3505, 3875, 5776, 3684, 7610, 5052, 1868, 6169, 1595, 1295, 4904, 2763, 5500, 62, 722, 1483, 6448, 1963, 2080, 3838, 63, 1597, 5183, 1611, 6185, 6430, 2309, 6611, 2527, 68, 2411, 6153, 272, 2215, 4497, 5758, 7589, 6331, 4337, 7514, 6367, 2637, 2112, 2257, 3134, 921, 6741, 5132, 3292, 1455, 6259, 1268, 258, 2, 3673, 5215, 3417, 1375, 4424, 3995, 5785, 2583, 2874, 3107, 1713, 7529, 2505, 4423, 7140, 7386, 90, 2912, 3105, 3736, 4138, 4525, 6454, 6564, 1331, 7570, 5157, 5521, 2272, 7793, 1439, 6032, 2599, 2581, 1255, 4223, 6109, 3686, 3038, 1773, 6578, 5731, 2170, 5504, 2376, 1309, 5922, 6306, 5986, 3414, 6767, 7927, 3624, 5209, 1580, 5547, 5955, 626, 4255, 7760, 4856, 1136, 678, 468, 7780, 230, 6604, 3299, 6712, 1908, 5682, 3326, 4239, 6996, 544, 6506, 5822, 4824, 423, 3919, 2063, 2867, 5697, 432, 1124, 1215, 391, 510, 759, 3298, 1567, 7462, 1318, 6654, 3109, 7359, 5664, 2121, 6372, 2926, 1229, 401, 3984, 871, 5249, 1196, 498, 6103, 4766, 1859, 2356, 7867, 27, 5236, 4469, 5642, 1502, 4916, 2241, 5811, 4126, 5832, 66, 579, 6487, 292, 4921, 4839, 1956, 4610, 5980, 1841, 3625, 4317, 5861, 5224, 1936, 7480, 6860, 996, 7969, 2379, 630, 4943, 1530, 3911, 6371, 7220, 4272, 6357, 1174, 1336, 2468, 7586, 4751, 210, 5818, 1019, 537, 618, 7216, 7792, 6073, 2947, 629, 1144, 1704, 6311, 5448, 78, 2528, 7673, 5904, 7763, 1825, 4071, 5844, 1998, 6418, 4908, 3913, 2448, 2822, 7737, 6472, 2916, 543, 348, 5937, 2195, 20, 2467, 5902, 6234, 6223, 4870, 4632, 5058, 6499, 3763, 4165, 4713, 158, 5753, 2369, 276, 169, 6899, 5783, 7985, 6862, 6422, 6116, 6545, 6431, 100, 2020, 7422, 1708, 7168, 4457, 3434, 2471, 5713, 244, 3650, 769, 6765, 6878, 5796, 6557, 5773, 5374, 2841, 5738, 7678, 1218, 5860, 2891, 6829, 5494, 6582, 637, 1228, 4380, 4321, 6917, 150, 2184, 7125, 4514, 4615, 296, 6330, 4397, 5806, 3334, 2163, 234, 49, 6590, 7060, 6592, 1117, 4635, 2269, 2997, 7562, 6600, 2588, 5879, 7200, 1130, 6301, 4914, 4811, 6958, 2759, 4790, 724, 4640, 3309, 2869, 3749, 986, 270, 1180, 6791, 5447, 3360, 6385, 5996, 2616, 935, 2288, 4949, 5225, 2743, 5019, 7021, 4833, 69, 2255, 3388, 3529, 5216, 4672, 119, 6191, 4301, 5162, 3362, 702, 6404, 3327, 4122, 5358, 2128, 2885, 7691, 5576, 2132, 379, 4205, 831, 4168, 5312, 5171, 4467, 1191, 7559, 7878, 3412, 4334, 5233, 4459, 946, 2131, 2270, 7503, 7237, 6254, 3068, 4844, 7873, 5342, 1471, 7371, 2094, 1529, 7833, 3741, 2519, 7249, 5175, 7112, 1139, 7495, 4984, 1211, 5826, 3141, 7047, 4629, 6319, 817, 127, 7956, 2142, 7269, 1484, 5619, 5991, 7679, 5127, 3568, 6764, 1258, 530, 3330, 3248, 1545, 1329, 7240, 1478, 4075, 290, 266, 2470, 719, 4111, 6500, 7637, 2147, 5116, 1822, 7814, 5667, 2108, 6661, 7431, 5972, 7532, 7478, 5347, 5366, 7281, 5076, 526, 2901, 4033, 3256, 3257, 3018, 7486, 501, 1348, 5004, 7534, 5631, 1966, 7023, 5750, 6314, 3455, 5618, 3586, 3088, 2403, 1261, 1299, 6017, 92, 4820, 5406, 3115, 6018, 7432, 1550, 2745, 5336, 3504, 1867, 1616, 4132, 310, 4967, 5259, 2279, 4262, 1248, 7510, 5022, 5676, 5214, 458, 7891, 673, 7122, 3778, 4386, 3366, 5503, 1169, 1556, 6977, 3670, 1622, 5211, 2836, 6720, 524, 4220, 2263, 2784, 1774, 4087, 547, 5997, 232, 1106, 5586, 1817, 1374, 1583, 7558, 2422, 6383, 3575, 4382, 1067, 1644, 102, 454, 3611, 7516, 3051, 5786, 7769, 1970, 3227, 41, 7762, 6490, 6647, 1240, 1429, 7584, 1537, 4343, 5834, 3869, 7299, 7965, 6556, 7295, 610, 6271, 6983, 7302, 855, 3714, 7459, 6266, 1535, 6051, 7427, 3817, 5691, 324, 5206, 2183, 4895, 5684, 4374, 3135, 1533, 3910, 898, 3013, 7156, 4650, 4918, 1972, 3996, 2647, 5551, 5651, 7743, 4628, 2906, 2331, 4569, 6147, 5467, 5464, 5732, 5036, 83, 1663, 3128, 5614, 6260, 972, 4966, 6970, 194, 6675, 6270, 4759, 5199, 2202, 4965, 569, 7448, 5730, 4409, 1338, 2636, 5989, 4937, 1612, 5314, 7946, 6657, 3552, 7377, 3961, 577, 3801, 551, 1319, 7366, 1147, 5201, 7321, 7666, 6618, 5390, 19, 2714, 3429, 7571, 2973, 1291, 5459, 7909, 4527, 4327, 146, 5659, 200, 6082, 4680, 3832, 3394, 6613, 5401, 7097, 5232, 4612, 4711, 3034, 3017, 4278, 3639, 3782, 1555, 4982, 1837, 4203, 3576, 661, 1506, 2050, 760, 3301, 1969, 4244, 7698, 3192, 5051, 6483, 3481, 5981, 3243, 6513, 4963, 2036, 3558, 4381, 1627, 3556, 6091, 5831, 2159, 3032, 3794, 3968, 3458, 1743, 7932, 4234, 122, 4691, 2153, 6986, 1425, 6226, 7658, 4807, 5505, 4146, 7823, 4260, 5727, 596, 3098, 6920, 7000, 6502, 2595, 1832, 5964, 5668, 7777, 4796, 3237, 7926, 6956, 3839, 2197, 516, 2613, 6015, 3338, 3605, 2697, 415, 7244, 3307, 1467, 6061, 3287, 3112, 2967, 2547, 7034, 365, 1171, 7176, 1874, 4461, 1372, 4135, 4738, 183, 1043, 3, 6744, 746, 7, 1501, 4201, 1740, 4193, 387, 1900, 4645, 6049, 3878, 5706, 5561, 4149, 2597, 7721, 3765, 4376, 7489, 2148, 5613, 6167, 7446, 3819, 3203, 5702, 2839, 4426, 7843, 4001, 6465, 2424, 6811, 3497, 1914, 7222, 374, 109, 2594, 5318, 5828, 193, 2118, 3204, 7225, 7171, 3361, 5015, 6940, 5422, 7151, 4522, 1497, 2650, 580, 5324, 3444, 6660, 836, 95, 1034, 487, 4465, 2084, 3331, 5908, 6696, 4659, 6805, 3706, 3669, 3722, 2825, 3190, 6948, 5060, 3867, 834, 6304, 5069, 6718, 3191, 1078, 6775, 1073, 6932, 3060, 5287, 449, 2773, 4779, 1465, 7758, 1232, 3096, 6526, 6186, 6686, 6179, 4197, 6734, 4919, 5801, 4580, 5647, 211, 3541, 3448, 5156, 6979, 6897, 2182, 3273, 4018, 2220, 2177, 3480, 3437, 6426, 2047, 5306, 5479, 4548, 3001, 4932, 615, 377, 1760, 3221, 6399, 1251, 3508, 1082, 400, 2548, 5557, 3369, 2958, 1155, 7464, 3322, 6760, 4399, 7232, 2371, 2692, 4452, 3246, 633, 609, 7186, 3482, 2629, 7337, 6341, 6723, 362, 3559, 5098, 2959, 7356, 1297, 4648, 17, 3147, 2982, 407, 7212, 2558, 4794, 1513, 7093, 4066, 6111, 6681, 4489, 859, 4435, 7195, 7304, 1879, 1074, 4900, 571, 4578, 4495, 2212, 749, 4366, 5399, 5897, 2282, 5808, 7178, 5481, 2052, 5698, 2044, 7682, 6952, 5320, 4757, 6755, 3011, 7783, 3411, 204, 1522, 1330, 7260, 2482, 1986, 801, 6934, 3242, 4989, 3170, 2265, 1457, 725, 7421, 6010, 7389, 6906, 5714, 6677, 5836, 1151, 6772, 3591, 4730, 2935, 5663, 5103, 2965, 1891, 2168, 6980, 813, 2710, 795, 7252, 3015, 2271, 6024, 3854, 5243, 2501, 1990, 4336, 4852, 1952, 2503, 5349, 5389, 4114, 1563, 7015, 1185, 1892, 5337, 4838, 3489, 1739, 4229, 1910, 5223, 5895, 4763, 5102, 222, 5794, 4493, 1156, 2952, 4058, 7073, 6747, 623, 7736, 2229, 7639, 949, 6382, 4718, 3768, 6099, 5598, 6229, 6671, 7344, 3471, 2543, 6583, 1843, 4501, 4809, 4060, 5637, 1086, 4537, 5426, 1177, 648, 5111, 2460, 1334, 5288, 6416, 1002, 176, 658, 4983, 2619, 7916, 6770, 4688, 7467, 3375, 1224, 4128, 6409, 5478, 6634, 3962, 7103, 1744, 6321, 5680, 4425, 6452, 2540, 3925, 6063, 7424, 2724, 1382, 5749, 1458, 540, 4587, 5017, 2203, 1666, 4550, 2627, 4030, 6040, 5266, 7412, 3353, 7213, 7805, 2631, 4014, 3675, 4797, 7565, 4969, 3469, 5061, 7555, 6529, 5442, 4432, 5690, 2709, 6874, 5112, 3719, 924, 2385, 6572, 5420, 5954, 889, 4604, 816, 1767, 2682, 1662, 3131, 1884, 4586, 180, 1202, 7681, 5960, 1342, 185, 7643, 7577, 1030, 7233, 7079, 6695, 1625, 1430, 4, 4959, 5073, 4307, 4034, 6233, 2767, 1882, 5278, 910, 6104, 6050, 6700, 1386, 3212, 4479, 1909, 1592, 4363, 7276, 6221, 3826, 6648, 6670, 4785, 835, 3977, 2991, 857, 4532, 7045, 5154, 1274, 6551, 2297, 4108, 245, 4884, 2721, 4694, 7915, 6248, 4415, 3075, 902, 2946, 3347, 196, 5510, 5392, 7978, 4826, 1603, 3727, 307, 1872, 1128, 7645, 978, 6918, 486, 5558, 7702, 1737, 4153, 7990, 1749, 4088, 3579, 2026, 28, 5063, 7512, 1320, 4981, 7654, 1569, 366, 5439, 4022, 893, 5591, 2735, 1716, 5610, 7401, 1564, 7977, 4420, 7844, 7710, 1991, 2475, 6435, 2125, 7816, 261, 6569, 1566, 6135, 5239, 4641, 6113, 7184, 4802, 3570, 152, 4143, 5166, 405, 6334, 6801, 2350, 2652, 7585, 6441, 2738, 5176, 7287, 1889, 3661, 2712, 5147, 3332, 6603, 5048, 7369, 6030, 3325, 5906, 7876, 1011, 418, 5468, 6558, 2920, 7986, 3852, 3171, 4827, 780, 2994, 2797, 4710, 5219, 231, 3223, 2236, 4543, 1064, 2908, 4069, 5516, 6929, 1881, 5299, 982, 5805, 3130, 319, 4752, 3770, 7119, 1246, 7279, 6831, 5272, 326, 5696, 2796, 4486, 2755, 5649, 1387, 7676, 6616, 3501, 1127, 7910, 4861, 5992, 2632, 5626, 5804, 2113, 7539, 3012, 6093, 5354, 7856, 6060, 5606, 3244, 1069, 7747, 6069, 7157, 7683, 1143, 2099, 4328, 6504, 2139, 3628, 5350, 3306, 2479, 2681, 7883, 7920, 5874, 4351, 4973, 2585, 4408, 4242, 5128, 5373, 2782, 1735, 7505, 5250, 2705, 2830, 6780, 894, 4509, 1403, 2409, 336, 7268, 1423, 7274, 799, 1690, 6209, 4348, 2542, 4478, 4412, 1307, 5909, 3976, 7452, 5041, 323, 5035, 3695, 5772, 7246, 7309, 619, 2427, 4354, 3288, 4161, 105, 6281, 3341, 784, 602, 6444, 1759, 1433, 542, 1667, 2083, 6149, 7374, 5419, 1635, 3210, 6949, 262, 7774, 2433, 6213, 4225, 5630, 1674, 4992, 6369, 2565, 3164, 5120, 57, 6475, 1259, 4142, 2399, 2227, 4224, 4564, 3310, 386, 3339, 3820, 965, 3944, 4676, 1044, 6288, 5761, 5193, 2477, 2070, 3084, 7538, 4874, 4418, 301, 2929, 1598, 4438, 3320, 4144, 1768, 754, 4699, 7849, 6652, 5496, 7382, 1938, 3939, 3861, 1250, 2720, 201, 4724, 5148, 5605, 7173, 745, 5024, 6108, 1398]\n" + ] + } + ], + "source": [ + "print(train_dataset.original_indices)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'max_len': 280, 'vocab_size': 10556, 'embed_dim': 100, 'num_heads': 2, 'num_layers': 2, 'hidden_dim': 256, 'epochs': 3, 'batch_size': 8, 'learning_rate': 2e-05, 'accuracy': 0.5056}\n" + ] + } + ], + "source": [ + "print(params)" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\felix\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\torch\\nn\\modules\\transformer.py:379: UserWarning: enable_nested_tensor is True, but self.use_nested_tensor is False because encoder_layer.self_attn.batch_first was not True(use batch_first for better inference performance)\n", + " warnings.warn(\n", + "C:\\Users\\felix\\AppData\\Local\\Temp\\ipykernel_16796\\3082896325.py:7: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model.load_state_dict(torch.load(model_path))\n" + ] + } + ], + "source": [ + "import transformer_1b\n", + "\n", + "model = transformer_1b.TransformerBinaryClassifier(params['vocab_size'], params['embed_dim'], \n", + " params['num_heads'], params['num_layers'], \n", + " params['hidden_dim'])\n", + "\n", + "model.load_state_dict(torch.load(model_path))\n", + "\n", + "\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "model.to(device)\n", + "\n", + "predictions = []\n", + "labels = []\n", + "\n", + "# Predict on test set\n", + "model.eval()\n", + "with torch.no_grad():\n", + " data_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)\n", + " for batch in data_loader:\n", + " input_ids = batch['input_ids'].to(device)\n", + " labels_batch = batch['labels'].unsqueeze(1).to(device)\n", + " outputs = model(input_ids)\n", + " outputs = outputs.cpu().round().numpy()\n", + " labels_batch = labels_batch.cpu().numpy()\n", + "\n", + " predictions.append(outputs)\n", + " labels.append(labels_batch)\n", + "\n", + "# Concatenate all predictions\n", + "predictions = np.concatenate(predictions)\n", + "labels = np.concatenate(labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [], + "source": [ + "# get df data for original indices\n", + "df_test = df.iloc[test_dataset.original_indices].copy()\n", + "df_test['prediction'] = predictions\n", + "df_test['label'] = labels\n", + "df_test['pred_correct'] = (df_test['prediction'] == df_test['label'])\n", + "\n", + "df_test_sorted = df_test.sort_values(by='humor_rating').reset_index(drop=True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "997\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from matplotlib import patches as mpatches\n", + "\n", + "median_rating = df['humor_rating'].median()\n", + "# get first index where humor_rating is greater than median_rating\n", + "median_idx = df_test_sorted[df_test_sorted['humor_rating'] > median_rating].index[0]\n", + "print(median_idx)\n", + "# range idx for len df_test\n", + "range_idx = range(len(df_test))\n", + "colors = df_test_sorted['pred_correct'].map({True: 'g', False: 'r'})\n", + "# bar plot for each df_test humor_rating value \n", + "plt.bar(range_idx, df_test_sorted['humor_rating'], color=colors)\n", + "# vertical line for True/False cut off\n", + "plt.axvline(x=median_idx, color='black', linestyle='--')\n", + "# Create a legend handles\n", + "green_patch = mpatches.Patch(color='g', label='Correct Prediction')\n", + "red_patch = mpatches.Patch(color='r', label='Incorrect Prediction')\n", + "line_patch = mpatches.Patch(color='black', label='humor_rating cut off')\n", + "plt.title('Humor Rating vs Prediction for Test Set')\n", + "plt.xlabel('Index')\n", + "plt.ylabel('Humor Rating')\n", + "plt.legend(handles=[green_patch, red_patch, line_patch])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NOTE: \n", + "- model currently only predicts 0 therefore one site is green and other red\n", + "- plot can be helpfull to identify if around the cut off the model gets confused" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}