Google I / O가 5 월 18 ~ 20 일에 돌아옵니다! 공간을 예약하고 일정을 짜세요 지금 등록하세요

언어 이해를위한 변환기 모델

TensorFlow.org에서보기 Google Colab에서 실행 GitHub에서 소스보기 노트북 다운로드

이 가이드에서는 Transformer 모델 을 학습시켜포르투갈어를 영어 데이터 세트 로 번역합니다. 이것은 텍스트 생성주의에 대한 지식을 가정하는 고급 예제입니다.

Transformer 모델의 핵심 아이디어는 입력 시퀀스의 다른 위치에 주의를 기울여 해당 시퀀스의 표현을 계산하는 능력 인 자기주의 입니다. Transformer는 자기주의 레이어 스택을 생성하며 아래의 Scaled dot product AttentionMulti-head Attention 섹션에서 설명합니다.

대신에 자기 관심 층의 스택을 사용하여 변압기 모델 핸들 변수 크기의 입력 RNNs 또는 CNNs를 . 이 일반 아키텍처에는 다음과 같은 여러 장점이 있습니다.

  • 데이터 전반에 걸친 시간적 / 공간적 관계에 대한 가정을하지 않습니다. 이것은 일련의 개체 (예 : StarCraft 유닛 )를 처리하는 데 이상적입니다.
  • 레이어 출력은 RNN과 같은 시리즈 대신 병렬로 계산할 수 있습니다.
  • 멀리있는 항목은 많은 RNN 단계 또는 컨볼 루션 레이어를 통과하지 않고도 서로의 출력에 영향을 미칠 수 있습니다 (예 : Scene Memory Transformer 참조).
  • 장거리 의존성을 배울 수 있습니다. 이것은 많은 시퀀스 작업의 도전입니다.

이 아키텍처의 단점은 다음과 같습니다.

  • 시계열의 경우 시간 단계에 대한 출력은 입력 및 현재 숨겨진 상태 만이 아닌 전체 기록 에서 계산됩니다. 이것은 덜 효율적일 있습니다.
  • 입력이 시간적 / 공간적 관계, 텍스트와 같은 일부 위치 부호화 추가해야 경우가 있는가 또는 모델 효과적으로 단어의 가방을 볼 것이다.

이 노트북에서 모델을 학습 한 후 포르투갈어 문장을 입력하고 영어 번역을 반환 할 수 있습니다.

주의 히트 맵

설정

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 Talks Open Translation Project 에서 포르투갈어-영어 번역 데이터 세트 를로드합니다.

이 데이터 세트에는 약 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']

TensorFlow 데이터 세트에서 반환 된tf.data.Dataset 객체는 텍스트 예제 쌍을 생성합니다.

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 .

텍스트 토큰 화 및 디 토큰 화

텍스트에서 직접 모델을 훈련 할 수 없습니다. 먼저 텍스트를 숫자 표현으로 변환해야합니다. 일반적으로 텍스트를 포함에 대한 인덱스 인 토큰 ID 시퀀스로 변환합니다.

Subword 토크 나이저 튜토리얼 에서이 데이터 세트에 최적화 된 text.BertTokenizer 워드 토크 나이저 ( text.BertTokenizer )를 빌드하고이를 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 에는 두 개의 텍스트 토크 나이저가 포함되어 있습니다. 하나는 영어 용이고 다른 하나는 포르투갈어 용입니다. 둘 다 동일한 방법이 있습니다.

[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 메서드는 문자열 일괄 처리를 토큰 ID의 패딩 일괄 처리로 변환합니다. 이 방법은 토큰 화하기 전에 구두점, 소문자를 분할하고 입력을 유니 코드로 정규화합니다. 입력 데이터가 이미 표준화 되었기 때문에 이러한 표준화는 여기에 표시되지 않습니다.

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 메서드는 이러한 토큰 ID를 사람이 읽을 수있는 텍스트로 다시 변환하려고 시도합니다.

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 방법은 토큰 ID에서 토큰 텍스트로 변환합니다.

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

여기에서 토크 나이저의 "서브 워드"측면을 볼 수 있습니다. "searchability"라는 단어는 "search ## ability"로 분해되고 "serindipity"라는 단어는 "s ## 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)

위치 인코딩

이 모델에는 반복이나 컨볼 루션이 포함되어 있지 않기 때문에 위치 인코딩이 추가되어 문장에서 단어의 상대적 위치에 대한 정보를 모델에 제공합니다.

위치 인코딩 벡터가 임베딩 벡터에 추가됩니다. 임베딩은 비슷한 의미의 토큰이 서로 더 가까워지는 d 차원 공간의 토큰을 나타냅니다. 그러나 임베딩은 문장에서 단어의 상대적 위치를 인코딩하지 않습니다. 따라서 위치 인코딩을 추가하면 단어 의 의미와 문장에서의 위치 , d 차원 공간의 유사성에 따라 단어가 서로 더 가까워집니다.

위치 인코딩을 계산하는 공식은 다음과 같습니다.

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

png

마스킹

시퀀스 배치의 모든 패드 토큰을 마스킹합니다. 모델이 패딩을 입력으로 취급하지 않도록합니다. 마스크는 패드 값 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)>

