सहायता Kaggle पर TensorFlow साथ ग्रेट बैरियर रीफ की रक्षा चैलेंज में शामिल हों

भाषा की समझ के लिए ट्रांसफार्मर मॉडल

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखेंनोटबुक डाउनलोड करें

इस ट्यूटोरियल गाड़ियों एक ट्रांसफार्मर मॉडल एक अनुवाद करने के लिए पुर्तगाली अंग्रेजी को डाटासेट । यह एक उन्नत उदाहरण इस बात का ज्ञान हो जाती है पाठ पीढ़ी और ध्यान

ट्रांसफार्मर मॉडल के पीछे मूल विचार आत्म ध्यान कि अनुक्रम का प्रतिनिधित्व गणना करने के लिए इनपुट अनुक्रम के विभिन्न पदों के लिए भाग लेने के लिए -इस क्षमता है। ट्रांसफार्मर आत्म ध्यान परतों के ढेर बनाता है और वर्गों डॉट उत्पाद ध्यान और बहु सिर ध्यान स्केल्ड में नीचे समझाया गया है।

एक ट्रांसफॉर्मर मॉडल हैंडल चर आकार इनपुट के बजाय आत्म ध्यान परतों के ढेर का उपयोग कर RNNs या CNNs । इस सामान्य वास्तुकला के कई फायदे हैं:

  • यह डेटा भर में अस्थायी/स्थानिक संबंधों के बारे में कोई धारणा नहीं बनाता है। यह वस्तुओं का एक सेट (उदाहरण के लिए, प्रसंस्करण के लिए आदर्श है StarCraft इकाइयों )।
  • परत आउटपुट की गणना RNN जैसी श्रृंखला के बजाय समानांतर में की जा सकती है।
  • दूर आइटम कई RNN-कदम, या घुमाव के परतों (देखें के माध्यम से गुजर बिना एक दूसरे के उत्पादन को प्रभावित कर सकते दृश्य मेमोरी ट्रांसफार्मर उदाहरण के लिए)।
  • यह लंबी दूरी की निर्भरता सीख सकता है। यह कई अनुक्रम कार्यों में एक चुनौती है।

इस वास्तुकला के नुकसान हैं:

  • एक समय श्रृंखला के लिए, एक समय कदम के लिए उत्पादन केवल इनपुट और वर्तमान छिपा राज्य के बजाय पूरे इतिहास से की जाती है। यह कम कुशल हो सकता है।
  • इनपुट है एक अस्थायी / स्थानिक संबंध, पाठ की तरह, कुछ स्थितीय एन्कोडिंग जोड़ा जाना चाहिए करता है या तो मॉडल को प्रभावी ढंग से शब्दों का एक बैग देखेंगे।

इस नोटबुक में मॉडल को प्रशिक्षित करने के बाद, आप एक पुर्तगाली वाक्य दर्ज करने और अंग्रेजी अनुवाद वापस करने में सक्षम होंगे।

ध्यान हीटमैप

सेट अप

pip install tensorflow_datasets
pip install -U 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 Talks ओपन अनुवाद परियोजना

इस डेटासेट में लगभग 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 ट्यूटोरियल subword tokenizers (बनाता text.BertTokenizer ) इस डेटासेट और उन्हें एक में निर्यात के लिए अनुकूलित saved_model

डाउनलोड करें और unzip और आयात 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
196608/184801 [===============================] - 0s 0us/step
'./ted_hrlr_translate_pt_en_converter.zip'
tokenizers = tf.saved_model.load(model_name)

tf.saved_model दो पाठ tokenizers, अंग्रेजी के लिए एक और पुर्तगाली के लिए एक में शामिल है। दोनों के तरीके समान हैं:

[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 विधि टोकन आईडी की एक गद्देदार बैच के लिए तार का एक बैच बदल देता है। यह विधि विराम चिह्न, लोअरकेस और यूनिकोड को विभाजित करती है-टोकन करने से पहले इनपुट को सामान्य करती है। वह मानकीकरण यहां दिखाई नहीं दे रहा है क्योंकि इनपुट डेटा पहले से ही मानकीकृत है।

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]']]>

यहां आप टोकननाइज़र के "सबवर्ड" पहलू को देख सकते हैं। शब्द "खोज योग्यता" "खोज ## क्षमता" में और "सीरेन्डिपिटी" शब्द "एस ##ere ##nd ##ip ##ity" में विघटित हो गया है।

सेटअप इनपुट पाइपलाइन

प्रशिक्षण के लिए उपयुक्त इनपुट पाइपलाइन बनाने के लिए आप डेटासेट में कुछ परिवर्तन लागू करेंगे।

इस फ़ंक्शन का उपयोग कच्चे पाठ के बैचों को एन्कोड करने के लिए किया जाएगा:

def tokenize_pairs(pt, en):
    pt = tokenizers.pt.tokenize(pt)
    # Convert from ragged to dense, padding with zeros.
    pt = pt.to_tensor()

    en = tokenizers.en.tokenize(en)
    # Convert from ragged to dense, padding with zeros.
    en = en.to_tensor()
    return pt, en

यहां एक सरल इनपुट पाइपलाइन है जो डेटा को प्रोसेस, फेरबदल और बैच करती है:

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)

स्थितीय एन्कोडिंग

ध्यान परतें अपने इनपुट को बिना किसी अनुक्रमिक क्रम के वैक्टर के एक सेट के रूप में देखती हैं। इस मॉडल में कोई आवर्तक या दृढ़ परत भी नहीं है। इस वजह से मॉडल को वाक्य में टोकन की सापेक्ष स्थिति के बारे में कुछ जानकारी देने के लिए "स्थितिगत एन्कोडिंग" जोड़ा जाता है।

पोजिशनल एन्कोडिंग वेक्टर को एम्बेडिंग वेक्टर में जोड़ा जाता है। एंबेडिंग एक डी-डायमेंशनल स्पेस में एक टोकन का प्रतिनिधित्व करते हैं जहां समान अर्थ वाले टोकन एक दूसरे के करीब होंगे। लेकिन एम्बेडिंग एक वाक्य में टोकन की सापेक्ष स्थिति को एन्कोड नहीं करते हैं। तो स्थितीय एन्कोडिंग को जोड़ने के बाद, टोकन उनके अर्थ और वाक्य में अपनी स्थिति, घ आयामी अंतरिक्ष में की समानता के आधार पर एक दूसरे के करीब हो जाएगा।

स्थितीय एन्कोडिंग की गणना के लिए सूत्र इस प्रकार है:

\[\Large{PE_{(pos, 2i)} = \sin(pos / 10000^{2i / d_{model} })} \]

\[\Large{PE_{(pos, 2i+1)} = \cos(pos / 10000^{2i / d_{model} })} \]

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

स्केल किए गए डॉट उत्पाद ध्यान

