Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/pt-br/tutorials/load_data/text.ipynb
25118 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

Carregue texto

Este tutorial mostra duas maneiras de carregar e pré-processar texto.

  • Primeiro, você usará utilitários e camadas de pré-processamento do Keras. Isso inclui tf.keras.utils.text_dataset_from_directory para transformar os dados em um tf.data.Dataset e tf.keras.layers.TextVectorization para a padronização, tokenização e vetorização dos dados. Se você for iniciante no TensorFlow, comece com eles.

  • Em seguida, você usará utilitários de nível inferior, como tf.data.TextLineDataset para carregar arquivos de texto, e APIs TensorFlow Text, como text.UnicodeScriptTokenizer e text.case_fold_utf8, para pré-processar os dados para um controle mais granular.

!pip install "tensorflow-text==2.11.*"
import collections import pathlib import tensorflow as tf from tensorflow.keras import layers from tensorflow.keras import losses from tensorflow.keras import utils from tensorflow.keras.layers import TextVectorization import tensorflow_datasets as tfds import tensorflow_text as tf_text

Exemplo 1: preveja a tag de uma pergunta do Stack Overflow

Como um primeiro exemplo, baixe o dataset de perguntas de programação do Stack Overflow. Cada pergunta ("How do I sort a dictionary by value?", ou "Como classificar um dicionário por valor?") está rotulada com apenas uma tag (Python, CSharp, JavaScript ou Java). Sua tarefa é desenvolver um modelo que prevê a tag de uma pergunta. Isso é um exemplo de classificação multiclasse — um tipo de problema de aprendizado de máquina importante e amplamente aplicável.

Baixe e explore o dataset

Para começar, baixe o dataset do Stack Overflow usando tf.keras.utils.get_file e explore a estrutura do diretório:

data_url = 'https://storage.googleapis.com/download.tensorflow.org/data/stack_overflow_16k.tar.gz' dataset_dir = utils.get_file( origin=data_url, untar=True, cache_dir='stack_overflow', cache_subdir='') dataset_dir = pathlib.Path(dataset_dir).parent
list(dataset_dir.iterdir())
train_dir = dataset_dir/'train' list(train_dir.iterdir())

Os diretórios train/csharp, train/java, train/python e train/javascript contêm vários arquivos de texto, sendo cada um deles uma pergunta do Stack Overflow.

Imprima um arquivo de exemplo e inspecione os dados:

sample_file = train_dir/'python/1755.txt' with open(sample_file) as f: print(f.read())

Carregue o dataset

Em seguida, você vai carregar os dados para fora do disco e prepará-los em um formato adequado para treinamento. Para isso, você usará o utilitário tf.keras.utils.text_dataset_from_directory para criar um tf.data.Dataset rotulado. Se você for iniciante no tf.data, é uma coleção poderosa de ferramentas para criar pipelines de entrada. (Saiba mais no guia tf.data: crie pipelines de entrada do TensorFlow.)

A API tf.keras.utils.text_dataset_from_directory espera uma estrutura de diretório assim:

train/ ...csharp/ ......1.txt ......2.txt ...java/ ......1.txt ......2.txt ...javascript/ ......1.txt ......2.txt ...python/ ......1.txt ......2.txt

Ao realizar um experimento de aprendizado de máquina, é uma prática recomendada dividir o dataset em três: treinamento, validação e teste.

O dataset do Stack Overflow já foi dividido em treinamento e teste, mas ainda falta o dataset de validação.

Crie um dataset de validação com uma divisão de 80:20 dos dados de treinamento usando tf.keras.utils.text_dataset_from_directory com validation_split definido como 0.2 (ou seja, 20%):

batch_size = 32 seed = 42 raw_train_ds = utils.text_dataset_from_directory( train_dir, batch_size=batch_size, validation_split=0.2, subset='training', seed=seed)

Como a saída da célula anterior sugere, há 8.000 exemplos nessa pasta de treinamento, e você usará 80% (ou 6.400) para treinamento. Você aprenderá em um instante que é possível treinar um modelo ao passar um tf.data.Dataset diretamente para Model.fit.