배율 내적주의

scaled_dot_product_attention

변환기가 사용하는주의 함수는 Q (쿼리), K (키), V (값)의 세 가지 입력을받습니다. 주의 가중치를 계산하는 데 사용되는 방정식은 다음과 같습니다.

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

내적 관심도는 깊이의 제곱근 계수로 조정됩니다. 이것은 큰 깊이 값의 경우 내적이 크기가 커져서 작은 기울기가있는 소프트 맥스 함수를 밀어서 매우 단단한 소프트 맥스가되기 때문입니다.

예를 들어, QK 의 평균이 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에 부여되는 중요도를 결정합니다.

출력은주의 가중치와 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 (값). 이들은 선형 (Dense) 레이어를 통과하여 여러 개의 헤드로 분할됩니다.

위에서 정의한 scaled_dot_product_attention 은 각 헤드에 적용됩니다 (효율성을 위해 방송 됨). 주의 단계에서 적절한 마스크를 사용해야합니다. 그런 다음 각 헤드에 대한 어텐션 출력이 연결되고 ( tf.transposetf.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 인코더 레이어를 통해 전달됩니다.
  • 디코더는 다음 단어를 예측하기 위해 인코더의 출력과 자체 입력 (자기주의)을 처리합니다.

인코더 레이어

각 인코더 계층은 하위 계층으로 구성됩니다.

  1. 다중 머리주의 (패딩 마스크 포함)
  2. 포인트 현명한 피드 포워드 네트워크.

이러한 각 하위 계층에는 계층 정규화가 뒤 따르는 잔여 연결이 있습니다. 잔여 연결은 딥 네트워크에서 사라지는 그래디언트 문제를 방지하는 데 도움이됩니다.

각 하위 계층의 출력은 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])

디코더 레이어

각 디코더 계층은 하위 계층으로 구성됩니다.

  1. 마스킹 된 멀티 헤드 어텐션 (미리보기 마스크 및 패딩 마스크 포함)
  2. 다중 머리주의 (패딩 마스크 포함). V (값) 및 K (키)는 엔코더 출력 을 입력으로받습니다. Q (쿼리)는 마스킹 된 다중 머리주의 하위 계층에서 출력을 수신합니다 .
  3. 포인트 현명한 피드 포워드 네트워크

이러한 각 하위 계층에는 계층 정규화가 뒤 따르는 잔여 연결이 있습니다. 각 하위 계층의 출력은 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 는 다음으로 구성됩니다.

  1. 입력 임베딩
  2. 위치 인코딩
  3. 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 는 다음으로 구성됩니다.

  1. 출력 임베딩
  2. 위치 인코딩
  3. 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]))

변환기 만들기

Transformer는 인코더, 디코더 및 최종 선형 레이어로 구성됩니다. 디코더의 출력은 선형 레이어에 대한 입력이며 출력이 반환됩니다.

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

초 매개 변수 설정

이 예제를 작고 비교적 빠르게 유지하기 위해 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

옵티 마이저

논문 의 공식에 따라 맞춤 학습률 스케줄러와 함께 Adam 최적화 프로그램을 사용합니다.

$$\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')

png

손실 및 지표

타겟 시퀀스가 ​​패딩되기 때문에 손실을 계산할 때 패딩 마스크를 적용하는 것이 중요합니다.

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 epoch마다 체크 포인트를 저장하는 데 사용됩니다.

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.8704 Accuracy 0.0081
Epoch 1 Batch 50 Loss 8.8161 Accuracy 0.0091
Epoch 1 Batch 100 Loss 8.7176 Accuracy 0.0225
Epoch 1 Batch 150 Loss 8.6033 Accuracy 0.0354
Epoch 1 Batch 200 Loss 8.4620 Accuracy 0.0424
Epoch 1 Batch 250 Loss 8.2929 Accuracy 0.0474
Epoch 1 Batch 300 Loss 8.1045 Accuracy 0.0522
Epoch 1 Batch 350 Loss 7.9074 Accuracy 0.0579
Epoch 1 Batch 400 Loss 7.7174 Accuracy 0.0657
Epoch 1 Batch 450 Loss 7.5503 Accuracy 0.0728
Epoch 1 Batch 500 Loss 7.4023 Accuracy 0.0794
Epoch 1 Batch 550 Loss 7.2690 Accuracy 0.0864
Epoch 1 Batch 600 Loss 7.1429 Accuracy 0.0939
Epoch 1 Batch 650 Loss 7.0231 Accuracy 0.1012
Epoch 1 Batch 700 Loss 6.9124 Accuracy 0.1077
Epoch 1 Batch 750 Loss 6.8118 Accuracy 0.1140
Epoch 1 Batch 800 Loss 6.7182 Accuracy 0.1195
Epoch 1 Loss 6.7023 Accuracy 0.1205
Time taken for 1 epoch: 67.89 secs

