Introdução ao aumento de imagens usando a biblioteca fastai

Um passo a passo baseado em exemplos de aplicação de aumento de imagem usando a biblioteca fastai

Sanyam Bhutani Seguir Abr 14 · 10 min ler Foto por Thomas Willmott em Unsplash

Você também pode encontrar o código executável deste blog neste kernel kaggle .

Para mais detalhes sobre o curso fastai, ou biblioteca: confira o site do curso e os documentos da biblioteca.

Introdução ao writeup

O objetivo deste writeup é dar-lhe um passo a passo de todos os acréscimos de imagem no fastai. Começarei introduzindo aumento de dados seguido de aumento de imagem.

Então vamos fazer um caso de por que os padrões fastai "simplesmente funcionam".

A seguir, veremos alguns casos de uso do mundo real em que essas transformações serão super úteis:

  • Construindo um detector de piscinas no bairro SOTA
  • Construindo uma imagem médica OCR
  • Construindo um Ripoff de Lente do Google (tosse, inicialização, tosse)
  • Construindo um Detector de matrículas.

Vamos olhar para uma imagem de base de um filhote fofo e primeiro aplicar as transformações para usá-lo como uma referência e, em seguida, mostrarei os exemplos dos casos de uso do mundo real dos mesmos.

Note que estas definições e explicações são fortemente derivadas dos documentos do fastai, eu recomendo que você verifique isso.

Além disso, isso não deve ser um código pesado, em vez disso, uma discussão de nível mais alto sobre onde usar o código ou quando.

Se você quer rodar o kernel, por favor siga o link no espaço do subtítulo.

Aumento de dados

O aumento de dados é uma das técnicas de regularização mais comuns, especialmente comum em tarefas de processamento de imagens.

Quando você está trabalhando em um modelo de aprendizado de máquina, o desempenho do seu modelo é tão bom quanto os dados. Dependendo do modelo e do problema que você está tentando resolver, você precisaria de uma quantidade diferente de dados.

No entanto, a coleta e a limpeza de dados é um processo que consome recursos e pode nem sempre ser viável.

Uma rede neural, ou como normalmente usado para fins de processamento de imagem: Convolutional Neural Networks, aprende sobre “recursos” dentro de suas imagens.

Por que o aumento de imagem funciona?

Nosso objetivo com qualquer projeto de aprendizado de máquina é garantir que nosso código ou "modelo" seja capaz de generalizar para dados do mundo real. No entanto, o oposto disso é “overfitting”, onde seu modelo aprende a reconhecer recursos dentro do seu conjunto de dados de treinamento.

Para evitar isso, "aumentamos" ou adicionamos pequenas variações ao alimentar nossas imagens no modelo. Mesmo que a rotação de 2 graus não faça uma grande diferença para o olho humano, essas pequenas variações são úteis o suficiente para permitir que o modelo seja bem generalizado.

Para lhe dar um exemplo de "apenas funciona", vamos tentar executar o treinamento de uma ResNet 50 no conjunto de dados CIFAR-10 com o aumento de imagem ativado / desativado.

Com os acréscimos (padrão) habilitados, você pode ver que o modelo tem um desempenho melhor.

A seguir, vou aprofundar os aprimoramentos de imagem suportados pelo fastai e dar exemplos possíveis de casos de uso de onde isso pode ser útil.

Aumento de imagem usando fastai

Para aplicar "transformações" ao seu conjunto de dados, passamos a lista de transformações ao criar os objetos "ImageDataBunch".

O fastai tem uma lista de transformações padrão recomendadas que foram derivadas de intensa experimentação pela equipe, então para começar, eu recomendo confiar nelas:

 tfms = get_transforms () 

Isso retorna uma tupla de comprimento 2, contendo 2 listas: uma para o conjunto de dados de treinamento e outra para o conjunto de dados de validação.

Os parâmetros padrão para a função get_transforms (fonte: fastai docs) são:

 get_transforms (do_flip: bool = Verdadeiro, flip_vert: bool = Falso, max_rotate: float = 10.0, max_zoom: float = 1.1, max_lighting: float = 0.2, max_warp: float = 0.2, p_affine: float = 0.75, p_lighting: float = 0.75, xtra_tfms: Opcional [Collection [Transform]] = None) ? Coleção [Transform] 