Primeiro, itere o dataset e imprima alguns exemplos, para ter uma noção dos dados.

Observação: para aumentar a dificuldade do problema de classificação, o autor do dataset trocou as ocorrências das palavras Python, CSharp, JavaScript ou Java na pergunta de programação pela palavra blank.

for text_batch, label_batch in raw_train_ds.take(1): for i in range(10): print("Question: ", text_batch.numpy()[i]) print("Label:", label_batch.numpy()[i])

Os rótulos são 0, 1, 2 ou 3. Para conferir quais deles correspondem a cada rótulo de string, inspecione a propriedade class_names do dataset:

for i, label in enumerate(raw_train_ds.class_names): print("Label", i, "corresponds to", label)

Em seguida, você criará um dataset de validação e teste usando tf.keras.utils.text_dataset_from_directory. Você usará as 1.600 avaliações restantes do dataset de treinamento para validação.

Observação: ao usar os argumentos validation_split e subset de tf.keras.utils.text_dataset_from_directory, especifique uma semente aleatória ou passe shuffle=False, para que as divisões de validação e treinamento não se sobreponham.

# Create a validation set. raw_val_ds = utils.text_dataset_from_directory( train_dir, batch_size=batch_size, validation_split=0.2, subset='validation', seed=seed)
test_dir = dataset_dir/'test' # Create a test set. raw_test_ds = utils.text_dataset_from_directory( test_dir, batch_size=batch_size)

Prepare o dataset para treinamento

Em seguida, você padronizará, tokenizará e vetorizará os dados usando a camada tf.keras.layers.TextVectorization.

  • A padronização se refere ao pré-processamento do texto, geralmente para remover pontuação ou elementos HTML, simplificando o dataset.

  • A tokenização se refere à divisão de strings em tokens (por exemplo, dividindo uma frase em palavras individuais ao separar nos espaços em branco).

  • A vetorização se refere à conversão de tokens em números para alimentar uma rede neural.

Todas essas tarefas podem ser realizadas com essa camada. (Saiba mais sobre cada uma delas nos documentos da API tf.keras.layers.TextVectorization.)

Observe que:

  • A padronização padrão converte o texto para letras minúsculas e remove a pontuação (standardize='lower_and_strip_punctuation').

  • O tokenizer padrão faz a separação nos espaços em branco (split='whitespace').

  • O modo de vetorização padrão é 'int' (output_mode='int'). Isso gera índices de números inteiros (um por token). Esse modo pode ser usado para criar modelos que consideram a ordem das palavras. Você também pode usar outros modos, como 'binary', para criar modelos bag-of-words.

Você criará dois modelos para saber mais sobre a padronização, tokenização e vetorização com TextVectorization:

  • Primeiro, você usará o modo de vetorização 'binary' para criar um modelo bag-of-words.

  • Em seguida, você usará o modo 'int' com uma ConvNet 1D.

VOCAB_SIZE = 10000 binary_vectorize_layer = TextVectorization( max_tokens=VOCAB_SIZE, output_mode='binary')

Para o modo 'int', além do tamanho de vocabulário máximo, você precisa definir um comprimento de sequência máximo explícito (MAX_SEQUENCE_LENGTH), que fará com que a camada preencha ou trunque as sequências exatamente para valores output_sequence_length:

MAX_SEQUENCE_LENGTH = 250 int_vectorize_layer = TextVectorization( max_tokens=VOCAB_SIZE, output_mode='int', output_sequence_length=MAX_SEQUENCE_LENGTH)

Em seguida, chame TextVectorization.adapt para adequar o estado da camada de pré-processamento ao dataset. Isso fará com que o modelo crie um índice de strings para os números inteiros.

Observação: é importante só usar seus dados de treinamento ao chamar TextVectorization.adapt, já que o uso do dataset de teste vazaria informações.

# Make a text-only dataset (without labels), then call `TextVectorization.adapt`. train_text = raw_train_ds.map(lambda text, labels: text) binary_vectorize_layer.adapt(train_text) int_vectorize_layer.adapt(train_text)

Imprima o resultado de usar essas camadas para pré-processar dados:

