ConvNets — 3

Henrique Peixoto Machado
4 min readMay 28, 2020

Neste post irei focar no código que é usado para criar uma ConvNet, caso sobre queria saber mais detalhes sobre o assunto, recomendo irem no post 1 e post 2 onde eu explico os conceitos do que está sendo feito aqui.

Para realizar esse exemplo, eu peguei uma competição do Kaggle chamada de Dovs vs Cats. O objetivo do desafio era bem simples, eles forneciam 10k fotos de cachorros e gatos, e deveríamos contruir um modelo que identificasse se na foto era um cachorro ou gato.

Primeiramente vamos importar os pacotes que vamos necessitar para esse projeto:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import pandas as pd
import numpy as np

Como você deve ter percebido, irei usar Tensorflow para construir a ConvNet, sei que existem outras plataformas, entretanto eu acho Tensorflow uma das melhores do mercado e é gratis.

Após importar os pacotes que iremos usar, seguimos para importar os dados, alguns pontos importantes sobre os dados:

O pacote do tensorflow data_generator foi usado para classificar as imagens no diretório.

Também estou dividindo todas as imagens por 255 como uma forma de normaliza-la, pois ML algorítimos tendem a performar melhor em dados normalizados.

Os dados também estão sendo dividios em batch sizes (blocos) de 1000, isso torna mais rápido o treino da rede neural, pois ao invés de treinar cada passo nos 8k dados realizamos os treinos nos blocos, tornando assim mais rápido o processo de aprendizado.

O código:

test_dir=”../input/dogs-cats-images/dog vs cat/dataset/test_set”
train_dir=”../input/dogs-cats-images/dog vs cat/dataset/training_set”

train_dir_cats = train_dir + ‘/cats’
train_dir_dogs = train_dir + ‘/dogs’
test_dir_cats = test_dir + ‘/cats’
test_dir_dogs = test_dir + ‘/dogs’

data_generator = ImageDataGenerator(rescale = 1.0/255.0, zoom_range = 0.2)

batch_size = 1000
training_data = data_generator.flow_from_directory(directory = train_dir,
target_size = (64, 64),
batch_size = batch_size,
class_mode = ‘binary’)
testing_data = data_generator.flow_from_directory(directory = test_dir,
target_size = (64, 64),
batch_size = batch_size,
class_mode = ‘binary’)

Agora o próximo bloco de código é para montar o modelos que vai aprender com as imagens, alguns pontos sobre:

Primeiro eu gosto de utilizar o método callback, que me permite determinar um número de acurácia que se atingindo o modelo para e se da por satisfeito.

Outro ponto de atenção é que para esse modelo foi utilizado 3 camadas de ConvNets, por as imagens serem pequenas (64x64), não vi necessidade de uma rede mais profunda.

Como classifier foi escolhido a Sigmoid, que é um classificador muito bom quando se tem apenas duas opções, no post 2 eu tinha falado do Sofmax, também poderia ser usado aqui, entretanto acaba que ele é mais usado quando temos mais de duas opções para classificar, para mais detalhes sobre classificadores clique aqui

O código fica assim:

#Primeiro vamos definir o callback para caso chegue a 99% pare o treinamento automaticamente

class myCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs={}):
if(logs.get(‘acc’)<0.999):
print(“\nReached 99% accuracy so cancelling training!”)
self.model.stop_training = True
callbacks = myCallback()

#Agora vamos definir as regras do modelo:

model = tf.keras.models.Sequential([

#Note que na primeira convolutional layer temos que imputar o tamanho da imagem, que é 64x64x3.
tf.keras.layers.Conv2D(16, (3,3), activation=’relu’, input_shape=(64, 64, 3)),
tf.keras.layers.MaxPooling2D(2, 2),

#Já na segundo conv layer não tem essa necessidade:
tf.keras.layers.Conv2D(32, (3,3), activation=’relu’),
tf.keras.layers.MaxPooling2D(2,2),

#Terceira conv layer:
tf.keras.layers.Conv2D(64, (3,3), activation=’relu’),
tf.keras.layers.MaxPooling2D(2,2),

# Agora transformamos tudo que aprendemos com as cov layer em um vetor de apenas uma coluna, onde será feito a rede neural:
tf.keras.layers.Flatten(),

# Rede neural de 512 Neurons
tf.keras.layers.Dense(512, activation=’relu’),

# Apenas um output de 2 neurons, que seria classificado como gato=0 e cachorro=1, em alguns lugares você também pode ver como output apenas 1 neuron, que seria sempre que for cachorro retorne 1 e quando não for iríamos assumir que era gato. É apenas uma questão de preferência.
tf.keras.layers.Dense(2, activation=’sigmoid’)

Agora vamos compilar o modelo, como métrica eu escolhi a acurácia e estou usando o Adam como optimizer, existem várias opções que poderiam entrar aqui e para da uma lida sobre o assunto recomendo que clique aqui:

model.compile(optimizer = ‘adam’, loss = ‘sparse_categorical_crossentropy’, metrics = [‘accuracy’])

Com isso seu modelo já está montado, mas ainda não foi treinado, tudo que foi feito foi apenas criar as regras do modelo que será treinado, para treinar você tem que usar o método .fit, como a seguir:

#Como pode ver estamos treinando 30 epochs (vezes), o callback está ativo.

fitted_model = model.fit_generator(training_data,
steps_per_epoch = 8,
epochs = 30, callbacks=[callbacks])

#Depois treinamos nos dados de teste:

test_loss = model.evaluate(testing_data)

Apenas com um modelo simples conseguimos já obter uma acurácia de 78% no treino e 78% também no teste.

Acredito que ainda tem muito espaço para melhorar, pois poderíamos aplicar padding para criar uma rede convulacional mais profunda ou realizar mais epochs por exemplo, entretanto acho que já chegamos num resultado legal com um modelo simples.

Caso queiram ver apenas o código segue o link do kaggle: https://www.kaggle.com/henriquepeixoto/keras-cats-vs-dogs/

Espero que esse tutorial tenha te dado um start sobre o assunto e qualquer dúvida ou comentários por favor não hesite me procurar!

--

--