DL_SEQ2SEQ/seq2seq-torch-successful.ipynb
2024-06-03 06:53:52 +02:00

1156 lines
121 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"source": [
"### Importy"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {
"collapsed": true,
"ExecuteTime": {
"start_time": "2024-06-02T19:58:41.249607Z",
"end_time": "2024-06-02T19:58:41.261609Z"
}
},
"outputs": [],
"source": [
"from __future__ import unicode_literals, print_function, division\n",
"from io import open\n",
"import unicodedata\n",
"import re\n",
"import os\n",
"import random\n",
"import torch\n",
"import pandas as pd\n",
"import torch.nn as nn\n",
"from torch import optim\n",
"import torch.nn.functional as F\n",
"from torchtext.data.metrics import bleu_score\n",
"\n",
"from torch.utils.data import TensorDataset, DataLoader, RandomSampler\n",
"os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\""
]
},
{
"cell_type": "code",
"execution_count": 9,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Is CUDA supported by this system? True\n",
"CUDA version: 12.1\n",
"ID of current CUDA device: 0\n",
"Name of current CUDA device: NVIDIA GeForce GTX 1660 Ti\n"
]
}
],
"source": [
"print(f'Is CUDA supported by this system? {torch.cuda.is_available()}')\n",
"print(f\"CUDA version: {torch.version.cuda}\")\n",
"\n",
"cuda_id = torch.cuda.current_device()\n",
"print(f'ID of current CUDA device: {torch.cuda.current_device()}')\n",
"\n",
"print(f'Name of current CUDA device: {torch.cuda.get_device_name(cuda_id)}')"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:20:55.709021Z",
"end_time": "2024-06-02T19:20:55.725023Z"
}
}
},
{
"cell_type": "code",
"execution_count": 10,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"cuda\n"
]
}
],
"source": [
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
"print(device)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:20:55.996605Z",
"end_time": "2024-06-02T19:20:56.041138Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Konwersja słów na tensory"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 11,
"outputs": [],
"source": [
"SOS_token = 0\n",
"EOS_token = 1\n",
"\n",
"class Lang:\n",
" def __init__(self, name):\n",
" self.name = name\n",
" self.word2index = {}\n",
" self.word2count = {}\n",
" self.index2word = {0: \"SOS\", 1: \"EOS\"}\n",
" self.n_words = 2 # Count SOS and EOS\n",
"\n",
" def addSentence(self, sentence):\n",
" for word in sentence.split(' '):\n",
" self.addWord(word)\n",
"\n",
" def addWord(self, word):\n",
" if word not in self.word2index:\n",
" self.word2index[word] = self.n_words\n",
" self.word2count[word] = 1\n",
" self.index2word[self.n_words] = word\n",
" self.n_words += 1\n",
" else:\n",
" self.word2count[word] += 1"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:20:59.879666Z",
"end_time": "2024-06-02T19:20:59.893667Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Przygotowanie danych"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 12,
"outputs": [],
"source": [
"# Turn a Unicode string to plain ASCII, thanks to\n",
"# https://stackoverflow.com/a/518232/2809427\n",
"def unicodeToAscii(s):\n",
" return ''.join(\n",
" c for c in unicodedata.normalize('NFD', s)\n",
" if unicodedata.category(c) != 'Mn'\n",
" )\n",
"\n",
"# Lowercase, trim, and remove non-letter characters\n",
"def normalizeString(s):\n",
" s = unicodeToAscii(s.lower().strip())\n",
" s = re.sub(r\"([.!?])\", r\" \\1\", s)\n",
" s = re.sub(r\"[^a-zA-Z!?]+\", r\" \", s)\n",
" return s.strip()"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:21:00.877093Z",
"end_time": "2024-06-02T19:21:00.892090Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Wczytanie danych"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 13,
"outputs": [],
"source": [
"def readLangs(lang1, lang2, reverse=False):\n",
" print(\"Reading lines...\")\n",
" # Read the file and split into lines\n",
" lines = open('data/%s-%s.txt' % (lang1, lang2), encoding='utf-8').\\\n",
" read().strip().split('\\n')\n",
"\n",
" # Split every line into pairs and normalize\n",
" pairs = [[normalizeString(s) for s in l.split('\\t')[:-1]] for l in lines]\n",
"\n",
" # Reverse pairs, make Lang instances\n",
" if reverse:\n",
" pairs = [df_filtered(reversed(p)) for p in pairs]\n",
" input_lang = Lang(lang2)\n",
" output_lang = Lang(lang1)\n",
" else:\n",
" input_lang = Lang(lang1)\n",
" output_lang = Lang(lang2)\n",
"\n",
" return input_lang, output_lang, pairs"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:21:02.075474Z",
"end_time": "2024-06-02T19:21:02.087474Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Filtracja danych"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "markdown",
"source": [
"Ograniczenie zdań do 10 słów oraz zdań zaczynających się od prefiksów"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 14,
"outputs": [],
"source": [
"MAX_LENGTH = 10\n",
"\n",
"eng_prefixes = (\n",
" \"i am \", \"i m \",\n",
" \"he is\", \"he s \",\n",
" \"she is\", \"she s \",\n",
" \"you are\", \"you re \",\n",
" \"we are\", \"we re \",\n",
" \"they are\", \"they re \"\n",
")\n",
"\n",
"def filterPair(p):\n",
" return len(p[0].split(' ')) < MAX_LENGTH and \\\n",
" len(p[1].split(' ')) < MAX_LENGTH and \\\n",
" p[1].startswith(eng_prefixes)\n",
"\n",
"\n",
"def filterPairs(pairs):\n",
" return [pair for pair in pairs if filterPair(pair)]"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:21:03.811303Z",
"end_time": "2024-06-02T19:21:03.829054Z"
}
}
},
{
"cell_type": "code",
"execution_count": 15,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Reading lines...\n",
"Read 49943 sentence pairs\n",
"Trimmed to 3613 sentence pairs\n",
"Counting words...\n",
"Counted words:\n",
"pol 3070\n",
"eng 1969\n",
"['nie umieram', 'i m not dying']\n"
]
}
],
"source": [
"def prepareData(lang1, lang2, reverse=False):\n",
" input_lang, output_lang, pairs = readLangs(lang1, lang2, reverse)\n",
" print(\"Read %s sentence pairs\" % len(pairs))\n",
" pairs = filterPairs(pairs)\n",
" print(\"Trimmed to %s sentence pairs\" % len(pairs))\n",
" print(\"Counting words...\")\n",
" for pair in pairs:\n",
" input_lang.addSentence(pair[0])\n",
" output_lang.addSentence(pair[1])\n",
" print(\"Counted words:\")\n",
" print(input_lang.name, input_lang.n_words)\n",
" print(output_lang.name, output_lang.n_words)\n",
" return input_lang, output_lang, pairs\n",
"\n",
"input_lang, output_lang, pairs = prepareData('eng', 'pol' , True)\n",
"print(random.choice(pairs))"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:21:04.527025Z",
"end_time": "2024-06-02T19:21:06.394023Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Model"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 16,
"outputs": [],
"source": [
"class EncoderRNN(nn.Module):\n",
" def __init__(self, input_size, hidden_size, dropout_p=0.1):\n",
" super(EncoderRNN, self).__init__()\n",
" self.hidden_size = hidden_size\n",
"\n",
" self.embedding = nn.Embedding(input_size, hidden_size)\n",
" self.gru = nn.GRU(hidden_size, hidden_size, batch_first=True)\n",
" self.dropout = nn.Dropout(dropout_p)\n",
"\n",
" def forward(self, input):\n",
" embedded = self.dropout(self.embedding(input))\n",
" output, hidden = self.gru(embedded)\n",
" return output, hidden"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:21:11.058623Z",
"end_time": "2024-06-02T19:21:11.074974Z"
}
}
},
{
"cell_type": "code",
"execution_count": 17,
"outputs": [],
"source": [
"class DecoderRNN(nn.Module):\n",
" def __init__(self, hidden_size, output_size):\n",
" super(DecoderRNN, self).__init__()\n",
" self.embedding = nn.Embedding(output_size, hidden_size)\n",
" self.gru = nn.GRU(hidden_size, hidden_size, batch_first=True)\n",
" self.out = nn.Linear(hidden_size, output_size)\n",
"\n",
" def forward(self, encoder_outputs, encoder_hidden, target_tensor=None):\n",
" batch_size = encoder_outputs.size(0)\n",
" decoder_input = torch.empty(batch_size, 1, dtype=torch.long, device=device).fill_(SOS_token)\n",
" decoder_hidden = encoder_hidden\n",
" decoder_outputs = []\n",
"\n",
" for i in range(MAX_LENGTH):\n",
" decoder_output, decoder_hidden = self.forward_step(decoder_input, decoder_hidden)\n",
" decoder_outputs.append(decoder_output)\n",
"\n",
" if target_tensor is not None:\n",
" # Teacher forcing: Feed the target as the next input\n",
" decoder_input = target_tensor[:, i].unsqueeze(1) # Teacher forcing\n",
" else:\n",
" # Without teacher forcing: use its own predictions as the next input\n",
" _, topi = decoder_output.topk(1)\n",
" decoder_input = topi.squeeze(-1).detach() # detach from history as input\n",
"\n",
" decoder_outputs = torch.cat(decoder_outputs, dim=1)\n",
" decoder_outputs = F.log_softmax(decoder_outputs, dim=-1)\n",
" return decoder_outputs, decoder_hidden, None # We return `None` for consistency in the training loop\n",
"\n",
" def forward_step(self, input, hidden):\n",
" output = self.embedding(input)\n",
" output = F.relu(output)\n",
" output, hidden = self.gru(output, hidden)\n",
" output = self.out(output)\n",
" return output, hidden"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:21:11.447213Z",
"end_time": "2024-06-02T19:21:11.462232Z"
}
}
},
{
"cell_type": "code",
"execution_count": 18,
"outputs": [],
"source": [
"class BahdanauAttention(nn.Module):\n",
" def __init__(self, hidden_size):\n",
" super(BahdanauAttention, self).__init__()\n",
" self.Wa = nn.Linear(hidden_size, hidden_size)\n",
" self.Ua = nn.Linear(hidden_size, hidden_size)\n",
" self.Va = nn.Linear(hidden_size, 1)\n",
"\n",
" def forward(self, query, keys):\n",
" scores = self.Va(torch.tanh(self.Wa(query) + self.Ua(keys)))\n",
" scores = scores.squeeze(2).unsqueeze(1)\n",
"\n",
" weights = F.softmax(scores, dim=-1)\n",
" context = torch.bmm(weights, keys)\n",
"\n",
" return context, weights\n",
"\n",
"class AttnDecoderRNN(nn.Module):\n",
" def __init__(self, hidden_size, output_size, dropout_p=0.1):\n",
" super(AttnDecoderRNN, self).__init__()\n",
" self.embedding = nn.Embedding(output_size, hidden_size)\n",
" self.attention = BahdanauAttention(hidden_size)\n",
" self.gru = nn.GRU(2 * hidden_size, hidden_size, batch_first=True)\n",
" self.out = nn.Linear(hidden_size, output_size)\n",
" self.dropout = nn.Dropout(dropout_p)\n",
"\n",
" def forward(self, encoder_outputs, encoder_hidden, target_tensor=None):\n",
" batch_size = encoder_outputs.size(0)\n",
" decoder_input = torch.empty(batch_size, 1, dtype=torch.long, device=device).fill_(SOS_token)\n",
" decoder_hidden = encoder_hidden\n",
" decoder_outputs = []\n",
" attentions = []\n",
"\n",
" for i in range(MAX_LENGTH):\n",
" decoder_output, decoder_hidden, attn_weights = self.forward_step(\n",
" decoder_input, decoder_hidden, encoder_outputs\n",
" )\n",
" decoder_outputs.append(decoder_output)\n",
" attentions.append(attn_weights)\n",
"\n",
" if target_tensor is not None:\n",
" # Teacher forcing: Feed the target as the next input\n",
" decoder_input = target_tensor[:, i].unsqueeze(1) # Teacher forcing\n",
" else:\n",
" # Without teacher forcing: use its own predictions as the next input\n",
" _, topi = decoder_output.topk(1)\n",
" decoder_input = topi.squeeze(-1).detach() # detach from history as input\n",
"\n",
" decoder_outputs = torch.cat(decoder_outputs, dim=1)\n",
" decoder_outputs = F.log_softmax(decoder_outputs, dim=-1)\n",
" attentions = torch.cat(attentions, dim=1)\n",
"\n",
" return decoder_outputs, decoder_hidden, attentions\n",
"\n",
"\n",
" def forward_step(self, input, hidden, encoder_outputs):\n",
" embedded = self.dropout(self.embedding(input))\n",
"\n",
" query = hidden.permute(1, 0, 2)\n",
" context, attn_weights = self.attention(query, encoder_outputs)\n",
" input_gru = torch.cat((embedded, context), dim=2)\n",
"\n",
" output, hidden = self.gru(input_gru, hidden)\n",
" output = self.out(output)\n",
"\n",
" return output, hidden, attn_weights"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:21:12.049305Z",
"end_time": "2024-06-02T19:21:12.073302Z"
}
}
},
{
"cell_type": "code",
"execution_count": 21,
"outputs": [],
"source": [
"def indexesFromSentence(lang, sentence):\n",
" return [lang.word2index[word] for word in sentence.split(' ')]\n",
"\n",
"def tensorFromSentence(lang, sentence):\n",
" indexes = indexesFromSentence(lang, sentence)\n",
" indexes.append(EOS_token)\n",
" return torch.tensor(indexes, dtype=torch.long, device=device).view(1, -1)\n",
"\n",
"def tensorsFromPair(pair):\n",
" input_tensor = tensorFromSentence(input_lang, pair[0])\n",
" target_tensor = tensorFromSentence(output_lang, pair[1])\n",
" return (input_tensor, target_tensor)\n",
"\n",
"def get_dataloader(batch_size):\n",
" input_lang, output_lang, pairs = prepareData( 'eng', 'pol', True)\n",
"\n",
" n = len(pairs)\n",
" input_ids = np.zeros((n, MAX_LENGTH), dtype=np.int32)\n",
" target_ids = np.zeros((n, MAX_LENGTH), dtype=np.int32)\n",
"\n",
" for idx, (inp, tgt) in enumerate(pairs):\n",
" inp_ids = indexesFromSentence(input_lang, inp)\n",
" tgt_ids = indexesFromSentence(output_lang, tgt)\n",
" inp_ids.append(EOS_token)\n",
" tgt_ids.append(EOS_token)\n",
" input_ids[idx, :len(inp_ids)] = inp_ids\n",
" target_ids[idx, :len(tgt_ids)] = tgt_ids\n",
"\n",
" train_data = TensorDataset(torch.LongTensor(input_ids).to(device),\n",
" torch.LongTensor(target_ids).to(device))\n",
"\n",
" train_sampler = RandomSampler(train_data)\n",
" train_dataloader = DataLoader(train_data, sampler=train_sampler, batch_size=batch_size)\n",
" return input_lang, output_lang, train_dataloader"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:23:18.301396Z",
"end_time": "2024-06-02T19:23:18.321420Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Trening"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 22,
"outputs": [],
"source": [
"def train_epoch(dataloader, encoder, decoder, encoder_optimizer,\n",
" decoder_optimizer, criterion):\n",
"\n",
" total_loss = 0\n",
" for data in dataloader:\n",
" input_tensor, target_tensor = data\n",
"\n",
" encoder_optimizer.zero_grad()\n",
" decoder_optimizer.zero_grad()\n",
"\n",
" encoder_outputs, encoder_hidden = encoder(input_tensor)\n",
" decoder_outputs, _, _ = decoder(encoder_outputs, encoder_hidden, target_tensor)\n",
"\n",
" loss = criterion(\n",
" decoder_outputs.view(-1, decoder_outputs.size(-1)),\n",
" target_tensor.view(-1)\n",
" )\n",
" loss.backward()\n",
"\n",
" encoder_optimizer.step()\n",
" decoder_optimizer.step()\n",
"\n",
" total_loss += loss.item()\n",
"\n",
" return total_loss / len(dataloader)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:23:19.166843Z",
"end_time": "2024-06-02T19:23:19.182827Z"
}
}
},
{
"cell_type": "code",
"execution_count": 23,
"outputs": [],
"source": [
"import time\n",
"import math\n",
"\n",
"def asMinutes(s):\n",
" m = math.floor(s / 60)\n",
" s -= m * 60\n",
" return '%dm %ds' % (m, s)\n",
"\n",
"def timeSince(since, percent):\n",
" now = time.time()\n",
" s = now - since\n",
" es = s / (percent)\n",
" rs = es - s\n",
" return '%s (- %s)' % (asMinutes(s), asMinutes(rs))"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:23:19.675207Z",
"end_time": "2024-06-02T19:23:19.699207Z"
}
}
},
{
"cell_type": "code",
"execution_count": 24,
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"plt.switch_backend('agg')\n",
"import matplotlib.ticker as ticker\n",
"import numpy as np\n",
"\n",
"def showPlot(points):\n",
" plt.figure()\n",
" fig, ax = plt.subplots()\n",
" # this locator puts ticks at regular intervals\n",
" loc = ticker.MultipleLocator(base=0.2)\n",
" ax.yaxis.set_major_locator(loc)\n",
" plt.plot(points)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:23:20.120325Z",
"end_time": "2024-06-02T19:23:20.833674Z"
}
}
},
{
"cell_type": "code",
"execution_count": 25,
"outputs": [],
"source": [
"def train(train_dataloader, encoder, decoder, n_epochs, learning_rate=0.001,\n",
" print_every=100, plot_every=100):\n",
" start = time.time()\n",
" plot_losses = []\n",
" print_loss_total = 0 # Reset every print_every\n",
" plot_loss_total = 0 # Reset every plot_every\n",
"\n",
" encoder_optimizer = optim.Adam(encoder.parameters(), lr=learning_rate)\n",
" decoder_optimizer = optim.Adam(decoder.parameters(), lr=learning_rate)\n",
" criterion = nn.NLLLoss()\n",
"\n",
" for epoch in range(1, n_epochs + 1):\n",
" loss = train_epoch(train_dataloader, encoder, decoder, encoder_optimizer, decoder_optimizer, criterion)\n",
" print_loss_total += loss\n",
" plot_loss_total += loss\n",
"\n",
" if epoch % print_every == 0:\n",
" print_loss_avg = print_loss_total / print_every\n",
" print_loss_total = 0\n",
" print('%s (%d %d%%) %.4f' % (timeSince(start, epoch / n_epochs),\n",
" epoch, epoch / n_epochs * 100, print_loss_avg))\n",
"\n",
" if epoch % plot_every == 0:\n",
" plot_loss_avg = plot_loss_total / plot_every\n",
" plot_losses.append(plot_loss_avg)\n",
" plot_loss_total = 0\n",
"\n",
" showPlot(plot_losses)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:23:21.920756Z",
"end_time": "2024-06-02T19:23:21.949755Z"
}
}
},
{
"cell_type": "code",
"execution_count": 98,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Reading lines...\n",
"Read 49943 sentence pairs\n",
"Trimmed to 3613 sentence pairs\n",
"Counting words...\n",
"Counted words:\n",
"pol 3070\n",
"eng 1969\n",
"0m 7s (- 2m 18s) (5 5%) 1.9851\n",
"0m 14s (- 2m 8s) (10 10%) 1.0089\n",
"0m 21s (- 1m 59s) (15 15%) 0.5189\n",
"0m 28s (- 1m 52s) (20 20%) 0.2294\n",
"0m 35s (- 1m 45s) (25 25%) 0.0961\n",
"0m 42s (- 1m 38s) (30 30%) 0.0509\n",
"0m 50s (- 1m 33s) (35 35%) 0.0355\n",
"0m 57s (- 1m 25s) (40 40%) 0.0289\n",
"1m 4s (- 1m 18s) (45 45%) 0.0249\n",
"1m 11s (- 1m 11s) (50 50%) 0.0228\n",
"1m 18s (- 1m 4s) (55 55%) 0.0207\n",
"1m 25s (- 0m 57s) (60 60%) 0.0215\n",
"1m 32s (- 0m 49s) (65 65%) 0.0249\n",
"1m 39s (- 0m 42s) (70 70%) 0.0184\n",
"1m 47s (- 0m 35s) (75 75%) 0.0172\n",
"1m 55s (- 0m 28s) (80 80%) 0.0166\n",
"2m 3s (- 0m 21s) (85 85%) 0.0163\n",
"2m 11s (- 0m 14s) (90 90%) 0.0163\n",
"2m 18s (- 0m 7s) (95 95%) 0.0176\n",
"2m 27s (- 0m 0s) (100 100%) 0.0256\n"
]
},
{
"data": {
"text/plain": "<Figure size 640x480 with 0 Axes>"
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": "<Figure size 640x480 with 1 Axes>",
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGdCAYAAADAAnMpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA9OElEQVR4nO3de3yU5Z3///cckkmCyXAIOUEgEcUTGChKjKigpmJ0qfy6W6m6onhoa7HFpu1qaoW17ZraqutWEZSK2K8HUFexVYvFKFAxSjlkKx5QJJAImUBQZnIgp5n790cyQwaSkAmZ3JnM6/l43I9k7rmumc/t7TDv3Nd93bfFMAxDAAAAJrGaXQAAAIhuhBEAAGAqwggAADAVYQQAAJiKMAIAAExFGAEAAKYijAAAAFMRRgAAgKnsZhfQEz6fT/v27VNiYqIsFovZ5QAAgB4wDEO1tbXKyMiQ1dr18Y+ICCP79u1TZmam2WUAAIBeqKys1OjRo7t8PiLCSGJioqS2jUlKSjK5GgAA0BMej0eZmZmB7/GuREQY8Q/NJCUlEUYAAIgwxzvFghNYAQCAqQgjAADAVIQRAABgKsIIAAAwFWEEAACYijACAABMRRgBAACmCimMFBcX69xzz1ViYqJSUlI0e/Zs7dix47j9XnzxRZ1++umKi4vTxIkT9cYbb/S6YAAAMLiEFEbWr1+v+fPn6/3339fatWvV0tKiyy67TPX19V32ee+993TNNdfo5ptv1rZt2zR79mzNnj1b27dvP+HiAQBA5LMYhmH0tvOBAweUkpKi9evX66KLLuq0zZw5c1RfX6/XXnstsO68887TpEmTtHTp0h69j8fjkdPplNvt5gqsAABEiJ5+f5/QOSNut1uSNHz48C7blJaWKj8/P2jdzJkzVVpa2mWfpqYmeTyeoAUAAAxOvQ4jPp9Pd9xxh6ZNm6YJEyZ02c7lcik1NTVoXWpqqlwuV5d9iouL5XQ6Awt37AUAYPDqdRiZP3++tm/frpUrV/ZlPZKkoqIiud3uwFJZWdnn7yFJq7ft1d2vfKgte74Oy+sDAIDj69Vde2+//Xa99tpr2rBhg0aPHt1t27S0NFVXVwetq66uVlpaWpd9HA6HHA5Hb0oLydpPqvX6P6uUnTxEU8YOC/v7AQCAY4V0ZMQwDN1+++165ZVX9Pbbbys7O/u4ffLy8lRSUhK0bu3atcrLywut0jDIHjFEklRe0/VsIAAAEF4hHRmZP3++nnvuOb366qtKTEwMnPfhdDoVHx8vSZo7d65GjRql4uJiSdKCBQs0ffp0Pfjgg7ryyiu1cuVKbd68WU888UQfb0roxo5IkCTtOdhgciUAAESvkI6MLFmyRG63WzNmzFB6enpgWbVqVaBNRUWFqqqqAo/PP/98Pffcc3riiSeUk5Ojl156SatXr+72pNf+kp3MkREAAMwW0pGRnlySZN26dces+853vqPvfOc7obxVvxjbPkyzz31YTa1eOew2kysCACD6RPW9aZJPitVJDrsMQ6r8iqEaAADMENVhxGKxBM4b2V1DGAEAwAxRHUYkKav9vJHdBzlvBAAAMxBG/EdGCCMAAJiCMNJ+EivDNAAAmIMwwjANAACmivow4j+Bdd+htum9AACgf0V9GBl5kkNDYm3yGVLlV4fNLgcAgKgT9WGkbXqv/7wRhmoAAOhvUR9GpCOXhee8EQAA+h9hRNwwDwAAMxFGxIwaAADMRBhRh2uNEEYAAOh3hBFJWcltwzR7vz6s5lafydUAABBdCCM6anrv15w3AgBAfyKMiOm9AACYiTDSzj9Us5sZNQAA9CvCSLssjowAAGAKwkg7ZtQAAGAOwkg7rjUCAIA5CCPtskYwvRcAADMQRtqNTHQogem9AAD0O8JIu47Te/cwVAMAQL8JOYxs2LBBs2bNUkZGhiwWi1avXn3cPs8++6xycnKUkJCg9PR03XTTTTp48GBv6g0r/1BNeQ1HRgAA6C8hh5H6+nrl5ORo8eLFPWq/ceNGzZ07VzfffLM++ugjvfjii9q0aZNuvfXWkIsNN/9JrBwZAQCg/9hD7VBQUKCCgoIety8tLVVWVpZ+/OMfS5Kys7P1/e9/X/fff3+obx12/iMjXPgMAID+E/ZzRvLy8lRZWak33nhDhmGourpaL730kq644oou+zQ1Ncnj8QQt/YELnwEA0P/CHkamTZumZ599VnPmzFFsbKzS0tLkdDq7HeYpLi6W0+kMLJmZmeEuU9KRYZovv25gei8AAP0k7GHk448/1oIFC7Rw4UJt2bJFa9as0e7du/WDH/ygyz5FRUVyu92BpbKyMtxlSpJSEh2Kj2mb3vsl03sBAOgXIZ8zEqri4mJNmzZNP//5zyVJZ599toYMGaILL7xQv/nNb5Senn5MH4fDIYfDEe7SjtE2vTdBn7pqtedgg04eeVK/1wAAQLQJ+5GRhoYGWa3Bb2Oz2SRJhmGE++1Dlt0+VFPOeSMAAPSLkMNIXV2dysrKVFZWJkkqLy9XWVmZKioqJLUNscydOzfQftasWXr55Ze1ZMkS7dq1Sxs3btSPf/xjTZ06VRkZGX2zFX2IC58BANC/Qh6m2bx5sy6++OLA48LCQknSDTfcoBUrVqiqqioQTCTpxhtvVG1trR599FH99Kc/1dChQ3XJJZcMyKm9kpSd3H7hM6b3AgDQLyzGQBwrOYrH45HT6ZTb7VZSUlJY3+v9XQf13Sfe19gRCVr/84uP3wEAAHSqp9/f3JvmKNmB6b2H1eJlei8AAOFGGDmKf3qv12foy68Pm10OAACDHmHkKP7pvRJXYgUAoD8QRjoRuCw8M2oAAAg7wkgnxiZzZAQAgP5CGOlEduDICNN7AQAIN8JIJ7jwGQAA/Ycw0gn/9N5KpvcCABB2hJFOpCQ6FBdjlddnaC/TewEACCvCSCesVktgRk05QzUAAIQVYaQL/muN7GFGDQAAYUUY6UJWMjNqAADoD4SRLnDhMwAA+gdhpAuBMMIwDQAAYUUY6UJW+1VYuXsvAADhRRjpQmpinOJirGplei8AAGFFGOmC1WrR2OGcNwIAQLgRRrqRxQ3zAAAIO8JIN7K4YR4AAGFHGOnGkWuNcGQEAIBwIYx0I3AVVo6MAAAQNoSRbviHaSq/alAr03sBAAgLwkg30pLi5LC3T+89xPReAADCIeQwsmHDBs2aNUsZGRmyWCxavXr1cfs0NTXp7rvv1tixY+VwOJSVlaXly5f3pt5+ZbVaAkM1nMQKAEB42EPtUF9fr5ycHN1000369re/3aM+V199taqrq/Xkk0/qlFNOUVVVlXy+yBj2yBoxRJ9V12l3Tb2mjx9pdjkAAAw6IYeRgoICFRQU9Lj9mjVrtH79eu3atUvDhw+XJGVlZYX6tqZhRg0AAOEV9nNG/vznP+ucc87R7373O40aNUrjx4/Xz372Mx0+3PU5GE1NTfJ4PEGLWbhhHgAA4RXykZFQ7dq1S++++67i4uL0yiuvqKamRj/84Q918OBBPfXUU532KS4u1r333hvu0noki+m9AACEVdiPjPh8PlksFj377LOaOnWqrrjiCj300EN6+umnuzw6UlRUJLfbHVgqKyvDXWaX/MM0FUzvBQAgLMIeRtLT0zVq1Cg5nc7AujPOOEOGYejLL7/stI/D4VBSUlLQYpaO03v3HWo0rQ4AAAarsIeRadOmad++faqrqwus++yzz2S1WjV69Ohwv/0J6zi9t5yTWAEA6HMhh5G6ujqVlZWprKxMklReXq6ysjJVVFRIahtimTt3bqD9tddeqxEjRmjevHn6+OOPtWHDBv385z/XTTfdpPj4+L7ZijAb234S6x7CCAAAfS7kMLJ582ZNnjxZkydPliQVFhZq8uTJWrhwoSSpqqoqEEwk6aSTTtLatWt16NAhnXPOObruuus0a9Ys/eEPf+ijTQi/7PbzRsqZUQMAQJ8LeTbNjBkzZBhGl8+vWLHimHWnn3661q5dG+pbDRjcMA8AgPDh3jQ9kM21RgAACBvCSA+MbR+mqfya6b0AAPQ1wkgPpCfFKdZuVYvXUJWb6b0AAPQlwkgPWK0WjR3ePr2XoRoAAPoUYaSHmN4LAEB4EEZ6KDvZf2SEGTUAAPQlwkgPcWQEAIDwIIz0UODCZ4QRAAD6FGGkh/wXPqv8qkFeX9cXfQMAAKEhjPRQhjM+ML1336HDZpcDAMCgQRjpIavVojHt03t3M1QDAECfIYyEIIvLwgMA0OcIIyHIGuE/MsL0XgAA+gphJARZyRwZAQCgrxFGQhAYpuGcEQAA+gxhJARZyf7pvYeZ3gsAQB8hjIQg3RmvWJtVzV4f03sBAOgjhJEQ2KwWjWk/iXUPJ7ECANAnCCMh8s+o4bLwAAD0DcJIiAI3zGNGDQAAfYIwEqLA9F6OjAAA0CcIIyHiwmcAAPQtwkiI/NcaqTjI3XsBAOgLIYeRDRs2aNasWcrIyJDFYtHq1at73Hfjxo2y2+2aNGlSqG87YGQMPTK9t8rN9F4AAE5UyGGkvr5eOTk5Wrx4cUj9Dh06pLlz5+rSSy8N9S0HFJvVoszh8ZKk3TUM1QAAcKLsoXYoKChQQUFByG/0gx/8QNdee61sNltIR1MGoqwRQ/TFgXrtPlivC05NNrscAAAiWr+cM/LUU09p165dWrRoUY/aNzU1yePxBC0DCTfMAwCg74Q9jHz++ee666679Mwzz8hu79mBmOLiYjmdzsCSmZkZ5ipDw4waAAD6TljDiNfr1bXXXqt7771X48eP73G/oqIiud3uwFJZWRnGKkPHtUYAAOg7IZ8zEora2lpt3rxZ27Zt0+233y5J8vl8MgxDdrtdf/vb33TJJZcc08/hcMjhcISztBNy9PRem9VickUAAESusIaRpKQkffjhh0HrHnvsMb399tt66aWXlJ2dHc63D5uMofGKsVkC03tHD0swuyQAACJWyGGkrq5OO3fuDDwuLy9XWVmZhg8frjFjxqioqEh79+7Vn/70J1mtVk2YMCGof0pKiuLi4o5ZH0napvcmaNeBeu052EAYAQDgBIR8zsjmzZs1efJkTZ48WZJUWFioyZMna+HChZKkqqoqVVRU9G2VA1D2CM4bAQCgL1gMwxjw1zT3eDxyOp1yu91KSkoyuxxJ0q/+8rGWbyzXrRdm6+4rzzS7HAAABpyefn9zb5peyk5mei8AAH2BMNJLY0dw4TMAAPoCYaSX/NN793zVIB937wUAoNcII72UMTSubXpvq09VnkazywEAIGIRRnrJbrMqs31K7x6GagAA6DXCyAnwXxa+nOm9AAD0GmHkBIxtv2HeHmbUAADQa4SRE5DtPzLCMA0AAL1GGDkB/um9eximAQCg1wgjJyA7EEaY3gsAQG8RRk5AxtA42a0WNbX65GJ6LwAAvUIYOQF2m1VjhrdfFp7zRgAA6BXCyAnyz6jhHjUAAPQOYeQE+a81wkmsAAD0DmHkBPnvUcP0XgAAeocwcoKOHBlhmAYAgN4gjJygrMA5I/VM7wUAoBcIIydo1ND4wPTe6lqm9wIAECrCyAmy26zKbJ/ey3kjAACEjjDSB7hhHgAAvUcY6QP+GTVc+AwAgNARRvpAx5NYAQBAaAgjfcA/vXd3DcM0AACEKuQwsmHDBs2aNUsZGRmyWCxavXp1t+1ffvllffOb39TIkSOVlJSkvLw8vfnmm72td0DyD9Ps+YrpvQAAhCrkMFJfX6+cnBwtXry4R+03bNigb37zm3rjjTe0ZcsWXXzxxZo1a5a2bdsWcrED1ehhbdN7G1uY3gsAQKjsoXYoKChQQUFBj9s//PDDQY/vu+8+vfrqq/rLX/6iyZMnh/r2A5LdZtXoYfHafbBBu2salO6MN7skAAAiRr+fM+Lz+VRbW6vhw4d32aapqUkejydoGegC541wEisAACHp9zDywAMPqK6uTldffXWXbYqLi+V0OgNLZmZmP1bYO4HpvYQRAABC0q9h5LnnntO9996rF154QSkpKV22KyoqktvtDiyVlZX9WGXv+Kf37mFGDQAAIQn5nJHeWrlypW655Ra9+OKLys/P77atw+GQw+Hop8r6xliGaQAA6JV+OTLy/PPPa968eXr++ed15ZVX9sdb9rvsDsM0hsH0XgAAeirkIyN1dXXauXNn4HF5ebnKyso0fPhwjRkzRkVFRdq7d6/+9Kc/SWobmrnhhhv0P//zP8rNzZXL5ZIkxcfHy+l09tFmmG/UsHjZ/NN7PU1Kc8aZXRIAABEh5CMjmzdv1uTJkwPTcgsLCzV58mQtXLhQklRVVaWKiopA+yeeeEKtra2aP3++0tPTA8uCBQv6aBMGhhibVZnD2qb0MlQDAEDPhXxkZMaMGd0OQ6xYsSLo8bp160J9i4g1dsSQ9muN1Ou8k0eYXQ4AABGBe9P0oSM3zGNGDQAAPUUY6UNHbpjHMA0AAD1FGOlDXPgMAIDQEUb6kP/IyJ6DDUzvBQCghwgjfWh0+/Tewy1e7a9tMrscAAAiAmGkD8W0371Xkso5bwQAgB4hjPSxsSP8QzWEEQAAeoIw0sey26f3lnPDPAAAeoQw0sc4MgIAQGgII30sO3D3Xo6MAADQE4SRPja2fZhmD3fvBQCgRwgjfWz0sATZrBY1NHt1gOm9AAAcF2Gkj8XarRo1lOm9AAD0FGEkDDpeiRUAAHSPMBIG/rv3ljOjBgCA4yKMhEEW03sBAOgxwkgYZCVz4TMAAHqKMBIGHS98xvReAAC6RxgJg8xhCbJaxPReAAB6gDASBrF2q0a1372XK7ECANA9wkiY+E9i3c21RgAA6BZhJEwCYYQZNQAAdIswEiZZyYQRAAB6IuQwsmHDBs2aNUsZGRmyWCxavXr1cfusW7dO3/jGN+RwOHTKKadoxYoVvSg1svgvfLab6b0AAHQr5DBSX1+vnJwcLV68uEfty8vLdeWVV+riiy9WWVmZ7rjjDt1yyy168803Qy42khy5JDzTewEA6I491A4FBQUqKCjocfulS5cqOztbDz74oCTpjDPO0Lvvvqv//u//1syZM0N9+4jhn95b3z69NyUpzuySAAAYkMJ+zkhpaany8/OD1s2cOVOlpaXhfmtTxdqtGjfyJEnS5j1fm1wNAAADV9jDiMvlUmpqatC61NRUeTweHT58uNM+TU1N8ng8QUskumj8SEnSuh37Ta4EAICBa0DOpikuLpbT6QwsmZmZZpfUK9Pbw8j6zw5w3ggAAF0IexhJS0tTdXV10Lrq6molJSUpPj6+0z5FRUVyu92BpbKyMtxlhsXU7OGKj7Gp2tOkT121ZpcDAMCAFPYwkpeXp5KSkqB1a9euVV5eXpd9HA6HkpKSgpZIFBdjU964EZKkdTsOmFwNAAADU8hhpK6uTmVlZSorK5PUNnW3rKxMFRUVktqOasydOzfQ/gc/+IF27dql//iP/9Cnn36qxx57TC+88IJ+8pOf9M0WDHBHhmo4bwQAgM6EHEY2b96syZMna/LkyZKkwsJCTZ48WQsXLpQkVVVVBYKJJGVnZ+v111/X2rVrlZOTowcffFB//OMfB/W03o5mnNYWRjbv/lq1jS0mVwMAwMBjMSLgzEqPxyOn0ym32x2RQzYXP7BO5TX1WvrvU3T5hDSzywEAoF/09Pt7QM6mGWw6zqoBAADBCCP9YHr7UM36HfuZ4gsAwFEII/3gvOwRirVbtc/dqJ3768wuBwCAAYUw0g/iY20672Sm+AIA0BnCSD+Z4b80PFN8AQAIQhjpJ/7zRv5R/rXqm1pNrgYAgIGDMNJPTk4eoszh8Wr2+lT6xUGzywEAYMAgjPQTi8WiGeNTJDFUAwBAR4SRfuS/3si6HdzFFwAAP8JIPzr/lBGKtVn15deHtaum3uxyAAAYEAgj/Sgh1q6p2cMlMcUXAAA/wkg/49LwAAAEI4z0M/9dfN/fdVCHm70mVwMAgPkII/3slJSTNGpovJpbfXp/F1N8AQAgjPQzi8WiixiqAQAggDBiAv9QzbodXG8EAADCiAmmnZIsu9Wi3QcbtJspvgCAKEcYMcFJDrvOyRomiaEaAAAIIyaZcVr7peEZqgEARDnCiEn8542U7jqoxham+AIAohdhxCSnpSYqLSlOjS0+bSr/yuxyAAAwDWHEJBaLJejGeQAARCvCiImm+6f4fsZ5IwCA6EUYMdG0U5Jls1q060C9Kr9qMLscAABM0aswsnjxYmVlZSkuLk65ubnatGlTt+0ffvhhnXbaaYqPj1dmZqZ+8pOfqLGxsVcFDybO+BhNGdM2xXcdU3wBAFEq5DCyatUqFRYWatGiRdq6datycnI0c+ZM7d/f+VDDc889p7vuukuLFi3SJ598oieffFKrVq3SL37xixMufjDwD9WsZ4ovACBKhRxGHnroId16662aN2+ezjzzTC1dulQJCQlavnx5p+3fe+89TZs2Tddee62ysrJ02WWX6Zprrjnu0ZRo4T+J9b0vDqqplSm+AIDoE1IYaW5u1pYtW5Sfn3/kBaxW5efnq7S0tNM+559/vrZs2RIIH7t27dIbb7yhK664osv3aWpqksfjCVoGq7MykjQy0aGGZq827/7a7HIAAOh3IYWRmpoaeb1epaamBq1PTU2Vy+XqtM+1116rX/3qV7rgggsUExOjcePGacaMGd0O0xQXF8vpdAaWzMzMUMqMKBaLRRedyo3zAADRK+yzadatW6f77rtPjz32mLZu3aqXX35Zr7/+un7961932aeoqEhutzuwVFZWhrtMU/mvxsp9agAA0cgeSuPk5GTZbDZVV1cHra+urlZaWlqnfe655x5df/31uuWWWyRJEydOVH19vb73ve/p7rvvltV6bB5yOBxyOByhlBbRLjw1WVaL9Fl1nfYdOqyMofFmlwQAQL8J6chIbGyspkyZopKSksA6n8+nkpIS5eXlddqnoaHhmMBhs9kkSYZhhFrvoDQ0IVaTModK4ugIACD6hDxMU1hYqGXLlunpp5/WJ598ottuu0319fWaN2+eJGnu3LkqKioKtJ81a5aWLFmilStXqry8XGvXrtU999yjWbNmBUIJuIsvACB6hTRMI0lz5szRgQMHtHDhQrlcLk2aNElr1qwJnNRaUVERdCTkl7/8pSwWi375y19q7969GjlypGbNmqX/+q//6rutGARmnDZSD639TBt3HlRzq0+xdi6OCwCIDhYjAsZKPB6PnE6n3G63kpKSzC4nLHw+Q+f+11s6WN+sld87T+edPMLskgAAOCE9/f7mz+8Bwmq16CLu4gsAiEKEkQHEP8WX80YAANGEMDKAXHjqSFks0qeuWlV7uJEgACA6EEYGkOFDYnX26KGSpPUM1QAAogRhZICZ4T9v5DOGagAA0YEwMsBMbz9v5O+f16jV6zO5GgAAwo8wMsDkjB6qYQkxqm1s1bbKQ2aXAwBA2BFGBhib1aILuYsvACCKEEYGoOnjuYsvACB6EEYGIP/Fz7bv9Wh/LVN8AQCDG2FkABqZ6NCEUW2Xzd3wWY3J1QAAEF6EkQFqxvi2u/gyVAMAGOwIIwPUjMAU3wPy+gb8vQwBAOg1wsgANSlzqJLi7DrU0KIypvgCAAYxwsgAZbdZA1N8GaoBAAxmhJEBzH811vVcbwQAMIgRRgYw//VG/rnXrYN1TSZXAwBAeBBGBrDUpDidkZ4kw2i7Vw0AAIMRYWSA88+q4dLwAIDBijAywPmHajZ8XiMfU3wBAIMQYWSAmzJ2mBIddn1V36wP97rNLgcAgD5HGBngYmxWTTslWZK0bgdTfAEAgw9hJAL4p/iu+4zzRgAAg0+vwsjixYuVlZWluLg45ebmatOmTd22P3TokObPn6/09HQ5HA6NHz9eb7zxRq8Kjkb+k1j/r/KQvq5vNrkaAAD6VshhZNWqVSosLNSiRYu0detW5eTkaObMmdq/v/O/2pubm/XNb35Tu3fv1ksvvaQdO3Zo2bJlGjVq1AkXHy3SnfE6LTVRPkP6+06m+AIABpeQw8hDDz2kW2+9VfPmzdOZZ56ppUuXKiEhQcuXL++0/fLly/XVV19p9erVmjZtmrKysjR9+nTl5OSccPHR5MjVWDlvBAAwuIQURpqbm7Vlyxbl5+cfeQGrVfn5+SotLe20z5///Gfl5eVp/vz5Sk1N1YQJE3TffffJ6/V2+T5NTU3yeDxBS7SbMf7IfWqY4gsAGExCCiM1NTXyer1KTU0NWp+amiqXy9Vpn127dumll16S1+vVG2+8oXvuuUcPPvigfvOb33T5PsXFxXI6nYElMzMzlDIHpXOyhish1qaauiZ9XEU4AwAMHmGfTePz+ZSSkqInnnhCU6ZM0Zw5c3T33Xdr6dKlXfYpKiqS2+0OLJWVleEuc8CLtVt1/ri2Kb7cxRcAMJiEFEaSk5Nls9lUXV0dtL66ulppaWmd9klPT9f48eNls9kC68444wy5XC41N3c+M8ThcCgpKSloAZeGBwAMTiGFkdjYWE2ZMkUlJSWBdT6fTyUlJcrLy+u0z7Rp07Rz5075fL7Aus8++0zp6emKjY3tZdnRyX9p+K0Vh+Q+3GJyNQAA9I2Qh2kKCwu1bNkyPf300/rkk0902223qb6+XvPmzZMkzZ07V0VFRYH2t912m7766istWLBAn332mV5//XXdd999mj9/ft9tRZTIHJ6gcSOHyOsztJEpvgCAQcIeaoc5c+bowIEDWrhwoVwulyZNmqQ1a9YETmqtqKiQ1Xok42RmZurNN9/UT37yE5199tkaNWqUFixYoDvvvLPvtiKKzDgtRV8cKNe6Hft1xcR0s8sBAOCEWQzDGPDzRD0ej5xOp9xud9SfP7LhswOau3yTUpMcer/oUlksFrNLAgCgUz39/ubeNBFmavZwxcfYVO1p0qeuWrPLAQDghBFGIkxcjE1540ZI4i6+AIDBgTASgfyzapjiCwAYDAgjEch/vZEte75WbSNTfAEAkY0wEoHGjhii7OQhavUZ2rjzoNnlAABwQggjEWp64MZ5DNUAACIbYSRCTW8fqln78X41tXZ9B2QAAAY6wkiEOn/cCKUlxammrkn/u2Wv2eUAANBrhJEI5bDbdOtFJ0uSlq7/Qq1e33F6AAAwMBFGItg1UzM1fEisKr5q0F/+uc/scgAA6BXCSARLiLXr5guyJUmPvfOFfL4Bf2V/AACOQRiJcNfnjVVinF2f76/T3z52mV0OAAAhI4xEuKS4GN2QlyVJevSdnYqA+x4CABCEMDII3HRBtuJjbNq+16P1n3G/GgBAZCGMDALDh8Tq2twxkqTF7+w0uRoAAEJDGBkkvnfRyYq1WfWP3V/rg11cIh4AEDkII4NEalKc/u2c0ZLazh0BACBSEEYGkdumj5PNatHfP6/R/1UeMrscAAB6hDAyiGQOT9BVORmSOHcEABA5CCODzA8vHieLRfrbx9Xa4ao1uxwAAI6LMDLInJKSqMvPSpMkPbaOoyMAgIGPMDIIzb/4FEnSX/5vn3bX1JtcDQAA3SOMDEITRjk147SR8hltd/QFAGAg61UYWbx4sbKyshQXF6fc3Fxt2rSpR/1Wrlwpi8Wi2bNn9+ZtEYLb24+O/O/WL7Xv0GGTqwEAoGshh5FVq1apsLBQixYt0tatW5WTk6OZM2dq//793fbbvXu3fvazn+nCCy/sdbHouXOyhis3e7havIae2LDL7HIAAOhSyGHkoYce0q233qp58+bpzDPP1NKlS5WQkKDly5d32cfr9eq6667Tvffeq5NPPvmECkbP3X5J29GRlf+oUE1dk8nVAADQuZDCSHNzs7Zs2aL8/PwjL2C1Kj8/X6WlpV32+9WvfqWUlBTdfPPNPXqfpqYmeTyeoAWhu+CUZOWMdqqxxacn3y03uxwAADoVUhipqamR1+tVampq0PrU1FS5XK5O+7z77rt68skntWzZsh6/T3FxsZxOZ2DJzMwMpUy0s1gsgZk1/690j9wNLSZXBADAscI6m6a2tlbXX3+9li1bpuTk5B73KyoqktvtDiyVlZVhrHJwyz8jVaelJqquqVVPl+42uxwAAI5hD6VxcnKybDabqqurg9ZXV1crLS3tmPZffPGFdu/erVmzZgXW+Xy+tje227Vjxw6NGzfumH4Oh0MOhyOU0tAFq9WiH148TgtWlmn5xnLdfEG2hjhC2u0AAIRVSEdGYmNjNWXKFJWUlATW+Xw+lZSUKC8v75j2p59+uj788EOVlZUFlm9961u6+OKLVVZWxvBLP/mXszOUNSJBhxpa9NwHFWaXAwBAkJD/RC4sLNQNN9ygc845R1OnTtXDDz+s+vp6zZs3T5I0d+5cjRo1SsXFxYqLi9OECROC+g8dOlSSjlmP8LFZLbptxjjd+b8fatnfd+n6vLGKi7GZXRYAAJJ6EUbmzJmjAwcOaOHChXK5XJo0aZLWrFkTOKm1oqJCVisXdh1o/r/Jo/XwW5+ryt2ol7Z8qX8/b6zZJQEAIEmyGIZhmF3E8Xg8HjmdTrndbiUlJZldTsR6amO57v3Lxxo9LF7v/GyGYmyERgBA+PT0+5tvoyjy3XPHaMSQWH359WH9uWyf2eUAACCJMBJV4mNtuvnCbEnSY+t2yucb8AfFAABRgDASZa4/b6yS4uz64kC91nzU+YXqAADoT4SRKJMYF6Mbz8+SJC1+Z6ci4JQhAMAgRxiJQvOmZSsh1qaP9nm0bscBs8sBAEQ5wkgUGjYkVtfljpEkPcrREQCAyQgjUerWC09WrN2qLXu+1vu7vjK7HABAFCOMRKmUpDhdfc5oSW3njgAAYBbCSBT7/kXjZLNa9O7OGpVVHjK7HABAlCKMRLHM4QmaPWmUJOnRtzk6AgAwB2Ekyv3w4nGyWKS3PqnWpy6P2eUAAKIQYSTKjRt5kq6YkC5JWvzOFyZXAwCIRoQR6IcXj5Mkvf7PfSqvqTe5GgBAtCGMQGdlOHXJ6SnyGdKSdZw7AgDoX4QRSJLmX3yKJOnlrXu199Bhk6sBAEQTwggkSVPGDlPeySPU6jP0xHrOHQEA9B/CCAJuv6Tt6MjKf1TqQG2TydUAAKIFYQQB548boUmZQ9XU6tMf391ldjkAgChBGEGAxWLR7e3njjxTukeHGppNrggAEA0IIwhy6RkpOj0tUfXNXq14b7fZ5QAAogBhBEEsFktgZs1TG3errqnV5IoAAIMdYQTHuGJiuk5OHiL34RY98vbnZpcDABjkCCM4hs1q0YL8UyVJj6/fpQf/tkOGYZhcFQBgsOpVGFm8eLGysrIUFxen3Nxcbdq0qcu2y5Yt04UXXqhhw4Zp2LBhys/P77Y9BoarJo3SXQWnS5IeeXunfvP6JwQSAEBYhBxGVq1apcLCQi1atEhbt25VTk6OZs6cqf3793faft26dbrmmmv0zjvvqLS0VJmZmbrsssu0d+/eEy4e4fWD6eN077fOkiQ9+W65frl6u3w+AgkAoG9ZjBD/3M3NzdW5556rRx99VJLk8/mUmZmpH/3oR7rrrruO29/r9WrYsGF69NFHNXfu3B69p8fjkdPplNvtVlJSUijlog+88I9K3fnyP2UY0re/MUq/+9ezZbcxwgcA6F5Pv79D+kZpbm7Wli1blJ+ff+QFrFbl5+ertLS0R6/R0NCglpYWDR8+vMs2TU1N8ng8QQvMc/W5mXp4ziTZrBa9vHWvFqwsU3Orz+yyAACDREhhpKamRl6vV6mpqUHrU1NT5XK5evQad955pzIyMoICzdGKi4vldDoDS2ZmZihlIgyumjRKi6/9hmJsFr3+YZVue2aLGlu8ZpcFABgE+vVY+29/+1utXLlSr7zyiuLi4rpsV1RUJLfbHVgqKyv7sUp05fIJaVo29xw57FaVfLpftzy9WQ3NXIcEAHBiQgojycnJstlsqq6uDlpfXV2ttLS0bvs+8MAD+u1vf6u//e1vOvvss7tt63A4lJSUFLRgYJhxWopWzJuqhFib3t1ZoxuWb1JtY4vZZQEAIlhIYSQ2NlZTpkxRSUlJYJ3P51NJSYny8vK67Pe73/1Ov/71r7VmzRqdc845va8WA0LeuBH6fzfnKjHOrn/s/lr//scPuI8NAKDXQh6mKSws1LJly/T000/rk08+0W233ab6+nrNmzdPkjR37lwVFRUF2t9///265557tHz5cmVlZcnlcsnlcqmurq7vtgL9bsrYYXr+1vM0LCFG//elW9994n3V1DWZXRYAIAKFHEbmzJmjBx54QAsXLtSkSZNUVlamNWvWBE5qraioUFVVVaD9kiVL1NzcrH/7t39Tenp6YHnggQf6bitgigmjnFr5vTwln+TQp65azXm8VC53o9llAQAiTMjXGTED1xkZ2HYdqNN1f/xAVe5GjRmeoGdvyVXm8ASzywIAmCws1xkBOnPyyJP0wvfzNGZ4giq+atCcx0tVXlNvdlkAgAhBGEGfyByeoBe+n6dxI4don7tRVz9eqs+qa80uCwAQAQgj6DNpzjit+n6eTk9L1IHaJs15vFTb97rNLgsAMMARRtCnkk9yaOX3zlPOaKe+bmjRNcve15Y9X5tdFgBgACOMoM8NTYjVM7fk6tysYaptbNX1T36g0i8Oml0WAGCAIowgLBLjYvT0TVN1wSnJamj26sanNmndjv1mlwUAGIAIIwibhFi7/njDObr09BQ1tfp06582682PenZDRQBA9CCMIKziYmxa8u9TdOXEdLV4Df3w2a16tWyv2WUBAAYQwgjCLtZu1f98d5K+PXmUvD5Dd6wq0wv/4E7MAIA2hBH0C7vNqge+k6Nrc8fIMKT/+N9/asXGckXABYABAGHG5eDRrwzD0G9e/0RPvlsuSRo7IkGXT0hTwYR05Yx2ymKxmFwhAKCv9PT7mzCCfmcYhh59e6cefWenmlp9gfUZzjhdPiFdBRPTNGXMMFmtBBMAiGSEEQx49U2temfHfv11u0vvfLpfDc3ewHMjEx2aeVaqCiakKzd7uOw2RhQBINIQRhBRGlu8Wv/ZAa3Z7tJbn1SrtrE18NywhBhddmaaLp+YpmnjkhVrJ5gAQCQgjCBiNbf6tPGLGv31wyqt/bhaXze0BJ5LjLPrm2ek6vIJabpo/EjFxdhMrBQA0B3CCAaFVq9PH5R/pb9ur9KbH1XrQG1T4LmEWJsuPj1FV0xI14zTRmqIw25ipQCAoxFGMOh4fYa27Pm6LZhsd2mfuzHwnMNu1fTxI1UwMU2XnpGqpLgYEysFAEiEEQxyhmHo/75066/bq/TXD12q+Koh8FyMzaILTknWBaeO1KihcUpzxivdGafkkxyyMUMHAPoNYQRRwzAMfVzl0ZrtLv11u0s799d12s5utSg1KU5pzrYlw3kkqLQ9jtfIRAILAPQVwgii1ufVtVqz3aVPXB5VuRvlcjeq2tMoXw/+T7dZLUpJdCjNGad0Z5zSO4QV/+OURAdTjQGgB3r6/c0Zfxh0Tk1N1KmpiUHrWr0+HahrCoSTtp+Hta/9scvdKJenUV6foar257d18fpWS9t1UIbGxyrBYdNJDrsSYm0aEmtXgqPt5xD/ug7PDXHYNcRhU0Jsh5+xNoINgKhHGEFUsNus7Uc54rts4/UZqgkElsOBUNLxcbWnUS1eQ9WeJlV7mrp8rVA47NajQktbUHHYrXLEWBVrsyrWbpXDblOs3f978DqHrfO2/nZBfWxtz9msFtmtFq50208Mw1CL15AhQ7E2K7c+gOl8PkP1za2qbWxVXVOr0pxxpp38TxgB2tnazylJTYqTMod22sbnM1RT3ySXuzHwAW5oblV9kzfws76pVfXN3qPWt69r/1nf1KrW9nGjplafmlqb9VV9P25sBxZL2/k0VktbOLFZLbLbOoQVi0V2myXw2Ga1Btr5F7s1+HmbVbJbrcHPBV7D2mmf4Pc49r38z9vav8QNST7DkM9o+6I3DMmQIZ/vyHP+9T7/c4akDn18Rls7BdpLXsNQq9dQc6tPLV6fmr1tP1taDTX7H3d8rn19S/vS1u/IOv/rtHiPjBParZbgI2dBR9fajpgFHUHrcCStq+fjY2wEnCjS1OpVXWNbkKhtbFVtU0vg97rGlsC/T57GVtU2tqiuyd+2JdCvrrlVHU/UWHLdN1QwMd2U7elVGFm8eLF+//vfy+VyKScnR4888oimTp3aZfsXX3xR99xzj3bv3q1TTz1V999/v6644opeFw2YxWq1KCUxTimJcSf8Wk2tXjU0eVXf3KqG9oDS0OwNBJzmVp+aWn2Bn0d+9wY9F1jn9ampxRf00/9cx/5HMwy1f1Ea6ptjPTieVp8hT2PbF0VfsVikhJi2o15Wi0UWi0VWS1vIbnssWS1tgc7/uzXw0yKrVYF+tg7rLUe9hsVikaX9/dp+HnksWTqsl9qeaf/d/7iTfh0f66h+7as6/G458nsge1mO3zbw3ym8gc3rM+RtD8JeX3vg9RnyGYa87eE38NjXFoq9xlHt2n/6jLbXMwxDrT5D9f5A0dTa6We5t2JsFiXGxfTovLpwCTmMrFq1SoWFhVq6dKlyc3P18MMPa+bMmdqxY4dSUlKOaf/ee+/pmmuuUXFxsf7lX/5Fzz33nGbPnq2tW7dqwoQJfbIRQCRy2G1y2G0aNiS2397TP1TQ7PW1/aPpM9Tqa/u91dv2D2Crf73XCPzD6vX5Ao9b/eu8R9p2bBNY52/r88nrU9vzQev979HJel8n79mhVunIl5f/i9T/xeP/EvY/1/ELtOOXstp/tq1vb9O+LsZmVayt/afd2uGnRbE2q2L86zo873/uyGOrYu3BrxFjs0qG1NDSFjyPhNHgo2sNzcFH0o73fNu+VdtRtw73eMLgd5LDrpMcdiXG2XVSnF2JcTFKjLMrsX1dYlxM4PnAc3H+Pm2PHXbzhw1Dnk2Tm5urc889V48++qgkyefzKTMzUz/60Y901113HdN+zpw5qq+v12uvvRZYd95552nSpElaunRpj96T2TQA0Dmfz1BjqzcwRNjq8wWGn9r+qtYxf2X7gv5C9z/fPkzV4a/yjn+1Gx1er220y5AhSe1DYEfWBz9WezvDONKn42voqD7tL9nh9yNt/IL7Kej5ju0NBT8ZypddqPNMDRkdjiy1H3VqH2LseAQq8Lj9aJPtqKNP1vbnbf7X6tD+pKMCxkkO+4C/FEFYZtM0Nzdry5YtKioqCqyzWq3Kz89XaWlpp31KS0tVWFgYtG7mzJlavXp1l+/T1NSkpqYjB4w9Hk8oZQJA1LBaLUqItSsh1q6RiQ6zywF6JaQ5hTU1NfJ6vUpNTQ1an5qaKpfL1Wkfl8sVUntJKi4ultPpDCyZmZmhlAkAACLIgLzAQVFRkdxud2CprKw0uyQAABAmIQ3TJCcny2azqbq6Omh9dXW10tLSOu2TlpYWUntJcjgccjg43AgAQDQI6chIbGyspkyZopKSksA6n8+nkpIS5eXlddonLy8vqL0krV27tsv2AAAguoQ8tbewsFA33HCDzjnnHE2dOlUPP/yw6uvrNW/ePEnS3LlzNWrUKBUXF0uSFixYoOnTp+vBBx/UlVdeqZUrV2rz5s164okn+nZLAABARAo5jMyZM0cHDhzQwoUL5XK5NGnSJK1ZsyZwkmpFRYWs1iMHXM4//3w999xz+uUvf6lf/OIXOvXUU7V69WquMQIAACRx114AABAmPf3+HpCzaQAAQPQgjAAAAFMRRgAAgKkIIwAAwFSEEQAAYCrCCAAAMFXI1xkxg3/2MXfvBQAgcvi/t493FZGICCO1tbWSxN17AQCIQLW1tXI6nV0+HxEXPfP5fNq3b58SExNlsVj67HU9Ho8yMzNVWVkZFRdTi6btZVsHr2jaXrZ18IqW7TUMQ7W1tcrIyAi6OvvRIuLIiNVq1ejRo8P2+klJSYP6f4ajRdP2sq2DVzRtL9s6eEXD9nZ3RMSPE1gBAICpCCMAAMBUUR1GHA6HFi1aJIfDYXYp/SKatpdtHbyiaXvZ1sEr2rb3eCLiBFYAADB4RfWREQAAYD7CCAAAMBVhBAAAmIowAgAATDXow8jixYuVlZWluLg45ebmatOmTd22f/HFF3X66acrLi5OEydO1BtvvNFPlZ6Y4uJinXvuuUpMTFRKSopmz56tHTt2dNtnxYoVslgsQUtcXFw/Vdx7//mf/3lM3aeffnq3fSJ1v0pSVlbWMdtrsVg0f/78TttH0n7dsGGDZs2apYyMDFksFq1evTroecMwtHDhQqWnpys+Pl75+fn6/PPPj/u6oX7u+0N329rS0qI777xTEydO1JAhQ5SRkaG5c+dq37593b5mbz4L/eV4+/bGG288pvbLL7/8uK8baftWUqefX4vFot///vddvuZA3rfhMKjDyKpVq1RYWKhFixZp69atysnJ0cyZM7V///5O27/33nu65pprdPPNN2vbtm2aPXu2Zs+ere3bt/dz5aFbv3695s+fr/fff19r165VS0uLLrvsMtXX13fbLykpSVVVVYFlz549/VTxiTnrrLOC6n733Xe7bBvJ+1WS/vGPfwRt69q1ayVJ3/nOd7rsEyn7tb6+Xjk5OVq8eHGnz//ud7/TH/7wBy1dulQffPCBhgwZopkzZ6qxsbHL1wz1c99futvWhoYGbd26Vffcc4+2bt2ql19+WTt27NC3vvWt475uKJ+F/nS8fStJl19+eVDtzz//fLevGYn7VlLQNlZVVWn58uWyWCz613/9125fd6Du27AwBrGpU6ca8+fPDzz2er1GRkaGUVxc3Gn7q6++2rjyyiuD1uXm5hrf//73w1pnOOzfv9+QZKxfv77LNk899ZThdDr7r6g+smjRIiMnJ6fH7QfTfjUMw1iwYIExbtw4w+fzdfp8pO5XScYrr7wSeOzz+Yy0tDTj97//fWDdoUOHDIfDYTz//PNdvk6on3szHL2tndm0aZMhydizZ0+XbUL9LJils+294YYbjKuuuiqk1xks+/aqq64yLrnkkm7bRMq+7SuD9shIc3OztmzZovz8/MA6q9Wq/Px8lZaWdtqntLQ0qL0kzZw5s8v2A5nb7ZYkDR8+vNt2dXV1Gjt2rDIzM3XVVVfpo48+6o/yTtjnn3+ujIwMnXzyybruuutUUVHRZdvBtF+bm5v1zDPP6Kabbur2ppGRul87Ki8vl8vlCtp3TqdTubm5Xe673nzuByq32y2LxaKhQ4d22y6Uz8JAs27dOqWkpOi0007TbbfdpoMHD3bZdrDs2+rqar3++uu6+eabj9s2kvdtqAZtGKmpqZHX61VqamrQ+tTUVLlcrk77uFyukNoPVD6fT3fccYemTZumCRMmdNnutNNO0/Lly/Xqq6/qmWeekc/n0/nnn68vv/yyH6sNXW5urlasWKE1a9ZoyZIlKi8v14UXXqja2tpO2w+W/SpJq1ev1qFDh3TjjTd22SZS9+vR/PsnlH3Xm8/9QNTY2Kg777xT11xzTbc3UQv1szCQXH755frTn/6kkpIS3X///Vq/fr0KCgrk9Xo7bT9Y9u3TTz+txMREffvb3+62XSTv296IiLv2IjTz58/X9u3bjzu+mJeXp7y8vMDj888/X2eccYYef/xx/frXvw53mb1WUFAQ+P3ss89Wbm6uxo4dqxdeeKFHf21EsieffFIFBQXKyMjosk2k7le0aWlp0dVXXy3DMLRkyZJu20byZ+G73/1u4PeJEyfq7LPP1rhx47Ru3TpdeumlJlYWXsuXL9d111133JPKI3nf9sagPTKSnJwsm82m6urqoPXV1dVKS0vrtE9aWlpI7Qei22+/Xa+99preeecdjR49OqS+MTExmjx5snbu3Bmm6sJj6NChGj9+fJd1D4b9Kkl79uzRW2+9pVtuuSWkfpG6X/37J5R915vP/UDiDyJ79uzR2rVrQ761/PE+CwPZySefrOTk5C5rj/R9K0l///vftWPHjpA/w1Jk79ueGLRhJDY2VlOmTFFJSUlgnc/nU0lJSdBfjR3l5eUFtZektWvXdtl+IDEMQ7fffrteeeUVvf3228rOzg75Nbxerz788EOlp6eHocLwqaur0xdffNFl3ZG8Xzt66qmnlJKSoiuvvDKkfpG6X7Ozs5WWlha07zwejz744IMu911vPvcDhT+IfP7553rrrbc0YsSIkF/jeJ+FgezLL7/UwYMHu6w9kvet35NPPqkpU6YoJycn5L6RvG97xOwzaMNp5cqVhsPhMFasWGF8/PHHxve+9z1j6NChhsvlMgzDMK6//nrjrrvuCrTfuHGjYbfbjQceeMD45JNPjEWLFhkxMTHGhx9+aNYm9Nhtt91mOJ1OY926dUZVVVVgaWhoCLQ5envvvfde48033zS++OILY8uWLcZ3v/tdIy4uzvjoo4/M2IQe++lPf2qsW7fOKC8vNzZu3Gjk5+cbycnJxv79+w3DGFz71c/r9Rpjxowx7rzzzmOei+T9Wltba2zbts3Ytm2bIcl46KGHjG3btgVmkPz2t781hg4darz66qvGP//5T+Oqq64ysrOzjcOHDwde45JLLjEeeeSRwOPjfe7N0t22Njc3G9/61reM0aNHG2VlZUGf4aampsBrHL2tx/ssmKm77a2trTV+9rOfGaWlpUZ5ebnx1ltvGd/4xjeMU0891WhsbAy8xmDYt35ut9tISEgwlixZ0ulrRNK+DYdBHUYMwzAeeeQRY8yYMUZsbKwxdepU4/333w88N336dOOGG24Iav/CCy8Y48ePN2JjY42zzjrLeP311/u54t6R1Ony1FNPBdocvb133HFH4L9NamqqccUVVxhbt27t/+JDNGfOHCM9Pd2IjY01Ro0aZcyZM8fYuXNn4PnBtF/93nzzTUOSsWPHjmOei+T9+s4773T6/61/e3w+n3HPPfcYqamphsPhMC699NJj/huMHTvWWLRoUdC67j73ZuluW8vLy7v8DL/zzjuB1zh6W4/3WTBTd9vb0NBgXHbZZcbIkSONmJgYY+zYscatt956TKgYDPvW7/HHHzfi4+ONQ4cOdfoakbRvw8FiGIYR1kMvAAAA3Ri054wAAIDIQBgBAACmIowAAABTEUYAAICpCCMAAMBUhBEAAGAqwggAADAVYQQAAJiKMAIAAExFGAEAAKYijAAAAFMRRgAAgKn+fzTIy0KxDClvAAAAAElFTkSuQmCC"
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"hidden_size = 256\n",
"batch_size = 64\n",
"\n",
"input_lang, output_lang, train_dataloader = get_dataloader(batch_size)\n",
"\n",
"encoder = EncoderRNN(input_lang.n_words, hidden_size).to(device)\n",
"decoder = AttnDecoderRNN(hidden_size, output_lang.n_words).to(device)\n",
"\n",
"train(train_dataloader, encoder, decoder, 100, print_every=5, plot_every=5)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:00:44.619526Z",
"end_time": "2024-06-02T20:03:13.180305Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Ewaluacja"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 85,
"outputs": [],
"source": [
"def evaluate(encoder, decoder, sentence, input_lang, output_lang):\n",
" with torch.no_grad():\n",
" input_tensor = tensorFromSentence(input_lang, sentence)\n",
"\n",
" encoder_outputs, encoder_hidden = encoder(input_tensor)\n",
" decoder_outputs, decoder_hidden, decoder_attn = decoder(encoder_outputs, encoder_hidden)\n",
"\n",
" _, topi = decoder_outputs.topk(1)\n",
" decoded_ids = topi.squeeze()\n",
"\n",
" decoded_words = []\n",
" for idx in decoded_ids:\n",
" if idx.item() == EOS_token:\n",
" decoded_words.append('<EOS>')\n",
" break\n",
" decoded_words.append(output_lang.index2word[idx.item()])\n",
" return decoded_words, decoder_attn"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:59:01.782695Z",
"end_time": "2024-06-02T19:59:01.811933Z"
}
}
},
{
"cell_type": "code",
"execution_count": 86,
"outputs": [],
"source": [
"def evaluateRandomly(encoder, decoder, n=10):\n",
" for i in range(n):\n",
" pair = random.choice(pairs)\n",
" print('>', pair[0])\n",
" print('=', pair[1])\n",
" output_words, _ = evaluate(encoder, decoder, pair[0], input_lang, output_lang)\n",
" output_sentence = ' '.join(output_words)\n",
" print('<', output_sentence)\n",
" print('')"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:59:02.352827Z",
"end_time": "2024-06-02T19:59:02.374825Z"
}
}
},
{
"cell_type": "code",
"execution_count": 99,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"> utne sobie drzemke\n",
"= i m going to go take a nap\n",
"< i m going to go take a nap wallet <EOS>\n",
"\n",
"> nie jestem co do tego pewny to zalezy\n",
"= i m not sure about that it depends\n",
"< i m not sure about that it depends <EOS>\n",
"\n",
"> nie kupujemy\n",
"= we re not buying\n",
"< we re not buying <EOS>\n",
"\n",
"> nie jestem g upi\n",
"= i m not stupid\n",
"< i m not stupid <EOS>\n",
"\n",
"> jestes wymagajacy\n",
"= you re demanding\n",
"< you re demanding <EOS>\n",
"\n",
"> jestem m ody ale nie az tak\n",
"= i m young but i m not that young\n",
"< i m young but i m not that young <EOS>\n",
"\n",
"> nie jestem ubrana\n",
"= i m not dressed\n",
"< i m not dressed <EOS>\n",
"\n",
"> jestem gotowy sie z tym pogodzic\n",
"= i m ready to accept it\n",
"< i m ready to accept it <EOS>\n",
"\n",
"> jestem pewny ze ona nied ugo wroci\n",
"= i m sure that she will come back soon\n",
"< i m sure that she will come back soon <EOS>\n",
"\n",
"> w niedziele mam wolne\n",
"= i m free on sunday\n",
"< i m free on sunday <EOS>\n",
"\n"
]
}
],
"source": [
"encoder.eval()\n",
"decoder.eval()\n",
"evaluateRandomly(encoder, decoder)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:03:19.348154Z",
"end_time": "2024-06-02T20:03:19.572157Z"
}
}
},
{
"cell_type": "code",
"execution_count": 88,
"outputs": [],
"source": [
"def showAttention(input_sentence, output_words, attentions):\n",
" fig = plt.figure()\n",
" ax = fig.add_subplot(111)\n",
" cax = ax.matshow(attentions.cpu().numpy(), cmap='bone')\n",
" fig.colorbar(cax)\n",
"\n",
" # Set up axes\n",
" ax.set_xticklabels([''] + input_sentence.split(' ') +\n",
" ['<EOS>'], rotation=90)\n",
" ax.set_yticklabels([''] + output_words)\n",
"\n",
" # Show label at every tick\n",
" ax.xaxis.set_major_locator(ticker.MultipleLocator(1))\n",
" ax.yaxis.set_major_locator(ticker.MultipleLocator(1))\n",
"\n",
" plt.show()\n",
"\n",
"\n",
"def evaluateAndShowAttention(input_sentence):\n",
" input_sentence = normalizeString(input_sentence)\n",
" output_words, attentions = evaluate(encoder, decoder, input_sentence, input_lang, output_lang)\n",
" print('input =', input_sentence)\n",
" print('output =', ' '.join(output_words))\n",
" showAttention(input_sentence, output_words, attentions[0, :len(output_words), :])"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T19:59:04.218821Z",
"end_time": "2024-06-02T19:59:04.250855Z"
}
}
},
{
"cell_type": "code",
"execution_count": 100,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"input = nie jestem katoliczka\n",
"output = i m not catholic <EOS>\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\adamw\\AppData\\Local\\Temp\\ipykernel_17652\\691622281.py:8: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
" ax.set_xticklabels([''] + input_sentence.split(' ') +\n",
"C:\\Users\\adamw\\AppData\\Local\\Temp\\ipykernel_17652\\691622281.py:10: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
" ax.set_yticklabels([''] + output_words)\n"
]
},
{
"data": {
"text/plain": "<Figure size 640x480 with 2 Axes>",
"image/png": "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K927dze7BJf27LPPKiAgQJKUlpZmbjEu7pdfflFgYKDt57Vr1+qOO+6w/dyjRw8VFRWZURoaGcGIZueNN95Qenq69u7dq7y8PHXv3l1paWk6//zzTxt272ni4+Pr/D1O1717d61fv17du3dXWVmZtmzZopEjR9peLyoqUlBQkIkVorEwKhXNyksvvaSkpCSNGzdOhw8ftt1TbNu2LS0k6bSVgM62ebr4+HhNnTpVjz/+uG666Sb169dPQ4cOtb2+du1aDRgwwMQK0VhoMaJZef7557Vw4UJNmDBBTz75pG1/VFSUHnroIRMrcw1t27b9zUUPGKh0ysMPP6zjx4/rnXfeUWhoqJYtW+bw+ldffaVJkyaZVB0aE6NS0ay0bNlS27dvV/fu3RUQEKB///vf6tGjh3bt2qVBgwZ5/ALj9VkD9fLLL2/ESgDXRYsRzcr555+vjRs3njYIJzs7W/379zepKtdB2NXfL7/8ok8//VQ7d+6UJPXp00ejR49Wy5YtTa4MjYVgRLOSlJSkqVOn6sSJE7JarcrPz9eSJUuUmprKfLM6HD58WBkZGbZnC15wwQW6/fbbGVTyXytWrNCdd96psrIyh/3BwcHKyMjQ+PHjTaoMjYmuVDQ7b775pmbNmqXvv/9ektS5c2fNnj3bYag9pG+++UZjxoxRy5YtNXz4cEnS119/rV9++UWffPKJLrzwQpMrNNfatWs1atQoXXvttXrwwQdtPQ5bt27VM888ow8//FBr1qzRRRddZHKlaGgEI5qt48eP69ixY+rYsaPZpbikSy+9VL169dLChQvVosWpzqOTJ0/qzjvv1J49e/TFF1+YXKG5xo0bp7CwML388st1vn7XXXepsLBQq1atauLK0NgIRjQrV155pd555x21bdvWYX95ebkmTJigzz77zJzCXFDLli317bffql+/fg77t27dqqioKB0/ftykylxD+/bttWbNGg0cOLDO1zdt2qTLL79chw4dauLK0NiYx4hmJTc3t86Hx544cUL//Oc/TajIdQUGBqqgoOC0/YWFhbbVcTzZr1e++bWgoCCdOHGiCStCU2HwDZqFTZs22X6/detWh6W6qqurlZ2drS5duphRmsuKjY3VHXfcoXnz5uniiy+WdGpu3l/+8hfm50nq3bu3PvvsszOuh5qTk6PevXs3cVVoCgQjmoXIyEhZLBZZ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0WIEABjk5CLico8WI8EIADDEQx6u4VldqbNmzVJkZKTZZQCAWzoVjFYnNrM/gTEeFYwAAPwWtwrGUaNG6c9//rMefvhhtW/fXqGhoZo1a5bt9YKCAl133XVq06aNAgMD9Yc//EHFxcWSpMzMTM2ePVv//ve/ZbFYZLFYlJmZWed1KisrVV5e7rABgKerna7hzOYO3CoYJWnx4sVq3bq11q1bp7lz5+qxxx7Tp59+qpqaGl133XX6+eeftWbNGn366afas2ePYmNjJUmxsbF68MEHdcEFF+jgwYM6ePCg7bVfS01NVVBQkG0LCwtryo8IAC7JuW5U56Z6NCW3G3wzaNAgpaSkSJJ69+6tF154QTk5OZKk7777Tnv37rUF2euvv64LLrhAX3/9tYYNG6Y2bdqoRYsWCg0NPes1pk+frqSkJNvP5eXlhCMAeAi3DEZ7nTp1UklJibZt26awsDCHAIuIiFDbtm21bds2DRs2zPA1/Pz85Ofn12A1A0Bz4CkT/N0uGH18fBx+tlgsqqmpMakaAPAgznaHukkwut09xjPp37+/CgsLVVhYaNu3detWHT58WBEREZIkX19fVVdXm1UiAMANNJtgjImJ0cCBAzV58mRt2LBB+fn5iouL0+WXX66oqChJUnh4uPbu3auNGzeqrKxMlZWVJlcNAG6kdoa/M5sbaDbBaLFY9P7776tdu3a67LLLFBMTox49eigrK8t2zI033qixY8fqiiuuUIcOHbRkyRITKwYA9+Ip0zXc6h5jbm7uafvee+892++7deum999//4zn+/n56e23326EygAAzUWzaTECABqXWT2pCxYsUHh4uPz9/TVixAjl5+cbOm/p0qWyWCyaMGFCva5HMAIADDFjgn9WVpaSkpKUkpKiDRs2aPDgwRozZoxKSkrOet4PP/yghx56SJdeemm9r0kwAgAMMSMY58+frylTpighIUERERFKT09Xq1attGjRojOeU11drcmTJ2v27Nnq0aNHva9JMAIAmtSv16I+0wyBqqoqrV+/XjExMbZ9Xl5eiomJUV5e3hnf/7HHHlPHjh11xx13nFN9BCMAwJCGajGGhYU5rEedmppa5/XKyspUXV2tkJAQh/0hISEqKiqq85wvv/xSGRkZWrhw4Tl/TrcalQoAMI+zUy5qzy0sLFRgYKBtf0MtwXn06FHdeuutWrhwoYKDg8/5fQhGAECTCgwMdAjGMwkODpa3t7ft8YG1iouL63wYxPfff68ffvhB48ePt+2rXTK0RYsW2rFjh3r27Pmb16UrFQBgSFMPvvH19dXQoUNtT1CSTgVdTk6OoqOjTzu+X79++u6777Rx40bbdu211+qKK67Qxo0bDT8liRYjAMAgZ5d1q/+5SUlJio+PV1RUlIYPH660tDRVVFQoISFBkhQXF6cuXbooNTVV/v7+GjBggMP5bdu2laTT9p8NwQgAcFmxsbEqLS1VcnKyioqKFBkZqezsbNuAnIKCAnl5NWznJ8EIADDErOcxJiYmKjExsc7X6loq1F5mZma9r0cwAgAMcfYBGW7ycA0G3wAAYI8WIwDAkIaax+jqCEYAgCFm3WNsagQjAMAQTwlG7jECAGCHFiMAwBBPaTESjAAAQ05N13AmGBuwmEZEVyoAAHZoMQIADGG6BgAA9jxk6Ru6UgEAsEOLEQBgiIc0GAlGAIAxnjJdg65UAADs0GIEABjjZIvRXfpSCUYAgCFM1wAAwI6n3GMkGOvhvXf+ZnYJaCZ8/XzMLsEtXD/xHrNLcHlVVSf0+sInzC6jWSEYAQCGWOVki1G0GAEAzYindKUyXQMAADu0GAEAxnjI0jcEIwDAEGvNqc2Z890BXakAANihxQgAMMRTBt8QjAAAQzwlGOlKBQDADi1GAIAhntJiJBgBAIYQjAAA2PGUp2twjxEAADsEIwDAmNqVb5zZzsGCBQsUHh4uf39/jRgxQvn5+Wc89p133lFUVJTatm2r1q1bKzIyUm+88Ua9rkcwAgAMsTbAr/rKyspSUlKSUlJStGHDBg0ePFhjxoxRSUlJnce3b99eM2bMUF5enjZt2qSEhAQlJCTo448/NnxNghEA4LLmz5+vKVOmKCEhQREREUpPT1erVq20aNGiOo8fNWqUrr/+evXv3189e/bUfffdp0GDBunLL780fE2CEQBgSO2oVGc2SSovL3fYKisr67xeVVWV1q9fr5iYGNs+Ly8vxcTEKC8vz1C9OTk52rFjhy677DLDn5NgBAAYcircapzYTgVjWFiYgoKCbFtqamqd1ysrK1N1dbVCQkIc9oeEhKioqOiMdR45ckRt2rSRr6+vfve73+n555/X6NGjDX9OpmsAAJpUYWGhAgMDbT/7+fk16PsHBARo48aNOnbsmHJycpSUlKQePXpo1KhRhs4nGAEAhjTUBP/AwECHYDyT4OBgeXt7q7i42GF/cXGxQkNDz3iel5eXevXqJUmKjIzUtm3blJqaajgY6UoFABjSUPcYjfL19dXQoUOVk5Nj21dTU6OcnBxFR0cbfp+ampoz3sesCy1GAIDLSkpKUnx8vKKiojR8+HClpaWpoqJCCQkJkqS4uDh16dLFdp8yNTVVUVFR6tmzpyorK7Vq1Sq98cYbeumllwxfk2AEABhixlqpsbGxKi0tVXJysoqKihQZGans7GzbgJyCggJ5ef2v87OiokL33HOP9u/fr5YtW6pfv376+9//rtjYWMPXJBgBAIbUji515vxzkZiYqMTExDpfy83Ndfj5iSee0BNPPHFO16lFMAIAjHFiWTfb+W6AwTcAANihxQgAMORc1zu1P98dEIwAAIOcG3wjNwlGulIBALBDixEAYIgZ0zXMQDACAAwxa7pGU6MrFQAAOy4RjBaLRe+9955T7zFq1Cjdf//9tp/Dw8OVlpbm1HsCAP6nqddKNUuTdqXOmjVL7733njZu3Njo1/r666/VunXrRr8OAHgK7jG6uQ4dOphdAgDADdW7K7WmpkZz585Vr1695Ofnp27duumvf/2rJGnatGnq06ePWrVqpR49emjmzJn6z3/+I0nKzMzU7Nmz9e9//1sWi0UWi0WZmZm29y0rK9P111+vVq1aqXfv3lqxYoXDddesWaPhw4fLz89PnTp10iOPPKKTJ0+esc5fd6UePnxYd911l0JCQuTv768BAwboww8/rPPcyspKlZeXO2wA4OnoSj2D6dOna+HChXr22Wd1ySWX6ODBg9q+fbukU09NzszMVOfOnfXdd99pypQpCggI0MMPP6zY2Fht3rxZ2dnZWr16tSQpKCjI9r6zZ8/W3Llz9fTTT+v555/X5MmTtW/fPrVv314//vijxo0bp9tuu02vv/66tm/frilTpsjf31+zZs36zZpramp0zTXX6OjRo/r73/+unj17auvWrfL29q7z+NTUVM2ePbu+Xw0ANG8eslZqvYLx6NGjeu655/TCCy8oPj5ektSzZ09dcsklkqRHH33Udmx4eLgeeughLV26VA8//LBatmypNm3aqEWLFnU+efm2227TpEmTJElz5szR3/72N+Xn52vs2LF68cUXFRYWphdeeEEWi0X9+vXTgQMHNG3a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"
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"evaluateAndShowAttention('Nie jestem katoliczką')"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:03:24.422192Z",
"end_time": "2024-06-02T20:03:24.634214Z"
}
}
},
{
"cell_type": "code",
"execution_count": 101,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"input = przykro nam ze to sie zdarzy o\n",
"output = we re sorry that it happened <EOS>\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\adamw\\AppData\\Local\\Temp\\ipykernel_17652\\691622281.py:8: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
" ax.set_xticklabels([''] + input_sentence.split(' ') +\n",
"C:\\Users\\adamw\\AppData\\Local\\Temp\\ipykernel_17652\\691622281.py:10: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
" ax.set_yticklabels([''] + output_words)\n"
]
},
{
"data": {
"text/plain": "<Figure size 640x480 with 2 Axes>",
"image/png": "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"
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"evaluateAndShowAttention('Przykro nam ze to sie zdarzyło')\n"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:03:25.856941Z",
"end_time": "2024-06-02T20:03:26.205536Z"
}
}
},
{
"cell_type": "code",
"execution_count": 102,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"input = on mowi p ynnie po francusku\n",
"output = he is fluent in french <EOS>\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\adamw\\AppData\\Local\\Temp\\ipykernel_17652\\691622281.py:8: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
" ax.set_xticklabels([''] + input_sentence.split(' ') +\n",
"C:\\Users\\adamw\\AppData\\Local\\Temp\\ipykernel_17652\\691622281.py:10: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
" ax.set_yticklabels([''] + output_words)\n"
]
},
{
"data": {
"text/plain": "<Figure size 640x480 with 2 Axes>",
"image/png": "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zpw59p9Q+/btq0ceeUR16tQxODr8mRUrVmjZsmX2Qc+easSIEWrQoIE2bdqksLAwSdLx48f197//XSNGjNCyZcsMjrD8GjRooF9++UVXXnmlmjRpovfee0/XX3+9PvnkE49ZVHHlypUKCQmRdGlGYVpamn2g98mTJw2MDM5g4KyB2rZtq5kzZ+qmm24yOhSXO3/+vHbs2FFsu+CPA2rhXq666iotX75cTZs2NToUl6pevbq+/PLLIg+p2759u2688Ub79Hkzmjlzpnx9fTVixAitXr1avXr1ks1m04ULFzRjxgyNHDnS6BCdUpplDDyphe5NSFIMtGbNGj311FOaMmWKmjdvXmT9CbNPCyyUmpqq+Ph4HT9+vMiANv7hcH9vvvmmPv74Yy1atEhXXHGF0eG4TFhYmD799FN16NDBYf+GDRvUq1cvjxrkfeDAAW3dulUNGzZUbGys0eEAJSJJMdDvs//f9/k9beBso0aN1K1bN02YMEERERFGh4MyatWqlfbu3SubzaaYmJgiyfQ333xjUGQVKz4+Xt98843mz5+v66+/XpL01VdfaejQoWrTpo0WLlxobIDldOHCBfXo0UNz58716IfsnT17Vnv37i1SCZOkH374QfXr11dgYKABkcEZjEkx0Nq1a40OoVJkZ2dr9OjRJCgm1adPH6NDqBQvvviiEhIS1L59e3siduHCBfXu3VsvvPCCwdGVX9WqVbVjxw6jw3C5/Px8tWvXTunp6fYkU5J+/PFHtWrVShkZGSQpJkQlxWAnT57U/Pnz7QNKmzVrpgceeMA+AMwT3H///brxxhv1wAMPGB2KyxX+dfKkGTAJCQm6//771alTJ6NDqRR79uzRjz/+KOnS38eGDRsaHJHzRo0aJX9/f02dOtXoUFzqnnvuUe3atZWSkmLfN27cOG3bts1jZhIWt2Jwefj5+SkgIKACInItkhQDbdmyRT169FBAQIA98//666917tw5ffbZZ2rdurXBEVaMs2fP6u6771atWrWKHXszYsQIgyKrOPPnz9fMmTO1e/duSZdaXElJSRoyZIjBkTmvT58+Wr58uerXr6/Bgwdr0KBBHjsry1O/jo8++qhef/11NWrUSG3atFH16tUd3veU5y8tW7ZMgwYN0uHDh1WlShXZbDbVr19fzz//vO655x6jw3Pa+fPnddVVVykrK8vpz4qM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9nbP008/rV69etmTldIgSQEAAJfVr18/HT16VBMmTFBWVpZatmyp1NRU+2DajIwMh8rJU089JYvFoqeeekqHDh1SrVq11KtXLz333HNlui5JCgAAJmLUs3sSExOVmJhY7Hvp6ekOr6tUqaKJEydq4sSJ5bqW/XOcOhsAAFSqipqCbAYMnAUAAG6JSgoAACZiVLvHCCQpAACYiDclKbR7AACAW6KSAgCAiXjTwFmSFAAATKSint1jBiQpAACYSHmWtv/j+WbBmBQAAOCWqKQAAGAijEkBAABuySbnphGbJ0Wh3QMAANwUlRQAAEyEdg8AAHBLrDhrYp07d1ZSUpLRYQAAACd5XCXlww8/VNWqVY0OAwAAl/CmSorHJSlhYWFGhwAAgOt40WpuHt3ueemll9SoUSMFBAQoIiJCd911l7HBAQCAUvO4SkqhLVu2aMSIEXrjjTfUoUMHnThxQuvXry/x+Ly8POXl5dlf5+bmVkaYAACUic1qk83qRLvHiXMrm8cmKRkZGapevbr++te/KigoSPXr11erVq1KPD45OVnPPPNMJUYIAEA5ONntMdNqbh7X7inUtWtX1a9fXw0aNNDAgQP11ltv6ezZsyUeP27cOOXk5Ni3zMzMSowWAIDSKRw468xmFh6bpAQFBembb77RO++8o6ioKE2YMEEtWrTQyZMniz3e399fwcHBDhsAADCOxyYpklSlShV16dJF06ZN044dO7R//36tWbPG6LAAACg3b6qkeOyYlE8//VT79u3TzTffrBo1amj58uWyWq265pprjA4NAIByY50UDxAaGqoPP/xQkyZN0vnz59WoUSO98847uvbaa40ODQAAlILHJSnp6enF/h4AAE/AFGQAAOCWvKnd49EDZwEAgHlRSQEAwES8qZJCkgIAgJnwgEEAAABjUUkBAMBEvKiQQpICAICZ2GxOTkE2UZZCkgIAgIl408BZxqQAAAC3RCUFAAAT8aZKCkkKAAAm4k1JCu0eAADglqikAABgIt5USSFJAQDATKySnHmSsbXCInE52j0AAMAtUUkBAMBEaPcAAAC35E3L4tPuAQAAbolKCgAAJkK7BwAAuCWSFAAA4JZsViefguzM9OVKRpLi5apXDzE6BDgpP++c0SG4XM2adY0OweUyfsowOgSXOnnyiNEhuJSZqhNmQpICAICZONnuMdP0HpIU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"
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"evaluateAndShowAttention('On mówi płynnie po francusku')\n"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:03:26.594026Z",
"end_time": "2024-06-02T20:03:26.838018Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### BLEU"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": 103,
"outputs": [],
"source": [
"def filter_rows(row):\n",
" return len(row[\"eng\"].split(' '))<MAX_LENGTH and \\\n",
" len(row[\"pol\"].split(' '))<MAX_LENGTH and \\\n",
" row[\"eng\"].startswith(eng_prefixes)\n",
"\n",
"def evaluateWithTokenization(input_sentence):\n",
" input_sentence = normalizeString(input_sentence)\n",
" output_words, attentions = evaluate(encoder, decoder, input_sentence, input_lang, output_lang)\n",
" if \"<EOS>\" in output_words:\n",
" output_words.remove(\"<EOS>\")\n",
" return output_words"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:03:29.868015Z",
"end_time": "2024-06-02T20:03:29.884050Z"
}
}
},
{
"cell_type": "code",
"execution_count": 114,
"outputs": [],
"source": [
"df = pd.read_csv(\"data/eng-pol.txt\", sep='\\t', names=[\"eng\", \"pol\", \"attribution\"])\n",
"df[\"eng\"] = df[\"eng\"].apply(normalizeString)\n",
"df[\"pol\"] = df[\"pol\"].apply(normalizeString)\n",
"df_filtered = df.apply(filter_rows, axis=1)\n",
"test_df = df[df_filtered].sample(frac=1)\n",
"test_df[\"eng_token\"] = test_df[\"eng\"].apply(lambda x: x.split())\n",
"test_df[\"eng_eval\"] = test_df[\"pol\"].apply(lambda x: evaluateWithTokenization(x))"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:07:48.707058Z",
"end_time": "2024-06-02T20:08:22.246952Z"
}
}
},
{
"cell_type": "code",
"execution_count": 115,
"outputs": [],
"source": [
"references_corpus = test_df[\"eng_token\"].values.tolist()\n",
"candidate_corpus = test_df[\"eng_eval\"].values.tolist()\n",
"references_corpus = [[el] for el in references_corpus]"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:08:22.248949Z",
"end_time": "2024-06-02T20:08:22.262981Z"
}
}
},
{
"cell_type": "code",
"execution_count": 116,
"outputs": [
{
"data": {
"text/plain": "0.9301728010177612"
},
"execution_count": 116,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bleu_score(candidate_corpus, references_corpus)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2024-06-02T20:08:22.264948Z",
"end_time": "2024-06-02T20:08:23.695461Z"
}
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 0
}