स्केल्ड_डॉट_प्रोडक्ट_ध्यान

ट्रांसफार्मर द्वारा उपयोग किया जाने वाला ध्यान कार्य तीन इनपुट लेता है: क्यू (क्वेरी), के (कुंजी), वी (मान)। ध्यान भार की गणना के लिए प्रयुक्त समीकरण है:

\[\Large{Attention(Q, K, V) = softmax_k\left(\frac{QK^T}{\sqrt{d_k} }\right) V} \]

डॉट-उत्पाद का ध्यान गहराई के वर्गमूल के कारक द्वारा बढ़ाया जाता है। ऐसा इसलिए किया जाता है क्योंकि गहराई के बड़े मूल्यों के लिए, डॉट उत्पाद सॉफ्टमैक्स फ़ंक्शन को धक्का देकर परिमाण में बड़ा हो जाता है, जहां इसमें छोटे ग्रेडिएंट होते हैं जिसके परिणामस्वरूप बहुत कठोर सॉफ्टमैक्स होता है।

उदाहरण के लिए, विचार है कि Q और K 0 और की 1. उनके आव्यूह गुणन विचरण का एक मतलब है 0 और विचरण एक मतलब होगा dk । तो का वर्गमूल dk , स्केलिंग के लिए इस्तेमाल किया है ताकि आप एक सुसंगत विचरण के मूल्य की परवाह किए बिना प्राप्त है dk । यदि विचरण बहुत कम है तो आउटपुट प्रभावी ढंग से अनुकूलित करने के लिए बहुत सपाट हो सकता है। यदि विचरण बहुत अधिक है तो सॉफ्टमैक्स आरंभीकरण पर संतृप्त हो सकता है जिससे इसे सीखना मुश्किल हो जाता है।

मास्क को -1e9 (नकारात्मक अनंत के करीब) से गुणा किया जाता है। ऐसा इसलिए किया जाता है क्योंकि मास्क को Q और K के स्केल्ड मैट्रिक्स गुणन के साथ अभिव्यक्त किया जाता है और इसे सॉफ्टमैक्स से ठीक पहले लगाया जाता है। लक्ष्य इन कोशिकाओं को शून्य करना है, और सॉफ्टमैक्स के बड़े नकारात्मक इनपुट आउटपुट में शून्य के करीब हैं।

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

जैसा कि K पर सॉफ्टमैक्स सामान्यीकरण किया जाता है, इसके मान Q को दिए गए महत्व की मात्रा तय करते हैं।

आउटपुट ध्यान भार और वी (मान) वेक्टर के गुणन का प्रतिनिधित्व करता है। यह सुनिश्चित करता है कि जिन टोकन पर आप ध्यान केंद्रित करना चाहते हैं, उन्हें यथावत रखा गया है और अप्रासंगिक टोकन हटा दिए गए हैं।

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)

बहु-सिर ध्यान

बहु-सिर ध्यान

बहु-सिर ध्यान में चार भाग होते हैं:

  • रैखिक परतें।
  • स्केल किए गए डॉट-उत्पाद ध्यान।
  • अंतिम रैखिक परत।

प्रत्येक मल्टी-हेड अटेंशन ब्लॉक को तीन इनपुट मिलते हैं; क्यू (क्वेरी), के (कुंजी), वी (मान)। इन्हें मल्टी-हेड अटेंशन फंक्शन से पहले रैखिक (घने) परतों के माध्यम से रखा जाता है।

ऊपर चित्र में (K,Q,V) sepearte रैखिक (के माध्यम से पारित कर रहे हैं Dense प्रत्येक ध्यान सिर के लिए) परतों। सादगी / दक्षता के लिए लागू नीचे कोड इस के साथ एक एकल घने परत का उपयोग num_heads कई आउटपुट के रूप में कई बार। उत्पादन का एक आकार के पुन: व्यवस्थित किया जाता है (batch, num_heads, ...) ध्यान समारोह लागू करने से पहले।

scaled_dot_product_attention समारोह ऊपर परिभाषित एक कॉल में लागू किया, दक्षता के लिए प्रसारित किया जाता है। अटेंशन स्टेप में एक उपयुक्त मास्क का उपयोग किया जाना चाहिए। प्रत्येक सिर के लिए ध्यान उत्पादन तो concatenated है (का उपयोग कर tf.transpose , और tf.reshape ) और एक अंतिम के माध्यम से डाल Dense परत।

एक एकल ध्यान शीर्ष के बजाय, क्यू, के, और वी को कई शीर्षों में विभाजित किया जाता है क्योंकि यह मॉडल को विभिन्न पदों पर विभिन्न प्रतिनिधित्व उप-स्थानों से संयुक्त रूप से जानकारी में शामिल होने की अनुमति देता है। विभाजन के बाद प्रत्येक सिर में कम आयामीता होती है, इसलिए कुल गणना लागत पूर्ण आयामीता के साथ एकल सिर के ध्यान के समान होती है।

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 एनकोडर परतों कि क्रम में प्रत्येक टोकन के लिए एक आउटपुट उत्पन्न करता है।
  • अगले शब्द की भविष्यवाणी करने के लिए डिकोडर एन्कोडर के आउटपुट और अपने स्वयं के इनपुट (आत्म-ध्यान) में भाग लेता है।

एनकोडर परत

प्रत्येक एन्कोडर परत में सबलेयर होते हैं:

  1. मल्टी-हेड अटेंशन (पैडिंग मास्क के साथ)
  2. प्वाइंट वाइज फीड फॉरवर्ड नेटवर्क।

इन सबलेयर्स में से प्रत्येक के पास एक परत सामान्यीकरण के बाद इसके चारों ओर एक अवशिष्ट कनेक्शन होता है। अवशिष्ट कनेक्शन गहरे नेटवर्क में लुप्त हो रही ढाल की समस्या से बचने में मदद करते हैं।

प्रत्येक उप-परत के उत्पादन में है LayerNorm(x + Sublayer(x)) सामान्य पर किया जाता है d_model (अंतिम) अक्ष। ट्रांसफार्मर में एन एनकोडर परतें होती हैं।

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

डिकोडर परत

प्रत्येक डिकोडर परत में सबलेयर होते हैं:

  1. नकाबपोश बहु-सिर ध्यान (आगे की ओर मुखौटा और पैडिंग मास्क के साथ)
  2. मल्टी-हेड अटेंशन (पैडिंग मास्क के साथ)। वी (मान) और कश्मीर (कुंजी) इनपुट के रूप में एनकोडर उत्पादन प्राप्त करते हैं। क्यू (क्वेरी) नकाबपोश बहु सिर ध्यान उप-परत से उत्पादन प्राप्त करता है।
  3. पॉइंट वाइज फीड फॉरवर्ड नेटवर्क

