Por que a inicialização importa (e o que pode dar errado)
Em redes profundas, os sinais (ativações) e os gradientes atravessam muitas camadas. Se, ao passar de uma camada para a próxima, a variância das ativações cresce um pouco a cada etapa, em poucas camadas ela explode; se diminui um pouco, ela colapsa para quase zero. O mesmo vale para os gradientes no caminho inverso. A inicialização define o “ponto de partida estatístico” do fluxo de informação e, por isso, influencia diretamente estabilidade, velocidade de convergência e até a capacidade de treinar camadas profundas.
Uma forma prática de pensar: cada camada aplica uma transformação linear seguida de uma não linearidade. Se os pesos forem muito grandes, a saída tende a ter magnitude grande (ativação pode saturar ou ficar com variância alta); se forem muito pequenos, a saída tende a ficar perto de zero (variância baixa). Em ambos os casos, o gradiente pode se tornar instável.
Objetivo da inicialização “boa”
- Manter a variância das ativações aproximadamente constante ao longo das camadas (no forward).
- Manter a variância dos gradientes aproximadamente constante ao longo das camadas (no backward).
- Quebrar simetria: neurônios não devem começar com pesos idênticos, senão aprendem a mesma coisa.
Intuição de Xavier/Glorot e He: preservando variância
Considere uma camada densa com entrada x e pesos W, produzindo z = W x. Se os elementos de W forem aleatórios com média zero e variância adequada, é possível manter a variância de z em um nível estável. A escolha da variância depende do número de conexões.
Xavier/Glorot (bom para ativações “simétricas”)
A inicialização de Xavier (também chamada Glorot) busca equilibrar a variância no forward e no backward usando o número de entradas e saídas da camada:
fan_in: número de entradas da camadafan_out: número de saídas da camada
Uma forma comum (normal):
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
W ~ Normal(0, 2 / (fan_in + fan_out))Ou uniforme:
W ~ Uniform(-a, a), a = sqrt(6 / (fan_in + fan_out))Ela costuma funcionar bem quando a ativação não “zera metade” do sinal (por exemplo, tanh em regimes não saturados) e em redes onde se busca preservar energia do sinal de forma equilibrada.
He/Kaiming (bom para ReLU e variantes)
Para ReLU e variantes, metade das ativações tende a ser zerada (em média), o que altera a variância efetiva. A inicialização de He compensa isso usando principalmente fan_in:
W ~ Normal(0, 2 / fan_in)Ou uniforme:
W ~ Uniform(-a, a), a = sqrt(6 / fan_in)Na prática, He é uma escolha padrão para redes profundas com ReLU/LeakyReLU/GELU (dependendo do framework, a variante exata pode mudar).
Viés (bias): regra prática
É comum inicializar o bias com zero. Em alguns casos específicos (por exemplo, portas em RNNs ou certos blocos), pode-se usar bias positivo para favorecer ativação inicial, mas em MLPs/CNNs padrão, bias = 0 é um ponto de partida seguro.
Problemas de gradiente: desaparecimento e explosão
Gradiente que desaparece (vanishing gradient)
O gradiente “encolhe” ao atravessar camadas no backward. Isso faz com que camadas iniciais aprendam muito lentamente (ou quase nada). Sintomas típicos:
- Treino estagna cedo: a loss para de cair rapidamente, mesmo com dados e modelo razoáveis.
- Camadas iniciais quase não mudam: normas de gradiente muito pequenas nas primeiras camadas.
- Ativações colapsadas: muitas ativações próximas de zero (ou em regiões pouco informativas), dependendo da arquitetura.
Causas comuns incluem inicialização inadequada (variância pequena), profundidade alta sem mecanismos de estabilização e combinações de ativação/arquitetura que reduzem o fluxo de gradiente.
Gradiente que explode (exploding gradient)
O gradiente cresce ao atravessar camadas, levando a atualizações gigantescas. Sintomas típicos:
- Loss vira NaN/Inf após algumas iterações.
- Oscilações fortes: loss sobe e desce violentamente, sem tendência clara.
- Norma do gradiente muito alta: picos grandes e frequentes.
- Pesos “disparam”: parâmetros crescem rapidamente em magnitude.
Causas comuns incluem inicialização com variância grande, taxa de aprendizado alta, ausência de normalização e, em alguns casos, dados com escalas muito diferentes sem padronização.
Normalização para estabilizar o treinamento (BatchNorm e LayerNorm)
Normalização em redes neurais busca controlar a distribuição interna dos sinais durante o treinamento. A ideia central é reduzir a sensibilidade do modelo a mudanças de escala e deslocamento nas ativações internas, o que tende a estabilizar gradientes e permitir taxas de aprendizado maiores.
Batch Normalization (BatchNorm): conceito
BatchNorm normaliza as ativações de uma camada usando estatísticas do mini-batch. Para um conjunto de ativações z (por canal/feature), ela calcula média e variância no batch e produz uma versão normalizada:
mu_B = mean(z) (no batch) sigma_B^2 = var(z) (no batch) z_hat = (z - mu_B) / sqrt(sigma_B^2 + eps) y = gamma * z_hat + betagamma e beta são parâmetros treináveis que permitem ao modelo recuperar escalas/deslocamentos úteis. O eps evita divisão por zero.
Como BatchNorm ajuda no forward e no backward (visão conceitual)
- No forward: mantém as ativações com média ~0 e variância ~1 (antes de
gamma/beta), reduzindo o risco de sinais ficarem muito grandes ou muito pequenos ao longo das camadas. - No backward: ao controlar a escala das ativações, tende a controlar também a escala dos gradientes associados, reduzindo explosões/colapsos. Além disso, a presença de
gammacria um “controle de ganho” aprendível.
Observação prática: BatchNorm depende do tamanho do batch. Batches muito pequenos tornam as estatísticas ruidosas, o que pode prejudicar estabilidade.
Layer Normalization (LayerNorm): conceito
LayerNorm normaliza usando estatísticas calculadas por amostra (ao longo das features da camada), em vez de ao longo do batch. Em termos conceituais:
- BatchNorm: normaliza “entre exemplos” (no batch) para cada feature/canal.
- LayerNorm: normaliza “dentro do exemplo” (na camada) ao longo das features.
Isso torna LayerNorm menos sensível ao tamanho do batch e muito usada em arquiteturas onde o batch pode ser pequeno ou variável (por exemplo, muitos modelos baseados em atenção).
Onde inserir normalização (regra prática)
- Em MLPs: frequentemente após a transformação linear e antes da ativação (padrão comum), mas há variações.
- Em CNNs: BatchNorm costuma ser aplicada após a convolução e antes da ativação.
- Em arquiteturas modernas: a posição exata pode variar (por exemplo, “pre-norm” vs “post-norm” em blocos), mas a motivação é sempre estabilizar o fluxo de sinal/gradiente.
Passo a passo prático: escolhendo inicialização e normalização
1) Identifique a ativação dominante
- Se a rede usa majoritariamente ReLU/variantes: prefira He.
- Se usa ativações mais “simétricas” (ou configurações onde Xavier é padrão): prefira Xavier/Glorot.
2) Defina uma configuração base estável
- Inicialização: He (ReLU) ou Xavier (outros casos).
- Normalização: BatchNorm (se batch razoável) ou LayerNorm (se batch pequeno/instável).
- Taxa de aprendizado: comece com valor conservador e aumente se o treino estiver estável.
3) Instrumente o treino para observar gradientes e ativações
Além de loss e métricas, acompanhe:
- Norma do gradiente (global e por camada).
- Distribuição de ativações (média/variância por camada).
- Distribuição de pesos (média/variância e crescimento ao longo do tempo).
Em muitos casos, apenas registrar a norma do gradiente por camada já revela onde o sinal está morrendo (muito pequeno) ou explodindo (muito grande).
4) Aplique intervenções incrementais
Evite mudar tudo ao mesmo tempo. Ajuste um fator, rode alguns ciclos e reavalie.
Diagnóstico: sinais em métricas e como intervir
| Sinal observado | Hipótese provável | Intervenções recomendadas |
|---|---|---|
| Loss vira NaN/Inf rapidamente | Gradiente explodindo; LR alta; instabilidade numérica | Reduzir LR; aplicar gradient clipping; revisar inicialização (He/Xavier correto); adicionar normalização; aumentar eps em normalizações se necessário |
| Loss oscila muito e não converge | LR alta; gradientes instáveis; batch ruidoso | Reduzir LR; usar scheduler; adicionar BatchNorm/LayerNorm; aumentar batch (se possível); clipping |
| Loss cai muito lentamente desde o início | Gradiente desaparecendo; inicialização “fraca”; normalização ausente | Trocar para He/Xavier adequado; adicionar normalização; aumentar LR com cuidado; revisar profundidade/largura |
| Camadas iniciais com gradiente ~0, camadas finais ok | Vanishing gradient nas primeiras camadas | Normalização; inicialização correta; reduzir profundidade ou usar arquitetura mais estável; ajustar LR; verificar saturação de ativações |
| Norma do gradiente tem picos esporádicos | Explosões locais; batches difíceis; outliers | Gradient clipping (por norma global); reduzir LR; normalização; checar pré-processamento/escala de entrada |
| Ativações com variância crescendo por camada | Forward amplificando sinal (pesos grandes) | Rever inicialização; adicionar normalização; reduzir LR; considerar regularização |
| Ativações colapsando para ~0 por camada | Forward perdendo sinal (pesos pequenos) | Rever inicialização; adicionar normalização; aumentar LR moderadamente; checar se há excesso de regularização |
Gradient clipping: quando e como usar (passo a passo)
Clipping é uma intervenção direta contra explosão de gradiente. A forma mais comum é por norma global:
- Passo 1: compute a norma global do gradiente (por exemplo, L2) agregando todos os parâmetros.
- Passo 2: defina um limiar
c(ex.: 1.0, 5.0). - Passo 3: se
||g|| > c, reescale:g = g * (c / ||g||).
Clipping não “resolve” a causa raiz, mas frequentemente evita que o treino colapse enquanto você ajusta LR, inicialização e normalização.
Checklist rápido de intervenção (ordem sugerida)
- 1) Verifique LR: se há NaN/oscilações, reduza LR antes de qualquer outra coisa.
- 2) Confirme inicialização: He para ReLU; Xavier para casos apropriados.
- 3) Adicione normalização: BatchNorm (batch ok) ou LayerNorm (batch pequeno).
- 4) Aplique clipping: se ainda houver picos de gradiente.
- 5) Monitore por camada: encontre onde o gradiente some/explode e ajuste localmente (ex.: normalização naquela região).