Epoch 2 Batch 0 Loss 5.1591 Accuracy 0.2270
Epoch 2 Batch 50 Loss 5.2163 Accuracy 0.2126
Epoch 2 Batch 100 Loss 5.1807 Accuracy 0.2167
Epoch 2 Batch 150 Loss 5.1651 Accuracy 0.2190
Epoch 2 Batch 200 Loss 5.1359 Accuracy 0.2227
Epoch 2 Batch 250 Loss 5.1069 Accuracy 0.2253
Epoch 2 Batch 300 Loss 5.0841 Accuracy 0.2275
Epoch 2 Batch 350 Loss 5.0592 Accuracy 0.2301
Epoch 2 Batch 400 Loss 5.0360 Accuracy 0.2325
Epoch 2 Batch 450 Loss 5.0155 Accuracy 0.2346
Epoch 2 Batch 500 Loss 4.9966 Accuracy 0.2364
Epoch 2 Batch 550 Loss 4.9763 Accuracy 0.2382
Epoch 2 Batch 600 Loss 4.9571 Accuracy 0.2400
Epoch 2 Batch 650 Loss 4.9392 Accuracy 0.2417
Epoch 2 Batch 700 Loss 4.9229 Accuracy 0.2431
Epoch 2 Batch 750 Loss 4.9063 Accuracy 0.2445
Epoch 2 Batch 800 Loss 4.8908 Accuracy 0.2458
Epoch 2 Loss 4.8871 Accuracy 0.2462
Time taken for 1 epoch: 51.84 secs

Epoch 3 Batch 0 Loss 4.7496 Accuracy 0.2528
Epoch 3 Batch 50 Loss 4.5931 Accuracy 0.2724
Epoch 3 Batch 100 Loss 4.5815 Accuracy 0.2730
Epoch 3 Batch 150 Loss 4.5607 Accuracy 0.2747
Epoch 3 Batch 200 Loss 4.5467 Accuracy 0.2760
Epoch 3 Batch 250 Loss 4.5444 Accuracy 0.2764
Epoch 3 Batch 300 Loss 4.5312 Accuracy 0.2778
Epoch 3 Batch 350 Loss 4.5188 Accuracy 0.2791
Epoch 3 Batch 400 Loss 4.5048 Accuracy 0.2808
Epoch 3 Batch 450 Loss 4.4914 Accuracy 0.2822
Epoch 3 Batch 500 Loss 4.4781 Accuracy 0.2835
Epoch 3 Batch 550 Loss 4.4637 Accuracy 0.2853
Epoch 3 Batch 600 Loss 4.4502 Accuracy 0.2869
Epoch 3 Batch 650 Loss 4.4355 Accuracy 0.2887
Epoch 3 Batch 700 Loss 4.4193 Accuracy 0.2904
Epoch 3 Batch 750 Loss 4.4046 Accuracy 0.2922
Epoch 3 Batch 800 Loss 4.3877 Accuracy 0.2943
Epoch 3 Loss 4.3835 Accuracy 0.2947
Time taken for 1 epoch: 50.60 secs

Epoch 4 Batch 0 Loss 4.1652 Accuracy 0.3333
Epoch 4 Batch 50 Loss 4.0788 Accuracy 0.3290
Epoch 4 Batch 100 Loss 4.0445 Accuracy 0.3339
Epoch 4 Batch 150 Loss 4.0198 Accuracy 0.3370
Epoch 4 Batch 200 Loss 4.0064 Accuracy 0.3390
Epoch 4 Batch 250 Loss 3.9912 Accuracy 0.3406
Epoch 4 Batch 300 Loss 3.9757 Accuracy 0.3426
Epoch 4 Batch 350 Loss 3.9589 Accuracy 0.3447
Epoch 4 Batch 400 Loss 3.9458 Accuracy 0.3464
Epoch 4 Batch 450 Loss 3.9309 Accuracy 0.3481
Epoch 4 Batch 500 Loss 3.9130 Accuracy 0.3505
Epoch 4 Batch 550 Loss 3.9002 Accuracy 0.3521
Epoch 4 Batch 600 Loss 3.8851 Accuracy 0.3542
Epoch 4 Batch 650 Loss 3.8680 Accuracy 0.3564
Epoch 4 Batch 700 Loss 3.8556 Accuracy 0.3582
Epoch 4 Batch 750 Loss 3.8442 Accuracy 0.3597
Epoch 4 Batch 800 Loss 3.8292 Accuracy 0.3618
Epoch 4 Loss 3.8263 Accuracy 0.3622
Time taken for 1 epoch: 50.77 secs

