Entendendo Autoencoders (parte 1)

Henrique Voni
SiDi NLP
Published in
6 min readMar 11, 2022
Foto: Tomas Sobek

Uma das grandes vantagens dos modelos de deep learning é que eles são capazes de extrair as características mais relevantes para o problema em que são aplicados, dispensando a tarefa de feature engineering que até então era realizada em uma etapa prévia de pré-processamento.

Nesse sentido, surgiram os autoencoders — arquiteturas de redes neurais capazes de gerar uma representação a partir dados de entrada em um espaço dimensional significativamente menor que o original. Dada sua relevância, os autoencoders são aplicados em muitas tarefas de machine learning, como: redução de dimensionalidade, classificação, detecção de anomalias, geração de dados, entre outras.

Neste primeiro artigo sobre o tema, vamos passar sobre pontos importantes sobre a arquitetura dos autoencoders, tal como os principais pontos em comum com as redes neurais tradicionais.

Afinal, como funciona?

O conceito de autoencoder foi proposto inicialmente no artigo Learning Internal Representations by Error Propagation (Rumelhart et al, 1986) com o intuito de investigar a capacidade de reconstruir amostras com o uso de modelos profundos, obtendo o menor erro possível. Isto é, em um conjunto de dados Sₜ sendo

em que xᵢ ∈ ℝⁿ. Tradicionalmente, o uso de redes neurais envolve uma saída esperada yᵢ associada a cada amostra xᵢ , o que não necessariamente acontece no caso dos autoencoders. Aqui, a ideia é que a rede gere uma saída o mais próxima possível da entrada xᵢ . Ou seja, com o menor erro de reconstrução possível.

Neste artigo vamos abordar o Feedforward Autoencoder. Sua estrutura possui três componentes principais: um encoder, uma representação latente e um decoder. O encoder e o decoder podem ser vistos simplesmente como funções, enquanto que a representação latente refere-se a um tensor de números reais com uma dimensionalidade menor do que a entrada da rede. Essa estrutura é ilustrada pela figura abaixo:

Estrutura geral de um autoencoder — fonte: https://blog.keras.io/building-autoencoders-in-keras.html

De forma geral, queremos que o autoencoder seja capaz de aprender a reconstruir amostras suficientemente bem. Ao mesmo tempo, a representação latente gerada pela saída do encoder deve ser representativa, gerada a partir da extração das características mais relevantes da entrada. Se a representação latente atender a esse quesito, o uso de autoencoders torna-se muito útil para diversas tarefas, como por exemplo a compressão dos dados para uma tarefa de classificação, ou ainda para simplesmente entender quais as características essenciais de um dataset.

Em grande parte das arquiteturas de autoencoder, o encoder e o decoder são redes neurais, onde a saída do encoder pode ser escrita como uma função g(.) que depende de alguns parâmetros:

onde 𝐡ᵢ ∈ ℝᵘ é a representação latente dada pela saída do encoder quando aplicado à amostra xᵢ. A função g(.), portanto, faz o mapeamento entre os espaços ℝⁿ → ℝᵘ.

A partir da representação hᵢ, o decoder — denotado pela função f(.) — gera a reconstrução x̃ᵢ:

Treinamento do autoencoder

O treinamento do autoencoder acontece por meio do ajuste dos parâmetros do encoder e decoder, de maneira que, como mencionado anteriormente, possibilite a reconstrução da entrada com o menor erro possível. Matematicamente, busca-se encontrar as funções g(.) e f(.) que satisfaçam a condição:

Sendo que Δ indica uma medida de diferença entre a entrada e a saída do autoencoder e < . >indica o valor médio entre todas as amostras. Note que, embora busca-se o menor erro de reconstrução, um valor igual a 0 indicaria que o autoencoder é uma função identidade, o que não é ideal por ser de pouca utilidade.

Ativação na camada de saída

Em problemas de classificação, a camada de saída geralmente é responsável por retornar uma distribuição de probabilidades entre as classes através, por exemplo, da função softmax. Entretanto, no caso dos autoencoders, as funções mais utilizadas são ReLU e sigmóide.

A função ReLU assume qualquer valor no intervalo [0, ∞], e é dada por

e é uma boa opção em casos onde a entrada assume valores positivos. Já a função sigmóide compreende valores entre 0 e 1, e é calculada da seguinte forma:

A função sigmóide é uma opção interessante quando os valores de entrada estão no intervalo [0,1] (ou foram normalizados para atender a esse requisito).

Função de custo

Outro ponto em comum com as redes neurais de classificação é o uso de uma função de custo, que deverá ser minimizada. Como foi mencionado, busca-se medir a diferença entre a entrada xᵢ e a saída x̃ᵢ de forma que o autoencoder seja capaz de gerar uma aproximação da função identidade (lembre-se: aproximação).

Duas funções de custo amplamente utilizadas são a Mean Squared Error (MSE) e Binary Cross-Entropy (BCE). O uso dessas funções está associado a algumas condições.

Relembrando, a função MSE é dada por:

Sendo | . | a norma de um vetor e M o número de amostras no conjunto de dados. Seu uso é popular nos autoencoders pela simplicidade de implementação, que também independe da escala dos dados de entrada e/ou da função de ativação escolhida para a camada de saída.

Já a BCE é calculada da seguinte forma:

em que xⱼᵢ representa o j-ésimo atributo da i-ésima amostra. A BCE, que geralmente é utilizada em problemas de classificação, funciona muito bem com os autoencoders, desde que os dados de entrada estejam no intervalo de [0,1] e a função de ativação da camada de saída seja softmax ou sigmóide.

Autoencoders e NLP

A capacidade dos autoencoders de gerar projeções representativas sobre os dados de entrada também é explorada em tarefas de NLP. Estruturas baseadas em Transformers, por exemplo, foram um grande marco por conseguirem capturar relações de contexto não antes possíveis com outros modelos, como as redes LSTM, GRU, entre outros.

Caso queira conhecer mais sobre, temos um artigo que retrata embeddings. Não deixe de conferir.

O que vimos até aqui

Chegamos ao final da primeira parte do tutorial sobre autoencoders! Esse post foi um primeiro contato com o tema, com os principais aspectos da construção do autoencoder Feedfoward. No próximo artigo da série, traremos um tutorial de implementação de um autoencoder aplicado a uma tarefa de classificação.

--

--

Henrique Voni
SiDi NLP

Desenvolvedor de Machine Learning no time de NLP do SiDi e Doutorando em Engenharia da Computação na UNICAMP