לשמור את התאריך! קלט / פלט של Google חוזר 18-20 במאי הירשם עכשיו
דף זה תורגם על ידי Cloud Translation API.
Switch to English

תרגום מכונה עצבי עם תשומת לב

צפה ב- TensorFlow.org הפעל בגוגל קולאב צפה במקור ב- GitHub הורד מחברת

מחברת זו מכשירה מודל רצף לרצף (seq2seq) לתרגום מספרדית לאנגלית. זו דוגמה מתקדמת המניחה ידע מסוים על רצף למודלים של רצף.

לאחר אימון המודל במחברת זו, תוכלו להזין משפט ספרדי, כגון "¿todavia estan en casa?" והחזירו את התרגום לאנגלית: "האם אתה עדיין בבית?"

איכות התרגום סבירה לדוגמא צעצוע, אך עלילת הקשב שנוצרת אולי מעניינת יותר. זה מראה לאילו חלקים ממשפט הקלט יש את תשומת הלב של המודל בזמן התרגום:

עלילת קשב ספרדית-אנגלית

import tensorflow as tf

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from sklearn.model_selection import train_test_split

import unicodedata
import re
import numpy as np
import os
import io
import time

הורד והכין את מערך הנתונים

נשתמש במערך נתונים של שפות המסופק על ידי http://www.manythings.org/anki/ מערך נתונים זה מכיל זוגות תרגום לשפות בפורמט:

May I borrow this book? ¿Puedo tomar prestado este libro?

ישנם מגוון שפות זמינות, אך נשתמש במערך הנתונים האנגלי-ספרדי. מטעמי נוחות, אירחנו עותק של מערך נתונים זה ב- Google Cloud, אך תוכל גם להוריד עותק משלך. לאחר הורדת מערך הנתונים, להלן הצעדים שננקוט להכנת הנתונים:

  1. הוסף אסימון התחלה וסיום לכל משפט.
  2. נקה את המשפטים על ידי הסרת תווים מיוחדים.
  3. צור אינדקס מילים ואינדקס מילים הפוך (מילונים מיפוי ממילה → מזהה ומזהה → מילה).
  4. מרפדים כל משפט לאורך מקסימלי.
# Download the file
path_to_zip = tf.keras.utils.get_file(
    'spa-eng.zip', origin='http://storage.googleapis.com/download.tensorflow.org/data/spa-eng.zip',
    extract=True)

path_to_file = os.path.dirname(path_to_zip)+"/spa-eng/spa.txt"
Downloading data from http://storage.googleapis.com/download.tensorflow.org/data/spa-eng.zip
2646016/2638744 [==============================] - 0s 0us/step
# Converts the unicode file to ascii
def unicode_to_ascii(s):
  return ''.join(c for c in unicodedata.normalize('NFD', s)
                 if unicodedata.category(c) != 'Mn')


def preprocess_sentence(w):
  w = unicode_to_ascii(w.lower().strip())

  # creating a space between a word and the punctuation following it
  # eg: "he is a boy." => "he is a boy ."
  # Reference:- https://stackoverflow.com/questions/3645931/python-padding-punctuation-with-white-spaces-keeping-punctuation
  w = re.sub(r"([?.!,¿])", r" \1 ", w)
  w = re.sub(r'[" "]+', " ", w)

  # replacing everything with space except (a-z, A-Z, ".", "?", "!", ",")
  w = re.sub(r"[^a-zA-Z?.!,¿]+", " ", w)

  w = w.strip()

  # adding a start and an end token to the sentence
  # so that the model know when to start and stop predicting.
  w = '<start> ' + w + ' <end>'
  return w
en_sentence = u"May I borrow this book?"
sp_sentence = u"¿Puedo tomar prestado este libro?"
print(preprocess_sentence(en_sentence))
print(preprocess_sentence(sp_sentence).encode('utf-8'))
<start> may i borrow this book ? <end>
b'<start> \xc2\xbf puedo tomar prestado este libro ? <end>'
# 1. Remove the accents
# 2. Clean the sentences
# 3. Return word pairs in the format: [ENGLISH, SPANISH]
def create_dataset(path, num_examples):
  lines = io.open(path, encoding='UTF-8').read().strip().split('\n')

  word_pairs = [[preprocess_sentence(w) for w in line.split('\t')]
                for line in lines[:num_examples]]

  return zip(*word_pairs)
