Aula 9: Funções Compostas, Redes Neurais e Diferenciação Automática

Otimização e Álgebra Linear para Machine Learning

Marcos M. Raimundo — Instituto de Computação, UNICAMP

2026-10-15

Revisão e Introdução

Da Aula 8: O Que Já Temos

  • Descida do Gradiente: Regra iterativa \(\mathbf{w}_{k+1} = \mathbf{w}_k - \alpha \nabla f(\mathbf{w}_k)\) com garantia de descida sob \(0 < \alpha < 2/L\).
  • Modelos Lineares: Regressão Linear (\(X\mathbf{w}\)) e Logística (\(\sigma(X\mathbf{w})\)) geram gradientes simples e superfícies de custo convexas.
  • O Limite Estrutural: Modelos lineares não aprendem representações nem interações de ordem superior entre atributos.
  • A Necessidade: Empilhar camadas de transformações lineares intercaladas por não-linearidades — os Perceptrons Multicamadas (Multilayer Perceptrons - MLPs).

O Pesadelo da Diferenciação Simbólica

Considere uma função composta com subexpressões repetidas: \[f(x) = \sqrt{x^2 + \exp(x^2)} + \cos(x^2 + \exp(x^2))\]

Aplicando a regra da cadeia analítica diretamente: \[\frac{df}{dx} = \frac{2x + 2x\exp(x^2)}{2\sqrt{x^2 + \exp(x^2)}} - \sin(x^2 + \exp(x^2))\cdot(2x + 2x\exp(x^2))\]

Simplificando os termos comuns: \[\frac{df}{dx} = 2x(1 + \exp(x^2))\left[ \frac{1}{2\sqrt{x^2 + \exp(x^2)}} - \sin(x^2 + \exp(x^2)) \right]\]

O Problema do Inchaço Algébrico

  • Escrever explicitamente o gradiente expandido gera expressões longas e cheias de subexpressões repetidas.
  • Em redes neurais profundas, a expansão simbólica explode exponencialmente (expression swell).

Ideia Central

A Dupla Face da Diferenciação em Deep Learning

  • 1. Reutilização de Computações: O gradiente da camada \(i\) reaproveita quase todo o cálculo já realizado na camada \(i+1\), adicionando apenas termos locais.
  • 2. Diferenciação Automática em DAGs: Em vez de fórmulas gigantescas no papel, propagamos valores numéricos de sensibilidade através de operações atômicas elementares, garantindo tempo de execução linear.

Roteiro da Aula

  • Pergunta 1: Como a Regra da Cadeia explora o reuso de prefixos no Backpropagation analítico (\(\boldsymbol{\delta}^{(l)}\) e \(\nabla_W \mathcal{L} = \boldsymbol{\delta} \mathbf{a}^T\))?
  • Pergunta 2: Por que cálculo manual, numérico e simbólico falham em escala, e como DAGs com variáveis intermediárias viabilizam a Diferenciação Automática?
  • Pergunta 3: Como a sensibilidade se propaga em nós bifurcados somando todos os caminhos direcionados até a saída?
  • Pergunta 4: Qual a dualidade Forward vs. Reverse via associatividade de produtos matriciais e como o Teorema de Baur-Strassen garante tempo linear?

O Dilema dos Parâmetros Ocultos

Problema Motivador: Arquitetura \(4 \to 3 \to 1\) no California Housing

  • Camada Oculta: \(\mathbf{z}^{(1)} = W^{(1)}\mathbf{x} + \mathbf{b}^{(1)} \in \mathbb{R}^3\) e \(\mathbf{a}^{(1)} = \sigma(\mathbf{z}^{(1)})\).
  • Predição Final: \(\hat{y} = \mathbf{w}^{(2)T}\mathbf{a}^{(1)} + b^{(2)}\).
  • O Desafio: Como calcular \(\nabla_{W^{(1)}}\mathcal{L}\) se \(W^{(1)}\) que está em camada intermediária?

Pausa Ativa 1 — O Desafio da Profundidade

Pergunta Aberta

Por que não podemos simplesmente aplicar o algoritmo de Descida do Gradiente da Aula 8 em um MLP calculando derivadas analíticas individuais para cada um dos parâmetros de forma independente, tratando cada peso como uma função isolada?

Otimização em Modelos Profundos

Julgue V ou F — a questão só conta se acertar os 4 itens:

  • □ Em um MLP com ativações não-lineares, a superfície de perda em relação aos parâmetros é em geral estritamente convexa, herdando as garantias de mínimo global da Aula 7.
  • □ A inclusão de ativações não-lineares é indispensável: compor múltiplas camadas puramente afins \(W^{(2)}(W^{(1)}\mathbf{x} + \mathbf{b}^{(1)}) + \mathbf{b}^{(2)}\) equivale estritamente a um único modelo afim \(\tilde{W}\mathbf{x} + \tilde{\mathbf{b}}\).
  • □ O gradiente da perda em relação a um peso de uma camada interna independe dos pesos das camadas posteriores, dependendo exclusivamente dos dados de entrada.
  • □ O gradiente descendente pode ser aplicado a superfícies não-convexas, mas a convergência passa a ser garantida apenas para pontos críticos (onde \(\nabla \mathcal{L} = \mathbf{0}\)), sem garantia de mínimo global.