Epoch 5 Batch 0 Loss 3.6539 Accuracy 0.3988
Epoch 5 Batch 50 Loss 3.5384 Accuracy 0.3941
Epoch 5 Batch 100 Loss 3.5270 Accuracy 0.3959
Epoch 5 Batch 150 Loss 3.5129 Accuracy 0.3992
Epoch 5 Batch 200 Loss 3.4907 Accuracy 0.4023
Epoch 5 Batch 250 Loss 3.4844 Accuracy 0.4029
Epoch 5 Batch 300 Loss 3.4699 Accuracy 0.4049
Epoch 5 Batch 350 Loss 3.4615 Accuracy 0.4060
Epoch 5 Batch 400 Loss 3.4520 Accuracy 0.4073
Epoch 5 Batch 450 Loss 3.4455 Accuracy 0.4080
Epoch 5 Batch 500 Loss 3.4331 Accuracy 0.4098
Epoch 5 Batch 550 Loss 3.4182 Accuracy 0.4116
Epoch 5 Batch 600 Loss 3.4119 Accuracy 0.4124
Epoch 5 Batch 650 Loss 3.4020 Accuracy 0.4137
Epoch 5 Batch 700 Loss 3.3951 Accuracy 0.4148
Epoch 5 Batch 750 Loss 3.3880 Accuracy 0.4156
Epoch 5 Batch 800 Loss 3.3780 Accuracy 0.4171
Saving checkpoint for epoch 5 at ./checkpoints/train/ckpt-1
Epoch 5 Loss 3.3768 Accuracy 0.4172
Time taken for 1 epoch: 50.68 secs

Epoch 6 Batch 0 Loss 3.2038 Accuracy 0.4183
Epoch 6 Batch 50 Loss 3.1073 Accuracy 0.4465
Epoch 6 Batch 100 Loss 3.1056 Accuracy 0.4467
Epoch 6 Batch 150 Loss 3.0853 Accuracy 0.4500
Epoch 6 Batch 200 Loss 3.0788 Accuracy 0.4512
Epoch 6 Batch 250 Loss 3.0802 Accuracy 0.4507
Epoch 6 Batch 300 Loss 3.0750 Accuracy 0.4516
Epoch 6 Batch 350 Loss 3.0661 Accuracy 0.4528
Epoch 6 Batch 400 Loss 3.0562 Accuracy 0.4543
Epoch 6 Batch 450 Loss 3.0464 Accuracy 0.4558
Epoch 6 Batch 500 Loss 3.0342 Accuracy 0.4575
Epoch 6 Batch 550 Loss 3.0282 Accuracy 0.4584
Epoch 6 Batch 600 Loss 3.0199 Accuracy 0.4596
Epoch 6 Batch 650 Loss 3.0085 Accuracy 0.4614
Epoch 6 Batch 700 Loss 3.0005 Accuracy 0.4625
Epoch 6 Batch 750 Loss 2.9946 Accuracy 0.4634
Epoch 6 Batch 800 Loss 2.9895 Accuracy 0.4642
Epoch 6 Loss 2.9875 Accuracy 0.4645
Time taken for 1 epoch: 50.88 secs

Epoch 7 Batch 0 Loss 2.7694 Accuracy 0.4982
Epoch 7 Batch 50 Loss 2.7504 Accuracy 0.4915
Epoch 7 Batch 100 Loss 2.7268 Accuracy 0.4952
Epoch 7 Batch 150 Loss 2.7187 Accuracy 0.4960
Epoch 7 Batch 200 Loss 2.7095 Accuracy 0.4972
Epoch 7 Batch 250 Loss 2.7081 Accuracy 0.4978
Epoch 7 Batch 300 Loss 2.6940 Accuracy 0.5001
Epoch 7 Batch 350 Loss 2.6906 Accuracy 0.5008
Epoch 7 Batch 400 Loss 2.6818 Accuracy 0.5023
Epoch 7 Batch 450 Loss 2.6795 Accuracy 0.5027
Epoch 7 Batch 500 Loss 2.6768 Accuracy 0.5031
Epoch 7 Batch 550 Loss 2.6754 Accuracy 0.5034
Epoch 7 Batch 600 Loss 2.6715 Accuracy 0.5039
Epoch 7 Batch 650 Loss 2.6682 Accuracy 0.5046
Epoch 7 Batch 700 Loss 2.6643 Accuracy 0.5053
Epoch 7 Batch 750 Loss 2.6607 Accuracy 0.5060
Epoch 7 Batch 800 Loss 2.6548 Accuracy 0.5070
Epoch 7 Loss 2.6560 Accuracy 0.5069
Time taken for 1 epoch: 50.55 secs

Epoch 8 Batch 0 Loss 2.5369 Accuracy 0.5155
Epoch 8 Batch 50 Loss 2.4466 Accuracy 0.5349
Epoch 8 Batch 100 Loss 2.4255 Accuracy 0.5371
Epoch 8 Batch 150 Loss 2.4299 Accuracy 0.5357
Epoch 8 Batch 200 Loss 2.4301 Accuracy 0.5361
Epoch 8 Batch 250 Loss 2.4266 Accuracy 0.5369
Epoch 8 Batch 300 Loss 2.4291 Accuracy 0.5367
Epoch 8 Batch 350 Loss 2.4275 Accuracy 0.5372
Epoch 8 Batch 400 Loss 2.4261 Accuracy 0.5372
Epoch 8 Batch 450 Loss 2.4248 Accuracy 0.5373
Epoch 8 Batch 500 Loss 2.4253 Accuracy 0.5371
Epoch 8 Batch 550 Loss 2.4238 Accuracy 0.5374
Epoch 8 Batch 600 Loss 2.4215 Accuracy 0.5378
Epoch 8 Batch 650 Loss 2.4203 Accuracy 0.5383
Epoch 8 Batch 700 Loss 2.4182 Accuracy 0.5386
Epoch 8 Batch 750 Loss 2.4160 Accuracy 0.5389
Epoch 8 Batch 800 Loss 2.4154 Accuracy 0.5391
Epoch 8 Loss 2.4155 Accuracy 0.5391
Time taken for 1 epoch: 50.08 secs

