1630 lines
153 KiB
Plaintext
1630 lines
153 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Seq2Seq Polski --> Angielski\n",
|
|
"https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
|
|
"_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:03:55.887266Z",
|
|
"iopub.status.busy": "2024-05-25T14:03:55.886451Z",
|
|
"iopub.status.idle": "2024-05-25T14:04:02.514594Z",
|
|
"shell.execute_reply": "2024-05-25T14:04:02.513697Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:03:55.887232Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from __future__ import unicode_literals, print_function, division\n",
|
|
"from io import open\n",
|
|
"import unicodedata\n",
|
|
"import re\n",
|
|
"import random\n",
|
|
"\n",
|
|
"import torch\n",
|
|
"import torch.nn as nn\n",
|
|
"from torch import optim\n",
|
|
"import torch.nn.functional as F\n",
|
|
"\n",
|
|
"import numpy as np\n",
|
|
"from torch.utils.data import TensorDataset, DataLoader, RandomSampler\n",
|
|
"\n",
|
|
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:04:09.403926Z",
|
|
"iopub.status.busy": "2024-05-25T14:04:09.403445Z",
|
|
"iopub.status.idle": "2024-05-25T14:04:09.434533Z",
|
|
"shell.execute_reply": "2024-05-25T14:04:09.433678Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:04:09.403898Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0"
|
|
]
|
|
},
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"torch.cuda.device_count()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Konwersja słów na index"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:04:14.014490Z",
|
|
"iopub.status.busy": "2024-05-25T14:04:14.014114Z",
|
|
"iopub.status.idle": "2024-05-25T14:04:14.024526Z",
|
|
"shell.execute_reply": "2024-05-25T14:04:14.023673Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:04:14.014461Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Normalizacja tekstu"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:04:23.432285Z",
|
|
"iopub.status.busy": "2024-05-25T14:04:23.431898Z",
|
|
"iopub.status.idle": "2024-05-25T14:04:23.438688Z",
|
|
"shell.execute_reply": "2024-05-25T14:04:23.437569Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:04:23.432256Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Wczytywanie danych (zmodyfikowane ze względu na ścieżkę w kaggle)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:12:25.386029Z",
|
|
"iopub.status.busy": "2024-05-25T14:12:25.385674Z",
|
|
"iopub.status.idle": "2024-05-25T14:12:25.394103Z",
|
|
"shell.execute_reply": "2024-05-25T14:12:25.392925Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:12:25.386002Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def readLangs(reverse=False):\n",
|
|
" print(\"Reading lines...\")\n",
|
|
" lang1=\"en\"\n",
|
|
" lang2=\"pol\"\n",
|
|
" # Read the file and split into lines\n",
|
|
" lines = open('pol.txt', 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 = [list(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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Ograniczenie do zdań max 10 słów, formy I am / You are / He is etc. bez interpunkcji"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:12:29.730147Z",
|
|
"iopub.status.busy": "2024-05-25T14:12:29.729786Z",
|
|
"iopub.status.idle": "2024-05-25T14:12:29.737013Z",
|
|
"shell.execute_reply": "2024-05-25T14:12:29.735886Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:12:29.730121Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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)]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:12:33.204776Z",
|
|
"iopub.status.busy": "2024-05-25T14:12:33.204103Z",
|
|
"iopub.status.idle": "2024-05-25T14:12:36.889693Z",
|
|
"shell.execute_reply": "2024-05-25T14:12:36.888700Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:12:33.204744Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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",
|
|
"en 1969\n",
|
|
"['jestem tylko mechanikiem', 'i m only the mechanic']\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def prepareData(reverse=False):\n",
|
|
" input_lang, output_lang, pairs = readLangs(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(True)\n",
|
|
"print(random.choice(pairs))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Definicja modelu"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:12:52.384131Z",
|
|
"iopub.status.busy": "2024-05-25T14:12:52.383787Z",
|
|
"iopub.status.idle": "2024-05-25T14:12:52.391196Z",
|
|
"shell.execute_reply": "2024-05-25T14:12:52.390316Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:12:52.384104Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:12:54.394808Z",
|
|
"iopub.status.busy": "2024-05-25T14:12:54.393953Z",
|
|
"iopub.status.idle": "2024-05-25T14:12:54.409000Z",
|
|
"shell.execute_reply": "2024-05-25T14:12:54.407827Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:12:54.394765Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:13:00.670758Z",
|
|
"iopub.status.busy": "2024-05-25T14:13:00.670299Z",
|
|
"iopub.status.idle": "2024-05-25T14:13:00.687695Z",
|
|
"shell.execute_reply": "2024-05-25T14:13:00.686610Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:13:00.670720Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:22:08.184711Z",
|
|
"iopub.status.busy": "2024-05-25T14:22:08.183866Z",
|
|
"iopub.status.idle": "2024-05-25T14:22:08.194870Z",
|
|
"shell.execute_reply": "2024-05-25T14:22:08.193965Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:22:08.184675Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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(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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:16:38.895410Z",
|
|
"iopub.status.busy": "2024-05-25T14:16:38.894580Z",
|
|
"iopub.status.idle": "2024-05-25T14:16:38.902142Z",
|
|
"shell.execute_reply": "2024-05-25T14:16:38.900953Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:16:38.895382Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:16:43.069953Z",
|
|
"iopub.status.busy": "2024-05-25T14:16:43.069584Z",
|
|
"iopub.status.idle": "2024-05-25T14:16:43.075972Z",
|
|
"shell.execute_reply": "2024-05-25T14:16:43.075033Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:16:43.069926Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:20:58.574520Z",
|
|
"iopub.status.busy": "2024-05-25T14:20:58.574148Z",
|
|
"iopub.status.idle": "2024-05-25T14:20:58.583203Z",
|
|
"shell.execute_reply": "2024-05-25T14:20:58.582230Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:20:58.574492Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:21:00.586719Z",
|
|
"iopub.status.busy": "2024-05-25T14:21:00.586018Z",
|
|
"iopub.status.idle": "2024-05-25T14:21:00.592633Z",
|
|
"shell.execute_reply": "2024-05-25T14:21:00.591636Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:21:00.586683Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import matplotlib.pyplot as plt\n",
|
|
"plt.switch_backend('agg')\n",
|
|
"import matplotlib.ticker as ticker\n",
|
|
"import numpy as np\n",
|
|
"%matplotlib inline\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)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Ewaluacja"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:21:01.859612Z",
|
|
"iopub.status.busy": "2024-05-25T14:21:01.858691Z",
|
|
"iopub.status.idle": "2024-05-25T14:21:01.866857Z",
|
|
"shell.execute_reply": "2024-05-25T14:21:01.865732Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:21:01.859574Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:39:52.475327Z",
|
|
"iopub.status.busy": "2024-05-25T14:39:52.474985Z",
|
|
"iopub.status.idle": "2024-05-25T14:39:52.481801Z",
|
|
"shell.execute_reply": "2024-05-25T14:39:52.480957Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:39:52.475304Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def evaluateRandomly(encoder, decoder, n=10):\n",
|
|
" for i in range(n):\n",
|
|
" pair = random.choice(pairs)\n",
|
|
" print('Input sentence: ', pair[0])\n",
|
|
" print('Target (true) translation:' , pair[1])\n",
|
|
" output_words, _ = evaluate(encoder, decoder, pair[0], input_lang, output_lang)\n",
|
|
" output_sentence = ' '.join(output_words)\n",
|
|
" print('Output sentence: ', output_sentence)\n",
|
|
" print('')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Wykorzystanie zdefiniowanych wyżej funkcji"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Trenowanie modelu"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:22:39.754740Z",
|
|
"iopub.status.busy": "2024-05-25T14:22:39.754370Z",
|
|
"iopub.status.idle": "2024-05-25T14:26:53.707012Z",
|
|
"shell.execute_reply": "2024-05-25T14:26:53.705969Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:22:39.754714Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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",
|
|
"en 1969\n",
|
|
"0m 47s (- 11m 58s) (5 6%) 2.1245\n",
|
|
"1m 33s (- 10m 57s) (10 12%) 1.2482\n",
|
|
"2m 13s (- 9m 36s) (15 18%) 0.8442\n",
|
|
"2m 51s (- 8m 35s) (20 25%) 0.5612\n",
|
|
"3m 32s (- 7m 46s) (25 31%) 0.3599\n",
|
|
"4m 10s (- 6m 56s) (30 37%) 0.2216\n",
|
|
"4m 51s (- 6m 15s) (35 43%) 0.1367\n",
|
|
"5m 30s (- 5m 30s) (40 50%) 0.0894\n",
|
|
"6m 9s (- 4m 47s) (45 56%) 0.0647\n",
|
|
"6m 48s (- 4m 5s) (50 62%) 0.0489\n",
|
|
"7m 27s (- 3m 23s) (55 68%) 0.0402\n",
|
|
"8m 8s (- 2m 42s) (60 75%) 0.0345\n",
|
|
"8m 48s (- 2m 1s) (65 81%) 0.0315\n",
|
|
"9m 25s (- 1m 20s) (70 87%) 0.0278\n",
|
|
"10m 3s (- 0m 40s) (75 93%) 0.0271\n",
|
|
"10m 42s (- 0m 0s) (80 100%) 0.0253\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 0 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGeCAYAAABGlgGHAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABAzUlEQVR4nO3de3gU9d3//9cekk0IyWIC5AABgkcKCiER5OihGgv8uG/uWsWbShSxt3xvFDFKNeUuWtuaaqtFSwFRkFtFGg+ItEVr7loJR4FAEAFFTSQBEiKn3RAgh935/RGyEpJANmQzOTwf1zVXsp+d2XlPvZp9MZ+ZeVsMwzAEAABgEqvZBQAAgI6NMAIAAExFGAEAAKYijAAAAFMRRgAAgKkIIwAAwFSEEQAAYCrCCAAAMBVhBAAAmMpudgGN4fV6dfDgQYWHh8tisZhdDgAAaATDMFRaWqq4uDhZrec5/2H44emnnzaSk5ONzp07G926dTP+/d//3fjiiy/Ou827775r3HzzzUbXrl2N8PBw47rrrjM+/PBDf3ZrFBYWGpJYWFhYWFhY2uBSWFh43u95i2E0vjfNj370I91555269tprVVVVpdmzZ2vnzp3avXu3wsLC6t1m5syZiouL04033qguXbro1Vdf1R/+8Ad9+umnSkxMbNR+XS6XunTposLCQkVERDS2XAAAYCK32634+HgdP35cTqezwfX8CiPn+u6779S9e3etWbNGo0ePbvR2/fv318SJEzVnzpxGre92u+V0OuVyuQgjAAC0EY39/r6oa0ZcLpckKTIystHbeL1elZaWnneb8vJylZeX+1673e6mFwkAAFq1Jt9NYxiG0tLSNHLkSA0YMKDR2z333HMqKyvTHXfc0eA6GRkZcjqdviU+Pr6pZQIAgFauydM006dP19///netW7dOPXv2bNQ2y5cv13333af3339fN998c4Pr1XdmJD4+nmkaAADakIBO0zz44INatWqVsrOzGx1EMjMzNXXqVL399tvnDSKS5HA45HA4mlIaAABoY/wKI4Zh6MEHH9R7772nTz75RAkJCY3abvny5br33nu1fPlyjRs3rkmFAgCA9smvMDJ9+nS9+eabev/99xUeHq7i4mJJktPpVGhoqCQpPT1dBw4c0GuvvSapOoikpqbqhRde0HXXXefbJjQ09Ly3+QAAgI7BrwtY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27dPaWlp2rNnj5YsWaLFixfr0Ucfbb6jAAAAbZbfzxmZOHGijhw5oqeeekpFRUUaMGCAVq9erd69e0uSioqKVFBQ4Fs/ISFBq1ev1sMPP6w///nPiouL04svvsgzRgAAgKQmPGfEDDxnBACAticgzxkBAABoboQRAABgKsIIAAAwFWEEAACYijACAABM5fetvWaoueGHHjUAALQdNd/bF7pxt02EkdLSUkmiRw0AAG1QaWmpnE5ng++3ieeMeL1eHTx4UOHh4edtyOcvt9ut+Ph4FRYWdpjnl3S0Y+Z42zeOt33jeNs+wzBUWlqquLg4Wa0NXxnSJs6MWK1W9ezZM2Cf3xH733S0Y+Z42zeOt33jeNu2850RqcEFrAAAwFSEEQAAYKoOHUYcDoeeeOIJORwOs0tpMR3tmDne9o3jbd843o6jTVzACgAA2q8OfWYEAACYjzACAABMRRgBAACmIowAAABTdegwMn/+fCUkJCgkJERJSUlau3at2SUFREZGhq699lqFh4ere/fumjBhgr788kuzy2oxGRkZslgsmjlzptmlBMyBAwd01113KSoqSp06ddKgQYOUk5NjdlkBUVVVpf/5n/9RQkKCQkND1bdvXz311FPyer1ml9ZssrOzNX78eMXFxclisWjlypW13jcMQ08++aTi4uIUGhqqG264Qbt27TKn2GZwvuOtrKzUY489pquvvlphYWGKi4tTamqqDh48aF7BF+lC/33Pdv/998tisWju3LktVp8ZOmwYyczM1MyZMzV79mxt375do0aN0pgxY1RQUGB2ac1uzZo1mj59ujZt2qSsrCxVVVUpJSVFZWVlZpcWcFu2bNGiRYt0zTXXmF1KwBw7dkwjRoxQUFCQPvjgA+3evVvPPfecunTpYnZpAfHMM89o4cKFmjdvnvbs2aNnn31Wv//97/WnP/3J7NKaTVlZmQYOHKh58+bV+/6zzz6r559/XvPmzdOWLVsUExOjW265xdfHq6053/GePHlS27Zt0y9/+Utt27ZNK1as0N69e/Vv//ZvJlTaPC7037fGypUr9emnnyouLq6FKjOR0UENGTLEmDZtWq2xq666ynj88cdNqqjllJSUGJKMNWvWmF1KQJWWlhqXX365kZWVZVx//fXGQw89ZHZJAfHYY48ZI0eONLuMFjNu3Djj3nvvrTX24x//2LjrrrtMqiiwJBnvvfee77XX6zViYmKM3/3ud76x06dPG06n01i4cKEJFTavc4+3Pps3bzYkGfv27WuZogKooePdv3+/0aNHD+Pzzz83evfubfzxj39s8dpaUoc8M1JRUaGcnBylpKTUGk9JSdGGDRtMqqrluFwuSVJkZKTJlQTW9OnTNW7cON18881mlxJQq1atUnJysm6//XZ1795diYmJevnll80uK2BGjhypf/7zn9q7d68kaceOHVq3bp3Gjh1rcmUtIz8/X8XFxbX+fjkcDl1//fUd4u+XVP03zGKxtNuzf16vV5MnT9asWbPUv39/s8tpEW2iUV5zO3z4sDwej6Kjo2uNR0dHq7i42KSqWoZhGEpLS9PIkSM1YMAAs8sJmL/85S/atm2btmzZYnYpAZeXl6cFCxYoLS1Nv/jFL7R582bNmDFDDodDqampZpfX7B577DG5XC5dddVVstls8ng8+u1vf6v//M//NLu0FlHzN6q+v1/79u0zo6QWdfr0aT3++OOaNGlSu2omd7ZnnnlGdrtdM2bMMLuUFtMhw0gNi8VS67VhGHXG2psHHnhAn332mdatW2d2KQFTWFiohx56SB999JFCQkLMLifgvF6vkpOT9fTTT0uSEhMTtWvXLi1YsKBdhpHMzEy98cYbevPNN9W/f3/l5uZq5syZiouL09133212eS2mI/79qqys1J133imv16v58+ebXU5A5OTk6IUXXtC2bdva/X/Ps3XIaZquXbvKZrPVOQtSUlJS518b7cmDDz6oVatW6V//+pd69uxpdjkBk5OTo5KSEiUlJclut8tut2vNmjV68cUXZbfb5fF4zC6xWcXGxuoHP/hBrbF+/fq1y4uxJWnWrFl6/PHHdeedd+rqq6/W5MmT9fDDDysjI8Ps0lpETEyMJHW4v1+VlZW64447lJ+fr6ysrHZ7VmTt2rUqKSlRr169fH+/9u3bp0ceeUR9+vQxu7yA6ZBhJDg4WElJScrKyqo1npWVpeHDh5tUVeAYhqEHHnhAK1as0Mcff6yEhASzSwqoH/7wh9q5c6dyc3N9S3Jysn76058qNzdXNpvN7BKb1YgRI+rcqr1371717t3bpIoC6+TJk7Jaa//pstls7erW3vNJSEhQTExMrb9fFRUVWrNmTbv8+yV9H0S++uor/d///Z+ioqLMLilgJk+erM8++6zW36+4uDjNmjVL//jHP8wuL2A67DRNWlqaJk+erOTkZA0bNkyLFi1SQUGBpk2bZnZpzW769Ol688039f777ys8PNz3Lyqn06nQ0FCTq2t+4eHhda6HCQsLU1RUVLu8Tubhhx/W8OHD9fTTT+uOO+7Q5s2btWjRIi1atMjs0gJi/Pjx+u1vf6tevXqpf//+2r59u55//nnde++9ZpfWbE6cOKGvv/7a9zo/P1+5ubmKjIxUr169NHPmTD399NO6/PLLdfnll+vpp59Wp06dNGnSJBOrbrrzHW9cXJx+8pOfaNu2bfrb3/4mj8fj+xsWGRmp4OBgs8pusgv99z03bAUFBSkmJkZXXnllS5facsy9mcdcf/7zn43evXsbwcHBxuDBg9vtra6S6l1effVVs0trMe351l7DMIy//vWvxoABAwyHw2FcddVVxqJFi8wuKWDcbrfx0EMPGb169TJCQkKMvn37GrNnzzbKy8vNLq3Z/Otf/6r3/7N33323YRjVt/c+8cQTRkxMjOFwOIzRo0cbO3fuNLfoi3C+483Pz2/wb9i//vUvs0tvkgv99z1XR7i112IYhtFCuQcAAKCODnnNCAAAaD0IIwAAwFSEEQAAYCrCCAAAMBVhBAAAmIowAgAATEUYAQAApiKMAAAAUxFGAACAqQgjAADAVIQRAABgKsIIAAAw1f8Pskc+XZbCblkAAAAASUVORK5CYII=",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"hidden_size = 128\n",
|
|
"batch_size = 32\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, 80, print_every=5, plot_every=5)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:48:23.131948Z",
|
|
"iopub.status.busy": "2024-05-25T15:48:23.131435Z",
|
|
"iopub.status.idle": "2024-05-25T15:48:23.213007Z",
|
|
"shell.execute_reply": "2024-05-25T15:48:23.211856Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:48:23.131911Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Input sentence: ciesze sie ze by em w stanie pomoc\n",
|
|
"Target (true) translation: i m glad i was able to help\n",
|
|
"Output sentence: i m glad i was able to help <EOS>\n",
|
|
"\n",
|
|
"Input sentence: to moja matka chrzestna\n",
|
|
"Target (true) translation: she s my godmother\n",
|
|
"Output sentence: she s my godmother by three <EOS>\n",
|
|
"\n",
|
|
"Input sentence: nie gram w zadna gre\n",
|
|
"Target (true) translation: i m not playing a game\n",
|
|
"Output sentence: i m not playing a game <EOS>\n",
|
|
"\n",
|
|
"Input sentence: jestem wyzszy\n",
|
|
"Target (true) translation: i am taller\n",
|
|
"Output sentence: i am taller <EOS>\n",
|
|
"\n",
|
|
"Input sentence: jestes zdesperowany\n",
|
|
"Target (true) translation: you re desperate\n",
|
|
"Output sentence: you re desperate <EOS>\n",
|
|
"\n",
|
|
"Input sentence: zostane zwolniony\n",
|
|
"Target (true) translation: i m going to get fired\n",
|
|
"Output sentence: i m going to be arrested i think <EOS>\n",
|
|
"\n",
|
|
"Input sentence: mamy dzisiaj rybe jako g owne danie\n",
|
|
"Target (true) translation: we are having fish for our main course\n",
|
|
"Output sentence: we are having fish for our main course <EOS>\n",
|
|
"\n",
|
|
"Input sentence: jestes przepracowana\n",
|
|
"Target (true) translation: you are overworked\n",
|
|
"Output sentence: you are overworked <EOS>\n",
|
|
"\n",
|
|
"Input sentence: jestes elokwentny\n",
|
|
"Target (true) translation: you re articulate\n",
|
|
"Output sentence: you re articulate <EOS>\n",
|
|
"\n",
|
|
"Input sentence: zaczynam rozumiec\n",
|
|
"Target (true) translation: i m beginning to understand\n",
|
|
"Output sentence: i m beginning to understand <EOS>\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"evaluateRandomly(encoder, decoder)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:30:41.253734Z",
|
|
"iopub.status.busy": "2024-05-25T15:30:41.253325Z",
|
|
"iopub.status.idle": "2024-05-25T15:30:41.264515Z",
|
|
"shell.execute_reply": "2024-05-25T15:30:41.263376Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:30:41.253703Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"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), :])\n",
|
|
"\n",
|
|
"def translate(input_sentence, tokenized=False):\n",
|
|
" input_sentence = normalizeString(input_sentence)\n",
|
|
" output_words, attentions = evaluate(encoder, decoder, input_sentence, input_lang, output_lang)\n",
|
|
" if tokenized:\n",
|
|
" if \"<EOS>\" in output_words:\n",
|
|
" output_words.remove(\"<EOS>\")\n",
|
|
" return output_words\n",
|
|
" return ' '.join(output_words)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:58:53.639963Z",
|
|
"iopub.status.busy": "2024-05-25T14:58:53.639252Z",
|
|
"iopub.status.idle": "2024-05-25T14:58:53.654186Z",
|
|
"shell.execute_reply": "2024-05-25T14:58:53.653028Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:58:53.639932Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"['we', 'are', 'hungry']"
|
|
]
|
|
},
|
|
"execution_count": 24,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"translate(\"Jesteśmy głodni\", tokenized=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:46:05.024277Z",
|
|
"iopub.status.busy": "2024-05-25T14:46:05.023218Z",
|
|
"iopub.status.idle": "2024-05-25T14:46:05.426793Z",
|
|
"shell.execute_reply": "2024-05-25T14:46:05.424993Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:46:05.024227Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"input = jestes zbyt naiwny\n",
|
|
"output = you re too naive <EOS>\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"C:\\Users\\Michał\\AppData\\Local\\Temp\\ipykernel_10608\\712218569.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\\Michał\\AppData\\Local\\Temp\\ipykernel_10608\\712218569.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": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAcQAAAHHCAYAAAAhyyixAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA2C0lEQVR4nO3de3iMd/7/8dcESVQk6pSDRhK1SBrntFtUHVq69GtX6aJUHKJfSluqjhdXq9aKaqW0Kg5bEVazKP3SriKtQ5GenEt0aRVBQh2axKFIZn5/ZDO/jmSmYST3TOb5cN3Xyj33Pfd7Zq/m7f3+3J/PbbJYLBYBAODhvIwOAAAAV0BCBABAJEQAACSREAEAkERCBABAEgkRAABJJEQAACSREAEAkERCBABAEgkRAABJJEQAACSREAEAkERCBABAEgkRABzKz8/XgQMHlJeXZ3QoKGUkRMCDXLlyxegQ3M7HH3+s5s2ba8WKFUaHglJGQgQ8SGBgoAYPHqwdO3YYHYrbSE5OVq1atbRkyRKjQ0EpIyECHiQlJUXZ2dl67LHH1KBBA82YMUNnzpwxOiyXdf78eX366adasmSJtm3bplOnThkdEkoRCRHwIN26ddPq1at15swZPf/880pJSVFYWJj+53/+R2vWrGGc7BYffPCBoqOj9ac//Ult27bV0qVLjQ4JpYiECHigGjVq6OWXX9b+/fuVkJCgzz77TE8//bRCQkL06quv6urVq0aH6BKSk5MVGxsrSXr22WdJiOWcyWKxWIwOAkDZysrK0tKlS5WUlKSTJ0/qqaeeUlxcnM6cOaMZM2YoODhYmzZtMjpMQx08eFAtW7bU6dOnVbNmTV2+fFmBgYHavHmz/vjHPxodHkpBRaMDAFB21qxZo6SkJG3cuFFRUVEaMWKEnn32WVWrVs16TLNmzdS8eXPjgnQRS5Ys0RNPPKGaNWtKkvz8/NS9e3clJSWREMspWqZu5pdffjE6BLixQYMGKSQkRDt37tS+ffv0wgsv2CRDSapXr54mTZpkTIAuIj8/X8uXL7e2Sws9++yzWrlypW7cuGFQZChNtExd2BtvvKHw8HD17t1bktSrVy+tXr1aQUFBWr9+vZo2bWpwhHA3V69e1T333GN0GC4vMzNTixYt0oQJE+Tt7W3dbzabNX36dMXGxqpu3boGRojSQEJ0YfXq1dM///lPtW7dWqmpqerVq5dWrFihlStX6uTJkx4/xoM7Yzab9cMPP+jcuXMym802rz366KMGRQUYjzFEF5aZmanQ0FBJ0ieffKJevXqpc+fOCg8PZwwDd+Srr75S3759deLECd36b2GTyaT8/HyDInN9J06c0JUrV9SoUSN5eTHaVB7x/6oLu/fee5WRkSFJ2rBhgx5//HFJksVi4RcX7siwYcMUExOjgwcP6uLFi7p06ZJ1u3jxotHhuYTk5GTNnj3bZt///u//ql69emrcuLGio6Ot/12ifCEhurAePXqob9++6tSpky5cuKAuXbpIkvbt26f69esbHB3c0dGjRzV9+nRFRkaqWrVqCggIsNkgzZ8/3+a72LBhg5KSkrR06VJ9++23qlatml5//XUDI0RpoWXqwt5++22Fh4crIyNDM2fOlJ+fn6SCVurw4cMNjg7u6I9//KN++OEH/kHlwJEjRxQTE2P9ee3atfrzn/+sfv36SZKmT5+uQYMGGRUeShEJ0YVVqlRJY8aMKbJ/1KhRZR8MyoUXX3xRr7zyirKystS4cWNVqlTJ5vUmTZoYFJnruHbtmvz9/a0/p6WlafDgwdaf69Wrp6ysLCNCQykjIbq4ZcuWacGCBTp27Ji+/PJLhYWFafbs2YqIiNBf/vIXo8ODm+nZs6ck2fyCN5lMslgs3FTzX2FhYdq9e7fCwsJ0/vx5HTp0SI888oj19aysLNrL5RQJ0YUlJibq1Vdf1ahRo/T3v//d+suqWrVqmj17NgkRt+2nn34yOgSXFxsbqxEjRujQoUPavHmzGjVqpJYtW1pfT0tLU3R0tIERorSQEF3Yu+++q0WLFql79+6aMWOGdX9MTEyxrVTg94SFhRkdgssbP368rl69qjVr1igoKEirVq2yeX3nzp165plnDIoOpYmJ+S6scuXK+v777xUWFqaqVatq//79qlevno4ePaomTZro2rVrRocINxMSEqL27durffv2ateunRo2bGh0SIDLYNqFC4uIiNC+ffuK7P/0008VFRVV9gG5sMGDBys3N7fI/itXrtiMl3m6WbNmyd/fXwkJCYqMjFRwcLD69Omj+fPn6/Dhw0aH51KuXbumdevW6a233tKsWbO0bt06/hFa3lngshYvXmypU6eO5V//+pelSpUqlpSUFMu0adOsf8f/5+XlZTl79myR/T///LOlQoUK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BLdw+uJFo0NwCxmnvjc6BJdXlm1IWqYAAMizpl3QMgUAQFSIAAAHaJkCAKDCu0ydSYh3MZhSRssUAABRIQIAHKBlCgCASIgAABQwWwo2Z853E4whAgAgKkQAgAMWObmW6V2LpPSREAEA9jk5huhO8y5omQIAICpEAIAD3GUKAIBY3BsAAI9DhQgAsIuWKQAA8qyESMsUAABRIQIAHCl4/pNz57sJEiIAwC5PapmSEAEAdlnMBZsz57sLxhABABAVIgDAAVqmAADIsxIiLVMAAESFCABwwJMqRBIiAMAuT0qItEwBABAVIgDAAU96/BMJEQBgFy1TAAA8DBUiAMABJxf3lvtUiCREAIBdHvSwC/dombZv316jRo0yOgwA8DgFCdHixGb0Jyg5t0iIAACUNpdPiAMHDtS2bds0Z84cmUwmmUwmHT9+XNu2bdNDDz0kHx8fBQcHa8KECcrLy7Oed/36db300kuqXbu2fH199cgjj+jbb7+1e53r168rJyfHZgMAT1c47cKZzV24fEKcM2eOWrVqpeeee06ZmZnKzMxUpUqV1LVrVz344IPav3+/EhMT9f7772vatGnW88aNG6fVq1crOTlZe/bsUf369fXEE0/o4sWLxV4nPj5eAQEB1i00NLSsPiIAuCzn2qXOTdkoay6fEAMCAuTt7a177rlHQUFBCgoK0rx58xQaGqq5c+eqUaNG6t69u15//XXNmjVLZrNZV65cUWJiot5880116dJFUVFRWrRokSpXrqz333+/2OtMnDhR2dnZ1i0jI6OMPykAwEhueZfp4cOH1apVK5lMJuu+Nm3a6PLlyzp16pR++eUX3bx5U23atLG+XqlSJT300EM6fPhwse/p4+MjHx+fUo8dANyJJ03Md8uEaLFYbJJh4T5JMplMNn//vfMAAA442/Z0o4To8i1TSfL29lZ+fr7156ioKKWlpdn8n5SWlqaqVauqTp06ql+/vry9vbVjxw7r6zdv3tSuXbsUGRlZprEDANyDWyTE8PBwff311zp+/LjOnz+v4cOHKyMjQy+++KK+//57rV27Vq+99ppGjx4tLy8vValSRc8//7zGjh2rDRs2KD09Xc8995yuXr2quLg4oz8OALiPwpn5zmxuwi1apmPGjNGAAQMUFRWla9eu6aefftL69es1duxYNW3aVNWrV1dcXJwmT55sPWfG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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 2 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"evaluateAndShowAttention('Jesteś zbyt naiwny')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:46:10.395671Z",
|
|
"iopub.status.busy": "2024-05-25T14:46:10.394969Z",
|
|
"iopub.status.idle": "2024-05-25T14:46:10.793392Z",
|
|
"shell.execute_reply": "2024-05-25T14:46:10.791940Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:46:10.395630Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"input = naprawde mi przykro\n",
|
|
"output = i m really sorry <EOS>\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"C:\\Users\\Michał\\AppData\\Local\\Temp\\ipykernel_10608\\712218569.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\\Michał\\AppData\\Local\\Temp\\ipykernel_10608\\712218569.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": {
|
|
"image/png": "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ERWiCRw8eFD9+vXT7t27ZbFYVPyvrPgHGyvVoCqcP3++VMXoiRYuXKhTp04pKSmpZN+DDz6o+fPnS5Jat26tNWvWKDw83KAIUV34NccEHnvsMUVGRurYsWO66qqrlJ6erk2bNikmJkYbN240OjyYyMMPP1zm/ry8PPXq1esKR+Oe/vnPf9rNx1y9erVSUlK0aNEifffdd6pXr56mTZtmYISoLiREE9i6daumT5+uRo0aycvLS15eXuratauSk5NZkBkVsnbtWj399NN2+/Ly8nTHHXfQafjN/v37FRMTU/L1J598oj59+ui+++5T586d9dxzz2ndunUGRojqQkI0gaKiopIVaYKDg3X06FFJUkREhP71r38ZGRpMZu3atUpJSdGsWbMkSWfOnFGPHj1ksVi0evVqg6NzD+fPn1dgYGDJ11u2bNGf//znkq+bN2/OdKcaikE1JtC+fXvt2rVLzZs314033qgZM2bIx8dH8+bNU/PmzY0ODyYSGRmpNWvWqHv37vLy8tK7774rX19fffbZZ/L39zc6PLcQERGhHTt2KCIiQidOnFB6erq6du1a8v3s7GyWuKuhSIgm8PTTTysvL0+S9Oyzz+qvf/2runXrpoYNG/KMNlRY+/bt9emnn+r222/XjTfeqE8//ZTBNL+TkJCghx9+WOnp6Vq/fr3atGmj6Ojoku9v2bKFOZw1FKNMTerkyZOqX78+Q+hxWdddd12Z/538+9//VuPGje2S4c6dO69kaG7JarVqypQp+vTTTxUaGqqZM2eqbdu2Jd8fMGCA7rjjDo0aNcrAKFEdSIhurrCwUH5+fvr+++/5rRSVUpERkVOmTKnGSAD3RsvUzdWqVUsRERGMAESlkeQq5/z580pNTdX+/ftlsVgUFRWlHj160F6uwagQTSAlJUXvv/++3n77bTVo0MDocGBiw4cP18iRI+1GTaK0FStWKDExUSdOnLDbHxwcrPnz56t3794GRYbqxLQLE3jllVf01VdfKSwsTK1bt1bnzp3tNqC8zpw5o/j4eEVFRem5557TkSNHjA7J7WzZskX33HOP/vznP2vz5s06efKkTp48qa+//lrdunXTPffco61btxodJqoBFaIJXO4eEC0xVEROTo7efvttLViwQHv27NHtt9+uUaNG6a677lLt2rWNDs9wf/nLXxQeHq7XX3+9zO+PHj1amZmZWrVq1RWODNWNhAh4sLS0NL311lt68803FRAQoPvvv19jx45VVFSU0aEZpn79+tq0aZM6dOhQ5vd37dqlm2++WadOnbrCkaG60TI1ke3bt2vx4sV6++23tWPHDqPDgcllZWVp7dq1Wrt2rby9vfWXv/xF6enpateuXclKNp7owoULdivV/FFQUJDy8/OvYES4UhhlagKHDx/W4MGDtXnzZtWrV0+S9Ouvvyo2NlZLly5l1X2U28WLF7VixQqlpKRo7dq1uvbaa/X444/rvvvuU926dSVJ7777rh566CE9/vjjBkdrjFatWmn9+vUaMWJEmd9ft26dWrZseYWjwpVAhWgCI0eO1MWLF7Vv376SG/z79u2TzWZjcjAqpEmTJnrggQcUERGhb7/9Vtu3b9eYMWNKkqF06anwxb94eaLhw4friSeeKPMe4WeffaYnn3zSYbKEuXEP0QTq1KmjLVu26LrrrrPbv3PnTsXFxen8+fMGRQazWbx4sQYMGCA/Pz+jQ3FbVqtVAwcO1AcffKDWrVuXrFKzd+9e/fTTT+rbt6/ef/99HhJcA/Fv1ASaNWumixcvltpfWFioq6++2oCIYFY2m02//PJLqf0XLlzQokWLDIjI/Xh5een999/X0qVL1bp1a/3444/68ccf1aZNGy1ZskQffPABybCGokI0gU8++UTPPfecXnvtNUVHR8tisWj79u169NFHNXHiRPXt29foEGESXl5e8vf314IFC3T33XeX7D927JjCwsJYEQkejV9zTGD48OH6/vvvdeONN8rPz0++vr668cYbtXPnTo0cOVINGjQo2YDLmTZtmoYOHaqpU6caHYpbeu+991RQUFDy9aFDh+x+UTh37pxmzJhhRGioZlSIJrBw4cJyHzts2LBqjARm5+XlpezsbB08eFD9+vVTXFycFi9erNzcXCrE33h7eysrK0uNGzeWJAUGBur7778vefYo1XTNxbQLEyDJoaoUPwbqpptu0rZt29SnTx/Fxsbqn//8p8GRuY8/1gjUDJ6DhGgy58+fLzXAxtkk4posNze35L3n5uY6PdZTP6M/+v0P92bNmmnLli2677771KNHDwOjAtwDCdEE8vLyNHHiRL333nvKyckp9X1Pbd3Ur1+/pLVVr169Mh+Ca7PZZLFYPPYz+qMpU6YoICCg5OurrrpKH330kaZMmaJN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Ct1mSoi0TAEAEBUiAMAJWqYAAMizEiItUwAARIUIAHDCkypEEiIAwCGbzeriKNPKn3ulkRABAI550NJt3EMEAEBUiAAAJzxpLVMSIgDACdcG1chECZGWKQAAokIEADjBtAsAAORZ0y5omQIAICpEAIATtExN4uLFi6pdu7bdvoKCAvn4+BgUEQDULJ6UEK94y3T58uXq0KGD6tSpo4YNG+r2229XXl6erFarpk+frqZNm8rX11edOnXS6tWrS847dOiQLBaL3nvvPXXv3l1+fn56++23NXz4cPXt21fJyckKCwtTq1atNH36dHXo0KHUtaOjo/XMM89cybcLADCJK5oQs7KyNHjwYI0cOVL79u3Txo0b1b9/f9lsNr388st66aWX9OKLL2rXrl3q2bOn+vTpo59++snuNSZOnKhx48Zp37596tmzpyRp3bp12rdvn1JTU/Xpp59q5MiR2rt3r7777ruS83bt2qW0tDQNHz68zNjy8/OVm5trtwGApyuuEF3ZzOKKtkyzsrJUWFio/v37KyIiQpJKKrkXX3xREydO1KBBgyRJzz//vDZs2KDZs2frtddeK3mNpKQk9e/f3+51/f399eabb9q1Snv27KmUlBRdf/31kqSUlBTdfPPNat68eZmxJScna9q0aVX3ZgGgJmAt0+rRsWNH3XbbberQoYMGDBigN954Q6dOnVJubq6OHj2quLg4u+Pj4uK0b98+u30xMTGlXrdDhw6l7hs+8MADWrp0qS5cuKCLFy9qyZIlGjlypMPYJk+erNOnT5dsmZmZLrxTAKgZLi3cZnVhIyGWydvbW6mpqfr888/Vrl07vfrqq2rdurV++eUXSZLFYrE73mazldrn7+9f6nXL2te7d2/5+vrqo48+0sqVK5Wfn6+7777bYWy+vr4KDAy02wAAnuOKD6qxWCyKi4vTtGnTlJaWJh8fH61bt05hYWH6+uuv7Y7dsmWL2rZtW6nr1KpVS8OGDVNKSopSUlI0aNAgXXXVVVXxFgDAY3APsZps27ZN69atU3x8vBo3bqxt27bpP//5j9q2basJEyZoypQpatGihTp16qSUlBR9//33WrJkSaWvl5iYWJJQN2/eXFVvAwA8hidNu7iiCTEwMFCbNm3S7NmzlZubq4iICL300kvq1auXevbsqdzcXP3tb3/T8ePH1a5dO61YsUJRUVGV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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 2 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"evaluateAndShowAttention('Naprawdę mi przykro')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:46:13.191025Z",
|
|
"iopub.status.busy": "2024-05-25T14:46:13.190403Z",
|
|
"iopub.status.idle": "2024-05-25T14:46:13.613486Z",
|
|
"shell.execute_reply": "2024-05-25T14:46:13.612143Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:46:13.190997Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"input = jestes moim ojcem\n",
|
|
"output = you are my father <EOS>\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"C:\\Users\\Michał\\AppData\\Local\\Temp\\ipykernel_10608\\712218569.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\\Michał\\AppData\\Local\\Temp\\ipykernel_10608\\712218569.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": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 2 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"evaluateAndShowAttention('Jesteś moim ojcem')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:46:15.841005Z",
|
|
"iopub.status.busy": "2024-05-25T14:46:15.840433Z",
|
|
"iopub.status.idle": "2024-05-25T14:46:16.232003Z",
|
|
"shell.execute_reply": "2024-05-25T14:46:16.230365Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:46:15.840973Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"input = on tez jest nauczycielem\n",
|
|
"output = he is a teacher too <EOS>\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"C:\\Users\\Michał\\AppData\\Local\\Temp\\ipykernel_10608\\712218569.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\\Michał\\AppData\\Local\\Temp\\ipykernel_10608\\712218569.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": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAdIAAAHzCAYAAACUkJylAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABC0UlEQVR4nO3de1xU1f7/8feAAqYOeAUyRMxUDC2FOuElzdSyjmWXk6ZH06Ty0OUgx0y/dtKspMxMrTAtU+mUWekpKzJJ07yUJZGZVOYtiMALlngFZeb3h8f5NQEG7M1smXk9fexHzJq9Z3829ODDZ6291rY5nU6nAABAtfhZHQAAALUZiRQAAANIpAAAGEAiBQDAABIpAAAGkEgBADCARAoAgAEkUgAADCCRAgBgAIkUAAADSKQAABhAIgUAwIA6VgcAwHcdOXJEDofDrc1ut1sUDVA9VKQAPGr37t26/vrrVb9+fQUHB6tRo0Zq1KiRQkJC1KhRI6vDA6qMihSARw0dOlSS9Morryg0NFQ2m83iiABjbDyPFIAnNWjQQJmZmWrXrp3VoQCmoGsXgEdddtllys3NtToMwDR07QLwqJdfflmjR49WXl6eYmJiVLduXbf3O3XqZFFkQPWQSAF41P79+7Vz506NHDnS1Waz2eR0OmWz2VRaWmphdEDVMUYKwKM6dOig6OhojRs3rtybjSIjIy2KDKgeEikAj6pfv762bNmiNm3aWB0KYApuNgLgUb1799aWLVusDgMwDWOkADxqwIABGjNmjLZu3aqOHTuWudnohhtusCgyoHro2gXgUX5+FXeEcbMRaiMSKQAABjBGCsAyJ06csDoEwDASKQCPKi0t1WOPPaYWLVqoQYMG2rVrlyTp3//+t+bPn29xdEDVkUgBeNQTTzyhhQsXatq0aQoICHC1d+zYUS+//LKFkQHVQyIF4FFpaWmaN2+ehg4dKn9/f1d7p06d9P3331sYGVA9JFIAHpWXl1fuYgwOh0MnT560ICLAGBIpAI+6+OKLtW7dujLtb731ljp37mxBRIAxLMgAwKMmTZqkYcOGKS8vTw6HQ8uWLdMPP/ygtLQ0vf/++1aHB1QZ80gBeNxHH32kqVOnKjMzUw6HQ126dNEjjzyifv36WR0aUGUkUgAADGCMFAAAAxgjBVDjGjVqVOa5oxU5ePBgDUcDmItECqDGzZw50+oQgBrDGCkAAAYwRgrA43bu3KmHH35Yt99+u/bt2ydJWrFihbZt22ZxZEDVkUgBeNTatWvVsWNHbdq0ScuWLdORI0ckSd98840mTZpkcXRA1ZFIAXjU+PHj9fjjjysjI8Nt0fqrrrpKn332mYWRAdVDIgXgUVu3btVNN91Upr1Zs2YqLCy0ICLAGBIpAI8KCQlRfn5+mfasrCy1aNHCgogAY0ikADxqyJAheuihh1RQUCCbzSaHw6ENGzZo7NixGj58uNXhAVXG9BcAHnXy5EmNGDFCb7zxhpxOp+rUqaPS0lINGTJECxcudHtGKVAbkEgBWGLnzp3KysqSw+FQ586dddFFF1kdElAtJFIAAAxgiUAANS45OVmPPfaY6tevr+Tk5LPuO2PGDA9FBZiDRAqgxmVlZenkyZOurytS2YXtgXMJXbsAABjA9BcAHnXo0KFyH5V28OBBFRUVWRARYAyJFIBHDR48WG+88UaZ9jfffFODBw+2ICLAGLp2AXhU48aNtWHDBkVHR7u1f//99+rWrRvLBKLWoSIF4FHFxcU6depUmfaTJ0/q+PHjFkQEGEMiBeBRl112mebNm1em/cUXX1RsbKwFEQHGMP0FgEc98cQT6tOnj7Zs2aKrr75akrRq1Sp9+eWXWrlypcXRAVVHRQrAo7p166bPPvtMERERevPNN/Xee++pTZs2+uabb9SjRw+rw6txpaWl+uabb8rt3kbtxM1GAOBB77zzjm655RalpaVp6NChVocDE1CRAvCoXr16KS0tzWdvLFq0aJGaNWumhQsXWh0KTEIiBeBRsbGxGjdunMLCwnTXXXfp888/tzokjzlw4IA+/PBDLVy4UGvXrtXPP/9sdUgwAYkUgEc988wzysvLU1pamvbv368rr7xSHTp00PTp07V3716rw6tRr7/+umJiYnTttdeqR48eSktLszokmIBECsDj/P39deONN+qdd95RXl6ehgwZon//+9+KiIjQwIEDtXr1aqtDrBGLFi3S8OHDJUl///vfSaRegpuNAFjmiy++0IIFC7R48WIFBwdrxIgRys/P12uvvaZ//OMfmj59utUhmubbb79VbGys8vLy1LRpUx05ckShoaFavXq1/vKXv1gdHgwgkQLwqH379unVV1/VggUL9OOPP2rAgAFKSEjQNddc43qM2scff6yBAwfqyJEjFkdrnrFjx2r79u1avny5q23o0KFq2LChXnzxRQsjg1EkUgAeFRAQoAsvvFB33nmnRowYoWbNmpXZp6ioSDfeeKM++eQTCyI0X2lpqS644AI999xzuvXWW13tH374oYYOHaqCggIFBARYGCGMIJEC8Kh169b5xMILv5efn6+XXnpJ48ePd0uYDodDU6dO1fDhw9WyZUsLI4QRJFIAHjVlyhR1795dvXv3dms/evSonnnmGT3yyCMWRQZUD4kUgEf5+fmpbt26SklJUXJysqt97969Ov/881VaWmphdJ7z008/6ejRo2rfvr38/JhAUZvx0wPgcWlpaUpJSdGIESNUUlJidTg1atGiRZo5c6Zb2913363WrVurY8eOiomJUW5urjXBwRQkUgAed9VVV+nzzz/XF198oV69enn1QgwvvviigoODXa9XrFihBQsWKC0tTV9++aVCQkL06KOPWhghjCKRAvCoM1NcLrzwQn3++eey2+2Ki4vT5s2bLY6sZmzfvl1xcXGu1++++65uuOEGDR06VF26dNHUqVO1atUqCyOEUSRSAB71+9sy7Ha70tPTddNNN2ngwIHWBVWDjh8/Lrvd7nq9ceNGXXnlla7XrVu3VkFBgRWhwSQ82BuARy1YsMCtq9PPz0+zZ89W586d9emnn1oYWc2IjIxUZmamIiMjdeDAAW3btk3du3d3vV9QUOD2/UDtw127AFCDUlJSNHv2bCUmJmr16tXav3+/vv32W9f7M2fO1Pvvv6+PP/7YwihhBBUpAI964IEH1KZNGz3wwANu7c8//7x27NhR5g7X2u6hhx7SsWPHtGzZMoWFhemtt95ye3/Dhg26/fbbLYoOZqAiBeBRLVq00PLlyxUbG+vW/tVXX+mGG27gGZ2odahIAXhUYWFhuWOCdrtdBw4csCAizzh+/LgyMjK0fft22Ww2XXTRRerbt6/q1atndWgwiEQKwKPatGmjFStW6L777nNr//DDD9W6dWuLoqpZy5cvV0JCQpk/FJo2bar58+drwIABFkUGM5BIAXhUcnKy7rvvPu3fv9+13u6qVav0zDPPeN34qHR6usutt96qG264Qf/6178UHR0tScrOztYzzzyjW2+9VWvWrFF8fLzFkaK6GCMF4HFz5szRE088oV9++UWS1KpVK02ePFnDhw+3ODLzXXfddYqIiNDcuXPLff+ee+5Rbm6u0tPTPRwZzEIiBSzQu3dvLVu2TCEhIW7tRUVFGjhwoFavXm1NYB62f/9+1atXTw0aNLA6lBrTqFEjffrpp+rYsWO573/zzTfq2bOnfv31Vw9HBrPQtQtYYM2aNeUu1n7ixAmtW7fOgoisUd5Dvb3NiRMn3FY2+qPg4GAVFxd7MCKYjUQKeNA333zj+jo7O9ttabjS0lKtWLFCLVq0sCI0j4mKinKtt1ueXbt2eTCamte2bVutXr1aI0eOLPf9VatWqU2bNh6OCmYikQIedOmll8pms8lms5V5sLUk1atXT88995wFkXlOUlKS2+uTJ08qKytLK1as0IMPPmhNUDVoxIgRGjt2rEJDQ3Xddde5vffBBx9o3LhxmjhxokXRwQyMkQIe9NNPP8npdKp169b64osv3Lo2AwIC1Lx5c/n7+1sYoXVeeOEFbd68WQsWLLA6FFM5HA4NGjRIS5cuVbt27dzu2v3xxx81cOBAvfXWWzzcuxYjkcJyvXv3Vs+ePTVp0iS39l9//VW33HKLz9x44+t27dqlSy+9VEVFRVaHUiOWLFmixYsXa/v27ZJOd/kOHjxYgwcPtjgyGEUiheX8/PzUpEkTdevWTa+99prq168vSdq7d6/OP/98lZaWWhyh+RYtWqSmTZvq+uuvlySNGzdO8+bNU4cOHbR48WJFRkZaHKHnTZs2TampqdqzZ4/VoQBVQl8Czgkff/yxCgoKdMUVV/jEL9KpU6e6lob77LPP9Pzzz2vatGlq2rSpxowZY3F0Natz587q0qWLa+vcubPCw8P1f//3f/q///s/q8Mz3Ztvvul2h/aePXvc/jg8duyYpk2bZkVoMAkVKSzn5+fneibjnXfeqZUrV+qtt95SdHS011ak5513nr7//nu1bNlSDz30kPLz85WWlqZt27apV69e2r9/v9Uh1phHH33U7bWfn5+aNWumXr16qX379hZFVXP8/f2Vn5+v5s2bSzq9pvDXX3/tWg7Rm3tefAV37Z6jSkpKtG/fPjkcDrf2li1bWhRRzTkzFSIwMFCvvfaaHn/8cV177bV66KGHLI6s5jRo0ECFhYVq2bKlVq5c6apCg4KCdPz4cYujq1l/HAv3dn+sVahdvA+J9Bzz448/6s4779TGjRvd2p1Op2w2m1f+1frHXywPP/ywoqOjdccdd1gUUc3r27evEhIS1LlzZ23fvt01Vrpt2za1atXK2uA86Pjx4zp58qRb29kWLwDORSTSc8yIESNUp04dvf/++woPDz/rxHVvsXv3bjVt2tSt7ZZbblG7du2UmZlpUVQ164UXXtDDDz+s3NxcLV26VE2aNJEkZWZmev1Dno8ePaqHHnpIb775pgoLC8u8741/LMK7MUZ6jqlfv74yMzO9cqzoz+zYsUM7d+7UlVdeqXr16rmqcHiXe++9V5988ommTJmi4cOH64UXXlBeXp7mzp2rJ598UkOHDrU6RFP5+flp0aJFrmew3n777Zo5c6ZCQ0MlSb/99ptGjhzJHxC1GIn0HHPZZZfp2WefVffu3a0OxWMKCws1aNAgrV69WjabTT/++KNat26tUaNGqVGjRpo+fbrVIdaIdevWae7cudq1a5feeusttWjRQq+++qqioqK8+uffsmVLpaWlqVevXrLb7frqq6/Upk0bvfrqq1q8eLHXPQWlMgsteOuwja9g+ss55qmnntK4ceO0Zs0aFRYWqqioyG3zRmPGjFGdOnWUk5Oj8847z9U+aNAgffjhhxZGVnOWLl2qa665RvXq1dNXX33lWrT88OHDmjp1qsXR1ayDBw8qKipK0unx0IMHD0qSunfvrk8//dTK0GqEw+H4040kWruRSM8xffr00eeff67evXurefPmatSokRo1aqSQkBA1atTI6vBqxMqVK/XUU0/pggsucGu/6KKL9NNPP1kUVc16/PHH9eKLL+qll15S3bp1Xe1du3bVV199ZWFkNa9169auucIdOnTQm2++KUl67733yjxWzlscO3ZMW7duLfe9bdu26ciRIx6OCGbiZqNzzCeffGJ1CB539OhRt0r0jAMHDigwMNCCiGreDz/8oCuvvLJMu91u12+//eb5gDxo5MiR2rJli3r27KkJEybo+uuv13PPPadTp05pxowZVodXI0pKSvSXv/xFa9as0eWXX+5qz87OVufOnZWTk+PVz2T1diTSc0zPnj3122+/af78+fruu+9ks9kUHR2tUaNGuW5W8DZXXnml0tLS9Nhjj0k6PV7kcDj09NNP66qrrrI4upoRHh6uHTt2lJnqsn79etdEfW/1+5WbrrrqKn3//ffavHmzLrzwQl1yySUWRlZzQkJCNGDAAC1atMgtkb766qvq06ePwsLCLIwORnGz0Tlm8+bNuvbaaxUUFKTLL79cTqdTmzdv1vHjx7Vy5Up16dLF6hBNl52drV69eik2NlarV6/WDTfcoG3btungwYPasGGDLrzwQqtDNN20adO0aNEivfLKK+rbt6/S09P1008/acyYMXrkkUd03333WR1ijVq1apVWrVpV7qIjr7zyikVR1awPPvhAI0aMUH5+vurUqSOn06nIyEhNnz5dt912m9XhwQAS6TmmR48eatOmjV566SXVqXO6w+DUqVNKSEjQrl27vPJmjJycHNWpU0dz585VZmamHA6HunTponvvvVcnT570ytWcJGnixIl69tlndeLECUmnV3YaO3asqzL3Vo8++qimTJmiuLi4cudK//e//7UosppVWlqqCy64QC+++KJuvPFGrV69WrfeeqsKCgoUEBBgdXgwgER6jqlXr56ysrLKzCPNzs5WXFycjh07ZlFkNeePa5GeUVhYqObNm3v1HY3Hjh1Tdna2HA6HOnTo4BPjZOHh4Zo2bZqGDRtmdSge9+CDD2rnzp1atmyZRo4cqaCgIM2ZM8fqsGAQY6TnGLvdrpycnDKJNDc3Vw0bNrQoqppV0d9yR44cUVBQkIejqTk333yzFi5cKLvdrptvvvms+zZo0EAXX3yxRo8e7XVj4yUlJeratavVYVhi+PDhuvzyy5WXl6elS5dq5cqVVocEE5BIzzGDBg3SqFGjNH36dHXt2lU2m03r16/Xgw8+6HVLxyUnJ0s6fXPRI4884nbnbmlpqTZt2qRLL73UoujMFxwc7OrG/LPkWFxcrBdffFEbNmzQ8uXLPRGexyQkJOj111/Xv//9b6tD8biOHTuqQ4cOGjp0qM4//3xdccUVVocEE5BIzzHTp0+XzWbT8OHDderUKUlS3bp19Y9//ENPPvmkxdGZKysrS9LpinTr1q1u40QBAQG65JJLNHbsWKvCM92CBQvK/boi2dnZuuyyy2oyJEucOHFC8+bN08cff6xOnTq5zaOV5LVTYM644447lJSUpCeeeMLqUGASxkjPUceOHdPOnTvldDrVpk2bcudZeouRI0dq1qxZPPXjD0pLS/Xtt9963ZSQs01pstlsWr16tQej8byDBw/queee0z333MO0Fy9BIgUAwACWCAQAwAASKQAABpBIAQAwgER6DisuLtbkyZNdj9jyBb54zRLX7UvX7YvX7O242egcVlRUpODgYB06dMhn7mj1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tZZXjUpS06ZN5e/vX6b63LdvX5kqVZIOHz6szZs3KysrS/fdd58kyeFwyOl0qk6dOlq5cqV69+5dqUhJpACAc5bdbndLpBUJCAhQbGysMjIydNNNN7naMzIydOONN5b7uVu3bnVrS01N1erVq/X2228rKiqq0jGSSAEAprNiQYbk5GQNGzZMcXFxio+P17x585STk6PRo0dLkiZMmKC8vDylpaXJz89PMTExbsc3b95cQUFBZdr/DIkUAGA6K5YIHDRokAoLCzVlyhTl5+crJiZG6enpioyMlCTl5+f/6ZzS6iCRAgC8RmJiohITE8t9b+HChWc9dvLkyZo8eXKVz0kiBQCYzpceo0YiBQCYzpcWrSeRAgBM50uJlAUZAAAwgIoUAGA6KtJzyOTJk6v1fDgAgHVOT38xskSg1VdQeVVKpL169VJSUlINhQIAQO3jk127TqdTpaWlhlb7BwBUzJemv1S6Ih0xYoTWrl2rWbNmyWazyWazac+ePcrOztZ1112nBg0aKDQ0VMOGDdOBAwdcx61YsULdu3dXSEiImjRpor/+9a/auXOn22f//PPPGjx4sBo3bqz69esrLi5OmzZtctvn1VdfVatWrRQcHKzBgwfr8OHDrvecTqemTZum1q1bq169errkkkv09ttvu95fs2aNbDabPvroI8XFxSkwMFDr1q2r8jcLAFBJZ5Y2MrLVEpVOpLNmzVJ8fLzuuusu5efnKz8/X3Xr1lXPnj116aWXavPmzVqxYoX27t2r2267zXXc0aNHlZycrC+//FKrVq2Sn5+fbrrpJjkcDknSkSNH1LNnT/3yyy9avny5tmzZonHjxrnel6SdO3fqnXfe0fvvv6/3339fa9eu1ZNPPul6/+GHH9aCBQs0Z84cbdu2TWPGjNHf//53rV271u0axo0bp5SUFH333Xfq1KlTuddZXFysoqIitw0AgIpUum8zODhYAQEBOu+88xQWFiZJeuSRR9SlSxdNnTrVtd8rr7yiiIgIbd++XW3bttUtt9zi9jnz589X8+bNlZ2drZiYGL3++uvav3+/vvzySzVu3FiS1KZNG7djHA6HFi5cqIYNG0qShg0bplWrVumJJ57Q0aNHNWPGDK1evVrx8fGSpNatW2v9+vWaO3euevbs6fqcKVOmqG/fvme9zpSUFD366KOV/bYAAMphxVq7VjF0125m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P3++Hn/8cddx48aN09KlS7Vo0SJ99dVXatOmja655hodPHiwwnMVFxerqKjIbQMAoCK1IpEGBwcrICBA5513nsLCwhQWFqbU1FRFRETo+eefV/v27TVw4EA9+uijeuaZZ+RwOHT06FHNmTNHTz/9tPr3768OHTropZdeUr169TR//vwKz5WSkqLg4GDXFhER4cErBQDvQEVaC3z33XeKj4+XzWZztXXr1k1HjhzRzz//rJ07d+rkyZPq1q2b6/26devq8ssv13fffVfh506YMEGHDh1ybbm5uTV6HQDgnRyuO3ers0m1567dWnuzkdPpdEuiZ9okyWazuX39Z8f9XmBgoAIDA02OFgDgrWpNRRoQEKDS0lLX6w4dOmjjxo1u5f/GjRvVsGFDtWjRQm3atFFAQIDWr1/vev/kyZPavHmzoqOjPRo7APgaq7p2U1NTFRUVpaCgIMXGxmrdunUV7rts2TL17dtXzZo1k91uV3x8vD766KMqn7PWJNJWrVpp06ZN2rNnjw4cOKDExETl5ubq/vvv1/fff693331XkyZNUnJysvz8/FS/fn394x//0IMPPqgVK1YoOztbd911l44dO6ZRo0ZZfTkA4N3OLBFoZKuiJUuWKCkpSRMnTlRWVpZ69Oih/v37Kycnp9z9P/30U/Xt21fp6enKzMzUVVddpQEDBigrK6tK5601Xbtjx47VHXfcoQ4dOuj48ePavXu30tPT9eCDD+qSSy5R48aNNWrUKD388MOuY5588kk5HA4NGzZMhw8fVlxcnD766CM1atTIwisBANSEGTNmaNSoUUpISJAkzZw5Ux999JHmzJmjlJSUMvvPnDnT7fXUqVP17rvv6r333lPnzp0rfd5ak0jbtm2rzz77zK2tVatW+uKLLyo8JigoSLNnz9bs2bNrOjwAwO84ZWy93DNH/nEKYkX3sZSUlCgzM1Pjx493a+/Xr582btxYqXM6HA4dPnxYjRs3rlKstaZrFwBQe5g1RhoREeE2JbG8ylKSDhw4oNLSUoWGhrq1h4aGqqCgoFIxP/PMMzp69Khuu+22Kl1rralIAQC1h1mL1ufm5sput7va/2xWRVVnapyxePFiTZ48We+++66aN29epVhJpACAc5bdbndLpBVp2rSp/P39y1Sf+/btK1Ol/tGSJUs0atQovfXWW+rTp0+VY6RrFwBgOk9PfwkICFBsbKwyMjLc2jMyMtS1a9cKj1u8eLFGjBih119/Xddff321rpWKFABgOiue/pKcnKxhw4YpLi5O8fHxmjdvnnJycjR69GhJp1euy8vLU1pamqTTSXT48OGaNWuWrrjiClc1W69ePQUHB1f6vCRSAIBXGDRokAoLCzVlyhTl5+crJiZG6enpioyMlCTl5+e7zSmdO3euTp06pXvvvVf33nuvq/2OO+7QwoULK31eEikAwHRWPY80MTFRiYmJ5b73x+S4Zs2aap3jj0ikAADT8WBvAABQKVSkAADzOR2nNyPH1xIkUgCA6Zz/+2fk+NqCrl0AAAygIgUAmM6XbjYikQIATEciBQDAALMWra8NGCMFAMAAKlIAgOno2gUAwABfSqR07QIAYAAVKQDAdL5UkZJIAQDmc0oykgxrTx6laxcAACOoSAEApnPKIadsho6vLUikqFB29karQ/C4U6dOWh2CJX74YZPVIXhcasoCq0PwuKNHjmjJf6Z55Fy+NEZK1y4AAAZQkQIAaoCxirQ23W1EIgUAmM6XunZJpAAA051etN7AzUYsWg8AgG+gIgUAmI6uXQAADPClRErXLgAABlCRAgDM53QaXGu39lSkJFIAgOmc//tn5Pjagq5dAAAMoCIFAJjOl+aRkkgBAKbzpbt2SaQAANP5UiJljBQAAANIpAAA052pSI1s1ZGamqqoqCgFBQUpNjZW69atq3Df/Px8DRkyRO3atZOfn5+SkpKqdU4SKQDAdFYk0iVLligpKUkTJ05UVlaWevToof79+ysnJ6fc/YuLi9WsWTNNnDhRl1xySbWvlUQKAPAKM2bM0KhRo5SQkKDo6GjNnDlTERERmjNnTrn7t2rVSrNmzdLw4cMVHBxc7fNysxEAwHSnq8rqT2E5U5EWFRW5tQcGBiowMLDM/iUlJcrMzNT48ePd2vv166eNGzdWO47KoCIFAJjvzBKBRjZJERERCg4Odm0pKSnlnu7AgQMqLS1VaGioW3toaKgKCgpq9FKpSAEA56zc3FzZ7XbX6/Kq0d+z2dwXgXA6nWXazEYiBQCYzqy1du12u1sirUjTpk3l7+9fpvrct29fmSrVbHTtAgBM5+m7dgMCAhQbG6uMjAy39oyMDHXt2tXMSyuDihQA4BWSk5M1bNgwxcXFKT4+XvPmzVNOTo5Gjx4tSZowYYLy8vKUlpbmOubrr7+WJB05ckT79+/X119/rYCAAHXo0KHS5yWRAgBMd3rRemPHV9WgQYNUWFioKVOmKD8/XzExMUpPT1dkZKSk0wsw/HFOaefOnV1fZ2Zm6vXXX1dkZKT27NlT6fOSSAEAprNqrd3ExEQlJiaW+97ChQtNO8/v1fgYqc1mK3d74403XPuUlpbq2WefVadOnRQUFKSQkBD1799fGzZscPus0tJSpaSkqH379qpXr54aN26sK664QgsWLKjpywAAVIFVSwRaoUYq0l9//VV169ZVgwYNJEkLFizQtdde67ZPSEiIpNPf7MGDB+vjjz/W008/rauvvlpFRUV64YUX1KtXL7311lsaOHCgJGny5MmaN2+enn/+ecXFxamoqEibN2/Wr7/+6vrcX375Rc2bN1edOhTbAICaZ1q2OXXqlD766CMtWrRIy5cv16ZNm1xrF4aEhCgsLKzc49588029/fbbWr58uQYMGOBqnzdvngoLC5WQkKC+ffuqfv36eu+995SYmKi//e1vrv3+uD7iSy+9pDlz5mjo0KEaMWKEOnbsaNYlAgAqiceoVcHWrVs1duxYXXDBBRo+fLiaNGmiTz75pNILAL/++utq27atWxI941//+pcKCwtdtzOHhYVp9erV2r9/f4Wf99BDD2n27Nn64Ycf1KVLF3Xp0kWzZs066zG/V1xcrKKiIrcNAFBVRrt1vTyRFhYWavbs2erSpYvi4uK0Y8cOpaamKj8/X3PmzFF8fLzb/rfffrsaNGjgtu3atUuStH37dkVHR5d7njPt27dvl3R6QeL9+/crLCxMnTp10ujRo/Xhhx+6HRMUFKTbbrtN77//vvLy8jR8+HAtWrRILVq00MCBA/Xf//5Xp06dqvDaUlJS3JajioiIqM63CADgI6qVSJ977jn985//VIMGDbRjxw698847uvnmmxUQEFDu/s8++6y+/vprt60qCerM8k4dOnTQt99+q88//1wjR47U3r17NWDAACUkJJR7XPPmzZWUlKSvvvpK7777rj777DPdfPPN+vbbbys814QJE3To0CHXlpubW+k4AQD/43QY32qJao2R3n333apbt64WLVqkDh066JZbbtGwYcN01VVXyc+vbG4OCwtTmzZtyv2stm3bKjs7u9z3vvvuO0nSRRdd5Grz8/PTZZddpssuu0xjxozRf/7zHw0bNkwTJ05UVFSU2/GHDx/W22+/rVdffVWffvqpevbsqTvuuOOsE20rerIAAKDyTi/xZ3yJwNqgWhXp+eefr4kTJ2r79u366KOPFBgYqFtuuUWRkZEaP368tm3bVunPGjx4sH788Ue99957Zd575pln1KRJE/Xt27fC488kxaNHj0o6PUXmww8/1JAhQxQaGqqUlBT17t1bu3bt0qpVqzR8+PAKK2cAAKrK8M1GXbt21dy5c1VQUKCnn35aW7Zs0SWXXKKtW7e69vntt99UUFDgtp1JfIMHD9ZNN92kO+64Q/Pnz9eePXv0zTff6J577tHy5cv18ssvq379+pKkW2+9Vc8++6w2bdqkn376SWvWrNG9996rtm3bqn379pKkqVOnusZkP/74Y23fvl0PP/ywWrZsafRSAQCV5EvzSG3OGoj2l19+UYMGDWS32yt8fE1KSorrAaynTp3SrFmztGDBAu3YsUOBgYGKj4/Xww8/rO7du7uOeemll7R48WJ9++23OnTokMLCwtS7d29NnjzZtQTUnj17FBYWpqCgIFOupaioyNCT02uzNm1irQ7B43bs+MrqECzRtm2c1SF4XOoy31vI5eiRI7rxiit06NChSj1RpTrO/M6025vIZqt+reZ0OlRUVFijsZqlRhKpNyGR+hYSqe8gkZJIzcLyPwAA01Vn0Xkzj/ckEikAwHSn+zqNrGxkWig1jkQKADCd0VHD2jTqWONPfwEAwJtRkQIATOdLFSmJFABgPqOJsBYlUrp2AQAwgIoUAGA6pxySyl+Qp3LH156KlEQKADCdL42R0rULAIABVKQAANP5UkVKIgUAmM6XEilduwAAGEBFCgAwnS9VpCRSAIDpTj+9xcD0FxIpAMCX+VJFyhgpAAAGUJECAMznQ2vtkkgBAKYzusRfbVoikK5dAAAMoCIFAJiOu3YBADCAu3YBAEClUJH+idr0V5HZHI5Sq0OwgG/+vEtLfe9nffTIEatD8LhjR49K8tzvNV/5/Wlz+sqVVtPPP/+siIgIq8MAANPk5ubqggsuqJHPPnHihKKiolRQUGD4s8LCwrR7924FBQWZEFnNIZH+CYfDoV9++UUNGzaUzVb9gfPqKCoqUkREhHJzc2W32z16bqv44jVLXLcvXbeV1+x0OnX48GGdf/758vOruZG9EydOqKSkxPDnBAQEnPNJVKJr90/5+fnV2F9ulWW3233ml8wZvnjNEtftS6y65uDg4Bo/R1BQUK1IgGbhZiMAAAwgkQIAYACJ9BwWGBioSZMmKTAw0OpQPMYXr1niun3pun3xmr0dNxsBAGAAFSkAAAaQSAEAMIBECgCAASRSAAAMIJECAGAAiRQAAANIpAAAGEAiBQDAgP8H96NuNLiqOEUAAAAASUVORK5CYII=",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 2 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"evaluateAndShowAttention('On też jest nauczycielem')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T14:50:24.774464Z",
|
|
"iopub.status.busy": "2024-05-25T14:50:24.773506Z",
|
|
"iopub.status.idle": "2024-05-25T14:50:24.795895Z",
|
|
"shell.execute_reply": "2024-05-25T14:50:24.794979Z",
|
|
"shell.execute_reply.started": "2024-05-25T14:50:24.774430Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"torch.save(encoder.state_dict(), \"encoder.pt\")\n",
|
|
"torch.save(decoder.state_dict(), \"decoder.pt\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# BLEU score"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Jako że korzystaliśmy z okrojonej wersji zbioru danych, słownik nie zawiera wszystkich słów pojawiających się w przykładach więc do ewaluacji wykorzystujemy część przykładów z treningu"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:28:54.297253Z",
|
|
"iopub.status.busy": "2024-05-25T15:28:54.296348Z",
|
|
"iopub.status.idle": "2024-05-25T15:28:59.041172Z",
|
|
"shell.execute_reply": "2024-05-25T15:28:59.040201Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:28:54.297211Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>English</th>\n",
|
|
" <th>Polish</th>\n",
|
|
" <th>attribution</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>13492</th>\n",
|
|
" <td>i m the last in line</td>\n",
|
|
" <td>jestem ostatni w kolejce</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #5...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>14379</th>\n",
|
|
" <td>you are not a coward</td>\n",
|
|
" <td>nie jestes tchorzem</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #1...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>31538</th>\n",
|
|
" <td>we re anxious about her health</td>\n",
|
|
" <td>martwimy sie o jej zdrowie</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #7...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>33382</th>\n",
|
|
" <td>he s not at all afraid of snakes</td>\n",
|
|
" <td>on zupe nie nie boi sie wezy</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #2...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>13031</th>\n",
|
|
" <td>he is a fast speaker</td>\n",
|
|
" <td>on szybko mowi</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #3...</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" English Polish \\\n",
|
|
"13492 i m the last in line jestem ostatni w kolejce \n",
|
|
"14379 you are not a coward nie jestes tchorzem \n",
|
|
"31538 we re anxious about her health martwimy sie o jej zdrowie \n",
|
|
"33382 he s not at all afraid of snakes on zupe nie nie boi sie wezy \n",
|
|
"13031 he is a fast speaker on szybko mowi \n",
|
|
"\n",
|
|
" attribution \n",
|
|
"13492 CC-BY 2.0 (France) Attribution: tatoeba.org #5... \n",
|
|
"14379 CC-BY 2.0 (France) Attribution: tatoeba.org #1... \n",
|
|
"31538 CC-BY 2.0 (France) Attribution: tatoeba.org #7... \n",
|
|
"33382 CC-BY 2.0 (France) Attribution: tatoeba.org #2... \n",
|
|
"13031 CC-BY 2.0 (France) Attribution: tatoeba.org #3... "
|
|
]
|
|
},
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"import pandas as pd\n",
|
|
"\n",
|
|
"\n",
|
|
"def filter_rows(row):\n",
|
|
" return len(row[\"English\"].split(' '))<MAX_LENGTH and \\\n",
|
|
" len(row[\"Polish\"].split(' '))<MAX_LENGTH and \\\n",
|
|
" row[\"English\"].startswith(eng_prefixes)\n",
|
|
"data_file = pd.read_csv(\"pol.txt\", sep='\\t', names=[\"English\",\"Polish\",\"attribution\"])\n",
|
|
"data_file[\"English\"] = data_file[\"English\"].apply(normalizeString)\n",
|
|
"data_file[\"Polish\"] = data_file[\"Polish\"].apply(normalizeString)\n",
|
|
"\n",
|
|
"filter_list = data_file.apply(filter_rows, axis=1)\n",
|
|
"\n",
|
|
"test_section = data_file[filter_list]\n",
|
|
"test_section = test_section.sample(frac=1).head(500)\n",
|
|
"test_section.head()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:29:07.110816Z",
|
|
"iopub.status.busy": "2024-05-25T15:29:07.110416Z",
|
|
"iopub.status.idle": "2024-05-25T15:29:07.117378Z",
|
|
"shell.execute_reply": "2024-05-25T15:29:07.116136Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:29:07.110786Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"test_section[\"English_tokenized\"] = test_section[\"English\"].apply(lambda x: x.split())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 34,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:29:10.203540Z",
|
|
"iopub.status.busy": "2024-05-25T15:29:10.203170Z",
|
|
"iopub.status.idle": "2024-05-25T15:29:10.212993Z",
|
|
"shell.execute_reply": "2024-05-25T15:29:10.211937Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:29:10.203511Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"13492 [i, m, the, last, in, line]\n",
|
|
"14379 [you, are, not, a, coward]\n",
|
|
"31538 [we, re, anxious, about, her, health]\n",
|
|
"33382 [he, s, not, at, all, afraid, of, snakes]\n",
|
|
"13031 [he, is, a, fast, speaker]\n",
|
|
"Name: English_tokenized, dtype: object"
|
|
]
|
|
},
|
|
"execution_count": 34,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"test_section.head()[\"English_tokenized\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 35,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:30:53.183937Z",
|
|
"iopub.status.busy": "2024-05-25T15:30:53.183117Z",
|
|
"iopub.status.idle": "2024-05-25T15:30:56.313012Z",
|
|
"shell.execute_reply": "2024-05-25T15:30:56.312202Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:30:53.183902Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"test_section[\"English_translated\"] = test_section[\"Polish\"].apply(lambda x: translate(x, tokenized=True))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 36,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:31:06.746471Z",
|
|
"iopub.status.busy": "2024-05-25T15:31:06.745381Z",
|
|
"iopub.status.idle": "2024-05-25T15:31:06.771839Z",
|
|
"shell.execute_reply": "2024-05-25T15:31:06.770679Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:31:06.746417Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>English</th>\n",
|
|
" <th>Polish</th>\n",
|
|
" <th>attribution</th>\n",
|
|
" <th>English_tokenized</th>\n",
|
|
" <th>English_translated</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>13492</th>\n",
|
|
" <td>i m the last in line</td>\n",
|
|
" <td>jestem ostatni w kolejce</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #5...</td>\n",
|
|
" <td>[i, m, the, last, in, line]</td>\n",
|
|
" <td>[i, m, the, last, in, line]</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>14379</th>\n",
|
|
" <td>you are not a coward</td>\n",
|
|
" <td>nie jestes tchorzem</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #1...</td>\n",
|
|
" <td>[you, are, not, a, coward]</td>\n",
|
|
" <td>[you, are, not, a, coward]</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>31538</th>\n",
|
|
" <td>we re anxious about her health</td>\n",
|
|
" <td>martwimy sie o jej zdrowie</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #7...</td>\n",
|
|
" <td>[we, re, anxious, about, her, health]</td>\n",
|
|
" <td>[we, are, worried, about, her, health]</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>33382</th>\n",
|
|
" <td>he s not at all afraid of snakes</td>\n",
|
|
" <td>on zupe nie nie boi sie wezy</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #2...</td>\n",
|
|
" <td>[he, s, not, at, all, afraid, of, snakes]</td>\n",
|
|
" <td>[he, s, not, afraid, of, snakes, at, all, afraid]</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>13031</th>\n",
|
|
" <td>he is a fast speaker</td>\n",
|
|
" <td>on szybko mowi</td>\n",
|
|
" <td>CC-BY 2.0 (France) Attribution: tatoeba.org #3...</td>\n",
|
|
" <td>[he, is, a, fast, speaker]</td>\n",
|
|
" <td>[he, is, a, fast, speaker, young]</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" English Polish \\\n",
|
|
"13492 i m the last in line jestem ostatni w kolejce \n",
|
|
"14379 you are not a coward nie jestes tchorzem \n",
|
|
"31538 we re anxious about her health martwimy sie o jej zdrowie \n",
|
|
"33382 he s not at all afraid of snakes on zupe nie nie boi sie wezy \n",
|
|
"13031 he is a fast speaker on szybko mowi \n",
|
|
"\n",
|
|
" attribution \\\n",
|
|
"13492 CC-BY 2.0 (France) Attribution: tatoeba.org #5... \n",
|
|
"14379 CC-BY 2.0 (France) Attribution: tatoeba.org #1... \n",
|
|
"31538 CC-BY 2.0 (France) Attribution: tatoeba.org #7... \n",
|
|
"33382 CC-BY 2.0 (France) Attribution: tatoeba.org #2... \n",
|
|
"13031 CC-BY 2.0 (France) Attribution: tatoeba.org #3... \n",
|
|
"\n",
|
|
" English_tokenized \\\n",
|
|
"13492 [i, m, the, last, in, line] \n",
|
|
"14379 [you, are, not, a, coward] \n",
|
|
"31538 [we, re, anxious, about, her, health] \n",
|
|
"33382 [he, s, not, at, all, afraid, of, snakes] \n",
|
|
"13031 [he, is, a, fast, speaker] \n",
|
|
"\n",
|
|
" English_translated \n",
|
|
"13492 [i, m, the, last, in, line] \n",
|
|
"14379 [you, are, not, a, coward] \n",
|
|
"31538 [we, are, worried, about, her, health] \n",
|
|
"33382 [he, s, not, afraid, of, snakes, at, all, afraid] \n",
|
|
"13031 [he, is, a, fast, speaker, young] "
|
|
]
|
|
},
|
|
"execution_count": 36,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"test_section.head()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 37,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:43:29.442752Z",
|
|
"iopub.status.busy": "2024-05-25T15:43:29.441911Z",
|
|
"iopub.status.idle": "2024-05-25T15:43:29.447799Z",
|
|
"shell.execute_reply": "2024-05-25T15:43:29.446877Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:43:29.442721Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"candidate_corpus = test_section[\"English_translated\"].values\n",
|
|
"references_corpus = test_section[\"English_tokenized\"].values.tolist()\n",
|
|
"x = candidate_corpus.tolist()\n",
|
|
"y = [[el] for el in references_corpus]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 38,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:43:30.475080Z",
|
|
"iopub.status.busy": "2024-05-25T15:43:30.474463Z",
|
|
"iopub.status.idle": "2024-05-25T15:43:30.482690Z",
|
|
"shell.execute_reply": "2024-05-25T15:43:30.481686Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:43:30.475039Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[[['i', 'm', 'the', 'last', 'in', 'line']],\n",
|
|
" [['you', 'are', 'not', 'a', 'coward']],\n",
|
|
" [['we', 're', 'anxious', 'about', 'her', 'health']],\n",
|
|
" [['he', 's', 'not', 'at', 'all', 'afraid', 'of', 'snakes']],\n",
|
|
" [['he', 'is', 'a', 'fast', 'speaker']]]"
|
|
]
|
|
},
|
|
"execution_count": 38,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"y[:5]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 39,
|
|
"metadata": {
|
|
"execution": {
|
|
"iopub.execute_input": "2024-05-25T15:43:36.654953Z",
|
|
"iopub.status.busy": "2024-05-25T15:43:36.654035Z",
|
|
"iopub.status.idle": "2024-05-25T15:43:36.916617Z",
|
|
"shell.execute_reply": "2024-05-25T15:43:36.915429Z",
|
|
"shell.execute_reply.started": "2024-05-25T15:43:36.654906Z"
|
|
},
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"C:\\Users\\Michał\\AppData\\Roaming\\Python\\Python310\\site-packages\\torchtext\\data\\__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"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0.8122377991676331"
|
|
]
|
|
},
|
|
"execution_count": 39,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from torchtext.data.metrics import bleu_score\n",
|
|
"\n",
|
|
"bleu_score(x, y)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kaggle": {
|
|
"accelerator": "nvidiaTeslaT4",
|
|
"dataSources": [
|
|
{
|
|
"datasetId": 5082663,
|
|
"sourceId": 8513800,
|
|
"sourceType": "datasetVersion"
|
|
}
|
|
],
|
|
"dockerImageVersionId": 30699,
|
|
"isGpuEnabled": true,
|
|
"isInternetEnabled": true,
|
|
"language": "python",
|
|
"sourceType": "notebook"
|
|
},
|
|
"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.11"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|