Uma visão conceitual de Redes Neurais — Parte 1

Ricardo Araujo
7 min readNov 26, 2020

Vimos anteriormente que um Perceptron nada mais é que um classificador linear. Como tal, ele representa um hiperplano separador no espaço de atributos, como abaixo. Diremos que a classe laranja é a classe positiva (a indicada quando o perceptron se ativa).

Se agora tivermos um problema que não é linearmente separável, um Perceptron será incapaz de fazer a separação de forma adequada, pois não há um hiperplano que separe perfeitamente as classes.

Porém, podemos observar que é possível fazer a separação das classes se pudermos usar dois hiperplanos (retas neste caso), definindo uma região específica no espaço de atributos. No exemplo abaixo, um exemplo pertence a classe laranja quando ele se encontra simultaneamente à direita da primeira reta e à esquerda da segunda.

Podemos usar um perceptron para representar cada hiperplano, mas ainda precisamos decidir quando um exemplo está na área definida por ambos hiperplanos. Um terceiro perceptron pode ocupar esta função. Na imagem abaixo, cada um dos dois perceptrons na esquerda (a "primeira camada") definem hiperplanos no espaço de atributos. O perceptron na direita, porém, não recebe atributos dos exemplos, mas saídas dos dois outros perceptrons (y1 e y2). Corretamente treinado (e veremos como treinar adiante), ele representará uma regra como "ative se o primeiro perceptron não ativar e o segundo ativar".

O terceiro perceptron define um hiperplano em outro espaço, diferente do espaço de atributos que operam os dois primeiros. A representação deste espaço e do hiperplano resultante são dadas pelas saídas dos perceptrons na primeira camada, como abaixo. O problema original não era linearmente separável, mas se tornou separável com a aplicação da primeira camada de perceptrons.

Cada perceptron na primeira camada pode estar ativo ou não, gerando quatro possibilidades. O perceptron de saída consegue decidir facilmente sobre este novo espaço

Assim, ainda que um perceptron seja apenas um classificador linear simples, o uso de múltiplos perceptrons de forma encadeada pode solucionar problemas mais complexos. A este uso damos o nome de Redes Neurais Artificiais, ou apenas Redes Neurais.

Considere um problema um pouco mais complexo, ainda com exemplos com apenas dois atributos.

Neste caso, dois hiperplanos não são suficientes para delimitar uma região e separar os exemplos mas quatro são suficientes. Assim, precisaríamos de quatro perceptrons, cada um representando um hiperplano. Tornar a rede mais larga aumenta a expressividade da rede naquele espaço de representação. Um único perceptron na saída ainda é suficiente para decidir sobre as saídas destes perceptrons, pois continua sendo um operação de conjunção (operador E lógico), que é linearmente separável. Por outro lado, considere o caso abaixo.

Com apenas três perceptrons conseguimos separar as regiões, mas a lógica a ser aplicada sobre os hiperplanos resultantes não é mais um simples E lógico. Um exemplo é da classe laranja se estiver entre os dois primeiros hiperplanos ou à direita do terceiro. Este não é um padrão linearmente separável (é difícil de ver por ser em 3 dimensões, porém) e, portanto, um único perceptron na saída não conseguirá aprender a relação entre estes hiperplanos.

Para solucionar este problema, podemos adicionar uma camada adicional. A primeira camada é responsável por definir os hiperplanos na figura acima. Uma possibilidade para a segunda camada é ter dois perceptrons, onde um ativará se o exemplo estiver presente entre os dois hiperplanos da esquerda (um E lógico, que já vimos ser linearmente separável) e o outro ativará sempre que o perceptron representando o terceiro hiperplano ativar (de fato este perceptron não precisaria existir, mas não queremos quebrar a modularidade da rede por motivos que ficarão claros adiante). Por fim, o perceptron de saída apenas precisa ativar se algum destes dois perceptrons está ativo.

De forma simplificada, enquanto mais perceptrons em uma camada aumentam a expressividade da rede naquela representação, disponibilizando mais hiperplanos para separações mais complexas, o aumento da profundidade da rede (o número de camadas) permite desenvolver uma lógica mais complexa sobre os hiperplanos por meio de progressivas transformações da representação. Esta é uma simplificação pois estas duas variáveis são interdependentes, já que as separações não fazem sentido sem a lógica de uso destas, e vice-versa.

A capacidade de redes neurais de trabalharem com representações intermediárias é um dos grandes atrativos deste modelo, permitindo lidar com problemas que não são linearmente separáveis. O kernel em uma SVM tem função semelhante: ele mapeia a representação original para outra, em um espaço multi-dimensional. Porém, no SVM temos que escolher o kernel a priori. Uma rede neural é capaz de, em teoria, aprender um mapeamento adequado para o problema de forma automática.