Epoch 9 Batch 0 Loss 2.1173 Accuracy 0.5724
Epoch 9 Batch 50 Loss 2.2597 Accuracy 0.5580
Epoch 9 Batch 100 Loss 2.2266 Accuracy 0.5628
Epoch 9 Batch 150 Loss 2.2298 Accuracy 0.5626
Epoch 9 Batch 200 Loss 2.2301 Accuracy 0.5627
Epoch 9 Batch 250 Loss 2.2381 Accuracy 0.5619
Epoch 9 Batch 300 Loss 2.2342 Accuracy 0.5626
Epoch 9 Batch 350 Loss 2.2366 Accuracy 0.5623
Epoch 9 Batch 400 Loss 2.2374 Accuracy 0.5623
Epoch 9 Batch 450 Loss 2.2357 Accuracy 0.5627
Epoch 9 Batch 500 Loss 2.2348 Accuracy 0.5630
Epoch 9 Batch 550 Loss 2.2324 Accuracy 0.5635
Epoch 9 Batch 600 Loss 2.2337 Accuracy 0.5634
Epoch 9 Batch 650 Loss 2.2343 Accuracy 0.5632
Epoch 9 Batch 700 Loss 2.2358 Accuracy 0.5631
Epoch 9 Batch 750 Loss 2.2344 Accuracy 0.5634
Epoch 9 Batch 800 Loss 2.2353 Accuracy 0.5634
Epoch 9 Loss 2.2343 Accuracy 0.5636
Time taken for 1 epoch: 48.99 secs

Epoch 10 Batch 0 Loss 1.9922 Accuracy 0.5977
Epoch 10 Batch 50 Loss 2.0634 Accuracy 0.5875
Epoch 10 Batch 100 Loss 2.0665 Accuracy 0.5864
Epoch 10 Batch 150 Loss 2.0772 Accuracy 0.5852
Epoch 10 Batch 200 Loss 2.0844 Accuracy 0.5847
Epoch 10 Batch 250 Loss 2.0829 Accuracy 0.5845
Epoch 10 Batch 300 Loss 2.0851 Accuracy 0.5841
Epoch 10 Batch 350 Loss 2.0884 Accuracy 0.5838
Epoch 10 Batch 400 Loss 2.0882 Accuracy 0.5838
Epoch 10 Batch 450 Loss 2.0893 Accuracy 0.5835
Epoch 10 Batch 500 Loss 2.0865 Accuracy 0.5839
Epoch 10 Batch 550 Loss 2.0883 Accuracy 0.5839
Epoch 10 Batch 600 Loss 2.0881 Accuracy 0.5840
Epoch 10 Batch 650 Loss 2.0886 Accuracy 0.5839
Epoch 10 Batch 700 Loss 2.0903 Accuracy 0.5839
Epoch 10 Batch 750 Loss 2.0901 Accuracy 0.5839
Epoch 10 Batch 800 Loss 2.0936 Accuracy 0.5836
Saving checkpoint for epoch 10 at ./checkpoints/train/ckpt-2
Epoch 10 Loss 2.0936 Accuracy 0.5836
Time taken for 1 epoch: 49.90 secs

Epoch 11 Batch 0 Loss 1.9743 Accuracy 0.6003
Epoch 11 Batch 50 Loss 1.9758 Accuracy 0.5977
Epoch 11 Batch 100 Loss 1.9516 Accuracy 0.6016
Epoch 11 Batch 150 Loss 1.9523 Accuracy 0.6028
Epoch 11 Batch 200 Loss 1.9650 Accuracy 0.6004
Epoch 11 Batch 250 Loss 1.9619 Accuracy 0.6013
Epoch 11 Batch 300 Loss 1.9623 Accuracy 0.6012
Epoch 11 Batch 350 Loss 1.9674 Accuracy 0.6003
Epoch 11 Batch 400 Loss 1.9678 Accuracy 0.6003
Epoch 11 Batch 450 Loss 1.9687 Accuracy 0.6004
Epoch 11 Batch 500 Loss 1.9708 Accuracy 0.6001
Epoch 11 Batch 550 Loss 1.9738 Accuracy 0.5997
Epoch 11 Batch 600 Loss 1.9769 Accuracy 0.5994
Epoch 11 Batch 650 Loss 1.9754 Accuracy 0.5997
Epoch 11 Batch 700 Loss 1.9760 Accuracy 0.5998
Epoch 11 Batch 750 Loss 1.9789 Accuracy 0.5994
Epoch 11 Batch 800 Loss 1.9801 Accuracy 0.5994
Epoch 11 Loss 1.9801 Accuracy 0.5993
Time taken for 1 epoch: 50.51 secs

