Europarl/TAU_translator_from_scratch.ipynb
2020-01-28 18:51:11 +01:00

45 KiB

Install

TO DO

  • Load and prepare data for train, dev-0 and test-A sets
  • Prepere basic Encoder adn Decoder
  • Test training basic Encoder-Decoder + Adam optimzer + Cross Entropy loss fnc
  • Report model training status (epoch, time, iterations, current loss)
  • Model saving to drive, saving evaluation on test-A (and evaluation on dev-0?) on the end of epoch
  • Add pretrained embeddings
  • Add attention mechanism
  • Reverse input sentence?
  • BiRNN?
from google.colab import drive
drive.mount('/content/drive')
!pip install torch torchvision
import re
import math
import time
import os.path

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
from torch import optim
from tqdm import tqdm
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
cuda:0

Load data

BLANK_TOKEN = 0
SOS_TOKEN = 1
EOS_TOKEN = 2
UNK_TOKEN = 3

class Lang:
    # https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html

    def __init__(self, name):
        self.name = name
        self.word2index = {"<BLANK>": 0, "<SOS>": 1, "<EOS>": 2, "<UNK>": 3}
        self.word2count = {}
        self.index2word = {0: "<BLANK>", 1: "<SOS>", 2: "<EOS>", 3: "<UNK>"}
        self.n_words = 4

    def addSentence(self, sentence):
        for word in sentence.split(' '):
            self.addWord(word)

    def addWord(self, word):
        if word not in self.word2index:
            self.word2index[word] = self.n_words
            self.word2count[word] = 1
            self.index2word[self.n_words] = word
            self.n_words += 1
        else:
            self.word2count[word] += 1

    def vector2Sentence(self, vector):
        words = []
        for index in vector:
            if index not in self.index2word:
                words.append("<UNK>")
            else:
                words.append(self.index2word[index])
        return " ".join(words)

    # def blankAllLowFreqWorlds(self):
    #     new_word2index = {"SOS": 0, "EOS": 1, "<UNK>": 2}
    #     new_index2word = {0: "SOS", 1: "EOS", 2: "<UNK>"}
    #     new_n_words = 3

    #     for word in self.word2count:
    #         if self.word2count[word] == 1:
    #             new_word2index[word] = 2
    #         else:
    #             if word not in new_word2index:
    #                 new_word2index[word] = new_n_words
    #                 new_index2word[new_n_words] = word
    #                 new_n_words += 1

class MyData(Dataset):
    def __init__(self, X, y):
        self.data = X
        self.target = y
        self.length = [ np.sum(1 - np.equal(x, 0)) for x in X]
        
    def __getitem__(self, index):
        x = self.data[index]
        y = self.target[index]
        x_len = self.length[index]
        return x,y,x_len
    
    def __len__(self):
        return len(self.data)


def normalize_line(line: str) -> str:
    out = line.strip().lower()
    out = re.sub(r"([,:.!?\)])", r" \1", out)
    out = re.sub(r"([\(])", r"\1 ", out)
    return out


def sentence_to_indexes(lang: Lang, sentence: str) -> list:
    out = [lang.word2index["<SOS>"]]
    for s in sentence.split(" "):
        if s not in lang.word2index:
            out.append(lang.word2index["<UNK>"])
        else:
            out.append(lang.word2index[s])
    out.append(lang.word2index["<EOS>"])
    return out


# def sentence_to_tensor(lang: Lang, sentence: str) -> list:
#     indexes = sentence_to_indexes(lang, sentence)
#     indexes.append(lang.word2index["<EOS>"])
#     out = torch.tensor(indexes, dtype=torch.long, device=device)
#     out = out.view(-1, 1)
#     return out


# def sentence_pair_to_tensors(lang_1: Lang, lang_2: Lang, pair):
#     out_sentence_1 = sentence_to_tensor(lang_1, pair[0])
#     out_sentence_2 = sentence_to_tensor(lang_2, pair[1])
#     return((out_sentence_1, out_sentence_2))
TRAIN_DATA_PATH = "/content/drive/My Drive/Colab Notebooks/euro-parl-data/train/train.tsv"
TEST_DATA_DEV_0_IN_PATH = "/content/drive/My Drive/Colab Notebooks/euro-parl-data/dev-0/in.tsv"
TEST_DATA_DEV_0_EXPECTED_PATH = "/content/drive/My Drive/Colab Notebooks/euro-parl-data/dev-0/expected.tsv"
TEST_DATA_A_PATH = "/content/drive/My Drive/Colab Notebooks/euro-parl-data/test-A/in.tsv"

print(f"{TRAIN_DATA_PATH}: {os.path.isfile(TRAIN_DATA_PATH)}")
print(f"{TEST_DATA_DEV_0_IN_PATH}: {os.path.isfile(TEST_DATA_DEV_0_IN_PATH)}")
print(f"{TEST_DATA_DEV_0_EXPECTED_PATH}: {os.path.isfile(TEST_DATA_DEV_0_EXPECTED_PATH)}")
print(f"{TEST_DATA_A_PATH}: {os.path.isfile(TEST_DATA_A_PATH)}")

