Path: blob/master/site/pt-br/tutorials/images/transfer_learning.ipynb
25118 views
Copyright 2019 The TensorFlow Authors.
Transferência de Aprendizado com uma ConvNet Pré-Treinada
Neste tutorial, você aprenderá a classificar imagens de cães e gatos usando a transferência de aprendizado de uma rede pré-treinada.
Um modelo pré-treinado é uma rede salva que foi treinada anteriormente em um grande dataset, geralmente em uma tarefa de classificação de imagem em larga escala. Você usa o modelo pré-treinado como está ou usa a transferência de aprendizado para personalizar esse modelo para uma determinada tarefa.
A intuição por trás da transferência de aprendizado para classificação de imagens é que, se um modelo for treinado em um dataset grande e geral o suficiente, esse modelo servirá efetivamente como um modelo genérico do mundo visual. Você pode aproveitar esses mapas de características aprendidas sem precisar começar do zero treinando um modelo grande em um grande dataset.
Neste notebook, você tentará duas maneiras de personalizar um modelo pré-treinado:
Extração de características: use as representações aprendidas por uma rede anterior para extrair características significativas de novas amostras. Você simplesmente adiciona um novo classificador, que será treinado do zero, sobre o modelo pré-treinado, para que você possa adaptar novamente os mapas de características aprendidas anteriormente para o dataset.
Você não precisa (re) treinar o modelo inteiro. A rede convolucional de base já contém características que são genericamente úteis para classificar imagens. No entanto, a parte final de classificação do modelo pré-treinado é específica para a tarefa de classificação original e subsequentemente específica para o conjunto de classes em que o modelo foi treinado.
Ajuste fino: descongele algumas das camadas superiores de uma base modelo congelada e treine em conjunto as camadas de classificação recém-adicionadas e as últimas camadas do modelo base. Isso nos permite "ajustar" as representações de características de ordem superior no modelo base para torná-las mais relevantes para a tarefa específica.
Você seguirá o fluxo de trabalho geral de aprendizado de máquina.
Examine e entenda os dados
Crie um pipeline de entrada, neste caso usando o Keras ImageDataGenerator
Componha o modelo
Carregue no modelo base pré-treinado (e pesos pré-treinados)
Empilhe as camadas de classificação na parte superior
Treine o modelo
Avalie o modelo
Pré-Processamento dos Dados
Baixe os dados
Neste tutorial, você usará um dataset contendo milhares de imagens de cães e gatos. Baixe e extraia um arquivo zip contendo as imagens e, em seguida, crie um tf.data.Dataset
para treinamento e validação usando o utilitário tf.keras.utils.image_dataset_from_directory
. Você pode aprender mais sobre como carregar imagens neste tutorial.
Mostre as duas primeiras imagens e rótulos do dataset de treinamento:
Como o dataset original não contém um dataset de testes, você criará um. Para fazer isso, determine quantos lotes de dados estão disponíveis no dataset de validação usando tf.data.experimental.cardinality
e mova 20% deles para um dataset de teste.
Configure o dataset para melhor desempenho
Use a pré-busca em buffer para carregar imagens do disco sem bloquear a E/S. Para saber mais sobre esse método, consulte o guia desempenho de dados.
Use ampliação de dados
Quando você não tem um grande dataset de imagens, é uma boa prática introduzir artificialmente a diversidade de amostras aplicando transformações aleatórias, mas realistas, às imagens de treinamento, como rotação e inversão horizontal. Isto ajuda a expor o modelo a diferentes aspectos dos dados de treinamento e a reduzir o overfitting. Você pode aprender mais sobre ampliação de dados neste tutorial.
Observação: estas camadas ficam ativas somente durante o treinamento, quando você faz uma chamada a Model.fit
. Elas ficam inativas quando o modelo é usado no modo de inferência em Model.evaluate
, Model.predict
ou Model.call
.
Vamos aplicar essas camadas repetidamente na mesma imagem e ver o resultado.
Redimensione valores de pixel
Em alguns instantes, você fará o download do tf.keras.applications.MobileNetV2
para usar como modelo básico. Este modelo espera valores de pixel em [-1, 1]
, mas neste ponto, os valores de pixel em suas imagens estão em [0, 255]
. Para redimensioná-las, use o método de pré-processamento incluído no modelo.
Observação: como alternativa, você pode redimensionar os valores de pixel de [0, 255]
para [-1, 1]
usando tf.keras.layers.Rescaling
.
Observação: Se estiver usando outro tf.keras.applications
, certifique-se de verificar o documento da API para determinar se eles esperam pixels em [-1, 1]
ou [0, 1]
, ou use a função preprocess_input
incluída.
Crie o modelo base a partir das ConvNets pré-treinadas
Você criará o modelo base a partir do modelo MobileNet V2 desenvolvido no Google. Isso é pré-treinado no dataset ImageNet, um grande dataset composto por 1,4 milhões de imagens e 1000 classes. O ImageNet é um dataset de treinamento de pesquisa com uma ampla variedade de categorias, como jaca
e seringa
. Essa base de conhecimento nos ajudará a classificar cães e gatos de nosso dataset específico.
Primeiro, você precisa escolher qual camada do MobileNet V2 usará para extração de características. A última camada de classificação (na parte superior, como a maioria dos diagramas dos modelos de aprendizado de máquina vai de baixo para cima) não é muito útil. Em vez disso, você seguirá a prática comum de depender da última camada antes da operação de nivelamento. Essa camada é chamada de "camada de gargalo". Os recursos da camada de gargalo retêm mais generalidade em comparação com a camada final/superior.
Primeiro, instancie um modelo MobileNet V2 pré-carregado com pesos treinados no ImageNet. Ao especificar o argumento include_top = False, você carrega uma rede que não inclui as camadas de classificação na parte superior, o que é ideal para a extração de características.
Este extrator de características converte cada imagem 160x160x3
em um bloco de características 5x5x1280
. Veja o que ele faz com o lote de imagens de exemplo:
Extração de Características
Nesta etapa, você congelará a base convolucional criada a partir da etapa anterior e utilizará como extrator de características. Além disso, você adiciona um classificador sobre ele e treina o classificador de nível superior.
Congele a base convolucional
É importante congelar a base convolucional antes de compilar e treinar o modelo. O congelamento (definindo layer.trainable = False) evita que os pesos de uma determinada camada sejam atualizados durante o treinamento. O MobileNet V2 tem muitas camadas, portanto, definir o sinalizador trainable
de todo o modelo como False irá congelar todas elas.
Observações importantes sobre as camadas BatchNormalization
Muitos modelos contêm camadas tf.keras.layers.BatchNormalization
. Esta camada é um caso especial e devem ser tomadas precauções no contexto do tuning, conforme mostrado mais adiante neste tutorial.
Quando você define layer.trainable = False
, a camada BatchNormalization
será executada no modo de inferência e não atualizará suas estatísticas de média e variância.
Ao descongelar um modelo que contém camadas BatchNormalization para fazer o tuning, você deve manter as camadas BatchNormalization no modo de inferência passando training = False
ao chamar o modelo base. Caso contrário, as atualizações aplicadas aos pesos não treináveis destruirão o que o modelo aprendeu.
Para mais detalhes, consulte o Guia de aprendizado por transferência.
Adicione um cabeçalho de classificação
Para gerar previsões a partir do bloco de características, calcule a média dos espaços 5x5
, usando uma camada tf.keras.layers.GlobalAveragePooling2D
para converter as características em um único vetor de 1280 elementos por imagem.
Aplique uma camada tf.keras.layers.Dense
para converter esses recursos em uma única previsão por imagem. Você não precisa de uma função de ativação aqui porque esta previsão será tratada como um logit
ou um valor bruto de previsão. Números positivos predizem a classe 1, números negativos predizem a classe 0.
Crie um modelo encadeando as camadas de ampliação de dados, redimensionamento, base_model
e extrator de recursos usando a API Keras Functional. Conforme mencionado anteriormente, use training=False
pois nosso modelo contém uma camada BatchNormalization
.
Os mais de 8 milhões de parâmetros no MobileNet estão congelados, mas existem 1,2 mil parâmetros treináveis na camada Densa. Eles são divididos entre dois objetos tf.Variable
, os pesos e os bias.
Compile o modelo
Compile o modelo antes de treiná-lo. Como existem duas classes, use a perda tf.keras.losses.BinaryCrossentropy
com from_logits=True
, pois o modelo fornece uma saída linear.
Treine o modelo
Após treinar por 10 épocas, você deverá perceber uma precisão de aproximadamente 96% no dataset de validação.
Curvas de aprendizado
Vamos dar uma olhada nas curvas de aprendizado da acurácia/perda do treinamento e da validação ao usar o modelo base do MobileNet V2 como um extrator de características fixo.
Nota: Se você está se perguntando por que as métricas de validação são claramente melhores que as métricas de treinamento, o principal fator é que camadas como tf.keras.layers.BatchNormalization
e tf.keras.layers.Dropout
afetam a acurácia durante o treinamento. Eles são desativados ao calcular a perda de validação.
Em menor grau, é também porque as métricas de treinamento relatam a média de uma época, enquanto as métricas de validação são avaliadas após a época, portanto, as métricas de validação veem um modelo que foi treinado um pouco mais.
Ajuste fino (tuning)
No experimento de extração de características, você treinava apenas algumas camadas sobre um modelo base do MobileNet V2. Os pesos da rede pré-treinada não foram atualizados durante o treinamento.
Uma maneira de aumentar ainda mais o desempenho é treinar (ou "ajustar") os pesos das camadas superiores do modelo pré-treinado, juntamente com o treinamento do classificador adicionado. O processo de treinamento forçará os pesos a serem ajustados com mapas de características genéricas para recursos associados especificamente ao dataset.
Nota: Isso só deve ser tentado depois de você treinar o classificador de nível superior com o modelo pré-treinado definido como não treinável. Se você adicionar um classificador inicializado aleatoriamente sobre um modelo pré-treinado e tentar treinar todas as camadas em conjunto, a magnitude das atualizações de gradiente será muito grande (devido aos pesos aleatórios do classificador) e seu modelo pré-treinado esquecerá o que aprendeu.
Além disso, você deve tentar ajustar um pequeno número de camadas superiores em vez de todo o modelo MobileNet. Na maioria das redes convolucionais, quanto mais alta a camada, mais especializada ela é. As primeiras camadas aprendem recursos muito simples e genéricos que generalizam para quase todos os tipos de imagens. À medida que você aumenta, as características são cada vez mais específicas para o dataset no qual o modelo foi treinado. O objetivo do ajuste fino é adaptar essas características especializados para trabalhar com o novo dataset, em vez de substituir o aprendizado genérico.
Descongele as camadas superiores do modelo
Tudo o que você precisa fazer é descongelar o base_model
e definir as camadas inferiores para que não possam ser treinadas. Em seguida, recompile o modelo (necessário para que essas alterações entrem em vigor) e reinicie o treinamento.
Compile o modelo
Compile o modelo usando uma taxa de aprendizado muito menor.
Continue treinando o modelo
Se você treinou para convergência anteriormente, esta etapa melhorará sua acurácia em alguns pontos percentuais.
Vamos dar uma olhada nas curvas de aprendizado da acurácia/perda do treinamento e da validação ao ajustar as últimas camadas do modelo base do MobileNet V2 e treinar o classificador sobre ele. A perda de validação é muito maior do que a perda de treinamento, portanto, você pode obter um overfitting.
Você também pode obter um overfitting, pois o novo dataset de treinamento é relativamente pequeno e semelhante aos datasets originais do MobileNet V2.
Após o ajuste fino, o modelo atinge quase 98% de acurácia.
Avaliação e previsão
Finalmente, você pode verificar o desempenho do modelo em novos dados usando o dataset de testes.
E agora você está pronto para usar este modelo para prever se seu animal de estimação é um gato ou um cachorro.
Resumo:
Usando um modelo pré-treinado para extração de características: Ao trabalhar com um pequeno dataset, é uma prática comum tirar proveito das características aprendidas por um modelo treinado em um dataset maior no mesmo domínio. Isso é feito instanciando o modelo pré-treinado e adicionando um classificador totalmente conectado na parte superior. O modelo pré-treinado é "congelado" e apenas os pesos do classificador são atualizados durante o treinamento. Nesse caso, a base convolucional extraiu todas as características associadas a cada imagem e você acabou de treinar um classificador que determina a classe da imagem, considerando esse conjunto de características extraídas.
Ajuste fino de um modelo pré-treinado: Para melhorar ainda mais o desempenho, é possível redirecionar as camadas de nível superior dos modelos pré-treinados para o novo dataset via ajuste fino. Nesse caso, você ajustou seus pesos para que seu modelo aprendesse características de alto nível específicas ao dataset. Essa técnica geralmente é recomendada quando o dataset de treinamento é grande e muito semelhante ao dataset original em que o modelo pré-treinado foi treinado.
Para saber mais, veja o Guia de aprendizado por transferência.