Path: blob/master/site/pt-br/tutorials/images/data_augmentation.ipynb
25118 views
Copyright 2020 The TensorFlow Authors.
Ampliação de dados
Visão geral
Este tutorial demonstra a ampliação de dados, uma técnica para aumentar a diversidade do conjunto de treinamento por meio da aplicação de transformações aleatórias (mas realistas), como rotação de imagem.
Você aprenderá a aplicar a ampliação de dados de duas maneiras:
Usando as camadas de pré-processamento do Keras, como
tf.keras.layers.Resizing
,tf.keras.layers.Rescaling
,tf.keras.layers.RandomFlip
etf.keras.layers.RandomRotation
.Usando os métodos do
tf.image
, comotf.image.flip_left_right
,tf.image.rgb_to_grayscale
,tf.image.adjust_brightness
,tf.image.central_crop
etf.image.stateless_random*
.
Configuração
Baixar um dataset
Este tutorial usa o dataset tf_flowers. Para sua conveniência, baixe o dataset usando os TensorFlow Datasets. Se você quiser saber mais sobre outras formar de importar dados, confira o tutorial Carregar imagens.
O dataset Flowers tem cinco classes.
Vamos recuperar uma imagem do dataset e usá-la para demonstrar a ampliação de dados.
Usar as camadas de pré-processamento do Keras
Redimensionamento e reescalonamento
Você pode usar as camadas de pré-processamento do Keras para redimensionar suas imagens para um formato consistente (com tf.keras.layers.Resizing
) e para reescalonar valores de pixels (com tf.keras.layers.Rescaling
).
Observação: a camada de reescalonamento acima padroniza os valores de pixel no intervalo [0, 1]
. Se, em vez disso, você quiser que seja [-1, 1]
, pode escrever tf.keras.layers.Rescaling(1./127.5, offset=-1)
.
Você pode visualizar o resultado da aplicação dessas camadas em uma imagem.
Verifique se os pixels estão no intervalo [0, 1]
:
Ampliação de dados
Você também pode usar as camadas de pré-processamento do Keras para fazer ampliação de dados, como tf.keras.layers.RandomFlip
e tf.keras.layers.RandomRotation
.
Vamos criar algumas camadas de pré-processamento e aplicá-las repetidamente à mesma imagem.
Há diversas camadas de pré-processamento que você pode usar para fazer ampliação de dados, incluindo tf.keras.layers.RandomContrast
, tf.keras.layers.RandomCrop
, tf.keras.layers.RandomZoom
, entre outras.
Duas opções de uso das camadas de pré-processamento do Keras
Existem duas formas de usar essas camadas de pré-processamento, com contrapartidas importantes.
Opção 1: tornar as camadas de pré-processamento parte do seu modelo
É importante ficar ciente destes dois pontos importantes nesse caso:
A ampliação de dados será executada no dispositivo de forma síncrona com o restante das suas camadas e se beneficiará da aceleração de GPU.
Ao exportar o modelo usando
model.save
, as camadas de pré-processamento serão salvas junto com o restante do modelo. Se você implantar esse modelo posteriormente, ele vai padronizar as imagens de forma automática (de acordo com a configuração das suas camadas). Assim, você não precisará reimplementar essa lógica no servidor, poupando esforços.
Observação: a ampliação de dados fica inativa no momento do teste, então as imagens de entrada serão ampliadas somente durante chamadas a Model.fit
(e não a Model.evaluate
ou a Model.predict
).
Opção 2: aplicar as camadas de pré-processamento ao seu dataset
Com esta estratégia, você usa Dataset.map
para criar um dataset que gera lotes de imagens ampliadas. Neste caso:
A ampliação de dados acontecerá de forma assíncrona na CPU e não causa bloqueios. Você pode sobrepor o treinamento do modelo na GPU com pré-processamento de dados usando
Dataset.prefetch
, conforme exibido abaixo.Neste caso, as camadas de pré-processamento não serão exportadas com o modelo ao chamar
Model.save
. Você precisará anexá-las ao modelo antes de salvá-lo e reimplementá-las no servidor. Após o treinamento, você pode anexar as camadas de pré-processamento antes da exportação.
Confira um exemplo da primeira opção no tutorial Classificação de imagens. Demonstraremos a segunda opção aqui.
Aplicar as camadas de pré-processamento aos datasets
Configure os datasets de treinamento, validação e teste com as camadas de pré-processamento do Keras criadas anteriormente. Você também vai configurar os datasets para melhor desempenho usando leituras paralelas e pré-busca em buffers para gerar lotes pelo disco sem bloqueio de I/O (saiba mais sobre o desempenho do dataset no guia Desempenho melhor com a API tf.data).
Observação: a ampliação de dados deve ser aplicada somente ao conjunto de treinamento.
Treinar um modelo
Para completar, agora você treinará um modelo simples usando os datasets que 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 para exatidão (o objetivo é mostrar as mecânicas).
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
.
Treine com algumas épocas:
Ampliação de dados personalizada
Você também pode criar camadas personalizadas de ampliação de dados.
Esta seção do tutorial mostra duas maneiras de fazer isso:
Primeiro, você criará uma camada
tf.keras.layers.Lambda
. Essa é uma boa maneira de escrever códigos concisos.Em seguida, você escreverá uma nova camada fazendo uma subclasse, o que oferece um controle maior.
As duas camadas inverterão aleatoriamente as cores de uma imagem de acordo com uma determinada probabilidade.
Agora, implemente uma camada personalizada fazendo uma subclasse:
As duas camadas podem ser usadas conforme descrito nas opções 1 e 2 acima.
Uso de tf.image
Os utilitários de pré-processamento do Keras acima são convenientes, mas, para ter um controle mais granular, você pode escrever seus próprios pipelines ou camadas de ampliação de dados usando tf.data
e tf.image
(talvez você queira verificar também Imagem dos complementos do TensorFlow: operações e I/O do TensorFlow: conversões do espaço de cores).
Como o dataset Flowers foi configurado anteriormente com ampliação de dados, vamos reimportá-lo para que tenha a configuração original:
Recupere uma imagem para trabalhar com ela:
Vamos usar a seguinte função para visualizar e comparar lado a lado as imagens original e ampliada:
Ampliação de dados
Inverter uma imagem
Inverta uma imagem vertical ou horizontalmente com tf.image.flip_left_right
:
Mudar uma imagem para escala de cinza
Você pode mudar uma imagem para escala de cinza com tf.image.rgb_to_grayscale
:
Saturar uma imagem
Sature uma imagem com tf.image.adjust_saturation
, fornecendo um fator de saturação:
Alterar o brilho da imagem
Altere o brilho da imagem com tf.image.adjust_brightness
, fornecendo um fator de brilho:
Recorte uma imagem a partir do centro
Recorte a imagem a partir do centro até a parte desejada usando tf.image.central_crop
:
Girar uma imagem
Gire um imagem em 90 graus com tf.image.rot90
:
Transformações aleatórias
Atenção: há dois conjuntos de operações aleatórias de imagens: tf.image.random*
e tf.image.stateless_random*
. É altamente desaconselhável usar as operações de tf.image.random*
, pois elas usam os RNGs antigos do TF 1.x. Em vez disso, use as operações aleatórias de imagens apresentadas neste tutorial. Confira mais informações em Geração de números aleatórios.
A aplicação de transformações aleatórias às imagens pode generalizar e expandir o dataset ainda mais. A API tf.image
atual fornece oito operações aleatórias de imagens (também chamadas de ops):
Essas operações aleatórias de imagens são puramente funcionais: a saída depende somente da entrada, o que simplifica seu uso em pipelines de entrada determinísticos de alto desempenho. Elas requerem que um valor de seed
(semente) seja a entrada em cada passo. Dada a mesma seed
, elas retornam os mesmos resultados, não importa quantas vezes sejam chamadas.
Observação: seed
é um Tensor
de tamanho (2,)
cujos valores são números inteiros.
Nas próximas seções, você:
Verá exemplos de como usar operações aleatórias de imagens para transformar uma imagem.
Demonstrará como aplicar transformações aleatórias a um dataset de treinamento.
Alterar o brilho da imagem aleatoriamente
Altere o brilho da image
aleatoriamente usando tf.image.stateless_random_brightness
ao fornecer um fator de brilho e uma seed
. O fator de brilho é escolhido aleatoriamente no intervalo [-max_delta, max_delta)
e está associado à seed
fornecida.
Alterar o contraste da imagem aleatoriamente
Altere o contraste da image
aleatoriamente usando tf.image.stateless_random_contrast
ao fornecer um fator de contraste e uma seed
. O fator de contraste é escolhido aleatoriamente no intervalo [lower, upper]
e está associado à seed
fornecida.
Recortar uma imagem aleatoriamente
Recorte uma image
aleatoriamente usando tf.image.stateless_random_crop
ao fornecer o size
(tamanho) e a seed
(semente) alvos. A parte da image
recortada tem um deslocamento escolhido aleatoriamente e está associada à seed
fornecida.
Aplicar ampliação a um dataset
Primeiro, vamos baixar o dataset de imagens novamente caso tenha sido modificado nas seções anteriores.
Agora, defina uma função utilitária para redimensionar e reescalonar as imagens. Essa função será usada para unificar o tamanho e a escala das imagens no dataset:
Também vamos definir a função augment
, que pode aplicar as transformações aleatórias às imagens. Esta função será usada no dataset no próximo passo.
Opção 1: usando tf.data.experimental.Counter
Crie um objeto tf.data.experimental.Counter
(vamos chamá-lo de counter
) (contador) e compacte (Dataset.zip
) o conjunto com (counter, counter)
. Isso garantirá que cada imagem do dataset seja associada a um valor único (de formato (2,)
) com base no counter
, que depois poderá ser passado para a função augment
como o valor de seed
para transformações aleatórias.
Mapeie a função augment
para o dataset de treinamento:
Opção 2: usando tf.random.Generator
Crie um objeto
tf.random.Generator
com um valor inicial deseed
. Ao chamar a funçãomake_seeds
no mesmo objeto gerador, sempre será retornado um novo valor deseed
único.Defina uma função de encapsulamento que: 1) chame a função
make_seeds
; e 2) passe o valor deseed
recém-gerado para a funçãoaugment
para que sejam feitas transformações aleatórias.
Observação: objetos tf.random.Generator
armazenam o estado RNG em um tf.Variable
e, portanto, ele pode ser salvo como um checkpoint ou em um SavedModel. Confira mais detalhes em Geração de números aleatórios.
Mapeie a função de encapsulamento f
para o dataset de treinamento, e a função resize_and_rescale
para os conjuntos de validação e teste.
Agora, esses datasets podem ser usados para treinar um modelo conforme mostrado anteriormente.
Próximos passos
Este tutorial demonstrou a ampliação de dados usando as camadas de pré-processamento do Keras e tf.image
.
Para ver como incluir camadas de pré-processamento dentro do seu modelo, confira o tutorial Classificação de imagens.
Se tiver interesse em aprender como as camadas de pré-processamento podem ajudar a classificar o texto, confira o tutorial Classificação básica de texto.
Saiba mais sobre o
tf.data
neste guia e veja como configurar seus pipelines de entrada para melhor desempenho aqui.