Gradients qui disparaissent et qui explosent

Deep learning intermédiaire avec PyTorch

Michal Oleszak

Machine Learning Engineer

Gradients qui disparaissent

  • Les gradients diminuent à rebours
  • Les premières couches reçoivent de petites mises à jour
  • Le modèle n’apprend pas

Graphiques montrant la taille des gradients selon l’indice de couche : pour les premières couches, les gradients sont plus petits

Deep learning intermédiaire avec PyTorch

Gradients qui explosent

  • Les gradients deviennent de plus en plus grands
  • Mises à jour des paramètres trop importantes
  • L’entraînement diverge

Graphiques montrant la taille des gradients selon l’indice de couche : pour les premières couches, les gradients sont plus grands

Deep learning intermédiaire avec PyTorch

Solution aux gradients instables

  1. Bonne initialisation des poids
  2. Bonnes activations
  3. Normalisation par lot

 

 

Trois étapes

Deep learning intermédiaire avec PyTorch

Initialisation des poids

layer = nn.Linear(8, 1)
print(layer.weight)
Parameter containing:
tensor([[-0.0195,  0.0992,  0.0391,  0.0212,
         -0.3386, -0.1892, -0.3170,  0.2148]])
Deep learning intermédiaire avec PyTorch

Initialisation des poids

Une bonne initialisation garantit :

  • Variance des entrées = variance des sorties de couche
  • Variance des gradients identique avant et après une couche

 

La méthode dépend de l’activation :

  • Pour ReLU et similaires, utiliser l’initialisation de He/Kaiming
Deep learning intermédiaire avec PyTorch

Initialisation des poids

import torch.nn.init as init

init.kaiming_uniform_(layer.weight)
print(layer.weight)
Parameter containing:
tensor([[-0.3063, -0.2410,  0.0588,  0.2664,
          0.0502, -0.0136,  0.2274,  0.0901]])
Deep learning intermédiaire avec PyTorch

Initialisation de He / Kaiming

init.kaiming_uniform_(self.fc1.weight)
init.kaiming_uniform_(self.fc2.weight)
init.kaiming_uniform_(
  self.fc3.weight,
  nonlinearity="sigmoid",
)
Deep learning intermédiaire avec PyTorch

Initialisation de He / Kaiming

import torch.nn as nn
import torch.nn.init as init

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(9, 16)
        self.fc2 = nn.Linear(16, 8)
        self.fc3 = nn.Linear(8, 1)


init.kaiming_uniform_(self.fc1.weight) init.kaiming_uniform_(self.fc2.weight) init.kaiming_uniform_( self.fc3.weight, nonlinearity="sigmoid", )




    def forward(self, x):
        x = nn.functional.relu(self.fc1(x))
        x = nn.functional.relu(self.fc2(x))
        x = nn.functional.sigmoid(self.fc3(x))
        return x







Deep learning intermédiaire avec PyTorch

Fonctions d’activation

Courbe de la fonction ReLU. En dessous de zéro, la ligne est horizontale à zéro ; au-dessus, la pente est positive.

  • Souvent l’activation par défaut
  • nn.functional.relu()
  • Zéro pour les entrées négatives — neurones « morts »

Courbe de la fonction ELU. Semblable à ReLU mais avec une transition lisse depuis les valeurs négatives vers la zone positive.

  • nn.functional.elu()
  • Gradients non nuls pour les valeurs négatives — évite les neurones « morts »
  • Sortie moyenne proche de zéro — limite les gradients qui disparaissent
Deep learning intermédiaire avec PyTorch

Normalisation par lot (BatchNorm)

Après une couche :

  1. Normaliser les sorties en :

    • Soustrayant la moyenne
    • Divisant par l’écart type
  2. Redimensionner et décaler via des paramètres appris

Le modèle apprend une distribution d’entrées optimale par couche :

  • Perte qui diminue plus vite
  • Aide contre les gradients instables
Deep learning intermédiaire avec PyTorch

Normalisation par lot (BatchNorm)

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(9, 16)
        self.bn1 = nn.BatchNorm1d(16)

        ...


def forward(self, x): x = self.fc1(x) x = self.bn1(x) x = nn.functional.elu(x) ...
Deep learning intermédiaire avec PyTorch

Passons à la pratique !

Deep learning intermédiaire avec PyTorch

Preparing Video For Download...