Lab9 - Redes Neurais - Transfer learning
Introdução ao Transfer Learning com redes pré-treinadas¶
Excelente! Agora que já sabemos como utilizar uma rede pré-treinada, vamos explorar uma técnica poderosa chamada Transfer Learning (Aprendizagem por Transferência). Essa abordagem nos permite tirar proveito das arquiteturas de redes neurais existentes e treiná-las para classificar objetos personalizados ou novas categorias de imagens.
O Transfer Learning é uma técnica em que um modelo de aprendizado profundo, treinado previamente em um conjunto de dados maior e mais diversificado, é adaptado para ser aplicado a um novo problema. O conhecimento adquirido pelo modelo original é transferido para o novo problema, permitindo um treinamento mais rápido e, muitas vezes, um desempenho melhor do que treinar uma rede neural do zero.
A ideia por trás do Transfer Learning é que as redes neurais pré-treinadas, como VGG, ResNet e Inception, já aprenderam a extrair características
importantes das imagens em seus primeiros estágios. Essas características podem ser comuns a muitos problemas de classificação de imagens, como detecção de bordas, texturas e padrões. Ao aproveitar esse conhecimento prévio, podemos nos concentrar no treinamento das últimas camadas do modelo, que são responsáveis por aprender características específicas do novo problema.
Ao utilizar o Transfer Learning, podemos economizar tempo e recursos computacionais, além de obter melhores resultados do que treinar uma rede do zero para um conjunto de dados menor e específico. Portanto, é uma técnica amplamente utilizada em aplicações práticas de aprendizado profundo e processamento de imagens.
Combinando a rede pré-treinada com um classificador MLP¶
Ao aplicar o Transfer Learning, nossa rede convolucional será composta por duas partes principais: o extrator de características e o classificador. O extrator de características será baseado em uma rede pré-treinada, como VGG16, ResNet50 ou InceptionV3. Essa parte da rede já aprendeu a extrair características relevantes de imagens, como bordas, texturas e padrões, durante o treinamento em um grande conjunto de dados, como o ImageNet.
Em seguida, adicionaremos um classificador MLP (Multilayer Perceptron) personalizado para resolver o nosso problema específico de classificação de imagens. Esse classificador será responsável por aprender as características específicas do novo conjunto de dados e classificar as imagens nas categorias desejadas.
Dessa forma, a rede ajustada combina o poder das redes pré-treinadas, que já aprenderam a extrair características gerais de imagens, com um classificador personalizado que aprenderá a distinguir as categorias específicas do nosso problema. Como mostra a figura abaixo:
Agora que entendemos os conceitos básicos de Transfer Learning, podemos prosseguir com os passos para aplicar o Transfer Learning e adaptar a rede pré-treinada ao nosso problema de classificação de imagens.
Passo a passo para aplicar Transfer Learning¶
Escolha uma rede pré-treinada: Selecione uma rede neural pré-treinada disponível no Keras (por exemplo, VGG16, ResNet50, InceptionV3) com base nas características e requisitos do seu problema. Cada arquitetura tem suas próprias vantagens e desvantagens, portanto, escolha aquela que melhor se adapta às suas necessidades.
Remova a camada de classificação: Carregue a rede neural pré-treinada sem a camada de classificação final. Isso pode ser feito usando o argumento include_top=False ao carregar o modelo no Keras. Isso permitirá que você adicione suas próprias camadas personalizadas para classificar as novas categorias.
Adicione camadas personalizadas: Adicione camadas específicas para o seu problema de classificação. Normalmente, isso inclui uma camada de GlobalAveragePooling2D, seguida por uma camada densa com uma função de ativação softmax e o número de neuronios igual ao número de classes do novo problema.
Congele as camadas pré-treinadas: É uma boa prática congelar as camadas pré-treinadas da rede neural, especialmente durante as primeiras épocas do treinamento. Isso evitará que os pesos dessas camadas sejam atualizados e preservará o conhecimento prévio que elas possuem. No Keras, você pode fazer isso com o modelxxx.trainable = False
Pré-processamento dos dados: Prepare os dados de acordo com a rede pré-treinada escolhida. Isso inclui redimensionar as imagens, normalizar os valores dos pixels e codificar as etiquetas das categorias. Lembre-se de aplicar as mesmas transformações usadas no conjunto de dados original da rede pré-treinada.
Treine o modelo: Treine o modelo ajustado no seu conjunto de dados. Durante as primeiras épocas, com as camadas pré-treinadas congeladas, o modelo aprenderá as características específicas do novo problema.
Avalie e otimize: Avalie o desempenho do modelo ajustado em um conjunto de teste e otimize os hiperparâmetros conforme necessário. Você pode experimentar diferentes arquiteturas de redes neurais, taxas de aprendizado, otimizadores e outros hiperparâmetros para encontrar a melhor configuração para o seu problema.
Aplicando transfer learning em um dataset já preparado pelo tensorflow¶
Vamos usar o dataset cats_vs_dogs
que é disponibilizado pelo proprio tensorflow, desta forma focamos apenas no entendimento da tecnica de transfer learning e menos em preprocessamento e criação de dados. nas proximas aulas vamos criar nosso proprio dataset...
import os
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2, preprocess_input
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# Configuração dos diretórios e parâmetros do conjunto de dados
_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True)
PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered')
train_dir = os.path.join(PATH, 'train')
validation_dir = os.path.join(PATH, 'validation')
batch_size = 32
image_size = (224, 224)
# Função para exibir algumas imagens do conjunto de dados
def plot_images(images, labels, class_names):
plt.figure(figsize=(10, 10))
for i, (img, label) in enumerate(zip(images, labels)):
plt.subplot(3, 3, i + 1)
plt.imshow(img)
plt.title(class_names[label])
plt.axis("off")
plt.show()
# Carregar imagens e rótulos do conjunto de dados de treinamento
train_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
validation_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=image_size,
batch_size=batch_size,
class_mode='binary'
)
# Carregar imagens e rótulos do conjunto de dados de validação
validation_generator = validation_datagen.flow_from_directory(
validation_dir,
target_size=image_size,
batch_size=batch_size,
class_mode='binary'
)
# Carregar algumas imagens e rótulos do conjunto de dados de treinamento
sample_datagen = ImageDataGenerator(rescale=1./255)
sample_generator = sample_datagen.flow_from_directory(
train_dir,
target_size=image_size,
batch_size=9,
class_mode='binary'
)
sample_images, sample_labels = next(sample_generator)
class_names = {v: k for k, v in sample_generator.class_indices.items()}
plot_images(sample_images, sample_labels, class_names)
Found 2000 images belonging to 2 classes. Found 1000 images belonging to 2 classes. Found 2000 images belonging to 2 classes.
Escolhendo um modelo pré-treinado¶
A MobileNet V2
desenvolvido no Google e foi treinado com 1,4 milhão de imagens
e possui 1000 classes diferentes
com pesos predeterminados do imagenet (Googles dataset).
Carregue a rede neural pré-treinada sem a camada de classificação final. Isso pode ser feito usando o argumento include_top=False
# Cria o base_model referente a MobileNet V2, sem a camada de classificação
base_model = MobileNetV2(input_shape=(224, 224, 3),
include_top=False,
weights='imagenet')
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/mobilenet_v2/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224_no_top.h5 9406464/9406464 ━━━━━━━━━━━━━━━━━━━━ 2s 0us/step
base_model.summary()
#Congela a base_model para não atuaizar os pesos quando treinar.
base_model.trainable = False
base_model.summary()
Model: "mobilenetv2_1.00_224"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ Connected to ┃ ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩ │ input_layer │ (None, 224, 224, │ 0 │ - │ │ (InputLayer) │ 3) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ Conv1 (Conv2D) │ (None, 112, 112, │ 864 │ input_layer[0][0] │ │ │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ bn_Conv1 │ (None, 112, 112, │ 128 │ Conv1[0][0] │ │ (BatchNormalizatio… │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ Conv1_relu (ReLU) │ (None, 112, 112, │ 0 │ bn_Conv1[0][0] │ │ │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ expanded_conv_dept… │ (None, 112, 112, │ 288 │ Conv1_relu[0][0] │ │ (DepthwiseConv2D) │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ expanded_conv_dept… │ (None, 112, 112, │ 128 │ expanded_conv_de… │ │ (BatchNormalizatio… │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ expanded_conv_dept… │ (None, 112, 112, │ 0 │ expanded_conv_de… │ │ (ReLU) │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ expanded_conv_proj… │ (None, 112, 112, │ 512 │ expanded_conv_de… │ │ (Conv2D) │ 16) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ expanded_conv_proj… │ (None, 112, 112, │ 64 │ expanded_conv_pr… │ │ (BatchNormalizatio… │ 16) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_expand │ (None, 112, 112, │ 1,536 │ expanded_conv_pr… │ │ (Conv2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_expand_BN │ (None, 112, 112, │ 384 │ block_1_expand[0… │ │ (BatchNormalizatio… │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_expand_relu │ (None, 112, 112, │ 0 │ block_1_expand_B… │ │ (ReLU) │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_pad │ (None, 113, 113, │ 0 │ block_1_expand_r… │ │ (ZeroPadding2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_depthwise │ (None, 56, 56, │ 864 │ block_1_pad[0][0] │ │ (DepthwiseConv2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_depthwise_… │ (None, 56, 56, │ 384 │ block_1_depthwis… │ │ (BatchNormalizatio… │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_depthwise_… │ (None, 56, 56, │ 0 │ block_1_depthwis… │ │ (ReLU) │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_project │ (None, 56, 56, │ 2,304 │ block_1_depthwis… │ │ (Conv2D) │ 24) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_1_project_BN │ (None, 56, 56, │ 96 │ block_1_project[… │ │ (BatchNormalizatio… │ 24) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_expand │ (None, 56, 56, │ 3,456 │ block_1_project_… │ │ (Conv2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_expand_BN │ (None, 56, 56, │ 576 │ block_2_expand[0… │ │ (BatchNormalizatio… │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_expand_relu │ (None, 56, 56, │ 0 │ block_2_expand_B… │ │ (ReLU) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_depthwise │ (None, 56, 56, │ 1,296 │ block_2_expand_r… │ │ (DepthwiseConv2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_depthwise_… │ (None, 56, 56, │ 576 │ block_2_depthwis… │ │ (BatchNormalizatio… │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_depthwise_… │ (None, 56, 56, │ 0 │ block_2_depthwis… │ │ (ReLU) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_project │ (None, 56, 56, │ 3,456 │ block_2_depthwis… │ │ (Conv2D) │ 24) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_project_BN │ (None, 56, 56, │ 96 │ block_2_project[… │ │ (BatchNormalizatio… │ 24) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_2_add (Add) │ (None, 56, 56, │ 0 │ block_1_project_… │ │ │ 24) │ │ block_2_project_… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_expand │ (None, 56, 56, │ 3,456 │ block_2_add[0][0] │ │ (Conv2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_expand_BN │ (None, 56, 56, │ 576 │ block_3_expand[0… │ │ (BatchNormalizatio… │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_expand_relu │ (None, 56, 56, │ 0 │ block_3_expand_B… │ │ (ReLU) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_pad │ (None, 57, 57, │ 0 │ block_3_expand_r… │ │ (ZeroPadding2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_depthwise │ (None, 28, 28, │ 1,296 │ block_3_pad[0][0] │ │ (DepthwiseConv2D) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_depthwise_… │ (None, 28, 28, │ 576 │ block_3_depthwis… │ │ (BatchNormalizatio… │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_depthwise_… │ (None, 28, 28, │ 0 │ block_3_depthwis… │ │ (ReLU) │ 144) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_project │ (None, 28, 28, │ 4,608 │ block_3_depthwis… │ │ (Conv2D) │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_3_project_BN │ (None, 28, 28, │ 128 │ block_3_project[… │ │ (BatchNormalizatio… │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_expand │ (None, 28, 28, │ 6,144 │ block_3_project_… │ │ (Conv2D) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_expand_BN │ (None, 28, 28, │ 768 │ block_4_expand[0… │ │ (BatchNormalizatio… │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_expand_relu │ (None, 28, 28, │ 0 │ block_4_expand_B… │ │ (ReLU) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_depthwise │ (None, 28, 28, │ 1,728 │ block_4_expand_r… │ │ (DepthwiseConv2D) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_depthwise_… │ (None, 28, 28, │ 768 │ block_4_depthwis… │ │ (BatchNormalizatio… │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_depthwise_… │ (None, 28, 28, │ 0 │ block_4_depthwis… │ │ (ReLU) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_project │ (None, 28, 28, │ 6,144 │ block_4_depthwis… │ │ (Conv2D) │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_project_BN │ (None, 28, 28, │ 128 │ block_4_project[… │ │ (BatchNormalizatio… │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_4_add (Add) │ (None, 28, 28, │ 0 │ block_3_project_… │ │ │ 32) │ │ block_4_project_… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_expand │ (None, 28, 28, │ 6,144 │ block_4_add[0][0] │ │ (Conv2D) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_expand_BN │ (None, 28, 28, │ 768 │ block_5_expand[0… │ │ (BatchNormalizatio… │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_expand_relu │ (None, 28, 28, │ 0 │ block_5_expand_B… │ │ (ReLU) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_depthwise │ (None, 28, 28, │ 1,728 │ block_5_expand_r… │ │ (DepthwiseConv2D) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_depthwise_… │ (None, 28, 28, │ 768 │ block_5_depthwis… │ │ (BatchNormalizatio… │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_depthwise_… │ (None, 28, 28, │ 0 │ block_5_depthwis… │ │ (ReLU) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_project │ (None, 28, 28, │ 6,144 │ block_5_depthwis… │ │ (Conv2D) │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_project_BN │ (None, 28, 28, │ 128 │ block_5_project[… │ │ (BatchNormalizatio… │ 32) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_5_add (Add) │ (None, 28, 28, │ 0 │ block_4_add[0][0… │ │ │ 32) │ │ block_5_project_… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_expand │ (None, 28, 28, │ 6,144 │ block_5_add[0][0] │ │ (Conv2D) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_expand_BN │ (None, 28, 28, │ 768 │ block_6_expand[0… │ │ (BatchNormalizatio… │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_expand_relu │ (None, 28, 28, │ 0 │ block_6_expand_B… │ │ (ReLU) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_pad │ (None, 29, 29, │ 0 │ block_6_expand_r… │ │ (ZeroPadding2D) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_depthwise │ (None, 14, 14, │ 1,728 │ block_6_pad[0][0] │ │ (DepthwiseConv2D) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_depthwise_… │ (None, 14, 14, │ 768 │ block_6_depthwis… │ │ (BatchNormalizatio… │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_depthwise_… │ (None, 14, 14, │ 0 │ block_6_depthwis… │ │ (ReLU) │ 192) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_project │ (None, 14, 14, │ 12,288 │ block_6_depthwis… │ │ (Conv2D) │ 64) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_6_project_BN │ (None, 14, 14, │ 256 │ block_6_project[… │ │ (BatchNormalizatio… │ 64) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_expand │ (None, 14, 14, │ 24,576 │ block_6_project_… │ │ (Conv2D) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_expand_BN │ (None, 14, 14, │ 1,536 │ block_7_expand[0… │ │ (BatchNormalizatio… │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_expand_relu │ (None, 14, 14, │ 0 │ block_7_expand_B… │ │ (ReLU) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_depthwise │ (None, 14, 14, │ 3,456 │ block_7_expand_r… │ │ (DepthwiseConv2D) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_depthwise_… │ (None, 14, 14, │ 1,536 │ block_7_depthwis… │ │ (BatchNormalizatio… │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_depthwise_… │ (None, 14, 14, │ 0 │ block_7_depthwis… │ │ (ReLU) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_project │ (None, 14, 14, │ 24,576 │ block_7_depthwis… │ │ (Conv2D) │ 64) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_project_BN │ (None, 14, 14, │ 256 │ block_7_project[… │ │ (BatchNormalizatio… │ 64) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_7_add (Add) │ (None, 14, 14, │ 0 │ block_6_project_… │ │ │ 64) │ │ block_7_project_… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_expand │ (None, 14, 14, │ 24,576 │ block_7_add[0][0] │ │ (Conv2D) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_expand_BN │ (None, 14, 14, │ 1,536 │ block_8_expand[0… │ │ (BatchNormalizatio… │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_expand_relu │ (None, 14, 14, │ 0 │ block_8_expand_B… │ │ (ReLU) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_depthwise │ (None, 14, 14, │ 3,456 │ block_8_expand_r… │ │ (DepthwiseConv2D) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_depthwise_… │ (None, 14, 14, │ 1,536 │ block_8_depthwis… │ │ (BatchNormalizatio… │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_depthwise_… │ (None, 14, 14, │ 0 │ block_8_depthwis… │ │ (ReLU) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_project │ (None, 14, 14, │ 24,576 │ block_8_depthwis… │ │ (Conv2D) │ 64) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_project_BN │ (None, 14, 14, │ 256 │ block_8_project[… │ │ (BatchNormalizatio… │ 64) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_8_add (Add) │ (None, 14, 14, │ 0 │ block_7_add[0][0… │ │ │ 64) │ │ block_8_project_… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_expand │ (None, 14, 14, │ 24,576 │ block_8_add[0][0] │ │ (Conv2D) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_expand_BN │ (None, 14, 14, │ 1,536 │ block_9_expand[0… │ │ (BatchNormalizatio… │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_expand_relu │ (None, 14, 14, │ 0 │ block_9_expand_B… │ │ (ReLU) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_depthwise │ (None, 14, 14, │ 3,456 │ block_9_expand_r… │ │ (DepthwiseConv2D) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_depthwise_… │ (None, 14, 14, │ 1,536 │ block_9_depthwis… │ │ (BatchNormalizatio… │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_depthwise_… │ (None, 14, 14, │ 0 │ block_9_depthwis… │ │ (ReLU) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_project │ (None, 14, 14, │ 24,576 │ block_9_depthwis… │ │ (Conv2D) │ 64) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_project_BN │ (None, 14, 14, │ 256 │ block_9_project[… │ │ (BatchNormalizatio… │ 64) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_9_add (Add) │ (None, 14, 14, │ 0 │ block_8_add[0][0… │ │ │ 64) │ │ block_9_project_… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_10_expand │ (None, 14, 14, │ 24,576 │ block_9_add[0][0] │ │ (Conv2D) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_10_expand_BN │ (None, 14, 14, │ 1,536 │ block_10_expand[… │ │ (BatchNormalizatio… │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_10_expand_re… │ (None, 14, 14, │ 0 │ block_10_expand_… │ │ (ReLU) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_10_depthwise │ (None, 14, 14, │ 3,456 │ block_10_expand_… │ │ (DepthwiseConv2D) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_10_depthwise… │ (None, 14, 14, │ 1,536 │ block_10_depthwi… │ │ (BatchNormalizatio… │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_10_depthwise… │ (None, 14, 14, │ 0 │ block_10_depthwi… │ │ (ReLU) │ 384) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_10_project │ (None, 14, 14, │ 36,864 │ block_10_depthwi… │ │ (Conv2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_10_project_BN │ (None, 14, 14, │ 384 │ block_10_project… │ │ (BatchNormalizatio… │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_expand │ (None, 14, 14, │ 55,296 │ block_10_project… │ │ (Conv2D) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_expand_BN │ (None, 14, 14, │ 2,304 │ block_11_expand[… │ │ (BatchNormalizatio… │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_expand_re… │ (None, 14, 14, │ 0 │ block_11_expand_… │ │ (ReLU) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_depthwise │ (None, 14, 14, │ 5,184 │ block_11_expand_… │ │ (DepthwiseConv2D) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_depthwise… │ (None, 14, 14, │ 2,304 │ block_11_depthwi… │ │ (BatchNormalizatio… │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_depthwise… │ (None, 14, 14, │ 0 │ block_11_depthwi… │ │ (ReLU) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_project │ (None, 14, 14, │ 55,296 │ block_11_depthwi… │ │ (Conv2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_project_BN │ (None, 14, 14, │ 384 │ block_11_project… │ │ (BatchNormalizatio… │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_11_add (Add) │ (None, 14, 14, │ 0 │ block_10_project… │ │ │ 96) │ │ block_11_project… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_expand │ (None, 14, 14, │ 55,296 │ block_11_add[0][… │ │ (Conv2D) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_expand_BN │ (None, 14, 14, │ 2,304 │ block_12_expand[… │ │ (BatchNormalizatio… │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_expand_re… │ (None, 14, 14, │ 0 │ block_12_expand_… │ │ (ReLU) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_depthwise │ (None, 14, 14, │ 5,184 │ block_12_expand_… │ │ (DepthwiseConv2D) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_depthwise… │ (None, 14, 14, │ 2,304 │ block_12_depthwi… │ │ (BatchNormalizatio… │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_depthwise… │ (None, 14, 14, │ 0 │ block_12_depthwi… │ │ (ReLU) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_project │ (None, 14, 14, │ 55,296 │ block_12_depthwi… │ │ (Conv2D) │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_project_BN │ (None, 14, 14, │ 384 │ block_12_project… │ │ (BatchNormalizatio… │ 96) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_12_add (Add) │ (None, 14, 14, │ 0 │ block_11_add[0][… │ │ │ 96) │ │ block_12_project… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_expand │ (None, 14, 14, │ 55,296 │ block_12_add[0][… │ │ (Conv2D) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_expand_BN │ (None, 14, 14, │ 2,304 │ block_13_expand[… │ │ (BatchNormalizatio… │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_expand_re… │ (None, 14, 14, │ 0 │ block_13_expand_… │ │ (ReLU) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_pad │ (None, 15, 15, │ 0 │ block_13_expand_… │ │ (ZeroPadding2D) │ 576) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_depthwise │ (None, 7, 7, 576) │ 5,184 │ block_13_pad[0][… │ │ (DepthwiseConv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_depthwise… │ (None, 7, 7, 576) │ 2,304 │ block_13_depthwi… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_depthwise… │ (None, 7, 7, 576) │ 0 │ block_13_depthwi… │ │ (ReLU) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_project │ (None, 7, 7, 160) │ 92,160 │ block_13_depthwi… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_13_project_BN │ (None, 7, 7, 160) │ 640 │ block_13_project… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_expand │ (None, 7, 7, 960) │ 153,600 │ block_13_project… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_expand_BN │ (None, 7, 7, 960) │ 3,840 │ block_14_expand[… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_expand_re… │ (None, 7, 7, 960) │ 0 │ block_14_expand_… │ │ (ReLU) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_depthwise │ (None, 7, 7, 960) │ 8,640 │ block_14_expand_… │ │ (DepthwiseConv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_depthwise… │ (None, 7, 7, 960) │ 3,840 │ block_14_depthwi… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_depthwise… │ (None, 7, 7, 960) │ 0 │ block_14_depthwi… │ │ (ReLU) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_project │ (None, 7, 7, 160) │ 153,600 │ block_14_depthwi… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_project_BN │ (None, 7, 7, 160) │ 640 │ block_14_project… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_14_add (Add) │ (None, 7, 7, 160) │ 0 │ block_13_project… │ │ │ │ │ block_14_project… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_expand │ (None, 7, 7, 960) │ 153,600 │ block_14_add[0][… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_expand_BN │ (None, 7, 7, 960) │ 3,840 │ block_15_expand[… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_expand_re… │ (None, 7, 7, 960) │ 0 │ block_15_expand_… │ │ (ReLU) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_depthwise │ (None, 7, 7, 960) │ 8,640 │ block_15_expand_… │ │ (DepthwiseConv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_depthwise… │ (None, 7, 7, 960) │ 3,840 │ block_15_depthwi… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_depthwise… │ (None, 7, 7, 960) │ 0 │ block_15_depthwi… │ │ (ReLU) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_project │ (None, 7, 7, 160) │ 153,600 │ block_15_depthwi… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_project_BN │ (None, 7, 7, 160) │ 640 │ block_15_project… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_15_add (Add) │ (None, 7, 7, 160) │ 0 │ block_14_add[0][… │ │ │ │ │ block_15_project… │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_16_expand │ (None, 7, 7, 960) │ 153,600 │ block_15_add[0][… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_16_expand_BN │ (None, 7, 7, 960) │ 3,840 │ block_16_expand[… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_16_expand_re… │ (None, 7, 7, 960) │ 0 │ block_16_expand_… │ │ (ReLU) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_16_depthwise │ (None, 7, 7, 960) │ 8,640 │ block_16_expand_… │ │ (DepthwiseConv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_16_depthwise… │ (None, 7, 7, 960) │ 3,840 │ block_16_depthwi… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_16_depthwise… │ (None, 7, 7, 960) │ 0 │ block_16_depthwi… │ │ (ReLU) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_16_project │ (None, 7, 7, 320) │ 307,200 │ block_16_depthwi… │ │ (Conv2D) │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ block_16_project_BN │ (None, 7, 7, 320) │ 1,280 │ block_16_project… │ │ (BatchNormalizatio… │ │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ Conv_1 (Conv2D) │ (None, 7, 7, │ 409,600 │ block_16_project… │ │ │ 1280) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ Conv_1_bn │ (None, 7, 7, │ 5,120 │ Conv_1[0][0] │ │ (BatchNormalizatio… │ 1280) │ │ │ ├─────────────────────┼───────────────────┼────────────┼───────────────────┤ │ out_relu (ReLU) │ (None, 7, 7, │ 0 │ Conv_1_bn[0][0] │ │ │ 1280) │ │ │ └─────────────────────┴───────────────────┴────────────┴───────────────────┘
Total params: 2,257,984 (8.61 MB)
Trainable params: 0 (0.00 B)
Non-trainable params: 2,257,984 (8.61 MB)
Adicionando um Classificador¶
#Camada para gerar um vetor de 1280 elementos
global_average_layer = layers.GlobalAveragePooling2D()
# O Classificador para gato cachorro com 1 neuronio
saida_layer = layers.Dense(1, activation='sigmoid')
model = tf.keras.Sequential([
base_model, #### cnn mobilenet
global_average_layer, ###flatten
saida_layer ### especiallista
])
model.summary()
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ mobilenetv2_1.00_224 │ ? │ 2,257,984 │ │ (Functional) │ │ │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ global_average_pooling2d │ ? │ 0 (unbuilt) │ │ (GlobalAveragePooling2D) │ │ │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense (Dense) │ ? │ 0 (unbuilt) │ └─────────────────────────────────┴────────────────────────┴───────────────┘
Total params: 2,257,984 (8.61 MB)
Trainable params: 0 (0.00 B)
Non-trainable params: 2,257,984 (8.61 MB)
Pronto! Já criamos a nossa rede para classificação. Agora podemos treinar nossa rede e testar.
Desafio 2¶
Vamos entender o que acabamos de fazer. Avalie a quantidade de parametros total, treinaveis e não treinaveis. O que foi identificado?
sua resposta aqui.....¶
.
Treinamento do modelo¶
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
#Avaliação do modelo antes de treiná-lo com novas imagens
validation_steps=20
loss0,accuracy0 = model.evaluate(train_generator, steps = validation_steps)
/Users/arnaldoalvesvianajunior/Library/Python/3.9/lib/python/site-packages/keras/src/trainers/data_adapters/py_dataset_adapter.py:121: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored. self._warn_if_super_not_called()
20/20 ━━━━━━━━━━━━━━━━━━━━ 12s 532ms/step - accuracy: 0.4012 - loss: 0.8502
# Treinamento da nova CNN
history = model.fit(train_generator, epochs=5, validation_data=validation_generator)
Epoch 1/5 63/63 ━━━━━━━━━━━━━━━━━━━━ 57s 839ms/step - accuracy: 0.7936 - loss: 0.4272 - val_accuracy: 0.9800 - val_loss: 0.0941 Epoch 2/5 63/63 ━━━━━━━━━━━━━━━━━━━━ 51s 808ms/step - accuracy: 0.9750 - loss: 0.0902 - val_accuracy: 0.9820 - val_loss: 0.0717 Epoch 3/5 63/63 ━━━━━━━━━━━━━━━━━━━━ 51s 799ms/step - accuracy: 0.9825 - loss: 0.0656 - val_accuracy: 0.9830 - val_loss: 0.0602 Epoch 4/5 63/63 ━━━━━━━━━━━━━━━━━━━━ 50s 801ms/step - accuracy: 0.9880 - loss: 0.0511 - val_accuracy: 0.9840 - val_loss: 0.0511 Epoch 5/5 63/63 ━━━━━━━━━━━━━━━━━━━━ 50s 794ms/step - accuracy: 0.9904 - loss: 0.0442 - val_accuracy: 0.9830 - val_loss: 0.0503
import pandas as pd
metrics_df = pd.DataFrame(history.history)
metrics_df[["loss","val_loss"]].plot();
metrics_df[["accuracy", "val_accuracy"]].plot();
Fazendo predições¶
import numpy as np
from tensorflow.keras.preprocessing import image
def predict_cat_or_dog(img_path):
img = image.load_img(img_path, target_size=image_size)
img_array = image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
img_array = preprocess_input(img_array)
prediction = model.predict(img_array)
if prediction[0][0] < 0.5:
return "gatinhooooo"
else:
return "cachorrinho"
# Teste a função de previsão com uma imagem
# !wget https://uploads.metropoles.com/wp-content/uploads/2022/07/21154234/como-identificar-que-um-cachorro-esta-sendo-vitima-de-maus-tratos-1.jpg -O /content/cachorro.jpg
# img_path = "cachorro.jpg"
img_path = "dog.png"
result = predict_cat_or_dog(img_path)
print("Essa foto é de um ", result)
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 899ms/step Essa foto é de um cachorrinho
Salvando o modelo da rede treinada¶
Agora que já temos um modelo treinado e ajustado para resolver o problema especifico que temos, podemos salver a arquitetura e os pesos em um arquivo com extensão .h5
para usar esta rede, basta carregar o arquivo.h5
# Salvando a rede
model.save("dogs_vs_cats.h5")
#Carregando uma rede .h5
new_model = models.load_model('dogs_vs_cats.h5')
Desafio 3¶
Aplicar o Transfer Learning usando a rede pré-treinada ResNet50 e o conjunto de dados CIFAR-10, que possui 10 classes de objetos.
### Seu código aqui....