Perceptron Multi-Layer usando FastAI e PyTorch

Aayush Agrawal Blocked Unblock Seguir Seguindo 5 de janeiro

Neste blog, vou mostrar como construir uma rede neural (perceptron multicamada) usando FastAI v1 e Pytorch e treiná-la com sucesso para reconhecer dígitos na imagem. O Pytorch é um framework de aprendizado profundo muito popular lançado pelo Facebook, e o FastAI v1 é uma biblioteca que simplifica o treinamento rápido e preciso de redes neurais usando as melhores práticas modernas. Ele é baseado em pesquisas sobre as melhores práticas de aprendizagem profunda realizadas no fast.ai , incluindo suporte “ pronto para uso ” para modelos de visão, texto, tabular e collab (filtragem colaborativa). Se você está procurando pelo código-fonte, vá para o repositório do fastai no GitHub. Este notebook irá guiar para construir uma rede neural com esta biblioteca. Se você quer entender o que é um perceptron multicamada, você pode olhar para o meu blog anterior, onde eu criei um perceptron multicamada a partir do zero usando numpy e outro blog onde eu construí o mesmo modelo usando o TensorFlow. Como você notará, a quantidade de código necessária para escrever este bloco de notas é bem menor do que o que foi usado em notebooks anteriores, tudo graças à biblioteca fastai que nos permite focar mais na resolução de problemas do que escrever código. Este blog também está disponível como um Notebook Jupyter no meu Github .

Comando BoilerPlate

É prática padrão iniciar o notebook com as três linhas a seguir; eles garantem que quaisquer edições nas bibliotecas que você fizer sejam recarregadas aqui automaticamente, e também que quaisquer gráficos ou imagens exibidas sejam mostrados neste caderno.

 % reload_ext autoreload 
% autoreload 2
% matplotlib inline

Importando biblioteca Fast AI

Vamos importar a biblioteca fastai e definir nosso parâmetro batch_size para 128. Geralmente, bancos de dados de imagens são enormes, então precisamos alimentar essas imagens em uma GPU usando lotes, tamanho de lote 128 significa que vamos alimentar 128 imagens de uma só vez para atualizar os parâmetros do nosso profundo modelo de aprendizagem. Se você está ficando sem memória por causa da menor GPU RAM, você pode reduzir o tamanho do lote para 64 ou 32.

 da importação fastai.vision * 
bs = 128

Download do conjunto de dados

Começaremos baixando o conjunto de dados manuscritos MNIST da página fastai dataset . MNIST é um conjunto de dados padrão de pequenos dígitos de escala de cinza manuscritos (28 x 28), desenvolvidos na década de 1990 para testar os modelos mais sofisticados do dia; hoje, muitas vezes usado como um “mundo de olá” básico para introduzir aprendizado profundo. Essa versão de conjuntos de dados fast.ai usa um formato PNG padrão em vez do formato binário especial do original, para que você possa usar os pipelines de dados regulares na maioria das bibliotecas; Se você quiser usar apenas um único canal de entrada como o original, basta escolher uma única fatia do eixo dos canais.

 caminho = untar_data (URLs.MNIST); 
caminho

Ao executar o comando acima, os dados são baixados e armazenados no caminho mostrado acima. Vamos ver como o diretório de dados é configurado, já que temos que importar dados desses diretórios. Vamos começar olhando para o diretório de caminho, e podemos ver abaixo que nossos dados já possuem pasta de treinamento e teste.

 path.ls () 

Vamos olhar dentro da pasta de treinamento. Os dados são divididos pelos dígitos de 1 a 9 em uma pasta diferente.

 (caminho / 'treinamento'). ls () 

Dentro de cada pasta de dígitos, temos imagens.

 (caminho / 'treinamento / 0'). ls () [1: 5] 

Importando dados

Agora temos uma compreensão de como nosso diretório de dados está configurado; usaremos a incrível API de bloqueio de dados FastAI para importar dados e funções de transformação de imagem FastAI para aumentar os dados. Vamos começar definindo qual transformação queremos fazer.

 ds_tfms = get_transforms (do_flip = Falso , flip_vert = Falso , max_rotate = 15, max_zoom = 1.1, max_lighting = 0.2, max_warp = 0.2) 