en, sp = create_dataset(path_to_file, None)
print(en[-1])
print(sp[-1])
<start> if you want to sound like a native speaker , you must be willing to practice saying the same sentence over and over in the same way that banjo players practice the same phrase over and over until they can play it correctly and at the desired tempo . <end>
<start> si quieres sonar como un hablante nativo , debes estar dispuesto a practicar diciendo la misma frase una y otra vez de la misma manera en que un musico de banjo practica el mismo fraseo una y otra vez hasta que lo puedan tocar correctamente y en el tiempo esperado . <end>
def tokenize(lang):
  lang_tokenizer = tf.keras.preprocessing.text.Tokenizer(filters='')
  lang_tokenizer.fit_on_texts(lang)

  tensor = lang_tokenizer.texts_to_sequences(lang)

  tensor = tf.keras.preprocessing.sequence.pad_sequences(tensor,
                                                         padding='post')

  return tensor, lang_tokenizer
def load_dataset(path, num_examples=None):
  # creating cleaned input, output pairs
  targ_lang, inp_lang = create_dataset(path, num_examples)

  input_tensor, inp_lang_tokenizer = tokenize(inp_lang)
  target_tensor, targ_lang_tokenizer = tokenize(targ_lang)

  return input_tensor, target_tensor, inp_lang_tokenizer, targ_lang_tokenizer

הגבל את גודל מערך הנתונים לניסוי מהיר יותר (אופציונלי)

אימונים על מערך הנתונים המלא של> 100,000 משפטים ייקח זמן רב. כדי להתאמן מהר יותר, אנו יכולים להגביל את גודל מערך הנתונים ל -30,000 משפטים (כמובן שאיכות התרגום מתמעטת עם פחות נתונים):

# Try experimenting with the size of that dataset
num_examples = 30000
input_tensor, target_tensor, inp_lang, targ_lang = load_dataset(path_to_file,
                                                                num_examples)

# Calculate max_length of the target tensors
max_length_targ, max_length_inp = target_tensor.shape[1], input_tensor.shape[1]
# Creating training and validation sets using an 80-20 split
input_tensor_train, input_tensor_val, target_tensor_train, target_tensor_val = train_test_split(input_tensor, target_tensor, test_size=0.2)

# Show length
print(len(input_tensor_train), len(target_tensor_train), len(input_tensor_val), len(target_tensor_val))
24000 24000 6000 6000
def convert(lang, tensor):
  for t in tensor:
    if t != 0:
      print(f'{t} ----> {lang.index_word[t]}')
print("Input Language; index to word mapping")
convert(inp_lang, input_tensor_train[0])
print()
print("Target Language; index to word mapping")
convert(targ_lang, target_tensor_train[0])
Input Language; index to word mapping
1 ----> <start>
53 ----> quiero
154 ----> otra
301 ----> cerveza
3 ----> .
2 ----> <end>

Target Language; index to word mapping
1 ----> <start>
4 ----> i
47 ----> want
371 ----> another
347 ----> beer
3 ----> .
2 ----> <end>

צור מערך נתונים tf.data

BUFFER_SIZE = len(input_tensor_train)
BATCH_SIZE = 64
steps_per_epoch = len(input_tensor_train)//BATCH_SIZE
embedding_dim = 256
units = 1024
vocab_inp_size = len(inp_lang.word_index)+1
vocab_tar_size = len(targ_lang.word_index)+1

dataset = tf.data.Dataset.from_tensor_slices((input_tensor_train, target_tensor_train)).shuffle(BUFFER_SIZE)
dataset = dataset.batch(BATCH_SIZE, drop_remainder=True)
example_input_batch, example_target_batch = next(iter(dataset))
example_input_batch.shape, example_target_batch.shape
(TensorShape([64, 16]), TensorShape([64, 11]))

כתוב את מודל המקודד והמפענח

יישם מודל מקודד-מפענח עם תשומת לב עליו תוכלו לקרוא במדריך TensorFlow Neural Machine Translation (seq2seq) . בדוגמה זו משתמשים במערך API חדש יותר. מחברת זו מיישמת את משוואות הקשב מהמדריך seq2seq. התרשים הבא מראה כי לכל מילות קלט מוקצה משקל על ידי מנגנון הקשב המשמש את המפענח ואז לחיזוי המילה הבאה במשפט. התמונה והנוסחאות שלהלן הם דוגמה למנגנון קשב ממאמרו של לואונג .

