الترجمة الآلية باستخدام الشبكات العصبية مع آلية الانتباه

إفتح المحتوى على موقع TensorFlow.org تفاعل مع المحتوى على Google Colab اعرض المصدر على Github نزّل الدّفتر

نقوم في هذا الدفتر بتعلّم كيفية تدريب نموذج تسلسل إلى تسلسل (seq2seq) للترجمة من الإسبانية إلى الإنجليزية. هذا مثال متقدم يفترض بعض المعرفة بنماذج التسلسل إلى تسلسل. بعد تدريب النموذج في هذا الدفتر، ستتمكن من إدخال جملة إسبانية ، مثل:

"¿todavia estan en casa؟"

واستخراج الترجمة الإنجليزية:

"are you still at home?"

جودة الترجمة مقبولة لمثال بسيط ، ولكن ربما يكون الرسم البياني للانتباه (attention) الناتج أكثر إثارة للاهتمام. فهو يوضح أجزاء الجملة المدخلة التي لفتت انتباه النموذج أثناء الترجمة:

spanish-english attention plot

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

تنزيل وتحضير مجموعة البيانات

سنستخدم مجموعة بيانات لغوية مقدمة من موقع manythings.org. تحتوي هذه المجموعة على أزواج لغوية في الشكل التالي:

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

هناك مجموعة متنوعة من اللغات المتاحة ، ولكننا سنستخدم مجموعة البيانات الإنجليزية الإسبانية. لتبسيط الأمر ، اضفنا نسخة من مجموعة البيانات هذه على Google Cloud ، ولكن يمكنك أيضًا تنزيل نسختك الخاصة. بعد تنزيل مجموعة البيانات ، إليك الخطوات التي سنتخذها لإعدادها:

  1. أضف رمز start و end لكل جملة.
  2. نظف الجمل بإزالة الأحرف الخاصة. 3.كوِّن فهرس الكلمات وفهرس الكلمات العكسي (قواميس تعطي لكل كلمة معرف وحيد والعكس بالعكس).
  3. كمل كل جملة إلى الطول الأقصى.
# 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 l.split('\t')]  for l 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 max_length(tensor):
  return max(len(t) for t in tensor)
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 = max_length(target_tensor), max_length(input_tensor)
# 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 ("%d ----&gt; %s" % (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>
8 ----> no
63 ----> nos
392 ----> queda
900 ----> ninguna
8663 ----> bala
3 ----> .
2 ----> <end>

Target Language; index to word mapping
1 ----> <start>
16 ----> we
23 ----> re
74 ----> out
59 ----> of
2392 ----> bullets
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]))

برمجة نموذج التشفير - فك التشفير (encoder - decoder)

لنقم ببرمجة نموذج التشفير - فك التشفير ببواسطة آلية الانتباه (attention). يمكنك أن تقرأ المزيد عن هذا النوع من النماذج في الدرس التعلمي لTensorFlow الترجمة الآلية باستخدام الشبكات العصبية (seq2seq). يستخدم هذا المثال مجموعةً أحدث من واجهات برمجة التطبيقات (APIs). و يستخدم هذا الدّفتر معادلات الانتباه من الدرس التعليمي seq2seq. يوضح الرسم البياني التالي أن كل كلمة مدخلة يتم تعيين وزن لها بواسطة آلية الانتباه التي يستخدمها نموذج فك التشفير (decoder) بعد ذلك للتنبؤ بالكلمة التالية في الجملة. الصورة و المعادلات أدناه هما مثال لآلية الانتباه من ورقة بحث لونغ Luong.

attention mechanism

يتم إدخال الجمل إلى نموذج التشفير الذي يعطينا ناتج التشفير بالأبعاد التّالية (batch_size، max_length، hidden_size) و الحالة الخفية (hidden state) لنموذج التشفير بالأبعاد التّالية (batch_size، hidden_size).

فيما يلي المعادلات التي يتم تطبيقها:

attention equation 0 attention equation 1

