Optimization Algorithm
Un algorithme d’optimisation met à jour les poids d’un modèle pour minimiser sa fonction de perte pendant l’entraînement. Découvre la descente de gradient, la quantité de mouvement, Adam, AdamW, Muon et des exemples de code.
Un algorithme d’optimisation, ou optimiseur, est la règle qu’un processus d’entraînement utilise pour modifier les paramètres d’un modèle afin de réduire sa fonction de perte. En apprentissage profond, l’optimiseur reçoit, par rétropropagation, le gradient de la perte par rapport à chaque poids du modèle, puis décide de la distance et de la direction du déplacement de chacun. Avec le taux d’apprentissage, l’optimiseur détermine la vitesse de convergence de l’entraînement, sa stabilité, la mémoire nécessaire et, souvent, la capacité du modèle final à généraliser.
Fonctionnement des optimiseurs#
Presque tous les optimiseurs d’apprentissage profond sont des variantes de la descente de gradient : calculer le gradient g de la perte sur un mini-lot, puis déplacer les poids d’un petit pas dans la direction opposée, w ← w − η·g. Les optimiseurs diffèrent par le traitement de g avant ce déplacement. Les méthodes avec momentum font la moyenne des gradients au fil du temps pour accélérer le déplacement dans les directions qui restent cohérentes. Les méthodes adaptatives divisent le pas de chaque paramètre par une estimation glissante de la taille de son gradient. Muon orthogonalise la mise à jour de chaque matrice de poids dans son ensemble. Les méthodes du second ordre utilisent aussi la courbure, ce qui permet de mieux guider chaque pas au prix d’un calcul bien plus coûteux. Les méthodes qui n’ont pas besoin de gradient, comme les algorithmes évolutionnaires et la recherche aléatoire, optimisent en testant des candidats et en conservant le meilleur :
La règle de mise à jour compte surtout lorsque la surface de perte est mal conditionnée, avec une courbure prononcée dans certaines directions et douce dans d’autres. Exécuter trois optimiseurs à partir du même point de départ dans une vallée étroite montre la différence :
import torch
# A long, narrow valley: f(w) = w1^2 + 50 * w2^2, with its minimum at (0, 0)
scale = torch.tensor([1.0, 50.0])
optimizers = {
"SGD": lambda p: torch.optim.SGD(p, lr=0.015),
"SGD + momentum": lambda p: torch.optim.SGD(p, lr=0.015, momentum=0.9),
"Adam": lambda p: torch.optim.Adam(p, lr=0.1),
}
for name, make_optimizer in optimizers.items():
w = torch.tensor([5.0, 1.0], requires_grad=True)
optimizer = make_optimizer([w])
# Same loss and starting point for every optimizer; only the update rule differs
for step in range(100):
loss = (scale * w**2).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"{name:15s} f(w) after 100 steps: {(scale * w**2).sum().item():.6f}")La SGD simple s’arrête à 0.056531, car la direction raide w2 plafonne son taux d’apprentissage : tout taux supérieur à 0.02 fait davantage dépasser w2 à chaque pas, et avec un taux de 0.021, la perte atteint environ 9,5 milliards en 100 pas. À ce plafond, les progrès dans la direction douce w1 sont lents. Le momentum atteint 0.000216 en accélérant le long de w1, et Adam atteint 0.001953 en donnant à chaque coordonnée son propre pas.
Algorithmes d’optimisation courants#
- Descente de gradient stochastique (SGD) : effectue un pas dans la direction opposée au gradient du mini-lot. Avec un momentum de 0.9, elle a servi à entraîner la plupart des réseaux convolutifs de référence et stocke une valeur supplémentaire par paramètre.
- AdaGrad et RMSProp : ajustent le pas de chaque paramètre selon l’historique de ses gradients au carré. AdaGrad divise par la racine de leur somme cumulée, qui ne fait qu’augmenter ; ses pas diminuent donc tout au long de l’entraînement. RMSProp utilise plutôt une moyenne à décroissance exponentielle, ce qui permet aux tailles de pas de rester réactives.
- Adam : combine le momentum et l’ajustement d’échelle de type RMSProp, et corrige les deux moyennes glissantes pour tenir compte de leur initialisation à zéro. Ses valeurs par défaut, un taux d’apprentissage de 0.001 avec β1 = 0.9 et β2 = 0.999, conviennent à de nombreux problèmes.
- AdamW : Adam avec une décroissance des poids découplée, qui réduit directement les poids au lieu de le faire par l’intermédiaire de l’ajustement adaptatif de l’échelle du gradient. C’est l’optimiseur standard pour les transformers et les grands modèles de langage (LLM).
- Muon : orthogonalise la mise à jour du momentum de chaque matrice de poids 2D au moyen d’itérations de Newton–Schulz et conserve un seul tampon d’état par paramètre. Moonshot AI l’a adapté au préentraînement de LLM.
- L-BFGS : méthode quasi-Newton qui construit une estimation de la courbure à partir des gradients récents. Elle converge en peu de pas sur des problèmes lisses traités par lots complets, mais les gradients bruités des mini-lots la rendent peu adaptée aux grands réseaux.
Le module d’optimisation de PyTorch implémente toutes ces méthodes, y compris torch.optim.Muon, ainsi que des planificateurs de taux d’apprentissage compatibles avec chacune d’elles.
Optimiseur et notions connexes#
- Fonction de perte : objectif que l’optimiseur minimise, comme l’entropie croisée pour la classification ou l’erreur quadratique moyenne pour la régression.
- Planificateur de taux d’apprentissage : ajuste la taille du pas η pendant l’entraînement au moyen d’une phase de chauffe, d’une décroissance par paliers ou d’un recuit cosinus, en complément de n’importe quel optimiseur.
- Réglage des hyperparamètres : recherche externe de paramètres tels que l’optimiseur, le taux d’apprentissage et la taille du lot, où chaque candidat nécessite un entraînement complet ou partiel. Les méthodes sans gradient, comme l’optimisation bayésienne et la recherche évolutionnaire, s’en chargent, car un score de validation ne peut pas être différencié par rapport à des choix tels que l’optimiseur.
Choisir un optimiseur#
L’optimiseur et le taux d’apprentissage se choisissent ensemble, car chaque optimiseur a sa propre plage : la SGD avec momentum commence généralement entre 0.01 et 0.1, et les optimiseurs de la famille Adam autour de 0.001. L’entraînement Ultralytics YOLO fait ce choix automatiquement : la valeur par défaut optimizer="auto" ignore lr0 et choisit AdamW avec un taux d’apprentissage adapté au nombre de classes pour les exécutions d’au plus 10 000 itérations, ou MuSGD, l’hybride SGD et Muon utilisé pour entraîner les points de contrôle YOLO26 publiés, pour les programmes plus longs ; indiquer un optimiseur active lr0 :
from ultralytics import YOLO
# Charger un modèle YOLO26n préentraîné
model = YOLO("yolo26n.pt")
# # Choisis SGD explicitement ; lr0 s’applique uniquement lorsque l’optimiseur n’est pas « auto »
results = model.train(data="coco8.yaml", epochs=5, optimizer="SGD", lr0=0.01)Avec optimizer="SGD", l’entraîneur active aussi le momentum de Nesterov, en utilisant l’argument momentum, qui vaut 0.937 par défaut, comme coefficient.