def binary_vectorize_text(text, label): text = tf.expand_dims(text, -1) return binary_vectorize_layer(text), label
def int_vectorize_text(text, label): text = tf.expand_dims(text, -1) return int_vectorize_layer(text), label
# Retrieve a batch (of 32 reviews and labels) from the dataset. text_batch, label_batch = next(iter(raw_train_ds)) first_question, first_label = text_batch[0], label_batch[0] print("Question", first_question) print("Label", first_label)
print("'binary' vectorized question:", binary_vectorize_text(first_question, first_label)[0])
print("'int' vectorized question:", int_vectorize_text(first_question, first_label)[0])

Conforme mostrado acima, o modo 'binary' de TextVectorization retorna um array que indica quais tokens existem pelo menos uma vez na entrada, enquanto o modo 'int' substitui cada token por um número inteiro, preservando a ordem deles.

Você pode consultar o token (string) correspondente a cada número inteiro ao chamar TextVectorization.get_vocabulary na camada:

print("1289 ---> ", int_vectorize_layer.get_vocabulary()[1289]) print("313 ---> ", int_vectorize_layer.get_vocabulary()[313]) print("Vocabulary size: {}".format(len(int_vectorize_layer.get_vocabulary())))

Já está quase tudo pronto para treinar o modelo.

Como etapa final de pré-processamento, você aplicará as camadas TextVectorization criadas antes para os datasets de treinamento, validação e teste:

binary_train_ds = raw_train_ds.map(binary_vectorize_text) binary_val_ds = raw_val_ds.map(binary_vectorize_text) binary_test_ds = raw_test_ds.map(binary_vectorize_text) int_train_ds = raw_train_ds.map(int_vectorize_text) int_val_ds = raw_val_ds.map(int_vectorize_text) int_test_ds = raw_test_ds.map(int_vectorize_text)

Configure o dataset para melhor desempenho

Há dois métodos importantes que você deve usar ao carregar os dados para garantir que a I/O não seja bloqueada.

  • Dataset.cache mantém os dados na memória após o carregamento fora do disco. Isso garante que o dataset não se torne um gargalo ao treinar seu modelo. Se o dataset for muito grande para a memória, você também pode usar esse método para criar um cache no disco eficaz, que tem uma leitura mais eficiente do que vários arquivos pequenos.

  • Dataset.prefetch sobrepõe o pré-processamento de dados e a execução do modelo durante o treinamento.

Saiba mais sobre ambos os métodos, além de como armazenar os dados em cache no disco, na seção Pré-busca do guia Melhor desempenho com a API tf.data API.

AUTOTUNE = tf.data.AUTOTUNE def configure_dataset(dataset): return dataset.cache().prefetch(buffer_size=AUTOTUNE)
binary_train_ds = configure_dataset(binary_train_ds) binary_val_ds = configure_dataset(binary_val_ds) binary_test_ds = configure_dataset(binary_test_ds) int_train_ds = configure_dataset(int_train_ds) int_val_ds = configure_dataset(int_val_ds) int_test_ds = configure_dataset(int_test_ds)

Treine o modelo

Chegou a hora de criar sua rede neural.

Para os dados 'binary' vetorizados, defina um modelo linear bag-of-words simples. Depois, configure e treine esse modelo:

binary_model = tf.keras.Sequential([layers.Dense(4)]) binary_model.compile( loss=losses.SparseCategoricalCrossentropy(from_logits=True), optimizer='adam', metrics=['accuracy']) history = binary_model.fit( binary_train_ds, validation_data=binary_val_ds, epochs=10)

Em seguida, você usará a camada 'int' vetorizada para criar uma ConvNet 1D:

def create_model(vocab_size, num_labels): model = tf.keras.Sequential([ layers.Embedding(vocab_size, 64, mask_zero=True), layers.Conv1D(64, 5, padding="valid", activation="relu", strides=2), layers.GlobalMaxPooling1D(), layers.Dense(num_labels) ]) return model
# `vocab_size` is `VOCAB_SIZE + 1` since `0` is used additionally for padding. int_model = create_model(vocab_size=VOCAB_SIZE + 1, num_labels=4) int_model.compile( loss=losses.SparseCategoricalCrossentropy(from_logits=True), optimizer='adam', metrics=['accuracy']) history = int_model.fit(int_train_ds, validation_data=int_val_ds, epochs=5)