A tupla padrão que isso gera é:

 ([RandTransform (tfm = TfmCrop (crop_pad), kwargs = {'row_pct': (0, 1), 'col_pct': (0, 1), 'padding_mode': 'reflexão'}, p = 1.0, resolvido = { }, do_run = True, is_random = True), 
RandTransform (tfm = TfmAffine (flip_affine), kwargs = {}, p = 0,5, resolvido = {}, do_run = True, is_random = True),
RandTransform (tfm = TfmCoord (symmetric_warp), kwargs = {'magnitude': (-0,2, 0,2)}, p = 0,75, resolvido = {}, do_run = Verdadeiro, is_random = Verdadeiro),
RandTransform (tfm = TfmAffine (girar), kwargs = {'graus': (-10.0, 10.0)}, p = 0.75, resolvido = {}, do_run = Verdadeiro, is_random = Verdadeiro),
RandTransform (tfm = TfmAffine (zoom), kwargs = {'escala': (1.0, 1.1), 'row_pct': (0, 1), 'col_pct': (0, 1)}, p = 0.75, resolvido = { }, do_run = True, is_random = True),
RandTransform (tfm = TfmLighting (brilho), kwargs = {'mudar': (0.4, 0.6)}, p = 0.75, resolvido = {}, do_run = Verdadeiro, is_random = Verdadeiro),
RandTransform (tfm = TfmLighting (contraste), kwargs = {'scale': (0.8, 1.25)}, p = 0.75, resolvido = {}, do_run = True, is_random = True)],
[RandTransform (tfm = TfmCrop (crop_pad), kwargs = {}, p = 1,0, resolvido = {}, do_run = True, is_random = True)])

Tudo bem se você não entender todas as palavras indexadas lá. Vamos dar um mergulho profundo e tentar explorar alguns deles. O caso que faço ao compartilhá-los é: os padrões são sempre um bom ponto de partida, a menos que você esteja trabalhando em dados muito diferentes. Por ex: mutações pontuais ou imagens inter-galácticas.

Transformações suportadas pelo fastai

  • brilho
  • contraste
  • colheita
  • crop_pad
  • diédrico
  • dihedral_affine
  • flip_lr
  • flip_affine
  • instabilidade
  • almofada
  • perspective_warp
  • redimensionar
  • rodar
  • rgb_randomize
  • inclinar
  • esmagado
  • symmetric_warp
  • inclinar
  • zoom
  • Cortar fora

Função de conveniência:

  • rand_crop
  • rand_pad
  • rand_zoom

Essa é uma longa lista! Vamos tentar explorar esses casos por caso.

Padrões:

Eu (roubado) peguei emprestado algum código auxiliar dos documentos:

 #Helper funções do fastai docs 
def get_ex (): retornar open_image (caminho / 'images / beagle_192.jpg')

def plots_f (linhas, cols, largura, altura, ** kwargs):
[get_ex (). apply_tfms (tfms [0], ** kwargs) .show (ax = ax) para i, ax em enumerar (plt.subplots (
linhas, cols, figsize = (largura, altura)) [1] .flatten ()]]

Isso nos permitirá ver fotos de cachorros. Estes serão o caso base para comparação. Então, mais adiante, eu compartilharei a transformação, o que ela faz com a imagem do cão de base e onde você pode achar útil no mundo real, já que nossa foto doggy pode não servir como o melhor exemplo para todos os casos, como veremos.

Rotação

(max_rotate = ângulo) alterna as rotações aleatórias entre o ângulo e o ângulo especificado aqui.

 tfms = get_transforms (max_rotate = 180) 

Já que ninguém clicaria em fotos de seus cachorrinhos nesses ângulos. Vamos considerar outro caso:

Caso de uso do mundo real

Você está encarregado de encontrar piscinas em sua vizinhança. Você faz o download de imagens de satélite, mas como a sua região é pequena, o seu modelo é superequipado.

Nesse caso, o aumento de imagem pode ser útil:

À primeira vista, eu poderia ter mentido para você sobre essas fotos diferentes, não é? Eu acredito que isso definitivamente serviria como um bom propósito para o nosso modelo.

RGB Randomise

rgb_randomize ( x , channel : int = None , thresh : float = 0.3 ) ? Image :: TfmPixel

Imagens como sabemos, tem 3 canais (vermelho, verde, azul AKA RGB). Essa transformação randomiza um dos canais da imagem de entrada.

  • canal : qual canal (RGB) para randomizar.
  • thresh : Após a randomização, dimensione os valores para não exceder o valor de thresh

Isso pode ser útil em um caso em que seu conjunto de dados supostamente ajuda a detectar carros, mas seus estagiários (ou o Graduate Student Turk did) fizeram um trabalho ruim e coletaram apenas imagens de carros vermelhos. Você pode randomizar as cores e ajudar o aluno a generalizar melhor.

Brilho

Podemos variar o brilho de 0 a 1, 0,5 é o padrão.

Vamos dar uma olhada em nossa foto canina com todas as variações na escala de brilho. Como a imagem original foi tirada com perfeição, o aumento não ajudou aqui. Este é outro exemplo de como aumentar sua imagem pode arruinar seu modelo. Portanto, tenha cuidado ao aplicar as transformações aos seus dados.

Caso de uso do mundo real

Com o aviso fora do nosso caminho. Aqui está um exemplo do meu trabalho: A tarefa é extrair texto desta imagem. Mesmo para os olhos humanos, isso é mais fácil de fazer quando a diferença entre o fundo e o texto é mais pronunciada. Então, por ex: veja o valor 0.3 – este é o melhor resultado para este caso.