מנגנון קשב

הקלט מועבר באמצעות מודל מקודד אשר נותן לנו את פלט המקודד של צורה (batch_size, max_length, hidden_size) ואת מצב הצפנה הנסתר של batch (batch_size, hidden_size) .

להלן המשוואות המיושמות:

משוואת תשומת לב 0משוואת תשומת לב 1

הדרכה זו משתמשת בתשומת לב בהדנאו עבור המקודד. בואו נחליט על סימון לפני שנכתוב את הטופס הפשוט:

  • FC = שכבה מחוברת לחלוטין (צפופה)
  • EO = פלט מקודד
  • H = מצב נסתר
  • X = קלט למפענח

והקוד הפסאודו:

  • score = FC(tanh(FC(EO) + FC(H)))
  • attention weights = softmax(score, axis = 1) . Softmax כברירת מחדל מוחל על הציר האחרון אך כאן אנו רוצים ליישם אותו על הציר הראשון , מכיוון שצורת הניקוד היא (batch_size, max_length, hidden_size) . Max_length הוא אורך הקלט שלנו. מכיוון שאנו מנסים להקצות משקל לכל קלט, יש להחיל את softmax על ציר זה.
  • context vector = sum(attention weights * EO, axis = 1) . אותה סיבה כמו לעיל לבחירת ציר כ- 1.
  • embedding output = הקלט למפענח X מועבר דרך שכבת הטבעה.
  • merged vector = concat(embedding output, context vector)
  • הווקטור הממוזג הזה ניתן לאחר מכן ל- GRU

הצורות של כל הווקטורים בכל שלב צוינו בתגובות בקוד:

class Encoder(tf.keras.Model):
  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.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
    self.gru = tf.keras.layers.GRU(self.enc_units,
                                   return_sequences=True,
                                   return_state=True,
                                   recurrent_initializer='glorot_uniform')

  def call(self, x, hidden):
    x = self.embedding(x)
    output, state = self.gru(x, initial_state=hidden)
    return output, state

  def initialize_hidden_state(self):
    return tf.zeros((self.batch_sz, self.enc_units))
encoder = Encoder(vocab_inp_size, embedding_dim, units, BATCH_SIZE)

# sample input
sample_hidden = encoder.initialize_hidden_state()
sample_output, sample_hidden = encoder(example_input_batch, sample_hidden)
print('Encoder output shape: (batch size, sequence length, units)', sample_output.shape)
print('Encoder Hidden state shape: (batch size, units)', sample_hidden.shape)
Encoder output shape: (batch size, sequence length, units) (64, 16, 1024)
Encoder Hidden state shape: (batch size, units) (64, 1024)
class BahdanauAttention(tf.keras.layers.Layer):
  def __init__(self, units):
    super(BahdanauAttention, self).__init__()
    self.W1 = tf.keras.layers.Dense(units)
    self.W2 = tf.keras.layers.Dense(units)
    self.V = tf.keras.layers.Dense(1)

  def call(self, query, values):
    # query hidden state shape == (batch_size, hidden size)
    # query_with_time_axis shape == (batch_size, 1, hidden size)
    # values shape == (batch_size, max_len, hidden size)
    # we are doing this to broadcast addition along the time axis to calculate the score
    query_with_time_axis = tf.expand_dims(query, 1)

    # score shape == (batch_size, max_length, 1)
    # we get 1 at the last axis because we are applying score to self.V
    # the shape of the tensor before applying self.V is (batch_size, max_length, units)
    score = self.V(tf.nn.tanh(
        self.W1(query_with_time_axis) + self.W2(values)))

    # attention_weights shape == (batch_size, max_length, 1)
    attention_weights = tf.nn.softmax(score, axis=1)

    # context_vector shape after sum == (batch_size, hidden_size)
    context_vector = attention_weights * values
    context_vector = tf.reduce_sum(context_vector, axis=1)

    return context_vector, attention_weights
attention_layer = BahdanauAttention(10)
attention_result, attention_weights = attention_layer(sample_hidden, sample_output)