Epoch 12 Batch 0 Loss 2.0371 Accuracy 0.5814
Epoch 12 Batch 50 Loss 1.8457 Accuracy 0.6189
Epoch 12 Batch 100 Loss 1.8479 Accuracy 0.6178
Epoch 12 Batch 150 Loss 1.8477 Accuracy 0.6182
Epoch 12 Batch 200 Loss 1.8504 Accuracy 0.6180
Epoch 12 Batch 250 Loss 1.8545 Accuracy 0.6172
Epoch 12 Batch 300 Loss 1.8621 Accuracy 0.6159
Epoch 12 Batch 350 Loss 1.8635 Accuracy 0.6157
Epoch 12 Batch 400 Loss 1.8686 Accuracy 0.6153
Epoch 12 Batch 450 Loss 1.8712 Accuracy 0.6151
Epoch 12 Batch 500 Loss 1.8746 Accuracy 0.6145
Epoch 12 Batch 550 Loss 1.8756 Accuracy 0.6143
Epoch 12 Batch 600 Loss 1.8764 Accuracy 0.6143
Epoch 12 Batch 650 Loss 1.8796 Accuracy 0.6136
Epoch 12 Batch 700 Loss 1.8810 Accuracy 0.6135
Epoch 12 Batch 750 Loss 1.8836 Accuracy 0.6134
Epoch 12 Batch 800 Loss 1.8847 Accuracy 0.6133
Epoch 12 Loss 1.8841 Accuracy 0.6134
Time taken for 1 epoch: 50.77 secs

Epoch 13 Batch 0 Loss 1.7012 Accuracy 0.6425
Epoch 13 Batch 50 Loss 1.7877 Accuracy 0.6252
Epoch 13 Batch 100 Loss 1.7753 Accuracy 0.6284
Epoch 13 Batch 150 Loss 1.7830 Accuracy 0.6275
Epoch 13 Batch 200 Loss 1.7758 Accuracy 0.6285
Epoch 13 Batch 250 Loss 1.7815 Accuracy 0.6274
Epoch 13 Batch 300 Loss 1.7873 Accuracy 0.6266
Epoch 13 Batch 350 Loss 1.7875 Accuracy 0.6266
Epoch 13 Batch 400 Loss 1.7876 Accuracy 0.6268
Epoch 13 Batch 450 Loss 1.7885 Accuracy 0.6266
Epoch 13 Batch 500 Loss 1.7904 Accuracy 0.6264
Epoch 13 Batch 550 Loss 1.7896 Accuracy 0.6266
Epoch 13 Batch 600 Loss 1.7909 Accuracy 0.6266
Epoch 13 Batch 650 Loss 1.7947 Accuracy 0.6260
Epoch 13 Batch 700 Loss 1.7988 Accuracy 0.6255
Epoch 13 Batch 750 Loss 1.8013 Accuracy 0.6254
Epoch 13 Batch 800 Loss 1.8027 Accuracy 0.6253
Epoch 13 Loss 1.8044 Accuracy 0.6251
Time taken for 1 epoch: 50.61 secs

Epoch 14 Batch 0 Loss 1.5408 Accuracy 0.6717
Epoch 14 Batch 50 Loss 1.6916 Accuracy 0.6429
Epoch 14 Batch 100 Loss 1.6907 Accuracy 0.6429
Epoch 14 Batch 150 Loss 1.7023 Accuracy 0.6407
Epoch 14 Batch 200 Loss 1.7057 Accuracy 0.6400
Epoch 14 Batch 250 Loss 1.7103 Accuracy 0.6390
Epoch 14 Batch 300 Loss 1.7094 Accuracy 0.6392
Epoch 14 Batch 350 Loss 1.7124 Accuracy 0.6389
Epoch 14 Batch 400 Loss 1.7136 Accuracy 0.6387
Epoch 14 Batch 450 Loss 1.7161 Accuracy 0.6383
Epoch 14 Batch 500 Loss 1.7169 Accuracy 0.6381
Epoch 14 Batch 550 Loss 1.7184 Accuracy 0.6380
Epoch 14 Batch 600 Loss 1.7204 Accuracy 0.6376
Epoch 14 Batch 650 Loss 1.7242 Accuracy 0.6370
Epoch 14 Batch 700 Loss 1.7270 Accuracy 0.6365
Epoch 14 Batch 750 Loss 1.7311 Accuracy 0.6359
Epoch 14 Batch 800 Loss 1.7329 Accuracy 0.6357
Epoch 14 Loss 1.7332 Accuracy 0.6357
Time taken for 1 epoch: 49.79 secs