A maneira com que conectamos os perceptrons, definindo a chamada arquitetura da rede, em camadas bem definidas não foi por acaso. Esta arquitetura hierárquica é denominada Multilayer Perceptron (MLP). Em uma MLP, a rede é construída em camadas totalmente conectadas entre si (isto é, cada perceptron é conectado a todos perceptrons da camada seguinte), sem possibilidade de conexões que pulem camadas ou retornem a camadas anteriores.

Esta forma de construir redes neurais simplifica a especificação de arquiteturas: ela é predominantemente definida pelo número de camadas intermediárias (ou ocultas) e pelo número de perceptrons em cada camada. As camadas de entrada e saída são tipicamente pré-definidas pelos dados (número de atributos e número de classes). Não perdemos generalidade com estas restrições: MLPs com duas ou mais camadas são capazes de aproximar qualquer função (desde que um número suficiente de perceptrons sejam alocadas em cada camada). Também não devemos ler demais nesta afirmação: ela é o equivalente a dizer que é sempre possível esconder uma agulha em uma palheiro arbitrariamente grande.

Uma aparente dificuldade de utilizar camadas é o treino da rede. No perceptron, atualizamos os pesos a partir do erro na sua saída. Este erro pode ser calculado pois sabemos qual é a saída correta. Para perceptrons que não estão na saída da rede, não temos uma boa definição do que seria uma saída correta — não é algo especificado nos dados. Sabemos porém que estas saídas intermediárias contribuem para a saída final e, portanto, para o erro medido.

MLPs são tipicamente treinadas utilizando o algoritmo backpropagation. Este algoritmo provê uma maneira de distribuir o erro global da rede entre seus perceptrons, permitindo a atualização dos pesos. Este algoritmo utiliza descida de gradiente e, portanto, exige que as funções envolvidas sejam diferenciáveis. Assim, faz-se necessário utilizar funções de ativação diferenciáveis no lugar da função degrau comumente utilizada nos perceptrons. Uma função tradicionalmente utilizada é a função logística fazendo com que Multilayer Perceptrons possam ser, na verdade, compostos de regressões logísticas e não de perceptrons! 😱

O uso de uma função que não a degrau, em particular nos perceptrons de saída, também permite que a rede neural seja utilizada em problemas de regressão. De fato, uma rede neural é primariamente um regressor pois sua saída é sempre numérica. O uso como classificador exige a interpretação desta saída numérica. Por exemplo, se temos um único perceptron na saída com uma função logística, devemos estabelecer um limiar de decisão para diferenciar as classes, como fazemos na regressão logística. Em problemas multi-classe, tipicamente temos um perceptron na saída para cada classe e podemos considerar como classe predita aquela associada ao perceptron com maior ativação.

Um exemplo interessante do processo de aprendizado de representações intermediárias por uma rede neural é um autoencoder. Um autoencoder é um modelo treinado para representar a sua entrada na saída. A utilidade de um autoencoder é precisamente encontrar representações intermediárias que permitam reconstruir uma entrada com menos informações. O treinamento de um autoencoder é um exemplo de aprendizado auto-supervisionado: não precisamos rotular os dados pois sabemos exatamente, para qualquer entrada, qual a saída desejada.

Um autoencoder simples baseado em uma MLP está representado abaixo. A entrada é um vetor one-hot: um vetor binário onde todos bits são zero exceto um. Desejamos replicar este vetor na saída. Assim, temos 8 possíveis entradas. A primeira metade da rede é chamada codificador, enquanto a segunda decodificador.

Esta tarefa é trivial se permitirmos que o número de perceptrons na camada intermediária seja igual ao tamanho do vetor. Porém, se tivermos menos unidades a rede se verá forçada a encontrar uma representação alternativa, mais compacta, da entrada.

Com três perceptrons, como na figura acima, conseguimos treinar a rede sem maiores problemas. Colocando mais perceptrons apenas torna o treinamento e inferência mais custosos, mas a rede ainda é capaz de reproduzir perfeitamente sua entrada.

No entanto, ao reduzirmos para dois perceptrons, a rede não consegue mais solucionar o problema. O motivo de 3 ser o número mínimo é devido ao fato de termos 8 exemplos distintos que precisamos diferenciar. A função logística tem como saída essencialmente 0 ou 1 — portanto, 3 perceptrons conseguem “contar” facilmente até 8 (2³=8). Você pode verificar isto experimentalmente neste notebook.

--

--

Ricardo Araujo

Computer Science professor at UFPel. Machine Learning and Artificial Intelligence practitioner and researcher.