print("Attention result shape: (batch size, units)", attention_result.shape)
print("Attention weights shape: (batch_size, sequence_length, 1)", attention_weights.shape)
Attention result shape: (batch size, units) (64, 1024)
Attention weights shape: (batch_size, sequence_length, 1) (64, 16, 1)
class Decoder(tf.keras.Model):
  def __init__(self, vocab_size, embedding_dim, dec_units, batch_sz):
    super(Decoder, self).__init__()
    self.batch_sz = batch_sz
    self.dec_units = dec_units
    self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
    self.gru = tf.keras.layers.GRU(self.dec_units,
                                   return_sequences=True,
                                   return_state=True,
                                   recurrent_initializer='glorot_uniform')
    self.fc = tf.keras.layers.Dense(vocab_size)

    # used for attention
    self.attention = BahdanauAttention(self.dec_units)

  def call(self, x, hidden, enc_output):
    # enc_output shape == (batch_size, max_length, hidden_size)
    context_vector, attention_weights = self.attention(hidden, enc_output)

    # x shape after passing through embedding == (batch_size, 1, embedding_dim)
    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)

    # passing the concatenated vector to the GRU
    output, state = self.gru(x)

    # output shape == (batch_size * 1, hidden_size)
    output = tf.reshape(output, (-1, output.shape[2]))

    # output shape == (batch_size, vocab)
    x = self.fc(output)

    return x, state, attention_weights
decoder = Decoder(vocab_tar_size, embedding_dim, units, BATCH_SIZE)

sample_decoder_output, _, _ = decoder(tf.random.uniform((BATCH_SIZE, 1)),
                                      sample_hidden, sample_output)

print('Decoder output shape: (batch_size, vocab size)', sample_decoder_output.shape)
Decoder output shape: (batch_size, vocab size) (64, 4935)

הגדר את האופטימיזציה ואת פונקציית האובדן

optimizer = tf.keras.optimizers.Adam()
loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True,
                                                            reduction='none')


def loss_function(real, pred):
  mask = tf.math.logical_not(tf.math.equal(real, 0))
  loss_ = loss_object(real, pred)

  mask = tf.cast(mask, dtype=loss_.dtype)
  loss_ *= mask

  return tf.reduce_mean(loss_)

מחסומים (חיסכון מבוסס עצמים)

checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
checkpoint = tf.train.Checkpoint(optimizer=optimizer,
                                 encoder=encoder,
                                 decoder=decoder)

הַדְרָכָה

  1. העבירו את הקלט דרך המקודד המחזיר את פלט המקודד ומצב הנסתר של המקודד .
  2. פלט המקודד, מצב מוסתר המקודד וקלט המפענח (שהוא אסימון ההתחלה ) מועברים למפענח.
  3. המפענח מחזיר את התחזיות ואת מצב הנסתר של המפענח .
  4. המצב המוסתר של המפענח מועבר חזרה למודל והתחזיות משמשות לחישוב ההפסד.
  5. השתמש בכוח המורה כדי להחליט על הקלט הבא למפענח.
  6. אילוץ מורים הוא הטכניקה בה מועברת מילת היעד כקלט הבא למפענח.
  7. השלב האחרון הוא לחשב את הדרגתיות ולהחיל אותם על אופטימיזציה ו backpropagate.
@tf.function
def train_step(inp, targ, enc_hidden):
  loss = 0

  with tf.GradientTape() as tape:
    enc_output, enc_hidden = encoder(inp, enc_hidden)

    dec_hidden = enc_hidden

    dec_input = tf.expand_dims([targ_lang.word_index['<start>']] * BATCH_SIZE, 1)

    # Teacher forcing - feeding the target as the next input
    for t in range(1, targ.shape[1]):
      # passing enc_output to the decoder
      predictions, dec_hidden, _ = decoder(dec_input, dec_hidden, enc_output)

      loss += loss_function(targ[:, t], predictions)

      # using teacher forcing
      dec_input = tf.expand_dims(targ[:, t], 1)

  batch_loss = (loss / int(targ.shape[1]))

  variables = encoder.trainable_variables + decoder.trainable_variables

  gradients = tape.gradient(loss, variables)

  optimizer.apply_gradients(zip(gradients, variables))

  return batch_loss
EPOCHS = 10

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

  enc_hidden = encoder.initialize_hidden_state()
  total_loss = 0

  for (batch, (inp, targ)) in enumerate(dataset.take(steps_per_epoch)):
    batch_loss = train_step(inp, targ, enc_hidden)
    total_loss += batch_loss

    if batch % 100 == 0:
      print(f'Epoch {epoch+1} Batch {batch} Loss {batch_loss.numpy():.4f}')
  # saving (checkpoint) the model every 2 epochs
  if (epoch + 1) % 2 == 0:
    checkpoint.save(file_prefix=checkpoint_prefix)

  print(f'Epoch {epoch+1} Loss {total_loss/steps_per_epoch:.4f}')
  print(f'Time taken for 1 epoch {time.time()-start:.2f} sec\n')