# load train data
# MAX_TOKENS_IN_SENTENCE = 20
# MAX_TOKENS_OUT_SENTENCE = 25
MAX_TOKENS_IN_SENTENCE = 30
MAX_TOKENS_OUT_SENTENCE = 30
SRC_lang = Lang("eng")
TRG_lang = Lang("pol")
# SRC_TRG_pairs = []
train_SRC_tensor = []
train_TRG_tensor = []

test_dev_0_SRC_tensor = []
test_dev_0_TRG_tensor_oryginal = []

test_A_SRC_tensor = []

print(f"\n> Loading train data from '{TRAIN_DATA_PATH}'")
with open(TRAIN_DATA_PATH) as file_in:
  for line in file_in:
    pl_line, en_line = line.strip().split("\t")
    pl_line = normalize_line(pl_line)
    en_line = normalize_line(en_line)
    if(len(pl_line.split(" ")) > MAX_TOKENS_IN_SENTENCE):
      continue

    if(len(en_line.split(" ")) > MAX_TOKENS_OUT_SENTENCE):
      continue
    TRG_lang.addSentence(pl_line)
    SRC_lang.addSentence(en_line)
    # SRC_TRG_pairs.append((en_line, pl_line))
    train_SRC_tensor.append(sentence_to_indexes(SRC_lang, en_line))
    train_TRG_tensor.append(sentence_to_indexes(TRG_lang, pl_line))



print(f"---TEST---")
print(f"\n> no. pairs: {len(train_SRC_tensor)}")
print(f"> {SRC_lang.name} - no. words: {SRC_lang.n_words}")
print(f"> {TRG_lang.name} - no. words: {TRG_lang.n_words}")


print(f"\n> Loading test dev-0 data from '{TEST_DATA_DEV_0_IN_PATH}' and '{TEST_DATA_DEV_0_EXPECTED_PATH}'")
with open(TEST_DATA_DEV_0_IN_PATH) as file_in:
  for line in file_in:
    en_line = normalize_line(line.strip())
    test_dev_0_SRC_tensor.append(sentence_to_indexes(SRC_lang, en_line))

with open(TEST_DATA_DEV_0_EXPECTED_PATH) as file_in:
  for line in file_in:
    test_dev_0_TRG_tensor_oryginal.append(line.strip())


print(f"---TEST DEV 0---")
print(f"> no. pairs: {len(test_dev_0_SRC_tensor)}, {len(test_dev_0_TRG_tensor_oryginal)}")


print(f"\n> Loading test test-A data from '{TEST_DATA_A_PATH}'")
with open(TEST_DATA_A_PATH) as file_in:
  for line in file_in:
    en_line = normalize_line(line.strip())
    test_A_SRC_tensor.append(sentence_to_indexes(SRC_lang, en_line))


print(f"---TEST A---")
print(f"> no. pairs: {len(test_A_SRC_tensor)}")


 
/content/drive/My Drive/Colab Notebooks/euro-parl-data/train/train.tsv: True
/content/drive/My Drive/Colab Notebooks/euro-parl-data/dev-0/in.tsv: True
/content/drive/My Drive/Colab Notebooks/euro-parl-data/dev-0/expected.tsv: True
/content/drive/My Drive/Colab Notebooks/euro-parl-data/test-A/in.tsv: True

> Loading train data from '/content/drive/My Drive/Colab Notebooks/euro-parl-data/train/train.tsv'
---TEST---

> no. pairs: 354115
> eng - no. words: 51106
> pol - no. words: 126051

> Loading test dev-0 data from '/content/drive/My Drive/Colab Notebooks/euro-parl-data/dev-0/in.tsv' and '/content/drive/My Drive/Colab Notebooks/euro-parl-data/dev-0/expected.tsv'
---TEST DEV 0---
> no. pairs: 10000, 10000

> Loading test test-A data from '/content/drive/My Drive/Colab Notebooks/euro-parl-data/test-A/in.tsv'
---TEST A---
> no. pairs: 5000
def max_length(tensor):
    lengths = [len(t) for t in tensor]
    return max(lengths), lengths.index(max(lengths))

def pad_sequence(x, max_len):
    padded = np.zeros((max_len), dtype=np.int64)
    eos_index = SRC_lang.word2index["<EOS>"]
    if len(x) > max_len:
       padded[:] = x[:max_len]
       if padded[-1] != eos_index:
          padded[-1] = eos_index
    else: 
      padded[:len(x)] = x
    
    return padded
max_length_SRC, max_index_SRC = max_length(train_SRC_tensor)
max_length_TRG, max_index_TRG = max_length(train_TRG_tensor)