Contraste

Como o nome sugere, nos permite variar o contraste, de uma escala de 0 a 2. 1 sendo a imagem padrão / original.

Aqui está nossa pobre imagem canina passando por outro conjunto de aumento:

Pessoalmente, eu votaria na imagem mais "contrastada" para ser a melhor. A culpa é dos filtros do Instagram.

Caso de uso do mundo real

Vamos pegar o desafio anterior novamente. Temos a tarefa de criar um leitor de personagens que leia os personagens da imagem do medicamento. Isso funciona melhor quando o contraste é máximo.

Não acredita em mim? Dê uma olhada:

Colheita

O corte ajuda a cortar os setores mencionados da imagem.

Caso de uso do mundo real

Você é encarregado de construir uma máquina de faturamento de estacionamento. Uma vez que nossa câmera seria fixada em um ângulo e podemos esperar que a maioria dos sedans entrem muito, a placa numérica estaria provavelmente em uma região fixa (meio Inferior). O corte aqui permitirá que nosso modelo se concentre apenas nessa região, facilitando o trabalho de nosso e do modelo.

Almofada de colheita

Crop_pad, crop e pads baseados no modo de ajuste. O recomendado pelo fastai dev (s) é o “reflexo de preenchimento”. Veja os exemplos abaixo para preenchimento com zero e reflexão.

Diédrico

Transformações Diédricas rotacionam as imagens nas 8 direções / ângulos possíveis de um diedro.

Vamos primeiro olhar para o que é um ângulo diédrico:

Como você pode imaginar, ele girará a imagem em todas essas orientações possíveis. Definições suficientes, vamos olhar para o nosso cachorrinho inocente em ângulos ruins:

Caso de uso do mundo real

Agora, eu aposto se você tirar fotos do seu cachorro em tais ângulos , no seu Instagram ou um pai ruim. De qualquer forma, não é um bom exemplo.

De volta à nossa missão original de acampamento de verão, estamos espionando a vizinhança usando o google maps e procurando por piscinas.

Como você pode ver, nesse caso, pode fazer muito mais sentido girar a imagem nesses ângulos. Se você não sabia, elas podem parecer imagens completamente diferentes à primeira vista. Não é?

Jitter

Jitter adiciona ruído aleatório à imagem. Eu não tenho certeza qual é o melhor caso prático de uso para o mesmo, a magnitude pode ser definida de -x para + x com 0 sendo a imagem original.

Caso de uso do mundo real

Nos bastidores, o jitter é uma substituição aleatória de pixels da vizinhança. O que significa que isso pode ajudar a evitar overfitting (pense que é semelhante ao dropout)

Perspectiva

Essa transformação altera a perspectiva da imagem como se nosso objeto fosse movido.

Lembre-se deste vídeo da Apple?

Isso é exatamente o que isso faz.

Para referência, vamos olhar novamente para o nosso filhote primeiro.

Caso de uso do mundo real

Um caso de uso onde isso pode ser útil é, suponha que você esteja criando um detector de medicamentos no qual deseja que o cliente tire fotos do medicamento e sua “tecnologia” deve ser capaz de detectar / ler todos os detalhes. Agora, o cliente pode não clicar nas fotos nos melhores ângulos e você odiaria ensiná-las da mesma forma. Em vez disso, você só usaria essa transformação.

Verifique estes exemplos:

Urdidura Simétrica

Aqui está a definição, dos documentos :

Aplique as quatro inclinações ao mesmo tempo, cada uma com uma força dada na magnitude do vetor.

Vamos olhar para o nosso cachorro para referência.

Caso de uso do mundo real

Ok, agora para um exemplo do mundo real. Já ouviu falar do Google Lens?
É também conhecido como mecanismo de busca de conteúdo / mecanismo de busca de imagens nos clubes de tecnologia. Agora, se você pensar sobre isso, o uso de tais serviços realmente não se preocupa com os ângulos certos. Então é seu trabalho cuidar disso.

Por exemplo, se você tiver a tarefa de criar um mecanismo de imagem de detector de cereais SOTA, a transformação realmente se destacará aqui:

Inclinar

A inclinação permite “inclinar” um campo para uma direção aleatória e uma magnitude especificada.

direction é um número (0: esquerda, 1: direita, 2: superior, 3: inferior). Uma magnitude positiva é uma inclinação para frente (em direção à pessoa que olha para a foto), uma magnitude negativa para trás.

Caso de uso do mundo real

Vou poupar o nosso filhote fofo e voltar à importante tarefa de construir um detector de caixas de cereais de classe mundial. Você pode ver que a transformação é realmente útil novamente para este caso de uso:

Esta foi uma lista muito longa de transformações e exemplos. Se você estiver interessado em testá-las, sugiro que você verifique meu kernel inicial.

Se você tiver alguma dúvida, por favor, me faça um tweet ou deixe um comentário abaixo.