इन सबलेयर्स में से प्रत्येक के पास एक परत सामान्यीकरण के बाद इसके चारों ओर एक अवशिष्ट कनेक्शन होता है। प्रत्येक उप-परत के उत्पादन में है LayerNorm(x + Sublayer(x)) सामान्य पर किया जाता है d_model (अंतिम) अक्ष।

ट्रांसफार्मर में एन डिकोडर परतें होती हैं।

चूंकि क्यू डिकोडर के पहले ध्यान ब्लॉक से आउटपुट प्राप्त करता है, और के एन्कोडर आउटपुट प्राप्त करता है, ध्यान भार एन्कोडर के आउटपुट के आधार पर डिकोडर के इनपुट को दिए गए महत्व का प्रतिनिधित्व करता है। दूसरे शब्दों में, डिकोडर एन्कोडर आउटपुट को देखकर और अपने स्वयं के आउटपुट में स्वयं उपस्थित होकर अगले टोकन की भविष्यवाणी करता है। ऊपर दिए गए प्रदर्शन को स्केल किए गए डॉट उत्पाद ध्यान अनुभाग में देखें।

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 के होते हैं:

  1. इनपुट एम्बेडिंग
  2. स्थितीय एन्कोडिंग
  3. एन एनकोडर परतें

इनपुट को एक एम्बेडिंग के माध्यम से रखा जाता है जिसे स्थितीय एन्कोडिंग के साथ अभिव्यक्त किया जाता है। इस योग का आउटपुट एन्कोडर परतों का इनपुट है। एनकोडर का आउटपुट डिकोडर का इनपुट होता है।

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 के होते हैं:

  1. आउटपुट एम्बेडिंग
  2. स्थितीय एन्कोडिंग
  3. एन डिकोडर परतें

लक्ष्य को एक एम्बेडिंग के माध्यम से रखा जाता है जिसे स्थितीय एन्कोडिंग के साथ अभिव्यक्त किया जाता है। इस योग का आउटपुट डिकोडर परतों का इनपुट है। डिकोडर का आउटपुट अंतिम रैखिक परत का इनपुट है।

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().__init__()
    self.encoder = 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, inputs, training):
    # Keras models prefer if you pass all your inputs in the first argument
    inp, tar = inputs

    enc_padding_mask, look_ahead_mask, dec_padding_mask = self.create_masks(inp, tar)

    enc_output = self.encoder(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

  def create_masks(self, 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)
    look_ahead_mask = tf.maximum(dec_target_padding_mask, look_ahead_mask)

    return enc_padding_mask, look_ahead_mask, dec_padding_mask
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)

fn_out.shape  # (batch_size, tar_seq_len, target_vocab_size)
TensorShape([64, 36, 8000])

हाइपरपैरामीटर सेट करें

इस उदाहरण छोटे रखने के लिए और अपेक्षाकृत तेजी से, के लिए मूल्यों num_layers, d_model, dff कम हो गई है।

बेस मॉडल में वर्णित कागज का प्रयोग किया: num_layers=6, d_model=512, dff=2048

num_layers = 4
d_model = 128
dff = 512
num_heads = 8
dropout_rate = 0.1

अनुकूलक

में सूत्र के अनुसार एक कस्टम सीखने दर अनुसूचक के साथ एडम अनुकूलक का उपयोग कागज

\[\Large{lrate = d_{model}^{-0.5} * \min(step{\_}num^{-0.5}, step{\_}num \cdot warmup{\_}steps^{-1.5})}\]

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().numpy(),
    target_vocab_size=tokenizers.en.get_vocab_size().numpy(),
    pe_input=1000,
    pe_target=1000,
    rate=dropout_rate)

चेकपॉइंट पथ और चेकपॉइंट मैनेजर बनाएं। इस चौकियों हर बचाने के लिए इस्तेमाल किया जाएगा 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 = "जंगल में एसओएस एक शेर EOS सो रहा है"

tar_inp = "जंगल में एसओएस एक शेर सो रहा है"

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:]

  with tf.GradientTape() as tape:
    predictions, _ = transformer([inp, tar_inp],
                                 training = True)
    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.8389 Accuracy 0.0000
Epoch 1 Batch 50 Loss 8.7850 Accuracy 0.0015
Epoch 1 Batch 100 Loss 8.6954 Accuracy 0.0258
Epoch 1 Batch 150 Loss 8.5875 Accuracy 0.0361
Epoch 1 Batch 200 Loss 8.4497 Accuracy 0.0396
Epoch 1 Batch 250 Loss 8.2832 Accuracy 0.0412
Epoch 1 Batch 300 Loss 8.0957 Accuracy 0.0424
Epoch 1 Batch 350 Loss 7.9001 Accuracy 0.0462
Epoch 1 Batch 400 Loss 7.7106 Accuracy 0.0530
Epoch 1 Batch 450 Loss 7.5449 Accuracy 0.0608
Epoch 1 Batch 500 Loss 7.3965 Accuracy 0.0686
Epoch 1 Batch 550 Loss 7.2629 Accuracy 0.0764
Epoch 1 Batch 600 Loss 7.1374 Accuracy 0.0841
Epoch 1 Batch 650 Loss 7.0225 Accuracy 0.0915
Epoch 1 Batch 700 Loss 6.9148 Accuracy 0.0987
Epoch 1 Batch 750 Loss 6.8137 Accuracy 0.1055
Epoch 1 Batch 800 Loss 6.7228 Accuracy 0.1115
Epoch 1 Loss 6.7072 Accuracy 0.1126
Time taken for 1 epoch: 62.48 secs

Epoch 2 Batch 0 Loss 5.3320 Accuracy 0.2099
Epoch 2 Batch 50 Loss 5.2248 Accuracy 0.2119
Epoch 2 Batch 100 Loss 5.1947 Accuracy 0.2152
Epoch 2 Batch 150 Loss 5.1643 Accuracy 0.2191
Epoch 2 Batch 200 Loss 5.1383 Accuracy 0.2224
Epoch 2 Batch 250 Loss 5.1123 Accuracy 0.2254
Epoch 2 Batch 300 Loss 5.0864 Accuracy 0.2277
Epoch 2 Batch 350 Loss 5.0697 Accuracy 0.2291
Epoch 2 Batch 400 Loss 5.0487 Accuracy 0.2313
Epoch 2 Batch 450 Loss 5.0272 Accuracy 0.2331
Epoch 2 Batch 500 Loss 5.0060 Accuracy 0.2349
Epoch 2 Batch 550 Loss 4.9882 Accuracy 0.2365
Epoch 2 Batch 600 Loss 4.9677 Accuracy 0.2382
Epoch 2 Batch 650 Loss 4.9496 Accuracy 0.2400
Epoch 2 Batch 700 Loss 4.9314 Accuracy 0.2417
Epoch 2 Batch 750 Loss 4.9172 Accuracy 0.2429
Epoch 2 Batch 800 Loss 4.9005 Accuracy 0.2444
Epoch 2 Loss 4.8976 Accuracy 0.2447
Time taken for 1 epoch: 47.81 secs

