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, viesesb - 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.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
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/dbonde η é 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 yDefinindo as operações explicitamente:
u = w * xz = u + by_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(porqueu = w*x)dz/du = 1(porquez = u + b)dz/db = 1dy_hat/dz = f'(z)dL/dy_hatdepende 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_hatg_z = dL/dzg_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_zg_u = g_z * (dz/du) = g_zdL/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 = 2w = 0.5b = -1f(z) = σ(z) = 1/(1+e^{-z})L = 0.5 * (y_hat - y)^2y = 1
Forward
u = w*x = 0.5*2 = 1z = u + b = 1 + (-1) = 0y_hat = σ(0) = 0.5L = 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 emz=0:σ'(0)=0.5*(1-0.5)=0.25
Agora combine:
dL/dz = (dL/dy_hat)*(dy_hat/dz) = (-0.5)*0.25 = -0.125dL/db = dL/dz * dz/db = -0.125 * 1 = -0.125dL/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.525b := -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*xz = u + by_hat = σ(z)L = 0.5*(y_hat - y)^2
Agora use os valores:
x = 3w = -0.2b = 0.4y = 0
Tarefas:
- Faça o forward e obtenha
u,z,y_hateL. - Calcule
dL/dy_hat,dy_hat/dz,dL/dz,dL/dwedL/db.
Valores esperados para conferência (aproximados)
Se você fizer as contas corretamente, deve encontrar aproximadamente:
u = -0.6z = -0.2y_hat ≈ 0.450166L ≈ 0.101325dL/dz ≈ 0.111423dL/dw ≈ 0.334269dL/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).