{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "f3452caf-df58-4394-b0d6-46459cb47045", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "S:\\WENV_TORCHTEXT\\Lib\\site-packages\\torchtext\\vocab\\__init__.py:4: UserWarning: \n", "/!\\ IMPORTANT WARNING ABOUT TORCHTEXT STATUS /!\\ \n", "Torchtext is deprecated and the last released version will be 0.18 (this one). You can silence this warning by calling the following at the beginnign of your scripts: `import torchtext; torchtext.disable_torchtext_deprecation_warning()`\n", " warnings.warn(torchtext._TORCHTEXT_DEPRECATION_MSG)\n", "S:\\WENV_TORCHTEXT\\Lib\\site-packages\\torchtext\\utils.py:4: UserWarning: \n", "/!\\ IMPORTANT WARNING ABOUT TORCHTEXT STATUS /!\\ \n", "Torchtext is deprecated and the last released version will be 0.18 (this one). You can silence this warning by calling the following at the beginnign of your scripts: `import torchtext; torchtext.disable_torchtext_deprecation_warning()`\n", " warnings.warn(torchtext._TORCHTEXT_DEPRECATION_MSG)\n" ] } ], "source": [ "from torch.utils.data import IterableDataset, DataLoader\n", "from torchtext.vocab import build_vocab_from_iterator\n", "\n", "import regex as re\n", "import itertools\n", "from itertools import islice\n", "\n", "from torch import nn\n", "import torch\n", "\n", "from tqdm.notebook import tqdm\n", "device = 'cuda'" ] }, { "cell_type": "code", "execution_count": 2, "id": "5ee9ad24-a5d2-47e1-a5c6-88981dc22b99", "metadata": {}, "outputs": [], "source": [ "def get_words_from_line(line):\n", " line = line.rstrip()\n", " yield ''\n", " for m in re.finditer(r'[\\p{L}0-9\\*]+|\\p{P}+', line):\n", " yield m.group(0).lower()\n", " yield ''\n", "\n", "def get_word_lines_from_file(file_name):\n", " with open(file_name, 'r', encoding='utf8') as fh:\n", " for line in fh:\n", " yield get_words_from_line(line)\n", "\n", "def look_ahead_iterator(gen):\n", " prev2, prev1, next1, next2 = None, None, None, None\n", " for item in gen:\n", " if prev2 is not None and prev1 is not None and next1 is not None and next2 is not None:\n", " yield (prev2, prev1, next2, item, next1)\n", " prev2, prev1, next1, next2 = prev1, next1, next2, item" ] }, { "cell_type": "code", "execution_count": 3, "id": "93279277-0765-4f85-9666-095fc7808c81", "metadata": {}, "outputs": [], "source": [ "class FiveGrams(IterableDataset):\n", " def __init__(self, text_file, vocabulary_size):\n", " self.vocab = build_vocab_from_iterator(\n", " get_word_lines_from_file(text_file),\n", " max_tokens=vocabulary_size,\n", " specials=['']\n", " )\n", " self.vocab.set_default_index(self.vocab[''])\n", " self.vocabulary_size = vocabulary_size\n", " self.text_file = text_file\n", "\n", " def __iter__(self):\n", " return look_ahead_iterator(\n", " (self.vocab[t] for t in itertools.chain.from_iterable(get_word_lines_from_file(self.text_file)))\n", " )" ] }, { "cell_type": "code", "execution_count": 4, "id": "6eb5fbd9-bc0f-499d-85f4-3998a4a3f56e", "metadata": {}, "outputs": [], "source": [ "class SimpleFiveGramNeuralLanguageModel(nn.Module):\n", " def __init__(self, vocabulary_size, embedding_size):\n", " super(SimpleFiveGramNeuralLanguageModel, self).__init__()\n", " self.embedding = nn.Embedding(vocabulary_size, embedding_size)\n", " self.linear1 = nn.Linear(embedding_size * 4, embedding_size)\n", " self.linear2 = nn.Linear(embedding_size, vocabulary_size)\n", " self.softmax = nn.Softmax(dim=1)\n", " self.embedding_size = embedding_size\n", "\n", " def forward(self, x):\n", " embeds = self.embedding(x).view(x.size(0), -1)\n", " out = self.linear1(embeds)\n", " out = self.linear2(out)\n", " return self.softmax(out)" ] }, { "cell_type": "code", "execution_count": 5, "id": "d0dc7c69-3f27-4f00-9b91-5f3a403df074", "metadata": {}, "outputs": [], "source": [ "def train(embed_size,vocab_size,num_epochs,batch_size,train_file_path):\n", " train_dataset = FiveGrams(train_file_path, vocab_size)\n", " model = SimpleFiveGramNeuralLanguageModel(vocab_size, embed_size).to(device)\n", " \n", " data = DataLoader(train_dataset, batch_size=batch_size)\n", " optimizer = torch.optim.Adam(model.parameters())\n", " criterion = torch.nn.CrossEntropyLoss()\n", " \n", " model.train()\n", " step = 0\n", " for _ in range(num_epochs):\n", " for x1, x2, x3, x4, y in tqdm(data, desc=\"Train loop\"):\n", " y = y.to(device)\n", " x = torch.cat((x1.unsqueeze(1), x2.unsqueeze(1), x3.unsqueeze(1), x4.unsqueeze(1)), dim=1).to(device)\n", " optimizer.zero_grad()\n", " ypredicted = model(x)\n", " \n", " loss = criterion(torch.log(ypredicted), y)\n", " if step % 5000 == 0:\n", " print(step, loss)\n", " step += 1\n", " loss.backward()\n", " optimizer.step()\n", " step = 0\n", " break\n", " model.eval()\n", "\n", " return model, train_dataset.vocab" ] }, { "cell_type": "code", "execution_count": 6, "id": "9a1b2240-d2ed-4c56-8443-12113e66b514", "metadata": {}, "outputs": [], "source": [ "def get_gap_candidates(words, model, vocab, n=20):\n", " ixs = vocab(words)\n", " ixs = torch.tensor(ixs).unsqueeze(0).to(device)\n", "\n", " out = model(ixs)\n", " top = torch.topk(out[0], n)\n", " top_indices = top.indices.tolist()\n", " top_probs = top.values.tolist()\n", " top_words = vocab.lookup_tokens(top_indices)\n", " return list(zip(top_words, top_probs))\n", "\n", "def clean(text):\n", " text = text.replace('-\\\\n', '').replace('\\\\n', ' ').replace('\\\\t', ' ')\n", " text = re.sub(r'\\n', ' ', text)\n", " text = re.sub(r'(?<=\\w)[,-](?=\\w)', '', text)\n", " text = re.sub(r'\\s+', ' ', text)\n", " text = re.sub(r'\\p{P}', '', text)\n", " text = text.strip()\n", " return text\n", " \n", "def predictor(prefix, suffix, model, vocab):\n", " prefix = clean(prefix)\n", " suffix = clean(suffix)\n", " words = prefix.split(' ')[-2:] + suffix.split(' ')[:2]\n", " candidates = get_gap_candidates(words, model, vocab)\n", "\n", " probs_sum = 0\n", " output = ''\n", " for word, prob in candidates:\n", " if word == \"\":\n", " continue\n", " probs_sum += prob\n", " output += f\"{word}:{prob} \"\n", " output += f\":{1-probs_sum}\"\n", "\n", " return output" ] }, { "cell_type": "code", "execution_count": 7, "id": "40af2781-3807-43e8-b6dd-3b70066e50c1", "metadata": {}, "outputs": [], "source": [ "def generate_result(input_path,model, vocab, output_path='out.tsv'):\n", " lines = []\n", " with open(input_path, encoding='utf-8') as f:\n", " for line in f:\n", " columns = line.split('\\t')\n", " prefix = columns[6]\n", " suffix = columns[7]\n", " lines.append((prefix, suffix))\n", "\n", " with open(output_path, 'w', encoding='utf-8') as output_file:\n", " for prefix, suffix in tqdm(lines):\n", " result = predictor(prefix, suffix, model, vocab)\n", " output_file.write(result + '\\n')" ] }, { "cell_type": "code", "execution_count": 8, "id": "d6b7234f-1f40-468f-8c69-2875bb1ec947", "metadata": {}, "outputs": [], "source": [ "import subprocess\n", "\n", "def evaluate():\n", " cmd = 'wsl bash -c \"cd /mnt/d/UAM/MODELOWANIE/5GRAM && ./geval -t dev-0\"'\n", " result = subprocess.run(cmd, shell=True, capture_output=True, text=True)\n", " return float(result.stdout)" ] }, { "cell_type": "code", "execution_count": 9, "id": "4c716463-27fe-4c2b-b859-ac9c8aff1942", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "1eac733e07974322bfd47dcff96aa8d4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Train loop: 0it [00:00, ?it/s]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "0 tensor(9.2551, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3df53998bc334a29bd355578738897d3", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(4.6065, device='cuda:0', grad_fn=)\n", "10000 tensor(4.4173, device='cuda:0', grad_fn=)\n", "15000 tensor(4.3352, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "1e3d1e4344f44285832accfc83ab2233", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3546c4fd825a4057b05c6105b25f6712", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(4.8952, device='cuda:0', grad_fn=)\n", "10000 tensor(4.7382, device='cuda:0', grad_fn=)\n", "15000 tensor(4.6068, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "cd0c53ddfb3148609218b56c72ce7777", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "42b54814d7f741ddb38d8e00d6db2126", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(5.0450, device='cuda:0', grad_fn=)\n", "10000 tensor(4.8688, device='cuda:0', grad_fn=)\n", "15000 tensor(4.7152, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "38a391c3471442dc8620524f0d5c5fc8", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "65a44fd20fce4ec49528763ebb351f4b", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(4.4829, device='cuda:0', grad_fn=)\n", "10000 tensor(4.2794, device='cuda:0', grad_fn=)\n", "15000 tensor(4.2239, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9b2f000b5c7a4ab08fb48c78b45c3a54", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6883012f36d44ab0842b14281ef5eb65", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(4.7515, device='cuda:0', grad_fn=)\n", "10000 tensor(4.5669, device='cuda:0', grad_fn=)\n", "15000 tensor(4.4938, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "53d6628208ac4997a290cdde469ccfb1", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ccb8ed60361c4a509afb628f52ce609c", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(4.8590, device='cuda:0', grad_fn=)\n", "10000 tensor(4.7090, device='cuda:0', grad_fn=)\n", "15000 tensor(4.5810, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "85f4db52171945fa9fb2890431a276b2", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "32802641dc974b6cb3404a12c51b611b", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(4.4134, device='cuda:0', grad_fn=)\n", "10000 tensor(4.2280, device='cuda:0', grad_fn=)\n", "15000 tensor(4.1653, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a97a141657af410b989bbd8ab8710955", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3aa3a60daf6145389312b031ca55e11d", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(4.6888, device='cuda:0', grad_fn=)\n", "10000 tensor(4.5068, device='cuda:0', grad_fn=)\n", "15000 tensor(4.4465, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "56e1065d5c01461e8cdfc38b7db2f3ed", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "58d964531ad14b69ba72b7d8d538cf2d", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00)\n", "5000 tensor(4.8159, device='cuda:0', grad_fn=)\n", "10000 tensor(4.6442, device='cuda:0', grad_fn=)\n", "15000 tensor(4.5524, device='cuda:0', grad_fn=)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "aedcfa56f6c345dd976b37535d0de2b4", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10519 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from scipy.interpolate import griddata\n", "\n", "# Sample data\n", "data = results\n", "\n", "# Extracting data\n", "vocab_size = [item['vocab_size'] for item in data if 'nano' not in item['train_file_path'] ]\n", "embed_size = [item['embed_size'] for item in data if 'nano' not in item['train_file_path'] ]\n", "perplexity = [item['perplexity'] for item in data if 'nano' not in item['train_file_path'] ]\n", "\n", "# Plotting\n", "grid_x, grid_y = np.meshgrid(np.linspace(min(vocab_size), max(vocab_size), 100),\n", " np.linspace(min(embed_size), max(embed_size), 100))\n", "grid_z = griddata((vocab_size, embed_size), perplexity, (grid_x, grid_y), method='cubic')\n", "\n", "# Plotting\n", "plt.figure(figsize=(10, 6))\n", "contour = plt.contourf(grid_x, grid_y, grid_z, cmap='viridis')\n", "plt.colorbar(contour, label='Perplexity')\n", "plt.scatter(vocab_size, embed_size, c='red') # Optional: plot actual data points\n", "plt.xlabel('Vocab Size')\n", "plt.ylabel('Embed Size')\n", "plt.title('Embed Size vs Vocab Size with Perplexity for whole training set')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 22, "id": "fe388a52-9bd3-4ee3-9cf1-838c9ff22c55", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Extracting data\n", "vocab_size = [item['vocab_size'] for item in data if 'nano' in item['train_file_path'] ]\n", "embed_size = [item['embed_size'] for item in data if 'nano' in item['train_file_path'] ]\n", "perplexity = [item['perplexity'] for item in data if 'nano' in item['train_file_path'] ]\n", "\n", "# Plotting\n", "grid_x, grid_y = np.meshgrid(np.linspace(min(vocab_size), max(vocab_size), 100),\n", " np.linspace(min(embed_size), max(embed_size), 100))\n", "grid_z = griddata((vocab_size, embed_size), perplexity, (grid_x, grid_y), method='cubic')\n", "\n", "# Plotting\n", "plt.figure(figsize=(10, 6))\n", "contour = plt.contourf(grid_x, grid_y, grid_z, cmap='viridis')\n", "plt.colorbar(contour, label='Perplexity')\n", "plt.scatter(vocab_size, embed_size, c='red') # Optional: plot actual data points\n", "plt.xlabel('Vocab Size')\n", "plt.ylabel('Embed Size')\n", "plt.title('Embed Size vs Vocab Size with Perplexity for nano training set')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 26, "id": "a310f1f5-0b2f-4994-b36a-e2ff1a7e6b70", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'embed_size': 300,\n", " 'vocab_size': 30000,\n", " 'num_epochs': 1,\n", " 'batch_size': 8192,\n", " 'train_file_path': 'train/train.txt',\n", " 'perplexity': 173.38,\n", " 'logPerplexity': 5.155485717440494}" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from math import log\n", "\n", "best_model_parameters = min(results, key=lambda x: x['perplexity'])\n", "best_model_parameters['logPerplexity'] = log(best_model_parameters['perplexity'])\n", "best_model_parameters" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }