Transfer Learning no Tensorflow

Original article was published on Deep Learning on Medium

Transfer Learning no Tensorflow

Semana passada eu fiz posts 1, 2 e 3 sobre visão computacional e como elas funcionam, entretanto refletindo faltou falar sobre uma função super importante para ConvNets, que é transfer learning.

Em visão computacional o grande desafio é encontrar grandes datasets com imagens corretamente identificadas, já houve algumas tentativas de usar imagens criadas digitalmente:

Mão feita em um software 3D

Mas quando esses modelos tiveram que classificar objetos reais performaram muito mal. Então como resolver isso?

Umas das técnicas que vem gerando resultados incríveis é o transfer learning, que parte da premissa que reconhecer as low-level features seria muito parecido não importa qual imagem você está tentando reconhecer, então com isso você pode pegar um modelo treinado com milhões de imagens para reconhecer as low features e depois você treinaria seu modelo apenas para as high-level features do seu problema em específico.

Para se aprofundar no assunto recomendo da uma olhada nesses 3 modelos: VGG, Inception, MobileNet.

Ta, agora como fazer isso no código?

Para este exemplo vou utilizar o dataset horse or human. Irei usar o Inception para transferir o conhecimento para o meu modelo.

Começamos importando os pacotes que vamos usar.

import os

import tensorflow as tf

from tensorflow.keras import layers

from tensorflow.keras import Model

from os import getcwd

E já vamos importar o modelo:

# Download the inception v3 weights

!wget — no-check-certificate \

https://storage.googleapis.com/mledu-datasets/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5 \

-O /tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5

# Import the inception model

from tensorflow.keras.applications.inception_v3 import InceptionV3

# Create an instance of the inception model from the local pre-trained weights

local_weights_file = ‘/tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5’

pre_trained_model = InceptionV3(input_shape = (150, 150, 3),

include_top = False,

weights = None)

pre_trained_model.load_weights(local_weights_file)

# Make all the layers in the pre-trained model non-trainable

for layer in pre_trained_model.layers:

layer.trainable = False

# Print the model summary

#pre_trained_model.summary()

Alguns pontos sobre o código acima, primeiro você tem que deixar layer trainable como False, para bloquear a sua nova rede neural de apagar os pesos do modelo que você está importando para as primeiras layers.

Agora vamos escolher a partir de qual layer o modelo será treinado, eu escolhi a ‘mixed7’ entretanto recomendo você testar com outras layers para ver o impacto no resultado.

last_layer = pre_trained_model.get_layer(‘mixed7’)

print(‘last layer output shape: ‘, last_layer.output_shape)

last_output = last_layer.output

Comece chamando o modelo definido acima como last_output ao invés de criar uma ConvNet, pois o last_output já é a ConvNet, então o código fica assim:

from tensorflow.keras.optimizers import RMSprop

# Flatten the output layer to 1 dimension

x = layers.Flatten()(last_output)

# Add a fully connected layer with 1,024 hidden units and ReLU activation

x = layers.Dense(1024, activation=’relu’)(x)

# Add a dropout rate of 0.2

x = layers.Dropout(0.2)(x)

# Add a final sigmoid layer for classification

x = layers.Dense (1, activation=’sigmoid’)(x)

model = Model( pre_trained_model.input, x)

model.compile(optimizer = RMSprop(lr=0.0001),

loss = ‘binary_crossentropy’,

metrics = [‘accuracy’])

O resto do código fica igual ao exemplo do post 3, mas caso queira da uma olhada detalhada segue o link do google colab ou do github para o projeto completo.

Espero que tenham gostado, e qualquer dúvida é só comentar que vamos aprendendo juntos.

So long and thanks for all the fish.