يستخدم هذا الدرس التعليمي آلية انتباه Bahdanau لنموذج التشفير. دعونا نحدد الرموز قبل كتابة النسخة المبسطة:

  • EO = نتاج نموذج التشفير (Encoder Ouput)
  • H = الحالة الخفية (hidden state)
  • X = المُدخل إلى نموذج فك التشفير

فيما يلي الشبه شفرة (pseudo-code)، أي الخطوات المبسّطة التي يقوم بها النموذج:

  • score = FC(tanh(FC(EO) + FC(H)))
  • attention weights = softmax(score, axis = 1)

    بدون تحديد صريح، يتم تطبيق Softmax على المحور (axis) الأخير ولكن هنا نريد تطبيقه على المحور الأول ، حيث أن شكل النتيجة هو (batch_size، max_length، hidden_size). "max_length" هو طول مدخلاتنا. نظرًا لأننا نحاول تعيين وزن لكل مدخل ، يجب تطبيق Softmax على هذا المحور.

  • context vector = sum(attention weights * EO, axis = 1). نفس السبب أعلاه لاختيار المحور 1.

  • embedding output = يتم تمرير المدخل X إلى نموذج فك التشفير من خلال طبقة التضمين (embedding).

  • merged vector = concat(embedding output, context vector)

  • ثم يتم إدخال هذا المتجه (vector) المدمج لـ GRU