Epoch 3 Batch 0 Loss 4.7853 Accuracy 0.2318
Epoch 3 Batch 50 Loss 4.6041 Accuracy 0.2673
Epoch 3 Batch 100 Loss 4.5869 Accuracy 0.2693
Epoch 3 Batch 150 Loss 4.5681 Accuracy 0.2723
Epoch 3 Batch 200 Loss 4.5502 Accuracy 0.2748
Epoch 3 Batch 250 Loss 4.5433 Accuracy 0.2755
Epoch 3 Batch 300 Loss 4.5279 Accuracy 0.2771
Epoch 3 Batch 350 Loss 4.5123 Accuracy 0.2792
Epoch 3 Batch 400 Loss 4.5001 Accuracy 0.2807
Epoch 3 Batch 450 Loss 4.4849 Accuracy 0.2825
Epoch 3 Batch 500 Loss 4.4699 Accuracy 0.2842
Epoch 3 Batch 550 Loss 4.4543 Accuracy 0.2861
Epoch 3 Batch 600 Loss 4.4397 Accuracy 0.2879
Epoch 3 Batch 650 Loss 4.4260 Accuracy 0.2896
Epoch 3 Batch 700 Loss 4.4098 Accuracy 0.2918
Epoch 3 Batch 750 Loss 4.3934 Accuracy 0.2938
Epoch 3 Batch 800 Loss 4.3774 Accuracy 0.2958
Epoch 3 Loss 4.3743 Accuracy 0.2961
Time taken for 1 epoch: 47.78 secs

Epoch 4 Batch 0 Loss 4.1607 Accuracy 0.3198
Epoch 4 Batch 50 Loss 4.0206 Accuracy 0.3366
Epoch 4 Batch 100 Loss 4.0181 Accuracy 0.3379
Epoch 4 Batch 150 Loss 4.0005 Accuracy 0.3390
Epoch 4 Batch 200 Loss 3.9809 Accuracy 0.3420
Epoch 4 Batch 250 Loss 3.9716 Accuracy 0.3436
Epoch 4 Batch 300 Loss 3.9561 Accuracy 0.3453
Epoch 4 Batch 350 Loss 3.9396 Accuracy 0.3476
Epoch 4 Batch 400 Loss 3.9287 Accuracy 0.3492
Epoch 4 Batch 450 Loss 3.9099 Accuracy 0.3516
Epoch 4 Batch 500 Loss 3.8948 Accuracy 0.3534
Epoch 4 Batch 550 Loss 3.8796 Accuracy 0.3554
Epoch 4 Batch 600 Loss 3.8647 Accuracy 0.3573
Epoch 4 Batch 650 Loss 3.8496 Accuracy 0.3593
Epoch 4 Batch 700 Loss 3.8345 Accuracy 0.3613
Epoch 4 Batch 750 Loss 3.8216 Accuracy 0.3631
Epoch 4 Batch 800 Loss 3.8113 Accuracy 0.3645
Epoch 4 Loss 3.8084 Accuracy 0.3649
Time taken for 1 epoch: 47.74 secs

Epoch 5 Batch 0 Loss 3.7892 Accuracy 0.3515
Epoch 5 Batch 50 Loss 3.5277 Accuracy 0.3971
Epoch 5 Batch 100 Loss 3.4909 Accuracy 0.4026
Epoch 5 Batch 150 Loss 3.4709 Accuracy 0.4059
Epoch 5 Batch 200 Loss 3.4637 Accuracy 0.4068
Epoch 5 Batch 250 Loss 3.4614 Accuracy 0.4071
Epoch 5 Batch 300 Loss 3.4471 Accuracy 0.4093
Epoch 5 Batch 350 Loss 3.4360 Accuracy 0.4102
Epoch 5 Batch 400 Loss 3.4277 Accuracy 0.4112
Epoch 5 Batch 450 Loss 3.4186 Accuracy 0.4124
Epoch 5 Batch 500 Loss 3.4127 Accuracy 0.4133
Epoch 5 Batch 550 Loss 3.4023 Accuracy 0.4145
Epoch 5 Batch 600 Loss 3.3931 Accuracy 0.4154
Epoch 5 Batch 650 Loss 3.3821 Accuracy 0.4169
Epoch 5 Batch 700 Loss 3.3719 Accuracy 0.4183
Epoch 5 Batch 750 Loss 3.3632 Accuracy 0.4195
Epoch 5 Batch 800 Loss 3.3550 Accuracy 0.4205
Saving checkpoint for epoch 5 at ./checkpoints/train/ckpt-1
Epoch 5 Loss 3.3540 Accuracy 0.4206
Time taken for 1 epoch: 47.47 secs

Epoch 6 Batch 0 Loss 3.5078 Accuracy 0.3912
Epoch 6 Batch 50 Loss 3.1028 Accuracy 0.4487
Epoch 6 Batch 100 Loss 3.0855 Accuracy 0.4503
Epoch 6 Batch 150 Loss 3.0784 Accuracy 0.4515
Epoch 6 Batch 200 Loss 3.0664 Accuracy 0.4534
Epoch 6 Batch 250 Loss 3.0621 Accuracy 0.4537
Epoch 6 Batch 300 Loss 3.0512 Accuracy 0.4556
Epoch 6 Batch 350 Loss 3.0368 Accuracy 0.4580
Epoch 6 Batch 400 Loss 3.0283 Accuracy 0.4592
Epoch 6 Batch 450 Loss 3.0176 Accuracy 0.4608
Epoch 6 Batch 500 Loss 3.0083 Accuracy 0.4623
Epoch 6 Batch 550 Loss 2.9966 Accuracy 0.4639
Epoch 6 Batch 600 Loss 2.9871 Accuracy 0.4652
Epoch 6 Batch 650 Loss 2.9777 Accuracy 0.4664
Epoch 6 Batch 700 Loss 2.9722 Accuracy 0.4673
Epoch 6 Batch 750 Loss 2.9650 Accuracy 0.4684
Epoch 6 Batch 800 Loss 2.9562 Accuracy 0.4697
Epoch 6 Loss 2.9548 Accuracy 0.4698
Time taken for 1 epoch: 47.10 secs

