Bem-vindo à parte 3 da série de aprendizagem profunda aplicada. A parte 1 foi uma introdução prática às Redes Neurais Artificiais, cobrindo tanto a teoria quanto a aplicação com um monte de exemplos de código e visualização. Na parte 2 aplicamos a aprendizagem profunda a Conjuntos de dados do mundo real, cobrindo os três problemas mais comumente encontrados como estudos de caso: classificação binária, classificação multicass e regressão.
agora vamos começar a mergulhar em arquiteturas específicas de aprendizagem profunda, começando com o mais simples: Autoencoders.
- Introdução
- Arquitetura
- Implantação
- Denoising Autoencoders
- Esparsos Autoencoders
- Casos de Uso
- Conclusão
O código este artigo está disponível aqui como um Jupyter notebook, sinta-se livre para fazer o download e experimente você mesmo.
Introduction
Autoencoders are a specific type of feedforward neural networks where the input is the same as the output. Eles comprimem a entrada em um código de dimensão inferior e então reconstruem a saída desta representação. O código é um compacto “resumo” ou “compressão” da entrada, também chamado de representação de espaço latente.
um auto-codificador consiste em 3 componentes: codificador, código e descodificador. O codificador comprime a entrada e produz o código, o decodificador então reconstrói a entrada somente usando este código.
Para construir um autoencoder precisamos de 3 coisas: um método de codificação, método de decodificação, e uma perda de função para comparar a saída com o destino. Vamos explorá-los na próxima seção.
Autoencoders são, principalmente, uma redução de dimensionalidade (ou compressão) algoritmo com um par de propriedades importantes:
- Dados específicos: Autoencoders só são capazes significativamente comprimir dados semelhantes ao que eles foram treinados. Uma vez que eles aprendem características específicas para os dados de treinamento dado, eles são diferentes de um algoritmo de compressão de dados padrão como gzip. Então, não podemos esperar que um autoencodificador treinado em dígitos manuscritos comprima fotos de paisagem.
- perda: A saída do autoencoder não será exatamente a mesma que a entrada, será uma representação próxima, mas degradada. Se você quer compressão sem perdas eles não são o caminho a seguir.
- sem supervisão: para treinar um auto-codificador não precisamos fazer nada de extravagante, basta jogar os dados de entrada raw sobre ele. Autoencoders são considerados uma técnica de aprendizagem não supervisionada, uma vez que eles não precisam de rótulos explícitos para treinar. Mas, para ser mais preciso, eles são auto-supervisionados porque eles geram seus próprios rótulos a partir dos dados de treinamento.
Architecture
Let’s explore the details of the encoder, code and decoder. Tanto o codificador como o descodificador são redes neurais feedforward conectadas, essencialmente os ans que cobrimos na parte 1. O código é uma única camada de um ANN com a dimensionalidade de nossa escolha. O número de nós na camada de Código (Tamanho do código) é um hiperparametro que definimos antes de treinar o autoencoder.
Esta é uma visualização mais detalhada de um autoencoder. Primeiro, a entrada passa através do codificador, que é um ANN totalmente conectado, para produzir o código. O decodificador, que tem a estrutura ANN semelhante, então produz a saída apenas usando o código. O objetivo é obter uma saída idêntica à entrada. Note que a arquitetura decodificadora é a imagem espelho do codificador. Isto não é um requisito, mas é tipicamente o caso. O único requisito é a dimensionalidade da entrada e saída precisa ser a mesma. Tudo no meio pode ser jogado com.Há 4 hiperparametros que precisamos de definir antes de treinar um autoencodificador:
- Tamanho do Código: número de nós na camada média. Tamanho menor resulta em mais compressão.
- número de camadas: o auto-codificador pode ser tão profundo quanto quisermos. Na figura acima temos 2 camadas no codificador e Decodificador, sem considerar a entrada e saída.
- número de nós por camada: a arquitetura de autoencoder em que estamos trabalhando é chamada de autoencoder empilhado uma vez que as camadas são empilhadas uma após a outra. Normalmente empilhados auto-codificadores parecem um “sandwitch”. O número de nós por camada diminui com cada camada subsequente do codificador, e aumenta de volta no decodificador. Também o descodificador é simétrico ao codificador em termos de estrutura de camadas. Como já foi referido, isto não é necessário e temos controlo total sobre estes parâmetros.
- função de perda: ou usamos o erro quadrático médio (mse) ou a crossentropia binária. Se os valores de entrada estão no intervalo, então normalmente usamos a crossentropia, caso contrário usamos o erro quadrado médio. Para mais detalhes confira este vídeo.
os auto-codificadores são treinados da mesma forma que os ans via backpropagation. Confira a introdução da parte 1 para mais detalhes sobre como as redes neurais são treinadas, ela se aplica diretamente aos autoencoders.
Implementation
Now let’s implement an autoencoder for the following architecture, 1 hidden layer in the encoder and decoder.
Vamos usar o extremamente popular MNIST conjunto de dados como entrada. Contém imagens a preto e branco de dígitos manuscritos.
Eles são de tamanho 28×28 e usá-los como um vetor de 784 números entre . Veja os detalhes no caderno do jupyter.Vamos agora implementar o autoencoder com Keras. Os hiperparâmetros são: 128 nós na camada oculta, o tamanho do código é 32, e a crossentropia binária é a função de perda.
isto é muito semelhante aos Ans em que trabalhamos, mas agora estamos usando a API funcional Keras. Consulte este guia para mais detalhes, mas aqui está uma comparação rápida. Antes de adicionarmos camadas usando a API sequencial como segue:
model.add(Dense(16, activation='relu'))
model.add(Dense(8, activation='relu'))
com a API funcional fazemos isso:
layer_1 = Dense(16, activation='relu')(input)
layer_2 = Dense(8, activation='relu')(layer_1)
é mais verboso, mas uma forma mais flexível de definir modelos complexos. Podemos facilmente pegar partes de nosso modelo, por exemplo, apenas o decodificador, e trabalhar com isso. A saída do método denso é uma camada ligável, usando a API funcional que lhe fornecemos com a entrada e armazenamos a saída. A saída de uma camada torna-se a entrada da camada seguinte. Com a API sequencial, O método add implicitamente lidou com isso para nós.
Note que todas as camadas usam a função de ativação de relu, pois é o padrão com redes neurais profundas. A última camada usa a ativação sigmoid porque precisamos que as saídas estejam entre elas . A entrada também está na mesma faixa.
note também a chamada para ajustar a função, antes com ans que costumávamos fazer:
model.fit(x_train, y_train)
mas agora temos:
model.fit(x_train, x_train)
lembre-se que os alvos do autoencoder são os mesmos que a entrada. É por isso que fornecemos os dados do treino como alvo.
Visualization
Now let’s visualize how well our autoencoder reconstructes its input.
executamos o autoencoder no conjunto de testes simplesmente usando a função de previsão de Keras. Para cada imagem no conjunto de teste, temos a saída do autoencoder. Esperamos que a saída seja muito semelhante à entrada.
Eles são realmente muito semelhantes, mas não exatamente o mesmo. Podemos notá-lo mais claramente no último dígito “4”. Uma vez que esta era uma tarefa simples, o nosso autoencoder funcionou muito bem.
Advice
we have total control over the architecture of the autoencoder. Podemos torná-lo muito poderoso, aumentando o número de camadas, nós por camada e, mais importante, o tamanho do Código. Aumentar estes hiper-parâmetros permitirá que o auto-codificador para aprender codificações mais complexas. Mas devemos ter o cuidado de não torná-lo muito poderoso. Caso contrário, o autoencoder irá simplesmente aprender a copiar as suas entradas para a saída, sem aprender qualquer representação significativa. Vai imitar a função de identidade. O autoencoder irá reconstruir os dados de treinamento perfeitamente, mas será sobrefitting sem ser capaz de generalizar para novas instâncias, que não é o que queremos.É por isso que preferimos uma arquitetura “sandwitch”, e deliberadamente manter o tamanho do Código pequeno. Uma vez que a camada de codificação tem uma dimensionalidade mais baixa do que os dados de entrada, o autoencoder é dito ser subcompleto. Ele não será capaz de copiar diretamente suas entradas para a saída, e será forçado a aprender recursos inteligentes. Se os dados de entrada têm um padrão, por exemplo, o dígito “1” geralmente contém uma linha um pouco reta e o dígito “0” é circular, ele vai aprender este fato e codificá-lo em uma forma mais compacta. Se os dados de entrada foram completamente aleatórios sem qualquer correlação interna ou dependência, então um autoencoder subcompleto não será capaz de recuperá-lo perfeitamente. Mas felizmente no mundo real há muita dependência.
Denoising Autoencoders
mantendo a camada de código pequena forçou o nosso autoencoder a aprender uma representação inteligente dos dados. Há outra maneira de forçar o autoencoder a aprender características úteis, que é adicionar ruído aleatório a suas entradas e fazê-lo recuperar os dados originais sem ruído. Desta forma, o autoencoder não pode simplesmente copiar a entrada para a sua saída porque a entrada também contém ruído aleatório. Pedimos-lhe que subtraia o ruído e produza os dados significativos subjacentes. Isto é chamado de um auto-codificador denoising.
A primeira linha contém a imagem original. Adicionamos ruído gaussiano Aleatório a eles e os dados ruidosos se tornam a entrada para o autoencoder. O autoencoder não vê a imagem original. Mas então esperamos que o autoencoder regenere a imagem original sem ruído.
Existe apenas uma pequena diferença entre a execução de denoising autoencoder e a regular. A arquitectura não muda nada, apenas a função adequada. Treinamos o autoencoder regular da seguinte forma::
autoencoder.fit(x_train, x_train)
o auto-codificador Denoising é treinado como:
autoencoder.fit(x_train_noisy, x_train)
tão simples quanto isso, tudo o resto é exactamente o mesmo. A entrada para o autoencoder é a imagem ruidosa, e o alvo esperado é o original sem ruído.
visualização
agora vamos visualizar se somos capazes de recuperar as imagens sem ruído.
Parece muito bom. A linha inferior é a saída do auto-codificador. Nós podemos fazer melhor usando arquitetura mais complexa autoencoder, como autoencoders convolucionais. Vamos cobrir as convoluções no próximo artigo.
Autoencoders esparsos
introduzimos duas formas de forçar o autoencoder a aprender características úteis: manter o tamanho do Código pequeno e denoising autoencoders. O terceiro método é o da regularização. Nós podemos regularizar o autoencoder usando uma restrição sparsity tal que apenas uma fração dos nós teria valores não-zero, chamados nós ativos.
em particular, adicionamos um termo de penalidade à função de perda de tal forma que apenas uma fração dos nós se tornam ativos. Isto força o autoencoder a representar cada entrada como uma combinação de um pequeno número de nós, e exige que ele descubra uma estrutura interessante nos dados. Este método funciona mesmo se o tamanho do código é grande, uma vez que apenas um pequeno subconjunto dos nós estará ativo a qualquer momento.
é muito fácil fazer isso em Keras com apenas um parâmetro. Como um lembrete, anteriormente criamos a camada de código como segue:
code = Dense(code_size, activation='relu')(input_img)
we now add another parameter called activity_regularizer by specifying the regularization strength. Este é tipicamente um valor na escala . Aqui escolhemos 10e-6.
code = Dense(code_size, activation='relu', activity_regularizer=l1(10e-6))(input_img)
a perda final do modelo esparso é 0,01 mais alto do que o padrão, devido ao termo de regularização adicional.Vamos demonstrar que as codificações geradas pelo modelo regularizado são realmente escassas. Se olharmos para o histograma de valores de código para as imagens no conjunto de testes, a distribuição é a seguinte::
A média para o modelo padrão é de 6,6 mas para o regularizada modelo é de 0,8, uma grande redução. Podemos ver que um grande pedaço de valores de código no modelo regularizado são de fato 0, que é o que queríamos. A variância do modelo regularizado também é bastante baixa.
Use Cases
now we might ask the following questions. Quão bons são os autoencoders para comprimir a entrada? E eles são uma técnica de aprendizagem profunda comumente usada?
infelizmente autoencoders não são amplamente utilizados em aplicações do mundo real. Como um método de compressão, eles não executam melhor do que suas alternativas, por exemplo jpeg faz compressão de fotos melhor do que um autoencoder. E o fato de que autoencoders são dados específicos torna-os impraticáveis como uma técnica geral. Eles têm 3 casos de uso comum, embora:
- denoising de dados: vimos um exemplo disso nas imagens.Redução de dimensionalidade: visualizar dados de alta dimensão é um desafio. o T-PND é o método mais usado, mas luta com um grande número de dimensões (normalmente acima de 32). Então autoencoders são usados como um passo de pré-processamento para reduzir a dimensionalidade, e esta representação comprimida é usada pelo T-SNE para visualizar os dados no espaço 2D. Para grandes artigos sobre o T-PNE se referir aqui e aqui.
- Variational Autoencoders( VAE): este é um caso de uso mais moderno e complexo de autoencoders e vamos cobri-los em outro artigo. Mas como um resumo rápido, VAE aprende os parâmetros da distribuição de probabilidade modelando os dados de entrada, em vez de aprender uma função arbitrária no caso de vanilla autoencoders. Por pontos de amostragem a partir desta distribuição também podemos usar a EAV como um modelo generativo. Aqui está uma boa referência.
Conclusion
Autoencoders are a very useful dimensionality reduction technique. Eles são muito populares como material didático em cursos de ensino profundo introdutório, muito provavelmente devido à sua simplicidade. Neste artigo abordámo-los em pormenor e espero que tenham gostado.
todo o código para este artigo está disponível aqui se você quiser hackeá-lo você mesmo. Se tiver algum feedback, sinta-se à vontade para me contactar no twitter.