Epoch 15 Batch 0 Loss 1.6071 Accuracy 0.6600
Epoch 15 Batch 50 Loss 1.6075 Accuracy 0.6563
Epoch 15 Batch 100 Loss 1.6176 Accuracy 0.6543
Epoch 15 Batch 150 Loss 1.6315 Accuracy 0.6522
Epoch 15 Batch 200 Loss 1.6394 Accuracy 0.6505
Epoch 15 Batch 250 Loss 1.6374 Accuracy 0.6508
Epoch 15 Batch 300 Loss 1.6396 Accuracy 0.6503
Epoch 15 Batch 350 Loss 1.6453 Accuracy 0.6494
Epoch 15 Batch 400 Loss 1.6499 Accuracy 0.6485
Epoch 15 Batch 450 Loss 1.6535 Accuracy 0.6480
Epoch 15 Batch 500 Loss 1.6549 Accuracy 0.6479
Epoch 15 Batch 550 Loss 1.6592 Accuracy 0.6470
Epoch 15 Batch 600 Loss 1.6633 Accuracy 0.6464
Epoch 15 Batch 650 Loss 1.6653 Accuracy 0.6462
Epoch 15 Batch 700 Loss 1.6672 Accuracy 0.6460
Epoch 15 Batch 750 Loss 1.6705 Accuracy 0.6455
Epoch 15 Batch 800 Loss 1.6713 Accuracy 0.6454
Saving checkpoint for epoch 15 at ./checkpoints/train/ckpt-3
Epoch 15 Loss 1.6711 Accuracy 0.6455
Time taken for 1 epoch: 49.58 secs

Epoch 16 Batch 0 Loss 1.5173 Accuracy 0.6608
Epoch 16 Batch 50 Loss 1.5766 Accuracy 0.6589
Epoch 16 Batch 100 Loss 1.5695 Accuracy 0.6607
Epoch 16 Batch 150 Loss 1.5790 Accuracy 0.6588
Epoch 16 Batch 200 Loss 1.5813 Accuracy 0.6589
Epoch 16 Batch 250 Loss 1.5881 Accuracy 0.6578
Epoch 16 Batch 300 Loss 1.5924 Accuracy 0.6570
Epoch 16 Batch 350 Loss 1.5967 Accuracy 0.6565
Epoch 16 Batch 400 Loss 1.5992 Accuracy 0.6560
Epoch 16 Batch 450 Loss 1.6021 Accuracy 0.6554
Epoch 16 Batch 500 Loss 1.6016 Accuracy 0.6557
Epoch 16 Batch 550 Loss 1.6044 Accuracy 0.6554
Epoch 16 Batch 600 Loss 1.6072 Accuracy 0.6548
Epoch 16 Batch 650 Loss 1.6100 Accuracy 0.6544
Epoch 16 Batch 700 Loss 1.6125 Accuracy 0.6540
Epoch 16 Batch 750 Loss 1.6164 Accuracy 0.6536
Epoch 16 Batch 800 Loss 1.6184 Accuracy 0.6534
Epoch 16 Loss 1.6194 Accuracy 0.6532
Time taken for 1 epoch: 49.55 secs

Epoch 17 Batch 0 Loss 1.4743 Accuracy 0.6809
Epoch 17 Batch 50 Loss 1.5117 Accuracy 0.6702
Epoch 17 Batch 100 Loss 1.5143 Accuracy 0.6695
Epoch 17 Batch 150 Loss 1.5157 Accuracy 0.6699
Epoch 17 Batch 200 Loss 1.5319 Accuracy 0.6668
Epoch 17 Batch 250 Loss 1.5337 Accuracy 0.6664
Epoch 17 Batch 300 Loss 1.5353 Accuracy 0.6663
Epoch 17 Batch 350 Loss 1.5389 Accuracy 0.6658
Epoch 17 Batch 400 Loss 1.5407 Accuracy 0.6655
Epoch 17 Batch 450 Loss 1.5454 Accuracy 0.6646
Epoch 17 Batch 500 Loss 1.5465 Accuracy 0.6644
Epoch 17 Batch 550 Loss 1.5507 Accuracy 0.6638
Epoch 17 Batch 600 Loss 1.5543 Accuracy 0.6634
Epoch 17 Batch 650 Loss 1.5579 Accuracy 0.6629
Epoch 17 Batch 700 Loss 1.5602 Accuracy 0.6625
Epoch 17 Batch 750 Loss 1.5646 Accuracy 0.6619
Epoch 17 Batch 800 Loss 1.5667 Accuracy 0.6614
Epoch 17 Loss 1.5678 Accuracy 0.6613
Time taken for 1 epoch: 49.26 secs

Epoch 18 Batch 0 Loss 1.5091 Accuracy 0.6582
Epoch 18 Batch 50 Loss 1.4854 Accuracy 0.6739
Epoch 18 Batch 100 Loss 1.4776 Accuracy 0.6749
Epoch 18 Batch 150 Loss 1.4790 Accuracy 0.6746
Epoch 18 Batch 200 Loss 1.4861 Accuracy 0.6735
Epoch 18 Batch 250 Loss 1.4875 Accuracy 0.6736
Epoch 18 Batch 300 Loss 1.4922 Accuracy 0.6730
Epoch 18 Batch 350 Loss 1.4953 Accuracy 0.6725
Epoch 18 Batch 400 Loss 1.5018 Accuracy 0.6714
Epoch 18 Batch 450 Loss 1.5055 Accuracy 0.6710
Epoch 18 Batch 500 Loss 1.5063 Accuracy 0.6710
Epoch 18 Batch 550 Loss 1.5091 Accuracy 0.6705
Epoch 18 Batch 600 Loss 1.5107 Accuracy 0.6701
Epoch 18 Batch 650 Loss 1.5142 Accuracy 0.6695
Epoch 18 Batch 700 Loss 1.5175 Accuracy 0.6690
Epoch 18 Batch 750 Loss 1.5198 Accuracy 0.6687
Epoch 18 Batch 800 Loss 1.5233 Accuracy 0.6683
Epoch 18 Loss 1.5240 Accuracy 0.6682
Time taken for 1 epoch: 49.24 secs

