Transfer Learning – Kaggle, CNN e Cachorros

Source: Deep Learning on Medium


Treinar redes neurais pode ser cansativo ao ponto de você ter que esperar muitas horas e no final talvez não obter uma acurácia desejada. Entretanto, imagine a ideia de você transferir conhecimento para seu algoritmo, esse “conhecimento que foi transferido” já possui habilidades e entendimento do problema. Pense nisso como coisas que aprendemos no nosso dia a dia. Talvez algo que você aprendeu hoje, pode ajudar você em outro problema e essa compreensão pode auxiliar na busca de outros conhecimentos.

Por exemplo, primeiro você aprende a andar de bicicleta e depois aprende a andar de moto. Nesse caso, você aplicou os conhecimentos de andar de bicicleta para andar de moto.

Transfer Learning(TL) segue a mesma ideia. Essa técnica de aprendizagem para algoritmos de Deep Learning, permite o aproveitamento de uma rede neural já treinada para uma tarefa específica.

Um dos campos que vemos a utilização dessa técnica com frequência é no reconhecimento de imagem. Digamos que você queira identificar cachorros, mas não há algoritmos disponíveis que faça um trabalho adequado. Com TF, você aplica uma rede neural convolucional já existente(obtida por meio de TF) que foi treinada em imagens de cachorro e aplica no seu código.

Nesse artigo vamos aplicar o método de TF em uma competição do Kaggle que envolve a classificação de cachorros de acordo com sua raça.

1. Introdução

TF é uma técnica de aprendizado de máquina em que um modelo treinado em uma tarefa específica é redirecionado para uma segunda tarefa relacionada.

Vemos com muita frequência a aplicação em Deep Learning. Treinar redes neurais geralmente exigem muitos dados e recursos computacionais. Então, por que não pegar os pesos de redes neurais já treinadas e aplicar em seus dados?

1.1. Desenvolvimento do modelo

TF pode ser aplicado da seguinte forma:

  1. Um modelo pré-treinado é escolhido. Muitas instituições de pesquisas lançam modelos sobre conjuntos de dados grandes para treinamento e obtenção dos pesos.
  2. O modelo deve se adaptar as entradas na qual você vai alimentar. Imagine que o modelo está propício a receber uma determinada entrada e acaba recebendo algo totalmente diferente, nesse caso, não será obtida performance alguma.

1.2. Quando usar Transfer Learning

TF é uma otimização, um atalho para economizar tempo e obter um melhor resultado.

Em alguns casos talvez isso não traga benefícios, nessa situação é melhor você construir seu próprio modelo, testar nos dados e comparar com o uso de TF.

Em geral, não é certeza que haverá um benefício na utilização, em um caso em que o modelo já tenha sido desenvolvido e avaliado.

1.3. Porque usar Transfer Learning

Quando treinamos uma rede neural convolucional em um conjunto de dados de imagens, durante o processo de treinamento, as imagens são passadas pela rede aplicando processos convolucionais e filtros nas imagens. Os valores das matrizes dos filtros são multiplicados com as ativações da imagem em cada camada. As ativações que saem da camada final são usadas para descobrir qual classe a imagem pertence.

A razão pela qual TF funciona tão bem, é que usamos uma rede que é pré-treinada no conjunto de dados imagenet e essa rede já aprendeu a reconhecer as principais características nas imagens. Usando uma rede pré-treinada para fazer TF, nos apenas devemos nos atentar em adicionar algumas camadas densas no final da rede(já pré-treinada) e treinar essa o topo da rede com o número certo de classes que você precisa classificar.

1.3. Arquiteturas

Durante os anos, algumas variações de arquiteturas de redes neurais convolucionais foram surgindo. Isso pode ser percebido acompanhado a competição ILSVRC. Nessa competição, em seis anos, a taxa de erro foi de 26% para apenas 3%.

Aqui estão algumas das arquiteturas de redes convolucionais que ganharam a competição e que são as mais utilizadas atualmente:

