Seu primeiro modelo do Keras com aprendizado por transferência

1. Visão geral

Neste laboratório, você vai aprender a criar um classificador do Keras. Em vez de tentar descobrir a combinação perfeita de camadas de rede neural para reconhecer flores, primeiro vamos usar uma técnica chamada aprendizado por transferência para adaptar um modelo pré-treinado avançado ao nosso conjunto de dados.

Este laboratório inclui as explicações teóricas necessárias sobre redes neurais e é um bom ponto de partida para desenvolvedores que estão aprendendo sobre aprendizado profundo.

Este laboratório é a Parte 2 da série "Keras no TPU". Você pode fazer isso na ordem a seguir ou de forma independente.

ca8cc21f6838eccc.png

O que você vai aprender

  • Para criar seu próprio classificador de imagens do Keras com uma camada softmax e perda de entropia cruzada
  • Para trapacear 😈, use o aprendizado por transferência em vez de criar seus próprios modelos.

Feedback

Se você notar algo errado neste codelab, informe-nos. O feedback pode ser enviado usando os problemas do GitHub [ link de feedback].

2. Início rápido do Google Colaboratory

Este laboratório usa o Google Colaboratory e não exige configuração da sua parte. O Colaboratory é uma plataforma de notebook on-line para fins educacionais. Ele oferece treinamento sem custo financeiro de CPU, GPU e TPU.

688858c21e3beff2.png

Abra este notebook de exemplo e execute algumas células para se familiarizar com o Colaboratory.

c3df49e90e5a654f.png Welcome to Colab.ipynb

Selecione um back-end de TPU.

8832c6208c99687d.png

No menu do Colab, selecione Ambiente de execução > Alterar o tipo de ambiente de execução e escolha TPU. Neste codelab, você vai usar uma TPU (Unidade de Processamento de Tensor) avançada com suporte para treinamento acelerado por hardware. A conexão com o ambiente de execução acontece automaticamente na primeira execução, ou você pode usar o botão "Conectar" no canto superior direito.

Execução do notebook

76d05caa8b4db6da.png

Execute as células uma de cada vez clicando em uma delas e usando Shift + ENTER. Você também pode executar o notebook inteiro com Ambiente de execução > Executar tudo.

Índice

429f106990037ec4.png

Todos os notebooks têm um sumário. É possível abrir usando a seta preta à esquerda.

Células ocultas

edc3dba45d26f12a.png

Algumas células vão mostrar apenas o título. Esse é um recurso específico do notebook do Colab. Clique duas vezes neles para ver o código, mas geralmente não é muito interessante. Normalmente, funções de suporte ou visualização. Ainda é necessário executar essas células para que as funções sejam definidas.

Authentication

cdd4b41413100543.png

O Colab pode acessar seus buckets privados do Google Cloud Storage, desde que você faça a autenticação com uma conta autorizada. O snippet de código acima vai acionar um processo de autenticação.

3. [INFO] Classificador de rede neural 101

Em poucas palavras

Se você já conhece todos os termos em negrito no próximo parágrafo, passe para o próximo exercício. Se você está começando no aprendizado profundo, seja bem-vindo e continue lendo.

Para modelos criados como uma sequência de camadas, o Keras oferece a API Sequential. Por exemplo, um classificador de imagens usando três camadas densas pode ser escrito em Keras da seguinte maneira:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png

Rede neural densa

Essa é a rede neural mais simples para classificar imagens. Ele é feito de "neurônios" organizados em camadas. A primeira camada processa os dados de entrada e alimenta as saídas em outras camadas. Ela é chamada de "densa" porque cada neurônio está conectado a todos os neurônios da camada anterior.

c21bae6dade487bc.png

É possível inserir uma imagem em uma rede desse tipo ao achatar os valores RGB de todos os pixels em um vetor longo e usá-lo como entrada. Não é a melhor técnica para reconhecimento de imagens, mas vamos melhorar isso depois.

Neurônios, ativações, RELU

Um "neurônio" calcula uma soma ponderada de todas as entradas, adiciona um valor chamado "tendência" e transmite o resultado por uma "função de ativação". Os pesos e o viés são desconhecidos no início. Eles são inicializados aleatoriamente e "aprendidos" com o treinamento da rede neural em muitos dados conhecidos.

644f4213a4ee70e5.png

A função de ativação mais popular é chamada de RELU, de Unidade Linear Retificada. É uma função muito simples, como você pode ver no gráfico acima.

Ativação do Softmax

A rede acima termina com uma camada de cinco neurônios porque estamos classificando flores em cinco categorias (rosa, tulipa, dente-de-leão, margarida e girassol). Os neurônios nas camadas intermediárias são ativados usando a função de ativação RELU clássica. Na última camada, queremos calcular números entre 0 e 1 que representam a probabilidade de a flor ser uma rosa, uma tulipa e assim por diante. Para isso, vamos usar uma função de ativação chamada "softmax".

Para aplicar o softmax em um vetor, pegue o exponencial de cada elemento e normalize o vetor, geralmente usando a norma L1 (soma dos valores absolutos) para que os valores somem 1 e possam ser interpretados como probabilidades.