Compare os dois modelos:

print("Linear model on binary vectorized data:") print(binary_model.summary())
print("ConvNet model on int vectorized data:") print(int_model.summary())

Avalie os dois modelos com o dataset de teste:

binary_loss, binary_accuracy = binary_model.evaluate(binary_test_ds) int_loss, int_accuracy = int_model.evaluate(int_test_ds) print("Binary model accuracy: {:2.2%}".format(binary_accuracy)) print("Int model accuracy: {:2.2%}".format(int_accuracy))

Observação: esse dataset de exemplo representa um problema de classificação bastante simples. Datasets e problemas mais complexos revelam diferenças sutis mas significativas nas estratégias de pré-processamento e arquiteturas de modelos. Teste épocas e hiperparâmetros diferentes para comparar várias abordagens.

Exporte o modelo

No código acima, você aplicou o tf.keras.layers.TextVectorization ao dataset antes de alimentar o modelo com texto. Se você quiser tornar o modelo capaz de processar strings brutas (por exemplo, para simplificar a implantação), é possível incluir a camada TextVectorization dentro do modelo.

Para isso, crie um novo modelo usando os pesos que você acabou de treinar:

export_model = tf.keras.Sequential( [binary_vectorize_layer, binary_model, layers.Activation('sigmoid')]) export_model.compile( loss=losses.SparseCategoricalCrossentropy(from_logits=False), optimizer='adam', metrics=['accuracy']) # Test it with `raw_test_ds`, which yields raw strings loss, accuracy = export_model.evaluate(raw_test_ds) print("Accuracy: {:2.2%}".format(accuracy))

Agora, seu modelo aceita strings brutas como entrada e prevê uma pontuação para cada rótulo usando Model.predict. Defina uma função para encontrar o rótulo com a pontuação máxima:

def get_string_labels(predicted_scores_batch): predicted_int_labels = tf.math.argmax(predicted_scores_batch, axis=1) predicted_labels = tf.gather(raw_train_ds.class_names, predicted_int_labels) return predicted_labels

Realize a inferência dos dados novos