Na função get_transforms , podemos definir todas as transformações que queremos fazer. A FastAI torna incrivelmente fácil aumentar os dados, já que toda a transformação pode ser passada em uma função e usa uma implementação incrivelmente rápida. Vamos ver cada argumento dado na função.

  • do_flip = False, flip_vert = Falso : Não queremos inverter dígitos na direção vertical e horizontal, já que isso não é uma boa idéia com dados de dígitos.
  • max_rotate = 15 : Gira imagens aleatoriamente enquanto importa até 15 graus no sentido horário e anti-horário
  • max_zoom = 1.1 : Ampliar / Reduzir as imagens em 10% da imagem original
  • max_lighting = 0.2 : A alteração aleatória de raios e contraste controlada por max_lighting será aplicada
  • max_warp = 0.2 : Uma distorção simétrica aleatória de magnitude entre -max_warp e + max_warp é aplicada com probabilidade p_affine, que é padronizada para 0.75 neste caso.

Agora que definimos qual transformação queremos fazer em nossas imagens de entrada, vamos começar definindo os dados ou o banco de dados como FastAI irá chamá-lo. Os conjuntos de dados de imagem são enormes, por isso nunca queremos importar o conjunto de dados inteiro na memória, em vez disso definimos um banco de dados que nos permitirá carregar lotes de dados e fazer a transformação necessária em tempo real.

 data = (ImageItemList.from_folder (caminho, convert_mode = 'L') 
.split_by_folder (train = 'treinamento', válido = 'teste')
.label_from_folder ()
.transform (tfms = ds_tfms, size = 28)
.databunch (bs = bs))

Jeremy Howard chama a etapa acima de engenharia de rótulos , já que a maior parte do tempo e esforço é gasto na importação de dados corretamente. A API de bloqueio de dados da FastAI torna drasticamente fácil definir como queremos importar nossos dados usando uma API de gráficos como API, onde você pode continuar encadeando diferentes funções até que seu conjunto de dados esteja pronto. Vamos entender o que o código acima está fazendo –

  • ImageItemList.from_folder (path, convert_mode = 'L') – Cria um ItemList no caminho dos nomes de arquivos que possuem um sufixo em extensões. Convert_mode = 'L' nos ajuda a definir que as imagens que estamos importando são padrão de imagem em escala de cinza / canal único é 'RGB', o que significa uma imagem de 3 canais. O FastAI usa a biblioteca PIL, portanto, converter é, na verdade, uma funcionalidade PIL
  • split_by_folder (train = 'training', valid = 'testing'): Esta função está informando ao databunch que temos dados de treinamento e teste em subpastas 'training' e 'testing' do diretório Path
  • label_from_folder () – Esta função está informando o banco de dados para pegar rótulos de dígitos do nome da pasta
  • transform (tfms = ds_tfms, size = 28) – Esta função está informando o banco de dados para aplicar a transformação definida na variável ds_tfms para cada imagem
  • databunch (bs = bs) – Essa função converte esse banco de dados na classe ImageDataBunch de FastAI com tamanho de lote definido na variável bs, isto é, 128 neste caso.

Agora nós definimos nosso banco de dados, vamos dar uma olhada nos nossos dados. Como pode ser visto abaixo, você pode ver que os dígitos são importados e visualizados usando a função show_batch e observe que essas imagens têm nossa transformação definida aplicada.

 print (data.classes) ## Imprime rótulos de classe 
print (data.c) ## Imprime o número de classes
data.show_batch (rows = 3, figsize = (10,6), hide_axis = False ) ## Mostrar dados da amostra

Definindo o Perceptron Multicamadas usando o Pytorch

