Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/pt-br/tutorials/load_data/images.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 e faça o pré-processamento de imagens

Este tutorial mostra como carregar e fazer o pré-processamento de um dataset de imagens de três maneiras:

  • Primeiro, você usará utilitários de pré-processamento do Keras de alto nível (como tf.keras.utils.image_dataset_from_directory) e camadas (como tf.keras.layers.Rescaling) para ler um diretório de imagens no disco.

  • Em seguida, você escreverá seu próprio pipeline de entrada do zero usando tf.data.

  • Por fim, você baixará um dataset do vasto catálogo disponível no TensorFlow Datasets.

Configuração

import numpy as np import os import PIL import PIL.Image import tensorflow as tf import tensorflow_datasets as tfds
print(tf.__version__)

Baixe o dataset Flowers

Este tutorial usa um dataset de milhares de fotos de flores. O dataset Flowers contém cinco subdiretórios, um por classe:

flowers_photos/ daisy/ dandelion/ roses/ sunflowers/ tulips/

Observação: todas as imagens têm uma licença CC-BY. Os criadores estão listados no arquivo LICENSE.txt.

import pathlib dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz" archive = tf.keras.utils.get_file(origin=dataset_url, extract=True) data_dir = pathlib.Path(archive).with_suffix('')

Depois de baixar (218MB), você terá uma cópia das fotos de flores disponíveis. Há 3.670 imagens no total:

image_count = len(list(data_dir.glob('*/*.jpg'))) print(image_count)

Cada diretório contém imagens do tipo específico de flor. Aqui estão algumas rosas:

roses = list(data_dir.glob('roses/*')) PIL.Image.open(str(roses[0]))
roses = list(data_dir.glob('roses/*')) PIL.Image.open(str(roses[1]))

Carregue os dados usando um utilitário do Keras

Vamos carregar essas imagens fora do disco usando o utilitário tf.keras.utils.image_dataset_from_directory prático.

Crie um dataset

Defina alguns parâmetros para o loader:

batch_size = 32 img_height = 180 img_width = 180

É recomendável usar uma divisão de validação ao desenvolver seu modelo. Você usará 80% das imagens para treinamento e 20% para validação.

train_ds = tf.keras.utils.image_dataset_from_directory( data_dir, validation_split=0.2, subset="training", seed=123, image_size=(img_height, img_width), batch_size=batch_size)
val_ds = tf.keras.utils.image_dataset_from_directory( data_dir, validation_split=0.2, subset="validation", seed=123, image_size=(img_height, img_width), batch_size=batch_size)

Encontre os nomes das classes na característica class_names desses datasets.

class_names = train_ds.class_names print(class_names)

Visualize os dados

Aqui estão as primeiras nove imagens do dataset de treinamento.

import matplotlib.pyplot as plt plt.figure(figsize=(10, 10)) for images, labels in train_ds.take(1): for i in range(9): ax = plt.subplot(3, 3, i + 1) plt.imshow(images[i].numpy().astype("uint8")) plt.title(class_names[labels[i]]) plt.axis("off")

Você pode treinar um modelo usando esses datasets ao passá-los para model.fit (mostrado mais adiante neste tutorial). Se você quiser, também pode iterar o dataset manualmente e recuperar lotes de imagens:

for image_batch, labels_batch in train_ds: print(image_batch.shape) print(labels_batch.shape) break

O image_batch é um tensor de formato (32, 180, 180, 3). Ele é um lote de 32 imagens com o formato 180x180x3 (a última dimensão refere-se aos canais de cores RGB). O label_batch é um tensor de formato (32,), que são os rótulos correspondentes às 32 imagens.

Você pode chamar .numpy() em qualquer um desses tensores para convertê-los em um numpy.ndarray.

Padronize os dados

Os valores de canais RGB estão no intervalo [0, 255]. Isso não é o ideal para uma rede neural. Em geral, você deve procurar diminuir seus valores de entrada.

Aqui, você padronizará os valores para colocá-los no intervalo [0, 1] usando tf.keras.layers.Rescaling:

normalization_layer = tf.keras.layers.Rescaling(1./255)

Há duas maneiras de usar essa camada. Você pode aplicá-la ao dataset ao chamar Dataset.map:

normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y)) image_batch, labels_batch = next(iter(normalized_ds)) first_image = image_batch[0] # Notice the pixel values are now in `[0,1]`. print(np.min(first_image), np.max(first_image))

Ou você pode incluir a camada dentro da definição do modelo para simplificar a implantação. Você usará a segunda abordagem aqui.

Observação: se você quiser escalar os valores de pixel para [-1,1], é possível escrever tf.keras.layers.Rescaling(1./127.5, offset=-1).

Observação: você redimensionou imagens anteriormente usando o argumento image_size de tf.keras.utils.image_dataset_from_directory. Se você quiser incluir a lógica de redimensionamento no seu modelo também, pode usar a camada tf.keras.layers.Resizing.

Configure o dataset para melhor desempenho

Vamos usar a pré-busca em buffer para gerar dados do disco sem o bloqueio de I/O. Esses são dois métodos importantes que você deve usar ao carregar os dados:

  • Dataset.cache mantém a imagem na memória após o carregamento fora do disco durante a primeira época. 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.

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

Os leitores interessados podem saber 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.

AUTOTUNE = tf.data.AUTOTUNE train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE) val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

Treine um modelo

Para completar, veja como treinar um modelo simples usando os datasets que você acabou de preparar.

O modelo Sequential consiste em três blocos de convolução (tf.keras.layers.Conv2D) com uma camada de pooling máximo (tf.keras.layers.MaxPooling2D) em cada um. Há uma camada totalmente conectada (tf.keras.layers.Dense) com 128 unidades sobre ela, que é ativada por uma função de ativação ReLU ('relu'). Esse modelo não foi ajustado de maneira alguma — o objetivo é mostrar a mecânica de uso dos datasets que você acabou de criar. Para saber mais sobre a classificação de imagens, acesse o tutorial Classificação de imagens.

num_classes = 5 model = tf.keras.Sequential([ tf.keras.layers.Rescaling(1./255), tf.keras.layers.Conv2D(32, 3, activation='relu'), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Conv2D(32, 3, activation='relu'), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Conv2D(32, 3, activation='relu'), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(num_classes) ])

Escolha o otimizador tf.keras.optimizers.Adam e a função de perda tf.keras.losses.SparseCategoricalCrossentropy. Para ver a exatidão do treinamento e da validação para cada época de treinamento, passe o argumento metrics para Model.compile.

model.compile( optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])

Observação: você só treinará para algumas épocas, então este tutorial é rápido.

model.fit( train_ds, validation_data=val_ds, epochs=3 )

Observação: você também pode escrever um loop de treinamento personalizado em vez de usar Model.fit. Para saber mais, acesse o tutorial Escrevendo um loop de treinamento do zero.

Talvez a exatidão da validação seja baixa comparada à exatidão do treinamento, indicando o overfitting do modelo. Saiba mais sobre o overfitting e como reduzir isso neste tutorial.

Usando tf.data para controle mais fino

O utilitário de pré-processamento do Keras acima — tf.keras.utils.image_dataset_from_directory — é uma maneira conveniente de criar um tf.data.Dataset a partir de um diretório de imagens.

Para um controle granular mais fino, você pode escrever seu próprio pipeline de entrada usando tf.data. Esta seção mostra como fazer exatamente isso, começando com os caminhos do arquivo TGZ que você já baixou.

list_ds = tf.data.Dataset.list_files(str(data_dir/'*/*'), shuffle=False) list_ds = list_ds.shuffle(image_count, reshuffle_each_iteration=False)
for f in list_ds.take(5): print(f.numpy())

A estrutura de árvores dos arquivos pode ser usada para compilar uma lista class_names.

class_names = np.array(sorted([item.name for item in data_dir.glob('*') if item.name != "LICENSE.txt"])) print(class_names)

Divida o dataset em conjuntos de treinamento e validação.

val_size = int(image_count * 0.2) train_ds = list_ds.skip(val_size) val_ds = list_ds.take(val_size)

Você pode imprimir o comprimento de cada dataset da seguinte maneira:

print(tf.data.experimental.cardinality(train_ds).numpy()) print(tf.data.experimental.cardinality(val_ds).numpy())