train_SRC_tensor = [pad_sequence(s, max_length_SRC) for s in train_SRC_tensor]
train_TRG_tensor = [pad_sequence(s, max_length_TRG) for s in train_TRG_tensor]

test_dev_0_SRC_tensor = [pad_sequence(s, max_length_SRC) for s in test_dev_0_SRC_tensor]
test_A_SRC_tensor = [pad_sequence(s, max_length_SRC) for s in test_A_SRC_tensor]
print(train_SRC_tensor[1])
print(SRC_lang.vector2Sentence(train_SRC_tensor[1]))
print()
print(train_TRG_tensor[1])
print(TRG_lang.vector2Sentence(train_TRG_tensor[1]))
print(max_length_SRC, max_length_TRG)
print(SRC_lang.vector2Sentence(train_SRC_tensor[max_index_SRC]))
print(TRG_lang.vector2Sentence(train_TRG_tensor[max_index_SRC]))
print()
print(SRC_lang.vector2Sentence(train_SRC_tensor[max_index_TRG]))
print(TRG_lang.vector2Sentence(train_TRG_tensor[max_index_TRG]))

print("\n\n---TEST DEV SET---")
print(test_dev_0_SRC_tensor[346])
print(SRC_lang.vector2Sentence(test_dev_0_SRC_tensor[346]))
print(test_dev_0_TRG_tensor_oryginal[346])

Docoder / Encoder

BUFFER_SIZE = len(train_SRC_tensor)
BATCH_SIZE = 50
N_BATCH = BUFFER_SIZE//BATCH_SIZE
embedding_dim = 256
hidden_units = 1024
vocab_src_size = SRC_lang.n_words
vocab_trg_size = TRG_lang.n_words

train_dataset = DataLoader(MyData(train_SRC_tensor , train_TRG_tensor), batch_size = BATCH_SIZE, drop_last=True, shuffle=True)
test_dev_0_dataset = DataLoader(MyData(test_dev_0_SRC_tensor, np.zeros((len(test_dev_0_SRC_tensor)), dtype=np.int64)), batch_size = BATCH_SIZE, shuffle=False)
test_A_dataset = DataLoader(MyData(test_A_SRC_tensor, np.zeros((len(test_A_SRC_tensor)), dtype=np.int64)), batch_size = BATCH_SIZE, shuffle=False)
for (batch, (inp, targ, inp_len)) in enumerate(train_dataset):
  print(f"{inp}\n{targ}\n{inp_len}\n\n")
  break

for (batch, (inp, targ, inp_len)) in enumerate(test_A_dataset):
  # print(f"{inp}\n{targ}\n{inp_len}\n\n")
  for vec in inp.numpy():
    print(SRC_lang.vector2Sentence(vec))
  break

for (batch, (inp, targ, inp_len)) in enumerate(test_dev_0_dataset):
  print(f"{inp}\n{targ}\n{inp_len}\n\n")
  break

class Encoder(nn.Module):
    def __init__(self, vocab_size, embedding_dim, enc_units, batch_sz):
        super(Encoder, self).__init__()
        self.batch_sz = batch_sz
        self.enc_units = enc_units
        self.vocab_size = vocab_size
        self.embedding_dim = embedding_dim
        self.embedding = nn.Embedding(self.vocab_size, self.embedding_dim)
        self.gru = nn.GRU(self.embedding_dim, self.enc_units)
        
    def forward(self, x, lens, device):
        # x: batch_size, max_length 
        
        # x: batch_size, max_length, embedding_dim
        x = self.embedding(x) 
                
        # x transformed = max_len X batch_size X embedding_dim
        # x = x.permute(1,0,2)
        x = pack_padded_sequence(x, lens) # unpad
    
        self.hidden = self.initialize_hidden_state(device)
        
        # output: max_length, batch_size, enc_units
        # self.hidden: 1, batch_size, enc_units
        output, self.hidden = self.gru(x, self.hidden) # gru returns hidden state of all timesteps as well as hidden state at last timestep
        
        # pad the sequence to the max length in the batch
        output, _ = pad_packed_sequence(output)
        
        return output, self.hidden

    def initialize_hidden_state(self, device):
        return torch.zeros((1, self.batch_sz, self.enc_units)).to(device)

### sort batch function to be able to use with pad_packed_sequence
def sort_batch(X, y, lengths):
    lengths, indx = lengths.sort(dim=0, descending=True)
    X = X[indx]
    y = y[indx]
    return X.transpose(0,1), y, lengths, indx # transpose (batch x seq) to (seq x batch)
