Path: blob/master/site/pt-br/tutorials/generative/style_transfer.ipynb
25118 views
Copyright 2018 The TensorFlow Authors.
Transferência neural de estilo
Este tutorial usa aprendizado profundo para criar uma imagem com o estilo de outra (você já desejou pintar como Picasso ou Van Gogh?). Isso é conhecido como transferência neural de estilo, e uma técnica é descrita em Algoritmo neural de estilo artístico (Gatys et al.).
Observação: este tutorial demonstra o algoritmo de transferência de estilo original, que otimiza o conteúdo da imagem para um estilo específico. Nas estratégias modernas, um modelo é treinado para gerar a imagem estilizada diretamente (similar à CycleGAN). Essa estratégia é muito mais rápida (até 1.000 vezes).
Para ver uma aplicação simples de transferência de estilo com um modelo pré-treinado do TensorFlow Hub, confira o tutorial Transferência rápida de estilo para estilos arbitrários, que usa um modelo arbitrário de estilização de imagem. Para ver um exemplo de transferência de estilo com o TensorFlow Lite, confira Transferência de estilo artístico com o TensorFlow Lite.
A transferência neural de estilo é uma técnica de otimização usada para pegar duas imagens, uma de conteúdo e uma de referência de estilo (como uma obra de arte de um pintor famoso), e combiná-las para que a imagem produzida pareça a imagem de conteúdo, mas esteja “pintada” com o estilo da imagem de referência de estilo.
Essa implementação é feita otimizando-se a imagem produzida para que corresponda às estatísticas de conteúdo da imagem de conteúdo e às estatísticas de estilo da imagem de referência de estilo. Essas estatísticas são extraídas das imagens usando uma rede convolucional.
Por exemplo, vamos pegar uma imagem deste cachorro e a Composição VII de Wassily Kandinsky:
Labrador amarelo olhando para trás, disponível na Wikimedia Commons por Elf. Licença CC BY-SA 3.0
Como essa imagem ficaria se Kandinsky decidisse pintar esse cachorro exclusivamente com esse estilo? Algo assim?
Configuração
Importar e configurar os modelos
Baixe as imagens e escolha uma imagem de estilo e outra de conteúdo:
Visualizar a entrada
Defina uma função para carregar uma imagem e limitar sua dimensão máxima a 512 pixels.
Crie uma função simples para exibir uma imagem:
Transferência rápida de estilo usando o TF-Hub
Este tutorial demonstra o algoritmo de transferência de estilo original, que otimiza o conteúdo da imagem para um estilo específico. Antes de darmos maiores detalhes, vejamos como o modelo do TensorFlow Hub faz isso:
Definir as representações de conteúdo e estilo
Use as camadas intermediárias do modelo para obter as representações de conteúdo e estilo da imagem. Começando pela camada de entrada da rede, as primeiras ativações de camada representam as características de baixo nível, como contornos e texturas. À medida que você executa os passos da rede, as camadas finais representam características de alto nível: partes de objetos, como rodas ou olhos. Neste caso, você está usando a arquitetura de rede VGG19, uma rede de classificação de imagens pré-treinada. Essas camadas intermediárias são necessárias para definir a representação do conteúdo e do estilo das imagens. Para uma imagem de entrada, tente compatibilizar as representações correspondentes de estilo e conteúdo alvo nessas camadas intermediárias.
Carregue um VGG19 e execute um teste na imagem para garantir que o uso esteja correto:
Agora, carregue um VGG19
sem o cabeçalho de classificação e liste os nomes das camadas:
Escolha camadas intermediárias da rede para representar o estilo e o conteúdo da imagem:
Camadas intermediárias para estilo e conteúdo
Por que essas saídas intermediárias dentro da nossa rede de classificação de imagens pré-treinada permite a definição de representações de estilo e classificação?
De forma geral, para que uma rede realize classificação de imagens (que essa rede foi treinada para fazer), ela precisa entender a imagem. Isso requer pegar a imagem bruta como pixels de entrada e criar uma representação interna que converta os pixels da imagem bruta em uma compreensão complexa das características presentes na imagem.
Também é por isso que redes neurais convolucionais conseguem generalizar bem: elas conseguem capturar as invariâncias e características determinantes de classes (por exemplo, gatos versus cachorros), que são agnósticas quanto ao ruído de segundo plano e outros inconvenientes. Portanto, entre a alimentação da imagem bruta no modelo e o rótulo de classificação da saída, o modelo serve como um extrator de características complexas. Ao acessar as camadas intermediárias do modelo, você consegue descrever o conteúdo e o estilo das imagens de entrada.
Criação do modelo
As redes em tf.keras.applications
foram criadas para que você possa extrair facilmente os valores de camadas intermediárias usando a API funcional do Keras.
Para definir um modelo usando a API funcional, especifique as entradas e as saídas:
model = Model(inputs, outputs)
A função abaixo cria um modelo VGG19 que retorna uma lista de saídas de camadas intermediárias:
Para criar o modelo:
Calcular o estilo
O conteúdo de uma imagem é representado pelos valores dos mapas de características intermediárias.
Então, o estilo de uma imagem pode ser descrito por médias e correlações dos diferentes mapas de características. Calcule uma matriz de Gram que inclua essa informação calculando o produto externo do vetor de características consigo mesmo em cada local e fazendo a média do produto externo de todos os locais. Essa matriz de Gram pode ser calculada para uma camada específica da seguinte forma:
Isso pode ser implementado de forma concisa usando a função tf.linalg.einsum
:
Extrair o estilo e o conteúdo
Crie um modelo que retorne os tensores de estilo e conteúdo.
Quando uma imagem faz uma chamada, esse modelo retorna uma matriz de Gram (estilo) das style_layers
e de conteúdo das content_layers
:
Executar o método do gradiente descendente
Com esse extrator de estilo e conteúdo, agora você pode implementar o algoritmo de transferência de estilo. Faça isso calculando o erro quadrático médio da saída da sua imagem em relação a cada alvo, depois faça a soma ponderada dessas perdas.
Defina seus valores alvo de estilo e conteúdo:
Defina uma tf.Variable
, que conterá a imagem a ser otimizada. Para deixar isso rápido, inicialize-a com a imagem de conteúdo (a tf.Variable
precisa ter o mesmo formato que o da imagem de conteúdo):
Como essa imagem é um float, defina uma função para manter os valores de pixels entre e 0 e 1:
Crie um otimizador. O artigo recomenda o LBFGS, mas o Adam também funciona bem:
Para otimizar, use uma combinação ponderada das duas perdas para obter a perda total:
Use tf.GradientTape
para atualizar a imagem.
Agora, execute alguns passos para testar:
Como está funcionando, faça uma otimização mais longa:
Perda de variação total
Uma desvantagem dessa implementação básica é que são produzidos muitos artefatos de alta frequência. Para diminuir a quantidade de artefatos, use um termo de regularização explícita nos componentes de alta frequência da imagem. Na transferência de estilo, geralmente isso é chamado de perda de variação total:
Isso mostra como os componentes de alta frequência aumentaram.
Além disso, esse componente de alta frequência é basicamente um detector de contornos. Você consegue uma saída similar com o detector de contornos Sobel. Por exemplo:
A perda de regularização associada a isso é a soma dos quadrados dos valores:
Isso demonstrou o que ele faz. Mas você não precisa implementar, pois o TensorFlow inclui uma implementação padrão:
Executar a otimização novamente
Escolha um peso para total_variation_loss
:
Agora, inclua na função train_step
:
Reinicialize a variável de imagem e o otimizador:
E execute a otimização:
Por fim, salve o resultado:
Saiba mais
Este tutorial demonstra o algoritmo de transferência de estilo original. Para ver uma aplicação simples de transferência de estilo, confira este tutorial para saber mais sobre como usar o modelo arbitrário de transferência de estilo de imagem do TensorFlow Hub.