Escreva uma breve função para converter um caminho de arquivo em um par (img, label):

def get_label(file_path): # Convert the path to a list of path components parts = tf.strings.split(file_path, os.path.sep) # The second to last is the class-directory one_hot = parts[-2] == class_names # Integer encode the label return tf.argmax(one_hot)
def decode_img(img): # Convert the compressed string to a 3D uint8 tensor img = tf.io.decode_jpeg(img, channels=3) # Resize the image to the desired size return tf.image.resize(img, [img_height, img_width])
def process_path(file_path): label = get_label(file_path) # Load the raw data from the file as a string img = tf.io.read_file(file_path) img = decode_img(img) return img, label

Use Dataset.map para criar um dataset de pares image, label:

# Set `num_parallel_calls` so multiple images are loaded/processed in parallel. train_ds = train_ds.map(process_path, num_parallel_calls=AUTOTUNE) val_ds = val_ds.map(process_path, num_parallel_calls=AUTOTUNE)
for image, label in train_ds.take(1): print("Image shape: ", image.numpy().shape) print("Label: ", label.numpy())

Configure o dataset para melhor desempenho

Para treinar um modelo com esse dataset, os dados devem:

  • Ser bem misturados.

  • Ser divididos em lotes.

  • Ter os lotes disponíveis assim que possível.

Essas características podem ser adicionadas usando a API tf.data. Para mais detalhes, acesse o guia Desempenho do pipeline de entrada.

def configure_for_performance(ds): ds = ds.cache() ds = ds.shuffle(buffer_size=1000) ds = ds.batch(batch_size) ds = ds.prefetch(buffer_size=AUTOTUNE) return ds train_ds = configure_for_performance(train_ds) val_ds = configure_for_performance(val_ds)

Visualize os dados

É possível visualizar esse dataset de forma parecida com o que você criou antes.

image_batch, label_batch = next(iter(train_ds)) plt.figure(figsize=(10, 10)) for i in range(9): ax = plt.subplot(3, 3, i + 1) plt.imshow(image_batch[i].numpy().astype("uint8")) label = label_batch[i] plt.title(class_names[label]) plt.axis("off")

Continue a treinar o modelo

Você criou manualmente um tf.data.Dataset parecido com o criado pelo tf.keras.utils.image_dataset_from_directory acima. É possível continuar a treinar o modelo com ele. Como antes, você treinará para apenas algumas épocas, diminuindo o tempo de execução.

model.fit( train_ds, validation_data=val_ds, epochs=3 )

Usando o TensorFlow Datasets

Até aqui, este tutorial focou no carregamento de dados fora do disco. Você também pode encontrar um dataset para usar explorando o vasto catálogo de datasets que podem ser facilmente baixados no TensorFlow Datasets.

Como você já carregou o dataset Flowers fora do disco, vamos importá-lo com o TensorFlow Datasets.

Baixe o dataset Flowers usando o TensorFlow Datasets:

(train_ds, val_ds, test_ds), metadata = tfds.load( 'tf_flowers', split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'], with_info=True, as_supervised=True, )

O dataset Flowers tem cinco classes:

num_classes = metadata.features['label'].num_classes print(num_classes)

Recupere uma imagem do dataset:

get_label_name = metadata.features['label'].int2str image, label = next(iter(train_ds)) _ = plt.imshow(image) _ = plt.title(get_label_name(label))

Como antes, lembre-se de criar lotes, misturar os dados e configurar os datasets de treinamento, validação e teste para melhor desempenho:

train_ds = configure_for_performance(train_ds) val_ds = configure_for_performance(val_ds) test_ds = configure_for_performance(test_ds)

Encontre um exemplo completo de como trabalhar com o dataset Flowers e o TensorFlow Datasets ao acessar o tutorial Ampliação de dados.

Próximos passos

Este tutorial mostra duas maneiras de carregar imagens fora do disco. Primeiro, você aprendeu a carregar e fazer o pré-processamento de um dataset de imagens usando camadas e utilitários de pré-processamento do Keras. Em seguida, você aprendeu a escrever um pipeline de entrada do zero usando tf.data. Por fim, você aprendeu a baixar um dataset do TensorFlow Datasets.

Para seus próximos passos: