Entenda o que é aumento de dados de imagem e como usá-lo usando Keras para seus projetos de aprendizado profundo
Se você já tentou realizar reconhecimento de imagens usando aprendizado profundo, sabe a importância de um bom conjunto de dados para treinamento. No entanto, nem sempre é fácil encontrar imagens suficientes para treinamento e a precisão do seu modelo depende diretamente da qualidade dos dados de treinamento.
Felizmente, existem técnicas que você pode usar para complementar o conjunto de dados de imagens usado para treinamento. Uma das técnicas é chamada aumento de dados de imagem. Neste artigo, discutirei o que é aumento de dados de imagem, como funciona, por que é útil no aprendizado profundo e, finalmente, como realizar aumento de dados de imagem usando a biblioteca Keras.
Aumento de dados de imagem é uma técnica que cria novas imagens a partir das existentes. Para fazer isso, você faz algumas pequenas alterações neles, como ajustar o brilho da imagem, girar a imagem ou deslocar o assunto na imagem horizontal ou verticalmente.
As técnicas de aumento de imagem permitem aumentar artificialmente o tamanho do seu conjunto de treinamento, fornecendo assim muito mais dados ao seu modelo para treinamento. Isso permite melhorar a precisão do seu modelo, aprimorando a capacidade do seu modelo de reconhecer novas variantes dos seus dados de treinamento.
Tipos de aumento de dados de imagem
O aumento de imagem vem em muitas formas, aqui estão algumas das mais comuns - deslocamento vertical, deslocamento horizontal, inversão vertical, inversão horizontal, rotação, ajuste de brilho e zoom in/out.
Demonstrarei primeiro as várias técnicas de aumento de imagem usando Python e Keras. Se você quiser experimentar, certifique-se de ter os seguintes softwares e pacotes instalados:
Depois que o Anaconda e o TensorFlow estiverem instalados, crie um novo Jupyter Notebook.
Deslocamento Vertical
A primeira técnica de aumento de imagem que quero mostrar é a deslocamento vertical. O deslocamento vertical desloca aleatoriamente a imagem verticalmente para cima ou para baixo. Para este exemplo, vou usar uma imagem chamada 747.jpg, localizado na mesma pasta do meu Jupyter Notebook.
O trecho de código a seguir usa o ImageDataGenerator
classe em Keras para deslocar verticalmente a imagem.
A
ImageDataGenerator
classe de Keras gera lotes de dados de imagem com aumento de dados em tempo real.
#---importar os módulos---
importar numpy como np
importar matplotlib.pyplot como pltde tensorflow.keras.preprocessing.image importação load_img
de tensorflow.keras.preprocessing.image importar img_to_array
de tensorflow.keras.preprocessing.image importar ImageDataGenerator#---carrega a imagem---
nome_do_arquivo_imagem = '747.jpg'
img = load_img(nome_arquivo_imagem)#---converter a imagem em array 3D---
dados_imagem = img_to_array(img)#---converter em uma matriz 4-D de 1 elemento da matriz 3D representando
# a imagem---
dados_imagens = np.expand_dims(dados_imagem, eixo=0)#---criar gerador de aumento de dados de imagem---
datagen = ImageDataGenerator (largura_shift_range = 0.2)#---prepare o iterador; flow() pega um array 4D e retorna
# um iterador contendo um lote de imagens---
train_generator=datagen.flow(images_data, batch_size=1)linhas = 5
colunas = 4#--- plotar 5 linhas e 4 colunas ---
fig, eixos = plt.subplots(linhas,colunas)para r no intervalo (linhas):
para c no intervalo (colunas):
#---obtém a próxima imagem do lote (uma imagem desde o lote
# tamanho é 1)---
imagem_batch = train_generator.next()#---converter em números inteiros sem sinal para visualização---
#---mostrar a imagem---
imagem = image_batch[0].astype('uint8')
eixos[r,c].imshow(imagem)#---definir o tamanho da figura---
fig.set_size_inches(15,10)
O trecho de código acima produz a seguinte saída:
Como você pode ver na saída acima, cada vez que você chama o next()
método do train_generator
objeto, você obtém uma imagem ligeiramente alterada. No trecho de código acima, uma nova imagem que é deslocada em 20% com base na altura da imagem original é retornada sempre que você chama o método next()
método:
datagen=ImageDataGenerator(largura_shift_range=0.2)
Curiosamente, para esta versão do
ImageDataGenerator
(tensorflow.keras.preprocessing.image
) classe, especificando owidth_shift_range
parâmetro desloca a imagem verticalmente, em vez de horizontalmente (que é o comportamento do antigoImageDataGenerator
dokeras.preprocessing.image
módulo). Da mesma forma, se quiser que a imagem seja deslocada horizontalmente, você precisa usar oheight_shift_range
parâmetro (veja a próxima seção).
Observe que o next()
método retornará uma imagem aumentada quantas vezes você quiser. No trecho de código acima, chamamos isso 20 vezes (5 linhas vezes 4 colunas).
Mudança Horizontal
Agora você pode tentar deslocar a imagem horizontalmente usando o height_shift_range
parâmetro:
datagen=ImageDataGenerator(intervalo_altura_deslocamento=0.2)
train_generator=datagen.flow(images_data, batch_size=1)linhas = 5
colunas = 4fig, eixos = plt.subplots(linhas,colunas)
para r no intervalo (linhas):
para c no intervalo (colunas):
imagem_batch = train_generator.next()
imagem = image_batch[0].astype('uint8')
eixos[r,c].imshow(imagem)fig.set_size_inches(15,10)
O trecho de código acima produz a seguinte saída:
Flip Horizontal
Às vezes faz sentido virar a imagem horizontalmente. No caso de um avião, a frente do avião pode estar voltada para a esquerda ou para a direita:
datagen=ImageDataGenerator(horizontal_flip = Verdadeiro)
train_generator=datagen.flow(images_data, batch_size=1)linhas = 2
colunas = 2fig, eixos = plt.subplots(linhas,colunas)
para r no intervalo (linhas):
para c no intervalo (colunas):
imagem_batch = train_generator.next()
imagem = image_batch[0].astype('uint8')
eixos[r,c].imshow(imagem)fig.set_size_inches(15,10)
Para o trecho de código acima, gerar quatro imagens é suficiente, pois a frente do avião pode estar voltada para a esquerda ou para a direita:
Lembre-se de que a inversão é aleatória (às vezes você obtém todas as quatro imagens originais e às vezes obtém imagens invertidas horizontalmente). É provável que as quatro imagens acima sejam todas iguais. Se isso acontecer, basta executar esse bloco de código novamente.
Virar vertical
Assim como a inversão horizontal, você também pode realizar a inversão vertical:
datagen=ImageDataGenerator(vertical_flip = Verdadeiro)
train_generator=datagen.flow(images_data, batch_size=1)linhas = 2
colunas = 2fig, eixos = plt.subplots(linhas,colunas)
para r no intervalo (linhas):
para c no intervalo (colunas):
imagem_batch = train_generator.next()
imagem = image_batch[0].astype('uint8')
eixos[r,c].imshow(imagem)fig.set_size_inches(15,10)
No caso dos aviões, pode não fazer muito sentido virar o avião de cabeça para baixo! Se você estiver tentando realizar o reconhecimento de imagens, é provável que suas imagens de aviões estejam na vertical e, portanto, treinar seu modelo para reconhecer planos invertidos pode não ser muito comum. Para outros casos, a inversão vertical faz muito sentido.
rotação
A rotação, como o nome indica, gira sua imagem. Isso seria muito útil para a imagem do nosso avião. Os seguintes trechos de código giram aleatoriamente a imagem em até 50 graus:
datagen=ImageDataGenerator(intervalo_rotação=50)
train_generator=datagen.flow(imagens_dados)linhas = 5
colunas = 4fig, eixos = plt.subplots(linhas,colunas)
para r no intervalo (linhas):
para c no intervalo (colunas):
imagem_batch = train_generator.next()
imagem = image_batch[0].astype('uint8')
eixos[r,c].imshow(imagem)fig.set_size_inches(15,10)
Com a rotação, a saída mostra os aviões nas diversas posições — simulando as posições de decolagem e pouso:
Brilho
Outra técnica de aumento é ajustar o brilho da imagem. O trecho de código a seguir define um intervalo de valores de mudança de brilho:
datagen=ImageDataGenerator(faixa_de brilho=[0.15,2.0])
train_generator=datagen.flow(images_data, batch_size=1)linhas = 5
colunas = 4fig, eixos = plt.subplots(linhas,colunas)
para r no intervalo (linhas):
para c no intervalo (colunas):
imagem_batch = train_generator.next()
imagem = image_batch[0].astype('uint8')
eixos[r,c].imshow(imagem)fig.set_size_inches(15,10)
A saída contém uma série de imagens com brilho variável:
Zoom
Você também pode ampliar ou reduzir as imagens:
datagen=ImageDataGenerator(intervalo_zoom=[5,0.5])
train_generator=datagen.flow(images_data, batch_size=1)linhas = 5
colunas = 4fig, eixos = plt.subplots(linhas,colunas)
para r no intervalo (linhas):
para c no intervalo (colunas):
imagem_batch = train_generator.next()
imagem = image_batch[0].astype('uint8')
eixos[r,c].imshow(imagem)fig.set_size_inches(15,10)
A saída mostra a imagem nas diversas taxas de zoom:
Observe que o zoom nas imagens alterará as proporções das imagens.
Combinando todos os aumentos
Claro, todas as diversas técnicas de aumento que discuti até agora podem ser combinadas:
datagen=ImageDataGenerator(largura_shift_range=0.2,
altura_shift_range = 0.2,
horizontal_flip=Verdadeiro,
intervalo_de rotação = 50,
faixa_de brilho=[0.15,2.0],
intervalo_zoom=[5,0.5])train_generator=datagen.flow(images_data, batch_size=1)linhas = 8
colunas = 8fig, eixos = plt.subplots(linhas,colunas)
para r no intervalo (linhas):
para c no intervalo (colunas):
imagem_batch = train_generator.next()
imagem = image_batch[0].astype('uint8')
eixos[r,c].imshow(imagem)fig.set_size_inches(15,10)
Observe que deixei de fora a inversão vertical, pois não faz sentido para o nosso exemplo.
A saída agora mostra a imagem com os vários aumentos aplicados:
As seções anteriores mostraram os fundamentos do aumento de dados de imagem e como ele pode ser aplicado a uma única imagem. Na aprendizagem profunda, muitas vezes lidamos com um conjunto de imagens. Então, vamos agora ver como o aumento de imagem pode ser aplicado a um conjunto de imagens. Para ilustrações, vou assumir que na pasta que contém seu Jupyter Notebook, você tem um Frutas pasta e as seguintes subpastas:
Frutas
|__banana
|__banana1.jpg
|__banana2.jpg
|__banana3.jpg
|__ ...
|__durian
|__durian1.jpg
|__durian2.jpg
|__durian3.jpg
|__ ...
|__laranja
|__orange1.jpg
|__orange2.jpg
|__orange3.jpg
|__ ...
|__morango
|__morango1.jpg
|__morango2.jpg
|__morango3.jpg
|__ ...
Cada subpasta contém um conjunto de imagens. Por exemplo, o Banana pasta contém uma série de imagens chamadas banana1.jpg, banana2.jpg, e assim por diante. Os nomes das subpastas servirão de rótulos para as diversas imagens. Isso significa que todos os arquivos sob o Banana pasta contém imagens de banana e assim por diante.
Para carregar uma série de imagens do disco, agora você chama o método flow_from_directory()
método do ImageDataGenerator
instância em vez do flow()
método (para carregar imagens da memória):
train_datagen=ImageDataGenerator(
horizontal_flip=Verdadeiro,
vertical_flip=Verdadeiro,
intervalo_de rotação = 50,
)tamanho_do_lote = 8train_generator = train_datagen.flow_from_directory(
'./Frutas',
tamanho_alvo=(224,224),
color_mode='rgb',
tamanho_do_lote=tamanho_do_lote,
class_mode='categórico',
embaralhar=Verdadeiro)
Observe que agora defino o
batch_size
para 8. Você verá o uso do tamanho do lote em breve.
Usando o iterador retornado, posso encontrar os rótulos das diversas frutas (banana, durião, laranja e morango):
class_dictionary=train_generator.class_indices#---crie um dicionário de rótulos---
class_dictionary = {valor:chave para chave,valor em
class_dictionary.items()}#---converter o dicionário em uma lista---
class_list = [valor para _, valor em class_dictionary.items()]
imprimir(lista_classes)
Você verá a seguinte saída:
Foram encontradas 54 imagens pertencentes a 4 classes.
['banana', 'durião', 'laranja', 'morango']
Ao todo, são um total de 54 imagens em 4 pastas. Também o class_list
variável contém a lista de frutas.
Vou agora imprimir o conjunto de imagens aumentadas que são criadas pelo ImageDataGenerator
aula. Definirei arbitrariamente as linhas como 10 e, para cada linha, quero imprimir o lote de imagens retornado (que é 8 neste exemplo):
linhas = 10fig, eixos = plt.subplots(linhas,batch_size)para r no intervalo (linhas):
#---obter o lote de imagens aumentadas---
imagem_batch = train_generator.next() #---obter o número de imagens retornadas---
contagem_imagens = lote_imagem[0].forma[0]para c no intervalo (images_count):
#---converter em números inteiros sem sinal para visualização---
imagem = image_batch[0][c].astype('uint8')#---exibe a imagem---
#---exibe o rótulo da imagem---
eixos[r,c].imshow(imagem)
eixos[r,c].title.set_text(
lista_classe[np.argmax(image_batch[1][c])]) #---oculta os ticks x e y---
eixos[r,c].set_xticks([])
eixos[r,c].set_yticks([])fig.set_size_inches(15,18)
Uma vez que o batch_size
agora está definido como 8 (e não mais 1), o train_generator.next()
método retornará a você um fornada de oito imagens aumentadas cada vez que você liga. O número de imagens retornadas é baseado em batch_size
que você definiu anteriormente no flow_from_directory()
método:
train_generator=train_datagen.flow_from_directory(
'./Frutas',
tamanho_alvo=(224,224),
color_mode='rgb',
tamanho_do_lote=tamanho_do_lote, #tamanho_do_lote = 8
class_mode='categórico',
embaralhar=Verdadeiro)
O valor do image_batch
variável (retornada pelo next()
método) é uma tupla de dois elementos:
- O primeiro elemento (
image_batch[0]
) é uma matriz de tamanho do batch imagens (matriz 4D) - O segundo elemento (
image_batch[1]
) contém os rótulos das imagens
O trecho de código acima produz a seguinte saída:
Observe que na sétima linha há dois gráficos vazios sem imagens. Lembre-se de que há um total de 54 imagens no conjunto de imagens e, como cada lote retorna 8 imagens (por linha), as primeiras sete linhas exibirão um total de 54 imagens (8×6 + 6). A figura a seguir deixa isso claro:
Observe que você pode definir
rows
para qualquer número e oImageDataGenerator
class continuará gerando novas imagens aumentadas para você.
Construindo um modelo usando aprendizagem por transferência
Agora você sabe como usar o ImageDataGenerator
para carregar conjuntos de imagens do disco para aumento. Mas como usá-lo para treinar? O trecho de código a seguir mostra como construir um modelo de aprendizado profundo usando transferir aprendizado.
O aprendizado por transferência é um método de aprendizado de máquina em que um modelo desenvolvido para uma tarefa é reutilizado como ponto de partida para um modelo em uma segunda tarefa. A aprendizagem por transferência reduz a quantidade de tempo que você precisa gastar em treinamento.
do modelo de importação tensorflow.keras.models
de tensorflow.keras.applications importar VGG16
de tensorflow.keras.layers importar Denso, GlobalAveragePooling2D#---número de frutas---
NO_CLASSES = max(train_generator.class_indices.values()) + 1#---carregar o modelo VGG16 como modelo base para treinamento---
modelo_base = VGG16(include_top=Falso, input_shape=(224, 224, 3))#---adicionar nossas próprias camadas---
x = modelo_base.saída
x = GlobalAveragePooling2D()(x)
x = Dense(1024,activation='relu')(x) # adiciona camadas densas para
# que o modelo pode
# aprenda mais complexo
# funções e
#classifique para melhor
# resultados.
x = Densa(1024,ativação='relu')(x) # camada densa 2
x = Densa(512,ativação='relu')(x) # camada densa 3preds = Denso(NO_CLASSES,
activation='softmax')(x) # camada final com
#ativação softmax#---crie um novo modelo com o modelo base original
# entrada e saída do novo modelo ---
modelo = Modelo (entradas = modelo_base.input, saídas = preds)#---não treine as primeiras 19 camadas - 0..18---
para camada em model.layers[:19]:
camada.trainable=Falso#---treine o restante das camadas - 19 em diante---
para camada em model.layers[19:]:
camada.trainable = Verdadeiro#---compilar o modelo---
model.compile(optimizer='Adam',
perda='categorical_crossentropy',
metrics = ['precisão'])
Explicar como funciona a aprendizagem por transferência está além do escopo deste artigo. Vou deixar para outro artigo.
Usando as imagens geradas para treinamento
Para utilizar as imagens aumentadas para treinamento, passe o train_generator
no fit()
método do modelo:
#---treinar o modelo---
step_size_train = train_generator.n // train_generator.batch_sizemodelo.fit(train_generator,
passos_por_época = passo_tamanho_trem,
épocas = 15)
A steps_per_epoch
parâmetro basicamente significa quantas etapas existem em uma época - depende do número de imagens que você possui e do tamanho do lote definido anteriormente. Se você definir um número alto, estará fazendo um treinamento repetitivo. Você deve configurá-lo com base nesta fórmula:
número de imagens/tamanho do lote
No nosso exemplo, temos 54 imagens no total. E assim, em cada época, o ImageDataGenerator
a aula transformará todas as 54 imagens para treinamento. Em cada época o modelo obterá diferentes variações das imagens. Se você tiver 15 épocas, um total de 15×54 variações das imagens serão geradas e alimentadas no modelo de treinamento.
A
ImageDataGenerator
class permite que seu modelo receba novas variações das imagens em cada época. Mas lembre-se que ele apenas retorna as imagens transformadas e não as adiciona ao conjunto de imagens que você possui.
Espero que este artigo tenha lhe dado uma boa ideia do que se trata o aumento de dados de imagem e por que você precisa deles no treinamento de seus modelos de aprendizado profundo. Em particular, demonstrei isso usando o módulo Keras na biblioteca TensorFlow.
Aumento de dados de imagem para aprendizado profundo republicado da fonte https://towardsdatascience.com/image-data-augmentation-for-deep-learning-77a87fabd2bf?source=rss—-7f60cf5620c9—4 via https://towardsdatascience.com/feed
<!–
->
- Bitcoin
- bizbuilder Mike
- blockchain
- conformidade do blockchain
- conferência blockchain
- Consultores Blockchain
- coinbase
- Coingenius
- Consenso
- conferência de criptografia
- crypto mining
- criptomoedas
- Descentralizada
- DeFi
- Ativos Digitais
- ethereum
- aprendizado de máquina
- token não fungível
- platão
- platão ai
- Inteligência de Dados Platão
- Platoblockchain
- PlatãoData
- jogo de platô
- Polygon
- prova de participação
- W3
- zefirnet