Epoch 1 Batch 0 Loss 4.6989
Epoch 1 Batch 100 Loss 2.1331
Epoch 1 Batch 200 Loss 1.8321
Epoch 1 Batch 300 Loss 1.7294
Epoch 1 Loss 2.0406
Time taken for 1 epoch 27.93 sec

Epoch 2 Batch 0 Loss 1.7868
Epoch 2 Batch 100 Loss 1.4302
Epoch 2 Batch 200 Loss 1.3607
Epoch 2 Batch 300 Loss 1.2717
Epoch 2 Loss 1.3987
Time taken for 1 epoch 15.70 sec

Epoch 3 Batch 0 Loss 1.1721
Epoch 3 Batch 100 Loss 0.9490
Epoch 3 Batch 200 Loss 0.9264
Epoch 3 Batch 300 Loss 0.8968
Epoch 3 Loss 0.9796
Time taken for 1 epoch 15.60 sec

Epoch 4 Batch 0 Loss 0.5519
Epoch 4 Batch 100 Loss 0.7205
Epoch 4 Batch 200 Loss 0.6876
Epoch 4 Batch 300 Loss 0.6771
Epoch 4 Loss 0.6630
Time taken for 1 epoch 16.00 sec

Epoch 5 Batch 0 Loss 0.3934
Epoch 5 Batch 100 Loss 0.4728
Epoch 5 Batch 200 Loss 0.5153
Epoch 5 Batch 300 Loss 0.3849
Epoch 5 Loss 0.4491
Time taken for 1 epoch 15.31 sec

Epoch 6 Batch 0 Loss 0.2552
Epoch 6 Batch 100 Loss 0.3069
Epoch 6 Batch 200 Loss 0.2838
Epoch 6 Batch 300 Loss 0.3230
Epoch 6 Loss 0.3119
Time taken for 1 epoch 15.64 sec

Epoch 7 Batch 0 Loss 0.2261
Epoch 7 Batch 100 Loss 0.2525
Epoch 7 Batch 200 Loss 0.2109
Epoch 7 Batch 300 Loss 0.2153
Epoch 7 Loss 0.2218
Time taken for 1 epoch 15.24 sec

Epoch 8 Batch 0 Loss 0.1259
Epoch 8 Batch 100 Loss 0.1299
Epoch 8 Batch 200 Loss 0.1506
Epoch 8 Batch 300 Loss 0.1699
Epoch 8 Loss 0.1652
Time taken for 1 epoch 15.83 sec

Epoch 9 Batch 0 Loss 0.1097
Epoch 9 Batch 100 Loss 0.1361
Epoch 9 Batch 200 Loss 0.1034
Epoch 9 Batch 300 Loss 0.1255
Epoch 9 Loss 0.1280
Time taken for 1 epoch 15.76 sec

Epoch 10 Batch 0 Loss 0.0599
Epoch 10 Batch 100 Loss 0.0686
Epoch 10 Batch 200 Loss 0.1235
Epoch 10 Batch 300 Loss 0.1186
Epoch 10 Loss 0.1056
Time taken for 1 epoch 16.07 sec

לתרגם

  • פונקציית הערכה דומה ללולאת ההדרכה, אלא שאיננו משתמשים בכפיית מורים כאן. הקלט למפענח בכל שלב בזמן הוא התחזיות הקודמות שלו יחד עם המצב הנסתר ופלט המקודד.
  • הפסק לנבא כאשר המודל מנבא את אסימון הסוף .
  • ואחסן את משקולות הקשב לכל שלב בפעם .