Pausa Ativa 1 — Resposta

Otimização em Modelos Profundos — Resposta

  • ✗ Falso: A composição de não-linearidades e produtos de pesos destrói a convexidade; a perda de redes neurais possui múltiplos mínimos locais e pontos de sela.
  • ✔ Verdadeiro: O produto de matrizes é fechado sob multiplicação: \(W^{(2)}W^{(1)} = \tilde{W}\). Sem não-linearidades, profundidade não agrega expressividade.
  • ✗ Falso: Pela regra da cadeia, o sinal de erro deve atravessar as camadas posteriores para alcançar os pesos anteriores.
  • ✔ Verdadeiro: O Lema da Descida garante que passos adequados diminuem o custo até um ponto estacionário \(\nabla \mathcal{L} = \mathbf{0}\).

Voltando à pergunta: Tratar cada peso isoladamente geraria uma redundância computacional catastrófica: recalcularíamos as ativações e sensibilidades da rede inteira \(d\) vezes. A regra da cadeia explora o compartilhamento de cálculos intermediários.

Intuição — A Correnteza e o Eco

A Correnteza e o Eco

  • A Correnteza (Forward Pass): Os dados e pesos fluem das entradas até a perda escalar, aplicando operações atômicas sucessivas.
  • O Eco (Backward Pass): A perda gera um sinal de sensibilidade (\(\frac{\partial \mathcal{L}}{\partial \mathcal{L}} = 1\)) que viaja rio acima pelo mesmo caminho, retropropagando derivadas parciais.
  • Modularidade Local: Cada nó do grafo só precisa conhecer:
    1. O valor de suas entradas locais;
    2. Como calcular sua própria derivada local;
    3. Como multiplicar a derivada local pelo gradiente que vem de cima.

Bloco 1: Redes Neurais e a Reutilização de Computações

Recordando: Regras da Soma e da Cadeia

