![]() | ![]() | ![]() | ![]() |
הדרכה זו מכשירה מודל רובוטריק לתרגוםמערך נתונים פורטוגזית לאנגלית . זו דוגמה מתקדמת המניחה ידע על יצירת טקסט ותשומת לב .
רעיון הליבה שעומד מאחורי מודל הרובוטריקים הוא תשומת לב עצמית - היכולת לטפל במיקומים שונים של רצף הקלט כדי לחשב ייצוג של אותו רצף. רובוטריק יוצר ערימות של שכבות של תשומת לב עצמית ומוסבר להלן בסעיפים תשומת לב מוצר נקודתית מוגברת ותשומת לב מרובת ראשים .
קלט משתנה בגודל ידיות דגם שנאי באמצעות ערימות של שכבות עצמית תשומת במקום RNNs או CNNs . לארכיטקטורה כללית זו מספר יתרונות:
- אין בו הנחות לגבי היחסים הזמניים / מרחביים על פני הנתונים. זה אידיאלי לעיבוד קבוצה של אובייקטים (למשל, יחידות StarCraft ).
- ניתן לחשב את תפוקות השכבה במקביל, במקום סדרה כמו RNN.
- פריטים מרוחקים יכולים להשפיע זה על הפלט של השני מבלי לעבור דרך שלבי RNN רבים, או שכבות פיתול (ראו שנאי זיכרון סצנה למשל).
- זה יכול ללמוד תלות ארוכת טווח. זהו אתגר במשימות רצף רבות.
החסרונות של אדריכלות זו הם:
- עבור סדרת זמן, הפלט עבור שלב זמן מחושב מכל ההיסטוריה במקום רק את התשומות והמצב הסמוי הנוכחי. זה עשוי להיות פחות יעיל.
- אם לקלט אכן יש קשר זמני / מרחבי, כמו טקסט, יש להוסיף קידוד מיקום כלשהו או שהמודל יראה למעשה שקית של מילים.
לאחר אימון המודל במחברת זו, תוכלו להזין משפט לפורטוגזית ולהחזיר את התרגום לאנגלית.
להכין
pip install -q tensorflow_datasets
pip install -q tensorflow_text
import collections
import logging
import os
import pathlib
import re
import string
import sys
import time
import numpy as np
import matplotlib.pyplot as plt
import tensorflow_datasets as tfds
import tensorflow_text as text
import tensorflow as tf
logging.getLogger('tensorflow').setLevel(logging.ERROR) # suppress warnings
הורד את מערך הנתונים
השתמש במערכי הנתונים של TensorFlow כדי לטעון את מערך התרגום לאנגלית מפורטוגזית מפרויקט התרגום הפתוח של TED .
מערך נתונים זה מכיל כ- 50000 דוגמאות אימונים, 1100 דוגמאות אימות ו- 2000 דוגמאות למבחן.
examples, metadata = tfds.load('ted_hrlr_translate/pt_to_en', with_info=True,
as_supervised=True)
train_examples, val_examples = examples['train'], examples['validation']
אובייקטtf.data.Dataset
שהוחזר על ידי מערכי נתונים של TensorFlow מניב זוגות של דוגמאות טקסט:
for pt_examples, en_examples in train_examples.batch(3).take(1):
for pt in pt_examples.numpy():
print(pt.decode('utf-8'))
print()
for en in en_examples.numpy():
print(en.decode('utf-8'))
e quando melhoramos a procura , tiramos a única vantagem da impressão , que é a serendipidade . mas e se estes fatores fossem ativos ? mas eles não tinham a curiosidade de me testar . and when you improve searchability , you actually take away the one advantage of print , which is serendipity . but what if it were active ? but they did n't test for curiosity .
טוקניזציה וטכניקת טקסט
אינך יכול להכשיר מודל ישירות על טקסט. יש להמיר את הטקסט תחילה לייצוג מספרי. בדרך כלל, אתה ממיר את הטקסט לרצפים של מזהי אסימונים, שהם אינדקסים להטבעה.
יישום פופולרי אחד מוצג במדריך Subword tokenizer לבניית tokenizers של text.BertTokenizer
( text.BertTokenizer
) המותאמת text.BertTokenizer
נתונים זה ומייצאת אותם ב- model_ Saved .
הורד ופתח את saved_model
של saved_model
:
model_name = "ted_hrlr_translate_pt_en_converter"
tf.keras.utils.get_file(
f"{model_name}.zip",
f"https://storage.googleapis.com/download.tensorflow.org/models/{model_name}.zip",
cache_dir='.', cache_subdir='', extract=True
)
Downloading data from https://storage.googleapis.com/download.tensorflow.org/models/ted_hrlr_translate_pt_en_converter.zip 188416/184801 [==============================] - 0s 0us/step './ted_hrlr_translate_pt_en_converter.zip'
tokenizers = tf.saved_model.load(model_name)
ה- tf.saved_model
מכיל שני tf.saved_model
טקסט, אחד לאנגלית ואחד לפורטוגזית. לשתיהן אותן שיטות:
[item for item in dir(tokenizers.en) if not item.startswith('_')]
['detokenize', 'get_reserved_tokens', 'get_vocab_path', 'get_vocab_size', 'lookup', 'tokenize', 'tokenizer', 'vocab']
שיטת tokenize
ממירה אצווה של מחרוזות לאצווה מרופדת של מזהי אסימונים. שיטה זו מבצעת פיצול פיסוק, הקטנת אותיות נמוכות ונורמליזציה של unicode לקלט לפני אסימון. סטנדרטיזציה זו אינה נראית כאן מכיוון שנתוני הקלט כבר סטנדרטיים.
for en in en_examples.numpy():
print(en.decode('utf-8'))
and when you improve searchability , you actually take away the one advantage of print , which is serendipity . but what if it were active ? but they did n't test for curiosity .
encoded = tokenizers.en.tokenize(en_examples)
for row in encoded.to_list():
print(row)
[2, 72, 117, 79, 1259, 1491, 2362, 13, 79, 150, 184, 311, 71, 103, 2308, 74, 2679, 13, 148, 80, 55, 4840, 1434, 2423, 540, 15, 3] [2, 87, 90, 107, 76, 129, 1852, 30, 3] [2, 87, 83, 149, 50, 9, 56, 664, 85, 2512, 15, 3]
שיטת ה- detokenize
מנסה להמיר את מזהי האסימון האלה לטקסט קריא על ידי האדם:
round_trip = tokenizers.en.detokenize(encoded)
for line in round_trip.numpy():
print(line.decode('utf-8'))
and when you improve searchability , you actually take away the one advantage of print , which is serendipity . but what if it were active ? but they did n ' t test for curiosity .
שיטת lookup
ברמה התחתונה הופכת ממזהים אסימוניים לטקסט אסימוני:
tokens = tokenizers.en.lookup(encoded)
tokens
<tf.RaggedTensor [[b'[START]', b'and', b'when', b'you', b'improve', b'search', b'##ability', b',', b'you', b'actually', b'take', b'away', b'the', b'one', b'advantage', b'of', b'print', b',', b'which', b'is', b's', b'##ere', b'##nd', b'##ip', b'##ity', b'.', b'[END]'], [b'[START]', b'but', b'what', b'if', b'it', b'were', b'active', b'?', b'[END]'], [b'[START]', b'but', b'they', b'did', b'n', b"'", b't', b'test', b'for', b'curiosity', b'.', b'[END]']]>
כאן תוכלו לראות את ההיבט "תת-מילת מפתח" של האסימונים. המילה "יכולת חיפוש" מפורקת ל"חיפוש ## יכולת "והמילה" serindipity "ל"ס ## לפני ## nd ## ip ## ity"
הגדרת צינור קלט
כדי לבנות צינור קלט מתאים לאימון, תחיל כמה שינויים במערך הנתונים.
פונקציה זו תשמש לקידוד קבוצות הטקסט הגולמי:
0629aeaff0להלן צינור קלט פשוט שמעבד, מדשדש ומנתח את הנתונים:
BUFFER_SIZE = 20000
BATCH_SIZE = 64
def make_batches(ds):
return (
ds
.cache()
.shuffle(BUFFER_SIZE)
.batch(BATCH_SIZE)
.map(tokenize_pairs, num_parallel_calls=tf.data.AUTOTUNE)
.prefetch(tf.data.AUTOTUNE))
train_batches = make_batches(train_examples)
val_batches = make_batches(val_examples)
קידוד מיקום
מכיוון שמודל זה אינו מכיל הישנות או התמרה, מתווסף קידוד מיקום כדי לספק למודל מידע על המיקום היחסי של המילים במשפט.
וקטור קידוד המיקום מתווסף לווקטור ההטבעה. ההטבעות מייצגות אסימון במרחב דו ממדי שבו אסימונים בעלי משמעות דומה יהיו קרובים יותר זה לזה. אך הטבילות אינן מקודדות את המיקום היחסי של מילים במשפט. אז לאחר הוספת קידוד המיקום, מילים יהיו קרובות יותר זו לזו על סמך הדמיון של משמעותן ומיקומן במשפט , במרחב הד-ממדי.
ראה את המחברת בנושא קידוד מיקום כדי ללמוד עוד על כך. הנוסחה לחישוב קידוד המיקום היא כדלקמן:
def get_angles(pos, i, d_model):
angle_rates = 1 / np.power(10000, (2 * (i//2)) / np.float32(d_model))
return pos * angle_rates
def positional_encoding(position, d_model):
angle_rads = get_angles(np.arange(position)[:, np.newaxis],
np.arange(d_model)[np.newaxis, :],
d_model)
# apply sin to even indices in the array; 2i
angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2])
# apply cos to odd indices in the array; 2i+1
angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2])
pos_encoding = angle_rads[np.newaxis, ...]
return tf.cast(pos_encoding, dtype=tf.float32)
n, d = 2048, 512
pos_encoding = positional_encoding(n, d)
print(pos_encoding.shape)
pos_encoding = pos_encoding[0]
# Juggle the dimensions for the plot
pos_encoding = tf.reshape(pos_encoding, (n, d//2, 2))
pos_encoding = tf.transpose(pos_encoding, (2, 1, 0))
pos_encoding = tf.reshape(pos_encoding, (d, n))
plt.pcolormesh(pos_encoding, cmap='RdBu')
plt.ylabel('Depth')
plt.xlabel('Position')
plt.colorbar()
plt.show()
(1, 2048, 512)
מִסוּך
מסווה את כל אסימוני הפדים בסדרת הרצפים. זה מבטיח שהדגם לא יתייחס לריפוד כאל קלט. המסכה מציינת היכן קיים ערך כרית 0
: היא מוציאה 1
במקומות אלה, ו- 0
אחרת.
def create_padding_mask(seq):
seq = tf.cast(tf.math.equal(seq, 0), tf.float32)
# add extra dimensions to add the padding
# to the attention logits.
return seq[:, tf.newaxis, tf.newaxis, :] # (batch_size, 1, 1, seq_len)
x = tf.constant([[7, 6, 0, 0, 1], [1, 2, 3, 0, 0], [0, 0, 0, 4, 5]])
create_padding_mask(x)
<tf.Tensor: shape=(3, 1, 1, 5), dtype=float32, numpy= array([[[[0., 0., 1., 1., 0.]]], [[[0., 0., 0., 1., 1.]]], [[[1., 1., 1., 0., 0.]]]], dtype=float32)>
מסכת המבט קדימה משמשת למסכת האסימונים העתידיים ברצף. במילים אחרות, המסכה מציינת באילו ערכים אסור להשתמש.
פירוש הדבר שכדי לחזות את המילה השלישית ישתמש רק במילה הראשונה והשנייה. באופן דומה כדי לחזות את המילה הרביעית, ישתמשו רק במילה הראשונה, השנייה והשלישית וכן הלאה.
def create_look_ahead_mask(size):
mask = 1 - tf.linalg.band_part(tf.ones((size, size)), -1, 0)
return mask # (seq_len, seq_len)
x = tf.random.uniform((1, 3))
temp = create_look_ahead_mask(x.shape[1])
temp
<tf.Tensor: shape=(3, 3), dtype=float32, numpy= array([[0., 1., 1.], [0., 0., 1.], [0., 0., 0.]], dtype=float32)>
תשומת לב מוגדלת למוצר
פונקציית הקשב המשמשת את השנאי לוקחת שלוש כניסות: Q (שאילתה), K (מפתח), V (ערך). המשוואה המשמשת לחישוב משקולות הקשב היא:
תשומת הלב של המוצר הנקודתי מוקטנת על ידי גורם של שורש רבוע של העומק. זה נעשה מכיוון שעבור ערכי עומק גדולים, מוצר הנקודות גדל בעוצמתו ודוחף את פונקציית softmax במקום שיש לו שיפועים קטנים וכתוצאה מכך softmax קשה מאוד.
לדוגמא, קחו בחשבון Q
ו- K
יש ממוצע של 0 ושונות של 1. לכפל המטריצה שלהם יהיה ממוצע של 0 ושונות של dk
. לכן השורש הריבועי של dk
משמש dk
המידה, כך שתקבל שונות עקבית ללא קשר לערך של dk
. אם השונות נמוכה מדי, התפוקה עשויה להיות שטוחה מכדי לבצע אופטימיזציה יעילה. אם השונות גבוהה מדי, ה- softmax עשוי להרוות בעת ההתחלה, מה שמקשה על הלימוד.
המסכה מוכפלת עם -1e9 (קרוב לאינסוף שלילי). זה נעשה מכיוון שהמסכה מסוכמת עם כפל המטריצה המוקטנת של Q ו- K והיא מוחלת מיד לפני softmax. המטרה היא לאפס את התאים הללו, ותשומות שליליות גדולות ל- softmax הן כמעט אפס בתפוקה.
def scaled_dot_product_attention(q, k, v, mask):
"""Calculate the attention weights.
q, k, v must have matching leading dimensions.
k, v must have matching penultimate dimension, i.e.: seq_len_k = seq_len_v.
The mask has different shapes depending on its type(padding or look ahead)
but it must be broadcastable for addition.
Args:
q: query shape == (..., seq_len_q, depth)
k: key shape == (..., seq_len_k, depth)
v: value shape == (..., seq_len_v, depth_v)
mask: Float tensor with shape broadcastable
to (..., seq_len_q, seq_len_k). Defaults to None.
Returns:
output, attention_weights
"""
matmul_qk = tf.matmul(q, k, transpose_b=True) # (..., seq_len_q, seq_len_k)
# scale matmul_qk
dk = tf.cast(tf.shape(k)[-1], tf.float32)
scaled_attention_logits = matmul_qk / tf.math.sqrt(dk)
# add the mask to the scaled tensor.
if mask is not None:
scaled_attention_logits += (mask * -1e9)
# softmax is normalized on the last axis (seq_len_k) so that the scores
# add up to 1.
attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1) # (..., seq_len_q, seq_len_k)
output = tf.matmul(attention_weights, v) # (..., seq_len_q, depth_v)
return output, attention_weights
כאשר הנורמליזציה של softmax נעשית ב- K, ערכיה מחליטים את מידת החשיבות שניתנה ל- Q.
הפלט מייצג את הכפל של משקולות הקשב והווקטור V (ערך). זה מבטיח שהמילים שאתה רוצה להתמקד בהן יישמרו כמו שהן והמילים הלא רלוונטיות נשטפות החוצה.
def print_out(q, k, v):
temp_out, temp_attn = scaled_dot_product_attention(
q, k, v, None)
print('Attention weights are:')
print(temp_attn)
print('Output is:')
print(temp_out)
np.set_printoptions(suppress=True)
temp_k = tf.constant([[10, 0, 0],
[0, 10, 0],
[0, 0, 10],
[0, 0, 10]], dtype=tf.float32) # (4, 3)
temp_v = tf.constant([[1, 0],
[10, 0],
[100, 5],
[1000, 6]], dtype=tf.float32) # (4, 2)
# This `query` aligns with the second `key`,
# so the second `value` is returned.
temp_q = tf.constant([[0, 10, 0]], dtype=tf.float32) # (1, 3)
print_out(temp_q, temp_k, temp_v)
Attention weights are: tf.Tensor([[0. 1. 0. 0.]], shape=(1, 4), dtype=float32) Output is: tf.Tensor([[10. 0.]], shape=(1, 2), dtype=float32)
# This query aligns with a repeated key (third and fourth),
# so all associated values get averaged.
temp_q = tf.constant([[0, 0, 10]], dtype=tf.float32) # (1, 3)
print_out(temp_q, temp_k, temp_v)
Attention weights are: tf.Tensor([[0. 0. 0.5 0.5]], shape=(1, 4), dtype=float32) Output is: tf.Tensor([[550. 5.5]], shape=(1, 2), dtype=float32)
# This query aligns equally with the first and second key,
# so their values get averaged.
temp_q = tf.constant([[10, 10, 0]], dtype=tf.float32) # (1, 3)
print_out(temp_q, temp_k, temp_v)
Attention weights are: tf.Tensor([[0.5 0.5 0. 0. ]], shape=(1, 4), dtype=float32) Output is: tf.Tensor([[5.5 0. ]], shape=(1, 2), dtype=float32)
העבירו את כל השאילתות יחד.
temp_q = tf.constant([[0, 0, 10],
[0, 10, 0],
[10, 10, 0]], dtype=tf.float32) # (3, 3)
print_out(temp_q, temp_k, temp_v)
Attention weights are: tf.Tensor( [[0. 0. 0.5 0.5] [0. 1. 0. 0. ] [0.5 0.5 0. 0. ]], shape=(3, 4), dtype=float32) Output is: tf.Tensor( [[550. 5.5] [ 10. 0. ] [ 5.5 0. ]], shape=(3, 2), dtype=float32)
תשומת לב מרובת ראשים
תשומת לב מרובת ראשים מורכבת מארבעה חלקים:
- שכבות ליניאריות ומתפצלות לראשים.
- תשומת לב מוגברת של מוצר נקודתי.
- שרשור ראשים.
- שכבה לינארית סופית.
כל בלוק קשב רב-ראשי מקבל שלוש כניסות; Q (שאילתה), K (מפתח), V (ערך). אלה מוכנסים דרך שכבות לינאריות (צפופות) ומתפצלים לראשים מרובים.
scaled_dot_product_attention
שהוגדרה לעיל מוחלת על כל ראש (משודר לצורך יעילות). יש להשתמש במסכה מתאימה בשלב הקשב. פלט תשומת הלב של כל ראש tf.transpose
(באמצעות tf.transpose
ו- tf.reshape
) tf.reshape
דרך שכבה Dense
סופית.
במקום ראש תשומת לב אחד, Q, K ו- V מחולקים למספר ראשים מכיוון שהוא מאפשר למודל לטפל במשותף במידע במיקומים שונים ממרחבי ייצוג שונים. לאחר הפיצול לכל ראש יש מימדי מופחת, כך שעלות החישוב הכוללת זהה לתשומת לב ראש אחת עם ממד מלא.
class MultiHeadAttention(tf.keras.layers.Layer):
def __init__(self, d_model, num_heads):
super(MultiHeadAttention, self).__init__()
self.num_heads = num_heads
self.d_model = d_model
assert d_model % self.num_heads == 0
self.depth = d_model // self.num_heads
self.wq = tf.keras.layers.Dense(d_model)
self.wk = tf.keras.layers.Dense(d_model)
self.wv = tf.keras.layers.Dense(d_model)
self.dense = tf.keras.layers.Dense(d_model)
def split_heads(self, x, batch_size):
"""Split the last dimension into (num_heads, depth).
Transpose the result such that the shape is (batch_size, num_heads, seq_len, depth)
"""
x = tf.reshape(x, (batch_size, -1, self.num_heads, self.depth))
return tf.transpose(x, perm=[0, 2, 1, 3])
def call(self, v, k, q, mask):
batch_size = tf.shape(q)[0]
q = self.wq(q) # (batch_size, seq_len, d_model)
k = self.wk(k) # (batch_size, seq_len, d_model)
v = self.wv(v) # (batch_size, seq_len, d_model)
q = self.split_heads(q, batch_size) # (batch_size, num_heads, seq_len_q, depth)
k = self.split_heads(k, batch_size) # (batch_size, num_heads, seq_len_k, depth)
v = self.split_heads(v, batch_size) # (batch_size, num_heads, seq_len_v, depth)
# scaled_attention.shape == (batch_size, num_heads, seq_len_q, depth)
# attention_weights.shape == (batch_size, num_heads, seq_len_q, seq_len_k)
scaled_attention, attention_weights = scaled_dot_product_attention(
q, k, v, mask)
scaled_attention = tf.transpose(scaled_attention, perm=[0, 2, 1, 3]) # (batch_size, seq_len_q, num_heads, depth)
concat_attention = tf.reshape(scaled_attention,
(batch_size, -1, self.d_model)) # (batch_size, seq_len_q, d_model)
output = self.dense(concat_attention) # (batch_size, seq_len_q, d_model)
return output, attention_weights
צור שכבת MultiHeadAttention
כדי לנסות. בכל מיקום ברצף, y
, MultiHeadAttention
מריץ את כל 8 ראשי הקשב בכל המיקומים האחרים ברצף, ומחזיר וקטור חדש באותו אורך בכל מיקום.
temp_mha = MultiHeadAttention(d_model=512, num_heads=8)
y = tf.random.uniform((1, 60, 512)) # (batch_size, encoder_sequence, d_model)
out, attn = temp_mha(y, k=y, q=y, mask=None)
out.shape, attn.shape
(TensorShape([1, 60, 512]), TensorShape([1, 8, 60, 60]))
נקודת העדכון נקודה חכמה
רשת העברת הזנה נקודתית חכמה מורכבת משתי שכבות מחוברות לחלוטין וביניהן הפעלת ReLU.
def point_wise_feed_forward_network(d_model, dff):
return tf.keras.Sequential([
tf.keras.layers.Dense(dff, activation='relu'), # (batch_size, seq_len, dff)
tf.keras.layers.Dense(d_model) # (batch_size, seq_len, d_model)
])
sample_ffn = point_wise_feed_forward_network(512, 2048)
sample_ffn(tf.random.uniform((64, 50, 512))).shape
TensorShape([64, 50, 512])
מקודד ומפענח
מודל השנאי עוקב אחר אותו דפוס כללי כמו רצף סטנדרטי לרצף עם מודל קשב .
- משפט הקלט מועבר דרך שכבות מקודד
N
המייצר פלט לכל מילה / אסימון ברצף. - המפענח מטפל בפלט המקודד ובקלט שלו (תשומת לב עצמית) כדי לחזות את המילה הבאה.
שכבת מקודד
כל שכבת מקודד מורכבת משכבות משנה:
- תשומת לב מרובת ראשים (עם מסכת ריפוד)
- נקודתי רשתות הזנה קדימה.
לכל אחת משכבות המשנה האלה יש חיבור שיורי ואחריו נורמליזציה של השכבה. קשרים שיוריים עוזרים במניעת בעיית השיפוע הנעלמת ברשתות עמוקות.
הפלט של כל שכבת משנה הוא LayerNorm(x + Sublayer(x))
. הנורמליזציה נעשית d_model
(האחרון). ישנן שכבות מקודדות N בשנאי.
class EncoderLayer(tf.keras.layers.Layer):
def __init__(self, d_model, num_heads, dff, rate=0.1):
super(EncoderLayer, self).__init__()
self.mha = MultiHeadAttention(d_model, num_heads)
self.ffn = point_wise_feed_forward_network(d_model, dff)
self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6)
self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6)
self.dropout1 = tf.keras.layers.Dropout(rate)
self.dropout2 = tf.keras.layers.Dropout(rate)
def call(self, x, training, mask):
attn_output, _ = self.mha(x, x, x, mask) # (batch_size, input_seq_len, d_model)
attn_output = self.dropout1(attn_output, training=training)
out1 = self.layernorm1(x + attn_output) # (batch_size, input_seq_len, d_model)
ffn_output = self.ffn(out1) # (batch_size, input_seq_len, d_model)
ffn_output = self.dropout2(ffn_output, training=training)
out2 = self.layernorm2(out1 + ffn_output) # (batch_size, input_seq_len, d_model)
return out2
sample_encoder_layer = EncoderLayer(512, 8, 2048)
sample_encoder_layer_output = sample_encoder_layer(
tf.random.uniform((64, 43, 512)), False, None)
sample_encoder_layer_output.shape # (batch_size, input_seq_len, d_model)
TensorShape([64, 43, 512])
שכבת מפענח
כל שכבת מפענח מורכבת משכבות משנה:
- תשומת לב מרובת ראשות רעולי פנים (עם מסיכת מבט קדימה ומסכת ריפוד)
- תשומת לב מרובת ראשים (עם מסכת ריפוד). V (ערך) ו- K (מפתח) מקבלים את פלט המקודד ככניסות. Q (שאילתה) מקבל את הפלט משכבת המשנה רב-ראשית עם מסיכת פנים.
- נקודתי רשתות הזנה קדימה
לכל אחת משכבות המשנה האלה יש חיבור שיורי ואחריו נורמליזציה של השכבה. הפלט של כל שכבת משנה הוא LayerNorm(x + Sublayer(x))
. הנורמליזציה נעשית d_model
(האחרון).
ישנן שכבות מפענח N בשנאי.
כאשר Q מקבל את הפלט מגוש הקשב הראשון של המפענח, ו- K מקבל את פלט המקודד, משקולות הקשב מייצגות את החשיבות הניתנת לקלט המפענח על בסיס פלט המקודד. במילים אחרות, המפענח מנבא את המילה הבאה על ידי התבוננות בפלט המקודד ומטפל בעצמו בפלט שלו. ראה את ההדגמה לעיל בסעיף תשומת הלב של המוצר.
class DecoderLayer(tf.keras.layers.Layer):
def __init__(self, d_model, num_heads, dff, rate=0.1):
super(DecoderLayer, self).__init__()
self.mha1 = MultiHeadAttention(d_model, num_heads)
self.mha2 = MultiHeadAttention(d_model, num_heads)
self.ffn = point_wise_feed_forward_network(d_model, dff)
self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6)
self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6)
self.layernorm3 = tf.keras.layers.LayerNormalization(epsilon=1e-6)
self.dropout1 = tf.keras.layers.Dropout(rate)
self.dropout2 = tf.keras.layers.Dropout(rate)
self.dropout3 = tf.keras.layers.Dropout(rate)
def call(self, x, enc_output, training,
look_ahead_mask, padding_mask):
# enc_output.shape == (batch_size, input_seq_len, d_model)
attn1, attn_weights_block1 = self.mha1(x, x, x, look_ahead_mask) # (batch_size, target_seq_len, d_model)
attn1 = self.dropout1(attn1, training=training)
out1 = self.layernorm1(attn1 + x)
attn2, attn_weights_block2 = self.mha2(
enc_output, enc_output, out1, padding_mask) # (batch_size, target_seq_len, d_model)
attn2 = self.dropout2(attn2, training=training)
out2 = self.layernorm2(attn2 + out1) # (batch_size, target_seq_len, d_model)
ffn_output = self.ffn(out2) # (batch_size, target_seq_len, d_model)
ffn_output = self.dropout3(ffn_output, training=training)
out3 = self.layernorm3(ffn_output + out2) # (batch_size, target_seq_len, d_model)
return out3, attn_weights_block1, attn_weights_block2
sample_decoder_layer = DecoderLayer(512, 8, 2048)
sample_decoder_layer_output, _, _ = sample_decoder_layer(
tf.random.uniform((64, 50, 512)), sample_encoder_layer_output,
False, None, None)
sample_decoder_layer_output.shape # (batch_size, target_seq_len, d_model)
TensorShape([64, 50, 512])
קוֹדַאִי
Encoder
מורכב מ:
- הטמעת קלט
- קידוד מיקום
- שכבות מקודד N
הקלט מועבר באמצעות הטבעה שמסוכמת עם קידוד המיקום. הפלט של סיכום זה הוא הקלט לשכבות המקודד. פלט המקודד הוא הקלט למפענח.
class Encoder(tf.keras.layers.Layer):
def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size,
maximum_position_encoding, rate=0.1):
super(Encoder, self).__init__()
self.d_model = d_model
self.num_layers = num_layers
self.embedding = tf.keras.layers.Embedding(input_vocab_size, d_model)
self.pos_encoding = positional_encoding(maximum_position_encoding,
self.d_model)
self.enc_layers = [EncoderLayer(d_model, num_heads, dff, rate)
for _ in range(num_layers)]
self.dropout = tf.keras.layers.Dropout(rate)
def call(self, x, training, mask):
seq_len = tf.shape(x)[1]
# adding embedding and position encoding.
x = self.embedding(x) # (batch_size, input_seq_len, d_model)
x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))
x += self.pos_encoding[:, :seq_len, :]
x = self.dropout(x, training=training)
for i in range(self.num_layers):
x = self.enc_layers[i](x, training, mask)
return x # (batch_size, input_seq_len, d_model)
sample_encoder = Encoder(num_layers=2, d_model=512, num_heads=8,
dff=2048, input_vocab_size=8500,
maximum_position_encoding=10000)
temp_input = tf.random.uniform((64, 62), dtype=tf.int64, minval=0, maxval=200)
sample_encoder_output = sample_encoder(temp_input, training=False, mask=None)
print(sample_encoder_output.shape) # (batch_size, input_seq_len, d_model)
(64, 62, 512)
מפענח
Decoder
מורכב מ:
- הטמעת פלט
- קידוד מיקום
- שכבות מפענח N
היעד מועבר באמצעות הטבעה שמסוכמת עם קידוד המיקום. הפלט של סיכום זה הוא הקלט לשכבות המפענח. הפלט של המפענח הוא הקלט לשכבה הליניארית הסופית.
class Decoder(tf.keras.layers.Layer):
def __init__(self, num_layers, d_model, num_heads, dff, target_vocab_size,
maximum_position_encoding, rate=0.1):
super(Decoder, self).__init__()
self.d_model = d_model
self.num_layers = num_layers
self.embedding = tf.keras.layers.Embedding(target_vocab_size, d_model)
self.pos_encoding = positional_encoding(maximum_position_encoding, d_model)
self.dec_layers = [DecoderLayer(d_model, num_heads, dff, rate)
for _ in range(num_layers)]
self.dropout = tf.keras.layers.Dropout(rate)
def call(self, x, enc_output, training,
look_ahead_mask, padding_mask):
seq_len = tf.shape(x)[1]
attention_weights = {}
x = self.embedding(x) # (batch_size, target_seq_len, d_model)
x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))
x += self.pos_encoding[:, :seq_len, :]
x = self.dropout(x, training=training)
for i in range(self.num_layers):
x, block1, block2 = self.dec_layers[i](x, enc_output, training,
look_ahead_mask, padding_mask)
attention_weights[f'decoder_layer{i+1}_block1'] = block1
attention_weights[f'decoder_layer{i+1}_block2'] = block2
# x.shape == (batch_size, target_seq_len, d_model)
return x, attention_weights
sample_decoder = Decoder(num_layers=2, d_model=512, num_heads=8,
dff=2048, target_vocab_size=8000,
maximum_position_encoding=5000)
temp_input = tf.random.uniform((64, 26), dtype=tf.int64, minval=0, maxval=200)
output, attn = sample_decoder(temp_input,
enc_output=sample_encoder_output,
training=False,
look_ahead_mask=None,
padding_mask=None)
output.shape, attn['decoder_layer2_block2'].shape
(TensorShape([64, 26, 512]), TensorShape([64, 8, 26, 62]))
צור את השנאי
שנאי מורכב מקודד, מפענח ושכבה לינארית סופית. הפלט של המפענח הוא הקלט לשכבה הליניארית והפלט שלו מוחזר.
class Transformer(tf.keras.Model):
def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size,
target_vocab_size, pe_input, pe_target, rate=0.1):
super(Transformer, self).__init__()
self.tokenizer = Encoder(num_layers, d_model, num_heads, dff,
input_vocab_size, pe_input, rate)
self.decoder = Decoder(num_layers, d_model, num_heads, dff,
target_vocab_size, pe_target, rate)
self.final_layer = tf.keras.layers.Dense(target_vocab_size)
def call(self, inp, tar, training, enc_padding_mask,
look_ahead_mask, dec_padding_mask):
enc_output = self.tokenizer(inp, training, enc_padding_mask) # (batch_size, inp_seq_len, d_model)
# dec_output.shape == (batch_size, tar_seq_len, d_model)
dec_output, attention_weights = self.decoder(
tar, enc_output, training, look_ahead_mask, dec_padding_mask)
final_output = self.final_layer(dec_output) # (batch_size, tar_seq_len, target_vocab_size)
return final_output, attention_weights
sample_transformer = Transformer(
num_layers=2, d_model=512, num_heads=8, dff=2048,
input_vocab_size=8500, target_vocab_size=8000,
pe_input=10000, pe_target=6000)
temp_input = tf.random.uniform((64, 38), dtype=tf.int64, minval=0, maxval=200)
temp_target = tf.random.uniform((64, 36), dtype=tf.int64, minval=0, maxval=200)
fn_out, _ = sample_transformer(temp_input, temp_target, training=False,
enc_padding_mask=None,
look_ahead_mask=None,
dec_padding_mask=None)
fn_out.shape # (batch_size, tar_seq_len, target_vocab_size)
TensorShape([64, 36, 8000])
הגדר פרפרמטרים
כדי לשמור על דוגמא זו קטנה ומהירה יחסית, הופחתו הערכים עבור מספר_שכבות, d_model ו- dff .
הערכים המשמשים במודל הבסיס של שנאי היו; מספר_שכבות = 6 , d_model = 512 , dff = 2048 . ראה בעיתון את כל הגרסאות האחרות של השנאי.
num_layers = 4
d_model = 128
dff = 512
num_heads = 8
dropout_rate = 0.1
מיטוב
השתמש בכלי האופטימיזציה של אדם עם מתזמן קצב למידה מותאם אישית על פי הנוסחה בעיתון .
class CustomSchedule(tf.keras.optimizers.schedules.LearningRateSchedule):
def __init__(self, d_model, warmup_steps=4000):
super(CustomSchedule, self).__init__()
self.d_model = d_model
self.d_model = tf.cast(self.d_model, tf.float32)
self.warmup_steps = warmup_steps
def __call__(self, step):
arg1 = tf.math.rsqrt(step)
arg2 = step * (self.warmup_steps ** -1.5)
return tf.math.rsqrt(self.d_model) * tf.math.minimum(arg1, arg2)
learning_rate = CustomSchedule(d_model)
optimizer = tf.keras.optimizers.Adam(learning_rate, beta_1=0.9, beta_2=0.98,
epsilon=1e-9)
temp_learning_rate_schedule = CustomSchedule(d_model)
plt.plot(temp_learning_rate_schedule(tf.range(40000, dtype=tf.float32)))
plt.ylabel("Learning Rate")
plt.xlabel("Train Step")
Text(0.5, 0, 'Train Step')
אובדן ומדדים
מכיוון שרצפי היעד מרופדים, חשוב להחיל מסכת ריפוד בעת חישוב ההפסד.
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_sum(loss_)/tf.reduce_sum(mask)
def accuracy_function(real, pred):
accuracies = tf.equal(real, tf.argmax(pred, axis=2))
mask = tf.math.logical_not(tf.math.equal(real, 0))
accuracies = tf.math.logical_and(mask, accuracies)
accuracies = tf.cast(accuracies, dtype=tf.float32)
mask = tf.cast(mask, dtype=tf.float32)
return tf.reduce_sum(accuracies)/tf.reduce_sum(mask)
train_loss = tf.keras.metrics.Mean(name='train_loss')
train_accuracy = tf.keras.metrics.Mean(name='train_accuracy')
אימונים ומחסומים
transformer = Transformer(
num_layers=num_layers,
d_model=d_model,
num_heads=num_heads,
dff=dff,
input_vocab_size=tokenizers.pt.get_vocab_size(),
target_vocab_size=tokenizers.en.get_vocab_size(),
pe_input=1000,
pe_target=1000,
rate=dropout_rate)
def create_masks(inp, tar):
# Encoder padding mask
enc_padding_mask = create_padding_mask(inp)
# Used in the 2nd attention block in the decoder.
# This padding mask is used to mask the encoder outputs.
dec_padding_mask = create_padding_mask(inp)
# Used in the 1st attention block in the decoder.
# It is used to pad and mask future tokens in the input received by
# the decoder.
look_ahead_mask = create_look_ahead_mask(tf.shape(tar)[1])
dec_target_padding_mask = create_padding_mask(tar)
combined_mask = tf.maximum(dec_target_padding_mask, look_ahead_mask)
return enc_padding_mask, combined_mask, dec_padding_mask
צור את נתיב המחסום ואת מנהל המחסום. זה ישמש כדי לחסוך מחסומים בכל n
תקופות.
checkpoint_path = "./checkpoints/train"
ckpt = tf.train.Checkpoint(transformer=transformer,
optimizer=optimizer)
ckpt_manager = tf.train.CheckpointManager(ckpt, checkpoint_path, max_to_keep=5)
# if a checkpoint exists, restore the latest checkpoint.
if ckpt_manager.latest_checkpoint:
ckpt.restore(ckpt_manager.latest_checkpoint)
print('Latest checkpoint restored!!')
היעד מחולק ל- tar_inp ו- tar_real. tar_inp מועבר כקלט למפענח. tar_real
הוא אותו קלט שהועבר ב -1: בכל מיקום ב- tar_input
, tar_real
מכיל את האסימון הבא שיש לחזות.
לדוגמה, sentence
= "SOS אריה בג'ונגל ישן EOS"
tar_inp
= "SOS אריה בג'ונגל ישן"
tar_real
= "אריה בג'ונגל ישן EOS"
השנאי הוא מודל רגרסיבי אוטומטי: הוא עושה תחזיות אחד בכל פעם ומשתמש בפלט שלו עד כה כדי להחליט מה לעשות הלאה.
במהלך האימון דוגמה זו משתמשת בכפיית מורים (כמו בהדרכה ליצירת טקסטים ). אילוץ מורים מעביר את התפוקה האמיתית לשלב הזמן הבא ללא קשר למה שהמודל חוזה בשלב הזמן הנוכחי.
כאשר השנאי מנבא כל מילה, תשומת לב עצמית מאפשרת לו להסתכל על המילים הקודמות ברצף הקלט כדי לחזות טוב יותר את המילה הבאה.
כדי למנוע מהמודל להציץ לפלט הצפוי, המודל משתמש במסכת מבט קדימה.
EPOCHS = 20
# The @tf.function trace-compiles train_step into a TF graph for faster
# execution. The function specializes to the precise shape of the argument
# tensors. To avoid re-tracing due to the variable sequence lengths or variable
# batch sizes (the last batch is smaller), use input_signature to specify
# more generic shapes.
train_step_signature = [
tf.TensorSpec(shape=(None, None), dtype=tf.int64),
tf.TensorSpec(shape=(None, None), dtype=tf.int64),
]
@tf.function(input_signature=train_step_signature)
def train_step(inp, tar):
tar_inp = tar[:, :-1]
tar_real = tar[:, 1:]
enc_padding_mask, combined_mask, dec_padding_mask = create_masks(inp, tar_inp)
with tf.GradientTape() as tape:
predictions, _ = transformer(inp, tar_inp,
True,
enc_padding_mask,
combined_mask,
dec_padding_mask)
loss = loss_function(tar_real, predictions)
gradients = tape.gradient(loss, transformer.trainable_variables)
optimizer.apply_gradients(zip(gradients, transformer.trainable_variables))
train_loss(loss)
train_accuracy(accuracy_function(tar_real, predictions))
פורטוגזית משמשת כשפת קלט ואנגלית היא שפת היעד.
for epoch in range(EPOCHS):
start = time.time()
train_loss.reset_states()
train_accuracy.reset_states()
# inp -> portuguese, tar -> english
for (batch, (inp, tar)) in enumerate(train_batches):
train_step(inp, tar)
if batch % 50 == 0:
print(f'Epoch {epoch + 1} Batch {batch} Loss {train_loss.result():.4f} Accuracy {train_accuracy.result():.4f}')
if (epoch + 1) % 5 == 0:
ckpt_save_path = ckpt_manager.save()
print(f'Saving checkpoint for epoch {epoch+1} at {ckpt_save_path}')
print(f'Epoch {epoch + 1} Loss {train_loss.result():.4f} Accuracy {train_accuracy.result():.4f}')
print(f'Time taken for 1 epoch: {time.time() - start:.2f} secs\n')
Epoch 1 Batch 0 Loss 8.9100 Accuracy 0.0000 Epoch 1 Batch 50 Loss 8.8356 Accuracy 0.0000 Epoch 1 Batch 100 Loss 8.7204 Accuracy 0.0189 Epoch 1 Batch 150 Loss 8.6013 Accuracy 0.0301 Epoch 1 Batch 200 Loss 8.4595 Accuracy 0.0368 Epoch 1 Batch 250 Loss 8.2902 Accuracy 0.0419 Epoch 1 Batch 300 Loss 8.0998 Accuracy 0.0480 Epoch 1 Batch 350 Loss 7.9023 Accuracy 0.0537 Epoch 1 Batch 400 Loss 7.7121 Accuracy 0.0603 Epoch 1 Batch 450 Loss 7.5456 Accuracy 0.0684 Epoch 1 Batch 500 Loss 7.3958 Accuracy 0.0762 Epoch 1 Batch 550 Loss 7.2616 Accuracy 0.0834 Epoch 1 Batch 600 Loss 7.1360 Accuracy 0.0909 Epoch 1 Batch 650 Loss 7.0193 Accuracy 0.0980 Epoch 1 Batch 700 Loss 6.9098 Accuracy 0.1048 Epoch 1 Batch 750 Loss 6.8094 Accuracy 0.1110 Epoch 1 Batch 800 Loss 6.7171 Accuracy 0.1166 Epoch 1 Loss 6.7009 Accuracy 0.1176 Time taken for 1 epoch: 62.77 secs Epoch 2 Batch 0 Loss 5.3367 Accuracy 0.1986 Epoch 2 Batch 50 Loss 5.2102 Accuracy 0.2122 Epoch 2 Batch 100 Loss 5.1933 Accuracy 0.2141 Epoch 2 Batch 150 Loss 5.1574 Accuracy 0.2184 Epoch 2 Batch 200 Loss 5.1324 Accuracy 0.2211 Epoch 2 Batch 250 Loss 5.1131 Accuracy 0.2230 Epoch 2 Batch 300 Loss 5.0927 Accuracy 0.2252 Epoch 2 Batch 350 Loss 5.0686 Accuracy 0.2279 Epoch 2 Batch 400 Loss 5.0458 Accuracy 0.2304 Epoch 2 Batch 450 Loss 5.0202 Accuracy 0.2330 Epoch 2 Batch 500 Loss 4.9994 Accuracy 0.2352 Epoch 2 Batch 550 Loss 4.9846 Accuracy 0.2367 Epoch 2 Batch 600 Loss 4.9679 Accuracy 0.2381 Epoch 2 Batch 650 Loss 4.9507 Accuracy 0.2399 Epoch 2 Batch 700 Loss 4.9325 Accuracy 0.2416 Epoch 2 Batch 750 Loss 4.9148 Accuracy 0.2431 Epoch 2 Batch 800 Loss 4.8987 Accuracy 0.2446 Epoch 2 Loss 4.8961 Accuracy 0.2449 Time taken for 1 epoch: 50.23 secs Epoch 3 Batch 0 Loss 4.4982 Accuracy 0.3001 Epoch 3 Batch 50 Loss 4.5929 Accuracy 0.2684 Epoch 3 Batch 100 Loss 4.5739 Accuracy 0.2724 Epoch 3 Batch 150 Loss 4.5582 Accuracy 0.2744 Epoch 3 Batch 200 Loss 4.5466 Accuracy 0.2755 Epoch 3 Batch 250 Loss 4.5418 Accuracy 0.2764 Epoch 3 Batch 300 Loss 4.5288 Accuracy 0.2779 Epoch 3 Batch 350 Loss 4.5153 Accuracy 0.2796 Epoch 3 Batch 400 Loss 4.4985 Accuracy 0.2813 Epoch 3 Batch 450 Loss 4.4831 Accuracy 0.2831 Epoch 3 Batch 500 Loss 4.4666 Accuracy 0.2851 Epoch 3 Batch 550 Loss 4.4518 Accuracy 0.2869 Epoch 3 Batch 600 Loss 4.4358 Accuracy 0.2888 Epoch 3 Batch 650 Loss 4.4201 Accuracy 0.2908 Epoch 3 Batch 700 Loss 4.4041 Accuracy 0.2927 Epoch 3 Batch 750 Loss 4.3882 Accuracy 0.2945 Epoch 3 Batch 800 Loss 4.3714 Accuracy 0.2966 Epoch 3 Loss 4.3674 Accuracy 0.2971 Time taken for 1 epoch: 49.58 secs Epoch 4 Batch 0 Loss 4.0688 Accuracy 0.3188 Epoch 4 Batch 50 Loss 4.0178 Accuracy 0.3364 Epoch 4 Batch 100 Loss 4.0144 Accuracy 0.3363 Epoch 4 Batch 150 Loss 3.9990 Accuracy 0.3384 Epoch 4 Batch 200 Loss 3.9837 Accuracy 0.3407 Epoch 4 Batch 250 Loss 3.9590 Accuracy 0.3442 Epoch 4 Batch 300 Loss 3.9439 Accuracy 0.3468 Epoch 4 Batch 350 Loss 3.9256 Accuracy 0.3491 Epoch 4 Batch 400 Loss 3.9088 Accuracy 0.3516 Epoch 4 Batch 450 Loss 3.8955 Accuracy 0.3534 Epoch 4 Batch 500 Loss 3.8801 Accuracy 0.3555 Epoch 4 Batch 550 Loss 3.8677 Accuracy 0.3572 Epoch 4 Batch 600 Loss 3.8543 Accuracy 0.3591 Epoch 4 Batch 650 Loss 3.8413 Accuracy 0.3610 Epoch 4 Batch 700 Loss 3.8278 Accuracy 0.3626 Epoch 4 Batch 750 Loss 3.8151 Accuracy 0.3643 Epoch 4 Batch 800 Loss 3.8018 Accuracy 0.3661 Epoch 4 Loss 3.7992 Accuracy 0.3664 Time taken for 1 epoch: 49.30 secs Epoch 5 Batch 0 Loss 3.4919 Accuracy 0.4033 Epoch 5 Batch 50 Loss 3.5070 Accuracy 0.3975 Epoch 5 Batch 100 Loss 3.4946 Accuracy 0.4005 Epoch 5 Batch 150 Loss 3.4881 Accuracy 0.4014 Epoch 5 Batch 200 Loss 3.4732 Accuracy 0.4044 Epoch 5 Batch 250 Loss 3.4666 Accuracy 0.4052 Epoch 5 Batch 300 Loss 3.4576 Accuracy 0.4060 Epoch 5 Batch 350 Loss 3.4427 Accuracy 0.4083 Epoch 5 Batch 400 Loss 3.4292 Accuracy 0.4102 Epoch 5 Batch 450 Loss 3.4159 Accuracy 0.4121 Epoch 5 Batch 500 Loss 3.4036 Accuracy 0.4137 Epoch 5 Batch 550 Loss 3.3930 Accuracy 0.4152 Epoch 5 Batch 600 Loss 3.3852 Accuracy 0.4163 Epoch 5 Batch 650 Loss 3.3783 Accuracy 0.4172 Epoch 5 Batch 700 Loss 3.3682 Accuracy 0.4186 Epoch 5 Batch 750 Loss 3.3597 Accuracy 0.4197 Epoch 5 Batch 800 Loss 3.3512 Accuracy 0.4209 Saving checkpoint for epoch 5 at ./checkpoints/train/ckpt-1 Epoch 5 Loss 3.3500 Accuracy 0.4209 Time taken for 1 epoch: 50.38 secs Epoch 6 Batch 0 Loss 2.7326 Accuracy 0.4912 Epoch 6 Batch 50 Loss 3.0709 Accuracy 0.4535 Epoch 6 Batch 100 Loss 3.0605 Accuracy 0.4557 Epoch 6 Batch 150 Loss 3.0550 Accuracy 0.4566 Epoch 6 Batch 200 Loss 3.0579 Accuracy 0.4564 Epoch 6 Batch 250 Loss 3.0414 Accuracy 0.4586 Epoch 6 Batch 300 Loss 3.0309 Accuracy 0.4606 Epoch 6 Batch 350 Loss 3.0224 Accuracy 0.4614 Epoch 6 Batch 400 Loss 3.0133 Accuracy 0.4624 Epoch 6 Batch 450 Loss 3.0020 Accuracy 0.4639 Epoch 6 Batch 500 Loss 2.9945 Accuracy 0.4650 Epoch 6 Batch 550 Loss 2.9890 Accuracy 0.4660 Epoch 6 Batch 600 Loss 2.9801 Accuracy 0.4672 Epoch 6 Batch 650 Loss 2.9739 Accuracy 0.4681 Epoch 6 Batch 700 Loss 2.9649 Accuracy 0.4694 Epoch 6 Batch 750 Loss 2.9566 Accuracy 0.4705 Epoch 6 Batch 800 Loss 2.9511 Accuracy 0.4712 Epoch 6 Loss 2.9493 Accuracy 0.4715 Time taken for 1 epoch: 50.79 secs Epoch 7 Batch 0 Loss 2.5923 Accuracy 0.5178 Epoch 7 Batch 50 Loss 2.7039 Accuracy 0.5011 Epoch 7 Batch 100 Loss 2.6967 Accuracy 0.5013 Epoch 7 Batch 150 Loss 2.6928 Accuracy 0.5017 Epoch 7 Batch 200 Loss 2.6884 Accuracy 0.5025 Epoch 7 Batch 250 Loss 2.6836 Accuracy 0.5029 Epoch 7 Batch 300 Loss 2.6736 Accuracy 0.5046 Epoch 7 Batch 350 Loss 2.6701 Accuracy 0.5052 Epoch 7 Batch 400 Loss 2.6645 Accuracy 0.5061 Epoch 7 Batch 450 Loss 2.6616 Accuracy 0.5065 Epoch 7 Batch 500 Loss 2.6530 Accuracy 0.5079 Epoch 7 Batch 550 Loss 2.6468 Accuracy 0.5088 Epoch 7 Batch 600 Loss 2.6410 Accuracy 0.5097 Epoch 7 Batch 650 Loss 2.6367 Accuracy 0.5105 Epoch 7 Batch 700 Loss 2.6331 Accuracy 0.5110 Epoch 7 Batch 750 Loss 2.6284 Accuracy 0.5119 Epoch 7 Batch 800 Loss 2.6259 Accuracy 0.5123 Epoch 7 Loss 2.6256 Accuracy 0.5124 Time taken for 1 epoch: 50.15 secs Epoch 8 Batch 0 Loss 2.0821 Accuracy 0.5868 Epoch 8 Batch 50 Loss 2.4047 Accuracy 0.5410 Epoch 8 Batch 100 Loss 2.4083 Accuracy 0.5394 Epoch 8 Batch 150 Loss 2.4116 Accuracy 0.5393 Epoch 8 Batch 200 Loss 2.4099 Accuracy 0.5397 Epoch 8 Batch 250 Loss 2.4124 Accuracy 0.5391 Epoch 8 Batch 300 Loss 2.4089 Accuracy 0.5395 Epoch 8 Batch 350 Loss 2.4047 Accuracy 0.5404 Epoch 8 Batch 400 Loss 2.4027 Accuracy 0.5407 Epoch 8 Batch 450 Loss 2.4025 Accuracy 0.5407 Epoch 8 Batch 500 Loss 2.4000 Accuracy 0.5412 Epoch 8 Batch 550 Loss 2.3966 Accuracy 0.5420 Epoch 8 Batch 600 Loss 2.3945 Accuracy 0.5423 Epoch 8 Batch 650 Loss 2.3957 Accuracy 0.5422 Epoch 8 Batch 700 Loss 2.3934 Accuracy 0.5426 Epoch 8 Batch 750 Loss 2.3945 Accuracy 0.5426 Epoch 8 Batch 800 Loss 2.3913 Accuracy 0.5431 Epoch 8 Loss 2.3909 Accuracy 0.5432 Time taken for 1 epoch: 50.24 secs Epoch 9 Batch 0 Loss 2.2065 Accuracy 0.5583 Epoch 9 Batch 50 Loss 2.2045 Accuracy 0.5660 Epoch 9 Batch 100 Loss 2.2084 Accuracy 0.5668 Epoch 9 Batch 150 Loss 2.2118 Accuracy 0.5665 Epoch 9 Batch 200 Loss 2.2072 Accuracy 0.5677 Epoch 9 Batch 250 Loss 2.2118 Accuracy 0.5668 Epoch 9 Batch 300 Loss 2.2182 Accuracy 0.5663 Epoch 9 Batch 350 Loss 2.2157 Accuracy 0.5665 Epoch 9 Batch 400 Loss 2.2184 Accuracy 0.5662 Epoch 9 Batch 450 Loss 2.2162 Accuracy 0.5667 Epoch 9 Batch 500 Loss 2.2162 Accuracy 0.5669 Epoch 9 Batch 550 Loss 2.2137 Accuracy 0.5674 Epoch 9 Batch 600 Loss 2.2144 Accuracy 0.5672 Epoch 9 Batch 650 Loss 2.2145 Accuracy 0.5674 Epoch 9 Batch 700 Loss 2.2142 Accuracy 0.5676 Epoch 9 Batch 750 Loss 2.2136 Accuracy 0.5678 Epoch 9 Batch 800 Loss 2.2143 Accuracy 0.5677 Epoch 9 Loss 2.2153 Accuracy 0.5676 Time taken for 1 epoch: 50.02 secs Epoch 10 Batch 0 Loss 2.2510 Accuracy 0.5560 Epoch 10 Batch 50 Loss 2.0568 Accuracy 0.5881 Epoch 10 Batch 100 Loss 2.0707 Accuracy 0.5854 Epoch 10 Batch 150 Loss 2.0704 Accuracy 0.5862 Epoch 10 Batch 200 Loss 2.0712 Accuracy 0.5863 Epoch 10 Batch 250 Loss 2.0676 Accuracy 0.5870 Epoch 10 Batch 300 Loss 2.0712 Accuracy 0.5864 Epoch 10 Batch 350 Loss 2.0699 Accuracy 0.5867 Epoch 10 Batch 400 Loss 2.0720 Accuracy 0.5864 Epoch 10 Batch 450 Loss 2.0706 Accuracy 0.5868 Epoch 10 Batch 500 Loss 2.0726 Accuracy 0.5866 Epoch 10 Batch 550 Loss 2.0770 Accuracy 0.5860 Epoch 10 Batch 600 Loss 2.0757 Accuracy 0.5863 Epoch 10 Batch 650 Loss 2.0770 Accuracy 0.5863 Epoch 10 Batch 700 Loss 2.0794 Accuracy 0.5860 Epoch 10 Batch 750 Loss 2.0783 Accuracy 0.5865 Epoch 10 Batch 800 Loss 2.0773 Accuracy 0.5868 Saving checkpoint for epoch 10 at ./checkpoints/train/ckpt-2 Epoch 10 Loss 2.0783 Accuracy 0.5867 Time taken for 1 epoch: 50.45 secs Epoch 11 Batch 0 Loss 2.1780 Accuracy 0.5496 Epoch 11 Batch 50 Loss 1.9558 Accuracy 0.6021 Epoch 11 Batch 100 Loss 1.9544 Accuracy 0.6036 Epoch 11 Batch 150 Loss 1.9594 Accuracy 0.6024 Epoch 11 Batch 200 Loss 1.9580 Accuracy 0.6032 Epoch 11 Batch 250 Loss 1.9611 Accuracy 0.6026 Epoch 11 Batch 300 Loss 1.9605 Accuracy 0.6024 Epoch 11 Batch 350 Loss 1.9613 Accuracy 0.6026 Epoch 11 Batch 400 Loss 1.9622 Accuracy 0.6024 Epoch 11 Batch 450 Loss 1.9624 Accuracy 0.6025 Epoch 11 Batch 500 Loss 1.9636 Accuracy 0.6022 Epoch 11 Batch 550 Loss 1.9651 Accuracy 0.6023 Epoch 11 Batch 600 Loss 1.9660 Accuracy 0.6022 Epoch 11 Batch 650 Loss 1.9666 Accuracy 0.6021 Epoch 11 Batch 700 Loss 1.9682 Accuracy 0.6019 Epoch 11 Batch 750 Loss 1.9691 Accuracy 0.6019 Epoch 11 Batch 800 Loss 1.9684 Accuracy 0.6022 Epoch 11 Loss 1.9684 Accuracy 0.6023 Time taken for 1 epoch: 49.93 secs Epoch 12 Batch 0 Loss 2.0619 Accuracy 0.5867 Epoch 12 Batch 50 Loss 1.8266 Accuracy 0.6231 Epoch 12 Batch 100 Loss 1.8458 Accuracy 0.6203 Epoch 12 Batch 150 Loss 1.8579 Accuracy 0.6175 Epoch 12 Batch 200 Loss 1.8604 Accuracy 0.6173 Epoch 12 Batch 250 Loss 1.8588 Accuracy 0.6179 Epoch 12 Batch 300 Loss 1.8587 Accuracy 0.6179 Epoch 12 Batch 350 Loss 1.8588 Accuracy 0.6180 Epoch 12 Batch 400 Loss 1.8620 Accuracy 0.6175 Epoch 12 Batch 450 Loss 1.8633 Accuracy 0.6174 Epoch 12 Batch 500 Loss 1.8645 Accuracy 0.6171 Epoch 12 Batch 550 Loss 1.8662 Accuracy 0.6168 Epoch 12 Batch 600 Loss 1.8680 Accuracy 0.6167 Epoch 12 Batch 650 Loss 1.8693 Accuracy 0.6165 Epoch 12 Batch 700 Loss 1.8712 Accuracy 0.6165 Epoch 12 Batch 750 Loss 1.8724 Accuracy 0.6164 Epoch 12 Batch 800 Loss 1.8736 Accuracy 0.6163 Epoch 12 Loss 1.8738 Accuracy 0.6163 Time taken for 1 epoch: 50.68 secs Epoch 13 Batch 0 Loss 1.6363 Accuracy 0.6542 Epoch 13 Batch 50 Loss 1.7369 Accuracy 0.6358 Epoch 13 Batch 100 Loss 1.7542 Accuracy 0.6321 Epoch 13 Batch 150 Loss 1.7633 Accuracy 0.6302 Epoch 13 Batch 200 Loss 1.7693 Accuracy 0.6293 Epoch 13 Batch 250 Loss 1.7778 Accuracy 0.6286 Epoch 13 Batch 300 Loss 1.7800 Accuracy 0.6285 Epoch 13 Batch 350 Loss 1.7840 Accuracy 0.6278 Epoch 13 Batch 400 Loss 1.7855 Accuracy 0.6277 Epoch 13 Batch 450 Loss 1.7845 Accuracy 0.6279 Epoch 13 Batch 500 Loss 1.7837 Accuracy 0.6281 Epoch 13 Batch 550 Loss 1.7856 Accuracy 0.6279 Epoch 13 Batch 600 Loss 1.7884 Accuracy 0.6276 Epoch 13 Batch 650 Loss 1.7907 Accuracy 0.6274 Epoch 13 Batch 700 Loss 1.7921 Accuracy 0.6275 Epoch 13 Batch 750 Loss 1.7938 Accuracy 0.6273 Epoch 13 Batch 800 Loss 1.7959 Accuracy 0.6271 Epoch 13 Loss 1.7955 Accuracy 0.6272 Time taken for 1 epoch: 51.56 secs Epoch 14 Batch 0 Loss 1.7589 Accuracy 0.6225 Epoch 14 Batch 50 Loss 1.6739 Accuracy 0.6436 Epoch 14 Batch 100 Loss 1.6871 Accuracy 0.6421 Epoch 14 Batch 150 Loss 1.6937 Accuracy 0.6416 Epoch 14 Batch 200 Loss 1.6950 Accuracy 0.6415 Epoch 14 Batch 250 Loss 1.6975 Accuracy 0.6415 Epoch 14 Batch 300 Loss 1.6951 Accuracy 0.6418 Epoch 14 Batch 350 Loss 1.7000 Accuracy 0.6411 Epoch 14 Batch 400 Loss 1.7041 Accuracy 0.6407 Epoch 14 Batch 450 Loss 1.7068 Accuracy 0.6402 Epoch 14 Batch 500 Loss 1.7096 Accuracy 0.6399 Epoch 14 Batch 550 Loss 1.7104 Accuracy 0.6398 Epoch 14 Batch 600 Loss 1.7128 Accuracy 0.6394 Epoch 14 Batch 650 Loss 1.7166 Accuracy 0.6388 Epoch 14 Batch 700 Loss 1.7200 Accuracy 0.6382 Epoch 14 Batch 750 Loss 1.7228 Accuracy 0.6379 Epoch 14 Batch 800 Loss 1.7256 Accuracy 0.6375 Epoch 14 Loss 1.7268 Accuracy 0.6374 Time taken for 1 epoch: 51.95 secs Epoch 15 Batch 0 Loss 1.6051 Accuracy 0.6474 Epoch 15 Batch 50 Loss 1.6280 Accuracy 0.6511 Epoch 15 Batch 100 Loss 1.6313 Accuracy 0.6497 Epoch 15 Batch 150 Loss 1.6378 Accuracy 0.6503 Epoch 15 Batch 200 Loss 1.6409 Accuracy 0.6502 Epoch 15 Batch 250 Loss 1.6412 Accuracy 0.6502 Epoch 15 Batch 300 Loss 1.6407 Accuracy 0.6505 Epoch 15 Batch 350 Loss 1.6438 Accuracy 0.6497 Epoch 15 Batch 400 Loss 1.6457 Accuracy 0.6492 Epoch 15 Batch 450 Loss 1.6487 Accuracy 0.6489 Epoch 15 Batch 500 Loss 1.6520 Accuracy 0.6485 Epoch 15 Batch 550 Loss 1.6559 Accuracy 0.6480 Epoch 15 Batch 600 Loss 1.6572 Accuracy 0.6477 Epoch 15 Batch 650 Loss 1.6595 Accuracy 0.6475 Epoch 15 Batch 700 Loss 1.6608 Accuracy 0.6474 Epoch 15 Batch 750 Loss 1.6632 Accuracy 0.6471 Epoch 15 Batch 800 Loss 1.6663 Accuracy 0.6466 Saving checkpoint for epoch 15 at ./checkpoints/train/ckpt-3 Epoch 15 Loss 1.6664 Accuracy 0.6467 Time taken for 1 epoch: 51.73 secs Epoch 16 Batch 0 Loss 1.6299 Accuracy 0.6467 Epoch 16 Batch 50 Loss 1.5914 Accuracy 0.6572 Epoch 16 Batch 100 Loss 1.5856 Accuracy 0.6581 Epoch 16 Batch 150 Loss 1.5843 Accuracy 0.6588 Epoch 16 Batch 200 Loss 1.5905 Accuracy 0.6575 Epoch 16 Batch 250 Loss 1.5917 Accuracy 0.6577 Epoch 16 Batch 300 Loss 1.5925 Accuracy 0.6574 Epoch 16 Batch 350 Loss 1.5928 Accuracy 0.6573 Epoch 16 Batch 400 Loss 1.5958 Accuracy 0.6570 Epoch 16 Batch 450 Loss 1.5962 Accuracy 0.6568 Epoch 16 Batch 500 Loss 1.5995 Accuracy 0.6563 Epoch 16 Batch 550 Loss 1.6030 Accuracy 0.6559 Epoch 16 Batch 600 Loss 1.6029 Accuracy 0.6559 Epoch 16 Batch 650 Loss 1.6027 Accuracy 0.6562 Epoch 16 Batch 700 Loss 1.6062 Accuracy 0.6557 Epoch 16 Batch 750 Loss 1.6095 Accuracy 0.6553 Epoch 16 Batch 800 Loss 1.6130 Accuracy 0.6549 Epoch 16 Loss 1.6133 Accuracy 0.6549 Time taken for 1 epoch: 51.53 secs Epoch 17 Batch 0 Loss 1.5703 Accuracy 0.6669 Epoch 17 Batch 50 Loss 1.5117 Accuracy 0.6696 Epoch 17 Batch 100 Loss 1.5209 Accuracy 0.6684 Epoch 17 Batch 150 Loss 1.5284 Accuracy 0.6669 Epoch 17 Batch 200 Loss 1.5316 Accuracy 0.6663 Epoch 17 Batch 250 Loss 1.5378 Accuracy 0.6653 Epoch 17 Batch 300 Loss 1.5382 Accuracy 0.6655 Epoch 17 Batch 350 Loss 1.5406 Accuracy 0.6650 Epoch 17 Batch 400 Loss 1.5433 Accuracy 0.6644 Epoch 17 Batch 450 Loss 1.5459 Accuracy 0.6641 Epoch 17 Batch 500 Loss 1.5509 Accuracy 0.6633 Epoch 17 Batch 550 Loss 1.5507 Accuracy 0.6634 Epoch 17 Batch 600 Loss 1.5524 Accuracy 0.6632 Epoch 17 Batch 650 Loss 1.5565 Accuracy 0.6626 Epoch 17 Batch 700 Loss 1.5592 Accuracy 0.6622 Epoch 17 Batch 750 Loss 1.5617 Accuracy 0.6619 Epoch 17 Batch 800 Loss 1.5647 Accuracy 0.6615 Epoch 17 Loss 1.5648 Accuracy 0.6615 Time taken for 1 epoch: 51.79 secs Epoch 18 Batch 0 Loss 1.6312 Accuracy 0.6418 Epoch 18 Batch 50 Loss 1.4663 Accuracy 0.6776 Epoch 18 Batch 100 Loss 1.4787 Accuracy 0.6749 Epoch 18 Batch 150 Loss 1.4886 Accuracy 0.6736 Epoch 18 Batch 200 Loss 1.4921 Accuracy 0.6734 Epoch 18 Batch 250 Loss 1.4908 Accuracy 0.6739 Epoch 18 Batch 300 Loss 1.4935 Accuracy 0.6735 Epoch 18 Batch 350 Loss 1.4975 Accuracy 0.6724 Epoch 18 Batch 400 Loss 1.4988 Accuracy 0.6722 Epoch 18 Batch 450 Loss 1.5011 Accuracy 0.6717 Epoch 18 Batch 500 Loss 1.5025 Accuracy 0.6716 Epoch 18 Batch 550 Loss 1.5069 Accuracy 0.6708 Epoch 18 Batch 600 Loss 1.5089 Accuracy 0.6704 Epoch 18 Batch 650 Loss 1.5114 Accuracy 0.6701 Epoch 18 Batch 700 Loss 1.5133 Accuracy 0.6699 Epoch 18 Batch 750 Loss 1.5155 Accuracy 0.6697 Epoch 18 Batch 800 Loss 1.5197 Accuracy 0.6692 Epoch 18 Loss 1.5196 Accuracy 0.6692 Time taken for 1 epoch: 51.27 secs Epoch 19 Batch 0 Loss 1.3096 Accuracy 0.7138 Epoch 19 Batch 50 Loss 1.4316 Accuracy 0.6818 Epoch 19 Batch 100 Loss 1.4265 Accuracy 0.6827 Epoch 19 Batch 150 Loss 1.4351 Accuracy 0.6816 Epoch 19 Batch 200 Loss 1.4462 Accuracy 0.6795 Epoch 19 Batch 250 Loss 1.4518 Accuracy 0.6788 Epoch 19 Batch 300 Loss 1.4582 Accuracy 0.6781 Epoch 19 Batch 350 Loss 1.4591 Accuracy 0.6784 Epoch 19 Batch 400 Loss 1.4607 Accuracy 0.6782 Epoch 19 Batch 450 Loss 1.4627 Accuracy 0.6779 Epoch 19 Batch 500 Loss 1.4636 Accuracy 0.6780 Epoch 19 Batch 550 Loss 1.4667 Accuracy 0.6775 Epoch 19 Batch 600 Loss 1.4682 Accuracy 0.6773 Epoch 19 Batch 650 Loss 1.4714 Accuracy 0.6768 Epoch 19 Batch 700 Loss 1.4742 Accuracy 0.6764 Epoch 19 Batch 750 Loss 1.4776 Accuracy 0.6757 Epoch 19 Batch 800 Loss 1.4810 Accuracy 0.6753 Epoch 19 Loss 1.4810 Accuracy 0.6754 Time taken for 1 epoch: 50.62 secs Epoch 20 Batch 0 Loss 1.2899 Accuracy 0.7115 Epoch 20 Batch 50 Loss 1.3791 Accuracy 0.6902 Epoch 20 Batch 100 Loss 1.3859 Accuracy 0.6901 Epoch 20 Batch 150 Loss 1.3991 Accuracy 0.6880 Epoch 20 Batch 200 Loss 1.4079 Accuracy 0.6867 Epoch 20 Batch 250 Loss 1.4115 Accuracy 0.6861 Epoch 20 Batch 300 Loss 1.4128 Accuracy 0.6858 Epoch 20 Batch 350 Loss 1.4180 Accuracy 0.6848 Epoch 20 Batch 400 Loss 1.4174 Accuracy 0.6850 Epoch 20 Batch 450 Loss 1.4209 Accuracy 0.6848 Epoch 20 Batch 500 Loss 1.4236 Accuracy 0.6844 Epoch 20 Batch 550 Loss 1.4280 Accuracy 0.6836 Epoch 20 Batch 600 Loss 1.4324 Accuracy 0.6828 Epoch 20 Batch 650 Loss 1.4337 Accuracy 0.6827 Epoch 20 Batch 700 Loss 1.4365 Accuracy 0.6822 Epoch 20 Batch 750 Loss 1.4391 Accuracy 0.6818 Epoch 20 Batch 800 Loss 1.4432 Accuracy 0.6813 Saving checkpoint for epoch 20 at ./checkpoints/train/ckpt-4 Epoch 20 Loss 1.4440 Accuracy 0.6812 Time taken for 1 epoch: 51.88 secs
להעריך
השלבים הבאים משמשים להערכה:
- קידד את משפט הקלט באמצעות tokenizer הפורטוגזי (
tokenizers.pt
). זהו קלט המקודד. - קלט המפענח מאותחל לאסימון
[START]
. - חשב את מסכות הריפוד ואת מסכות המבט קדימה.
- לאחר מכן
decoder
את התחזיות על ידי התבוננותencoder output
שלו (תשומת לב עצמית). - המודל מנבא את המילה הבאה עבור כל מילה בפלט. רוב אלה מיותרים. השתמש בתחזיות מהמילה האחרונה.
- שרשר את המילה החזויה לקלט המפענח והעביר אותה למפענח.
- בגישה זו, המפענח מנבא את המילה הבאה על סמך המילים הקודמות שחזה.
def evaluate(sentence, max_length=40):
# inp sentence is portuguese, hence adding the start and end token
sentence = tf.convert_to_tensor([sentence])
sentence = tokenizers.pt.tokenize(sentence).to_tensor()
encoder_input = sentence
# as the target is english, the first word to the transformer should be the
# english start token.
start, end = tokenizers.en.tokenize([''])[0]
output = tf.convert_to_tensor([start])
output = tf.expand_dims(output, 0)
for i in range(max_length):
enc_padding_mask, combined_mask, dec_padding_mask = create_masks(
encoder_input, output)
# predictions.shape == (batch_size, seq_len, vocab_size)
predictions, attention_weights = transformer(encoder_input,
output,
False,
enc_padding_mask,
combined_mask,
dec_padding_mask)
# select the last word from the seq_len dimension
predictions = predictions[:, -1:, :] # (batch_size, 1, vocab_size)
predicted_id = tf.argmax(predictions, axis=-1)
# concatentate the predicted_id to the output which is given to the decoder
# as its input.
output = tf.concat([output, predicted_id], axis=-1)
# return the result if the predicted_id is equal to the end token
if predicted_id == end:
break
# output.shape (1, tokens)
text = tokenizers.en.detokenize(output)[0] # shape: ()
tokens = tokenizers.en.lookup(output)[0]
return text, tokens, attention_weights
def print_translation(sentence, tokens, ground_truth):
print(f'{"Input:":15s}: {sentence}')
print(f'{"Prediction":15s}: {tokens.numpy().decode("utf-8")}')
print(f'{"Ground truth":15s}: {ground_truth}')
sentence = "este é um problema que temos que resolver."
ground_truth = "this is a problem we have to solve ."
translated_text, translated_tokens, attention_weights = evaluate(sentence)
print_translation(sentence, translated_text, ground_truth)
Input: : este é um problema que temos que resolver. Prediction : this is a problem that we have to solve . Ground truth : this is a problem we have to solve .
sentence = "os meus vizinhos ouviram sobre esta ideia."
ground_truth = "and my neighboring homes heard about this idea ."
translated_text, translated_tokens, attention_weights = evaluate(sentence)
print_translation(sentence, translated_text, ground_truth)
Input: : os meus vizinhos ouviram sobre esta ideia. Prediction : my neighbors heard about this idea . Ground truth : and my neighboring homes heard about this idea .
sentence = "vou então muito rapidamente partilhar convosco algumas histórias de algumas coisas mágicas que aconteceram."
ground_truth = "so i \'ll just share with you some stories very quickly of some magical things that have happened ."
translated_text, translated_tokens, attention_weights = evaluate(sentence)
print_translation(sentence, translated_text, ground_truth)
Input: : vou então muito rapidamente partilhar convosco algumas histórias de algumas coisas mágicas que aconteceram. Prediction : so i ' m very quickly to share with you some magic stories that happened . Ground truth : so i 'll just share with you some stories very quickly of some magical things that have happened .
אתה יכול להעביר שכבות שונות וגושי תשומת לב של המפענח לפרמטר plot
.
עלילות תשומת לב
פונקציית evaluate
מחזירה גם מילון של מפות קשב בהן תוכלו להשתמש בכדי לדמיין את העבודה הפנימית של המודל:
sentence = "este é o primeiro livro que eu fiz."
ground_truth = "this is the first book i've ever done."
translated_text, translated_tokens, attention_weights = evaluate(sentence)
print_translation(sentence, translated_text, ground_truth)
Input: : este é o primeiro livro que eu fiz. Prediction : this is the first book i did . Ground truth : this is the first book i've ever done.
def plot_attention_head(in_tokens, translated_tokens, attention):
# The plot is of the attention when a token was generated.
# The model didn't generate `<START>` in the output. Skip it.
translated_tokens = translated_tokens[1:]
ax = plt.gca()
ax.matshow(attention)
ax.set_xticks(range(len(in_tokens)))
ax.set_yticks(range(len(translated_tokens)))
labels = [label.decode('utf-8') for label in in_tokens.numpy()]
ax.set_xticklabels(
labels, rotation=90)
labels = [label.decode('utf-8') for label in translated_tokens.numpy()]
ax.set_yticklabels(labels)
head = 0
# shape: (batch=1, num_heads, seq_len_q, seq_len_k)
attention_heads = tf.squeeze(
attention_weights['decoder_layer4_block2'], 0)
attention = attention_heads[head]
attention.shape
TensorShape([9, 11])
in_tokens = tf.convert_to_tensor([sentence])
in_tokens = tokenizers.pt.tokenize(in_tokens).to_tensor()
in_tokens = tokenizers.pt.lookup(in_tokens)[0]
in_tokens
<tf.Tensor: shape=(11,), dtype=string, numpy= array([b'[START]', b'este', b'e', b'o', b'primeiro', b'livro', b'que', b'eu', b'fiz', b'.', b'[END]'], dtype=object)>
translated_tokens
<tf.Tensor: shape=(10,), dtype=string, numpy= array([b'[START]', b'this', b'is', b'the', b'first', b'book', b'i', b'did', b'.', b'[END]'], dtype=object)>
plot_attention_head(in_tokens, translated_tokens, attention)
def plot_attention_weights(sentence, translated_tokens, attention_heads):
in_tokens = tf.convert_to_tensor([sentence])
in_tokens = tokenizers.pt.tokenize(in_tokens).to_tensor()
in_tokens = tokenizers.pt.lookup(in_tokens)[0]
in_tokens
fig = plt.figure(figsize=(16, 8))
for h, head in enumerate(attention_heads):
ax = fig.add_subplot(2, 4, h+1)
plot_attention_head(in_tokens, translated_tokens, head)
ax.set_xlabel(f'Head {h+1}')
plt.tight_layout()
plt.show()
plot_attention_weights(sentence, translated_tokens,
attention_weights['decoder_layer4_block2'][0])
המודל מסתדר במילים לא מוכרות. לא "טריצרטופס" או "אנציקלופדיה" נמצאים במערך הקלט והמודל כמעט לומד לתעתק אותם, אפילו ללא אוצר מילים משותף:
sentence = "Eu li sobre triceratops na enciclopédia."
ground_truth = "I read about triceratops in the encyclopedia."
translated_text, translated_tokens, attention_weights = evaluate(sentence)
print_translation(sentence, translated_text, ground_truth)
plot_attention_weights(sentence, translated_tokens,
attention_weights['decoder_layer4_block2'][0])
Input: : Eu li sobre triceratops na enciclopédia. Prediction : i read about tribrushes in encyclopedia . Ground truth : I read about triceratops in the encyclopedia.
סיכום
במדריך זה למדת על קידוד מיקום, תשומת לב מרובת ראשים, חשיבות המסכה וכיצד ליצור שנאי.
נסה להשתמש במערך נתונים אחר כדי לאמן את השנאי. ניתן גם ליצור את שנאי הבסיס או השנאי XL על ידי שינוי ההיפרפרמטרים שלמעלה. אתה יכול גם להשתמש בשכבות המוגדרות כאן כדי ליצור BERT ולהכשיר מודלים חדישים. יתר על כן, אתה יכול ליישם חיפוש קרן כדי לקבל תחזיות טובות יותר.