← Tous les articles

Comment apprennent les réseaux de neurones : les maths derrière une prédiction rapide

Un réseau de neurones est une fonction à paramètres ajustables. L'entraînement mesure l'erreur, calcule des gradients et déplace légèrement les paramètres. Je déroule le tout avec un modèle jouet de prix d'ordinateurs portables : la perte, la descente de gradient avec de vrais chiffres, la rétropropagation, le surapprentissage, et un script de 10 lignes à lancer toi-même.

Sujets : IA · Apprentissage automatique · Réseaux de neurones

Sur cette page

TL;DR : Un réseau de neurones est une fonction paramétrée. L’entraînement mesure l’erreur avec une perte, calcule des gradients par rétropropagation, et met à jour les paramètres par descente de gradient. Une faible perte d’entraînement n’est pas le but. La généralisation à de nouvelles données, si. J’utilise un modèle jouet de prix d’ordinateurs portables avec de vrais chiffres pour que le mécanisme reste visible.

Deuxième article d’une série de deux. Le premier traite des prédictions rapides face à l’investigation délibérée.

Dans le premier article, j’ai réparti les décisions entre un modèle prédictif rapide et un processus plus lent et délibéré. Cet article descend d’un niveau : comment un modèle rapide acquiert-il son comportement au départ ?

Je commence par un modèle assez petit pour que les calculs se fassent à la main, puis je monte jusqu’à l’entraînement d’un réseau de neurones.

Un modèle est une fonction à paramètres ajustables

Un programme classique suit des relations que le développeur écrit explicitement. Un modèle d’apprentissage automatique contient des paramètres numériques qu’on ajuste à partir d’exemples. La façon compacte de l’écrire est ŷ = f(x; θ). Ici x est l’entrée, θ l’ensemble des paramètres et ŷ la prédiction.

Disons que je veux prédire le prix de revente d’un ordinateur portable à partir de son prix d’achat. J’utilise un modèle volontairement simple : prix de revente prédit = poids × prix d’achat. Un portable acheté 200 $ et revendu 300 $ donne un poids cible de 1,5 pour cet exemple. J’initialise le poids à 1, donc le modèle prédit 200 $. Il se trompe de 100 $, et il me faut un moyen de mesurer cette erreur et de la réduire.

La perte : définir ce qui compte comme une erreur

Une fonction de perte transforme les erreurs de prédiction en un seul nombre à minimiser. Pour des prédictions numériques, l’erreur quadratique moyenne (MSE) fait la moyenne des carrés des écarts entre prédictions et cibles :

MSE = (1/n) × Σ(ŷᵢ − yᵢ)²

Le carré empêche les erreurs positives et négatives de s’annuler, et il pénalise davantage les grosses erreurs.

La perte reflète l’objectif d’entraînement que j’ai choisi. Elle ne reflète pas toutes les exigences d’un système en production. Une faible perte d’entraînement ne garantit pas de bonnes prédictions quand les conditions du marché changent.

Une boucle d'entraînement en quatre étapes. Entrée : un prix d'achat de 200 $. Modèle : poids fois prix donne 200 $. Perte : erreur quadratique moyenne entre prédiction et cible. Mise à jour : poids moins 0,1 fois le gradient, qui reboucle vers le modèle. En dessous, le poids passe de 1,000 à 1,467, puis tend vers 1,500.

La descente de gradient : avancer vers une perte plus basse

Le gradient indique à quel point la perte est sensible à chaque paramètre, et dans quel sens. La descente de gradient s’en sert pour mettre à jour chaque poids. En une dimension :

nouveau poids = ancien poids − taux d'apprentissage × gradient

Prenons le jeu de données jouet, avec des prix en centaines de dollars : les paires (1 ; 1,5), (2 ; 3) et (3 ; 4,5). La perte vaut alors L(w) = (14/3)(w − 1,5)². Pour w = 1, sa dérivée est d’environ −4,667. Avec un taux d’apprentissage de 0,1, la première mise à jour donne w ≈ 1,467. On est déjà très près de la cible de 1,5.

Le taux d’apprentissage fixe la taille du pas. Trop petit, l’entraînement est lent. Trop grand, il dépasse la cible ou diverge. Les optimiseurs réels reprennent ces idées avec des règles de mise à jour plus fines.

La rétropropagation : des gradients à travers de nombreuses couches

