Neste tutorial, você aprenderá como classificar imagens de cães e gatos usando a aprendizagem por transferência de uma rede pré-treinada.
Um modelo pré-treinado é uma rede salva que foi previamente treinada em um grande conjunto de dados, normalmente em uma tarefa de classificação de imagem em grande escala. Você pode usar o modelo pré-treinado no estado em que se encontra ou usar a aprendizagem por transferência para personalizar esse modelo para uma determinada tarefa.
A intuição por trás do aprendizado de transferência para classificação de imagens é que se um modelo for treinado em um conjunto de dados grande e geral o suficiente, esse modelo servirá efetivamente como um modelo genérico do mundo visual. Você pode aproveitar as vantagens desses mapas de recursos aprendidos sem ter que começar do zero, treinando um grande modelo em um grande conjunto de dados.
Neste notebook, você experimentará duas maneiras de personalizar um modelo pré-treinado:
Extração de recursos: use as representações aprendidas por uma rede anterior para extrair recursos significativos de novos exemplos. Você simplesmente adiciona um novo classificador, que será treinado do zero, em cima do modelo pré-treinado para que possa redirecionar os mapas de recursos aprendidos anteriormente para o conjunto de dados.
Você não precisa (re) treinar todo o modelo. A rede convolucional de base já contém recursos que são genericamente úteis para classificar imagens. No entanto, a parte final da classificação do modelo pré-treinado é específica para a tarefa de classificação original e, subsequentemente, específica para o conjunto de classes nas quais o modelo foi treinado.
Ajuste fino: descongele algumas das camadas superiores de uma base de modelo congelada e, em conjunto, treine as camadas classificadoras recém-adicionadas e as últimas camadas do modelo base. Isso nos permite "ajustar" as representações de recursos de ordem superior no modelo básico para torná-los mais relevantes para a tarefa específica.
Você seguirá o fluxo de trabalho geral do aprendizado de máquina.
Examine e compreenda os dados
Carregar no modelo básico pré-treinado (e pesos pré-treinados)
Neste tutorial, você usará um conjunto de dados contendo vários milhares de imagens de cães e gatos. Faça o download e extrair um arquivo zip que contém as imagens, em seguida, criar um tf.data.Dataset para treinamento e validação usando o tf.keras.utils.image_dataset_from_directory utilidade. Você pode aprender mais sobre como carregar imagens neste tutorial .
Como o conjunto de dados original não contém um conjunto de teste, você criará um. Para fazê-lo, determinar quantos lotes de dados estão disponíveis no conjunto de validação usando tf.data.experimental.cardinality , em seguida, passar de 20% deles a um conjunto de teste.
Use a pré-busca em buffer para carregar imagens do disco sem que o I / O se torne um bloqueio. Para saber mais sobre este método ver o desempenho de dados guia.
Use o aumento de dados
Quando você não tem um grande conjunto de dados de imagens, é uma boa prática introduzir artificialmente a diversidade da amostra, aplicando transformações aleatórias, mas realistas, às imagens de treinamento, como rotação e inversão horizontal. Isso ajuda a expor o modelo para diferentes aspectos dos dados de treinamento e reduzir overfitting . Você pode aprender mais sobre o aumento de dados neste tutorial .
Nota: Estas camadas são ativos apenas durante o treinamento, quando você chamar Model.fit . Eles estão inativos quando o modelo é usado no modo de inferência em Model.evaluate ou Model.fit .
Vamos aplicar repetidamente essas camadas à mesma imagem e ver o resultado.
Em um momento, você vai baixar tf.keras.applications.MobileNetV2 para uso como seu modelo de base. Este modelo prevê valores de pixel em [-1, 1] , mas neste momento, os valores de pixel em suas imagens estão em [0, 255] . Para redimensioná-los, use o método de pré-processamento incluído no modelo.
Nota: Em alternativa, pode redimensionar os valores de pixel a partir de [0, 255] a [-1, 1] utilizando tf.keras.layers.Rescaling .
Nota: Se estiver usando outros tf.keras.applications , certifique-se de verificar o doc API para determinar se eles esperam pixels em [-1, 1] ou [0, 1] , ou usar o incluiu preprocess_input função.
Crie o modelo básico a partir dos convnets pré-treinados
Você vai criar o modelo básico do modelo MobileNet V2 desenvolvido pelo Google. Isso é pré-treinado no conjunto de dados ImageNet, um grande conjunto de dados que consiste em 1,4 milhões de imagens e 1000 classes. IMAGEnet é um conjunto de dados de treinamento pesquisa com uma ampla variedade de categorias como jackfruit e syringe . Essa base de conhecimento nos ajudará a classificar cães e gatos de nosso conjunto de dados específico.
Primeiro, você precisa escolher qual camada do MobileNet V2 usará para extração de recursos. A última camada de classificação (no "topo", já que a maioria dos diagramas de 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. Especificando o include_top = argumento falso, você carrega uma rede que não inclui as camadas de classificação no topo, que é ideal para a extração de características.
Esse extractor recurso converte cada 160x160x3 imagem em um 5x5x1280 bloco de recursos. Vamos ver o que isso faz com um exemplo de lote de imagens:
Nesta etapa, você congelará a base convolucional criada na etapa anterior e para usar como um extrator de recurso. Além disso, você adiciona um classificador em cima dele e treina o classificador de nível superior.
É importante congelar a base convolucional antes de compilar e treinar o modelo. Congelar (definindo layer.trainable = False) evita que os pesos em uma determinada camada sejam atualizados durante o treinamento. MobileNet V2 tem muitas camadas, assim, definir toda do modelo trainable bandeira para Falso irá congelar todos eles.
Observação importante sobre camadas BatchNormalization
Muitos modelos contêm tf.keras.layers.BatchNormalization camadas. Esta camada é um caso especial e deve-se tomar precauções no contexto do ajuste fino, conforme mostrado posteriormente neste tutorial.
Quando você define layer.trainable = False , o BatchNormalization camada será executado no modo de inferência, e não irá atualizar suas estatísticas de média e variância.
Quando você descongelar um modelo que contém camadas BatchNormalization, a fim de fazer o ajuste fino, 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 aprendizagem Transferência .
Adicionar uma cabeça de classificação
Para gerar as previsões do bloco de características, a média ao longo dos espaciais 5x5 localizações espaciais, utilizando um tf.keras.layers.GlobalAveragePooling2D camada para converter as características de um único elemento 1280-vector por imagem.
Aplique uma tf.keras.layers.Dense camada 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á tratado como um logit , ou um valor de previsão cru. Os números positivos preveem a classe 1, os números negativos preveem a classe 0.
Construir um modelo de encadeamento o aumento de dados, redimensionamento, base_model e exaustor recurso camadas usando a API Funcional Keras . Como mencionado anteriormente, o uso training=False como nosso modelo contém uma BatchNormalization camada.
Compile o modelo antes de treiná-lo. Uma vez que existem duas classes, use o tf.keras.losses.BinaryCrossentropy perda com from_logits=True já que o modelo fornece uma saída linear.
Os 2,5 milhões de parâmetros em MobileNet são congelados, mas há 1,2 mil parâmetros treináveis na camada densa. Estes são divididos entre duas tf.Variable objectos, os pesos e desvios.
Depois de treinar por 10 épocas, você verá aproximadamente 94% de precisão no conjunto de validação.
Vamos dar uma olhada nas curvas de aprendizado da precisão / perda de treinamento e validação ao usar o modelo base MobileNetV2 como um extrator de recurso fixo.
Nota: Se você está se perguntando por que as métricas de validação são claramente melhores do que as métricas de treinamento, o principal fator é porque camadas como tf.keras.layers.BatchNormalization e tf.keras.layers.Dropout afetar a precisão durante o treinamento. Eles são desligados ao calcular a perda de validação.
Em menor medida, 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, de modo que as métricas de validação veem um modelo que foi treinado um pouco mais.
No experimento de extração de recursos, você treinou apenas algumas camadas sobre um modelo básico MobileNetV2. Os pesos da rede pré-treinados 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 junto com o treinamento do classificador adicionado. O processo de treinamento forçará os pesos a serem ajustados de mapas de recursos genéricos para recursos associados especificamente ao conjunto de dados.
Nota: Isto só deve ser tentada depois de ter treinado o classificador de nível superior com o pré-treinados modelo definido para não-treinável. Se você adicionar um classificador inicializado aleatoriamente em cima de 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 será esqueça 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 se generalizam para quase todos os tipos de imagens. Conforme você sobe, os recursos são cada vez mais específicos para o conjunto de dados no qual o modelo foi treinado. O objetivo do ajuste fino é adaptar esses recursos especializados para trabalhar com o novo conjunto de dados, em vez de substituir o aprendizado genérico.
Descongelar as camadas superiores do modelo
Tudo que você precisa fazer é descongelar os base_model e definir as camadas inferiores para ser un-treinável. Em seguida, você deve recompilar o modelo (necessário para que essas alterações tenham efeito) e retomar o treinamento.
Como você está treinando um modelo muito maior e deseja readaptar os pesos pré-treinados, é importante usar uma taxa de aprendizado mais baixa neste estágio. Caso contrário, seu modelo pode ajustar-se excessivamente rapidamente.
Vamos dar uma olhada nas curvas de aprendizado da precisão / perda de treinamento e validação ao ajustar as últimas camadas do modelo básico do MobileNetV2 e treinar o classificador sobre ele. A perda de validação é muito maior do que a perda de treinamento, então você pode obter algum sobreajuste.
Você também pode obter alguns ajustes excessivos, pois o novo conjunto de treinamento é relativamente pequeno e semelhante aos conjuntos de dados MobileNetV2 originais.
E agora você está pronto para usar este modelo para prever se seu animal de estimação é um gato ou um cachorro.
Usando um modelo pré-treinados para extração de características: Ao trabalhar com um pequeno conjunto de dados, é uma prática comum para tirar proveito dos recursos aprendidas por um modelo treinado em um conjunto de dados 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 fica "congelado" e apenas os pesos do classificador são atualizados durante o treinamento. Nesse caso, a base convolucional extraiu todos os recursos associados a cada imagem e você apenas treinou um classificador que determina a classe da imagem dado aquele conjunto de recursos extraídos.
Ajustar um modelo pré-treinados: Para melhorar ainda mais o desempenho, pode-se querer adaptar as camadas de nível superior dos modelos pré-treinado para o novo conjunto de dados via ajuste fino. Nesse caso, você ajustou seus pesos de forma que seu modelo aprendeu recursos de alto nível específicos para o conjunto de dados. Essa técnica geralmente é recomendada quando o conjunto de dados de treinamento é grande e muito semelhante ao conjunto de dados original em que o modelo pré-treinado foi treinado.