Data Science & ML · L3 · Section 4/12
Apprentissage profond
Progression
#Deep Learning
Le deep learning empile des couches de neurones pour apprendre des représentations par niveaux: les premières couches capturent des motifs élémentaires, les suivantes les composent. Il domine sur les données non structurées: images, texte, audio, signaux.
#Prérequis et objectifs
Prérequis: page « Apprentissage supervisé » (sur-apprentissage, validation), page « Évaluation et généralisation » (split train/val/test), gradient et dérivée (module d'analyse).
Objectifs d'apprentissage:
- décider honnêtement si le problème justifie un réseau profond ou si un modèle tabulaire classique suffit;
- décrire la boucle d'entraînement: forward, loss, backward, update, et le rôle du learning rate;
- reconnaître et corriger les pannes classiques: gradient qui explose ou s'évanouit, apprentissage trop lent ou instable, sur-apprentissage;
- appliquer les régularisations usuelles: dropout, weight decay, early stopping, data augmentation.
#Quand utiliser le deep learning?
#Architecture d'un réseau simple
Un perceptron multicouche (MLP) empile des couches denses. Chaque couche applique une transformation linéaire suivie d'une activation non linéaire; sans non-linéarité, l'empilement entier se réduirait à une seule transformation linéaire.
1# PyTorch2import torch.nn as nn3 4model = nn.Sequential(5 nn.Linear(784, 256), # Couche 1: 784 → 2566 nn.ReLU(), # Activation7 nn.Dropout(0.2), # Régularisation8 nn.Linear(256, 128), # Couche 29 nn.ReLU(),10 nn.Linear(128, 10), # Sortie: 10 classes (logits)11)#Fonctions d'activation
ReLU: max(0, x), standard des couches cachées. Son gradient vaut 1 pour x positif, ce qui limite l'évanouissement du gradient; un neurone dont l'entrée reste négative sort 0 partout (neurone mort), d'où des variantes comme LeakyReLU.
Sigmoid: écrase dans [0,1] et sature à deux plateaux où son gradient est proche de zéro: à éviter dans les couches cachées profondes, à réserver à la sortie d'une classification binaire.
Softmax: normalise le vecteur de sortie en distribution de probabilités sur les classes, pour la sortie multi-classe.
Tanh: centrée sur zéro, sortie dans [-1,1]; alternative historique à ReLU.
#Entraînement: descente de gradient
La boucle: forward pass (calculer les prédictions), calcul de la loss (écart entre prédictions et cibles), backward pass (backpropagation des gradients), update (l'optimiseur ajuste les poids). La loss du mini-batch est bruyante; c'est précisément ce bruit contrôlé qui aide à sortir des minima locaux mal conditionnés.
Le learning rate gouverne la taille des pas. Trop petit: convergence lente. Trop grand: la loss oscille ou diverge. La descente stochastique classique part d'un taux modéré (0.1 pour SGD, 0.001 pour Adam) et le réduit sur plateau; les ordres de grandeur d'Adam et de SGD ne sont pas interchangeables.
Observation attendue: à lr=0.01, la fonction décroît lentement (f vaut encore 36 après 25 itérations); à lr=0.1, convergence nette (f ≈ 0.001). À lr=0.9, la valeur finale est identique à lr=0.1 (f ≈ 0.001), mais la trajectoire change de signe 25 fois: x oscille de part et d'autre du minimum à chaque pas au lieu de s'y glisser — lisible dans les premières itérations, invisible dans la valeur finale. À lr=1.1, divergence: f grimpe vers 9e5 en 25 itérations et tend vers l'infini. La valeur finale seule ne suffit pas à diagnostiquer le learning rate; il faut lire la trajectoire.
#Entraîner un vrai réseau, pas à pas
Sur un vrai jeu de données, le protocole ne change pas de nature, mais chaque étape devient mesurable: la loss d'entraînement et la loss de validation se tracent par époque. L'écart entre les deux courbes est le diagnostic le plus utile du praticien.
1import torch2import torch.nn as nn3 4criterion = nn.CrossEntropyLoss()5optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)6 7for epoch in range(num_epochs):8 model.train() # active le dropout9 for xb, yb in train_loader:10 optimizer.zero_grad() # sinon les gradients s'accumulent11 loss = criterion(model(xb), yb)12 loss.backward()13 optimizer.step()14 Trois détails qui coûtent des heures de débogage quand on les ignore: optimizer.zero_grad() à chaque itération (les gradients s'accumulent sinon), model.train() / model.eval() (dropout et batch norm changent de comportement), et une référence utile: sur MNIST, un réseau linéaire simple atteint environ 92%, un petit convnet dépasse 99%. C'est l'écart de performance qui justifie l'architecture, pas la mode.
#Pannes classiques et remèdes
Neurones morts en cascade, gradient nan: vérifiez l'échelle des entrées (standardisées), baissez le learning rate, testez LeakyReLU.
Loss de validation qui remonte pendant que la loss de train descend: sur-apprentissage; early stopping, dropout, weight decay, data augmentation.
Loss plate dès le début: learning rate trop faible, ou labels désynchronisés des features (vérifiez le pipeline, pas le modèle).
Loss de train elle-même élevée: sous-apprentissage; réseau trop petit, features trop pauvres, ou taux d'apprentissage inadéquat.
#Régularisation en deep learning
Dropout: désactive aléatoirement des neurones à chaque passage avant pendant l'entraînement, forçant la redondance des représentations.
Weight decay (L2): pénalise les poids de grande magnitude dans la loss de l'optimiseur.
Batch Normalization: normalise les activations par mini-batch, stabilise et accélère l'entraînement; le réseau apprend un décalage et une échelle par couche.
Data augmentation: rotations, recadrages, changements de teinte pour les images; remplace des données par des variantes crédibles.
Early stopping: on garde les poids du meilleur passage de validation, et on arrête quand elle cesse de s'améliorer. C'est la régularisation la moins coûteuse et souvent la plus efficace.
#Architectures spécialisées
CNN: convolutions qui exploitent la structure spatiale des images, avec partage de poids et invariance locale par translation, suivies de pooling. La convolution réduit drastiquement les paramètres par rapport à une couche dense sur pixels.
RNN / LSTM / GRU: traitent les séquences en maintenant un état caché; les LSTM ajoutent des portes qui contrôlent ce qui est mémorisé ou oublié, atténuant l'évanouissement du gradient sur les dépendances longues.
Transformers: attention qui pondère l'influence de chaque élément de la séquence sur chaque autre, en parallèle sur toute la séquence; backbone de BERT et GPT ainsi que des vision transformers modernes.
Autoencodeurs: encodeur vers un code latent étroit puis décodeur; l'objectif de reconstruction fournit un apprentissage sans label, utile au débruitage et à la détection d'anomalies (erreur de reconstruction élevée égale point suspect).
#Exercice vérifiable: lire une courbe d'apprentissage
Le playground « effet du learning rate » ci-dessus est votre instrument. Corrigé attendu, avec 25 itérations depuis x=10 sur f(x)=x²: lr=0.01 laisse f à environ 36, lr=0.1 et lr=0.9 aboutissent tous deux à f ≈ 0.001 (mais lr=0.9 change de signe à chaque itération, lisible sur les premières valeurs), lr=1.1 diverge vers ~9e5. Deuxième partie: remplacez la dérivée par 2 * x + 0.5 * np.sign(x) et constatez que la plage de stabilité du pas rétrécit: à lr=0.9, x oscille au bord de la stabilité et converge mal (x ≈ −2.3), et lr=1.0 diverge (x ≈ −22) quand lr=0.5 reste stable (x ≈ −0.25). Conclusion observable: la plage de learning rate sûre dépend de la courbure locale du paysage, exactement la raison pour laquelle on surveille la loss des premières itérations avant de lancer un long entraînement.