Esse tutorial tem como objetivo utilizar o framework de machine learning fastai, para realizar um dos desafios mais tradicionais de classificação de imagens. Este é um dos desafios iniciais para os apredizes de redes neurais artificiais no que tange processamento de imagens, a base de dados utilizada para projeto pode ser encontradas em dois links diferentes:

Carregando os pacotes utilizados

from fastai.vision.all import *
import numpy as np
import pandas as pd

Durante esse projeto estara sendo utilizado a versão 2.0.8 do fastai.

fastai.__version__

Definição do caminho dos arquivos

Um ponto inicial para o projeto é a definicação de um objeto que contenha o caminho diretório das imagens, para isso será utilizada o método Path do fastai. Esse método não retornará somente uma string contendo o diretório, mas sim uma classe da biblioteca padrão do Python 3, o que torna mais fácil o acesso aos arquivos e diretórios.

path = Path(r"/content/images")

Carregando as imagens para o modelo

Para carregar as imagens para o treinamento do modelo precisamos uma função a qual determina o tipo da base de dados e como ela está estruturada. Para isso, utiliza-se a função ImageDataLoaders.

dls = ImageDataLoaders.from_folder(path, train = 'train', valid = 'valid', shuffle_train = True, bs=16)

Definição e treinamento do modelo

Para definição da rede neural convolucional (Convolutional Neural Network) é utilizada a função cnn_learner.

Os argumentos que serão passados para esta será:

  • dls dataloader definido anteriormente;
  • resnet34 - arquitetura da rede neural, que neste caso está pretreinada amplamente utilizada para esse fim. Para saber mais sobre a resnet34: https://www.kaggle.com/pytorch/resnet34;
  • error_rate - metrica utilizada para avaliação do modelo.

Afim de agilizar o treinamento do modelo, será utilizado o método to_fp16 (half-precision floating point) que utilizada números menos precisos, onde é possível.

Após isso pode-se realizar o treinamento da rede neural, para isso está sendo utilizada o método fine_tune. Como estamos utilizando uma rede neural pre-treinada, iremos realizar 4 iterações randomicamente utilizando os parâmetros pre-treinados e depois "descongela" todos as camadas treina o modelo alterando todos os pesos.

from fastai.callback.fp16 import *
learn = cnn_learner(dls, resnet34, metrics=error_rate).to_fp16()
learn.fine_tune(12, freeze_epochs=4)
Downloading: "https://download.pytorch.org/models/resnet34-333f7ec4.pth" to /root/.cache/torch/hub/checkpoints/resnet34-333f7ec4.pth

epoch train_loss valid_loss error_rate time
0 0.924272 0.584760 0.178796 03:10
1 0.435553 0.265654 0.083622 03:07
2 0.220256 0.117850 0.036629 03:06
3 0.145699 0.071909 0.021520 03:07
epoch train_loss valid_loss error_rate time
0 0.071176 0.027350 0.007510 03:36
1 0.047109 0.023690 0.006851 03:36
2 0.061107 0.022068 0.005578 03:40
3 0.033989 0.016123 0.004743 03:37
4 0.024662 0.011009 0.003470 03:37
5 0.006776 0.007155 0.002108 03:36
6 0.003653 0.005281 0.001537 03:38
7 0.000893 0.003047 0.000922 03:38
8 0.000837 0.002989 0.000571 03:39
9 0.000062 0.001865 0.000571 03:37
10 0.002896 0.002266 0.000659 03:37
11 0.000056 0.001731 0.000527 03:43

Como pode-se observar no gráfico abaixo, o erro apresentado durante o trainamento decresceu até a marca de 5.27e-4 utilizando na base de dados de treinamento, o que para parece muito bom.

learn.recorder.plot_loss()

Salvando o modelo treinado

Para salvar o modelo pode-se utilizar o método export(), o qual irá salvar no diretório padrão o arquivo export.pkl. Para carregar o modelo basta utilizar a função load_learn().

learn.export()

Fazendo as predições

Para se realizar as predições, será utilizada o método predict() e o argumento é o arquivo de imagem em .jpg.

#hide_output
pred = []
for i in range(len(test_images)):
  image_path = "/content/images/test/" + str(i) + ".jpg"
  pred.append(int(learn.predict(image_path)[0]))

Para salvar o arquivo em um formato .csv foi criado um dataframe do pacote pandas e feita as devidas transformações para ser enviado para o Kaggle.

prediction = {'ImageId': list(range(1,28001)),
              'Label': pred}

df = pd.DataFrame(prediction)
df.to_csv('predicitons.csv', index = False)

Este modelo acertou 99,421% das 28000 imagens de teste.

Submission