Réseaux de Neurones — Propagation Avant & Rétro
“Des approximateurs universels construits sur la logique à seuil, optimisés par le calcul”
Du perceptron aux réseaux profonds : passe avant, fonctions d'activation, rétropropagation, gradient vanishing et initialisation.
Prérequis
Concepts Couverts
∑Formules Clés
Passage Avant
Transformation linéaire à la couche l — z = Wa + b
Activation
Activation non linéaire appliquée élément par élément — donne au réseau son pouvoir expressif
Delta de Rétropropagation
Signal d'erreur propagé en arrière à travers la couche l — produit de Hadamard avec la dérivée de l'activation
Gradient du Poids
Gradient de la perte par rapport aux poids de la couche l — utilisé pour la mise à jour SGD/Adam
▶Simulation Interactive
⬡Architecture du Modèle
Le Théorème d'Approximation Universelle
Cybenko (1989) a prouvé qu'une seule couche cachée avec suffisamment de neurones peut approximer n'importe quelle fonction continue à une précision arbitraire. Mais 'suffisamment' peut signifier des milliards de neurones pour des fonctions complexes. Les réseaux profonds (nombreuses couches, moins de neurones par couche) atteignent la même approximation avec exponentiellement moins de paramètres — ils apprennent des représentations hiérarchiques.
Un réseau profond avec L couches et n neurones par couche peut représenter des fonctions qui nécessitent O(2ⁿ) neurones dans un réseau à couche unique. La profondeur est de la compression.
Ce que Calculent Vraiment les Neurones
Chaque neurone calcule une somme pondérée de ses entrées (un hyperplan), puis applique une non-linéarité. Un seul neurone avec sigmoïde crée une frontière de décision douce. Plusieurs neurones dans une couche créent plusieurs hyperplans. Les couches profondes composent ces hyperplans, créant des frontières de décision de plus en plus complexes — des courbes, puis des courbes de courbes, puis des variétés.
Rétropropagation : La Règle de la Chaîne à Grande Échelle
L'entraînement nécessite le calcul de ∂L/∂W pour chaque poids. Le calcul direct est infaisable — un réseau avec 100M paramètres aurait besoin de 100M passes avant séparées. La rétropropagation exploite la règle de la chaîne pour calculer tous les gradients en une seule passe arrière, au même coût qu'une passe avant. C'est l'algorithme qui a rendu le deep learning possible.
Le Problème du Gradient Évanescent
Lors de la rétropropagation, les gradients sont multipliés à chaque couche. Pour la sigmoïde, σ'(z) ≤ 0,25 partout. Après 10 couches, le gradient est multiplié par 0,25¹⁰ ≈ 0,000001. Le gradient disparaît essentiellement — les premières couches cessent d'apprendre. ReLU corrige cela : sa dérivée est 1 pour z > 0, donc les gradients ne diminuent pas.
Boucle d'Entraînement SGD par Mini-Lots
Initialiser les poids : He init pour ReLU (W ~ N(0, √(2/fan_in)))
Pour chaque époque, mélanger les données d'entraînement
Pour chaque mini-lot de taille B :
Passe avant : calculer les activations a[1]...a[L] et la perte L
Passe arrière : calculer δ[L] puis propager en arrière
Mise à jour : W[l] ← W[l] - α · ∂L/∂W[l]
Mise à jour : b[l] ← b[l] - α · ∂L/∂b[l]
Appliquer un planificateur de taux d'apprentissage
PyTorch : Construction et Entraînement
import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import TensorDataset, DataLoader class="tok-comment"># ── Données dclass="tok-str">'exemple ────────────────────────────────────────────────── X_donnees = torch.randn(class="tok-num">1000, class="tok-num">128) y_donnees = torch.randint(class="tok-num">0, class="tok-num">2, (class="tok-num">1000,)).float() chargeur_donnees = DataLoader(TensorDataset(X_donnees, y_donnees), batch_size=class="tok-num">64, shuffle=True) class MLP(nn.Module): def __init__(self, dim_entree, dims_cachees, dim_sortie, dropout=class="tok-num">0.3): super().__init__() couches = [] dims = [dim_entree] + dims_cachees for i in range(len(dims_cachees)): couches += [ nn.Linear(dims[i], dims[i+class="tok-num">1]), nn.BatchNorm1d(dims[i+class="tok-num">1]), nn.ReLU(), nn.Dropout(dropout) ] couches.append(nn.Linear(dims_cachees[-class="tok-num">1], dim_sortie)) self.reseau = nn.Sequential(*couches) def forward(self, x): return self.reseau(x) modele = MLP(dim_entree=class="tok-num">128, dims_cachees=[class="tok-num">256, class="tok-num">128, class="tok-num">64], dim_sortie=class="tok-num">1) optimiseur = optim.AdamW(modele.parameters(), lr=class="tok-num">1e-3, weight_decay=class="tok-num">1e-4) planificateur = optim.lr_scheduler.CosineAnnealingLR(optimiseur, T_max=class="tok-num">100) class="tok-comment"># Étape d'entraînement for x_lot, y_lot in chargeur_donnees: optimiseur.zero_grad() logits = modele(x_lot).squeeze() perte = nn.BCEWithLogitsLoss()(logits, y_lot.float()) perte.backward() nn.utils.clip_grad_norm_(modele.parameters(), class="tok-num">1.0) optimiseur.step() planificateur.step()
Pièges Critiques
Neurones ReLU morts : si les poids d'un neurone poussent z < 0 pour toutes les entrées, il ne s'active jamais. Utilisez LeakyReLU ou l'initialisation He correcte.
Gradients explosifs : clip_grad_norm_(modele.parameters(), 1.0) doit toujours être dans votre boucle d'entraînement.
Pas de BatchNorm : le décalage de covariate rend les réseaux profonds instables. Toujours BatchNorm entre les couches linéaires et d'activation.
Taux d'apprentissage : trop élevé → la perte diverge ; trop faible → l'entraînement prend 100× plus longtemps. Utilisez lr_find ou commencez à 1e-3 avec AdamW.
?Vérification des Connaissances
La progression est sauvegardée dans votre navigateur — aucun compte requis.
Besoin d'un ingénieur IA ou data scientist ?
Je conçois des modèles ML sur mesure, des agents IA, de la vision par ordinateur et de l'automatisation — de l'idée à la production.