CI : Deep learning pour audio
Ce TP introduit une première chaîne de bout en bout pour l’apprentissage sur graphes avec des Graph Neural Networks (GNN), dans un cadre pragmatique orienté ingénieur. Vous travaillerez sur un dataset public de taille modérée (Cora) afin de comparer une approche tabulaire (MLP, sans structure de graphe) à deux modèles GNN (GCN et GraphSAGE). L’objectif est de comprendre ce que “rajoute” le graphe en pratique, mais aussi ce que cela coûte en temps de calcul.
Le TP est modérément guidé : le code est presque entièrement fourni, et vous devrez compléter quelques emplacements marqués ________. Vous exécuterez de préférence vos entraînements sur le cluster GPU (Slurm), mais le dataset restant petit, un test local est possible (plus lent). Les livrables prennent la forme d’un rapport en Markdown (TP4/rapport.md) rempli au fil de l’eau, avec des résultats synthétiques, des extraits de terminal et des captures d’écran légères (éviter les fichiers volumineux).
- Mettre en place un pipeline de node classification sur le dataset Cora avec PyTorch Geometric.
- Entraîner et comparer trois modèles : MLP (baseline tabulaire), GCN (baseline GNN), GraphSAGE (GNN scalable via neighbor sampling).
- Évaluer les performances avec des métriques adaptées : Accuracy et Macro-F1.
- Mesurer et comparer des métriques d’ingénierie : temps d’entraînement (par epoch et total) et latence d’inférence (batch de nœuds).
- Produire un rapport concis et exploitable qui justifie les choix (modèle, hyperparamètres simples, protocole de mesure) et discute les compromis.
Initialisation du TP et smoke test PyG (Cora)
Créez le dossier TP4/ dans le dépôt du TP précédent, avec la structure minimale suivante :
Ne commitez pas de données. Le dataset Cora sera téléchargé automatiquement par PyG dans un répertoire de cache. Si vous créez un dossier local TP4/data/ pour vos tests, ajoutez-le au .gitignore.
À mettre dans le rapport : une capture (ou un copier-coller) de la commande tree -L 3 TP4 montrant la structure (inutile d’ajouter d’autres détails ici).
Implémentez un script de vérification rapide TP4/src/smoke_test.py qui : (i) vérifie l’accès GPU (si disponible), (ii) importe PyTorch + PyTorch Geometric, (iii) charge le dataset Cora, (iv) affiche des statistiques utiles (taille, dimensions, masques).
Copiez le code ci-dessous et complétez uniquement les zones ________.
Si vous voulez forcer un répertoire de cache propre au TP, vous pouvez définir PYG_DATA_ROOT dans votre environnement (ex: dans votre session Slurm) afin d’éviter de télécharger plusieurs fois le dataset.
Exécutez le smoke test de préférence sur le cluster GPU (Slurm). Un test local est accepté si vous n’avez pas de GPU sous la main, mais il sera moins représentatif.
À mettre dans le rapport : la sortie du script (copie terminal ou capture) montrant au minimum : torch version, device, gpu name (si GPU), et les stats de Cora (num_nodes, num_edges, num_features, num_classes, tailles des masques).
Évitez de coller des pages entières de logs : 15–25 lignes propres suffisent.
Baseline tabulaire : MLP (features seules) + entraînement et métriques
Créez les fichiers suivants (vides pour l’instant) : TP4/src/data.py, TP4/src/models.py, TP4/src/train.py, et complétez le fichier TP4/configs/baseline_mlp.yaml.
À mettre dans le rapport : rien pour cette étape (structure déjà vérifiée au TP précédent).
Implémentez TP4/src/data.py pour charger Cora et renvoyer un objet simple contenant : x, y, train_mask, val_mask, test_mask, ainsi que num_features et num_classes. Copiez le code et complétez uniquement les ________.
Pour la baseline MLP, vous n’utilisez pas edge_index. Vous utilisez uniquement x (features des nœuds). C’est volontaire : cela permet de mesurer ce que “rajoute” réellement le graphe ensuite.
Créez TP4/src/utils.py (ou complétez-le) avec : une fonction de seed, un timer simple, et le calcul de Accuracy + Macro-F1. Copiez le code et complétez uniquement les ________.
Cette implémentation de Macro-F1 est volontairement explicite (TP/FP/FN). Elle est suffisante ici et évite une dépendance externe.
Implémentez le modèle MLP dans TP4/src/models.py. Il doit prendre x et produire des logits de taille num_classes. Copiez le code et complétez uniquement les ________.
Ici, on retourne des logits (pas un softmax). La loss CrossEntropyLoss s’occupe du softmax numériquement stable.
Complétez TP4/configs/baseline_mlp.yaml (hyperparamètres simples). Copiez le fichier et complétez uniquement les ________.
Ces valeurs sont “raisonnables par défaut”. Vous pourrez ajuster hidden_dim ou lr si vous observez une instabilité, mais ne partez pas dans une grille de recherche : le but est la comparaison MLP vs GNN.
Implémentez TP4/src/train.py pour entraîner la baseline MLP et journaliser : (i) Accuracy + Macro-F1 sur train/val/test, (ii) temps par epoch et temps total. Copiez le code et complétez uniquement les ________.
Dans votre rapport, expliquez en 4–6 lignes pourquoi on calcule les métriques sur train_mask, val_mask et test_mask séparément (pas besoin de reciter le cours, restez concret “ingénieur”).
Pensez “protocole d’évaluation” : on veut suivre l’apprentissage (train), régler des choix (val), et estimer la performance finale (test) sans biais.
Oui, ce script évalue à chaque epoch : Cora est petit, c’est acceptable. Sur un gros graphe, on ferait autrement.
Exécutez l’entraînement de la baseline MLP (cluster vivement conseillé). À mettre dans le rapport : une capture (ou copie terminal) montrant : la configuration utilisée, les métriques finales (Accuracy et Macro-F1 sur test), et total_train_time_s.
Ne collez pas tout le log : gardez 20–30 lignes max (début + fin + une ligne intermédiaire).
Baseline GNN : GCN (full-batch) + comparaison perf/temps
Complétez TP4/configs/gcn.yaml pour définir les hyperparamètres de la baseline GCN. Copiez le fichier et complétez uniquement les ________.
On part sur des valeurs proches du MLP pour isoler l’effet “graphe”. Libre à vous d’ajuster légèrement si le modèle diverge, mais l’objectif principal est la comparaison.
Mettez à jour TP4/src/data.py pour exposer aussi edge_index (nécessaire pour GCN). Copiez le code et complétez uniquement les ________.
edge_index est une liste d’arêtes au format COO : un tenseur [2, E]. Vous n’avez pas besoin de construire une matrice d’adjacence dense.
Implémentez un modèle GCN dans TP4/src/models.py avec PyG (GCNConv). Copiez le code et complétez uniquement les ________.
Ici, on reste volontairement simple : 2 couches GCN. Sur Cora, c’est un bon point de départ.
Mettez à jour TP4/src/train.py pour supporter aussi l’entraînement GCN. Pour éviter un gros refactor, vous allez ajouter un mode --model et brancher MLP/GCN. Copiez le code ci-dessous (version complète) et complétez uniquement les ________.
Entraînez le modèle GCN (cluster GPU conseillé). Puis comparez MLP vs GCN. À mettre dans le rapport : une capture (ou copie terminal) des dernières lignes pour MLP et pour GCN, montrant : test_acc, test_f1, et total_train_time_s.
Ajoutez aussi un mini-tableau (3 lignes max) “modèle / test_acc / test_f1 / temps” (format libre).
Gardez des logs courts. Ne joignez pas de fichiers de sortie volumineux.
Expliquez brièvement (6–10 lignes) : dans ce contexte (Cora), pourquoi GCN peut dépasser (ou non) le MLP ? Restez concret : “signal du graphe”, “homophilie”, “lissage”, “features déjà fortes”, etc.
Vous pouvez mentionner que GCN exploite le voisinage et donc encode de l’information relationnelle que le MLP ignore. À l’inverse, si les features suffisent, le gain peut être faible.
Modèle principal : GraphSAGE + neighbor sampling (mini-batch)
Complétez TP4/configs/sage_sampling.yaml pour définir les hyperparamètres de GraphSAGE et du sampling. Copiez le fichier et complétez uniquement les ________.
Mettez à jour TP4/src/data.py pour exposer aussi l’objet PyG complet (torch_geometric.data.Data), nécessaire à NeighborLoader. Copiez le code et complétez uniquement les ________.
Implémentez le modèle GraphSAGE dans TP4/src/models.py avec PyG (SAGEConv). Copiez le code et complétez uniquement les ________.
Le même forward(x, edge_index) fonctionne en full-batch et sur un sous-graphe échantillonné. C’est ce qui rend GraphSAGE pratique avec NeighborLoader.
Mettez à jour TP4/src/train.py pour ajouter le mode --model sage et entraîner GraphSAGE en mini-batch via NeighborLoader. Copiez le code ci-dessous (version complète) et complétez uniquement les ________.
L’évaluation est faite en full-batch (sur tout le graphe) pour garder la comparaison simple sur Cora. Sur un très grand graphe, on ferait aussi l’inférence avec sampling/caching.
Entraînez GraphSAGE avec sampling, puis comparez MLP, GCN, GraphSAGE. À mettre dans le rapport : une capture (ou copie terminal) des dernières lignes pour GraphSAGE montrant test_acc, test_f1, total_train_time_s, et les hyperparamètres de sampling (batch_size, num_neighbors).
Évitez les logs longs : gardez quelques lignes (début + milieu + fin), et un tableau synthétique (3 lignes) des résultats.
Expliquez (8–12 lignes) le compromis “neighbor sampling” : en quoi cela accélère l’entraînement, et quel risque cela introduit sur l’estimation du gradient / la performance ? Restez concret (fanout, variance, hubs, coût CPU sampling).
Un point important : en sampling, vous ne voyez qu’un sous-ensemble des voisins par itération, ce qui rend l’apprentissage plus “bruité” mais beaucoup plus scalable. Le choix du fanout a donc un impact direct sur coût et qualité.
Benchmarks ingénieur : temps d’entraînement et latence d’inférence (CPU/GPU)
Ajoutez un dossier TP4/runs/ (pour stocker des checkpoints légers) et assurez-vous qu’il n’est pas versionné. Vous pouvez ajouter TP4/runs/ à votre .gitignore.
À mettre dans le rapport : rien (pas besoin de preuve pour le .gitignore).
Modifiez TP4/src/train.py pour sauvegarder un checkpoint léger à la fin de l’entraînement (un fichier .pt dans TP4/runs/). Copiez le patch ci-dessous et complétez uniquement les ________.
Un checkpoint pour ces modèles sur Cora est petit (quelques centaines de Ko). Il ne doit pas être commité.
Créez TP4/src/benchmark.py pour mesurer la latence d’inférence (forward) de chaque modèle, en chargeant le checkpoint sauvegardé. Le benchmark doit : faire quelques itérations de warmup, puis mesurer plusieurs forwards, avec synchronisation GPU. Copiez le code et complétez uniquement les ________.
Sur GPU, sans synchronisation, vous risquez de mesurer uniquement le “temps de lancement” des kernels. La synchronisation force l’attente de fin de calcul avant de lire le chrono.
Lancez le benchmark pour les trois modèles, en utilisant les checkpoints produits après entraînement (TP4/runs/mlp.pt, TP4/runs/gcn.pt, TP4/runs/sage.pt). Exécutez de préférence sur GPU (cluster).
À mettre dans le rapport : une capture (ou copie terminal) des sorties avg_forward_ms pour les trois modèles, puis un tableau synthétique (3 lignes max) : modèle / test_acc / test_f1 / total_train_time_s / avg_forward_ms. Vous pouvez reprendre test_acc, test_f1, total_train_time_s des exercices précédents.
Ne joignez pas les checkpoints au rendu. Une capture des résultats suffit.
Expliquez (6–10 lignes) pourquoi on fait un warmup, et pourquoi on synchronise CUDA avant/après la mesure. Votre explication doit faire le lien avec l’exécution asynchrone GPU et la stabilité des mesures.
Synthèse finale : comparaison, compromis, et recommandations ingénieur
Dans votre rapport (TP4/rapport.md), ajoutez une synthèse finale (format libre) qui contient : un tableau comparatif des trois modèles et une courte discussion sur les compromis. Ne rajoutez pas de logs supplémentaires : réutilisez les résultats déjà obtenus.
Le tableau doit tenir sur quelques lignes. L’objectif est qu’un lecteur puisse décider rapidement “quel modèle choisir” selon la contrainte (qualité vs coût).
Complétez le squelette ci-dessous (à copier-coller dans votre TP4/rapport.md) en remplaçant les ________ par vos valeurs mesurées.
Si vos temps varient d’un run à l’autre, utilisez une valeur représentative (un run “propre”) et indiquez-le en une phrase.
Rédigez un paragraphe (8–12 lignes) “recommandation ingénieur” basé sur vos mesures, en répondant à : dans quel cas vous choisissez MLP / GCN / GraphSAGE ? Votre réponse doit s’appuyer explicitement sur au moins : (i) une métrique qualité (Accuracy ou Macro-F1), (ii) une métrique coût (train time ou latence).
Pensez “production” : si le graphe est petit et stable, GCN peut suffire ; si le graphe est grand et dynamique, GraphSAGE + sampling devient naturel. Si le graphe apporte peu de gain, un MLP est parfois le meilleur choix.
Expliquez brièvement (6–10 lignes) un risque de protocole qui pourrait fausser la comparaison entre modèles dans ce TP, et comment vous l’éviteriez dans un vrai projet (ex: seed, data leakage, mesures non comparables CPU/GPU, caching, etc.).
Vérifiez que votre dépôt contient bien TP4/ avec : rapport.md, les scripts src/, et les configs configs/, et qu’il ne contient pas de gros fichiers (datasets, checkpoints, logs massifs).
À mettre dans le rapport : une phrase confirmant que vous n’avez pas commité de fichiers volumineux (pas besoin de captures).