Ir para o conteúdo

5. Multi-Layer Perceptron

Apresentação: Perceptrons Multi-Camada (MLPs)

Todo neurônio faz sempre as mesmas duas coisas: uma soma ponderada de tudo o que chega até ele (mais um bias) e a passagem dessa soma por uma ativação não-linear. O painel de ampliação acima mostra essas duas operações; a rede é esse mesmo neurônio repetido e empilhado.

\[ y_k = \sigma \left( \sum_{j=1}^{m} v_{kj} \, \sigma \left( \sum_{i=1}^{n} w_{ji} x_i + b^{h}_{j} \right) + b^{y}_{k} \right) \]

onde:

  • \(y_k\) é a saída para o \(k\)-ésimo neurônio de saída.
  • \(x_i\) são as features de entrada.
  • \(w_{ji}\) é o peso que conecta a \(i\)-ésima entrada ao \(j\)-ésimo neurônio oculto — o neurônio que recebe vem primeiro, de modo que \(w_{ji}\) é a entrada da linha \(j\), coluna \(i\) de \(\mathbf{W}\).
  • \(v_{kj}\) é o peso que conecta o \(j\)-ésimo neurônio oculto ao \(k\)-ésimo neurônio de saída.
  • \(b^{h}_{j}\) é o bias para o \(j\)-ésimo neurônio oculto.
  • \(b^{y}_{k}\) é o bias para o \(k\)-ésimo neurônio de saída.
  • \(m\) é o número de neurônios ocultos.
  • \(n\) é o número de features de entrada.
  • \(\sigma\) é a função de ativação aplicada às somas ponderadas em cada camada, como sigmoid, tanh ou ReLU.

Representação matricial da arquitetura MLP:

\[ \begin{align*} \text{Camada de Entrada:} & \quad \mathbf{x} = [x_1, x_2, \ldots, x_n]^T \\ \text{Camada Oculta:} & \quad \mathbf{h} = \sigma (\mathbf{W} \mathbf{x} + \mathbf{b}^h) \\ \text{Camada de Saída:} & \quad \mathbf{y} = \sigma (\mathbf{V} \mathbf{h} + \mathbf{b}^y) \end{align*} \]

Funções de Ativação