Agora nós definimos nosso banco de dados. Vamos definir nosso modelo perceptron Multilayer usando o Pytorch. Para camadas totalmente conectadas, usamos a função nn.Linear e, para aplicar a não-linearidade, usamos a transformação ReLU. No Pytorch, precisamos apenas definir a função forward e a função backward é definida automaticamente usando o autograd. Se você é novo no Pytorch, eles fornecem excelente documentação e tutoriais. Eu recomendaria que você passasse por este tutorial DEEP LEARNING WITH PYTORCH: 60 MINUTE BLITZ , que cobrirá todos os conceitos básicos necessários para entender o que está acontecendo abaixo.

 classe Mnist_NN (nn.Module): 
def __init __ (self):
super () .__ init __ ()
self.lin1 = nn.Linear (784, 512, bias = True )
self.lin2 = nn.Linear (512, 256, bias = True )
self.lin3 = nn.Linear (256, 10, bias = True )

def forward (self, xb):
x = xb.view (-1,784)
x = F.relu (self.lin1 (x))
x = F.relu (self.lin2 (x))
return self.lin3 (x)

Treinando o modelo

Então agora definimos nosso modelo, precisamos treiná-lo. Podemos usar a função Learner da FastAI, o que facilita o aproveitamento de aprimoramentos modernos em métodos de otimização e muitos outros truques, como o treinamento em estilo de 1 ciclo, conforme destacado no artigo de Leslie Smith para uma convergência mais rápida. Vamos definir nossa classe Learner –

 ## Definindo o aluno 
mlp_learner = Aluno (dados = dados, modelo = Mnist_NN (), loss_func = nn.CrossEntropyLoss (), métricas = precisão)

Vamos entender o que acontece pelos argumentos acima

  • data = data – passando a nossa função Databunch
  • model = Mnist_NN () – Passando nosso modelo MLP definido Mnist_NN
  • loss_func = nn.CrossEntropyLoss () – Definindo a função de perda para otimizar, neste caso, estamos usando perda de entropia cruzada
  • métricas = precisão – é apenas para fins de impressão durante o treinamento, esse argumento não tem nada a ver com treinamento

A classe Learner fornece uma ótima função para encontrar a taxa de aprendizado ideal para começar enquanto você treina seu modelo de Aprendizado Profundo. Vamos tentar encontrar a taxa de aprendizado ideal.

 ## Finidng Aprendizagem ideal tardia 
mlp_learner.lr_find ()
mlp_learner.recorder.plot ()

Idealmente, queremos encontrar o ponto onde há o declive máximo. Nesse caso, esse ponto é 1e-2. Assim, começaremos com 1e-2 como nossa taxa de aprendizado e faremos cinco épocas usando uma função fit_one_cycle que usa uma abordagem de treinamento no estilo de 1 ciclo, conforme destacado no artigo de Leslie Smith para uma convergência mais rápida. Além disso, o FastAI mostra a barra de progresso do estilo tqdm durante o treinamento e, ao final do treinamento, começa a mostrar a tabela que mostra o progresso das funções de perda e métricas que definimos nos dados de validação.

 mlp_learner.fit_one_cycle (5,1e-2) 

Vamos diminuir a taxa de aprendizado um pouco mais, diminuindo a taxa de aprendizado e treinando o modelo um pouco mais.

 mlp_learner.fit_one_cycle (5,1e-3) 
 mlp_learner.recorder.plot_losses () 

Como podemos ver, estamos alcançando uma precisão de 98,6% usando apenas o Multilayer Perceptron.

Conclusão

O Fast.ai é uma excelente iniciativa de Jeremy Howard e sua equipe, e acredito que a biblioteca da fastai pode realmente alcançar o motivo de democratizar o aprendizado profundo para todos ao tornar a construção de modelos de aprendizagem profunda super simples.

Espero que você tenha gostado de ler e sinta-se à vontade para usar meu código para testá-lo para seus objetivos. Além disso, se houver algum comentário sobre o código ou apenas a postagem do blog, sinta-se à vontade para entrar em contato com o LinkedIn ou enviar um e-mail para aayushmnit@gmail.com. Por favor, deixe um comentário ou uma palmada se você gosta do conteúdo e quer que eu escreva esses blogs com mais frequência.