class Decoder(nn.Module):
    def __init__(self, vocab_size, embedding_dim, dec_units, enc_units, batch_sz):
        super(Decoder, self).__init__()
        self.batch_sz = batch_sz
        self.dec_units = dec_units
        self.enc_units = enc_units
        self.vocab_size = vocab_size
        self.embedding_dim = embedding_dim
        self.embedding = nn.Embedding(self.vocab_size, self.embedding_dim)
        self.gru = nn.GRU(self.embedding_dim + self.enc_units, 
                          self.dec_units,
                          batch_first=True)
        self.fc = nn.Linear(self.enc_units, self.vocab_size)
        
        # used for attention
        self.W1 = nn.Linear(self.enc_units, self.dec_units)
        self.W2 = nn.Linear(self.enc_units, self.dec_units)
        self.V = nn.Linear(self.enc_units, 1)
    
    def forward(self, x, hidden, enc_output):
        # enc_output original: (max_length, batch_size, enc_units)
        # enc_output converted == (batch_size, max_length, hidden_size)
        enc_output = enc_output.permute(1,0,2)
        # hidden shape == (batch_size, hidden size)
        # hidden_with_time_axis shape == (batch_size, 1, hidden size)
        # we are doing this to perform addition to calculate the score
        
        # hidden shape == (batch_size, hidden size)
        # hidden_with_time_axis shape == (batch_size, 1, hidden size)
        hidden_with_time_axis = hidden.permute(1, 0, 2)
        
        # score: (batch_size, max_length, hidden_size) # Bahdanaus's
        # we get 1 at the last axis because we are applying tanh(FC(EO) + FC(H)) to self.V
        # It doesn't matter which FC we pick for each of the inputs
        score = torch.tanh(self.W1(enc_output) + self.W2(hidden_with_time_axis))
        
        #score = torch.tanh(self.W2(hidden_with_time_axis) + self.W1(enc_output))
          
        # attention_weights shape == (batch_size, max_length, 1)
        # we get 1 at the last axis because we are applying score to self.V
        attention_weights = torch.softmax(self.V(score), dim=1)
        
        # context_vector shape after sum == (batch_size, hidden_size)
        context_vector = attention_weights * enc_output
        context_vector = torch.sum(context_vector, dim=1)
        
        # x shape after passing through embedding == (batch_size, 1, embedding_dim)
        # takes case of the right portion of the model above (illustrated in red)
        x = self.embedding(x)
        
        # x shape after concatenation == (batch_size, 1, embedding_dim + hidden_size)
        #x = tf.concat([tf.expand_dims(context_vector, 1), x], axis=-1)
        # ? Looks like attention vector in diagram of source
        x = torch.cat((context_vector.unsqueeze(1), x), -1)
        
        # passing the concatenated vector to the GRU
        # output: (batch_size, 1, hidden_size)
        output, state = self.gru(x)
        
        
        # output shape == (batch_size * 1, hidden_size)
        output =  output.view(-1, output.size(2))
        
        # output shape == (batch_size * 1, vocab)
        x = self.fc(output)
        
        return x, state, attention_weights
    
    def initialize_hidden_state(self):
        return torch.zeros((1, self.batch_sz, self.dec_units))
# TEST ENCODER
encoder = Encoder(vocab_src_size, embedding_dim, hidden_units, BATCH_SIZE)

encoder.to(device)

it = iter(train_dataset)
x, y, x_len = next(it)
xs, ys, lens, _ = sort_batch(x, y, x_len)

enc_output, enc_hidden = encoder(xs.to(device), lens, device)

print(enc_output.size()) # max_length, batch_size, enc_units
# TEST DECODER
encoder = Encoder(vocab_src_size, embedding_dim, hidden_units, BATCH_SIZE)
encoder.to(device)

it = iter(train_dataset)
x, y, x_len = next(it)
xs, ys, lens, _ = sort_batch(x, y, x_len)

enc_output, enc_hidden = encoder(xs.to(device), lens, device)

print("Input: ", x.shape)
print("Output: ", y.shape)

# sort the batch first to be able to use with pac_pack_sequence
xs, ys, lens, _ = sort_batch(x, y, x_len)

enc_output, enc_hidden = encoder(xs.to(device), lens, device)
print("Encoder Output: ", enc_output.shape) # batch_size X max_length X enc_units
print("Encoder Hidden: ", enc_hidden.shape) # batch_size X enc_units (corresponds to the last state)

decoder = Decoder(vocab_trg_size, embedding_dim, hidden_units, hidden_units, BATCH_SIZE)
decoder = decoder.to(device)

print(enc_hidden.squeeze(0).shape)

dec_hidden = enc_hidden#.squeeze(0)
dec_input = torch.tensor([[TRG_lang.word2index['<SOS>']]] * BATCH_SIZE)
print("Decoder Input: ", dec_input.shape)
print("--------")

