Como criar um classificador de imagem simples

A classificação de imagens é uma aplicação incrível de aprendizado profundo. Podemos treinar um algoritmo poderoso para modelar um grande conjunto de dados de imagens. Esse modelo pode então ser usado para classificar um conjunto de imagens semelhante, mas desconhecido.

Não há limite para as aplicações de classificação de imagens. Você pode usá-lo em seu próximo aplicativo ou para resolver algum problema do mundo real. Isso é tudo com você. Mas para alguém que é bastante novo neste reino, pode parecer muito desafiador no início. Como devo obter meus dados? Como devo construir meu modelo? Quais ferramentas devo usar?

Neste artigo, discutiremos tudo isso - desde encontrar um conjunto de dados até treinar seu modelo. Vou tentar tornar as coisas o mais simples possível, evitando alguns detalhes técnicos ( PS: Por favor, note que isso não significa que esses detalhes não sejam importantes. Mencionarei alguns recursos excelentes que você pode consultar para aprender mais sobre esses tópicos ). O objetivo deste artigo é explicar o processo básico de construção de um classificador de imagens e é nisso que nos concentraremos mais aqui.

Construiremos um classificador de imagens para o conjunto de dados Fashion-MNIST. O conjunto de dados Fashion-MNIST é uma coleção de imagens de artigos de Zalando. Ele contém 60.000 imagens para o conjunto de treinamento e 10.000 imagens para os dados do conjunto de teste ( discutiremos os conjuntos de dados de teste e treinamento junto com o conjunto de dados de validação posteriormente ). Essas imagens pertencem aos rótulos de 10 classes diferentes.

Importando Bibliotecas

Nosso objetivo é treinar um modelo de aprendizado profundo que possa classificar um determinado conjunto de imagens em uma dessas 10 classes. Agora que temos nosso conjunto de dados, devemos passar para as ferramentas de que precisamos. Existem muitas bibliotecas e ferramentas que você pode escolher com base em seus próprios requisitos de projeto. Para este, vou me limitar ao seguinte:

  1. Numpy - biblioteca Python para computação numérica
  2. Pandas - manipulação de dados da biblioteca Python
  3. Matplotlib - visualização de dados da biblioteca Python
  4. Keras - biblioteca Python baseada em tensorflow para a criação de modelos de aprendizado profundo
  5. Jupyter - executarei todo o meu código nos Notebooks Jupyter. Você pode instalá-lo através do link. Você também pode usar o Google Colabs se precisar de melhor capacidade computacional.

Junto com esses quatro, também usaremos o scikit-learn. O propósito dessas bibliotecas ficará mais claro assim que mergulharmos no código.

OK! Temos nossas ferramentas e bibliotecas prontas. Agora devemos começar a configurar nosso código.

Comece importando todas as bibliotecas mencionadas acima. Junto com a importação de bibliotecas, também importei alguns módulos específicos dessas bibliotecas. Deixe-me examiná-los um por um.

import numpy as np import pandas as pd import matplotlib.pyplot as plt import keras from sklearn.model_selection import train_test_split from keras.utils import to_categorical from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D from keras.layers import Dense, Dropout from keras.layers import Flatten, BatchNormalization

train_test_split: este módulo divide o conjunto de dados de treinamento em dados de treinamento e validação. A razão por trás dessa divisão é verificar se nosso modelo está com overfitting ou não. Usamos um conjunto de dados de treinamento para treinar nosso modelo e, em seguida, compararemos a precisão resultante com a precisão da validação. Se a diferença entre as duas quantidades for significativamente grande, nosso modelo provavelmente está com overfitting. Iremos reiterar através do nosso processo de construção de modelo e fazer as alterações necessárias ao longo do caminho. Assim que estivermos satisfeitos com nossas precisões de treinamento e validação, faremos as previsões finais sobre nossos dados de teste.

to_categorical: to_categorical é um utilitário keras. É usado para converter os rótulos categóricos em codificações one-hot. Digamos que temos três rótulos ("maçãs", "laranjas", "bananas"), então uma codificação ativa para cada um deles seria [1, 0, 0] -> "maçãs", [0, 1, 0] -> "laranjas", [0, 0, 1] -> "bananas".

O resto dos módulos Keras que importamos são camadas convolucionais. Discutiremos camadas convolucionais quando começarmos a construir nosso modelo. Também daremos uma rápida olhada no que cada uma dessas camadas faz.

Pré-processamento de dados

Por enquanto, mudaremos nossa atenção para obter nossos dados e analisá-los. Você deve sempre se lembrar da importância do pré-processamento e da análise dos dados. Ele não apenas fornece informações sobre os dados, mas também ajuda a localizar inconsistências.

Uma variação muito pequena nos dados às vezes pode levar a um resultado devastador para o seu modelo. Isso torna importante pré-processar seus dados antes de usá-los para treinamento. Portanto, com isso em mente, vamos iniciar o pré-processamento de dados.

train_df = pd.read_csv('./fashion-mnist_train.csv') test_df = pd.read_csv('./fashion-mnist_test.csv')

Primeiramente vamos importar nosso conjunto de dados ( aqui está o link para baixar este conjunto de dados em seu sistema ). Depois de importar o conjunto de dados, execute o seguinte comando.

train_df.head()

Este comando mostrará como seus dados se parecem. A captura de tela a seguir mostra a saída desse comando.

Podemos ver como nossos dados de imagem são armazenados na forma de valores de pixel. Mas não podemos fornecer dados ao nosso modelo neste formato. Portanto, teremos que convertê-lo em matrizes numpy.

train_data = np.array(train_df.iloc[:, 1:]) test_data = np.array(test_df.iloc[:, 1:])

Agora é hora de obter nossos rótulos.

train_labels = to_categorical(train_df.iloc[:, 0]) test_labels = to_categorical(test_df.iloc[:, 0])

Aqui, você pode ver que usamos to_categorical para converter nossos dados categóricos em uma codificação dinâmica .

Agora vamos remodelar os dados e convertê-los no tipo float32 para que possamos usá-los convenientemente.

rows, cols = 28, 28 train_data = train_data.reshape(train_data.shape[0], rows, cols, 1) test_data = test_data.reshape(test_data.shape[0], rows, cols, 1) train_data = train_data.astype('float32') test_data = test_data.astype('float32')

Estamos quase terminando. Vamos apenas terminar o pré-processamento de nossos dados normalizando-os. A normalização dos dados da imagem mapeará todos os valores de pixel em cada imagem para os valores entre 0 e 1. Isso nos ajuda a reduzir as inconsistências nos dados. Antes de normalizar, os dados da imagem podem ter grandes variações nos valores dos pixels, o que pode levar a algum comportamento incomum durante o processo de treinamento.

train_data /= 255.0 test_data /= 255.0

Redes Neurais Convolucionais

Então, o pré-processamento de dados é feito. Agora podemos começar a construir nosso modelo. Construiremos uma Rede Neural Convolucional para modelar os dados da imagem. CNNs são versões modificadas de redes neurais regulares. Eles são modificados especificamente para dados de imagem. Alimentar imagens para redes neurais regulares exigiria que nossa rede tivesse um grande número de neurônios de entrada. Por exemplo, apenas para uma imagem de 28x28, precisaríamos de 784 neurônios de entrada. Isso criaria uma grande confusão de parâmetros de treinamento.

As CNNs resolvem esse problema presumindo que a entrada será uma imagem. O objetivo principal das redes neurais convolucionais é tirar vantagem da estrutura espacial da imagem e extrair recursos de alto nível dela e, em seguida, treinar sobre esses recursos. Ele faz isso executando uma operação de convolução na matriz de valores de pixel.

The visualization above shows how convolution operation works. And the Conv2D layer we imported earlier does the same thing. The first matrix (from the left) in the demonstration is the input to the convolutional layer. Then another matrix called "filter" or "kernel" is multiplied (matrix multiplication) to each window of the input matrix. The output of this multiplication is the input to the next layer.

Other than convolutional layers, a typical CNN also has two other types of layers: 1) a  pooling layer, and 2) a fully connected layer.

Pooling layers are used to generalize the output of the convolutional layers. Along with generalizing, it also reduces the number of parameters in the model by down-sampling the output of the convolutional layer.

As we just learned, convolutional layers represent high level features from image data. Fully connected layers use these high level features to train the parameters and to learn to classify those images.

We will also use the Dropout, Batch-normalization and Flatten layers in addition to the layers mentioned above. Flatten layer converts the output of convolutional layers into a one dimensional feature vector. It is important to flatten the outputs because Dense (Fully connected) layers only accept a feature vector as input. Dropout and Batch-normalization layers are for preventing the model from overfitting.

train_x, val_x, train_y, val_y = train_test_split(train_data, train_labels, test_size=0.2) batch_size = 256 epochs = 5 input_shape = (rows, cols, 1)
def baseline_model(): model = Sequential() model.add(BatchNormalization(input_shape=input_shape)) model.add(Conv2D(32, (3, 3), padding="same", activation="relu")) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2))) model.add(Dropout(0.25)) model.add(BatchNormalization()) model.add(Conv2D(32, (3, 3), padding="same", activation="relu")) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation="relu")) model.add(Dropout(0.5)) model.add(Dense(10, activation="softmax")) return model

The code that you see above is the code for our CNN model. You can structure these layers in many different ways to get good results. There are many popular CNN architectures which give state of the art results. Here, I have just created my own simple architecture for the purpose of this problem. Feel free to try your own and let me know what results you get :)

Training the model

Once you have created the model you can import it and then compile it by using the code below.

model = baseline_model() model.compile(loss='categorical_crossentropy', optimizer="sgd", metrics=['accuracy']) 

model.compile configures the learning process for our model. We have passed it three arguments. These arguments define the loss function for our model, optimizer and metrics.

history = model.fit(train_x, train_y, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(val_x, val_y)) 

And finally by running the code above you can train your model. I am training this model for just five epochs but you can increase the number of epochs. After your training process is completed you can make predictions on the test set by using the following code.

predictions= model.predict(test_data)

Conclusion

Congrats! You did it, you have taken your first step into the amazing world of computer vision.

You have created a your own image classifier. Even though this is a great achievement, we have just scratched the surface.

There is a lot you can do with CNNs. The applications are limitless. I hope that this article helped you to get an understanding of how the process of training these models works.

Trabalhar em outros conjuntos de dados por conta própria ajudará você a entender isso ainda melhor. Também criei um repositório GitHub para o código que usei neste artigo. Portanto, se este artigo foi útil para você, por favor me avise.

Se você tiver alguma dúvida ou quiser compartilhar seus próprios resultados ou se quiser apenas dizer "oi", fique à vontade para me contactar no twitter, e eu tentarei fazer o meu melhor para ajudá-lo. E, finalmente, muito obrigado por ler este artigo !! :)