Un vrai réseau a de nombreux paramètres répartis sur des couches. Pendant la passe avant, les données traversent le modèle pour produire une prédiction et une perte. La rétropropagation applique ensuite la règle de dérivation en chaîne pour calculer comment la perte varie par rapport aux paramètres, jusqu’au fond du réseau. L’optimiseur utilise ces gradients pour mettre à jour les paramètres.

Un petit réseau avec une couche d'entrée de trois nœuds, une couche cachée de quatre et une sortie d'un seul, qui alimente un bloc de perte comparé à la cible. Une flèche en haut pointe vers la droite et indique : passe avant, prédire. Une flèche en bas pointe vers la gauche et indique : passe arrière, gradients.

Ce sont deux opérations différentes. La rétropropagation calcule les gradients. La descente de gradient, ou un autre optimiseur, effectue la mise à jour. Des bibliothèques comme PyTorch automatisent la différentiation, et le mécanisme en dessous reste le même.

Une itération d’entraînement minimale ressemble à ceci :

prediction = model(inputs)
loss = loss_function(prediction, targets)
optimizer.zero_grad()
loss.backward()
optimizer.step()

L’entraînement met à jour les paramètres du modèle. L’inférence ordinaire applique les paramètres appris à de nouvelles entrées, sans rien mettre à jour.

Le surapprentissage : une faible perte d’entraînement peut tromper

Imaginons un modèle de prix de revente qui prédit presque parfaitement les portables historiques mais se comporte mal sur ceux qui viennent d’être mis en vente. Il a peut-être appris les particularités de son échantillon d’entraînement plutôt qu’une relation qui tient. C’est le surapprentissage.

Un graphique en courbes de la perte en fonction des pas d'entraînement. La perte d'entraînement, en pointillés, continue de baisser. La perte de validation, en trait plein, baisse puis remonte. Un repère vertical, « stop here », se trouve au point le plus bas de la courbe de validation.

Pour vérifier la généralisation, je garde des jeux d’entraînement, de validation et de test séparés. Les données d’entraînement mettent à jour les paramètres. Les données de validation m’aident à choisir les architectures et les hyperparamètres, et à décider quand m’arrêter. Un jeu de test mis de côté estime la performance finale. Pour des prix qui évoluent dans le temps, un découpage chronologique peut en dire plus qu’un mélange aléatoire de transactions anciennes et récentes.

L’arrêt précoce, la régularisation, des données représentatives et un modèle de la bonne taille aident tous. Aucun ne supprime le besoin d’une évaluation réaliste.

Retour au Système 1 et au Système 2

L’entraînement peut dépenser beaucoup de calcul pour apprendre une correspondance. L’inférence l’applique ensuite rapidement. Les modèles prédictifs spécialisés conviennent donc bien aux tâches répétées et bien définies. Mais un modèle rapide peut échouer sur des entrées inconnues, et il peut se tromper avec assurance. Le processus qui l’entoure peut devoir aller chercher de nouvelles preuves, appliquer des règles de sécurité, ou passer la main à une personne.

Produire un score et décider quelle action ce score justifie sont deux métiers différents.

À lancer toi-même

Voici tout l’exemple jouet en Python pur, sans dépendance de machine learning, pour que le mécanisme d’apprentissage reste visible. Enregistre-le sous train_model.py et lance-le avec Python 3. Il n’est publié nulle part ailleurs sur ce site.

# Basic gradient descent: prices expressed in hundreds of dollars.
data = [(1.0, 1.5), (2.0, 3.0), (3.0, 4.5)]
weight = 1.0
learning_rate = 0.1
for epoch in range(20):
    loss = sum((weight*x-y)**2 for x,y in data)/len(data)
    gradient = sum(2*(weight*x-y)*x for x,y in data)/len(data)
    weight -= learning_rate*gradient
    print(f"epoch={epoch+1:02d} loss={loss:.6f} weight={weight:.6f}")
print(f"Predicted resale for $400 purchase: ${weight*400:.2f}")

Regarde le poids tendre vers 1,5. Essaie ensuite des taux d’apprentissage de 0,001 et de 0,5. Quand je l’ai lancé, 0,001 n’amenait le poids qu’à environ 1,09 au bout de 20 époques, et 0,5 dépassait la cible un peu plus à chaque pas jusqu’à un poids d’environ −10¹¹.

Où j’atterris

Un réseau de neurones est une fonction mathématique paramétrée. L’entraînement mesure les erreurs, calcule des gradients et met à jour les paramètres pour améliorer les prédictions. Ce qui décide si ces prédictions sont utiles, c’est leur généralisation à de nouvelles données, pas leur ajustement à l’ensemble d’entraînement.