for t in range(1, y.size(1)):
    # enc_hidden: 1, batch_size, enc_units
    # output: max_length, batch_size, enc_units
    predictions, dec_hidden, _ = decoder(dec_input.to(device), 
                                         dec_hidden.to(device), 
                                         enc_output.to(device))
    
    print("Prediction: ", predictions.shape)
    topv, topi = predictions.data.topk(1)
    print("Topi: ", topi.shape)
    print(topi)
    print("Decoder Hidden: ", dec_hidden.shape)
    
    #loss += loss_function(y[:, t].to(device), predictions.to(device))
    
    dec_input = y[:, t].unsqueeze(1)
    print(dec_input)

    print(dec_input.shape)
    break
def predict(enc, dec, seq, dev):
  pass
# TEST PREDICTION FOR TEST dev 0
# TEST PREDICTION FOR TEST A

Train

def loss_function(real, pred):
    """ Only consider non-zero inputs in the loss; mask needed """
    #mask = 1 - np.equal(real, 0) # assign 0 to all above 0 and 1 to all 0s
    #print(mask)
    if torch.cuda.is_available():
      mask = real.ge(1).type(torch.cuda.FloatTensor)
    else:
      mask = real.ge(1).type(torch.FloatTensor)
      
    
    loss_ = criterion(pred, real) * mask 
    return torch.mean(loss_)
encoder = Encoder(vocab_src_size, embedding_dim, hidden_units, BATCH_SIZE)
decoder = Decoder(vocab_trg_size, embedding_dim, hidden_units, hidden_units, BATCH_SIZE)

encoder.to(device)
decoder.to(device)

Decoder(
  (embedding): Embedding(126051, 256)
  (gru): GRU(1280, 1024, batch_first=True)
  (fc): Linear(in_features=1024, out_features=126051, bias=True)
  (W1): Linear(in_features=1024, out_features=1024, bias=True)
  (W2): Linear(in_features=1024, out_features=1024, bias=True)
  (V): Linear(in_features=1024, out_features=1, bias=True)
)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(list(encoder.parameters()) + list(decoder.parameters()), 
                       lr=0.001)
def predict(seq, seq_l):
  out_seq = []
  enc_output, enc_hidden = encoder(seq.to(device), seq_l, device)
  dec_hidden = enc_hidden
  dec_input = torch.tensor([[TRG_lang.word2index['<SOS>']]] * BATCH_SIZE)
  for i in range(MAX_TOKENS_OUT_SENTENCE):
    predictions, dec_hidden, _ = decoder(dec_input.to(device), 
                                         dec_hidden.to(device), 
                                         enc_output.to(device))
    topv, topi = predictions.data.topk(1)
    dec_input = topi
    out_seq.append(topi.cpu().squeeze().detach().numpy())

  out = []
  for vec in np.transpose(np.array(out_seq)):
      out.append(TRG_lang.vector2Sentence(vec))
  return np.array(out)



### TEST PREDICT
EPOCHS = 1
print(f"batches:{N_BATCH}")
for (batch, (inp, targ, inp_len)) in enumerate(train_dataset):
        

    
    encoder.train()
    decoder.train()
    
    xs, ys, lens, _ = sort_batch(inp, targ, inp_len)
    pred_x = xs.t()[3].numpy()
    pred_y = ys[3].numpy()
    print(SRC_lang.vector2Sentence(pred_x))
    print(TRG_lang.vector2Sentence(pred_y))


    for epoch in range(EPOCHS):
      
        start = time.time() 
        total_loss = 0
        loss = 0

        

        # print(xs)
        enc_output, enc_hidden = encoder(xs.to(device), lens, device)
        dec_hidden = enc_hidden
        
        # use teacher forcing - feeding the target as the next input (via dec_input)
        dec_input = torch.tensor([[TRG_lang.word2index['<SOS>']]] * BATCH_SIZE)
        
        # run code below for every timestep in the ys batch
        for t in range(1, 5):
            predictions, dec_hidden, _ = decoder(topi, 
                                         dec_hidden.to(device), 
                                         enc_output.to(device))
            dec_input = ys[:, t].unsqueeze(1)
            # print(dec_input, dec_input.shape)
            topv, topi = predictions.data.topk(1)
            print(np.transpose(np.array([TRG_lang.index2word[index] for index in topi.cpu().squeeze().detach().numpy()])))
            loss += loss_function(ys[:, t].to(device), predictions.to(device))
            topv, topi = predictions.data.topk(1)

            

            # dec_input = ys[:, t].unsqueeze(1)
            
        
        batch_loss = (loss / int(ys.size(1)))
        total_loss += batch_loss
        
        # optimizer.zero_grad()
        
        # loss.backward()

        # ### UPDATE MODEL PARAMETERS
        # optimizer.step()

      
        encoder.eval()
        decoder.eval()
        print(predict(xs, lens))
    break
TEST_DEV_PATH = "/content/drive/My Drive/Colab Notebooks/euro-parl-data/dev-0/"
TEST_A_PATH = "/content/drive/My Drive/Colab Notebooks/euro-parl-data/test-A/"
MODELS_PATH = "/content/drive/My Drive/Colab Notebooks/euro-parl-data/models/"
EPOCHS = 20
print(f"batches:{N_BATCH}")