Epoch 7 Batch 0 Loss 2.7935 Accuracy 0.4985
Epoch 7 Batch 50 Loss 2.6880 Accuracy 0.5017
Epoch 7 Batch 100 Loss 2.6676 Accuracy 0.5053
Epoch 7 Batch 150 Loss 2.6658 Accuracy 0.5062
Epoch 7 Batch 200 Loss 2.6631 Accuracy 0.5068
Epoch 7 Batch 250 Loss 2.6634 Accuracy 0.5069
Epoch 7 Batch 300 Loss 2.6575 Accuracy 0.5078
Epoch 7 Batch 350 Loss 2.6485 Accuracy 0.5088
Epoch 7 Batch 400 Loss 2.6472 Accuracy 0.5092
Epoch 7 Batch 450 Loss 2.6432 Accuracy 0.5097
Epoch 7 Batch 500 Loss 2.6398 Accuracy 0.5103
Epoch 7 Batch 550 Loss 2.6372 Accuracy 0.5111
Epoch 7 Batch 600 Loss 2.6340 Accuracy 0.5115
Epoch 7 Batch 650 Loss 2.6292 Accuracy 0.5123
Epoch 7 Batch 700 Loss 2.6266 Accuracy 0.5127
Epoch 7 Batch 750 Loss 2.6253 Accuracy 0.5129
Epoch 7 Batch 800 Loss 2.6217 Accuracy 0.5134
Epoch 7 Loss 2.6215 Accuracy 0.5134
Time taken for 1 epoch: 47.31 secs

Epoch 8 Batch 0 Loss 2.5891 Accuracy 0.5090
Epoch 8 Batch 50 Loss 2.4158 Accuracy 0.5395
Epoch 8 Batch 100 Loss 2.4099 Accuracy 0.5399
Epoch 8 Batch 150 Loss 2.4026 Accuracy 0.5408
Epoch 8 Batch 200 Loss 2.4023 Accuracy 0.5409
Epoch 8 Batch 250 Loss 2.4053 Accuracy 0.5404
Epoch 8 Batch 300 Loss 2.4085 Accuracy 0.5395
Epoch 8 Batch 350 Loss 2.4022 Accuracy 0.5406
Epoch 8 Batch 400 Loss 2.4031 Accuracy 0.5409
Epoch 8 Batch 450 Loss 2.3993 Accuracy 0.5416
Epoch 8 Batch 500 Loss 2.3970 Accuracy 0.5421
Epoch 8 Batch 550 Loss 2.3945 Accuracy 0.5429
Epoch 8 Batch 600 Loss 2.3908 Accuracy 0.5433
Epoch 8 Batch 650 Loss 2.3884 Accuracy 0.5439
Epoch 8 Batch 700 Loss 2.3864 Accuracy 0.5443
Epoch 8 Batch 750 Loss 2.3860 Accuracy 0.5443
Epoch 8 Batch 800 Loss 2.3829 Accuracy 0.5448
Epoch 8 Loss 2.3815 Accuracy 0.5450
Time taken for 1 epoch: 47.15 secs

Epoch 9 Batch 0 Loss 2.4162 Accuracy 0.5382
Epoch 9 Batch 50 Loss 2.2300 Accuracy 0.5635
Epoch 9 Batch 100 Loss 2.2048 Accuracy 0.5665
Epoch 9 Batch 150 Loss 2.2009 Accuracy 0.5681
Epoch 9 Batch 200 Loss 2.2006 Accuracy 0.5687
Epoch 9 Batch 250 Loss 2.2034 Accuracy 0.5682
Epoch 9 Batch 300 Loss 2.1974 Accuracy 0.5690
Epoch 9 Batch 350 Loss 2.2068 Accuracy 0.5678
Epoch 9 Batch 400 Loss 2.2058 Accuracy 0.5682
Epoch 9 Batch 450 Loss 2.2109 Accuracy 0.5677
Epoch 9 Batch 500 Loss 2.2112 Accuracy 0.5676
Epoch 9 Batch 550 Loss 2.2080 Accuracy 0.5685
Epoch 9 Batch 600 Loss 2.2106 Accuracy 0.5680
Epoch 9 Batch 650 Loss 2.2084 Accuracy 0.5684
Epoch 9 Batch 700 Loss 2.2082 Accuracy 0.5686
Epoch 9 Batch 750 Loss 2.2089 Accuracy 0.5685
Epoch 9 Batch 800 Loss 2.2084 Accuracy 0.5687
Epoch 9 Loss 2.2083 Accuracy 0.5686
Time taken for 1 epoch: 46.95 secs

Epoch 10 Batch 0 Loss 2.2234 Accuracy 0.5604
Epoch 10 Batch 50 Loss 2.1030 Accuracy 0.5814
Epoch 10 Batch 100 Loss 2.0774 Accuracy 0.5866
Epoch 10 Batch 150 Loss 2.0655 Accuracy 0.5881
Epoch 10 Batch 200 Loss 2.0661 Accuracy 0.5880
Epoch 10 Batch 250 Loss 2.0635 Accuracy 0.5883
Epoch 10 Batch 300 Loss 2.0616 Accuracy 0.5888
Epoch 10 Batch 350 Loss 2.0636 Accuracy 0.5886
Epoch 10 Batch 400 Loss 2.0621 Accuracy 0.5888
Epoch 10 Batch 450 Loss 2.0670 Accuracy 0.5878
Epoch 10 Batch 500 Loss 2.0652 Accuracy 0.5880
Epoch 10 Batch 550 Loss 2.0686 Accuracy 0.5875
Epoch 10 Batch 600 Loss 2.0692 Accuracy 0.5875
Epoch 10 Batch 650 Loss 2.0691 Accuracy 0.5876
Epoch 10 Batch 700 Loss 2.0707 Accuracy 0.5876
Epoch 10 Batch 750 Loss 2.0704 Accuracy 0.5878
Epoch 10 Batch 800 Loss 2.0722 Accuracy 0.5876
Saving checkpoint for epoch 10 at ./checkpoints/train/ckpt-2
Epoch 10 Loss 2.0715 Accuracy 0.5879
Time taken for 1 epoch: 47.13 secs

Epoch 11 Batch 0 Loss 1.9391 Accuracy 0.6270
Epoch 11 Batch 50 Loss 1.9758 Accuracy 0.5977
Epoch 11 Batch 100 Loss 1.9564 Accuracy 0.6024
Epoch 11 Batch 150 Loss 1.9526 Accuracy 0.6037
Epoch 11 Batch 200 Loss 1.9573 Accuracy 0.6030
Epoch 11 Batch 250 Loss 1.9471 Accuracy 0.6048
Epoch 11 Batch 300 Loss 1.9459 Accuracy 0.6048
Epoch 11 Batch 350 Loss 1.9490 Accuracy 0.6042
Epoch 11 Batch 400 Loss 1.9518 Accuracy 0.6040
Epoch 11 Batch 450 Loss 1.9549 Accuracy 0.6038
Epoch 11 Batch 500 Loss 1.9543 Accuracy 0.6040
Epoch 11 Batch 550 Loss 1.9537 Accuracy 0.6043
Epoch 11 Batch 600 Loss 1.9546 Accuracy 0.6042
Epoch 11 Batch 650 Loss 1.9556 Accuracy 0.6040
Epoch 11 Batch 700 Loss 1.9582 Accuracy 0.6038
Epoch 11 Batch 750 Loss 1.9592 Accuracy 0.6037
Epoch 11 Batch 800 Loss 1.9606 Accuracy 0.6037
Epoch 11 Loss 1.9614 Accuracy 0.6036
Time taken for 1 epoch: 46.59 secs