def evaluate(sentence):
  attention_plot = np.zeros((max_length_targ, max_length_inp))

  sentence = preprocess_sentence(sentence)

  inputs = [inp_lang.word_index[i] for i in sentence.split(' ')]
  inputs = tf.keras.preprocessing.sequence.pad_sequences([inputs],
                                                         maxlen=max_length_inp,
                                                         padding='post')
  inputs = tf.convert_to_tensor(inputs)

  result = ''

  hidden = [tf.zeros((1, units))]
  enc_out, enc_hidden = encoder(inputs, hidden)

  dec_hidden = enc_hidden
  dec_input = tf.expand_dims([targ_lang.word_index['<start>']], 0)

  for t in range(max_length_targ):
    predictions, dec_hidden, attention_weights = decoder(dec_input,
                                                         dec_hidden,
                                                         enc_out)

    # storing the attention weights to plot later on
    attention_weights = tf.reshape(attention_weights, (-1, ))
    attention_plot[t] = attention_weights.numpy()

    predicted_id = tf.argmax(predictions[0]).numpy()

    result += targ_lang.index_word[predicted_id] + ' '

    if targ_lang.index_word[predicted_id] == '<end>':
      return result, sentence, attention_plot

    # the predicted ID is fed back into the model
    dec_input = tf.expand_dims([predicted_id], 0)

  return result, sentence, attention_plot
# function for plotting the attention weights
def plot_attention(attention, sentence, predicted_sentence):
  fig = plt.figure(figsize=(10, 10))
  ax = fig.add_subplot(1, 1, 1)
  ax.matshow(attention, cmap='viridis')

  fontdict = {'fontsize': 14}

  ax.set_xticklabels([''] + sentence, fontdict=fontdict, rotation=90)
  ax.set_yticklabels([''] + predicted_sentence, fontdict=fontdict)

  ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
  ax.yaxis.set_major_locator(ticker.MultipleLocator(1))

  plt.show()
def translate(sentence):
  result, sentence, attention_plot = evaluate(sentence)

  print('Input:', sentence)
  print('Predicted translation:', result)

  attention_plot = attention_plot[:len(result.split(' ')),
                                  :len(sentence.split(' '))]
  plot_attention(attention_plot, sentence.split(' '), result.split(' '))

שחזר את המחסום האחרון ובדוק

# restoring the latest checkpoint in checkpoint_dir
checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))
<tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7f41986ac780>
translate(u'hace mucho frio aqui.')
Input: <start> hace mucho frio aqui . <end>
Predicted translation: it s very cold here . <end>
/home/kbuilder/.local/lib/python3.6/site-packages/ipykernel_launcher.py:9: UserWarning: FixedFormatter should only be used together with FixedLocator
  if __name__ == '__main__':
/home/kbuilder/.local/lib/python3.6/site-packages/ipykernel_launcher.py:10: UserWarning: FixedFormatter should only be used together with FixedLocator
  # Remove the CWD from sys.path while we load stuff.

png

translate(u'esta es mi vida.')
Input: <start> esta es mi vida . <end>
Predicted translation: this is my life . <end>
/home/kbuilder/.local/lib/python3.6/site-packages/ipykernel_launcher.py:9: UserWarning: FixedFormatter should only be used together with FixedLocator
  if __name__ == '__main__':
/home/kbuilder/.local/lib/python3.6/site-packages/ipykernel_launcher.py:10: UserWarning: FixedFormatter should only be used together with FixedLocator
  # Remove the CWD from sys.path while we load stuff.

png

translate(u'¿todavia estan en casa?')
Input: <start> ¿ todavia estan en casa ? <end>
Predicted translation: are you still at home ? <end>
/home/kbuilder/.local/lib/python3.6/site-packages/ipykernel_launcher.py:9: UserWarning: FixedFormatter should only be used together with FixedLocator
  if __name__ == '__main__':
/home/kbuilder/.local/lib/python3.6/site-packages/ipykernel_launcher.py:10: UserWarning: FixedFormatter should only be used together with FixedLocator
  # Remove the CWD from sys.path while we load stuff.

png

# wrong translation
translate(u'trata de averiguarlo.')
Input: <start> trata de averiguarlo . <end>
Predicted translation: try to figure it out . <end>
/home/kbuilder/.local/lib/python3.6/site-packages/ipykernel_launcher.py:9: UserWarning: FixedFormatter should only be used together with FixedLocator
  if __name__ == '__main__':
/home/kbuilder/.local/lib/python3.6/site-packages/ipykernel_launcher.py:10: UserWarning: FixedFormatter should only be used together with FixedLocator
  # Remove the CWD from sys.path while we load stuff.

png

הצעדים הבאים

  • הורד מערך נתונים אחר כדי להתנסות בתרגומים, למשל אנגלית לגרמנית או אנגלית לצרפתית.
  • התנסות באימונים על מערך נתונים גדול יותר, או באמצעות יותר תקופות.