Seu primeiro modelo do Keras com aprendizado por transferência

1. Visão geral

Neste laboratório, você vai aprender a criar um classificador Keras. Em vez de tentar descobrir a combinação perfeita de camadas de rede neural para reconhecer flores, primeiro usaremos uma técnica chamada aprendizado por transferência para adaptar um poderoso modelo pré-treinado 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 na TPU". Elas podem ser feitas na ordem abaixo ou de forma independente.

ca8cc21f6838eccc.png

O que você vai aprender

  • 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 pela página de problemas do GitHub [link do feedback].

2. Introdução ao Google Colaboratory

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

688858c21e3beff2.png

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

c3df49e90e5a654f.png Welcome to Colab.ipynb

Selecionar 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 selecione TPU. Neste codelab, você usará uma TPU (Unidade de Processamento de Tensor) poderosa 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 de notebooks

76d05caa8b4db6da.png

Execute as células uma por vez clicando em uma célula e usando Shift + ENTER. Também é possível executar todo o notebook em Ambiente de execução > Executar tudo.

Índice

429f106990037ec4.png

Todos os notebooks têm um sumário. Você pode abrir usando a seta preta à esquerda.

Células ocultas

edc3dba45d26f12a.png

Algumas células só mostram o título. Este é um recurso de notebook específico para o Colab. É possível clicar duas vezes neles para ver o código deles, mas normalmente não é muito interessante. Normalmente, são funções de suporte ou visualização. Você ainda precisa executar essas células para que as funções internas sejam definidas.

Authentication

cdd4b41413100543.png

O Colab pode acessar seus buckets particulares do Google Cloud Storage se você fizer a autenticação com uma conta autorizada. O snippet de código acima aciona um processo de autenticação.

3. [INFORMAÇÃO] Introdução ao classificador de rede neural

Resumindo

Se você já conhece todos os termos em negrito no próximo parágrafo, avance 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 que usa três camadas densas pode ser escrito em Keras como:

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. Ela é feita de "neurônios" dispostos em camadas. A primeira camada processa os dados de entrada e alimenta as saídas em outras camadas. É chamado de "denso" porque cada neurônio está conectado a todos os neurônios da camada anterior.

c21bae6dade487bc.png

É possível alimentar uma imagem nessa rede, achatando os valores RGB de todos os pixels em um vetor longo e usando-o como entradas. Essa não é a melhor técnica de reconhecimento de imagens, mas vamos melhorá-la mais tarde.

Neurônios, ativações, RELU

Um "neurônio" calcula uma soma ponderada de todas as entradas, adiciona um valor chamado "viés" e alimenta o resultado por meio de uma "função de ativação". Os pesos e o viés são desconhecidos no início. Elas serão inicializadas aleatoriamente e "aprendedas" treinando a rede neural com muitos dados conhecidos.

644f4213a4ee70e5.png

A função de ativação mais conhecida é chamada RELU, que significa "Unidade linear retificada". É uma função muito simples, como você pode ver no gráfico acima.

Ativação Softmax

A rede acima termina com uma camada de 5 neurônios porque estamos classificando as flores em cinco categorias (rosa, tulipa, dente-de-leão, margarida, girassol). Os neurônios em 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 essa flor ser uma rosa, uma tulipa e assim por diante. Para isso, vamos usar uma função de ativação chamada "softmax".

A aplicação de softmax em um vetor é feita tomando a exponencial de cada elemento e, em seguida, normalizando o vetor, normalmente usando a norma L1 (soma de valores absolutos) para que os valores somem até 1 e possam ser interpretados como probabilidades.

ef0d98c0952c262d.png d51252f75894479e.gif

Perda de entropia cruzada

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

Qualquer distância funciona, 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, na verdade, usar imagens e rótulos de treinamento para ajustar pesos e vieses, a fim de 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 a classe conhecida dela.

Se calcularmos as derivadas parciais da entropia cruzada em relação a todos os pesos e vieses, vamos conseguir 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 trabalho. 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 as tendências por uma fração do gradiente. Em seguida, fazemos a mesma coisa várias vezes usando os próximos lotes de imagens e rótulos de treinamento, em um loop de treinamento. Com sorte, isso converge para um lugar em que a entropia cruzada é mínima, embora nada garanta que esse mínimo seja único.