Regra da Soma (Linearidade)

  • Escalar: \[(u + v)' = u' + v'\]
  • Gradiente Vetorial: \[\nabla_{\mathbf{x}} (u + v) = \nabla_{\mathbf{x}} u + \nabla_{\mathbf{x}} v\]
  • Campos Vetoriais (Jacobianas): \[J_{\mathbf{u} + \mathbf{v}} = J_{\mathbf{u}} + J_{\mathbf{v}}\]

Regra da Cadeia (Composição)

  • Escalar Univariada: \[\frac{dy}{dx} = \frac{dy}{du} \frac{du}{dx}\]
  • Multivariada (Múltiplos Canais): \[\frac{dy}{dx} = \sum_{j=1}^m \frac{\partial y}{\partial u_j} \frac{\partial u_j}{\partial x}\]
  • Vetorial (Denominator Layout): \[\nabla_{\mathbf{x}} (g \circ \mathbf{f}) = J_{\mathbf{f}}(\mathbf{x})\, \nabla_{\mathbf{u}} g\]

O Motor do Backpropagation

Cada neurônio soma termos ponderados (Regra da Soma); cada camada compõe a anterior (Regra da Cadeia). O treino da rede orquestra ambas recursivamente!

Composição em Múltiplas Camadas

  • Composição Multinível: \[\hat{\mathbf{y}} = (f_K \circ f_{K-1} \circ \dots \circ f_1)(\mathbf{x}) = f_K\big(f_{K-1}(\dots(f_1(\mathbf{x}))\dots)\big)\]
  • A Estrutura de Cada Camada: \[f_i(\mathbf{x}_{i-1}) = \sigma(A_{i-1}\mathbf{x}_{i-1} + \mathbf{b}_{i-1})\]
  • O Objetivo: Encontrar parâmetros \(\boldsymbol{\theta} = \{A_0, \mathbf{b}_0, \dots, A_{K-1}, \mathbf{b}_{K-1}\}\) que minimizam: \[\mathcal{L}(\boldsymbol{\theta}) = \frac{1}{2}\|\mathbf{y} - f_K(\boldsymbol{\theta}, \mathbf{x})\|^2\]

Obtenção dos Gradientes em Cadeia

\[\begin{aligned} \frac{\partial \mathcal{L}}{\partial \boldsymbol{\theta}_{K-1}} &= \frac{\partial \mathcal{L}}{\partial f_K} \frac{\partial f_K}{\partial \boldsymbol{\theta}_{K-1}} \\ \frac{\partial \mathcal{L}}{\partial \boldsymbol{\theta}_{K-2}} &= \frac{\partial \mathcal{L}}{\partial f_K} \frac{\partial f_K}{\partial f_{K-1}} \frac{\partial f_{K-1}}{\partial \boldsymbol{\theta}_{K-2}} \\ \frac{\partial \mathcal{L}}{\partial \boldsymbol{\theta}_{K-3}} &= \frac{\partial \mathcal{L}}{\partial f_K} \frac{\partial f_K}{\partial f_{K-1}} \frac{\partial f_{K-1}}{\partial f_{K-2}} \frac{\partial f_{K-2}}{\partial \boldsymbol{\theta}_{K-3}} \\ &\;\;\vdots \\ \frac{\partial \mathcal{L}}{\partial \boldsymbol{\theta}_i} &= \underbrace{\left( \frac{\partial \mathcal{L}}{\partial f_K} \frac{\partial f_K}{\partial f_{K-1}} \dots \frac{\partial f_{i+2}}{\partial f_{i+1}} \right)}_{\text{Prefixo já computado para a camada } i+1} \frac{\partial f_{i+1}}{\partial \boldsymbol{\theta}_i} \end{aligned}\]

Reutilização de Computações

Pontos-Chave do Backpropagation

  • Reaproveitamento: Se já calculamos \(\frac{\partial \mathcal{L}}{\partial \boldsymbol{\theta}_{i+1}}\), a maior parte da computação pode ser reutilizada para calcular \(\frac{\partial \mathcal{L}}{\partial \boldsymbol{\theta}_i}\).
  • Custo Amortizado: Não recalculamos a cadeia desde a foz \(\mathcal{L}\) para cada parâmetro; acumulamos o sinal de trás para frente em um único passe linear.
  • Termos Adicionais: A cada camada retrocedida, apenas multiplicamos pelo Jacobiano de transição local.

Backpropagation: Sensibilidade da Saída (\(\boldsymbol{\delta}^{(L)}\))

Sensibilidade Pré-Sináptica

Definimos o vetor de erro pré-sináptico de cada camada \(l\) como o gradiente: \[\boldsymbol{\delta}^{(l)} := \nabla_{\mathbf{z}^{(l)}} \mathcal{L} \in \mathbb{R}^{d_l}\]

  • Regra da Cadeia na Saída: Como \(\mathbf{a}^{(L)} = \sigma(\mathbf{z}^{(L)})\), \[\frac{\partial \mathcal{L}}{\partial z_j^{(L)}} = \frac{\partial \mathcal{L}}{\partial a_j^{(L)}} \frac{\partial a_j^{(L)}}{\partial z_j^{(L)}} = \frac{\partial \mathcal{L}}{\partial a_j^{(L)}} \, \sigma'(z_j^{(L)})\]
  • Gradiente Vetorial com Produto de Hadamard (\(\odot\)): \[\boldsymbol{\delta}^{(L)} = \nabla_{\mathbf{z}^{(L)}} \mathcal{L} = \nabla_{\mathbf{a}^{(L)}}\mathcal{L} \odot \sigma'(\mathbf{z}^{(L)}) \in \mathbb{R}^{d_L}\]
  • Caso da Perda Quadrática \(\mathcal{L} = \frac{1}{2}\|\mathbf{a}^{(L)} - \mathbf{y}\|^2\): \[\nabla_{\mathbf{a}^{(L)}}\mathcal{L} = \mathbf{a}^{(L)} - \mathbf{y} \implies \boldsymbol{\delta}^{(L)} = (\mathbf{a}^{(L)} - \mathbf{y}) \odot \sigma'(\mathbf{z}^{(L)})\]

Backpropagation: Propagação Retrógrada (\(\boldsymbol{\delta}^{(l)}\))

  • Gradiente em Relação às Ativações \(\mathbf{a}^{(l)}\): Como \(\mathbf{z}^{(l+1)} = W^{(l+1)}\mathbf{a}^{(l)} + \mathbf{b}^{(l+1)}\), \[\frac{\partial \mathcal{L}}{\partial a_j^{(l)}} = \sum_{k=1}^{d_{l+1}} \frac{\partial \mathcal{L}}{\partial z_k^{(l+1)}} \frac{\partial z_k^{(l+1)}}{\partial a_j^{(l)}} = \sum_{k=1}^{d_{l+1}} \delta_k^{(l+1)} W_{kj}^{(l+1)} = \left((W^{(l+1)})^T \boldsymbol{\delta}^{(l+1)}\right)_j\] Logo: \(\nabla_{\mathbf{a}^{(l)}}\mathcal{L} = (W^{(l+1)})^T \boldsymbol{\delta}^{(l+1)} \in \mathbb{R}^{d_l}\).
  • Recuo até a Pré-Ativação \(\mathbf{z}^{(l)}\): Atravessando a ativação \(\mathbf{a}^{(l)} = \sigma(\mathbf{z}^{(l)})\): \[\boldsymbol{\delta}^{(l)} := \nabla_{\mathbf{z}^{(l)}}\mathcal{L} = \nabla_{\mathbf{a}^{(l)}}\mathcal{L} \odot \sigma'(\mathbf{z}^{(l)}) = \left( (W^{(l+1)})^T \boldsymbol{\delta}^{(l+1)} \right) \odot \sigma'(\mathbf{z}^{(l)})\]
  • O Papel da Transposta \((W^{(l+1)})^T\):
    • Operador adjunto linear que projeta o erro de \(\mathbb{R}^{d_{l+1}}\) de volta para \(\mathbb{R}^{d_l}\).
    • Se \(\sigma'(z_j^{(l)}) \approx 0\) (saturação), o sinal do gradiente é amortecido (vanishing gradient).

Backprop: Gradientes dos Parâmetros (\(W^{(l)}, \mathbf{b}^{(l)}\))

  • Gradiente do Peso Individual \(W_{jk}^{(l)}\): Como \(z_j^{(l)} = \sum_k W_{jk}^{(l)} a_k^{(l-1)} + b_j^{(l)}\), \[\frac{\partial \mathcal{L}}{\partial W_{jk}^{(l)}} = \frac{\partial \mathcal{L}}{\partial z_j^{(l)}} \frac{\partial z_j^{(l)}}{\partial W_{jk}^{(l)}} = \delta_j^{(l)} \, a_k^{(l-1)}\]
  • Gradiente Matricial dos Pesos (Produto Diádico / Posto 1): \[\nabla_{W^{(l)}}\mathcal{L} = \boldsymbol{\delta}^{(l)} (\mathbf{a}^{(l-1)})^T \in \mathbb{R}^{d_l \times d_{l-1}}\] Intuição: Cruza “o erro do neurônio \(j\)” (\(\delta_j^{(l)}\)) com “a ativação da entrada \(k\)” (\(a_k^{(l-1)}\)).
  • Gradiente dos Vieses: Como \(\frac{\partial z_j^{(l)}}{\partial b_j^{(l)}} = 1\), \[\nabla_{\mathbf{b}^{(l)}}\mathcal{L} = \boldsymbol{\delta}^{(l)} \in \mathbb{R}^{d_l}\]
  • Regra de Atualização no Gradiente Descendente: \[W^{(l)} \leftarrow W^{(l)} - \eta \, \nabla_{W^{(l)}}\mathcal{L}, \quad \mathbf{b}^{(l)} \leftarrow \mathbf{b}^{(l)} - \eta \, \nabla_{\mathbf{b}^{(l)}}\mathcal{L}\]

Pausa Ativa 2 — O Mecanismo da Retropropagação

Pergunta Aberta

Por que a propagação da sensibilidade de uma camada para a anterior multiplica a sensibilidade pela matriz transposta \((W^{(l+1)})^T\), e por que o gradiente do peso \(W^{(l)}\) tem a forma exata de um produto diádico \(\boldsymbol{\delta}^{(l)} (\mathbf{a}^{(l-1)})^T\)?

Álgebra do Backpropagation

Julgue V ou F — a questão só conta se acertar os 4 itens:

  • □ Em uma camada onde \(W^{(l)} \in \mathbb{R}^{3 \times 4}\), o produto diádico \(\boldsymbol{\delta}^{(l)} (\mathbf{a}^{(l-1)})^T\) gera uma matriz de dimensão \(3 \times 4\), perfeitamente compatível com a dimensão de \(W^{(l)}\).
  • □ Se um neurônio oculto estiver saturado na função sigmoide (isto é, \(|z^{(l)}_j| \gg 0\)), sua derivada local \(\sigma'(z^{(l)}_j) \approx 0\), bloqueando a passagem do gradiente para as camadas anteriores (desvanecimento do gradiente).
  • □ Para calcular os gradientes da camada 1, não é necessário armazenar as ativações intermediárias \(\mathbf{a}^{(1)}\) da passagem direta, pois o sinal de erro \(\boldsymbol{\delta}\) é auto-suficiente.
  • □ A complexidade temporal de calcular o gradiente de todos os pesos de uma rede densa via backpropagation analítico é assintoticamente da mesma ordem de grandeza da passagem direta.

Pausa Ativa 2 — Resposta

Álgebra do Backpropagation — Resposta

  • ✔ Verdadeiro: \(\boldsymbol{\delta} \in \mathbb{R}^{3 \times 1}\) e \(\mathbf{a}^T \in \mathbb{R}^{1 \times 4}\), logo o produto externo tem dimensão \(3 \times 4\).
  • ✔ Verdadeiro: Como \(\sigma'(z) = \sigma(z)(1-\sigma(z))\), quando \(z \to \pm \infty\), \(\sigma'(z) \to 0\), anulando o produto de Hadamard em \(\boldsymbol{\delta}\).
  • ✗ Falso: O gradiente \(\nabla_{W^{(2)}}\mathcal{L} = \boldsymbol{\delta}^{(2)}(\mathbf{a}^{(1)})^T\) exige explicitamente as ativações da passagem direta.
  • ✔ Verdadeiro: Cada peso é tocado exatamente uma vez na passagem direta e uma vez na passagem reversa (\(O(1)\) multiplicações por parâmetro).

Voltando à pergunta: A transposta \((W^{(l+1)})^T\) é o operador adjunto que mapeia o espaço de perturbação de saída de volta para o espaço de entrada da transformação linear. O produto diádico expressa que a taxa de variação da perda com relação ao peso \(W_{jk}\) é proporcional a “quanto o neurônio \(j\) precisava mudar” multiplicado por “quanto a entrada \(k\) contribuiu”.

Bloco 2: Paradigmas de Diferenciação e Grafos de Computação

Os Quatro Paradigmas de Diferenciação

O que é \(C_{\text{eval}}\)?

\(C_{\text{eval}}\) (Cost of Evaluation) é o custo computacional (tempo / operações) para avaliar a função \(f(\mathbf{x})\) para a frente uma única vez (forward pass).

  • 1. Manual: Deduzir à mão no papel.
    • Gargalo: Inviável para redes com dezenas de camadas ou conexões residuais dinâmicas.
  • 2. Numérico (Diferenças Finitas): \(f'(x) \approx \frac{f(x+h)-f(x)}{h}\).
    • Gargalo: Exige \(d\) avaliações diretas completas (\(\mathcal{O}(d \cdot C_{\text{eval}})\)) e sofre de cancelamento subtrativo catastrófico.
  • 3. Simbólico: Manipulação de árvores algébricas de fórmulas.
    • Gargalo: Inchaço de Expressões (Expression Swell) \(\mathcal{O}(2^d)\) por duplicação de subexpressões.
  • 4. Automático (Autodiff):
    • Aplica a regra da cadeia numericamente sobre variáveis intermediárias em tempo de execução.
    • Exato até a precisão da máquina, sem aproximação numérica e sem explosão simbólica.

Catálogo de Derivadas Simbólicas Pré-Computadas

Como a Autodiff Opera

O sistema não deduz derivadas: ele possui uma tabela pré-programada de derivadas locais analíticas para cada operação atômica.

  • Adição (\(z = x + y\)): \(\frac{\partial z}{\partial x} = 1, \quad \frac{\partial z}{\partial y} = 1\)
  • Multiplicação (\(z = x \cdot y\)): \(\frac{\partial z}{\partial x} = y, \quad \frac{\partial z}{\partial y} = x\)
  • Potência (\(z = x^k\)): \(\frac{\partial z}{\partial x} = k x^{k-1}\)
  • Exponencial (\(z = \exp(x)\)): \(\frac{\partial z}{\partial x} = \exp(x)\)
  • Cosseno (\(z = \cos(x)\)): \(\frac{\partial z}{\partial x} = -\sin(x)\)
  • Raiz (\(z = \sqrt{x}\)): \(\frac{\partial z}{\partial x} = \frac{1}{2\sqrt{x}}\)
  • Sigmoide (\(z = \sigma(x)\)): \(\frac{\partial z}{\partial x} = z(1-z)\)

O Segredo da Adição no Backward Pass

Como \(\frac{\partial (x+y)}{\partial x} = 1\) e \(\frac{\partial (x+y)}{\partial y} = 1\), a adição age como um roteador neutro: ela replica o gradiente recebido \(\bar{z}\) integralmente para ambas as entradas (\(\bar{x} = \bar{z}, \bar{y} = \bar{z}\)).

Variáveis Intermediárias e o Grafo de Computação

\[f(x) = \sqrt{x^2 + \exp(x^2)} + \cos(x^2 + \exp(x^2))\]

Decomposição em Variáveis:

  • \(a = x^2\)
  • \(b = \exp(a)\)
  • \(c = a + b\)
  • \(d = \sqrt{c}\)
  • \(e = \cos(c)\)
  • \(f = d + e\)

O Grafo Computacional

  • Nós: Variáveis intermediárias (\(a, b, c, d, e, f\)).
  • Arestas: Operações atômicas com derivadas locais conhecidas da tabela.

Acúmulo em Bifurcações: Regra da Cadeia Reversa

  • Passo 1 (Adição Final): \(\frac{\partial f}{\partial d} = 1, \quad \frac{\partial f}{\partial e} = 1\).
  • Passo 2 (Bifurcação em \(c\)): Como \(c\) afeta tanto \(d\) quanto \(e\), somamos os caminhos: \[\frac{\partial f}{\partial c} = \frac{\partial f}{\partial d}\frac{\partial d}{\partial c} + \frac{\partial f}{\partial e}\frac{\partial e}{\partial c} = 1 \cdot \frac{1}{2\sqrt{c}} - \sin(c)\]
  • Passo 3 (Bifurcação em \(a\)): \(a\) afeta \(b\) e alimenta \(c\) diretamente: \[\frac{\partial f}{\partial a} = \frac{\partial f}{\partial b}\frac{\partial b}{\partial a} + \frac{\partial f}{\partial c}\frac{\partial c}{\partial a} = \frac{\partial f}{\partial b}\exp(a) + \frac{\partial f}{\partial c} \cdot 1\]
  • Passo 4 (Entrada \(x\)): \(\frac{\partial f}{\partial x} = \frac{\partial f}{\partial a}(2x)\).

Regra Geral em DAGs

\[\bar{x}_i := \frac{\partial f}{\partial x_i} = \sum_{x_j \in \text{Filhos}(x_i)} \bar{x}_j \, \frac{\partial x_j}{\partial x_i}\] Cada nó acumula a soma ponderada de todos os nós que ele alimenta diretamente!

Pausa Ativa 3 — Grafos de Computação

Pergunta Aberta

Se um nó intermediário em um grafo de computação possui 3 arestas de saída (alimenta 3 variáveis subsequentes), por que a sua sensibilidade total acumulada é estritamente a soma das sensibilidades parciais que retornam de cada aresta, e o que aconteceria com o cálculo se uma biblioteca esquecesse de somar e simplesmente sobrescrevesse o valor do gradiente?

Propriedades dos Grafos de Autodiff

Julgue V ou F — a questão só conta se acertar os 4 itens:

  • □ O motor de diferenciação automática não precisa aplicar regras de cálculo simbólico em tempo de execução para cada programa: ele apenas avalia numericamente as derivadas de um catálogo fechado de operações atômicas pré-programadas.
  • □ A regra da adição \(z = x + y\) atua no backward pass como um divisor idêntico de fluxo, propagando o gradiente \(\bar{z}\) integralmente para ambas as variáveis \(x\) e \(y\) (\(\bar{x} = \bar{z}\) e \(\bar{y} = \bar{z}\)).
  • □ Em um nó com múltiplas arestas de saída (bifurcação), substituir o operador de acúmulo += por atribuição simples = preserva a correção do gradiente desde que as variáveis sejam processadas em ordem alfabética.
  • □ A diferenciação automática evita o inchaço de expressões (expression swell) porque nunca constrói a fórmula algébrica simbólica expandida global da derivada no papel.

Pausa Ativa 3 — Resposta

Propriedades dos Grafos de Autodiff — Resposta

  • ✔ Verdadeiro: O catálogo de derivadas primitivas é fixo na implementação (C++/CUDA/Python); a autodiff apenas conecta numericamente as regras locais via cadeia.
  • ✔ Verdadeiro: Como \(\frac{\partial (x+y)}{\partial x} = 1\) e \(\frac{\partial (x+y)}{\partial y} = 1\), a adição não atenua nem altera o gradiente.
  • ✗ Falso: Atribuição simples = sobrescreveria o sinal de erro de um dos caminhos, violando a regra da cadeia multivariada (que exige a soma de todos os caminhos incidentes).
  • ✔ Verdadeiro: A autodiff avalia números intermediários diretamente em tempo de execução, contornando a explosão exponencial de termos.

Voltando à pergunta: A regra da cadeia multivariada estabelece que a variação total na saída provocada por uma perturbação no nó é a soma das variações propagadas por cada caminho independente. Sobrescrever o gradiente ignoraria os efeitos de um dos ramos, gerando direções de descida matematicamente erradas e impedindo a convergência da rede.

Bloco 3: Modos de Diferenciação Automática: Forward vs. Reverse

A Dualidade: Associatividade da Regra da Cadeia

Seja uma composição de \(K\) transformações multivariadas: \[\mathbf{x}_0 \xrightarrow{\mathbf{f}_1} \mathbf{x}_1 \xrightarrow{\mathbf{f}_2} \dots \xrightarrow{\mathbf{f}_K} \mathbf{x}_K\]

A Jacobiana total é o produto de matrizes: \[J = J_K \cdot J_{K-1} \cdots J_2 \cdot J_1\]

O Teorema da Associatividade

A multiplicação matricial é associativa: \((A B) C = A (B C)\).

  • Ambos os modos alcançam o mesmo resultado exato.
  • A escolha dos parênteses determina se fazemos produtos Matriz \(\times\) Vetor ou Vetor \(\times\) Matriz!

Modo Forward (Tangente / Pushforward / JVP)

  • Parentização à Direita: \[J \cdot \mathbf{v} = J_K \Big( \dots \big( J_2 ( J_1 \mathbf{v} ) \big) \Big)\]
  • Operação Atômica: Produto Matriz \(\times\) Vetor (Jacobian-Vector Product - JVP).
  • Semântica: Propaga perturbações direcionais \(\dot{\mathbf{x}}_i\) para frente, junto com o fluxo de dados.
  • Complexidade: Cada passagem obtém 1 coluna da Jacobiana: \[\text{Custo Total} = \mathcal{O}(d_{\text{in}} \cdot C_{\text{eval}})\] (exige \(d_{\text{in}}\) passagens diretas completas pelo grafo)

Modo Forward no Grafo Canônico

Semente de entrada: \(\dot{x} = 1\). Regra direta: \(\dot{v}_i = \sum_{p \in \text{Pais}(v_i)} \frac{\partial v_i}{\partial p} \dot{p}\).

Nó Primal Tangente (\(\dot{v}\))
\(a = x^2\) \(a = x^2\) \(\dot{a} = 2x \cdot \dot{x} = 2x\)
\(b = \exp(a)\) \(b = \exp(a)\) \(\dot{b} = \exp(a) \cdot \dot{a} = 2x \exp(x^2)\)
\(c = a + b\) \(c = a + b\) \(\dot{c} = 1\cdot\dot{a} + 1\cdot\dot{b} = 2x(1 + \exp(x^2))\)
\(d = \sqrt{c}\) \(d = \sqrt{c}\) \(\dot{d} = \frac{1}{2\sqrt{c}} \dot{c}\)
\(e = \cos(c)\) \(e = \cos(c)\) \(\dot{e} = -\sin(c) \dot{c}\)
\(f = d + e\) \(f = d + e\) \(\dot{f} = \dot{d} + \dot{e} = (\frac{1}{2\sqrt{c}} - \sin(c))\dot{c} = \frac{\mathrm{d}f}{\mathrm{d}x}\)

Dualidade Topológica e Memória

  • Forward: Acumula soma nas convergências de entradas (pais de \(c\) e \(f\)).
  • Reverse: Acumula soma nas bifurcações de saídas (filhos de \(c\) e \(a\)).
  • Memória: Avaliação online \(\mathcal{O}(1)\) sem necessidade de fita (tape).

Modo Reverse (Adjunto / Pullback / VJP)

  • Parentização à Esquerda: \[\mathbf{u}^T \cdot J = \Big( \big( ( \mathbf{u}^T J_K ) J_{K-1} \big) \dots \Big) J_1\]
  • Operação Atômica: Produto Vetor \(\times\) Matriz (Vector-Jacobian Product - VJP).
  • Semântica: Propaga sensibilidades \(\bar{\mathbf{x}}_i\) para trás, no sentido inverso aos dados.
  • Complexidade: Cada passagem obtém 1 linha da Jacobiana: \[\text{Custo Total} = \mathcal{O}(d_{\text{out}} \cdot C_{\text{eval}})\]
  • Em ML (\(\mathcal{L} \in \mathbb{R}\)): \(d_{\text{out}} = 1 \implies\) Uma única passagem reversa computa todos os gradientes com custo \(\mathcal{O}(C_{\text{eval}})\)!

Teorema de Baur-Strassen (1983)

Teorema de Baur-Strassen / Speelpenning

Para qualquer função escalar \(f: \mathbb{R}^n \to \mathbb{R}\) computável em tempo \(C_{\text{eval}}\) (passagem direta): \[C_{\text{grad}} \le 5 \cdot C_{\text{eval}}\] independentemente do número de parâmetros \(n\).

  • Obter o gradiente de 100 bilhões de parâmetros custa no máximo \(5\times\) o custo \(C_{\text{eval}}\) de avaliar a rede para frente uma única vez.
  • Se usássemos modo forward ou diferenças finitas para 100 bilhões de parâmetros, o treinamento exigiria 100 bilhões de passagens diretas.

De Onde Vem o Fator 5 em Baur-Strassen?

Intuição Algébrica: Contagem de Operações por Nó

O custo total é a soma do Forward Pass (\(1 \cdot C_{\text{eval}}\)) com o Backward Pass (\(\le 4 \cdot C_{\text{eval}}\)).

Na Passagem Direta (1 op)

Para uma multiplicação \(v_i = v_j \cdot v_k\): - Custo no forward: 1 operação (\(\times\)).

Na Passagem Reversa (\(\le 4\) ops)

Atualizar os pais \(\bar{v}_j\) e \(\bar{v}_k\): - \(\bar{v}_j \mathrel{+}= \bar{v}_i \cdot v_k\) (1 mult + 1 soma = 2 ops) - \(\bar{v}_k \mathrel{+}= \bar{v}_i \cdot v_j\) (1 mult + 1 soma = 2 ops) - Custo no backward: \(2 + 2 = 4\) operações.

Total: \(C_{\text{forward}} + C_{\text{backward}} \le 1 + 4 = 5\)

\[C_{\text{grad}} \le C_{\text{eval}} + 4 \cdot C_{\text{eval}} = 5 \cdot C_{\text{eval}}\] Cada nó visitado no retorno faz no máximo 2 produtos e 2 somas para atualizar os erros de seus pais!

Critérios de Decisão: Forward vs. Reverse

Quando usar Forward?

  • Condição: \(d_{\text{in}} \ll d_{\text{out}}\)
  • Exemplo: Modelo generativo (\(z \in \mathbb{R}^{10} \to y \in \mathbb{R}^{10^6}\)).
  • Vantagem de Memória: \(\mathcal{O}(1)\) — descarta valores logo após usá-los.

Quando usar Reverse?

  • Condição: \(d_{\text{in}} \gg d_{\text{out}}\)
  • Exemplo: Treinamento de Redes Neurais (\(\mathcal{L} \in \mathbb{R}\) com milhões de pesos).
  • Custo de Memória: \(\mathcal{O}(L)\) — congela todas as ativações intermediárias na VRAM.

Síntese Unificadora

O algoritmo clássico de Backpropagation deduzido no Bloco 1 nada mais é do que o Modo Reverse de Diferenciação Automática aplicado à topologia específica de uma rede neural estruturada em camadas!

Pausa Ativa 4 — Modos Forward vs. Reverse

Pergunta Aberta

Imagine que você está projetando o sistema de controle de um braço robótico que recebe 3 ângulos de junta motora \(\boldsymbol{\theta} \in \mathbb{R}^3\) e calcula a trajetória espacial de 50 pontos da estrutura \(\mathbf{p} \in \mathbb{R}^{150}\). Você precisa da matriz Jacobiana completa \(\frac{\partial \mathbf{p}}{\partial \boldsymbol{\theta}} \in \mathbb{R}^{150 \times 3}\) a cada ciclo de controle de 1 milissegundo. Qual modo de autodiff você deve adotar e por quantas passagens pelo grafo?

Comparação entre os Modos de Autodiff

Julgue V ou F — a questão só conta se acertar os 4 itens:

  • □ Ambos os modos Forward e Reverse produzem exatamente a mesma matriz Jacobiana numérica, decorrendo da propriedade de associatividade da multiplicação matricial \((AB)C = A(BC)\).
  • □ O modo forward requer menos memória de execução que o modo reverso, pois pode descartar variáveis intermediárias da memória assim que seus nós dependentes imediatos forem avaliados.
  • □ Para treinar uma rede neural profunda com 1 milhão de pesos e função de perda escalar, o modo forward e o modo reverso demandam assintoticamente o mesmo número de operações de ponto flutuante.
  • □ O Teorema de Baur-Strassen garante que, para qualquer função escalar, o vetor gradiente completo pode ser calculado em no máximo cerca de 5 vezes o tempo de uma única passagem direta.

Pausa Ativa 4 — Resposta

Comparação entre os Modos de Autodiff — Resposta

  • ✔ Verdadeiro: A associatividade garante a identidade algébrica exata das expressões.
  • ✔ Verdadeiro: O modo forward descarta valores imediatamente; o modo reverso congela ativações até o retorno.
  • ✗ Falso: O modo forward exigiria 1 milhão de passagens pela rede; o modo reverso obtém todos os gradientes em um único passe!
  • ✔ Verdadeiro: O limitante superior \(5 C_{\text{eval}}\) é uma garantia teórica universal para funções escalares.

Voltando à pergunta: Como \(d_{\text{in}} = 3\) e \(d_{\text{out}} = 150\), a dimensão de entrada é muito menor que a de saída (\(d_{\text{in}} \ll d_{\text{out}}\)). O Modo Forward é a escolha ideal, exigindo apenas 3 passagens pelo grafo (uma para cada junta), com consumo mínimo de memória e sem necessidade de armazenar fita de execução. O modo reverso exigiria 150 passagens!

Fechamento

Retomando as Quatro Perguntas

  • 1. Reuso de Computações: O Backpropagation reaproveita os prefixos de derivadas anteriores via recorrência \(\boldsymbol{\delta}^{(l)} = (W^{T} \boldsymbol{\delta}) \odot \sigma'\) e produto diádico \(\nabla_W \mathcal{L} = \boldsymbol{\delta} \mathbf{a}^T\).
  • 2. Catálogo Atômico e DAGs: Decomposição em variáveis intermediárias avalia derivadas exatas sem inchaço simbólico e sem erro numérico.
  • 3. Acúmulo em Bifurcações: A sensibilidade de nós com múltiplos filhos é a soma de todos os caminhos; a adição opera como roteador perfeito de fluxo.
  • 4. Forward vs. Reverse e Baur-Strassen: Associatividade define JVPs vs VJPs; para perdas escalares (\(d_{\text{out}}=1\)), o modo reverso obtém o gradiente completo de bilhões de parâmetros em tempo \(\le 5 C_{\text{eval}}\).

Fechamento do Bloco 2

A Jornada do Bloco 2 Concluída

  1. Aula 6: Gradientes e Jacobianos (sensibilidade direcional).
  2. Aula 7: Hessiana e Convexidade (garantias globais vs pontos críticos).
  3. Aula 8: Gradient Descent e o Lema da Descida em modelos lineares.
  4. Aula 9: Redes Neurais, Regra da Cadeia e o Motor de Autodiff.

O Próximo Desafio: Como treinar quando avaliar o grafo completo para todas as \(N\) amostras é lento demais?

Próximos Passos: Bloco 3

Aula 10: Gradiente Descendente Estocástico (SGD) e Mini-Batching

  • Como substituir o somatório sobre \(N\) amostras por mini-batches estocásticos.
  • O compromisso entre variância do gradiente e vazão computacional na GPU.
  • E a seguir: Modelos de curvatura de Taylor de 2ª ordem para Momento e Métodos de Newton!

Exercícios Soluções