for epoch in range(10, EPOCHS):
    start = time.time()
    
    encoder.train()
    decoder.train()
    
    total_loss = 0
    
    for (batch, (inp, targ, inp_len)) in enumerate(train_dataset):
        loss = 0
        
        xs, ys, lens, _ = sort_batch(inp, targ, inp_len)
        enc_output, enc_hidden = encoder(xs.to(device), lens, device)
        dec_hidden = enc_hidden
        
        dec_input = torch.tensor([[TRG_lang.word2index['<SOS>']]] * BATCH_SIZE)
        
        for t in range(1, ys.size(1)):
            predictions, dec_hidden, _ = decoder(dec_input.to(device), 
                                         dec_hidden.to(device), 
                                         enc_output.to(device))
            loss += loss_function(ys[:, t].to(device), predictions.to(device))
            dec_input = ys[:, t].unsqueeze(1)
            
        
        batch_loss = (loss / int(ys.size(1)))
        total_loss += batch_loss
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if batch % 1000 == 0:
            print(f'Epoch {epoch + 1} Batch {batch} Loss {batch_loss.detach().item():.4f} Time {time.time() - start}')
        

    print('Epoch {} Loss {:.4f}'.format(epoch + 1,
                                        total_loss / N_BATCH))
    print('Time taken for 1 epoch {} sec\n'.format(time.time() - start))

    encoder.eval()
    decoder.eval()

    file_name = f"ep-{epoch+1}_embedding-dim-{embedding_dim}_hidden-units-{hidden_units}_max-len-in-{MAX_TOKENS_IN_SENTENCE}_max-len-out-{MAX_TOKENS_OUT_SENTENCE}"
    dev_file_path = f"{TEST_DEV_PATH}out-{file_name}.tsv"
    a_file_path = f"{TEST_A_PATH}out-{file_name}.tsv"
    model_file_path = f"{MODELS_PATH}model-{file_name}.pt"

    # dev-0 test
    preds = []
    for (batch, (inp, targ, inp_len)) in enumerate(test_dev_0_dataset):
        xs, ys, lens, indx = sort_batch(inp, targ, inp_len)
        tmp = [p for _, p in sorted([(indx[i].item(), pred) for i, pred in enumerate(predict(xs, lens))], key=lambda x: x[0])]
        preds.append(tmp)
    
    print(f"> Saving dev-0 to 'out-{file_name}.tsv'")
    np.savetxt(dev_file_path, np.array(preds).flatten(), delimiter='\t', fmt='%s')

    preds = []
    # test-A test
    for (batch, (inp, targ, inp_len)) in enumerate(test_A_dataset):
        xs, ys, lens, indx = sort_batch(inp, targ, inp_len)
        tmp = [p for _, p in sorted([(indx[i].item(), pred) for i, pred in enumerate(predict(xs, lens))], key=lambda x: x[0])]
        preds.append(tmp)
    print(f"> Saving test A to 'out-{file_name}.tsv'")
    np.savetxt(a_file_path, np.array(preds).flatten(), delimiter='\t', fmt='%s')

    if((epoch + 1) % 2 == 0):
        print(f"> Saving model to '{model_file_path}'")
        # save-model
        torch.save({'enc_state_dict': encoder.state_dict(), 'dec_state_dict': decoder.state_dict()}, model_file_path)
    
batches:7082
Epoch 11 Batch 0 Loss 6.2139 Time 1.2431468963623047
Epoch 11 Batch 1000 Loss 2.3112 Time 996.8302667140961
Epoch 11 Batch 2000 Loss 1.9345 Time 2001.6348514556885
Epoch 11 Batch 3000 Loss 1.6354 Time 3006.442977666855

Load model

file_name = "model-ep-10_embedding-dim-256_hidden-units-1024.pt"
print(f"> Loading model from '{file_name}'")
model = torch.load(f"{MODELS_PATH}{file_name}")
> Loading model from 'model-ep-10_embedding-dim-256_hidden-units-1024.pt'
print(model.keys())
dict_keys(['enc_state_dict', 'dec_state_dict'])
print(f"> Init model")
encoder = Encoder(vocab_src_size, embedding_dim, hidden_units, BATCH_SIZE)
decoder = Decoder(vocab_trg_size, embedding_dim, hidden_units, hidden_units, BATCH_SIZE)

encoder.load_state_dict(model['enc_state_dict'])
decoder.load_state_dict(model['dec_state_dict'])

encoder.to(device)
decoder.to(device)
file_name = f"ep-10_embedding-dim-{embedding_dim}_hidden-units-{hidden_units}"
dev_file_path = f"{TEST_DEV_PATH}dev-eval-out-{file_name}.tsv"
a_file_path = f"{TEST_A_PATH}A-eval-out-{file_name}.tsv"