ef0d98c0952c262d.png d51252f75894479e.gif

Perda de entropia cruzada

Agora que nossa rede neural gera previsões com base em imagens de entrada, precisamos medir a qualidade delas, ou seja, a distância entre o que a rede nos diz e as respostas corretas, geralmente chamadas de "rótulos". Lembre-se de que temos rótulos corretos para todas as imagens no conjunto de dados.

Qualquer distância funcionaria, mas para problemas de classificação, a chamada "distância de entropia cruzada" é a mais eficaz. Vamos chamar isso de função de erro ou "perda":

7bdf8753d20617fb.png

Gradiente descendente

"Treinar" a rede neural significa usar imagens e rótulos de treinamento para ajustar pesos e vieses e minimizar a função de perda de entropia cruzada. Confira como funciona.

A entropia cruzada é uma função de pesos, vieses, pixels da imagem de treinamento e da classe conhecida.

Se calcularmos as derivadas parciais da entropia cruzada em relação a todos os pesos e vieses, vamos obter um "gradiente", calculado para uma determinada imagem, rótulo e valor atual de pesos e vieses. Lembre-se de que podemos ter milhões de pesos e vieses, então calcular o gradiente parece muito trabalhoso. Felizmente, o TensorFlow faz isso por nós. A propriedade matemática de um gradiente é que ele aponta para cima. Como queremos ir para onde a entropia cruzada é baixa, vamos na direção oposta. Atualizamos os pesos e os vieses por uma fração do gradiente. Em seguida, fazemos a mesma coisa repetidamente usando os próximos lotes de imagens e rótulos de treinamento, em um loop de treinamento. Esperamos que isso convirja para um lugar em que a entropia cruzada seja mínima, embora nada garanta que esse mínimo seja único.

gradient descent2.png

Minilote e momentum

Você pode calcular o gradiente em apenas uma imagem de exemplo e atualizar os pesos e os vieses imediatamente, mas fazer isso em um lote de, por exemplo, 128 imagens, gera um gradiente que representa melhor as restrições impostas por diferentes imagens de exemplo e, portanto, provavelmente converge para a solução mais rapidamente. O tamanho do minilote é um parâmetro ajustável.

Essa técnica, às vezes chamada de "gradiente descendente estocástico", tem outro benefício mais pragmático: trabalhar com lotes também significa trabalhar com matrizes maiores, que geralmente são mais fáceis de otimizar em GPUs e TPUs.

No entanto, a convergência ainda pode ser um pouco caótica e até parar se o vetor de gradiente for todo zero. Isso significa que encontramos um mínimo? Nem sempre. Um componente de gradiente pode ser zero em um mínimo ou um máximo. Com um vetor de gradiente com milhões de elementos, se todos forem zeros, a probabilidade de que cada zero corresponda a um mínimo e nenhum deles a um ponto máximo é muito pequena. Em um espaço de muitas dimensões, os pontos de sela são bastante comuns, e não queremos parar neles.

52e824fe4716c4a0.png

Ilustração: um ponto de sela. O gradiente é 0, mas não é um mínimo em todas as direções. (Atribuição da imagem: Wikimedia: Por Nicoguaro - Trabalho próprio, CC BY 3.0)

A solução é adicionar um pouco de impulso ao algoritmo de otimização para que ele possa passar pelos pontos de sela sem parar.

Glossário

Lote ou minilote: o treinamento é sempre realizado em lotes de dados e rótulos de treinamento. Isso ajuda o algoritmo a convergir. A dimensão "lote" geralmente é a primeira dimensão dos tensores de dados. Por exemplo, um tensor de forma [100, 192, 192, 3] contém 100 imagens de 192 x 192 pixels com três valores por pixel (RGB).

Perda de entropia cruzada: uma função de perda especial usada com frequência em classificadores.

Camada densa: uma camada de neurônios em que cada neurônio está conectado a todos os neurônios da camada anterior.

Atributos: as entradas de uma rede neural às vezes são chamadas de "atributos". A arte de descobrir quais partes de um conjunto de dados (ou combinações de partes) alimentar em uma rede neural para receber boas previsões é chamada de "engenharia de atributos".

rótulos: outro nome para "classes" ou respostas corretas em um problema de classificação supervisionada

Taxa de aprendizado: fração do gradiente pela qual os pesos e os vieses são atualizados em cada iteração do loop de treinamento.

Logits: as saídas de uma camada de neurônios antes da aplicação da função de ativação são chamadas de "logits". O termo vem da "função logística", também conhecida como "função sigmoide", que costumava ser a função de ativação mais usada. "Saídas de neurônios antes da função logística" foi abreviado para "logits".

Perda: a função de erro que compara as saídas da rede neural com as respostas corretas.

Neurônio: calcula a soma ponderada das entradas, adiciona um viés e transmite o resultado por uma função de ativação.

Codificação one-hot: a classe 3 de 5 é codificada como um vetor de 5 elementos, todos zeros, exceto o terceiro, que é 1.