gradiente descendente

Minilote e momentum

Você pode calcular seu gradiente em apenas uma imagem de exemplo e atualizar os pesos e 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, é provável que converja para a solução mais rapidamente. O tamanho do minilote é um parâmetro ajustável.

Essa técnica, às vezes chamada de "descida estocástica do gradiente", 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 pode ser um pouco caótica e até parar se o vetor do 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. Em um vetor de gradiente com milhões de elementos, se todos eles forem zeros, a probabilidade de que cada zero corresponda a um mínimo e nenhum deles a um ponto máximo será muito pequena. Em um espaço de muitas dimensões, os pontos de sela são muito comuns e não queremos parar neles.

52e824fe4716c4a0.png

Ilustração: um ponto de sela. O gradiente é 0, mas não é o mínimo em todas as direções. (Atribuição de 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

batch ou mini-lote: o treinamento é sempre executado em lotes de dados de treinamento e rótulos. Isso ajuda o algoritmo a convergir. A dimensão "batch" é geralmente a primeira dimensão dos tensores de dados. Por exemplo, um tensor de forma [100, 192, 192, 3] contém 100 imagens de 192x192 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 um 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) devem ser alimentadas 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 em que os pesos e vieses são atualizados em cada iteração do ciclo de treinamento.

Logits: as saídas de uma camada de neurônios antes que a função de ativação seja aplicada 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 popular. "Neuron outputs before logistic function" foi abreviado para "logits".

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

neuron: calcula a soma ponderada das entradas, adiciona uma polarização e alimenta o resultado por meio de uma função de ativação.

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

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

Sigmóide: outra função de ativação que costumava ser 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 componente maior 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 em classificadores.

tensor: um "tensor" é como uma matriz, mas com um número arbitrário de dimensões. Um tensor unidimensional é um vetor. Um tensor de duas dimensões é uma matriz. E você pode ter tensors 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 as camadas convolucionais e as muitas maneiras de organizá-las.

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

Atividade prática

Abra o notebook a seguir, execute as células (Shift-ENTER) e siga as instruções sempre que encontrar o rótulo "WORK REQUIRED".

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

Informações adicionais

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

b8fc1efd2001f072.png

Ilustração: usar uma rede neural convolucional complexa já treinada como uma caixa preta, retreinando apenas a cabeça de classificação. Isso é aprendizado por transferência. Vamos ver como esses arranjos complicados de camadas convolucionais funcionam mais tarde. Por enquanto, o 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 com um tamanho razoável. Ao selecionar include_top=False, você recebe o modelo pré-treinado sem a camada softmax final para que possa adicionar o seu:

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 vieses do modelo pré-treinado para que você treine somente a camada de softmax. Isso normalmente envolve relativamente poucos pesos e pode ser feito rapidamente e sem a necessidade de um conjunto de dados muito grande. No entanto, se você tiver muitos dados, o aprendizado de transferência pode 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 problema.

Por fim, observe a camada Flatten() inserida antes da camada softmax densa. As camadas densas funcionam em vetores planos de dados, mas não sabemos se é isso que o modelo pré-treinado retorna. É por isso que precisamos separar. No próximo capítulo, à medida que nos aprofundamos nas arquiteturas convolucionais, vamos explicar o formato de dados retornado pelas camadas convolucionais.

Você deve chegar a uma precisão de 75% com essa abordagem.

Solução

Este é o notebook da solução. Você pode usá-la se tiver dificuldades.

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

O que vimos

  • 🤔 Como criar um classificador no Keras
  • 🤓 configurado com uma última camada softmax e perda de entropia cruzada
  • 😝 Aprendizado por transferência
  • 🤔 Como treinar seu primeiro modelo
  • 🧐 Após a perda e a acurácia durante o treinamento

Leia esta lista de verificação.

5. Parabéns!

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

TPUs na prática

TPUs e GPUs estão disponíveis na AI Platform do Cloud:

Por fim, adoramos receber feedback. Informe se você encontrar algo errado neste laboratório ou se achar que ele precisa ser melhorado. O feedback pode ser enviado pela página de problemas do GitHub [link do feedback].

HR.png

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

Logotipo do TensorFlow.jpg
www.tensorflow.org