หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

การแปลด้วยระบบประสาทด้วยความสนใจ

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน 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. สร้างดัชนีคำและดัชนีคำย้อนกลับ (การทำแผนที่พจนานุกรมจาก word → id และ id → word)
  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 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 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 ("%d ----> %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>
4 ----> tom
42 ----> tiene
2344 ----> tos
3 ----> .
2 ----> <end>

Target Language; index to word mapping
1 ----> <start>
5 ----> tom
51 ----> has
9 ----> a
1554 ----> cough
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 แผนภาพต่อไปนี้แสดงให้เห็นว่าแต่ละคำอินพุตถูกกำหนดน้ำหนักโดยกลไกความสนใจซึ่งจะใช้โดยเครื่องถอดรหัสเพื่อทำนายคำถัดไปในประโยค รูปภาพและสูตรด้านล่างเป็นตัวอย่างของกลไกการเอาใจใส่จาก กระดาษของ Luong

กลไกความสนใจ

อินพุตถูกป้อนผ่านโมเดลตัวเข้ารหัสซึ่งให้เอาต์พุตเข้ารหัสของรูปร่าง (batch_size, max_length, hidden_size) และสถานะตัวเข้ารหัสที่ซ่อนของรูปร่าง (batch_size, hidden_size)

นี่คือสมการที่นำมาใช้:

สมการสนใจ 0สมการการสนใจ 1

บทช่วยสอนนี้ใช้ ความสนใจ Bahdanau สำหรับโปรแกรมเปลี่ยนไฟล์ มาตัดสินใจเกี่ยวกับสัญกรณ์ก่อนที่จะเขียนแบบง่าย ๆ :

  • FC = เลเยอร์ (หนาแน่น) เชื่อมต่ออย่างสมบูรณ์
  • EO = เอาท์พุทตัวเข้ารหัส
  • H = สถานะที่ซ่อนอยู่
  • X = อินพุตไปยังตัวถอดรหัส

และหลอกรหัส:

  • score = FC(tanh(FC(EO) + FC(H)))
  • attention weights = softmax(score, axis = 1) Softmax โดยค่าเริ่มต้นจะใช้กับแกนสุดท้าย แต่ที่นี่เราต้องการนำไปใช้กับ แกนที่ 1 เนื่องจากรูปร่างของคะแนนคือ (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) {}'.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 = 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('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.4937
Epoch 1 Batch 100 Loss 2.3472
Epoch 1 Batch 200 Loss 1.9153
Epoch 1 Batch 300 Loss 1.8042
Epoch 1 Loss 2.0265
Time taken for 1 epoch 27.345187664031982 sec

Epoch 2 Batch 0 Loss 1.5260
Epoch 2 Batch 100 Loss 1.5228
Epoch 2 Batch 200 Loss 1.3840
Epoch 2 Batch 300 Loss 1.3131
Epoch 2 Loss 1.3900
Time taken for 1 epoch 15.777411222457886 sec

Epoch 3 Batch 0 Loss 1.0458
Epoch 3 Batch 100 Loss 0.9216
Epoch 3 Batch 200 Loss 0.9254
Epoch 3 Batch 300 Loss 0.9041
Epoch 3 Loss 0.9699
Time taken for 1 epoch 15.391497373580933 sec

Epoch 4 Batch 0 Loss 0.7582
Epoch 4 Batch 100 Loss 0.7201
Epoch 4 Batch 200 Loss 0.6765
Epoch 4 Batch 300 Loss 0.6696
Epoch 4 Loss 0.6555
Time taken for 1 epoch 15.782341480255127 sec

Epoch 5 Batch 0 Loss 0.3534
Epoch 5 Batch 100 Loss 0.4191
Epoch 5 Batch 200 Loss 0.5322
Epoch 5 Batch 300 Loss 0.4767
Epoch 5 Loss 0.4494
Time taken for 1 epoch 15.508086204528809 sec

Epoch 6 Batch 0 Loss 0.2508
Epoch 6 Batch 100 Loss 0.3366
Epoch 6 Batch 200 Loss 0.2935
Epoch 6 Batch 300 Loss 0.3432
Epoch 6 Loss 0.3137
Time taken for 1 epoch 15.811218738555908 sec

Epoch 7 Batch 0 Loss 0.1759
Epoch 7 Batch 100 Loss 0.1997
Epoch 7 Batch 200 Loss 0.2879
Epoch 7 Batch 300 Loss 0.2643
Epoch 7 Loss 0.2257
Time taken for 1 epoch 15.454826831817627 sec

Epoch 8 Batch 0 Loss 0.1318
Epoch 8 Batch 100 Loss 0.1151
Epoch 8 Batch 200 Loss 0.2130
Epoch 8 Batch 300 Loss 0.1852
Epoch 8 Loss 0.1712
Time taken for 1 epoch 15.786991596221924 sec

Epoch 9 Batch 0 Loss 0.0876
Epoch 9 Batch 100 Loss 0.1227
Epoch 9 Batch 200 Loss 0.1361
Epoch 9 Batch 300 Loss 0.1682
Epoch 9 Loss 0.1328
Time taken for 1 epoch 15.443743467330933 sec

Epoch 10 Batch 0 Loss 0.1048
Epoch 10 Batch 100 Loss 0.0736
Epoch 10 Batch 200 Loss 0.1056
Epoch 10 Batch 300 Loss 0.1204
Epoch 10 Loss 0.1074
Time taken for 1 epoch 15.615742683410645 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: %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 0x7ff366a4bcc0>
 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 มากขึ้น