تم تحديد أشكال جميع المتجهات (vectors) لكل خطوة في التعليقات في الكود:

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) {}'.format(sample_output.shape))
print ('Encoder Hidden state shape: (batch size, units) {}'.format(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) {}".format(attention_result.shape))
print("Attention weights shape: (batch_size, sequence_length, 1) {}".format(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) {}'.format(sample_decoder_output.shape))
Decoder output shape: (batch_size, vocab size) (64, 4935)

تحديد خوارزميّة تحسين (optimizer) ودالّة خسارة (loss function)

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_)

حفظ نقاط الفحص عبر الكائنات (objects)

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

التدريب

  1. مرر المُدخل عبر نموذج التشفير الذي يقوم بإخرج نتاج نموذج التشفير و الحالة المخفية.
  2. يتم تمرير نتاج نموذج التشفير ، والحالة المخفية ومُدخل نموذج فك التشفير (وهو الرمز المميز start) إلى نموذج فك التشفير.
  3. يقوم نموذج فك التشفير بإرجاع التنبؤات والحالة المخفية.
  4. يتم بعد ذلك تمرير الحالة المخفية لنموذج فك التشفير إلى النموذج واستخدام التنبؤات لحساب دالة الخسارة.
  5. استخدم إجبار المعلم (Teacher forcing) لتحديد المُدخل التالي إلى نموذج فك التشفير.
  6. إجبار المعلم هو التقنية الذي يتم خلالها تمرير الكلمة الهدف أي الصحيحة كالمدخل التالي إلى نموذج فك التشفير.
  7. الخطوة الأخيرة هي حساب الميول (gradients) وتطبيقها في خوارزميّة التحسين ثم تطبيق الانتشار العكسي (backpropagation).
@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('Epoch {} Batch {} Loss {:.4f}'.format(epoch + 1,
                                                   batch,
                                                   batch_loss.numpy()))
  # saving (checkpoint) the model every 2 epochs
  if (epoch + 1) % 2 == 0:
    checkpoint.save(file_prefix = checkpoint_prefix)

  print('Epoch {} Loss {:.4f}'.format(epoch + 1,
                                      total_loss / steps_per_epoch))
  print('Time taken for 1 epoch {} sec\n'.format(time.time() - start))
Epoch 1 Batch 0 Loss 4.5662
Epoch 1 Batch 100 Loss 2.0971
Epoch 1 Batch 200 Loss 1.8775
Epoch 1 Batch 300 Loss 1.7040
Epoch 1 Loss 2.0203
Time taken for 1 epoch 27.033990383148193 sec

Epoch 2 Batch 0 Loss 1.6372
Epoch 2 Batch 100 Loss 1.4505
Epoch 2 Batch 200 Loss 1.2186
Epoch 2 Batch 300 Loss 1.1339
Epoch 2 Loss 1.3785
Time taken for 1 epoch 15.517480611801147 sec

Epoch 3 Batch 0 Loss 0.9005
Epoch 3 Batch 100 Loss 1.0720
Epoch 3 Batch 200 Loss 0.9450
Epoch 3 Batch 300 Loss 0.9132
Epoch 3 Loss 0.9523
Time taken for 1 epoch 15.156470775604248 sec

Epoch 4 Batch 0 Loss 0.6605
Epoch 4 Batch 100 Loss 0.6594
Epoch 4 Batch 200 Loss 0.6250
Epoch 4 Batch 300 Loss 0.5412
Epoch 4 Loss 0.6272
Time taken for 1 epoch 15.53078031539917 sec

Epoch 5 Batch 0 Loss 0.3840
Epoch 5 Batch 100 Loss 0.4536
Epoch 5 Batch 200 Loss 0.3475
Epoch 5 Batch 300 Loss 0.4074
Epoch 5 Loss 0.4167
Time taken for 1 epoch 15.151145219802856 sec

Epoch 6 Batch 0 Loss 0.2204
Epoch 6 Batch 100 Loss 0.2503
Epoch 6 Batch 200 Loss 0.2763
Epoch 6 Batch 300 Loss 0.3049
Epoch 6 Loss 0.2856
Time taken for 1 epoch 15.555814266204834 sec

Epoch 7 Batch 0 Loss 0.2123
Epoch 7 Batch 100 Loss 0.2061
Epoch 7 Batch 200 Loss 0.1943
Epoch 7 Batch 300 Loss 0.1981
Epoch 7 Loss 0.2048
Time taken for 1 epoch 15.117473125457764 sec

Epoch 8 Batch 0 Loss 0.1252
Epoch 8 Batch 100 Loss 0.1283
Epoch 8 Batch 200 Loss 0.1425
Epoch 8 Batch 300 Loss 0.1484
Epoch 8 Loss 0.1507
Time taken for 1 epoch 15.514633417129517 sec

Epoch 9 Batch 0 Loss 0.1110
Epoch 9 Batch 100 Loss 0.1025
Epoch 9 Batch 200 Loss 0.1511
Epoch 9 Batch 300 Loss 0.1266
Epoch 9 Loss 0.1172
Time taken for 1 epoch 15.115840435028076 sec

Epoch 10 Batch 0 Loss 0.0825
Epoch 10 Batch 100 Loss 0.0646
Epoch 10 Batch 200 Loss 0.0726
Epoch 10 Batch 300 Loss 0.1250
Epoch 10 Loss 0.0972
Time taken for 1 epoch 15.492951154708862 sec


الترجمة

  • تشبه خطوات وظيفة التقييم التّالية خطوات عمليّة التدريب ، باستثناء أننا لا نستخدم تقنية إجبار المعلم هنا. المُدخل في نموذج فك التشفير في كل خطوة زمنية هو تنبؤاته السابقة بالإضافة إلى الحالة المخفية و نتاج نموذج التشفير.
  • أوقف التنبؤ عندما يتنبأ النموذج برمز end.
  • احفظ أوزان الانتباه لكل خطوة زمنية.
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: %s' % (sentence))
  print('Predicted translation: {}'.format(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 0x7f40fc2bda90>
translate(u'hace mucho frio aqui.')
Input: <start> hace mucho frio aqui . <end>
Predicted translation: it s very cold here . <end> 

png

translate(u'esta es mi vida.')
Input: <start> esta es mi vida . <end>
Predicted translation: this is my life . <end> 

png

translate(u'¿todavia estan en casa?')
Input: <start> ¿ todavia estan en casa ? <end>
Predicted translation: are you still at home ? <end> 

png

# wrong translation
translate(u'trata de averiguarlo.')
Input: <start> trata de averiguarlo . <end>
Predicted translation: try to figure it out . <end> 

png

الخطوات التالية

  • قم بتنزيل مجموعة بيانات مختلفة لتجربة ترجمات أخرى، على سبيل المثال ، الإنجليزية إلى الألمانية ، أو الإنجليزية إلى الفرنسية.
  • جرب التدريب على مجموعة بيانات أكبر ، أو استخدم المزيد من الحقبات (epochs).