Epoch 12 Batch 0 Loss 1.7234 Accuracy 0.6256
Epoch 12 Batch 50 Loss 1.8507 Accuracy 0.6169
Epoch 12 Batch 100 Loss 1.8460 Accuracy 0.6184
Epoch 12 Batch 150 Loss 1.8366 Accuracy 0.6207
Epoch 12 Batch 200 Loss 1.8454 Accuracy 0.6196
Epoch 12 Batch 250 Loss 1.8398 Accuracy 0.6205
Epoch 12 Batch 300 Loss 1.8441 Accuracy 0.6202
Epoch 12 Batch 350 Loss 1.8440 Accuracy 0.6199
Epoch 12 Batch 400 Loss 1.8443 Accuracy 0.6200
Epoch 12 Batch 450 Loss 1.8452 Accuracy 0.6198
Epoch 12 Batch 500 Loss 1.8499 Accuracy 0.6193
Epoch 12 Batch 550 Loss 1.8520 Accuracy 0.6190
Epoch 12 Batch 600 Loss 1.8554 Accuracy 0.6185
Epoch 12 Batch 650 Loss 1.8587 Accuracy 0.6179
Epoch 12 Batch 700 Loss 1.8610 Accuracy 0.6176
Epoch 12 Batch 750 Loss 1.8655 Accuracy 0.6170
Epoch 12 Batch 800 Loss 1.8684 Accuracy 0.6167
Epoch 12 Loss 1.8688 Accuracy 0.6167
Time taken for 1 epoch: 46.38 secs

Epoch 13 Batch 0 Loss 1.7697 Accuracy 0.6350
Epoch 13 Batch 50 Loss 1.7443 Accuracy 0.6337
Epoch 13 Batch 100 Loss 1.7422 Accuracy 0.6352
Epoch 13 Batch 150 Loss 1.7497 Accuracy 0.6331
Epoch 13 Batch 200 Loss 1.7603 Accuracy 0.6315
Epoch 13 Batch 250 Loss 1.7623 Accuracy 0.6316
Epoch 13 Batch 300 Loss 1.7656 Accuracy 0.6315
Epoch 13 Batch 350 Loss 1.7669 Accuracy 0.6312
Epoch 13 Batch 400 Loss 1.7683 Accuracy 0.6310
Epoch 13 Batch 450 Loss 1.7758 Accuracy 0.6298
Epoch 13 Batch 500 Loss 1.7758 Accuracy 0.6300
Epoch 13 Batch 550 Loss 1.7784 Accuracy 0.6296
Epoch 13 Batch 600 Loss 1.7804 Accuracy 0.6294
Epoch 13 Batch 650 Loss 1.7825 Accuracy 0.6291
Epoch 13 Batch 700 Loss 1.7867 Accuracy 0.6286
Epoch 13 Batch 750 Loss 1.7878 Accuracy 0.6284
Epoch 13 Batch 800 Loss 1.7913 Accuracy 0.6280
Epoch 13 Loss 1.7916 Accuracy 0.6280
Time taken for 1 epoch: 46.41 secs

Epoch 14 Batch 0 Loss 1.4785 Accuracy 0.6762
Epoch 14 Batch 50 Loss 1.7171 Accuracy 0.6378
Epoch 14 Batch 100 Loss 1.6949 Accuracy 0.6424
Epoch 14 Batch 150 Loss 1.6862 Accuracy 0.6440
Epoch 14 Batch 200 Loss 1.6893 Accuracy 0.6442
Epoch 14 Batch 250 Loss 1.6927 Accuracy 0.6432
Epoch 14 Batch 300 Loss 1.6943 Accuracy 0.6428
Epoch 14 Batch 350 Loss 1.6951 Accuracy 0.6427
Epoch 14 Batch 400 Loss 1.6961 Accuracy 0.6426
Epoch 14 Batch 450 Loss 1.7003 Accuracy 0.6420
Epoch 14 Batch 500 Loss 1.7028 Accuracy 0.6415
Epoch 14 Batch 550 Loss 1.7027 Accuracy 0.6413
Epoch 14 Batch 600 Loss 1.7066 Accuracy 0.6406
Epoch 14 Batch 650 Loss 1.7110 Accuracy 0.6399
Epoch 14 Batch 700 Loss 1.7140 Accuracy 0.6395
Epoch 14 Batch 750 Loss 1.7174 Accuracy 0.6390
Epoch 14 Batch 800 Loss 1.7198 Accuracy 0.6389
Epoch 14 Loss 1.7210 Accuracy 0.6387
Time taken for 1 epoch: 46.84 secs

Epoch 15 Batch 0 Loss 1.7209 Accuracy 0.6358
Epoch 15 Batch 50 Loss 1.6188 Accuracy 0.6545
Epoch 15 Batch 100 Loss 1.6084 Accuracy 0.6567
Epoch 15 Batch 150 Loss 1.6169 Accuracy 0.6557
Epoch 15 Batch 200 Loss 1.6215 Accuracy 0.6542
Epoch 15 Batch 250 Loss 1.6268 Accuracy 0.6534
Epoch 15 Batch 300 Loss 1.6257 Accuracy 0.6539
Epoch 15 Batch 350 Loss 1.6300 Accuracy 0.6531
Epoch 15 Batch 400 Loss 1.6318 Accuracy 0.6527
Epoch 15 Batch 450 Loss 1.6360 Accuracy 0.6521
Epoch 15 Batch 500 Loss 1.6403 Accuracy 0.6515
Epoch 15 Batch 550 Loss 1.6445 Accuracy 0.6509
Epoch 15 Batch 600 Loss 1.6467 Accuracy 0.6505
Epoch 15 Batch 650 Loss 1.6501 Accuracy 0.6499
Epoch 15 Batch 700 Loss 1.6537 Accuracy 0.6495
Epoch 15 Batch 750 Loss 1.6560 Accuracy 0.6492
Epoch 15 Batch 800 Loss 1.6602 Accuracy 0.6486
Saving checkpoint for epoch 15 at ./checkpoints/train/ckpt-3
Epoch 15 Loss 1.6598 Accuracy 0.6487
Time taken for 1 epoch: 46.54 secs