# dev-0 test
preds = []
for (batch, (inp, targ, inp_len)) in enumerate(test_dev_0_dataset):
    xs, ys, lens, indx = sort_batch(inp, targ, inp_len)
    tmp = [p for _, p in sorted([(indx[i].item(), pred) for i, pred in enumerate(predict(xs, lens))], key=lambda x: x[0])]
    preds.append(tmp)
    
print(f"> Saving dev-0 to 'out-{file_name}.tsv'")
np.savetxt(dev_file_path, np.array(preds).flatten(), delimiter='\t', fmt='%s')

preds = []
# test-A test
for (batch, (inp, targ, inp_len)) in enumerate(test_A_dataset):
    xs, ys, lens, indx = sort_batch(inp, targ, inp_len)
    tmp = [p for _, p in sorted([(indx[i].item(), pred) for i, pred in enumerate(predict(xs, lens))], key=lambda x: x[0])]
    preds.append(tmp)
print(f"> Saving test A to 'out-{file_name}.tsv'")
np.savetxt(a_file_path, np.array(preds).flatten(), delimiter='\t', fmt='%s')
> Saving dev-0 to 'out-ep-10_embedding-dim-256_hidden-units-1024.tsv'
> Saving test A to 'out-ep-10_embedding-dim-256_hidden-units-1024.tsv'
# dev-0 test
preds = []
for (batch, (inp, targ, inp_len)) in enumerate(test_dev_0_dataset):
    xs, ys, lens, indx = sort_batch(inp, targ, inp_len)
    preds = predict(xs, lens)
    preds = [p for _, p in sorted([(indx[i].item(), pred) for i, pred in enumerate(preds)], key=lambda x: x[0])]
    preds.append()