Epoch 19 Batch 0 Loss 1.3142 Accuracy 0.6876
Epoch 19 Batch 50 Loss 1.4266 Accuracy 0.6843
Epoch 19 Batch 100 Loss 1.4270 Accuracy 0.6841
Epoch 19 Batch 150 Loss 1.4367 Accuracy 0.6822
Epoch 19 Batch 200 Loss 1.4445 Accuracy 0.6810
Epoch 19 Batch 250 Loss 1.4516 Accuracy 0.6796
Epoch 19 Batch 300 Loss 1.4517 Accuracy 0.6799
Epoch 19 Batch 350 Loss 1.4592 Accuracy 0.6786
Epoch 19 Batch 400 Loss 1.4637 Accuracy 0.6777
Epoch 19 Batch 450 Loss 1.4640 Accuracy 0.6776
Epoch 19 Batch 500 Loss 1.4669 Accuracy 0.6773
Epoch 19 Batch 550 Loss 1.4672 Accuracy 0.6771
Epoch 19 Batch 600 Loss 1.4714 Accuracy 0.6764
Epoch 19 Batch 650 Loss 1.4766 Accuracy 0.6755
Epoch 19 Batch 700 Loss 1.4781 Accuracy 0.6752
Epoch 19 Batch 750 Loss 1.4817 Accuracy 0.6746
Epoch 19 Batch 800 Loss 1.4834 Accuracy 0.6745
Epoch 19 Loss 1.4833 Accuracy 0.6745
Time taken for 1 epoch: 48.96 secs

Epoch 20 Batch 0 Loss 1.4669 Accuracy 0.6734
Epoch 20 Batch 50 Loss 1.3892 Accuracy 0.6880
Epoch 20 Batch 100 Loss 1.3869 Accuracy 0.6889
Epoch 20 Batch 150 Loss 1.3953 Accuracy 0.6876
Epoch 20 Batch 200 Loss 1.3963 Accuracy 0.6882
Epoch 20 Batch 250 Loss 1.4018 Accuracy 0.6877
Epoch 20 Batch 300 Loss 1.4066 Accuracy 0.6868
Epoch 20 Batch 350 Loss 1.4136 Accuracy 0.6857
Epoch 20 Batch 400 Loss 1.4175 Accuracy 0.6851
Epoch 20 Batch 450 Loss 1.4217 Accuracy 0.6842
Epoch 20 Batch 500 Loss 1.4278 Accuracy 0.6833
Epoch 20 Batch 550 Loss 1.4296 Accuracy 0.6832
Epoch 20 Batch 600 Loss 1.4323 Accuracy 0.6827
Epoch 20 Batch 650 Loss 1.4341 Accuracy 0.6825
Epoch 20 Batch 700 Loss 1.4372 Accuracy 0.6820
Epoch 20 Batch 750 Loss 1.4408 Accuracy 0.6815
Epoch 20 Batch 800 Loss 1.4451 Accuracy 0.6807
Saving checkpoint for epoch 20 at ./checkpoints/train/ckpt-4
Epoch 20 Loss 1.4464 Accuracy 0.6806
Time taken for 1 epoch: 49.74 secs

평가

평가에는 다음 단계가 사용됩니다.

  • 포르투갈어 토크 나이저 ( tokenizers.pt )를 사용하여 입력 문장을 인코딩합니다. 이것은 인코더 입력입니다.
  • 디코더 입력은 [START] 토큰으로 초기화됩니다.
  • 패딩 마스크와 미리보기 마스크를 계산합니다.
  • 그런 다음 decoderencoder 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 going to share with you some very magical things that have 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)

png

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

png

모델이 익숙하지 않은 단어도 괜찮습니다. 입력 데이터 세트에 "트리케라톱스"또는 "백과 사전"이 없으며 모델은 공유 된 어휘 없이도이를 음역하는 방법을 거의 학습합니다.

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 trifters in egypt .
Ground truth   : I read about triceratops in the encyclopedia.

png

요약

이 자습서에서는 위치 인코딩, 다중 머리주의, 마스킹의 중요성 및 변환기를 만드는 방법에 대해 배웠습니다.

다른 데이터 세트를 사용하여 변환기를 훈련 시키십시오. 위의 하이퍼 파라미터를 변경하여 기본 트랜스포머 또는 트랜스포머 XL을 생성 할 수도 있습니다. 여기에 정의 된 레이어를 사용하여 BERT 를 생성하고 최첨단 모델을 학습 할 수도 있습니다. 또한 빔 검색을 구현하여 더 나은 예측을 얻을 수 있습니다.