Path: blob/master/site/pt-br/tutorials/images/segmentation.ipynb
25118 views
Copyright 2019 The TensorFlow Authors.
Licensed under the Apache License, Version 2.0 (the "License");
Segmentação de imagens
O foco deste tutorial é a tarefa de segmentação de imagens usando uma U-Net modificada.
O que é segmentação de imagens?
Em uma tarefa de classificação de imagens, a rede atribui um rótulo (ou classe) a cada imagem de entrada. Entretanto, vamos supor que você queira saber o formato desse objeto, qual pixel pertence a qual objeto, etc. Nesse caso, você precisa atribuir uma classe a cada pixel da imagem. Essa tarefa é conhecida como segmentação. Um modelo de segmentação retorna informações mais detalhadas sobre a imagem. A segmentação de imagens tem diversas aplicações nos exames de imagens médicos, em carros autônomos e em imagens de satélites, apenas para citar algumas.
Este tutorial usa o dataset Oxford-IIIT Pets (Parkhi et al, 2012). O dataset é composto por imagens de 37 raças de animais domésticos, com 200 imagens por raça (cerca de 100 para o treinamento e 100 para o teste). Cada imagem inclui os rótulos correspondentes e as máscaras de pixels. As máscaras são rótulos (classes) para cada pixel, e é atribuída uma categoria a cada pixel:
Classe 1: pixels pertencentes ao animal doméstico.
Classe 2: pixels no contorno do animal doméstico.
Classe 3: nenhuma das opções acima/pixels nos arredores.
Baixar o dataset Oxford-IIIT Pets
O dataset está disponível no TensorFlow Datasets. As máscaras de segmentação estão incluídas na versão 3 e posteriores.
Além disso, os valores de cor das imagens são normalizados no intervalo [0, 1]
. Por fim, conforme mencionado acima, os pixels na máscara de segmentação são rotulados como {1, 2, 3}. Por questões de conveniência, subtraia 1 da máscara de segmentação, e os rótulos resultantes serão: {0, 1, 2}.
O dataset já contém as divisões de treinamento e teste necessárias, então continue usando as mesmas divisões:
A classe abaixo faz uma ampliação simples invertendo uma imagem aleatoriamente. Saiba mais no tutorial Ampliação de imagens.
Crie o pipeline de entrada, aplicando a ampliação após dividir as entradas em lotes:
Veja uma imagem de exemplo e sua máscara correspondente do dataset:
Definir o modelo
O modelo em uso aqui é uma U-Net modificada. Uma U-Net consiste de um encoder (downsampler) e decoder (upsampler). Para aprender recursos robustos e reduzir o número de parâmetros treináveis, use um modelo pré-treinado, MobileNetV2, como encoder. Para o decoder, você usará o bloco de upsample, que já está implementado no exemplo Pix2Pix do repositório de exemplos do TensorFlow (confira o tutorial Pix2Pix: Conversão imagem-para-imagem com uma GAN condicional em um notebook).
Conforme mencionado, o encoder é um modelo MobileNetV2 pré-treinado. Você usará o modelo de tf.keras.applications
. O encoder consiste de saídas específicas das camadas intermediárias do modelo. É importante salientar que o encoder não será treinado durante o processo de treinamento.
O decoder/upsampler é simplesmente uma série de blocos de upsample implementados nos exemplos do TensorFlow:
O número de filtros na última camada é definido como o número de output_channels
(canais de saída). Será um canal de saída por classe.
Treinar o modelo
Agora, só falta compilar e treinar o modelo.
Como este é um problema de classificação multiclasse, use a função de perda do tf.keras.losses.SparseCategoricalCrossentropy
com o argumento from_logits
definido como True
, já que os rótulos são inteiros escalares em vez de vetores de pontuações para cada pixel de cada classe.
Ao executar a instância, o rótulo atribuído a cada pixel é o canal com o valor mais alto. É isso que a função create_mask
está fazendo.
Plote a arquitetura do modelo resultante:
Teste o modelo para verificar o que ele prevê antes do treinamento:
O callback definido abaixo é usado para observar como o modelo melhora à medida que é treinado:
Fazer previsões
Agora, faça previsões. Para poupar tempo, o número de épocas foi mantido baixo, mas você pode usar um valor mais alto para conseguir resultados mais precisos.
Opcional: classes desequilibradas e pesos de classes
Os datasets de segmentação semântica podem ficar muito desequilibrados, ou seja, pixels de uma classe específica podem estar mais presentes dentro das imagens do que de outras classes. Como os problemas de segmentação podem ser tratados como problemas de classificação por pixel, você pode lidar com o problema de desequilíbrio ponderando a função de perda para levar isso em conta. É uma forma simples e elegante de lidar com o problema. Confira mais detalhes no tutorial Classificação ao usar dados desequilibrados.
Para evitar ambiguidade, Model.fit
não tem suporte ao argumento class_weight
para alvos com mais de três dimensões.
Portanto, nesse caso, você é que precisa implementar os pesos. Para fazer isso, utilize pesos de amostra: além de pares (data, label)
, Model.fit
também aceita tuplas (data, label, sample_weight)
.
Model.fit
do Keras propaga sample_weight
para as perdas e métricas, que também aceitam um argumento sample_weight
. O peso da amostra é multiplicado pelo valor da amostra antes do passo de redução. Por exemplo:
Portanto, para fazer pesos de amostra para este tutorial, você precisa de uma função que receba um par (data, label)
e retorne uma tupla (data, label, sample_weight)
, em que sample_weight
é uma imagem de um canal contendo o peso de classes para cada pixel.
A implementação mais simples possível é usar o rótulo como índice em uma lista class_weight
:
Cada elemento do dataset resultante contém três imagens:
Agora, você pode treinar um modelo com esse dataset ponderado:
Próximos passos
Agora que você sabe o que é segmentação de imagens e como ela funciona, pode tentar usar este tutorial com diferentes saídas de camadas intermediárias ou até mesmo para diferentes modelos pré-treinados. Além disso, se quiser se desafiar, você pode experimentar o desafio de mascaramento de imagens Carvana, disponível no Kaggle.
Talvez também seja interessante conferir a API de Detecção de Objetos do Tensorflow para ver outro modelo que você pode treinar novamente usando seus próprios dados. Estão disponíveis modelos pré-treinados no TensorFlow Hub.