['kiedy zostanie ustanowiony 4 tysiące ton rocznie to jedno z całą pewnością w wysokości dodatkowych kosztów . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'tendencja do tego , aby zaradzić w sprawie niektórych unijnych programów na unię europejską nie są szkodliwe . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'to nie dla nas dobrym sposobem na podstawie polityki rybołówstwa , czy w naszej własnej , czy jesteśmy w naszej wodach lub wody <EOS> <BLANK>', 'chciałbym także , aby zapewnić , aby zapewnić , aby pieniądze ue pogrążyła się państwa trzecie ue w krajach trzecich , że pieniądze ue pogrążyła', '( de ) panie przewodniczący , pani komisarz , panie i panowie ! cieszę się , że parlament wreszcie zagłosują w tej sprawie trzeciej kwestii', 'poprawka do rozporządzenia rady w sprawie środków finansowych w społeczności we wspólnocie , której musimy wdrożyć . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'dotyczy to w szczególności sektora rybołówstwa stosunków , czyli o badania i badania . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'systemy kontroli nad wspólną polityką rybołówstwa oraz ich wdrażanie . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'sprawozdawca przedstawił wysiłek w celu ochrony jego pochodzeniu wspomniał o konieczności znacznego ograniczenia emisji w wyniku regulujących działalność 75% do 75% okresu odpoczynku . <EOS>', 'nie udało nam się nam do jego zamiaru . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'istniejące przepisy okazały się w praktyce i praktyki , aby przewidziane w niektórych dziedzinach . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'państwa członkowskie już w możliwość wykorzystania możliwości zawieszenia i możliwościach nie ma żadnych potrzeb . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'ważne jest , aby zmiana treści rozporządzenia będzie zapewnianie sposobem na rzecz realistycznych ram prawnych . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'panie przewodniczący ! sprawozdanie pana posła zbyt wiele wzywamy ostrzeżenie do komisji europejskiej . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'zachód szkocji , że trudno jest , dlaczego komisja potrafi powiedzieć , że komisja może powiedzieć , że chce powiedzieć , że chce wprowadzić ograniczenie', 'komisja wolałaby przedłużenia obecnej środków technicznych , które powodują one , w tym z dnia , w tym zwłaszcza dla wielu innych , w tym', 'komisja nie komisja 18 miesięcy , tzw . tymczasowego środków , które nie udało się nie zasobów ryb . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'kolejne 18 miesięcy ryb , ryb w morzu . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'wzywam kolegów o poparcie poprawek do wszystkich poprawek i mam nadzieję , że te poprawki zostaną przyjęte , gdyby poprawka poprawki , a przyjęciem tych', 'panie przewodniczący ! chciałbym zgłosić poprawkę do środków technicznych , które próbują temu sprostać temu , by mówili o najlepszym dowodem na odrażające , by', 'w czasach wzmożonego przesiedleń zasobów rybnych , komisja wprowadziła wyjątkowe układy przejściowe dotyczące przejściowych okresu ważności różnych polityk miesiącach 12 miesięcy z 12 nowym okresem', 'teraz komisja usiłuje przestrzegać zasad w sprawie wywozu , a następnie nowe porozumienie w życie przy nowym kształtem . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'dzięki temu doprowadziło to oznaczać , że przejściowe regulacje na okres przejściowy wynoszący 12 do rozpoczęcia jednego roku <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'mam nadzieję , że parlament poprze jutro . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', '( pt ) panie przewodniczący , pani komisarz ! wszyscy chcę pogratulować czterech sprawozdawców , chciałbym skupić się tylko na dwóch nowych konferencji mojej agendy', 'w 2008 roku brak jakichkolwiek przepisów w sprawie projektu rozporządzenia dotyczącego zagwarantowania uproszczenie i wyjaśnienia ue regulacje dotyczące przepisów ue na temat wspólnotowego w zakresie', 'wniosek ustawodawczy obejmuje wniosek spowoduje rozpoczęcie jednego z kolejnego okresu - w innych kilku dziewięćdziesiąt nr 7 - w innych kilku dziewięćdziesiąt nr 7 -', 'utrzymanie sąsiedztwa ramy regulacyjne w okresie trwania , zgodnie z uwzględnieniem rybaków takich jak bez utraty rybaków . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'obecna tajemniczość nie jest rozszerzenie stosowania jednego z prawem dokładnie i zakazu stosowania ich życia w przypadku kryzysów a czasami metrów . <EOS> <BLANK> <BLANK>', 'obecne zakaz tego zakazu stosowania pestycydów , która spotkała się od dziesięcioleci o 30% miasta w rejonie zanieczyszczenia dla trwałego restrukturyzacji długu do zanieczyszczenia w', 'dlatego apeluję o poparcie przyjęcia w propozycję w propozycji , dlatego właśnie to propozycje pana posła pana posła pana posła pana posła pana posła pana', 'chciałbym również wspomnieć o pakiecie projektu rozporządzenia dotyczącego środków finansowych wspólnoty dotyczące wdrażania wspólnej polityki i ustawy o prawie przegląd ustawy o prawie przegląd ustawy', 'wraz z europejską rybołówstwa europejski fundusz zapewnienia wspierania finansów publicznych , zapewniając wsparcie dla finansowania projektów obszarach pod względem zasobów , zapewniając wsparcie dla finansowania', 'w tym kontekście chciałbym wyrazić moje pełne poparcie dla propozycji przedstawionych w tej izbie , sprawozdawca , sprawozdawca , sprawozdawca , sprawozdawca , sprawozdawca ,', 'wagi i rosnące znaczenie chronienia znaczenia zarządzania legalną wymianę substancji i szczegółowe badania w pełnej autonomii zasobów . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', '( es ) panie przewodniczący , pani komisarz ! chciałbym pogratulować czterem sprawozdawcom sprawozdań w ich wyjątkowo wykonanej . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'skoncentruję się teraz na dwóch sprawozdań , uwzględniając ich znaczenie . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'jedną z nich dotyczy porozumienia z unią . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'jest to umowa acta unii europejskiej a państwami akp - o czym się , że tzw . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'przedmiotowa umowa ustanawia możliwość uznania ich ważności ryb . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'powtarzam : ryby . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'w sprawozdaniu przewidziano również dla samej korzyści , aby sam sposób , by poprawić jego ograniczenia jego zdolności i jej potencjał . <EOS> <BLANK> <BLANK>', 'ustanawia on ramy partnerstwa kryteriów dotyczących rybołówstwa i odpowiedzialnej , za ochronę zasobów naturalnych . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'musimy uwzględnić to , że istnieje szereg zawodów , ponieważ codziennie , co roku , że powstał co roku przeprowadzana zgodnie z prawem międzynarodowym rokiem', 'ułatwia on badania naukowe , a także obserwatorzy ponad obserwatorów oraz za zachowania bioróżnorodności , jak i zachowania bioróżnorodności , jak i zachowania bioróżnorodności ,', 'protokół ta czerpie korzyści dzięki istnieniu dostępu do połowów , ponieważ europejska regulacja , stały obszar , rozwoju , rozwoju , rozwoju , rozwoju ,', 'jest jednak ma ono również bardzo ważna element : każda trzecią państw trzecich od państwa , jeśli pieniądze od zapewnienia ochrony konsumentów . <EOS> <BLANK>', 'w państwach trzecich zatrudnieni stanowią wpływy zasobów rybołówstwa . <EOS> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK> <BLANK>', 'dlatego też uważamy , że nie tylko nie tylko przyczynia się z punktu widzenia funduszu , ale również pomóc w sposób jej przetrwanie . <EOS>', 'należy zwrócić szczególną uwagę na krótkie ramy w sprawie rozporządzenia dotyczącego konkretnych środków technicznych , które w czasie po wypadku czas , które w czasie']

Process output files