Epoch 16 Batch 0 Loss 1.5373 Accuracy 0.6739
Epoch 16 Batch 50 Loss 1.5678 Accuracy 0.6614
Epoch 16 Batch 100 Loss 1.5524 Accuracy 0.6646
Epoch 16 Batch 150 Loss 1.5550 Accuracy 0.6640
Epoch 16 Batch 200 Loss 1.5612 Accuracy 0.6627
Epoch 16 Batch 250 Loss 1.5703 Accuracy 0.6608
Epoch 16 Batch 300 Loss 1.5771 Accuracy 0.6597
Epoch 16 Batch 350 Loss 1.5812 Accuracy 0.6593
Epoch 16 Batch 400 Loss 1.5846 Accuracy 0.6588
Epoch 16 Batch 450 Loss 1.5864 Accuracy 0.6587
Epoch 16 Batch 500 Loss 1.5906 Accuracy 0.6581
Epoch 16 Batch 550 Loss 1.5940 Accuracy 0.6575
Epoch 16 Batch 600 Loss 1.5938 Accuracy 0.6576
Epoch 16 Batch 650 Loss 1.5959 Accuracy 0.6575
Epoch 16 Batch 700 Loss 1.5991 Accuracy 0.6571
Epoch 16 Batch 750 Loss 1.6017 Accuracy 0.6568
Epoch 16 Batch 800 Loss 1.6035 Accuracy 0.6566
Epoch 16 Loss 1.6043 Accuracy 0.6565
Time taken for 1 epoch: 46.25 secs

Epoch 17 Batch 0 Loss 1.6442 Accuracy 0.6463
Epoch 17 Batch 50 Loss 1.5289 Accuracy 0.6670
Epoch 17 Batch 100 Loss 1.5225 Accuracy 0.6684
Epoch 17 Batch 150 Loss 1.5237 Accuracy 0.6685
Epoch 17 Batch 200 Loss 1.5301 Accuracy 0.6674
Epoch 17 Batch 250 Loss 1.5323 Accuracy 0.6672
Epoch 17 Batch 300 Loss 1.5332 Accuracy 0.6670
Epoch 17 Batch 350 Loss 1.5349 Accuracy 0.6667
Epoch 17 Batch 400 Loss 1.5377 Accuracy 0.6662
Epoch 17 Batch 450 Loss 1.5399 Accuracy 0.6660
Epoch 17 Batch 500 Loss 1.5412 Accuracy 0.6660
Epoch 17 Batch 550 Loss 1.5468 Accuracy 0.6650
Epoch 17 Batch 600 Loss 1.5474 Accuracy 0.6651
Epoch 17 Batch 650 Loss 1.5504 Accuracy 0.6647
Epoch 17 Batch 700 Loss 1.5534 Accuracy 0.6643
Epoch 17 Batch 750 Loss 1.5562 Accuracy 0.6639
Epoch 17 Batch 800 Loss 1.5583 Accuracy 0.6635
Epoch 17 Loss 1.5593 Accuracy 0.6633
Time taken for 1 epoch: 46.66 secs

Epoch 18 Batch 0 Loss 1.5130 Accuracy 0.6849
Epoch 18 Batch 50 Loss 1.4575 Accuracy 0.6796
Epoch 18 Batch 100 Loss 1.4698 Accuracy 0.6770
Epoch 18 Batch 150 Loss 1.4760 Accuracy 0.6765
Epoch 18 Batch 200 Loss 1.4783 Accuracy 0.6762
Epoch 18 Batch 250 Loss 1.4811 Accuracy 0.6758
Epoch 18 Batch 300 Loss 1.4870 Accuracy 0.6749
Epoch 18 Batch 350 Loss 1.4929 Accuracy 0.6738
Epoch 18 Batch 400 Loss 1.4945 Accuracy 0.6736
Epoch 18 Batch 450 Loss 1.4979 Accuracy 0.6730
Epoch 18 Batch 500 Loss 1.4970 Accuracy 0.6731
Epoch 18 Batch 550 Loss 1.5004 Accuracy 0.6725
Epoch 18 Batch 600 Loss 1.5034 Accuracy 0.6721
Epoch 18 Batch 650 Loss 1.5073 Accuracy 0.6715
Epoch 18 Batch 700 Loss 1.5096 Accuracy 0.6712
Epoch 18 Batch 750 Loss 1.5129 Accuracy 0.6707
Epoch 18 Batch 800 Loss 1.5164 Accuracy 0.6701
Epoch 18 Loss 1.5160 Accuracy 0.6702
Time taken for 1 epoch: 46.40 secs

Epoch 19 Batch 0 Loss 1.5139 Accuracy 0.6813
Epoch 19 Batch 50 Loss 1.4341 Accuracy 0.6832
Epoch 19 Batch 100 Loss 1.4357 Accuracy 0.6828
Epoch 19 Batch 150 Loss 1.4364 Accuracy 0.6829
Epoch 19 Batch 200 Loss 1.4439 Accuracy 0.6816
Epoch 19 Batch 250 Loss 1.4448 Accuracy 0.6816
Epoch 19 Batch 300 Loss 1.4494 Accuracy 0.6812
Epoch 19 Batch 350 Loss 1.4543 Accuracy 0.6805
Epoch 19 Batch 400 Loss 1.4543 Accuracy 0.6804
Epoch 19 Batch 450 Loss 1.4583 Accuracy 0.6795
Epoch 19 Batch 500 Loss 1.4609 Accuracy 0.6789
Epoch 19 Batch 550 Loss 1.4637 Accuracy 0.6786
Epoch 19 Batch 600 Loss 1.4641 Accuracy 0.6787
Epoch 19 Batch 650 Loss 1.4674 Accuracy 0.6780
Epoch 19 Batch 700 Loss 1.4703 Accuracy 0.6776
Epoch 19 Batch 750 Loss 1.4722 Accuracy 0.6773
Epoch 19 Batch 800 Loss 1.4760 Accuracy 0.6768
Epoch 19 Loss 1.4767 Accuracy 0.6766
Time taken for 1 epoch: 46.45 secs

Epoch 20 Batch 0 Loss 1.3065 Accuracy 0.7057
Epoch 20 Batch 50 Loss 1.3843 Accuracy 0.6909
Epoch 20 Batch 100 Loss 1.3941 Accuracy 0.6891
Epoch 20 Batch 150 Loss 1.3995 Accuracy 0.6883
Epoch 20 Batch 200 Loss 1.3997 Accuracy 0.6888
Epoch 20 Batch 250 Loss 1.4033 Accuracy 0.6884
Epoch 20 Batch 300 Loss 1.4076 Accuracy 0.6873
Epoch 20 Batch 350 Loss 1.4130 Accuracy 0.6864
Epoch 20 Batch 400 Loss 1.4144 Accuracy 0.6862
Epoch 20 Batch 450 Loss 1.4186 Accuracy 0.6853
Epoch 20 Batch 500 Loss 1.4206 Accuracy 0.6851
Epoch 20 Batch 550 Loss 1.4225 Accuracy 0.6847
Epoch 20 Batch 600 Loss 1.4253 Accuracy 0.6843
Epoch 20 Batch 650 Loss 1.4299 Accuracy 0.6835
Epoch 20 Batch 700 Loss 1.4324 Accuracy 0.6831
Epoch 20 Batch 750 Loss 1.4376 Accuracy 0.6823
Epoch 20 Batch 800 Loss 1.4405 Accuracy 0.6817
Saving checkpoint for epoch 20 at ./checkpoints/train/ckpt-4
Epoch 20 Loss 1.4410 Accuracy 0.6816
Time taken for 1 epoch: 46.87 secs