2. Competição

Vamos aplicar os conceitos vistos acima em um caso real. Portanto, nada melhor que ir no Kaggle e participar de uma competição. Se você não conhece o Kaggle, escrevi um artigo apresentando a plataforma:

A competição que iremos participar será a Dog Breed Identification. Trata-se de uma competição em que nossa meta é classificar os cachorros de acordo com a raça apropriada.

Vamos fazer nossa implementação usando o Keras, já que essa biblioteca possui diversos modelos de redes neurais convolucionais já treinadas.

2.1. Implementação

Será seguido a seguinte ordem de implementação e resolução da competição:

  1. Pré-processar as imagens;
  2. Definir treino e teste;
  3. Transfer Learning;
  4. Treinamento da rede;

Como o foco do artigo está em apresentar TF, não será abordado os passos 1 e 2. Para isso, você pode conferir o código completo aqui.

3. Código

3.1. Aplicar Transfer Learning

Keras possui módulos que nos ajudam a aplicar TF de uma maneira muito fácil.

Nessa competição, iremos utilizar o modelo VGG19 que foi treinado em mais de um milhão de imagens no dataset imagenet, mas sinta-se livre para usar qualquer outro.

Esses são os modelos disponíveis para implementação no Keras.

Precisamos importar o modelo VGG19. O VGG19 (treinado para mil classes) terá uma última camada composta por 1000 neurônios. Não queremos tantos neurônios na camada de saída. Portanto, ao invés de 1000 saídas, reduzimos esse número para 120, já que esse é o número de raças para classificar. Isso pode ser feito definindo (IncludeTop = False) ao importar o modelo.

base_model = VGG19(weights='imagenet', include_top=False, input_shape=(150, 150, 3))
# Adicionando um novo topo na rede
x = base_model.output
x = layers.Flatten()(x)
predictions = layers.Dense(120, activation='softmax')(x)
# Ajustar o modelo para a nossa arquitetura
model = models.Model(inputs=base_model.input, outputs=predictions)

Agora que nosso modelo foi definido, como estamos usando os pesos pré-treinados, durante a execução do treinamento, precisamos especificar que os pesos não sejam treinados novamente. Será necessário apenas treinar as últimas camadas que adicionamos anteriormente.

for layer in base_model.layers:
layer.trainable = False

Chegamos na parte do treinamento da rede. Tudo que precisamos fazer é compilar e treinar o modelo. Isso pode ser feito usando o código abaixo.

model.compile(loss='categorical_crossentropy', 
optimizer='adam',
metrics=['accuracy'])
callbacks_list = [keras.callbacks.EarlyStopping(monitor='val_acc', patience=3, verbose=1)]
model.summary()
model.fit(X_train, y_train, epochs=1, validation_data=(X_test, y_test), verbose=1)

Depois de executar o código acima, obtemos a seguinte saída.

Após isso, para realizar as predições, execute.

preds = model.predict(x_test, verbose=1)

O prazo de envio das predições para essa competição já acabou, entretanto ainda é possível medir como foi a performance do seu modelo. Só temos que clicar em Late Submission e enviar os resultados.

Com esse modelo, obtive o valor de 3.85105 na competição. Considero essa valor alto e precisa ser melhorado. Perceba que durante o treinamento, defini apenas uma época, isso pode explicar porque a acurácia ficou baixa e a função de custo ficou alta. Como disse acima, teste outros modelos e parâmetros, esse exemplo é apenas um guia.

4. Conclusão

“Hoje ensinamos homens, amanhã ensinaremos máquinas!”

Tentei tornar esse post rápido e fácil para você conseguir aplicar modelos treinados em seus dados.

Ficou alguma dúvida ou sugestão? Deixe aqui nos comentários :)

Até a próxima!

5. Referências

Deep Learning — Ian Goodfellow and Yoshua Bengio and Aaron Courville

Hands-On Machine Learning with Scikit-Learn & TensorFlow — Aurélien Géron