MAML : Guide complet — Méta-Apprentissage Agnostique de Modèle
Résumé — Le MAML (Model-Agnostic Meta-Learning) est un algorithme de meta-learning proposé par Finn, Abbeel et Levine en 2017. Il apprend une initialisation des paramètres d’un modèle telle qu’après quelques steps de gradient sur une nouvelle tâche, les performances soient bonnes. Contrairement au meta-learning spécifique à une architecture (comme les réseaux mémoires), MAML fonctionne avec n’importe quel modèle entraînable par gradient (d’où “model-agnostic”). C’est la méthode de référence pour le few-shot learning: apprendre à partir de 1-5 exemples par classe.
Principe mathématique
1. Le problème du few-shot learning
En apprentissage classique, un modèle a besoin de milliers d’exemples par classe. Le few-shot learning vise à apprendre de nouvelles tâches avec seulement K exemples par classe (K=1 ou 5 typiquement). L’entraînement d’un modèle de zéro sur K exemples est impossible (surapprentissage massif). MAML résout ce problème en apprenant une “bonne” initialisation.
2. Formulation du meta-learning
On a une distribution de tâches p(T). Chaque tâche T_i a un support set S_i (K exemples par classe, utilisé pour l’adaptation) et un query set Q_i (utilisé pour évaluer l’adaptation):
min_θ somme_{T_i ~ p(T)} L_{T_i}(f_{θ_i'})
où θ_i' = θ - α · ∇_θ L_{T_i}(f_θ)
Le méta-modèle θ est mis à jour en fonction des performances après adaptation (θ_i’), pas avant.
3. Le méta-gradient
La mise à jour est une descente de gradient sur le méta-gradient:
θ ← θ - β · ∇_θ somme_i L_{T_i}(f_{θ - α∇L})
Cela nécessite de différencier à travers l’étape de gradient (d’où “gradient of a gradient”, ou méta-gradient de second ordre). En pratique, on utilise l’approximation du premier ordre (FOMAML) en ignorant les dérivées secondes:
∇_θ L_FOMAML ~ somme_i ∇_{θ_i'} L_{T_i}(f_{θ_i'})
4. Algorithme complet
Initialiser θ aléatoirement
Pour chaque méta-batch:
Pour chaque tâche T_i:
1. Calculer les gradients sur le support set: g_i = ∇_θ L_{T_i}(f_θ)
2. Adapter les paramètres: θ_i' = θ - α · g_i
3. Évaluer sur le query set: L_{T_i}(f_{θ_i'})
Mettre à jour θ avec les méta-gradients: θ ← θ - β · ∇_θ somme_i L_{T_i}(f_{θ_i'})
Intuition
Au lieu d’apprendre un modèle de zéro pour chaque nouvelle tâche, MAML apprend “comment apprendre”. C’est comme un étudiant qui a une bonne méthode de travail: quand il rencontre un nouveau sujet, il apprend vite car il sait déjà comment s’y prendre.
MAML trouve les bons “réflexes d’apprentissage” — une initialisation des poids qui est à égale distance de toutes les tâches possibles, prête à s’adapter dans n’importe quelle direction avec juste quelques exemples.
C’est comparable à un athlète polyglotte: il ne connaît pas toutes les langues du monde, mais il a développé une capacité d’apprentissage des langues qui lui permet d’en maîtriser une nouvelle en quelques semaines là où un débutant mettrait des années.
Implémentation Python
import torch
import torch.nn as nn
import torch.nn.functional as F
from copy import deepcopy
class MAML:
def __init__(self, model, inner_lr=0.01, outer_lr=1e-3, inner_steps=5):
self.model = model
self.inner_lr = inner_lr
self.outer_lr = outer_lr
self.inner_steps = inner_steps
self.outer_opt = torch.optim.Adam(self.model.parameters(), lr=outer_lr)
def inner_adapt(self, task_support_x, task_support_y):
"""Inner loop: adapter les poids sur le support set."""
adapted = deepcopy(self.model)
adapted_opt = torch.optim.SGD(adapted.parameters(), lr=self.inner_lr)
for step in range(self.inner_steps):
preds = adapted(task_support_x)
loss = F.cross_entropy(preds, task_support_y)
adapted_opt.zero_grad()
loss.backward()
adapted_opt.step()
return adapted
def meta_update(self, tasks):
"""Outer loop: méta-update sur plusieurs tâches."""
meta_loss = 0
for task in tasks:
support_x, support_y, query_x, query_y = task
# Adapter sur le support set
adapted = self.inner_adapt(support_x, support_y)
# Évaluer sur le query set
query_pred = adapted(query_x)
task_loss = F.cross_entropy(query_pred, query_y)
meta_loss += task_loss
meta_loss = meta_loss / len(tasks)
self.outer_opt.zero_grad()
meta_loss.backward()
self.outer_opt.step()
return meta_loss.item()
# Few-shot classification sur Omniglot (5-way 1-shot)
def create_task(dataset, n_way=5, k_shot=1, q_per_class=15):
"""Créer un tâche few-shot à partir du dataset."""
classes = torch.randperm(len(dataset.classes))[:n_way]
support_x, support_y = [], []
query_x, query_y = [], []
for c_idx, cls in enumerate(classes):
samples = dataset.get_samples(cls, k_shot + q_per_class)
support_x.append(samples[:k_shot])
support_y.extend([c_idx] * k_shot)
query_x.append(samples[k_shot:])
query_y.extend([c_idx] * q_per_class)
return (torch.cat(support_x), torch.tensor(support_y),
torch.cat(query_x), torch.tensor(query_y))
# Entraînement
model = nn.Sequential(
nn.Conv2d(1, 32, 3), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(32, 32, 3), nn.ReLU(), nn.MaxPool2d(2),
nn.Flatten(), nn.Linear(32*12*12, 5)
)
maml = MAML(model, inner_lr=0.01, outer_lr=1e-3, inner_steps=5)
for meta_epoch in range(1000):
tasks = [create_task(dataset, n_way=5, k_shot=1) for _ in range(4)]
loss = maml.meta_update(tasks)
if meta_epoch % 100 == 0:
print(f'Meta-epoch {meta_epoch} | Loss: {loss:.4f}')
# Évaluation: tester sur une nouvelle tâche jamais vue
new_task = create_task(dataset, n_way=5, k_shot=1)
adapted = maml.inner_adapt(new_task[0], new_task[1])
with torch.no_grad():
preds = adapted(new_task[2])
acc = (preds.argmax(dim=1) == new_task[3]).float().mean()
print(f'5-way 1-shot accuracy: {acc.item()*100:.1f}%')
Hyperparamètres
| Hyperparamètre | Valeur typique | Description |
|---|---|---|
| inner_lr | 0.001-0.01 | Taux d’apprentissage pour l’adaptation (alpha) |
| outer_lr | 1e-4-1e-3 | Taux d’apprentissage pour le meta-update (beta) |
| inner_steps | 1-10 | Nombre de steps de gradient dans la boucle interne |
| n_way | 5-20 | Nombre de classes par tâche |
| k_shot | 1-5 | Nombre d’exemples par classe dans le support set |
Comparaison avec d’autres méthodes de meta-learning
MAML vs Metric-Based (ProtoNet, Matching Networks)
Les approches métriques (ProtoNet, Matching Networks, Relation Networks) apprennent un espace d’embedding où les exemples de même classe sont proches. MAML, lui, apprend une initialisation des poids du modèle. Les métriques nécessitent de reclassifier à chaque nouvelle tâche (coûteux), tandis que MAML peut fine-tuner directement le classifieur existant.
MAML vs Reptile
Reptile est une approximation du premier ordre de MAML: au lieu de backpropager à travers les steps d’adaptation, on ajuste simplement les paramètres originaux vers les paramètres adaptés: θ ← θ + β · (θ’ – θ). C’est beaucoup plus simple et rapide, avec des performances comparables dans la plupart des cas.
MAML vs Fine-tuning standard
Le fine-tuning part d’une initialisation pré-entraînée sur une tâche source. MAML va plus loin: il trouve spécifiquement l’initialisation qui est la plus facile à adapter, même si elle n’est pas optimale pour la tâche source. C’est la différence entre être un expert généraliste et être un expert qui sait s’adapter.
Avantages
- Model-agnostic : Fonctionne avec n’importe quelle architecture entraînable par gradient (CNN, RNN, Transformers).
- Peu de données : S’adapte à de nouvelles tâches avec seulement 1-5 exemples par classe.
- Fast adaptation : L’adaptation ne nécessite que quelques steps de gradient, rapides à calculer.
Limites
- Méta-entraînement coûteux : Chaque meta-batch nécessite l’adaptation sur plusieurs tâches, chacune avec inner_steps forward/backward.
- Mémoire : Les gradients de second ordre nécessitent de stocker tout le graphe de calcul de l’adaptation.
- Performance variable : MAML peut être instable — les méta-gradients ont une variance élevée.
4 cas d’usage concrets
1. Reconnaissance de caractères rares
Dans des systèmes OCR pour des langues avec des milliers de caractères (chinois, japonais), de nouveaux caractères peuvent apparaître. MAML permet de reconnaître un nouveau caractère après 1-3 exemples seulement.
2. Recommandation personnalisée
Pour un nouvel utilisateur d’une plateforme, MAML adapte rapidement le modèle de recommandation à ses 5-10 premières interactions, offrant des recommandations pertinentes dès le premier jour.
3. Robotic control transfer
Un robot entraîné au MAML sur des dizaines de terrains différents (herbe, sable, glace) s’adapte rapidement à un nouveau terrain inédit avec seulement quelques minutes d’essais.
4. Diagnostic médical par cas rares
Pour des pathologies rares avec peu de cas disponibles, MAML adapte un modèle général d’imagerie médicale au cas spécifique avec les quelques exemples disponibles.
5. Adaptation de modèles de langage aux dialectes
Un modèle de langage entraîné sur l’anglais standard peut s’adapter rapidement à un dialecte régional grâce à l’initialisation MAML qui capture les compétences linguistiques de base. Quelques centaines de phrases suffisent pour obtenir des performances satisfaisantes sur le dialecte cible, évitant un réentraînement complet du modèle. Cette approche est particulièrement utile pour les langues ou dialectes avec des ressources limitées.
Conclusion
MAML a popularisé l’idée d’apprendre à apprendre par optimisation. Son influence se retrouve dans les algorithmes modernes de few-shot learning (ProtoNet, Relation Network, MetaOptNet) et a inspiré le transfert de connaissances entre modèles de langage (fine-tuning sur tâches multiples).
Les variantes comme Reptile (First-order MAML simplifié sans gradients de second ordre) et ANIL (Almost No Inner Loop) ont rendu le meta-learning plus accessible et moins coûteux. Ces avancées montrent que le principe fondamental de MAML — apprendre une initialisation adaptative plutôt qu’un modèle fixe — est robuste et s’étend au-delà des cas d’usage originaux.
Voir aussi
- Maîtriser les Diviseurs de Produits Binomiaux avec Python : Guide Complet
- Maîtriser les Composites à Propriété de Repunit Primaire avec Python : Guide et Applications