अनुमान चलाएँ

अनुमान के लिए निम्नलिखित चरणों का उपयोग किया जाता है:

  • पुर्तगाली tokenizer (का उपयोग कर इनपुट की सजा सांकेतिक शब्दों में बदलना tokenizers.pt )। यह एनकोडर इनपुट है।
  • विकोडक इनपुट करने के लिए आरंभ नहीं हो जाता [START] टोकन।
  • पैडिंग मास्क और आगे के मुखौटों की गणना करें।
  • decoder तो को देखकर भविष्यवाणियों आउटपुट encoder output और अपने स्वयं के उत्पादन (आत्म-ध्यान)।
  • डिकोडर इनपुट के लिए अनुमानित टोकन को संयोजित करें और इसे डिकोडर को पास करें।
  • इस दृष्टिकोण में, डिकोडर पिछले टोकन के आधार पर अगले टोकन की भविष्यवाणी करता है जिसकी उसने भविष्यवाणी की थी।
class Translator(tf.Module):
  def __init__(self, tokenizers, transformer):
    self.tokenizers = tokenizers
    self.transformer = transformer

  def __call__(self, sentence, max_length=20):
    # input sentence is portuguese, hence adding the start and end token
    assert isinstance(sentence, tf.Tensor)
    if len(sentence.shape) == 0:
      sentence = sentence[tf.newaxis]

    sentence = self.tokenizers.pt.tokenize(sentence).to_tensor()

    encoder_input = sentence

    # as the target is english, the first token to the transformer should be the
    # english start token.
    start_end = self.tokenizers.en.tokenize([''])[0]
    start = start_end[0][tf.newaxis]
    end = start_end[1][tf.newaxis]

    # `tf.TensorArray` is required here (instead of a python list) so that the
    # dynamic-loop can be traced by `tf.function`.
    output_array = tf.TensorArray(dtype=tf.int64, size=0, dynamic_size=True)
    output_array = output_array.write(0, start)

    for i in tf.range(max_length):
      output = tf.transpose(output_array.stack())
      predictions, _ = self.transformer([encoder_input, output], training=False)

      # select the last token 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_array = output_array.write(i+1, predicted_id[0])

      if predicted_id == end:
        break

    output = tf.transpose(output_array.stack())
    # output.shape (1, tokens)
    text = tokenizers.en.detokenize(output)[0]  # shape: ()

    tokens = tokenizers.en.lookup(output)[0]

    # `tf.function` prevents us from using the attention_weights that were
    # calculated on the last iteration of the loop. So recalculate them outside
    # the loop.
    _, attention_weights = self.transformer([encoder_input, output[:,:-1]], training=False)

    return text, tokens, attention_weights

इस का एक उदाहरण बना Translator वर्ग, और इसे बाहर कई बार कोशिश:

translator = Translator(tokenizers, transformer)
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 = translator(
    tf.constant(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 = translator(
    tf.constant(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 = translator(
    tf.constant(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 going to be very quickly share with you some of the magic stories that happened .
Ground truth   : so i 'll just share with you some stories very quickly of some magical things that have happened .

ध्यान भूखंड

Translator वर्ग रिटर्न ध्यान का एक शब्दकोश नक्शे आप मॉडल के आंतरिक कार्य कल्पना करने के लिए उपयोग कर सकते हैं:

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 = translator(
    tf.constant(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 = translator(
    tf.constant(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 trivalopat nairconcissus in the encyclo
Ground truth   : I read about triceratops in the encyclopedia.

पीएनजी

निर्यात

यही कारण है कि अनुमान मॉडल काम कर रहा है, इसलिए अगले आप एक के रूप में निर्यात करेंगे tf.saved_model

ऐसा करने के लिए, यह अभी तक एक और में लपेट tf.Module उप-वर्ग, इस बार एक साथ tf.function पर __call__ विधि:

class ExportTranslator(tf.Module):
  def __init__(self, translator):
    self.translator = translator

  @tf.function(input_signature=[tf.TensorSpec(shape=[], dtype=tf.string)])
  def __call__(self, sentence):
    (result, 
     tokens,
     attention_weights) = self.translator(sentence, max_length=100)

    return result

इसके बाद के संस्करण में tf.function केवल उत्पादन की सजा दिया जाता है। के लिए धन्यवाद गैर सख्त निष्पादन में tf.function किसी भी अनावश्यक मान कभी नहीं गणना की जाती है।

translator = ExportTranslator(translator)

मॉडल के बाद से उपयोग कर रहा भविष्यवाणियों डिकोडिंग है tf.argmax भविष्यवाणियों नियतात्मक हैं। मूल मॉडल और एक अपने से पुनः लोड SavedModel समान भविष्यवाणियों देना चाहिए:

translator("este é o primeiro livro que eu fiz.").numpy()
b'this is the first book i did .'
tf.saved_model.save(translator, export_dir='translator')
2021-11-02 15:48:30.232789: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
WARNING:absl:Found untraced functions such as embedding_4_layer_call_and_return_conditional_losses, embedding_4_layer_call_fn, dropout_37_layer_call_and_return_conditional_losses, dropout_37_layer_call_fn, embedding_5_layer_call_and_return_conditional_losses while saving (showing 5 of 560). These functions will not be directly callable after loading.
reloaded = tf.saved_model.load('translator')
reloaded("este é o primeiro livro que eu fiz.").numpy()
b'this is the first book i did .'

सारांश

इस ट्यूटोरियल में, आपने पोजिशनल एन्कोडिंग, मल्टी-हेड अटेंशन, मास्किंग के महत्व और ट्रांसफॉर्मर बनाने के तरीके के बारे में सीखा।

ट्रांसफॉर्मर को प्रशिक्षित करने के लिए किसी भिन्न डेटासेट का उपयोग करने का प्रयास करें। आप ऊपर दिए गए हाइपरपैरामीटर को बदलकर बेस ट्रांसफॉर्मर या ट्रांसफॉर्मर XL भी बना सकते हैं। तुम भी यहाँ बनाने के लिए परतों में परिभाषित का उपयोग कर सकते बर्ट कला मॉडल की और ट्रेन राज्य। इसके अलावा, आप बेहतर पूर्वानुमान प्राप्त करने के लिए बीम खोज को लागू कर सकते हैं।