Path: blob/master/site/pt-br/tutorials/generative/cvae.ipynb
25118 views
Copyright 2020 The TensorFlow Authors.
Autoenconder variacional convolucional
Este notebook demonstra como treinar um autoencoder variacional (VAE, na sigla em inglês) (1, 2) no dataset MNIST. Um VAE é uma versão probabilística do autoencoder, um modelo que recebe dados de entrada de dimensão alta e comprime-os em uma representação menor. Diferentemente de um autoencoder tradicional, que mapeia a entrada em um vetor latente, um VAE mapeia os dados de entrada nos parâmetros de uma distribuição de probabilidades, como a média e a variância gaussianas. Essa estratégia gera um espaço latente estruturado e contínuo, muito útil para a geração de imagens.
Configuração
Carregar o dataset MNIST
Cada imagem do MNIST é originalmente um vetor com 784 inteiros, sendo que cada um está entre 0 e 255 e representa a intensidade de um pixel. Modele cada pixel com uma distribuição de Bernoulli em nosso modelo e binarize estatisticamente o dataset.
Usar o tf.data para dividir os dados em lotes e misturá-los
Definir as redes do encoder e decoder com tf.keras.Sequential
Neste exemplo de VAE, use duas ConvNets pequenas para as redes do encoder e do decoder. Na literatura, essas redes também são chamadas de modelos de inferência/reconhecimento e generativo, respectivamente. Use o tf.keras.Sequential
para simplificar a implementação. e denotam a observação e a variável latente, respectivamente, nas seguintes descrições.
Rede do encoder
Define a distribuição posterior aproximada , que recebe como entrada uma observação e gera como saída um conjunto de parâmetros para especificar a distribuição condicional da representação latente . Neste exemplo, modele a distribuição como uma gaussiana diagonal, e a rede gera como saída a média e os parâmetros da variância logarítmica de uma distribuição gaussiana fatorial. Gere como a saída a variância logarítmica em vez da variância diretamente para proporcionar estabilidade numérica.
Rede do decoder
Define a distribuição condicional da observação , que recebe uma amostra latente como entrada e gera como saída os parâmetros de uma distribuição condicional da observação. Modele o prior da distribuição latente como uma gaussiana unitária.
Truque de reparametrização
Para gerar uma amostra para o decoder durante o treinamento, você pode fazer uma amostragem da distribuição latente definida pelos parâmetros gerados como saída pelo encoder, dada uma observação de entrada . Entretanto, essa operação de amostragem cria um gargalo, pois a retropropagação não pode fluir por um nó aleatório.
Para tratar esse problema, use um truque de reparametrização. Em nosso exemplo, você aproxima usando os parâmetros do decoder e outro parâmetro da seguinte forma:
em que e representam a média e o desvio padrão de uma distribuição gaussiana, respectivamente. Eles podem ser derivados da saída do decoder. Podemos pensar no como um ruído aleatório usado para manter a estocasticidade de . Gere a partir de uma distribuição normal padrão.
Agora, a variável latente é gerada por uma função de , e , o que permite ao modelo retropropagar os gradientes no encoder por meio de e , respectivamente, ao mesmo tempo em que mantém a estocasticidade por meio de .
Arquitetura da rede
Para a rede do encoder, use duas camadas convolucionais seguidas por uma camada totalmente conectada. Na rede do decoder, espelhe essa arquitetura usando uma camada totalmente conectada seguida por três camadas transpostas convolucionais (também conhecidas como camadas deconvolucionais em alguns contextos). É uma prática comum evitar o uso da normalização de lotes ao treinar VAEs, já que a estocasticidade adicional devido ao uso de minilotes pode agravar a instabilidade da estocasticidade oriunda da amostragem.
Definir a função de perda e o otimizador
Os VAEs são treinados pela maximização do limite inferior de evidência (ELBO, na sigla em inglês) na verossimilhança logarítmica marginal:
Na prática, otimize a estimativa de Monte Carlo de amostra única desta expectativa:
Observação: você também poderia computar analiticamente o termo KL, mas aqui você incorpora todos os três termos do estimador de Monte Carlo por questões de simplicidade.
Treinamento
Comece fazendo a iteração do dataset
Durante cada iteração, passe a imagem para o encoder a fim de obter um conjunto de média e parâmetros de variância logarítmica do posterior aproximado
Depois, aplique o truque de reparametrização para fazer a amostragem a partir de
Por fim, passe as amostras reparametrizadas para o decoder a fim de obter os logits da distribuição generativa
Observação: como você utiliza o dataset carregado pelo Keras com 60 mil pontos de dados no conjunto de treinamento e 10 mil pontos de dados no conjunto de teste, o ELBO resultante no conjunto de teste é ligeiramente superior aos resultados indicados na literatura, que usa a binarização dinâmica do MNIST de Larochelle.
Geração de imagens
Após fazer o treinamento, está na hora de gerar algumas imagens
Comece fazendo a amostragem de um conjunto de vetores latentes a partir da distribuição de prior gaussiana unitária
O gerador vai converter a amostra latente em logits da observação, gerando uma distribuição
Agora, plote as probabilidades das distribuições de Bernoulli
Exibição de uma imagem gerada na última época de treinamento
Exibição de um GIF animado de todas as imagens salvas
Exibição de uma variedade bidimensional de dígitos do espaço latente
Ao executar o código abaixo, será exibida uma distribuição contínua das diferentes classes de dígitos, em que cada dígito transforma-se em outro no espaço latente bidimensional. Use a TensorFlow Probability para gerar uma distribuição normal padrão para o espaço latente.
Próximos passos
Este tutorial demonstrou como implementar um autoencoder variacional convolucional usando o TensorFlow.
Agora, você pode tentar melhorar a saída do modelo aumentando o tamanho da rede. Por exemplo, você pode tentar definir os parâmetros de filter
para cada uma das camadas Conv2D
e Conv2DTranspose
como 512. Para gerar o gráfico de imagem latente bidimensional, você precisaria manter latent_dim
como 2. Além disso, o tempo de treinamento aumenta à medida que o tamanho da rede aumenta.
Você também pode tentar implementar um VAE usando um dataset diferente, como o CIFAR-10.
Os VAEs podem ser implementados com diferentes estilos e complexidades variadas. Confira outras implementações nas seguintes fontes:
Se quiser saber mais sobre os detalhes de VAEs, confira Introdução aos autoencoders variacionais.