Sigmoid Tanh ReLU
\(\sigma(x) = \displaystyle \frac{1}{1 + e^{-x}}\) \(\tanh(x) = \displaystyle \frac{e^{2x} - 1}{e^{2x} + 1}\) \(\text{ReLU}(x) = \max(0, x)\)
\(\sigma'(x) = \sigma(x)(1 - \sigma(x))\) \(\tanh'(x) = 1 - \tanh^2(x)\) \(\text{ReLU}'(x) = \begin{cases} 1 & \text{se } x > 0 \\ 0 & \text{se } x \leq 0 \end{cases}\)
Sigmoid é uma curva S suave que produz valores entre 0 e 1, sendo adequada para classificação binária. Tanh é uma curva suave que produz valores entre -1 e 1, centralizando os dados em zero, o que pode ajudar na convergência. ReLU é uma função linear por partes que produz zero para entradas negativas e a própria entrada para positivas, permitindo treinamento mais rápido e reduzindo o gradiente desvanecente.

Os três compartilham o mesmo eixo horizontal, então as derivadas tracejadas podem ser comparadas diretamente. Repare de onde vem o problema do gradiente desvanecente: a derivada da sigmoid nunca passa de 0,25, de modo que cada camada atravessada pelo gradiente o encolhe pelo menos quatro vezes, enquanto a derivada da ReLU vale exatamente 1 onde a unidade está ativa.

A retropropagação é o algoritmo usado para treinar MLPs ajustando pesos e biases com base no erro entre a saída prevista e o alvo real. O processo envolve dois passos principais:

  1. Passagem Direta: Os dados de entrada passam pela rede, camada por camada, para calcular a saída. A saída é comparada ao valor alvo para calcular a perda.
  2. Cálculo da Perda: Calcula-se a perda entre a saída prevista e o alvo real usando uma função de perda, como erro quadrático médio ou cross-entropy.
  3. Passagem Reversa: O erro é propagado de volta pela rede para calcular os gradientes da perda em relação a cada peso e bias. Esses gradientes são usados para atualizar os pesos e biases usando um algoritmo de otimização, como SGD ou Adam.

Passagem Direta (Feedforward)

Considere um MLP com:

  • 2 neurônios de entrada: \(x_1\) e \(x_2\)
  • 1 camada oculta com 2 neurônios: \(h_1\) e \(h_2\)
  • 1 neurônio de saída: \(y\)

Assumimos funções de ativação sigmoid para as camadas oculta e de saída:

\[\displaystyle \sigma(z) = \frac{1}{1 + e^{-z}}\]

com derivada \(\sigma'(z) = \sigma(z)(1 - \sigma(z))\).

A arquitetura, e a passagem direta por ela, pode ser percorrida passo a passo. Os valores mostrados são os mesmos da Simulação Numérica mais adiante, de modo que o diagrama e a aritmética são o mesmo exemplo:

Em termos matemáticos, o processo de passagem direta é descrito como:

\[ \begin{align*} \text{Camada de Entrada:} & \quad \mathbf{x} = [x_1, x_2]^T \\ \text{Camada Oculta:} & \quad \mathbf{h} = \sigma (\mathbf{W} \mathbf{x} + \mathbf{b}^h) \\ \text{Camada de Saída:} & \quad \mathbf{y} = \sigma (\mathbf{V} \mathbf{h} + \mathbf{b}^y) \end{align*} \]

ou, mais canonicamente:

\[ \hat{y} = \sigma \left( v_{11} \sigma \left(w_{11} x_1 + w_{12} x_2 + b^h_1\right) + v_{12} \sigma \left(w_{21} x_1 + w_{22} x_2 + b^h_2\right) + b^y_1 \right) \]
  1. Pré-ativação da camada oculta:
\[z_1 = w_{11} x_1 + w_{12} x_2 + b^h_1, \quad z_2 = w_{21} x_1 + w_{22} x_2 + b^h_2\]
  1. Ativações da camada oculta:
\[h_1 = \sigma(z_1), \quad h_2 = \sigma(z_2)\]
  1. Pré-ativação da camada de saída:
\[u = v_{11} h_1 + v_{12} h_2 + b^y_1\]
  1. Ativação da camada de saída:
\[\hat{y} = \sigma(u)\]

Cálculo da Perda

A função de perda quantifica a diferença entre a saída prevista e o alvo real. Para tarefas de regressão, o Erro Quadrático Médio (MSE) é comum:

\[L = \text{MSE} = \frac{1}{N} \sum_{i=1}^{N} (y_i - \hat{y}_i)^2\]

Retropropagação: Calculando Gradientes

O algoritmo de retropropagação calcula as derivadas parciais de \(L\) em relação a cada parâmetro usando a regra da cadeia, partindo da saída e propagando os erros de volta.

Os passos abaixo são o mesmo percurso que o diagrama faz. A rede é a da passagem direta, com os valores que ela produziu ainda sobre os neurônios — a retropropagação não os recalcula, ela os reaproveita:

Regra de Atualização

Para atualizar parâmetros (ex: via gradiente descendente com taxa de aprendizado \(\eta\)):

\[p \leftarrow p - \eta \cdot \frac{\partial L}{\partial p}\]

Passo 1: Erro da Camada de Saída

\[\sigma_y = \frac{\partial L}{\partial u} = \frac{2}{N}(\hat{y} - y) \cdot \hat{y}(1 - \hat{y})\]

Passo 2: Gradientes para Pesos e Bias de Saída

\[\frac{\partial L}{\partial v_{11}} = \sigma_y \cdot h_1, \quad \frac{\partial L}{\partial v_{12}} = \sigma_y \cdot h_2, \quad \frac{\partial L}{\partial b^y_1} = \sigma_y\]

Passo 3: Erros da Camada Oculta

\[\sigma_{h_1} = (\sigma_y \cdot v_{11}) \cdot h_1(1 - h_1), \quad \sigma_{h_2} = (\sigma_y \cdot v_{12}) \cdot h_2(1 - h_2)\]

Passo 4: Gradientes para Pesos e Biases Ocultos

\[\frac{\partial L}{\partial w_{11}} = \sigma_{h_1} \cdot x_1, \quad \frac{\partial L}{\partial w_{12}} = \sigma_{h_1} \cdot x_2\]
\[\frac{\partial L}{\partial w_{21}} = \sigma_{h_2} \cdot x_1, \quad \frac{\partial L}{\partial w_{22}} = \sigma_{h_2} \cdot x_2\]
\[\frac{\partial L}{\partial b^h_1} = \sigma_{h_1}, \quad \frac{\partial L}{\partial b^h_2} = \sigma_{h_2}\]

Passo 5: Atualizar Pesos e Biases

Usando os gradientes calculados e a taxa de aprendizado \(\eta\):

\[\mathbf{W} \leftarrow \mathbf{W} - \eta \frac{\partial L}{\partial \mathbf{W}}, \quad \mathbf{V} \leftarrow \mathbf{V} - \eta \frac{\partial L}{\partial \mathbf{V}}\]

Simulação Numérica

Com base na arquitetura MLP e nos passos de retropropagação descritos, podemos implementar uma simulação numérica simples para demonstrar o processo de treinamento.

Inicialização

As matrizes de pesos e vetores de bias são inicializados aleatoriamente em \([0,1]\):

\[\mathbf{W} = \begin{bmatrix} 0.2 & 0.4 \\ 0.6 & 0.8 \end{bmatrix}, \quad \mathbf{b}^h = [0.1, 0.2]^T\]
\[\mathbf{V} = \begin{bmatrix} 0.3 & 0.5 \end{bmatrix}, \quad b^y = 0.4, \quad \eta = 0.7\]

Passagem Direta

Para a amostra \(\mathbf{x} = [0.5, 0.8]^T\), \(y = 0\):

  1. Pré-ativação oculta: \(\mathbf{z} = [0.52, 1.14]^T\)
  2. Ativações ocultas: \(\mathbf{h} \approx [0.627, 0.758]^T\)
  3. Pré-ativação de saída: \(u \approx 0.967\)
  4. Ativação de saída: \(\hat{y} \approx 0.725\)

Cálculo da Perda

\[L = (0 - 0.725)^2 \approx 0.5249\]

Passagem Reversa

  1. Delta da saída: \(\delta_y = \partial L / \partial u = 2(\hat{y} - y) \cdot \hat{y}(1 - \hat{y}) \approx 0.289\)
  2. Deltas da camada oculta: \(\boldsymbol{\delta}_h = (\delta_y \mathbf{V}^T) \odot \mathbf{h} \odot (1 - \mathbf{h}) \approx [0.020, 0.027]^T\)
  3. Gradientes dos pesos: \(\displaystyle \frac{\partial L}{\partial \mathbf{W}} = \boldsymbol{\delta}_h \mathbf{x}^T \approx \begin{bmatrix} 0.010 & 0.016 \\ 0.013 & 0.021 \end{bmatrix}\), \(\displaystyle \frac{\partial L}{\partial \mathbf{V}} = \delta_y \mathbf{h}^T \approx \begin{bmatrix} 0.181 & 0.219 \end{bmatrix}\)
  4. Pesos atualizados: \(\mathbf{W} \leftarrow \begin{bmatrix} 0.193 & 0.389 \\ 0.591 & 0.785 \end{bmatrix}\), \(\mathbf{V} \leftarrow \begin{bmatrix} 0.173 & 0.347 \end{bmatrix}\), \(b^y \leftarrow 0.198\), \(\mathbf{b}^h \leftarrow [0.086, 0.181]^T\)

O gradiente é positivo, então a atualização reduz os parâmetros e empurra \(\hat{y}\) na direção do alvo \(y = 0\): apresentando a mesma amostra à rede atualizada, \(\hat{y} \approx 0.638\) e \(L \approx 0.407\), contra \(0.525\) antes.

Repita o processo de treinamento para cada amostra ou múltiplas épocas.

  • Aprendizado online: atualiza o modelo após cada exemplo de treinamento.
  • Aprendizado em batch: atualiza o modelo após processar um batch de exemplos.

Recursos Adicionais

Para uma compreensão mais intuitiva de redes neurais, recomendo a série de vídeos do 3Blue1Brown: https://www.3blue1brown.com/lessons/neural-networks


Interativo: Visualizador de Passagem Direta do MLP

Observe as ativações se propagando por uma rede 2-entradas → 3-ocultos → 2-saídas. Ajuste os sliders de entrada e veja os valores fluírem camada por camada.

Entrada x₁
Entrada x₂
Ativação


  1. Haykin, S. (1994). Neural Networks: A Comprehensive Foundation. Prentice Hall. 

  2. Bishop, C. M. (2006). Pattern Recognition and Machine Learning. Springer. 

  3. Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep Learning. MIT Press.