9. Deep Learning
Empilhar mais camadas não é uma decisão quantitativa. É uma aposta de que aquilo que você está modelando é composicional — que "um rosto" é feito de partes, que são feitas de bordas, que são feitas de pixels — e de que uma rede espelhando essa estrutura precisa de menos parâmetros do que uma que não a espelha.
O capítulo de MLP já disse que uma única camada oculta aproxima qualquer função contínua. Ou seja, profundidade não é sobre o que uma rede consegue representar; é sobre com que eficiência ela representa e sobre se você consegue de fato treinar a coisa depois de funda.
Este capítulo é sobre a conta que vem junto com a aposta. Tudo aqui responde a uma pergunta só: o que quebra quando se empilham camadas e o que foi inventado para consertar?
O sinal precisa sobreviver à viagem
Antes de qualquer treino, antes de qualquer dado, uma rede profunda precisa levar um sinal da entrada até a saída e um gradiente de volta. Os dois atravessam \(L\) matrizes de pesos e cada travessia multiplica o tamanho deles por algum fator — então o que chega é um produto de \(L\) fatores. Um produto de muitos números faz uma de duas coisas: vai a zero, ou vai ao infinito. Ficar perto de 1 é a exceção e você tem de construí-la.
O painel abaixo monta uma rede da profundidade que você escolher, roda uma passagem de ida e uma de volta na inicialização — sem treino nenhum — e acompanha as duas viagens.
Primeiro, o que está no eixo vertical. Chame de \(a\) o valor que uma unidade produz e de \(g\) a derivada da perda em relação à saída daquela camada. Cada camada tem 48 unidades e o lote tem 32 amostras, então em cada camada existem \(48 \times 32\) valores de \(a\) e outros tantos de \(g\). O painel resume cada camada em um número, a média dos quadrados:
O quadrado está aí para medir tamanho típico sem que valores positivos e negativos se cancelem — é a mesma quantidade das contas de Xavier e He da próxima seção. Um \(\mathbb{E}[a^2]\) de 100 quer dizer ativações da ordem de 10; de \(10^{-6}\), da ordem de 0,001.
Agora as duas viagens:
- À esquerda, a ida. O sinal entra na camada 1 e segue para a direita. A curva é o \(\mathbb{E}[a^2]\) de cada camada dividido pelo da camada 1, então ela parte de ① na ponta esquerda, valendo 1 por construção. O número que importa é o ② da ponta direita: quantas vezes maior ou menor o sinal chegou ao fim.
- À direita, a volta. O gradiente nasce na perda — depois da última camada — e caminha de volta até a camada 1. Para que a curva siga essa direção, o eixo desse gráfico está invertido: a última camada fica à esquerda e a camada 1 à direita. Assim os dois painéis se leem igual, da esquerda para a direita, de ① a ② — só a numeração das camadas corre ao contrário. A curva é o \(\mathbb{E}[g^2]\) de cada camada dividido pelo da última; o ② é o que sobrou de gradiente para as primeiras camadas.
Nos dois lados 1 quer dizer que nada se perdeu nem se amplificou: é a linha tracejada. A faixa verde em volta dela vai de 0,1× a 10×. O eixo é logarítmico e cobre sempre 12 ordens de grandeza, então uma reta inclinada quer dizer crescimento exponencial e a mesma inclinação quer dizer o mesmo fator em qualquer configuração. Ele parte do 1 e se estende para o lado em que os dados vão — para cima quando o sinal explode, para baixo quando morre, para os dois quando oscila em volta de 1. Os dois painéis usam sempre o mesmo intervalo. Quando a curva passa desses limites ela vira pontilhada, colada na borda, com uma seta onde saiu — o valor continua crescendo, só não cabe mais no desenho; o rótulo ② diz onde ele foi parar. As linhas finas são cinco redes sorteadas com pesos diferentes; a grossa é a média geométrica delas.
Seis experimentos e eles são o capítulo em ordem:
- ReLU, inicialização ingênua, 30 camadas — o estado em que o painel abre. Pesos sorteados de \(\mathcal{N}(0,1)\): o sinal chega à última camada \(10^{39}\) vezes maior e o gradiente chega à primeira igualmente inflado. As duas curvas saem do gráfico. Em amplitude — a raiz quadrada — as ativações ficam cerca de \(5 \cdot 10^{19}\) vezes maiores: o float32 ainda as comporta, mas uma perda quadrática passa do limite de \(3{,}4 \cdot 10^{38}\) e sai
inf; em float16, cujo limite é 65 504, a ida estoura muito antes da última camada. - Troque para Xavier. A explosão some e agora as duas curvas descem em linha reta: o sinal perde metade a cada camada e termina entre \(10^{-9}\) e \(10^{-10}\) depois de 30, enquanto o gradiente chega à camada 1 igualmente encolhido. Metade das saídas da ReLU é zero e metade da variância vai junto — a Xavier foi derivada para ativações simétricas e não sabe disso.
- Troque para He. As curvas grossas ficam dentro da faixa verde: a variância se mantém em média. Repare nas linhas finas, porém: uma rede sorteada pode terminar com o sinal em 1/200 do início ou em 1,5×. A conta \(\mathbb{E}[z^2] = n\sigma^2\,\mathbb{E}[a^2]\) da próxima seção é uma média sobre todos os sorteios de pesos; uma rede de 48 unidades é um sorteio e o desvio se acumula camada a camada. Mesmo assim a distância para os dois experimentos anteriores é de dezenas de ordens de grandeza — o fator dois na variância inicial é o que separa uma rede que treina de uma que não treina.
- Ligue as conexões residuais. Agora as duas curvas explodem, o sinal para ~\(10^{13}\) e o gradiente para ~\(10^{12}\). Cada bloco soma a própria saída à entrada, então a magnitude se acumula na ida; na volta, a derivada \(1 + \partial f/\partial a\) também passa de 1 em toda camada. O atalho sozinho não resolve e é por isso que blocos residuais nunca aparecem sozinhos.
- Escolha a normalização "depois da soma". É o bloco do Transformer original, de 2017: \(a \leftarrow \text{Norm}(a + f(a))\). O sinal fica cravado em 1 e o gradiente melhora muito, mas não se acerta: chega à camada 1 cerca de 150× maior com 30 camadas e mais de 1 000× com 40. O caminho de identidade agora atravessa um normalizador em cada camada e o estrago cresce com a profundidade.
- Troque para "dentro do ramo". É o pré-LN, \(a \leftarrow a + f(\text{Norm}(a))\), que os Transformers usam desde então. O gradiente fica em ~50× com 30 camadas e ~70× com 40: ir de 20 para 40 camadas multiplica o gradiente por menos de 3, contra quase 40 no pós-LN. O sinal passa a crescer, porque o fluxo residual acumula a contribuição de todos os blocos — mas mais ou menos com o quadrado da profundidade, não exponencialmente. Como cada bloco lê uma cópia normalizada do fluxo, o tamanho dele nunca chega à entrada de bloco nenhum. Para ver o quanto essa combinação é robusta, volte a inicialização para ingênua: com pré-LN o gradiente fica em ~130×; com pós-LN, em ~\(10^5\). O capítulo de Transformers conta o que essa troca mudou na prática.
Isso é decidido antes do primeiro passo de gradiente
Nada naquele painel é treinado. Uma rede pode nascer quebrada: com ReLU e Xavier em 30 camadas, o \(\mathbb{E}[a^2]\) da saída na inicialização é um bilionésimo do da primeira camada — a saída praticamente deixou de depender da entrada — e o gradiente chega às primeiras camadas encolhido na mesma proporção. A atualização dos pesos de uma camada é o gradiente que chega vezes a ativação que entra nela, então aqui o passo de todas as camadas sai dezenas de milhares de vezes menor que numa rede saudável (\(\sqrt{10^{-9}} \approx 3 \cdot 10^{-5}\)). E quando só um dos dois deriva — a normalização segurando o sinal enquanto o gradiente explode, como na seção de normalização adiante — as primeiras e as últimas camadas aprendem em escalas \(10^5\) vezes distantes e nenhuma taxa de aprendizado única serve às duas pontas. Confira a passagem de ida na inicialização antes de depurar o laço de treino.
Inicialização: duas linhas de conta, metade do problema
Pegue uma camada, \(z = Wa\) com \(n\) entradas, pesos sorteados de forma independente com variância \(\sigma^2\) e média zero. Então
Vale separar duas variâncias que a fórmula coloca lado a lado. O \(\sigma^2\) é a variância dos pesos — uma escolha sua, feita antes de qualquer dado existir. O \(\mathbb{E}[a^2]\) é o segundo momento das ativações, que depende dos dados. A conta acima liga as duas: escolher a variância dos pesos é escolher o que acontece com o tamanho das ativações, camada após camada.
O procedimento é este, executado uma vez por camada antes do treino:
- conte \(n\), o número de entradas de cada neurônio — o fan-in, que é o número de colunas de \(W\);
- sorteie cada peso separadamente de uma distribuição de média zero e variância \(\sigma^2\): uma normal \(\mathcal{N}(0, \sigma^2)\), ou uma uniforme em \([-\sqrt{3\sigma^2},\, +\sqrt{3\sigma^2}]\), que tem exatamente a mesma variância;
- zere os vieses.
Nenhum dado entra nessa conta — ela só olha para o formato da camada.
Para o sinal sobreviver à camada, você quer que o fator \(n\sigma^2\) valha 1, o que dá \(\sigma^2 = 1/n\) — a inicialização de Xavier (Glorot)1. Com ReLU, metade das saídas vira zero, então a própria ativação corta o segundo momento pela metade; compensar isso exige o dobro da variância, \(\sigma^2 = 2/n\) — a inicialização de He2.
| Ativação | Use | Por quê |
|---|---|---|
| tanh, sigmoide, ou qualquer ativação simétrica | Xavier / Glorot, \(\sigma^2 = 1/n\) | A ativação praticamente preserva o segundo momento perto de zero |
| ReLU e variantes | He, \(\sigma^2 = 2/n\) | A ReLU zera metade das saídas; o 2 paga por isso |
| A última camada de um bloco residual | Muitas vezes zero | Faz o bloco começar como identidade e uma pilha profunda começar como uma rasa |
O fator de uma camada e o que mexe nele
Vale dar nome ao número que a identidade acima produz. Cada camada multiplica o segundo momento por
onde \(\rho\) é a fração do segundo momento que a ativação deixa passar: exatamente \(\tfrac{1}{2}\) para a ReLU, que zera metade das saídas; no máximo 1 para a tanh, menos quanto mais ela satura.
Esse fator é o assunto do capítulo inteiro. Ele está desenhado no painel: a inclinação da reta é o \(\log_{10}\) do fator. É por isso que reta em gráfico logarítmico quer dizer exponencial — e é o número que o painel mostra no rodapé, medido, a cada configuração:
| configuração | fator na ida | na volta | \(n\sigma^2\rho\) previsto |
|---|---|---|---|
| ReLU, ingênua (\(\sigma^2 = 1\)) | 22,7 | 23,5 | 24 |
| ReLU, Xavier (\(\sigma^2 = 1/n\)) | 0,47 | 0,49 | 0,5 |
| ReLU, He (\(\sigma^2 = 2/n\)) | 0,95 | 0,98 | 1 |
| tanh, Xavier | 0,90 | 0,91 | 1 |
Nas três linhas de ReLU o fator medido fica os mesmos 5% abaixo do previsto na ida e 2% na volta. A previsão é uma média sobre os sorteios de pesos; o painel tira uma média geométrica de cinco redes e a média geométrica de uma quantidade que oscila fica abaixo da média comum — as linhas finas são essa oscilação. A linha da tanh se afasta mais por outro motivo: o \(\rho\) dela é menor que 1.
Cinco coisas mexem nele e as quatro primeiras estão nos controles do painel — a largura fica fixa em 48:
- A inicialização, de forma linear: é o \(\sigma^2\), o único termo que sai de graça.
- A ativação, pelo \(\rho\). Troque para tanh com He e o fator medido é 0,98, não os 2 previstos: os pesos maiores saturam a tanh, o \(\rho\) despenca e a conta simples deixa de valer.
- A largura \(n\), também linear — e é exatamente por isso que Xavier e He trazem \(n\) no denominador, para cancelá-la. Com a ingênua, \(\sigma^2 = 1\), ela não se cancela e o 24 da primeira linha é só \(48 \cdot \tfrac{1}{2}\).
- A arquitetura. O atalho residual soma o caminho da identidade ao do ramo e leva o fator para perto de 2,8 na ida e 2,6 na volta (experimento 4). A normalização depois da soma prende o fator da ida em 1,00 exato, mas deixa o da volta em 1,19.
- O treino, que muda os pesos e faz o fator derivar. A inicialização escolhe o ponto de partida; atalho e normalização é que o seguram.
A profundidade é o que não aparece nessa lista: numa pilha sem atalhos ela não muda o fator, ela o eleva a \(L\). Um fator de 0,95 é inofensivo em 5 camadas e vale \(10^{-7}\) em 300.
Fan-in ou fan-out?
O \(n\) acima é o fan-in, que é o que controla a ida. A volta atravessa \(W^\top\) e pede o fan-out, o número de saídas. Quando os dois diferem não dá para satisfazer os dois; o artigo original da Xavier propõe o meio-termo \(\sigma^2 = 2/(n_{\text{in}} + n_{\text{out}})\)1; o \(1/n\) só com o fan-in às vezes é chamado de inicialização de LeCun. No painel toda camada é 48 → 48, então as três coincidem. Para a He, o PyTorch deixa a escolha explícita em mode='fan_in' ou 'fan_out'; o padrão é fan_in.
Você já está usando uma delas — descubra qual
O torch.nn.Linear inicializa por padrão com kaiming_uniform_(a=√5), o que dá \(\mathcal{U}(-1/\sqrt{n},\, 1/\sqrt{n})\) — variância \(1/(3n)\), um sexto da He. Empilhado com ReLU, isso é um fator de cerca de \(\tfrac{1}{6}\) por camada, amortecido só pelos vieses. Quando uma rede profunda feita à mão não treina, imprimir o desvio padrão das ativações por camada na inicialização leva dois minutos e encerra a dúvida:
x = next(iter(loader))[0]
for name, layer in model.named_children():
x = layer(x)
print(f"{name:20s} std={x.std().item():.4f} mean={x.mean().item():+.4f}")
nn.Sequential. Se o desvio encolhe pela mesma fração a cada camada — ×0,71 é ReLU com Xavier, ×0,41 é ReLU com o padrão acima —, você achou o seu bug e ele não é a taxa de aprendizado. Conexões residuais: um caminho de identidade para o gradiente
A outra metade da correção muda a arquitetura. Em vez de pedir a um bloco que produza a próxima representação, peça que ele produza a mudança na representação atual3:
Derive e o motivo de funcionar fica visível:
O 1 é um caminho por onde o gradiente chega às primeiras camadas sem atenuação, faça o bloco o que fizer. Numa rede comum o gradiente é um produto de \(L\) jacobianas4. Um produto faz só duas coisas: com fator menor que 1 por camada ele morre exponencialmente — é a Xavier do painel, cujo gradiente é multiplicado por 0,49 por camada; com fator maior que 1 ele explode, como a ingênua, cujo fator previsto é \(n\sigma^2/2 = 24\) e o medido na volta, 23,5. Numa rede residual existe sempre uma rota que multiplica por um.
Esse 1, porém, é um piso e não um teto: ele impede o gradiente de desaparecer, não de crescer. O experimento 4 do painel é justamente isso — o atalho sozinho multiplica por cerca de 2,8 a cada bloco na ida e 2,6 na volta.
O diagrama mostra as duas passagens pelo mesmo bloco. Na ida, o atalho copia \(a_l\) e o soma à saída das camadas do bloco. Na volta, o gradiente \(g\) que chega da perda é copiado para os dois caminhos: pelas camadas ele é multiplicado por \(\partial f/\partial a_l\), que pode ser minúsculo; pelo atalho ele é multiplicado por 1. As duas parcelas voltam a se somar na entrada do bloco.
Há uma segunda leitura e para ensinar ela é a melhor: um bloco residual nasce como a função identidade, se \(f\) começa perto de zero. Acrescentar um bloco a uma rede treinada, portanto, não custa nada — a rede que você tinha continua lá dentro e o bloco só precisa aprender o que acrescentar. Profundidade deixa de ser risco e vira opção, que foi como uma rede de 152 camadas venceu uma de 193 em vez de desabar.
Uma conexão de atalho sozinha faz tudo explodir
Experimento 4 do painel: o \(\mathbb{E}[a^2]\) se acumula, porque cada bloco soma um termo de tamanho comparável ao que entrou — e o gradiente cresce junto na volta. Arquiteturas residuais sempre emparelham o atalho com uma normalização e o lugar dela importa: depois da soma (o Add & Norm de 2017) o caminho de identidade passa por um normalizador em cada camada; dentro do ramo (pré-LN) ele fica intocado. Os experimentos 5 e 6 mostram a diferença.
Normalização e onde ela mora neste curso
A terceira peça da resposta é a normalização, tratada com simulador próprio no capítulo de regularização: o que a BatchNorm calcula, por que treino e inferência são contas diferentes e por que os Transformers usam LayerNorm e não BatchNorm.
Numa rede profunda ela é feita camada a camada: há uma normalização dentro de cada bloco, repetida nas \(L\) camadas — não uma padronização única dos dados na entrada da rede. Duas perguntas costumam se misturar e o diagrama separa as duas. Onde ela entra no bloco é o que distingue o pós-LN do pré-LN dos experimentos 5 e 6. Sobre o quê ela calcula a média e o desvio é o que distingue a LayerNorm, que o painel usa sobre as 48 unidades de cada amostra, da BatchNorm, que usa o lote inteiro para cada unidade.
Dois fatos de lá importam para a profundidade e vale carregá-los:
- A normalização recentra e reescala o sinal a cada camada, que é a correção direta para a explosão acima e — junto com o atalho — a razão de pilhas muito profundas serem treináveis. Sozinha ela não basta: escolha "depois da soma" com as conexões residuais desligadas e o sinal fica em 1 enquanto o gradiente chega à camada 1 centenas de milhares de vezes maior. A volta divide o gradiente pelo mesmo desvio pelo qual a ida dividiu o sinal, só que esse desvio é calculado depois de tirar a média e a saída de uma ReLU é toda positiva: o desvio dela é menor que o tamanho dela e cada camada amplifica o gradiente por cerca de 1,5. Experimente as três inicializações ali — elas dão exatamente a mesma curva, porque o normalizador apaga a escala dos pesos.
- O efeito regularizador dela é um efeito colateral da composição do batch. É por isso que a LayerNorm, que não usa estatística de batch, normaliza igualmente bem e não tem esse efeito.
De que a profundidade é feita
Essas peças se combinam nas arquiteturas que ocupam o resto do curso:
| Arquitetura | A aposta estrutural | Onde é tratada |
|---|---|---|
| Feedforward (MLP) | Nada na entrada tem estrutura conhecida | Capítulo 5 |
| Convolucional | Entradas vizinhas se relacionam e o mesmo padrão importa em qualquer lugar | Capítulo 10 |
| Recorrente (LSTM/GRU) | A entrada é uma sequência e o passado importa através de um estado | Capítulo 11 |
| Transformer | Toda posição pode depender de todas as outras e isso deve ser calculado em paralelo | Capítulos 11–12 |
| Autoencoder | Os dados vivem numa variedade de dimensão menor | Capítulo 17 |
| GAN | O que é realista é mais fácil de julgar do que de especificar | Capítulo 18 |
O padrão por trás de todas elas
As camadas por trás das quatro primeiras linhas são restrições sobre os pesos, não capacidade extra: uma convolução é uma camada densa cujos pesos são compartilhados e quase todos zero; a atenção é uma camada densa cujos pesos são calculados a partir da entrada. As duas últimas apostam em outro lugar — o autoencoder num gargalo, a GAN no objetivo. Cada uma codifica uma hipótese sobre os dados e — exatamente como no capítulo de regularização — uma boa hipótese vale mais do que mais parâmetros.
Pontos-chave
- Profundidade é uma aposta de que o problema é composicional. Uma única camada larga já aproxima qualquer coisa; profundidade é sobre fazer isso com eficiência.
- O que quebra primeiro não é a acurácia, é a aritmética: sinal e gradiente são produtos de \(L\) termos e produtos ou somem ou explodem.
- Isso é visível na inicialização, antes de qualquer treino. Confira as estatísticas de ativação por camada antes de culpar o otimizador.
- Xavier (\(1/n\)) para ativações simétricas, He (\(2/n\)) para ReLU. O fator dois não é detalhe: em 30 camadas ele é a diferença entre \(10^{-9}\) e algo da ordem de \(1\) — em média, porque uma rede finita é um sorteio e se desvia dela.
- Conexões residuais dão ao gradiente um caminho de identidade — \(1 + \partial f/\partial a\) — e deixam um bloco começar como identidade, o que torna a profundidade opcional em vez de arriscada.
- Um atalho sozinho faz sinal e gradiente crescerem; ele vem sempre acompanhado de normalização e o lugar dela importa. Depois da soma (pós-LN) o gradiente piora exponencialmente com a profundidade; dentro do ramo (pré-LN, o padrão atual) ele quase não piora.
- Arquiteturas são hipóteses — quase sempre expressas como restrições nos pesos —, não capacidade extra.
Recursos adicionais
- Dive into Deep Learning — Zhang, A., et al. (2020). Livro aberto, com o código ao lado de cada dedução.
- Deep Learning — Goodfellow, I., Bengio, Y., & Courville, A. (2016). A referência canônica da área.
- The Little Book of Deep Learning — Fleuret, F. Cem páginas, para quem quer o essencial em uma sentada.
- A Survey of Deep Learning: From Activations to Transformers — Schneider, J., & Vlachos, M. (2024). Um mapa das ideias que ficaram, com a linhagem de cada uma.
Onde cada camada é tratada
Este capítulo é sobre o que acontece quando se empilha muita coisa: o que sobrevive à viagem, o que some e o que precisa ser construído para que a profundidade valha alguma coisa. A aritmética de cada tipo de camada — a ida, a volta e um exemplo com números — mora no capítulo que ensina aquela camada, cada um com o simulador correspondente:
| Camada | Onde | O que você encontra lá |
|---|---|---|
| Densa, ativações e retropropagação | capítulo 5 | a cadeia inteira em uma rede 2→2→1, com um passo de treino interativo |
| Convolução e pooling | capítulo 10 | os três gradientes, a convolução full com números e o roteamento do max pooling |
| Normalização e dropout | capítulo 7 | treino contra inferência, a passagem reversa da batch norm e o \(1/(1-p)\) |
| Embedding, atenção e recorrência | capítulo 11 | gradiente esparso, a jacobiana do softmax e por que a RNN perdeu |
-
Glorot, X., & Bengio, Y. (2010). Understanding the difficulty of training deep feedforward neural networks — AISTATS. De onde vêm o argumento de preservação de variância e a inicialização \(1/n\). ↩↩
-
He, K., Zhang, X., Ren, S., & Sun, J. (2015). Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification — ICCV. Refaz a derivação de Glorot para a ReLU e chega ao fator dois. ↩
-
He, K., Zhang, X., Ren, S., & Sun, J. (2016). Deep Residual Learning for Image Recognition — CVPR. Reformula as camadas "como aprendendo funções residuais com referência às entradas da camada"; as redes chegam a 152 camadas, oito vezes mais fundas que a VGG e um ensemble atinge 3,57% de erro top-5 na ImageNet. ↩↩
-
Bengio, Y., Simard, P., & Frasconi, P. (1994). Learning long-term dependencies with gradient descent is difficult — IEEE Transactions on Neural Networks 5(2), 157–166. O problema do gradiente que desaparece, enunciado e analisado muito antes de existir conserto. ↩