relu: unidade linear retificada. Uma função de ativação comum para neurônios.

sigmoid: outra função de ativação que era popular e ainda é útil em casos especiais.

softmax: uma função de ativação especial que atua em um vetor, aumenta a diferença entre o maior componente e todos os outros e também normaliza o vetor para ter uma soma de 1, para que possa ser interpretado como um vetor de probabilidades. Usado como a última etapa nos classificadores.

tensor: um "tensor" é como uma matriz, mas com um número arbitrário de dimensões. Um tensor unidimensional é um vetor. Um tensor bidimensional é uma matriz. E você pode ter tensores com 3, 4, 5 ou mais dimensões.

4. Aprendizado por transferência

Para um problema de classificação de imagens, as camadas densas provavelmente não serão suficientes. Precisamos aprender sobre camadas convolucionais e as várias maneiras de organizá-las.

Mas também podemos pegar um atalho! Há redes neurais convolucionais totalmente treinadas disponíveis para download. É possível remover a última camada, o cabeçalho de classificação softmax, e substituir por uma opção própria. Todos os pesos e vieses treinados permanecem como estão. Você só treina novamente a camada softmax adicionada. Essa técnica é chamada de aprendizado por transferência e funciona desde que o conjunto de dados em que a rede neural é pré-treinada seja "próximo o suficiente" do seu.

Prático

Abra o notebook a seguir, execute as células (Shift-ENTER) e siga as instruções sempre que vir o rótulo "TRABALHO NECESSÁRIO".

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

Informações adicionais

Com o aprendizado por transferência, você se beneficia das arquiteturas avançadas de redes neurais convolucionais desenvolvidas pelos melhores pesquisadores e do pré-treinamento em um enorme conjunto de dados de imagens. No nosso caso, vamos usar o aprendizado por transferência de uma rede treinada no ImageNet, um banco de dados de imagens com muitas plantas e cenas externas, que é bem parecido com flores.

b8fc1efd2001f072.png

Ilustração: usando uma rede neural convolucional complexa, já treinada, como uma caixa preta, retreinando apenas o cabeçalho de classificação. Isso é o aprendizado por transferência. Vamos ver como esses arranjos complicados de camadas convolucionais funcionam mais tarde. Por enquanto, é problema de outra pessoa.

Aprendizado por transferência no Keras

No Keras, é possível instanciar um modelo pré-treinado da coleção tf.keras.applications.*. A MobileNet V2, por exemplo, é uma arquitetura convolucional muito boa que permanece razoável em tamanho. Ao selecionar include_top=False, você recebe o modelo pré-treinado sem a camada softmax final para que possa adicionar a sua:

pretrained_model = tf.keras.applications.MobileNetV2(input_shape=[*IMAGE_SIZE, 3], include_top=False)
pretrained_model.trainable = False

model = tf.keras.Sequential([
    pretrained_model,
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(5, activation='softmax')
])

Observe também a configuração pretrained_model.trainable = False. Ele congela os pesos e os vieses do modelo pré-treinado para que você treine apenas a camada softmax. Isso geralmente envolve relativamente poucos pesos e pode ser feito rapidamente sem a necessidade de um conjunto de dados muito grande. No entanto, se você tiver muitos dados, o aprendizado por transferência poderá funcionar ainda melhor com pretrained_model.trainable = True. Os pesos pré-treinados fornecem excelentes valores iniciais e ainda podem ser ajustados pelo treinamento para se adequar melhor ao seu problema.

Por fim, observe a camada Flatten() inserida antes da camada softmax densa. As camadas densas funcionam em vetores de dados simples, mas não sabemos se é isso que o modelo pré-treinado retorna. Por isso, precisamos achatar. No próximo capítulo, ao analisarmos as arquiteturas convolucionais, vamos explicar o formato de dados retornado pelas camadas convolucionais.

Com essa abordagem, você deve chegar perto de 75% de acurácia.

Solução

Confira o notebook de solução. Use se tiver dificuldades.

c3df49e90e5a654f.png Keras Flowers transfer learning (solution).ipynb

O que vimos

  • 🤔 Como escrever um classificador no Keras
  • 🤓 configurado com uma última camada softmax e perda de entropia cruzada
  • 😈 Aprendizado por transferência
  • 🤔 Treinar seu primeiro modelo
  • 🧐 Acompanhar a perda e a acurácia durante o treinamento

Confira esta lista de verificação.

5. Parabéns!

Agora você pode criar um modelo do Keras. Continue para o próximo laboratório e saiba como montar camadas convolucionais.

TPUs na prática

As TPUs e GPUs estão disponíveis no AI Platform do Google Cloud:

Por fim, adoramos receber feedback. Informe se você notar algo errado neste laboratório ou se achar que ele pode ser melhorado. O feedback pode ser enviado usando os problemas do GitHub [ link de feedback].

HR.png

Martin Görner ID small.jpg
O autor: Martin Görner
Twitter: @martin_gorner

tensorflow logo.jpg
www.tensorflow.org