Backpropagation em Redes Neurais: regra da cadeia de forma intuitiva e computacional

Capítulo 6

Tempo estimado de leitura: 6 minutos

+ Exercício

O que é backpropagation (sem mistério)

Backpropagation é um procedimento para calcular, de forma eficiente, os gradientes de uma função de perda em relação aos parâmetros de uma rede (pesos e vieses). A ideia central é simples: a rede pode ser vista como uma composição de operações (somas, multiplicações, ativações, etc.). Para derivar a saída final em relação a um parâmetro lá do começo, aplicamos a regra da cadeia repetidamente, seguindo o caminho inverso do cálculo.

Em termos operacionais, o treinamento de uma rede em um exemplo (ou mini-batch) pode ser entendido como um ciclo com quatro etapas: forward pass (calcular predições), cálculo da perda, backward pass (propagar gradientes) e atualização (ajustar parâmetros).

Visão computacional: forward, loss, backward, update

1) Forward pass (construindo valores intermediários)

No forward pass, você calcula a saída da rede passo a passo, guardando valores intermediários (por exemplo, pré-ativações e ativações). Esses valores serão reutilizados no backward pass.

  • Entrada: x
  • Parâmetros: pesos W, vieses b
  • Intermediários: z (pré-ativação), a (ativação), etc.

2) Cálculo da perda (um escalar)

A perda L é um número que mede o quão distante a predição está do alvo. O ponto importante aqui é: a perda depende da saída, e a saída depende de todos os parâmetros via uma cadeia de operações.

3) Backward pass (gradientes camada a camada)

No backward pass, você começa pela perda e caminha “para trás” no grafo computacional, calculando derivadas locais e combinando-as via regra da cadeia. O resultado final são gradientes como dL/dW e dL/db.

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

Uma forma prática de pensar é: cada nó do grafo recebe um gradiente “vindo de cima” (do que depende dele) e o distribui para seus pais multiplicando pelas derivadas locais.

4) Atualização (usando os gradientes)

Com os gradientes em mãos, você atualiza os parâmetros na direção que reduz a perda. Em sua forma mais simples:

W := W - η * dL/dW  b := b - η * dL/db

onde η é a taxa de aprendizado.

Grafo computacional: como derivadas locais viram derivada global

Backpropagation fica muito mais intuitivo quando você enxerga a rede como um grafo computacional (um conjunto de operações encadeadas). Veja um exemplo mínimo com operações básicas:

Exemplo 1: um neurônio (operações: multiplicar, somar, ativar, calcular perda)

x ---(*)--- u --- (+) --- z --- f(.) --- y_hat --- loss --- L      ^        ^        ^         ^        ^      |      w        b        f        y_hat     y

Definindo as operações explicitamente:

  • u = w * x
  • z = u + b
  • y_hat = f(z)
  • L = loss(y_hat, y)

A regra da cadeia diz que:

dL/dw = (dL/dy_hat) * (dy_hat/dz) * (dz/du) * (du/dw)

Repare no padrão: é um produto de derivadas locais ao longo do caminho do parâmetro w até a perda.

Derivadas locais (as “peças” do produto)

Para o grafo acima, as derivadas locais típicas seriam:

  • du/dw = x (porque u = w*x)
  • dz/du = 1 (porque z = u + b)
  • dz/db = 1
  • dy_hat/dz = f'(z)
  • dL/dy_hat depende da função de perda escolhida

Então, sem precisar “reinventar” a derivada do começo ao fim, você só precisa combinar essas peças.

Backprop em forma de receita (com variáveis de gradiente)

Uma implementação mental útil é nomear gradientes intermediários. Por exemplo, defina:

  • g_y = dL/dy_hat
  • g_z = dL/dz
  • g_u = dL/du

Então você calcula:

  • g_z = g_y * (dy_hat/dz) = (dL/dy_hat) * f'(z)
  • dL/db = g_z * (dz/db) = g_z
  • g_u = g_z * (dz/du) = g_z
  • dL/dw = g_u * (du/dw) = g_u * x = g_z * x

Esse padrão “gradiente que chega” vezes “derivada local” é exatamente o que o backprop faz em redes profundas, só que repetido camada a camada.

Exemplo numérico completo (rede mínima) para ver o fluxo