inputs = [ "how do I extract keys from a dict into a list?", # 'python' "debug public static void main(string[] args) {...}", # 'java' ] predicted_scores = export_model.predict(inputs) predicted_labels = get_string_labels(predicted_scores) for input, label in zip(inputs, predicted_labels): print("Question: ", input) print("Predicted label: ", label.numpy())

Incluindo a lógica de pré-processamento de texto dentro do modelo, você pode exportar um modelo para produção que simplifica a implantação e reduz o potencial de desvio de treinamento/teste.

Há uma diferença de desempenho que você deve considerar ao escolher onde aplicar o tf.keras.layers.TextVectorization. Ao usá-lo fora do modelo, você pode fazer o processamento de CPU assíncrono e armazenar os dados em buffer ao treinar na GPU. Portanto, se você estiver treinando seu modelo na GPU, deve escolher essa opção para obter o melhor desempenho ao desenvolver o modelo. Depois, quando você estiver pronto para preparar a implantação, troque para a inclusão da camada TextVectorization dentro do modelo.

Acesse o tutorial Salve e carregue modelos para saber mais sobre como salvar modelos.

Exemplo 2: preveja o tradutor da Ilíada

Confira a seguir como usar o tf.data.TextLineDataset para carregar exemplos de arquivos de texto e o TensorFlow Text para pré-processar dados. Você usará três traduções em inglês da mesma obra, a Ilíada do Homero, e treinará um modelo para identificar o tradutor a partir de uma única linha de texto.

Baixe e explore o dataset

Os textos das três traduções são de:

Os arquivos de texto usados neste tutorial passaram por algumas tarefas típicas de pré-processamento, como remoção de cabeçalhos, rodapés, números de linhas e títulos de capítulos dos documentos.

Baixe esses arquivos ligeiramente manipulados localmente:

DIRECTORY_URL = 'https://storage.googleapis.com/download.tensorflow.org/data/illiad/' FILE_NAMES = ['cowper.txt', 'derby.txt', 'butler.txt'] for name in FILE_NAMES: text_dir = utils.get_file(name, origin=DIRECTORY_URL + name) parent_dir = pathlib.Path(text_dir).parent list(parent_dir.iterdir())

Carregue o dataset

Antes, com o tf.keras.utils.text_dataset_from_directory todo o conteúdo de um arquivo era tratado como um único exemplo. Aqui, você usará o tf.data.TextLineDataset, feito para criar um tf.data.Dataset a partir de um arquivo de texto em que cada exemplo é uma linha de texto do arquivo original. O TextLineDataset é útil para dados de texto que são principalmente baseados em linha (por exemplo, poesia ou logs de erros).

Itere esses arquivos, carregando cada um em um dataset próprio. Cada exemplo precisa ser rotulado individualmente, então use Dataset.map para aplicar uma função rotuladora. Isso fará com que cada exemplo do dataset seja iterado, retornando pares (example, label).

def labeler(example, index): return example, tf.cast(index, tf.int64)
labeled_data_sets = [] for i, file_name in enumerate(FILE_NAMES): lines_dataset = tf.data.TextLineDataset(str(parent_dir/file_name)) labeled_dataset = lines_dataset.map(lambda ex: labeler(ex, i)) labeled_data_sets.append(labeled_dataset)

Em seguida, combine esses datasets rotulados em um único dataset usando Dataset.concatenate e o misture com Dataset.shuffle:

BUFFER_SIZE = 50000 BATCH_SIZE = 64 VALIDATION_SIZE = 5000
all_labeled_data = labeled_data_sets[0] for labeled_dataset in labeled_data_sets[1:]: all_labeled_data = all_labeled_data.concatenate(labeled_dataset) all_labeled_data = all_labeled_data.shuffle( BUFFER_SIZE, reshuffle_each_iteration=False)

Imprima alguns exemplos como antes. O dataset ainda não foi dividido em lotes, então cada entrada em all_labeled_data corresponde a um ponto de dados:

for text, label in all_labeled_data.take(10): print("Sentence: ", text.numpy()) print("Label:", label.numpy())

Prepare o dataset para treinamento

Em vez de usar tf.keras.layers.TextVectorization para pré-processar o dataset de texto, use as APIs TensorFlow Text para padronizar e tokenizar os dados, crie um vocabulário e use tf.lookup.StaticVocabularyTable para mapear tokens para números inteiros e alimentar o modelo. (Saiba mais sobre o TensorFlow Text).

Defina uma função para converter o texto em letras maiúsculas e realizar a tokenização:

  • O TensorFlow Text oferece vários tokenizers. Neste exemplo, você usará text.UnicodeScriptTokenizer para tokenizar o dataset.

  • Você usará Dataset.map para aplicar a tokenização ao dataset.

tokenizer = tf_text.UnicodeScriptTokenizer()
def tokenize(text, unused_label): lower_case = tf_text.case_fold_utf8(text) return tokenizer.tokenize(lower_case)
tokenized_ds = all_labeled_data.map(tokenize)

Itere o dataset e imprima alguns exemplos tokenizados:

for text_batch in tokenized_ds.take(5): print("Tokens: ", text_batch.numpy())

Em seguida, crie um vocabulário ao ordenar os tokens por frequência e manter os principais tokens VOCAB_SIZE:

tokenized_ds = configure_dataset(tokenized_ds) vocab_dict = collections.defaultdict(lambda: 0) for toks in tokenized_ds.as_numpy_iterator(): for tok in toks: vocab_dict[tok] += 1 vocab = sorted(vocab_dict.items(), key=lambda x: x[1], reverse=True) vocab = [token for token, count in vocab] vocab = vocab[:VOCAB_SIZE] vocab_size = len(vocab) print("Vocab size: ", vocab_size) print("First five vocab entries:", vocab[:5])

Para converter os tokens em números inteiros, use o dataset vocab para criar um tf.lookup.StaticVocabularyTable. Você mapeará os tokens para números inteiros no intervalo [2, vocab_size + 2]. Assim como a camada TextVectorization, 0 é reservado para indicar o preenchimento e 1 para indicar um token fora do vocabulário (OOV).

keys = vocab values = range(2, len(vocab) + 2) # Reserve `0` for padding, `1` for OOV tokens. init = tf.lookup.KeyValueTensorInitializer( keys, values, key_dtype=tf.string, value_dtype=tf.int64) num_oov_buckets = 1 vocab_table = tf.lookup.StaticVocabularyTable(init, num_oov_buckets)

Por fim, defina uma função para padronizar, tokenizar e vetorizar o dataset usando o tokenizer e a tabela de consulta:

def preprocess_text(text, label): standardized = tf_text.case_fold_utf8(text) tokenized = tokenizer.tokenize(standardized) vectorized = vocab_table.lookup(tokenized) return vectorized, label

Teste isso em um único exemplo para imprimir a saída:

example_text, example_label = next(iter(all_labeled_data)) print("Sentence: ", example_text.numpy()) vectorized_text, example_label = preprocess_text(example_text, example_label) print("Vectorized sentence: ", vectorized_text.numpy())

Agora execute a função de pré-processamento no dataset usando Dataset.map:

all_encoded_data = all_labeled_data.map(preprocess_text)

Divida o dataset em treinamento e validação

A camada TextVectorization do Keras também divide em lotes e preenche os dados vetorizados. O preenchimento é necessário porque os exemplos dentro de um lote precisam ser do mesmo tamanho e formato, mas os exemplos nesses datasets não são todos do mesmo tamanho — cada linha de texto tem um número diferente de palavras.

tf.data.Dataset é compatível com a divisão e os lotes preenchidos de datasets:

train_data = all_encoded_data.skip(VALIDATION_SIZE).shuffle(BUFFER_SIZE) validation_data = all_encoded_data.take(VALIDATION_SIZE)
train_data = train_data.padded_batch(BATCH_SIZE) validation_data = validation_data.padded_batch(BATCH_SIZE)

Agora, validation_data e train_data não são coleções de pares (example, label), e sim coleções de lotes. Cada lote é um par de (vários exemplos, vários rótulos) representado como arrays.

Para ilustrar isso:

sample_text, sample_labels = next(iter(validation_data)) print("Text batch shape: ", sample_text.shape) print("Label batch shape: ", sample_labels.shape) print("First text example: ", sample_text[0]) print("First label example: ", sample_labels[0])

Já que você usou 0 para preenchimento e 1 para tokens fora do vocabulário (OOV), o tamanho do vocabulário aumentou em dois:

vocab_size += 2

Configure os datasets para melhor desempenho como antes:

train_data = configure_dataset(train_data) validation_data = configure_dataset(validation_data)

Treine o modelo

Você pode treinar um modelo com esse dataset como antes:

model = create_model(vocab_size=vocab_size, num_labels=3) model.compile( optimizer='adam', loss=losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy']) history = model.fit(train_data, validation_data=validation_data, epochs=3)
loss, accuracy = model.evaluate(validation_data) print("Loss: ", loss) print("Accuracy: {:2.2%}".format(accuracy))

Exporte o modelo

Para tornar o modelo capaz de aceitar strings brutas como entrada, crie uma camada TextVectorization do Keras que realize os mesmos passos que sua função de pré-processamento personalizado. Como você já treinou um vocabulário, use TextVectorization.set_vocabulary (em vez de TextVectorization.adapt), que treina um novo vocabulário.

preprocess_layer = TextVectorization( max_tokens=vocab_size, standardize=tf_text.case_fold_utf8, split=tokenizer.tokenize, output_mode='int', output_sequence_length=MAX_SEQUENCE_LENGTH) preprocess_layer.set_vocabulary(vocab)
export_model = tf.keras.Sequential( [preprocess_layer, model, layers.Activation('sigmoid')]) export_model.compile( loss=losses.SparseCategoricalCrossentropy(from_logits=False), optimizer='adam', metrics=['accuracy'])
# Create a test dataset of raw strings. test_ds = all_labeled_data.take(VALIDATION_SIZE).batch(BATCH_SIZE) test_ds = configure_dataset(test_ds) loss, accuracy = export_model.evaluate(test_ds) print("Loss: ", loss) print("Accuracy: {:2.2%}".format(accuracy))

A perda e a exatidão do modelo com o dataset de validação codificado e do modelo exportado com o dataset de validação bruto são as mesmas, conforme esperado.

Realize a inferência dos dados novos

inputs = [ "Join'd to th' Ionians with their flowing robes,", # Label: 1 "the allies, and his armour flashed about him so that he seemed to all", # Label: 2 "And with loud clangor of his arms he fell.", # Label: 0 ] predicted_scores = export_model.predict(inputs) predicted_labels = tf.math.argmax(predicted_scores, axis=1) for input, label in zip(inputs, predicted_labels): print("Question: ", input) print("Predicted label: ", label.numpy())

Baixe mais datasets usando o TensorFlow Datasets (TFDS)

Você pode baixar muitos outros datasets no TensorFlow Datasets.

Neste exemplo, você usará o grande dataset de avaliações de filmes do IMDB para treinar um modelo para classificação de sentimentos:

# Training set. train_ds = tfds.load( 'imdb_reviews', split='train[:80%]', batch_size=BATCH_SIZE, shuffle_files=True, as_supervised=True)
# Validation set. val_ds = tfds.load( 'imdb_reviews', split='train[80%:]', batch_size=BATCH_SIZE, shuffle_files=True, as_supervised=True)

Imprima alguns exemplos:

for review_batch, label_batch in val_ds.take(1): for i in range(5): print("Review: ", review_batch[i].numpy()) print("Label: ", label_batch[i].numpy())

Agora você pode pré-processar os dados e treinar um modelo como antes.

Observação: você usará tf.keras.losses.BinaryCrossentropy em vez de tf.keras.losses.SparseCategoricalCrossentropy para seu modelo, já que esse é um problema de classificação binária.

Prepare o dataset para treinamento

vectorize_layer = TextVectorization( max_tokens=VOCAB_SIZE, output_mode='int', output_sequence_length=MAX_SEQUENCE_LENGTH) # Make a text-only dataset (without labels), then call `TextVectorization.adapt`. train_text = train_ds.map(lambda text, labels: text) vectorize_layer.adapt(train_text)
def vectorize_text(text, label): text = tf.expand_dims(text, -1) return vectorize_layer(text), label
train_ds = train_ds.map(vectorize_text) val_ds = val_ds.map(vectorize_text)
# Configure datasets for performance as before. train_ds = configure_dataset(train_ds) val_ds = configure_dataset(val_ds)

Crie, configure e treine o modelo

model = create_model(vocab_size=VOCAB_SIZE + 1, num_labels=1) model.summary()
model.compile( loss=losses.BinaryCrossentropy(from_logits=True), optimizer='adam', metrics=['accuracy'])
history = model.fit(train_ds, validation_data=val_ds, epochs=3)
loss, accuracy = model.evaluate(val_ds) print("Loss: ", loss) print("Accuracy: {:2.2%}".format(accuracy))

Exporte o modelo

export_model = tf.keras.Sequential( [vectorize_layer, model, layers.Activation('sigmoid')]) export_model.compile( loss=losses.SparseCategoricalCrossentropy(from_logits=False), optimizer='adam', metrics=['accuracy'])
# 0 --> negative review # 1 --> positive review inputs = [ "This is a fantastic movie.", "This is a bad movie.", "This movie was so bad that it was good.", "I will never say yes to watching this movie.", ] predicted_scores = export_model.predict(inputs) predicted_labels = [int(round(x[0])) for x in predicted_scores] for input, label in zip(inputs, predicted_labels): print("Question: ", input) print("Predicted label: ", label)

Conclusão

Este tutorial mostra diversas maneiras de carregar e pré-processar texto. Como próximo passo, você pode explorar mais tutoriais de pré-processamento de texto do TensorFlow Text, como:

Você também pode encontrar novos datasets no TensorFlow Datasets. Para saber mais sobre o tf.data, confira o guia sobre a criação de pipelines de entrada.