Vamos usar um neurônio com ativação sigmoide apenas para ter um f'(z) concreto, e uma perda quadrática simples para facilitar contas manuais.

  • x = 2
  • w = 0.5
  • b = -1
  • f(z) = σ(z) = 1/(1+e^{-z})
  • L = 0.5 * (y_hat - y)^2
  • y = 1

Forward

  • u = w*x = 0.5*2 = 1
  • z = u + b = 1 + (-1) = 0
  • y_hat = σ(0) = 0.5
  • L = 0.5*(0.5 - 1)^2 = 0.5*( -0.5 )^2 = 0.125

Backward (derivadas locais e composição)

Primeiro, derivada da perda em relação à predição:

  • dL/dy_hat = (y_hat - y) = (0.5 - 1) = -0.5

Derivada da sigmoide:

  • σ'(z) = σ(z)*(1-σ(z)), então em z=0: σ'(0)=0.5*(1-0.5)=0.25

Agora combine:

  • dL/dz = (dL/dy_hat)*(dy_hat/dz) = (-0.5)*0.25 = -0.125
  • dL/db = dL/dz * dz/db = -0.125 * 1 = -0.125
  • dL/dw = dL/dz * dz/du * du/dw = (-0.125)*1*(x) = (-0.125)*2 = -0.25

Interpretação: como os gradientes são negativos, aumentar w e b (pois a atualização subtrai o gradiente) tende a reduzir a perda neste ponto.

Update (um passo)

Com taxa η = 0.1:

  • w := 0.5 - 0.1*(-0.25) = 0.525
  • b := -1 - 0.1*(-0.125) = -0.9875

Como isso escala para várias camadas (intuição “camada a camada”)

Em redes com várias camadas, o que muda é que o gradiente precisa atravessar mais operações. O backprop faz isso de forma organizada: você calcula um “erro” (gradiente) na saída e o transforma em gradientes para a camada anterior multiplicando por derivadas locais (matrizes de pesos e derivadas da ativação), repetindo até chegar na primeira camada.

Uma forma de enxergar: cada camada recebe dL/da (gradiente em relação à sua saída) e devolve dL/dz (aplicando a derivada da ativação) e então dL/dW, dL/db e o gradiente para a camada anterior.

Atividade prática (cálculo manual e comparação)

Parte A — calcule manualmente (1 neurônio)

Use exatamente o mesmo modelo do exemplo numérico:

  • u = w*x
  • z = u + b
  • y_hat = σ(z)
  • L = 0.5*(y_hat - y)^2

Agora use os valores:

  • x = 3
  • w = -0.2
  • b = 0.4
  • y = 0

Tarefas:

  • Faça o forward e obtenha u, z, y_hat e L.
  • Calcule dL/dy_hat, dy_hat/dz, dL/dz, dL/dw e dL/db.

Valores esperados para conferência (aproximados)

Se você fizer as contas corretamente, deve encontrar aproximadamente:

  • u = -0.6
  • z = -0.2
  • y_hat ≈ 0.450166
  • L ≈ 0.101325
  • dL/dz ≈ 0.111423
  • dL/dw ≈ 0.334269
  • dL/db ≈ 0.111423

Parte B — verificação por diferença finita (checar o gradiente)

Para validar seu dL/dw manual, estime numericamente:

grad_num ≈ (L(w + ε) - L(w - ε)) / (2ε)

Use, por exemplo, ε = 1e-4 e mantenha x, b, y fixos. O valor deve ficar bem próximo do seu dL/dw (diferenças pequenas são esperadas por aproximação numérica).

Agora responda o exercício sobre o conteúdo:

Em backpropagation, ao calcular dL/dw para um neurônio com u = w*x e z = u + b, qual expressão melhor representa como o gradiente é obtido a partir da regra da cadeia?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

No backprop, o gradiente flui de L para trás e cada nó multiplica o gradiente recebido pela sua derivada local. Assim, dL/dw é um produto de derivadas ao longo do caminho de w até L (regra da cadeia).

Próximo capitúlo

Estabilidade no treinamento de Redes Neurais: inicialização, normalização e problemas de gradiente

Arrow Right Icon
Capa do Ebook gratuito Introdução a Redes Neurais: do perceptron ao deep learning moderno
40%

Introdução a Redes Neurais: do perceptron ao deep learning moderno

Novo curso

15 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.