CSC 8607 – Introduction au deep learning

Portail informatique

Introduction au projet — CSC8607 : Introduction au Deep Learning

Bienvenue dans le projet de CSC8607 – Introduction au Deep Learning. Votre mission : implémenter un modèle qui vous sera assigné, le former sur un jeu de données également assigné, puis analyser et critiquer les résultats en suivant la procédure vue en cours.

Ci-dessous, vous trouverez la liste des projets (architecture × dataset). Chaque étudiant·e se voit attribuer un projet spécifique. La démarche reste toutefois identique pour tout le monde.

Procédure à suivre (rappel du cours)

  1. Vérifier la perte initiale.
  2. Overfit sur un très petit échantillon.
  3. Trouver un learning rate qui fait descendre la perte.
  4. Effectuer une petite grid search autour des paramètres prometteurs.
  5. Pour les meilleures configurations, poursuivre l’entraînement.
  6. Examiner et interpréter les courbes d’apprentissage.

Les questions et instructions plus bas vous guideront à chaque étape et structureront votre rapport.

Organisation et dépôt Git

Tous les projets doivent respecter la même structure disponible ici : https://github.com/Aunsiels/csc8607_projects. Vous devez forker ce dépôt et travailler dans votre propre dépôt Git.

Les règles détaillées (objectifs, Q&R) sont publiées sur cette page web et ne figurent pas dans le dépôt modèle.

Livrables attendus

  • Un dépôt Git public contenant :
    • Tout votre code (dans la structure fournie).
    • Votre rapport dans report_template.md à la racine du dépôt.
    • Les courbes d’apprentissage pertinentes compatibles TensorBoard dans runs/ (ne conservez que ce qui est utile).
    • Le meilleur checkpoint nommé exactement artifacts/best.ckpt.
    • Des captures d’écran (issues de TensorBoard) intégrées directement dans le rapport.

Important : respectez strictement les noms de fichiers et de dossiers ci-dessus.

Environnement et ressources

  • Installez les dépendances avec conda ou pip d’après requirements.txt.
  • Il est vivement conseillé d’utiliser les GPUs du cluster SLURM, selon la même procédure que durant les TPs.
  • Version Python recommandée : 3.9–3.11.

Esprit du projet

Vous pouvez utiliser des outils d’assistance au code, mais la difficulté réside dans l’intégration, le débogage, le lancement d’entraînements réels et l’interprétation des courbes. Votre évaluation se basera sur la traçabilité de la démarche et la cohérence de vos analyses.

Modalités de rendu

Date limite : .
À rendre par : envoi par e-mail du lien vers votre dépôt Git public.

Vérifications rapides avant rendu

  • Le dépôt est public et compilable (dépendances installables).
  • Le rapport est bien dans report_template.md et comprend les captures d’écran requises.
  • Les logs utiles sont dans runs/ (propres, non redondants).
  • Le meilleur modèle est présent sous artifacts/best.ckpt.

Liste des projets

Projet 1 — Tiny ImageNet (classification 200 classes) avec réseau convolutionnel à blocs simples

Étudiant : DELIÈRE

Dataset : Tiny ImageNet, 200 classes, ~100k images couleur 64×64 (train/val séparés). Tâche : classification multiclasses.

Où le trouver : via HuggingFace Datasets : zh-plus/tiny-imagenet (les images sont déjà au format 64×64). Vous pouvez l’utiliser avec PyTorch en écrivant un Dataset personnalisé qui lit les fichiers retournés par la librairie. Pour toute opération de transformation d’images, utilisez les fonctions de torchvision.transforms.

Modèle à implémenter : réseau convolutionnel en 3 stages, chaque stage étant répété plusieurs fois :

  • Entrée : image RGB 3×64×64.
  • Stage 1 (répéter N1 fois) :
    • Convolution 2D (filtre 3×3, padding 1), nombre de canaux = C1.
    • Batch normalization.
    • ReLU.
    À la fin du stage : Max pooling 2×2 (réduction de moitié des dimensions spatiales).
  • Stage 2 (répéter N2 fois) : identique au stage 1 mais avec C2 canaux, puis Max pooling 2×2.
  • Stage 3 (répéter N3 fois) : identique, avec C3 canaux, puis Global Average Pooling (moyenne spatiale).
  • Tête : couche linéaire (dimension C3 vers 200) pour obtenir les logits.

Utilisez les modules standards de PyTorch : nn.Conv2d, nn.BatchNorm2d, nn.ReLU, nn.AdaptiveAvgPool2d et nn.Linear.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de répétitions par stage : choisissez les triplets (N1, N2, N3) parmi {1,2,3}. Cela change la profondeur du réseau (plus de répétitions = plus de couches).
  2. Largeur des stages : fixez (C1, C2, C3) parmi des valeurs comme (64,128,256) ou (48,96,192). Largeur = nombre de canaux de sortie dans les convolutions ; augmenter la largeur accroît la capacité.

Projet 2 — CIFAR-100 (classification 100 classes) avec blocs résiduels simples

Étudiant : JERBI

Dataset : CIFAR-100, 100 classes, images couleur 32×32. Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.CIFAR100 (téléchargement automatique). Utilisez torchvision.transforms pour le prétraitement et l’augmentation (redimensionnement optionnel, normalisation, recadrage aléatoire, etc.).

Modèle à implémenter : réseau à blocs résiduels (skip connections). Un bloc résiduel prend un tenseur en entrée, applique Convolution→BatchNorm→ReLU→Convolution→BatchNorm, puis additionne l’entrée d’origine au résultat (chemin court) avant ReLU. Quand la taille spatiale ou le nombre de canaux change, utilisez une projection 1×1 sur le chemin court pour aligner les dimensions.

  • Entrée : 3×32×32.
  • Couche initiale : Convolution 3×3 (padding 1), canaux = C1, BatchNorm, ReLU.
  • Stage 1 : empilement de B1 blocs résiduels (toutes les convolutions 3×3, padding 1). Pas de changement d’échelle.
  • Stage 2 : première convolution du premier bloc avec stride 2 (réduction spatiale), canaux = C2. Empilez B2 blocs au total.
  • Stage 3 : même principe, stride 2 au début, canaux = C3, empilez B3 blocs.
  • Global Average Pooling puis couche linéaire vers 100 classes.

Référez-vous aux docs PyTorch pour nn.Conv2d et à la construction d’un skip connection avec addition de tenseurs (torch.add).

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de blocs par stage : choisissez (B1, B2, B3) parmi {(2,2,2), (3,3,3)}. Cela ajuste la profondeur.
  2. Nombre de canaux par stage : choisissez (C1, C2, C3) parmi {(64,128,256), (48,96,192)}. Plus de canaux = réseau plus large.

Projet 3 — AG News (classification de textes, 4 classes) avec réseau convolutionnel pour texte (TextCNN)

Étudiant : KJAOUJ

Dataset : AG News, 4 catégories d’actualités, texte en anglais (titre + description). Tâche : classification multiclasses.

Où le trouver : via torchtext (AG_NEWS) ou via HuggingFace Datasets (ag_news). Vous devrez tokeniser le texte, construire un vocabulaire ou utiliser des embeddings pré-entraînés si vous le souhaitez. Pour les séquences, référez-vous à nn.Embedding.

Modèle à implémenter : TextCNN avec plusieurs convolutions 1D en parallèle sur les séquences d’embeddings.

  • Convertissez chaque texte en une séquence d’indices, puis en séquence de vecteurs via une Embedding.
  • Appliquez en parallèle des Convolutions 1D avec des kernel sizes différents (par exemple 3, 4 et 5). Chaque convolution est suivie de ReLU puis d’un max-over-time pooling (max sur la dimension temporelle) pour résumer chaque carte de caractéristiques en un seul scalaire.
  • Concaténez les représentations issues de chaque branche, appliquez un dropout (si souhaité) puis une couche linéaire qui produit 4 logits.

Modules utiles : nn.Conv1d, nn.MaxPool1d, nn.Embedding.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Dimension des embeddings : choisissez parmi {100, 200, 300}. C’est la taille du vecteur représentant chaque mot.
  2. Nombre de filtres par taille de noyau : pour chaque convolution (par ex. tailles 3, 4, 5), choisissez le nombre de filtres parmi {50, 100, 150}. Plus de filtres donnent plus de caractéristiques extraites.

Projet 4 — Speech Commands v0.02 (reconnaissance de mots courts) avec CNN sur spectrogrammes log-mel

Étudiant : OUALGHAZI

Dataset : Speech Commands v0.02 (Google), clips audio 1 seconde, plusieurs mots (par ex. “yes”, “no”, “up”, “down”, etc.). Tâche : classification multiclasses (choisissez un sous-ensemble de classes si nécessaire).

Où le trouver : via torchaudio.datasets.SPEECHCOMMANDS. Convertissez chaque audio en spectrogramme log-mel avec les transformations de torchaudio.transforms (MelSpectrogram puis AmplitudeToDB). Le spectrogramme peut être traité comme une “image” (fréquence × temps).

Modèle à implémenter : CNN 2D sur spectrogrammes.

  • Entrée : tenseur 1×F×T (ajoutez une dimension “canal” = 1). Normalisez si nécessaire.
  • Bloc A : Convolution 2D (3×3, padding 1, canaux = C1) → Batch normalization → ReLU → Max pooling 2×2.
  • Bloc B : Convolution 2D (3×3, padding 1, canaux = C2) → Batch normalization → ReLU → Max pooling 2×2.
  • Bloc C : Convolution 2D (3×3, padding 1, canaux = C3) → Batch normalization → ReLU → Global Average Pooling.
  • Tête : couche linéaire vers le nombre de classes choisies.

Modules utiles : MelSpectrogram, AmplitudeToDB, nn.Conv2d, nn.MaxPool2d.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de canaux par bloc : fixez (C1, C2, C3) parmi {(32,64,128), (48,96,192)}.
  2. Taille de la fenêtre mel-spectrogramme (n_fft ou win_length dans torchaudio) : choisissez une valeur courte ou moyenne (par ex. {400, 512, 640}) qui impacte la résolution temps/fréquence du spectrogramme. Voir la documentation des paramètres dans torchaudio.transforms.MelSpectrogram.

Projet 5 — IMDb (analyse de sentiments binaire) avec BiLSTM et attention

Étudiant : DAVOUST

Dataset : IMDb, critiques de films en anglais, étiquettes positives/négatives. Tâche : classification binaire.

Où le trouver : via torchtext (IMDB) ou HuggingFace Datasets (imdb). Vous devez tokeniser, tronquer/padder les séquences, et construire un vocabulaire ou utiliser des embeddings.

Modèle à implémenter : BiLSTM (long short-term memory bidirectionnel) suivi d’un mécanisme d’attention simple pour agréger la séquence en un vecteur.

  • Embedding : transforme les indices de mots en vecteurs.
  • BiLSTM : une ou deux couches, renvoie une séquence de sorties (une par pas de temps) dans les deux directions (avant et arrière) concaténées.
  • Attention (simple) : apprenez un vecteur de requête (ou une petite couche linéaire) qui produit un poids (score) pour chaque pas de temps ; appliquez un softmax sur ces scores et calculez la moyenne pondérée des sorties BiLSTM. Le résultat est un vecteur fixe.
  • Tête : couche linéaire vers 1 logit (utilisez ensuite la perte binaire).

Référez-vous aux docs de nn.LSTM pour les options (bidirectional, num_layers) et à nn.Embedding.

Fonction de perte : BCEWithLogitsLoss (binaire, appliquée au logit de sortie).

Hyperparamètres du modèle à régler (2) :

  1. Taille cachée du LSTM (dimension de l’état caché par direction) : choisissez parmi {64, 128, 256}. Cela change la capacité de la mémoire.
  2. Nombre de couches LSTM : choisissez 1 ou 2 couches empilées (paramètre num_layers de nn.LSTM). Plus de couches augmentent la profondeur temporelle.

Projet 6 — Tiny ImageNet (200 classes) avec convolutions séparables en profondeur (depthwise + pointwise)

Étudiant : NIAURONIS

Dataset : Tiny ImageNet, 200 classes, ~100 000 images couleur 64×64. Tâche : classification multiclasses.

Où le trouver : via HuggingFace Datasets : zh-plus/tiny-imagenet. Chargez les images et les étiquettes avec un Dataset personnalisé et utilisez torchvision.transforms pour les transformations (normalisation, recadrage, etc.).

Concept à connaître (non vu en cours) : une convolution séparée en profondeur remplace une convolution 3×3 standard par deux étapes : (1) une convolution 3×3 depthwise qui applique un filtre indépendant sur chaque canal d’entrée (pas de mélange entre canaux), puis (2) une convolution 1×1 pointwise qui mélange les canaux et ajuste le nombre de canaux de sortie. Voir la documentation de PyTorch pour nn.Conv2d (paramètre groups pour réaliser la partie depthwise).

Modèle à implémenter : réseau en 3 stages avec blocs “Depthwise 3×3 → Batch normalization → ReLU → Pointwise 1×1 → Batch normalization → ReLU”.

  • Entrée : image RGB 3×64×64.
  • Stage 1 : répétez B1 fois le bloc :
    • Convolution 2D 3×3 depthwise (padding 1, groupes = nombre de canaux d’entrée), nombre de canaux conservé.
    • Batch normalization, ReLU.
    • Convolution 2D 1×1 pointwise pour produire 64 canaux.
    • Batch normalization, ReLU.
    À la fin du stage : Max pooling 2×2.
  • Stage 2 : même structure, répétez B2 fois, la convolution 1×1 produit 128 canaux. À la fin : Max pooling 2×2.
  • Stage 3 : même structure, répétez B3 fois, la convolution 1×1 produit 256 canaux. À la fin : Global Average Pooling.
  • Tête : couche linéaire (256 → 200).

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de blocs par stage : choisissez (B1, B2, B3) parmi {(1,1,1), (2,2,2)}.
  2. Facteur de largeur (multiplicateur des canaux après la convolution 1×1) : multipliez les valeurs de canaux (64, 128, 256) par {0.75 ou 1.0}. Par exemple, avec 0.75, les sorties deviennent (48, 96, 192). Un facteur de largeur ajuste uniformément la taille de toutes les couches de sortie.

Projet 7 — CIFAR-100 (100 classes) avec blocs “goulot d’étranglement” (bottleneck)

Étudiant : ROLAND

Dataset : CIFAR-100, 100 classes, images 32×32. Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.CIFAR100 (téléchargement automatique) avec transformations de torchvision.transforms.

Concept à connaître : un bloc bottleneck réduit brièvement le nombre de canaux avec une convolution 1×1 (goulot), applique une convolution 3×3 au faible coût, puis ré-augmente les canaux avec une autre convolution 1×1. Cela suit le schéma “1×1 réduction → 3×3 → 1×1 expansion”.

Modèle à implémenter : 3 stages de blocs bottleneck avec connexions résiduelles (addition entrée + sortie du bloc si dimensions égales ; sinon projection 1×1 sur le chemin court).

  • Entrée : 3×32×32.
  • Couche initiale : Conv 3×3 (padding 1, 64 canaux) → Batch normalization → ReLU.
  • Stage 1 (répéter B1 fois) :
    • Conv 1×1 réduit à 16 canaux.
    • Batch normalization, ReLU.
    • Conv 3×3 (padding 1) conserve 16 canaux.
    • Batch normalization, ReLU.
    • Conv 1×1 étend à 64 canaux.
    • Batch normalization.
    • Addition résiduelle (ou projection 1×1 si nécessaire), ReLU.
  • Stage 2 (répéter B2 fois) : le premier bloc utilise stride 2 dans la conv 3×3 pour réduire l’échelle spatiale, et l’extension finale produit 128 canaux. Les autres blocs du stage gardent stride 1 et 128 canaux.
  • Stage 3 (répéter B3 fois) : même logique, premier bloc stride 2, extension finale 256 canaux.
  • Global Average Pooling puis linéaire vers 100 classes.

Reportez-vous à la documentation de nn.Conv2d pour implémenter les convolutions 1×1 et 3×3 et à torch.add pour l’addition résiduelle.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de blocs par stage : choisissez (B1, B2, B3) parmi {(2,2,2), (3,3,3)}.
  2. Facteur de goulot (rapport de réduction dans la conv 1×1) : choisissez la réduction à {16 ou 32} canaux dans les stages où la sortie est respectivement {64 ou 128} canaux. Un facteur plus petit signifie un goulot plus étroit (plus de compression avant le 3×3).

Projet 8 — CelebA (multi-étiquettes visage, 5 attributs) avec CNN multi-label

Étudiant : BEN TALEB ALI

Dataset : CelebA, images de visages et ~40 attributs binaires. Tâche : prédire 5 attributs binaires simultanément (multi-label). Choisissez précisément 5 attributs (par exemple : Smiling, Wearing_Hat, Male, Young, Eyeglasses).

Où le trouver : via torchvision.datasets.CelebA (téléchargement après acceptation des conditions). Redimensionnez les images à 64×64 et normalisez-les.

Modèle à implémenter : CNN 2D à trois blocs convolutifs puis tête multi-sorties.

  • Entrée : image RGB 3×64×64.
  • Bloc 1 : Conv 3×3 (padding 1, 64 canaux) → Batch normalization → ReLU → Max pooling 2×2.
  • Bloc 2 : Conv 3×3 (padding 1, 128 canaux) → Batch normalization → ReLU → Max pooling 2×2.
  • Bloc 3 : Conv 3×3 (padding 1, 256 canaux) → Batch normalization → ReLU → Global Average Pooling.
  • Tête : couche linéaire (256 → 5) pour produire 5 logits indépendants (un par attribut).

Fonction de perte : BCEWithLogitsLoss (multi-label, appliquez-la à chaque logit avec les étiquettes {0,1}).

Hyperparamètres du modèle à régler (2) :

  1. Nombre de canaux dans le bloc 3 : choisissez 192 ou 256 pour la convolution du bloc 3 (les blocs 1 et 2 restent à 64 et 128).
  2. Probabilité de dropout appliquée juste avant la couche linéaire finale : choisissez {0.0, 0.2, 0.4}. Le dropout désactive aléatoirement des unités pour régulariser le modèle.

Projet 9 — Yelp Polarity (sentiment binaire) avec GRU et max-pooling global

Étudiant : GALSTIAN

Dataset : Yelp Polarity, critiques en anglais avec étiquette positive/négative. Tâche : classification binaire.

Où le trouver : via HuggingFace Datasets : yelp_polarity. Préparez une tokenisation simple (par mots), tronquez ou paddez les séquences à une longueur fixe et construisez un vocabulaire. Utilisez nn.Embedding pour représenter les mots.

Modèle à implémenter : Embedding → GRU → Global Max Pooling → Linéaire.

  • Embedding : transforme les indices en vecteurs de taille 200.
  • GRU : une couche unidirectionnelle (paramètre num_layers=1 et bidirectional=False) avec taille cachée H.
  • Global Max Pooling : prenez le maximum sur la dimension temporelle des sorties du GRU pour obtenir un vecteur fixe de taille H.
  • Tête : couche linéaire (H → 1) pour produire un logit binaire.

Voir la documentation de nn.GRU et nn.Embedding.

Fonction de perte : BCEWithLogitsLoss.

Hyperparamètres du modèle à régler (2) :

  1. Taille cachée du GRU H : choisissez parmi {128, 256, 384}.
  2. Longueur maximale de séquence (après tronquage/padding) : choisissez parmi {128, 256, 400}. Cela affecte la quantité de texte réellement lue par le modèle.

Projet 10 — UCI HAR (reconnaissance d’activités humaines, capteurs 1D) avec CNN 1D résiduel

Étudiant : UNG

Dataset : UCI Human Activity Recognition (HAR), signaux 1D issus d’accéléromètres/gyroscopes, plusieurs activités (par ex. : marcher, s’asseoir, etc.). Tâche : classification multiclasses.

Où le trouver : sur le dépôt UCI Machine Learning Repository (UCI HAR Dataset). Téléchargez les fichiers fournis (train/test), chargez-les avec un Dataset personnalisé PyTorch et normalisez chaque canal. La structure des fichiers est décrite dans le README du dataset.

Modèle à implémenter : CNN 1D avec blocs résiduels (skip connections) adaptés à des entrées de forme C×T (C canaux de capteurs, T pas de temps).

  • Entrée : C×T (par exemple 9 canaux si vous concaténez accéléromètre/gyroscope, selon votre préparation).
  • Couche initiale : Conv1d kernel 7, stride 2, padding 3, 64 canaux → Batch normalization → ReLU → MaxPool1d kernel 3, stride 2.
  • Stage 1 (répéter B1 fois) : chaque bloc = Conv1d 3×1 (padding 1) 64→64 → Batch normalization → ReLU → Conv1d 3×1 64→64 → Batch normalization → addition résiduelle → ReLU.
  • Stage 2 (répéter B2 fois) : premier bloc avec stride 2 dans la première conv pour réduire T, canaux 128 ; blocs suivants stride 1, canaux 128, avec projections 1×1 si nécessaire.
  • Stage 3 (répéter B3 fois) : même logique, 256 canaux.
  • Global Average Pooling 1D puis linéaire vers le nombre d’activités (par ex. 6).

Reportez-vous à nn.Conv1d, nn.MaxPool1d et à l’addition de tenseurs pour la connexion résiduelle.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de blocs par stage : choisissez (B1, B2, B3) parmi {(1,1,1), (2,2,2)}.
  2. Taille du noyau des convolutions dans les blocs : choisissez {3 ou 5}. Utilisez la même taille de noyau dans tous les blocs afin de garder un design cohérent.

Projet 11 — Tiny ImageNet (200 classes) avec convolutions dilatées (atrous) pour agrandir le champ réceptif

Étudiant : BOUTKRIDA

Dataset : Tiny ImageNet, 200 classes, ~100 000 images couleur 64×64. Tâche : classification multiclasses.

Où le trouver : via HuggingFace Datasets : zh-plus/tiny-imagenet. Chargez les images/étiquettes et utilisez torchvision.transforms pour normaliser et recadrer si nécessaire.

Concept : une convolution dilatée (dilated ou atrous) insère des “trous” dans le noyau (paramètre dilation de nn.Conv2d) afin d’agrandir le champ réceptif sans augmenter le nombre de paramètres.

Modèle à implémenter : réseau en 3 stages, chaque stage composé de blocs : Conv2d (3×3) → Batch normalization → ReLU. Les convolutions des stages 2 et 3 utilisent une dilation > 1. Réduction spatiale entre les stages par MaxPool.

  • Entrée : 3×64×64.
  • Stage 1 : répéter B1 fois : Conv 3×3, padding 1, 64 canaux, dilation 1 → Batch normalization → ReLU. Puis MaxPool 2×2.
  • Stage 2 : répéter B2 fois : Conv 3×3, padding ajusté, 128 canaux, dilation D2 → Batch normalization → ReLU. Puis MaxPool 2×2.
  • Stage 3 : répéter B3 fois : Conv 3×3, padding ajusté, 256 canaux, dilation D3 → Batch normalization → ReLU. Puis Global Average Pooling.
  • Tête : linéaire 256 → 200.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de blocs par stage : choisissez (B1, B2, B3) parmi {(2,2,2), (3,3,3)}.
  2. Dilation par stage : choisissez (D2, D3) parmi {(2,2), (2,3)}. Ajustez le padding en conséquence pour conserver les dimensions avant pooling.

Projet 12 — CIFAR-100 (100 classes) avec Group Normalization au lieu de Batch Normalization

Étudiant : CHARFEDDINE

Dataset : CIFAR-100, 100 classes, 32×32. Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.CIFAR100. Utilisez torchvision.transforms pour le prétraitement et l’augmentation.

Concept : Group Normalization normalise par groupes de canaux (voir nn.GroupNorm) et est moins sensible à la taille de batch que Batch Normalization.

Modèle à implémenter : réseau convolutionnel en 3 stages avec blocs Conv 3×3 → GroupNorm → ReLU. Réduction spatiale par stride 2 en début de stage 2 et 3 (dans la convolution).

  • Entrée : 3×32×32.
  • Stage 1 : deux blocs : Conv 3×3, 64 canaux, stride 1 → GroupNorm → ReLU (répéter deux fois).
  • Stage 2 : premier bloc Conv 3×3, 128 canaux, stride 2 → GroupNorm → ReLU, puis un second bloc identique avec stride 1.
  • Stage 3 : premier bloc Conv 3×3, 256 canaux, stride 2 → GroupNorm → ReLU, puis un second bloc identique avec stride 1.
  • Global Average Pooling → linéaire 256 → 100.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de groupes pour GroupNorm : choisissez {8, 16}. Le nombre de groupes doit diviser le nombre de canaux du bloc.
  2. Nombre de blocs par stage : choisissez {2 ou 3 blocs} dans chaque stage (si 3, ajoutez un bloc Conv→GroupNorm→ReLU supplémentaire avec stride 1).

Projet 13 — Food-101 (classification 101 classes) avec CNN à quatre stages

Étudiant : PILLET

Dataset : Food-101, 101 catégories de plats, ~101k images diverses. Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.Food101. Redimensionnez les images à 128×128 pour limiter le coût mémoire et normalisez-les.

Modèle à implémenter : CNN 2D avec 4 stages, blocs Conv 3×3 → Batch normalization → ReLU, et réduction spatiale par MaxPool entre les stages.

  • Entrée : 3×128×128.
  • Stage 1 : répéter N1 fois : Conv 3×3, 64 canaux, padding 1 → Batch normalization → ReLU. Puis MaxPool 2×2.
  • Stage 2 : répéter N2 fois : Conv 3×3, 128 canaux → Batch normalization → ReLU. Puis MaxPool 2×2.
  • Stage 3 : répéter N3 fois : Conv 3×3, 256 canaux → Batch normalization → ReLU. Puis MaxPool 2×2.
  • Stage 4 : répéter N4 fois : Conv 3×3, 256 canaux → Batch normalization → ReLU. Puis Global Average Pooling.
  • Tête : linéaire 256 → 101.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Répétitions par stage : choisissez (N1, N2, N3, N4) parmi {(1,1,2,2), (2,2,2,2)}.
  2. Canaux du stage 4 : choisissez 256 ou 384 canaux pour les convolutions du stage 4 (les autres stages restent à 64, 128, 256).

Projet 14 — Oxford-IIIT Pet (37 races de chats/chiens) avec blocs à attention de canal (Squeeze-and-Excitation)

Étudiant : RAKI

Dataset : Oxford-IIIT Pet, 37 classes (races de chats et de chiens), images de tailles variées. Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.OxfordIIITPet. Redimensionnez chaque image à 128×128 et normalisez-la (moyenne/écart-type usuels des images RGB). Utilisez les transformations de torchvision.transforms.

Modèle à implémenter : réseau convolutionnel en 3 stages, chaque bloc est : Convolution 3×3 → Batch normalization → ReLU → Squeeze-and-Excitation (SE). Réduction spatiale par max pooling entre les stages. La tête applique un global average pooling puis une couche linéaire vers 37 classes.

  • Entrée : image RGB 3×128×128.
  • Stage 1 :
    • Deux blocs identiques. Chaque bloc utilise une convolution 3×3 (padding 1) avec 64 canaux, suivie d’une batch normalization et de ReLU, puis d’un module SE (décrit plus bas) paramétré pour 64 canaux.
    • Après le second bloc : MaxPool 2×2.
  • Stage 2 :
    • Deux blocs identiques. Chaque bloc utilise une convolution 3×3 (padding 1) avec 128 canaux, batch normalization, ReLU, puis module SE pour 128 canaux.
    • Après le second bloc : MaxPool 2×2.
  • Stage 3 :
    • Deux blocs identiques. Chaque bloc utilise une convolution 3×3 (padding 1) avec 256 canaux, batch normalization, ReLU, puis module SE pour 256 canaux.
    • Après le dernier bloc : Global Average Pooling spatial (sortie de taille 256).
  • Tête : couche linéaire 256 → 37 (logits de classification).

Fonction de perte : CrossEntropyLoss.

Détails du module Squeeze-and-Excitation (SE)

Le module SE rééchelonne par canal les cartes de caractéristiques en apprenant des poids compris entre 0 et 1 pour chaque canal. Il comporte deux étapes : compression (squeeze) et excitation.

  1. Squeeze (compression) : appliquez une moyenne globale spatiale par canal pour résumer chaque carte en un scalaire. Utilisez nn.AdaptiveAvgPool2d(output_size=1).
    Si l’entrée du SE a la forme (N, C, H, W), la sortie du squeeze a la forme (N, C, 1, 1).
  2. Excitation : passez ce vecteur (aplatir en (N, C)) dans une petite MLP à deux couches linéaires de tailles C → C/r → C, avec ReLU entre les deux couches et une sigmoïde à la fin.
    • Première couche linéaire : dimension d’entrée = C, dimension de sortie = ceil(C / r). (Si C / r n’est pas entier, arrondissez à l’entier supérieur. Ne descendez jamais en dessous de 1.)
    • Activation ReLU.
    • Deuxième couche linéaire : dimension d’entrée = ceil(C / r), dimension de sortie = C.
    • Activation sigmoïde pour obtenir des coefficients dans [0, 1].
    Référez-vous à nn.Linear pour implémenter ces couches.
  3. Recalibrage : redimensionnez/broadcast les C poids obtenus à la forme (N, C, 1, 1) et multipliez-les canal-par-canal avec l’entrée du module SE (opération de type * en PyTorch).

Exemples de tailles de la MLP :

  • Dans un bloc avec C = 64 canaux et r = 16 : MLP = 64 → 4 → 64.
  • Dans un bloc avec C = 128 canaux et r = 8 : MLP = 128 → 16 → 128.
  • Dans un bloc avec C = 256 canaux et r = 16 : MLP = 256 → 16 → 256.

Hyperparamètres du modèle à régler (2) :

  1. Ratio de réduction r du module SE : choisissez {8, 16}. Cela contrôle la taille du goulot de la MLP (C/r). Un ratio plus grand (16) rend la MLP plus compacte, donc une excitation plus contrainte.
  2. Nombre de blocs par stage : choisissez {2 ou 3}. Si vous choisissez 3 :
    • Dans le stage 1 et le stage 2, insérez un bloc supplémentaire avant le MaxPool 2×2.
    • Dans le stage 3, insérez un bloc supplémentaire avant le global average pooling.
    • Chaque bloc ajouté est identique (mêmes canaux et même module SE).

Projet 15 — ESC-50 (50 classes de sons environnementaux) avec CNN 2D sur spectrogrammes log-mel

Étudiant : HADDAOUI

Dataset : ESC-50, 2 000 enregistrements audio de 5 secondes, 50 classes (40 exemples par classe). Tâche : classification multiclasses.

Où le trouver :
• Dépôt officiel : github.com/karolpiczak/ESC-50 (contient les fichiers .wav et le fichier d’annotations meta/esc50.csv). Utilisez les colonnes fold, category et filename pour créer vos splits train/val/test et vos étiquettes.
• Alternative prête à l’emploi : jeu de données HuggingFace : yangwang825/esc50.

Prétraitement audio (recommandé) : chargez les WAV, convertissez en mono, rééchantillonnez à 16 000 Hz, puis calculez un mel-spectrogramme (paramètres fixes : n_mels=64, n_fft=400, win_length=400, hop_length=160) et appliquez AmplitudeToDB (échelle log). Ces étapes se font avec torchaudio et ses transforms (MelSpectrogram, AmplitudeToDB). Traitez ensuite le spectrogramme comme une “image” 1×Fréquences×Temps.

Modèle à implémenter : CNN 2D à trois blocs convolutionnels suivis d’un global average pooling et d’une couche linéaire.

  • Entrée : tenseur 1×64×T (1 canal, 64 bandes mel, T pas de temps). Normalisez le spectrogramme (par ex. normalisation par feature).
  • Bloc A : Convolution 2D (3×3, padding 1, C1 canaux) → Batch normalization → ReLU → Max pooling 2×2.
  • Bloc B : Convolution 2D (3×3, padding 1, C2 canaux) → Batch normalization → ReLU → Max pooling 2×2.
  • Bloc C : Convolution 2D (3×3, padding 1, C3 canaux) → Batch normalization → ReLU → Global Average Pooling.
  • Tête : couche linéaire (C3 → 50) pour produire les logits.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de canaux par bloc : choisissez (C1, C2, C3) parmi {(32, 64, 128) ou (48, 96, 192)}.
  2. Taille de noyau des convolutions : choisissez {3×3 ou 5×5}. Si vous choisissez 5×5, utilisez padding=2 pour conserver la taille spatiale avant le pooling.

Projet 16 — 20 Newsgroups (20 catégories de textes) avec BiGRU et attention moyenne pondérée

Étudiant : AMDOUNI

Dataset : 20 Newsgroups, 20 catégories de forums texte. Tâche : classification multiclasses.

Où le trouver : via scikit-learn (fetch_20newsgroups) ou HuggingFace Datasets (newsgroup). Nettoyez le texte (minuscule, suppression ponctuation basique), tokenizez, tronquez/paddez à une longueur fixe, construisez un vocabulaire.

Modèle à implémenter : Embedding → BiGRU → attention simple → Linéaire (20).

  • Embedding : dimension 200.
  • BiGRU : une couche bidirectionnelle, taille cachée H par direction (la sortie par pas de temps a une dimension 2H).
  • Attention : calculez un score par pas de temps avec une petite couche linéaire appliquée sur 2H, puis appliquez softmax pour obtenir des poids ; faites la somme pondérée des sorties temporelles (vecteur 2H).
  • Tête : linéaire 2H → 20.

Voir nn.GRU (paramètre bidirectional=True) et nn.Embedding.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Taille cachée H du GRU (par direction) : choisissez {128, 192, 256}.
  2. Longueur maximale de séquence (après tronquage/padding) : choisissez {256, 400, 512}.

Projet 17 — Tiny ImageNet (200 classes) avec blocs résiduels pré-activation (BatchNorm/ReLU avant convolution)

Étudiant : ZRIGA

Dataset : Tiny ImageNet, 200 classes, environ 100 000 images couleur 64×64. Tâche : classification multiclasses.

Où le trouver : via HuggingFace Datasets : zh-plus/tiny-imagenet. Chargez les images et étiquettes, redimensionnez à 64×64 si nécessaire et normalisez-les avec les transformations de torchvision.transforms.

Modèle à implémenter : réseau convolutionnel avec blocs résiduels pré-activation. Dans un bloc pré-activation, l’ordre est Batch Normalization → ReLU → Convolution, et l’addition résiduelle se fait sur la sortie de la seconde convolution. Lorsque la résolution ou le nombre de canaux change, utilisez une projection 1×1 sur le chemin court pour faire correspondre les dimensions.

  • Entrée : image RGB 3×64×64.
  • Couche d’initialisation : Convolution 3×3, 64 canaux, stride 1, padding 1 (pas de pooling ici).
  • Stage 1 (résolution inchangée) : empilez B1 blocs. Chaque bloc contient :
    • BatchNorm 2D → ReLU → Convolution 3×3 (64 → 64, stride 1, padding 1).
    • BatchNorm 2D → ReLU → Convolution 3×3 (64 → 64, stride 1, padding 1).
    • Addition résiduelle (chemin court = identité, pas de projection ici).
  • Stage 2 (réduction de moitié des dimensions spatiales) : empilez B2 blocs. Dans le premier bloc du stage :
    • BatchNorm 2D → ReLU → Convolution 3×3 (64 → C2, stride 2, padding 1) pour réduire la résolution.
    • BatchNorm 2D → ReLU → Convolution 3×3 (C2 → C2, stride 1, padding 1).
    • Chemin court : Convolution 1×1 (64 → C2, stride 2) pour aligner résolution et canaux.
    Pour les blocs suivants du même stage, utilisez stride 1 dans les deux convolutions et un chemin court identité.
  • Stage 3 (réduction de moitié des dimensions spatiales) : même principe que le stage 2 mais avec C3 canaux. Dans le premier bloc, mettez stride 2 dans la première convolution et dans la projection 1×1 du chemin court.
  • Tête : Global Average Pooling (moyenne spatiale) → couche linéaire (C3 → 200) pour produire les logits.

Modules utiles : nn.BatchNorm2d, nn.ReLU, nn.Conv2d, nn.AdaptiveAvgPool2d. Pour l’addition du chemin résiduel : torch.add.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de blocs par stage : choisissez (B1, B2, B3) parmi {(2, 2, 2), (3, 3, 3)}. Plus de blocs = réseau plus profond.
  2. Nombre de canaux par stage : choisissez (C2, C3) parmi {(128, 256) ou (96, 192)}. Le stage 1 reste à 64 canaux (valeur fixée).

Projet 18 — SVHN (numéros de maison, 10 classes) avec CNN à blocs et downsampling par stride

Étudiant : ZEGANG KETCHAKEU

Dataset : SVHN, images couleur 32×32 de chiffres (scènes naturelles), 10 classes. Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.SVHN (split train et test disponibles). Normalisez les images.

Modèle à implémenter : CNN 3 stages ; chaque stage contient deux blocs Conv 3×3 → Batch normalization → ReLU. La première convolution du stage 2 et du stage 3 utilise stride = 2 pour réduire l’échelle spatiale (au lieu d’un MaxPool).

  • Entrée : 3×32×32.
  • Stage 1 : deux blocs à 64 canaux, stride 1.
  • Stage 2 : premier bloc 128 canaux avec stride 2, second bloc 128 canaux stride 1.
  • Stage 3 : premier bloc 256 canaux avec stride 2, second bloc 256 canaux stride 1, puis Global Average Pooling.
  • Tête : linéaire 256 → 10.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de canaux : choisissez les triplets {(64,128,256) ou (48,96,192)} pour les trois stages.
  2. Ajout d’un troisième bloc par stage : choisissez {oui ou non}. Si oui, ajoutez un bloc Conv→Batch normalization→ReLU supplémentaire avec le même nombre de canaux et stride 1 dans chaque stage.

Projet 19 — Tiny ImageNet (200 classes) avec modules “Inception-like” multibranches

Étudiant : KHALFALLAH

Dataset : Tiny ImageNet, 64×64, 200 classes. Tâche : classification multiclasses.

Où le trouver : via HuggingFace Datasets : zh-plus/tiny-imagenet.

Concept : un module “multibranches” applique en parallèle des convolutions de tailles différentes, puis concatène les sorties le long de la dimension des canaux (voir torch.cat pour la concaténation de tenseurs).

Modèle à implémenter : enchaînement de M modules identiques ; chaque module comporte 3 branches en parallèle : Conv 1×1 (réduction des canaux) → ReLU ; Conv 3×3 (padding 1) → ReLU ; MaxPool 3×3 (stride 1, padding 1) suivi d’une Conv 1×1 → ReLU. Concaténez les trois sorties (dimension des canaux), puis appliquez Batch normalization. Réduisez l’échelle spatiale par MaxPool 2×2 après chaque 2 modules. Terminez par Global Average Pooling puis linéaire vers 200.

  • Au début, appliquez une Conv 3×3, 64 canaux, padding 1.
  • Dans chaque module, fixez la sortie concaténée à 192 canaux en choisissant des largeurs appropriées dans les trois branches (par exemple 64 + 64 + 64).

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre total de modules M : choisissez {4, 6}. Insérez un MaxPool 2×2 après les modules 2 et 4 si M=6 (ou seulement après le module 2 si M=4).
  2. Répartition des canaux par branche : choisissez entre { (64,64,64) ou (48,72,72) } pour (branche 1×1, branche 3×3, branche pool+1×1) afin que la concaténation fasse 192 canaux.

Projet 20 — Flowers-102 (102 classes de fleurs) avec connexions denses (dense connections)

Étudiant : SLESINSKI

Dataset : Oxford Flowers-102, 102 classes, images variées. Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.Flowers102. Redimensionnez toutes les images à 128×128 et normalisez-les (moyennes/écarts-types RGB usuels). Utilisez torchvision.transforms pour le prétraitement et l’augmentation.

Idée des connexions denses : à l’intérieur d’un dense block, chaque bloc produit de nouveaux canaux qui sont concaténés (pas additionnés) aux entrées existantes. Ainsi, si l’entrée a C canaux, chaque bloc ajoute G nouveaux canaux (appelé taux de croissance), et la sortie du dense block grossit progressivement. La concaténation se fait sur la dimension “canaux”. Reportez-vous à torch.cat pour concaténer des tenseurs.

Modèle à implémenter : enchaînement DenseBlock 1 → Transition 1 → DenseBlock 2 → Transition 2 → DenseBlock 3 → Tête.

  • Entrée : image RGB 3×128×128.
  • Couche initiale : Conv2d 3×3, 64 canaux, stride 1, padding 1 → BatchNorm2dReLU.
    Voir nn.Conv2d, nn.BatchNorm2d, nn.ReLU.

Dense block (détails)

Un dense block répète K fois la séquence suivante, en réutilisant toutes les sorties précédentes par concaténation :

  1. Entrée du bloc courant : concaténation de toutes les sorties des blocs précédents du même dense block et de l’entrée du dense block. Si la première entrée du dense block a Cin canaux, alors l’entrée du bloc i (en commençant à 1) a Cin + (i-1)·G canaux.
  2. BN → ReLU → Conv 3×3 (padding 1, stride 1) produisant exactement G nouveaux canaux (taux de croissance). La sortie de ce bloc a donc G canaux.
  3. Concaténez (dimension “canaux”) l’entrée du bloc avec ses G nouveaux canaux pour former l’entrée du bloc suivant.

Après K blocs, la sortie du dense block a Cin + K·G canaux.

Transition (détails)

Une transition réduit à la fois le nombre de canaux et la résolution spatiale :

  • BN → ReLU → Conv 1×1 qui réduit les canaux de moitié (arrondi à l’entier inférieur).
  • Average Pooling 2×2 (stride 2) pour diviser largeur et hauteur par 2.

Exemple : si la sortie du dense block a 160 canaux, la transition produit 80 canaux avant le pooling (puis réduit H et W de moitié).

Architecture complète (tailles fixes quand non listées parmi les hyperparamètres)

  • DenseBlock 1 avec K blocs (voir hyperparamètres). Entrée : 64 canaux ⇒ sortie : 64 + K·G canaux.
  • Transition 1 : Conv 1×1 à ⌊(64 + K·G)/2⌋ canaux → AvgPool 2×2.
  • DenseBlock 2 avec K blocs. Entrée : ⌊(64 + K·G)/2⌋ ⇒ sortie : ⌊(64 + K·G)/2⌋ + K·G.
  • Transition 2 : Conv 1×1 à ⌊(⌊(64 + K·G)/2⌋ + K·G)/2⌋ canaux → AvgPool 2×2.
  • DenseBlock 3 avec K blocs. Entrée : ⌊(⌊(64 + K·G)/2⌋ + K·G)/2⌋ ⇒ sortie : entrée + K·G.
  • Tête : AdaptiveAvgPool2d(output_size=1) → aplatir → Linear vers 102 classes.
    Voir nn.AdaptiveAvgPool2d et nn.Linear.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Taux de croissance G (nouveaux canaux ajoutés par bloc) : choisissez 12 ou 24.
  2. Nombre de blocs K par dense block : choisissez 4 ou 6. Utilisez la même valeur K pour les trois dense blocks.

Remarques de mise en œuvre :

  • Tenez un liste/concat des tenseurs à l’intérieur d’un dense block pour alimenter chaque bloc avec torch.cat (dimension canaux).
  • Utilisez padding 1 pour toutes les convolutions 3×3 afin de conserver la taille spatiale à l’intérieur des dense blocks (la réduction spatiale ne se fait que dans les transitions).
  • Gardez l’ordre BN → ReLU → Conv dans les blocs denses, comme décrit ci-dessus.

Projet 21 — Stanford Cars (196 modèles de voitures) avec tête à Spatial Pyramid Pooling (SPP)

Étudiant : OUEDERNI

Dataset : Stanford Cars, 196 classes de modèles de voitures, images couleur de tailles variées. Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.StanfordCars (annotations incluses) ou via un dataset équivalent sur HuggingFace. Redimensionnez (optionnel) ou travaillez en taille variable ; normalisez les images avec torchvision.transforms.

Concept (SPP) : la Spatial Pyramid Pooling produit un vecteur de taille fixe quelle que soit la taille d’entrée en appliquant plusieurs poolings avec des grilles de sortie différentes, puis en concaténant. Vous pouvez implémenter l’équivalent avec plusieurs nn.AdaptiveMaxPool2d aux tailles de sortie 1×1, 2×2 et 4×4, puis aplatir et concaténer.

Modèle à implémenter : CNN 2D en 3 stages, puis tête SPP.

  • Entrée : image RGB 3×H×W (H et W variables ou fixées à 224).
  • Couche d’initialisation : Conv 3×3 (padding 1, 64 canaux) → BatchNorm → ReLU.
  • Stage 1 : deux blocs (Conv 3×3, 64 canaux → BatchNorm → ReLU), puis MaxPool 2×2.
  • Stage 2 : deux blocs (Conv 3×3, 128 canaux → BatchNorm → ReLU), puis MaxPool 2×2.
  • Stage 3 : deux blocs (Conv 3×3, 256 canaux → BatchNorm → ReLU).
  • Tête SPP :
    • Trois branches de pooling : AdaptiveMaxPool2d(1), AdaptiveMaxPool2d(2), AdaptiveMaxPool2d(4).
    • Aplatissez chaque branche et concaténez (dimension totale = 256×(1×1 + 2×2 + 4×4) = 256×21).
    • Couche linéaire : (256×21) → 196.

Modules utiles : nn.Conv2d, nn.BatchNorm2d, nn.ReLU, nn.AdaptiveMaxPool2d, nn.Linear.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de blocs par stage : choisissez {2 ou 3} blocs Conv→BatchNorm→ReLU dans chacun des trois stages (si 3, ajoutez un bloc avant le pooling dans les stages 1 et 2, et à la fin du stage 3).
  2. Type de pooling dans la tête SPP : choisissez entre {AdaptiveMaxPool2d ou AdaptiveAvgPool2d} pour les trois niveaux (1, 2, 4). Utilisez le même type pour tous les niveaux.

Projet 22 — CUB-200-2011 (oiseaux, 200 espèces) avec convolutions groupées (grouped convolutions)

Étudiant : DUMANGE

Dataset : CUB-200-2011, 200 classes d’oiseaux, images couleur, annotations disponibles. Tâche : classification multiclasses.

Où le trouver : via un dataset prêt à l’emploi sur HuggingFace (caltech_birds2011) ou depuis le site officiel. Redimensionnez les images à 224×224 et normalisez-les.

Concept : une grouped convolution divise les canaux d’entrée et de sortie en G groupes ; chaque groupe est convolué indépendamment (paramètre groups de nn.Conv2d). Cela réduit les connexions et le coût, et peut augmenter la diversité des filtres.

Modèle à implémenter : CNN 2D à 3 stages, où la deuxième convolution de chaque bloc est une grouped convolution.

  • Entrée : 3×224×224.
  • Couche d’initialisation : Conv 3×3 (64 canaux, padding 1) → BatchNorm → ReLU.
  • Stage 1 : deux blocs identiques :
    • Conv 3×3 (64 → 64, padding 1) → BatchNorm → ReLU.
    • Conv 3×3 (64 → 64, padding 1, groups = G) → BatchNorm → ReLU.
    Puis MaxPool 2×2.
  • Stage 2 : deux blocs identiques (canaux 128), même schéma, puis MaxPool 2×2.
  • Stage 3 : deux blocs identiques (canaux 256), même schéma, puis Global Average Pooling et linéaire 256 → 200.

Remarque : pour que groups=G soit valide, le nombre de canaux de la convolution doit être divisible par G.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Nombre de groupes G dans les convolutions groupées : choisissez {2, 4}. Assurez-vous que 64, 128 et 256 sont divisibles par G.
  2. Nombre de blocs par stage : choisissez {2 ou 3}. Si 3, ajoutez un bloc supplémentaire avant le pooling (stages 1 et 2) ou avant le GAP (stage 3).

Projet 23 — Tiny ImageNet (200 classes) avec blocs résiduels + Dropout2d dans les blocs

Étudiant : LAURET

Dataset : Tiny ImageNet, 200 classes, images 64×64. Tâche : classification multiclasses.

Où le trouver : via HuggingFace Datasets : zh-plus/tiny-imagenet. Normalisez les images (moyenne/écart-type RGB usuels).

Modèle à implémenter : réseau en blocs résiduels (deux convolutions 3×3 par bloc) avec insertion de nn.Dropout2d à l’intérieur des blocs pour régulariser.

  • Entrée : 3×64×64.
  • Couche initiale : Conv 3×3 (64 canaux, padding 1) → BatchNorm → ReLU.
  • Bloc résiduel (forme générale) :
    • Conv 3×3 (C → C, stride 1, padding 1) → BatchNorm → ReLU → Dropout2d.
    • Conv 3×3 (C → C, stride 1, padding 1) → BatchNorm.
    • Addition résiduelle (projection 1×1 si changement de dimensions) → ReLU.
  • Stage 1 : C=64, empilez B1 blocs, stride 1.
  • Stage 2 : C=128, premier bloc avec stride 2 (réduction spatiale), puis B2−1 blocs stride 1.
  • Stage 3 : C=256, même principe (stride 2 au premier bloc), total B3 blocs.
  • Tête : Global Average Pooling → linéaire 256 → 200.

Modules utiles : nn.Conv2d, nn.BatchNorm2d, nn.Dropout2d, nn.AdaptiveAvgPool2d, nn.Linear.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Taux de Dropout2d à l’intérieur des blocs : choisissez {0.1, 0.3} (même valeur dans tous les blocs).
  2. Nombre de blocs par stage : choisissez (B1, B2, B3) parmi {(2,2,2), (3,3,3)}.

Projet 24 — Caltech-101 (101 classes d’objets) avec blocs « inverted residual » (expansion 1×1 → depthwise 3×3 → projection 1×1)

Étudiant : RAMSIS

Dataset : Caltech-101, ~9 000 images, 101 classes + une classe arrière-plan (optionnelle). Tâche : classification multiclasses.

Où le trouver : via torchvision.datasets.Caltech101. Redimensionnez à 160×160 et normalisez.

Concept : un bloc inverted residual suit la séquence : (1) expansion 1×1 qui augmente le nombre de canaux d’un facteur t, (2) convolution depthwise 3×3 (groupes = canaux, voir groups dans nn.Conv2d), (3) projection 1×1 qui ramène à la largeur souhaitée. Si le stride vaut 1 et que les canaux d’entrée = canaux de sortie, ajoutez une connexion résiduelle (addition entrée + sortie).

Modèle à implémenter : enchaînement de stages de blocs inverted residual.

  • Entrée : 3×160×160.
  • Couche d’initialisation : Conv 3×3 (32 canaux, stride 2, padding 1) → BatchNorm → ReLU.
  • Stage 1 : répéter R1 blocs avec canaux de sortie = 32, stride 1.
  • Stage 2 : premier bloc stride 2, canaux de sortie = 64 ; puis R2−1 blocs stride 1 à 64 canaux.
  • Stage 3 : premier bloc stride 2, canaux de sortie = 128 ; puis R3−1 blocs stride 1 à 128 canaux.
  • Tête : Global Average Pooling → linéaire 128 → 101.

Activations : utilisez ReLU6 (ou ReLU) après les convolutions 1×1 d’expansion et la depthwise 3×3 ; la projection 1×1 est suivie d’aucune activation. Voir nn.ReLU6.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Facteur d’expansion t dans les blocs inverted residual : choisissez {4, 6}. Le nombre de canaux dans la convolution depthwise est alors t × (canaux d’entrée du bloc).
  2. Nombre de répétitions par stage : choisissez (R1, R2, R3) parmi {(2,2,2), (3,3,3)}.

Projet 25 — EuroSAT RGB (classification de scènes satellitaires, 10 classes) avec convolutions dilatées au dernier stage

Étudiant : BEN-GELOUNE

Dataset : EuroSAT RGB, 10 classes (différents types d’occupation du sol), images 64×64 issues de Sentinel-2. Tâche : classification multiclasses.

Où le trouver : via un dataset prêt à l’emploi sur HuggingFace (eurosat, configuration rgb), ou via des miroirs publics. Les images sont 64×64 ; normalisez-les.

Concept : les convolutions dilatées (dilated) agrandissent le champ réceptif sans augmenter le nombre de paramètres (paramètre dilation de nn.Conv2d). Utilisez-les uniquement dans le dernier stage pour capter un contexte plus large.

Modèle à implémenter : CNN 2D en 3 stages (Conv→BatchNorm→ReLU répétés), dilatation au stage 3.

  • Entrée : 3×64×64.
  • Stage 1 : deux blocs, chacun : Conv 3×3 (64 canaux, stride 1, padding 1, dilation 1) → BatchNorm → ReLU ; puis MaxPool 2×2 après le second bloc.
  • Stage 2 : deux blocs à 128 canaux, mêmes paramètres (dilation 1), puis MaxPool 2×2.
  • Stage 3 : deux blocs à 256 canaux, chaque Conv 3×3 utilise dilation D et un padding égal à D pour conserver la taille (stride 1). Pas de MaxPool ici.
  • Tête : Global Average Pooling → linéaire 256 → 10.

Modules utiles : nn.Conv2d (paramètres dilation et padding), nn.BatchNorm2d, nn.MaxPool2d, nn.AdaptiveAvgPool2d, nn.Linear.

Fonction de perte : CrossEntropyLoss.

Hyperparamètres du modèle à régler (2) :

  1. Dilation D au stage 3 : choisissez {2, 3}. Ajustez le padding à D pour garder la même taille spatiale.
  2. Nombre de blocs par stage : choisissez {2 ou 3}. Si 3, ajoutez un bloc supplémentaire (même configuration) avant le pooling des stages 1 et 2, et avant le GAP du stage 3.

Avant de commencer : votre fichier de configuration (configs/config.yaml)

Qu’est-ce que YAML ?

YAML est un format texte lisible par l’humain pour décrire des paramètres sous forme de paires clé : valeur, de listes et d’objets imbriqués. C’est comparable au JSON, mais plus agréable à lire et à éditer. Exemple :

# Exemple minimal (vous adapterez ces valeurs à votre projet)
dataset:
  name: "CIFAR100"
  root: "./data"
  download: true

model:
  type: "cnn_basic"
  num_classes: 100
  # hyperparamètres du modèle (exemples)
  channels: [64, 128, 256]
  blocks_per_stage: [2, 2, 2]

train:
  seed: 42
  batch_size: 64
  epochs: 20

paths:
  runs_dir: "./runs"
  artifacts_dir: "./artifacts" 

Pourquoi l’utiliser ici ?

  • Séparation clair(e) entre code et paramètres : vous modifiez vos choix (dataset, tailles, etc.) sans toucher au code Python.
  • Reproductibilité : le fichier de config documente exactement ce qui a été exécuté.
  • Traçabilité : vous pouvez sauvegarder une copie de la config aux côtés des résultats (./artifacts/ et ./runs/).
  • Expérimentation rapide : une même base de code, plusieurs configurations.

Où le mettre et comment l’utiliser ?

  • Le fichier se trouve dans configs/config.yaml (déjà présent dans le dépôt modèle).
  • Les scripts lisent ce fichier via l’argument --config.
    Exemples :
    python -m src.train --config configs/config.yaml
    python -m src.lr_finder --config configs/config.yaml
    python -m src.grid_search --config configs/config.yaml
    python -m src.evaluate --config configs/config.yaml --checkpoint artifacts/best.ckpt
    
  • Vous pouvez dupliquer le fichier pour essayer des variantes (ex. configs/config_v2.yaml) et passer le chemin correspondant.

Règles de base YAML (éviter les erreurs)

  • Indentation avec des espaces (pas de tabulations). Généralement 2 espaces par niveau.
  • Les listes peuvent être écrites - item sur plusieurs lignes, ou en ligne [a, b, c].
  • Les booléens s’écrivent true/false (minuscule).
  • Les chaînes peuvent être non-quotées (name: CIFAR100) ou entre guillettes ("CIFAR100") si votre valeur contient des espaces ou caractères spéciaux.
  • Les commentaires commencent par # et vont jusqu’à la fin de la ligne.

Que doit contenir votre config.yaml pour ce projet ?

Conservez ces sections (clés) : dataset, preprocess, augment, model, train, metrics, paths. Elles sont lues par les scripts fournis et par vos fonctions dans src/.

Liens utiles (fichiers du dépôt)

  • configs/config.yaml — fichier de configuration à compléter.
  • src/train.py — lit la config et lance l’entraînement.
  • src/data_loading.py, src/preprocessing.py, src/augmentation.py — utilisent les paramètres de la config pour préparer les données.

1) Données : préparation, prétraitements et augmentations

1.1 Installer l’environnement (si ce n'est pas fait)

  1. Créez/activez votre environnement (conda ou venv), puis installez les dépendances :
    pip install -r requirements.txt

    Référence dépôt : requirements.txt

  2. Vérifiez que tensorboard et torch se lancent sans erreur (versions affichées).

1.2 Téléchargement et chargement du dataset

Important SLURM : téléchargez les données pendant une réservation (nœud de calcul), pas sur le contrôleur Slurm. Placez les fichiers dans ./data/ ou le chemin défini dans votre config.

  1. Renseignez la section dataset dans configs/config.yaml (nom du dataset, chemin root, options de téléchargement si disponibles).
  2. Implémentez/complétez la fonction :

    Référence dépôt : src/data_loading.pyget_dataloaders(config) -> (train, val, test, meta)

    • train/val/test doivent être des DataLoader PyTorch.
    • meta doit contenir au minimum {"num_classes": int, "input_shape": tuple}.
  3. Si le dataset ne fournit pas de split val :
    • Créez une validation stratifiée (classification) ou un split temporel cohérent (séries temporelles).
    • Documentez la seed utilisée pour garantir la reproductibilité.

À rédiger dans le rapport

  • D1. Quel dataset utilisez-vous ? D’où provient-il (lien source) et quel est son format (dimensions, type d’entrée) ?
  • D2. Donnez la taille de chaque split (train/val/test) et le nombre de classes. Ajoutez le contenu de meta (num_classes, input_shape).
  • D3. Si vous avez créé un split, expliquez comment (stratification, ratio, seed).

1.3 Statistiques exploratoires minimales

Calculez et affichez rapidement des informations utiles :

  • Distribution des classes (compte par classe). Si elle est très déséquilibrée, notez-le.
  • Valeurs manquantes (si texte/tabulaire) ou longueurs de séquence (NLP/Audio).
  • Tailles d’images (si non uniformes) et éventuels canaux alpha.

Vous pouvez consigner ces informations dans TensorBoard (onglet Text) ou dans le rapport.

À rédiger dans le rapport

  • D4. Donnez la distribution des classes (graphique simple ou tableau). Commentez en une ou deux phrases les implications pour l’entraînement.
  • D5. Mentionnez toute particularité détectée (longueurs variables, tailles d’images variées, étiquettes multi-labels, etc.).

1.4 Prétraitements (preprocessing)

Implémentez les transformations invariantes (appliquées à train/val/test) dans :

Référence dépôt : src/preprocessing.pyget_preprocess_transforms(config)

Choisissez des paramètres fixes (non à chercher en grille) adaptés à la modalité :

  • Vision : redimensionnement (ex. 64, 96, 128, 224), recadrage central (pour val/test), normalisation par moyenne/écart-type, conversion en tenseur.
  • Audio : mono, rééchantillonnage (ex. 16 kHz), mel-spectrogram (paramètres fixes si non demandés comme hyperparamètres du modèle), conversion en dB/normalisation.
  • NLP : tokenisation, vocabulaire, padding/truncation à une longueur fixe (si non hyperparamètre du modèle), encodage numérique.
  • Séries temporelles : normalisation par canal, fenêtrage si nécessaire.

À rédiger dans le rapport

  • D6. Listez les prétraitements appliqués (opérations + paramètres exacts, par ex. résolution, normalisation, longueur max). Justifiez brièvement pourquoi chaque opération est nécessaire.
  • D7. Indiquez si vos prétraitements diffèrent entre train/val/test (ils ne devraient pas, sauf recadrage aléatoire interdit en val/test).

1.5 Augmentation de données (train uniquement)

Implémentez les transformations aléatoires (appliquées uniquement à l’entraînement) dans :

Référence dépôt : src/augmentation.pyget_augmentation_transforms(config)

Idées d’augmentations par modalité (choisissez pertinent et raisonnable) :

  • Vision : flips horizontaux, rotations modestes, recadrage aléatoire suivi de redimensionnement, léger color jitter, RandomErasing (petit), cutout simple.
  • Audio (spectrogrammes) : masquage de bandes de fréquence/temps (version légère de SpecAugment), léger décalage temporel. Attention : gardez les étiquettes identiques.
  • NLP : éviter les augmentations qui modifient le sens des phrases si vous n’êtes pas sûr·e. Dropout sur embeddings (dans le modèle) peut jouer un rôle de régularisation.
  • Séries temporelles : jitter de faible amplitude, scaling léger par canal, window cropping si la tâche le permet.

À rédiger dans le rapport

  • D8. Quelles augmentations avez-vous appliquées en train ? Donnez les paramètres (ex. probabilité, amplitude) et la justification (invariances attendues).
  • D9. Les augmentations conservent-elles les labels (label-preserving) ? Expliquez pour chaque transformation retenue.

1.6 Vérifications rapides (recommandées)

  • Affichez quelques exemples après prétraitement/augmentation pour vérifier les formes, plages de valeurs et labels (vous pouvez sauver 4–8 images/spectrogrammes en PNG dans artifacts/ pour le rapport).
  • Vérifiez que les DataLoaders shufflent le train (et pas val/test), et que les batchs ont les formes attendues (meta["input_shape"]).
  • Assurez-vous que les classes (indices/labels) correspondent bien aux logits de sortie du modèle (ordre et cardinalité).

À rédiger dans le rapport

  • D10. Montrez 2–3 exemples visuels (ou textuels) après prétraitements/augmentations. Commentez en une phrase ce que vous observez.
  • D11. Donnez la forme exacte d’un batch train (par ex. (batch_size, canaux, hauteur, largeur) ou (batch_size, longueur)) et vérifiez la cohérence avec meta["input_shape"].

1.7 Raccord avec la configuration et les scripts

  • Les chemins (dataset.root, paths.runs_dir, paths.artifacts_dir) sont définis dans configs/config.yaml.
  • Vos fonctions doivent être appelées par les scripts d’entraînement et d’évaluation :
    • Référence dépôt : src/train.py (utilise get_dataloaders, get_preprocess_transforms, get_augmentation_transforms).
    • Référence dépôt : src/evaluate.py (utilise les mêmes prétraitements sans augmentations).

1.8 Check-list (avant de passer au modèle)

  • get_dataloaders retourne train, val, test et meta complets.
  • ✅ Les prétraitements sont identiques entre val/test (pas d’aléatoire).
  • ✅ Les augmentations ne s’appliquent qu’au train et conservent les labels.
  • ✅ Les tailles/labels/ordres de classes sont cohérents avec la tête de votre futur modèle.

2) Implémentation du modèle & recherche d’hyperparamètres

Objectif : suivre la procédure vue en cours pour passer d’un modèle fonctionnel à un entraînement reproductible, en documentant chaque étape avec des courbes et des choix argumentés. Toutes les actions ci-dessous s’appuient sur la structure du dépôt fournie.

2.0 Baselines « aléatoire » et « classe majoritaire »

  1. Classe majoritaire : calculez la distribution des classes (section Données), prédisez toujours la classe la plus fréquente et mesurez la métrique pertinente (accuracy, F1 macro si jeu fortement déséquilibré, mAP pour multi-label). Consignez le résultat dans le rapport.
  2. Prédiction aléatoire uniforme : simulez des prédictions au hasard (probabilité égale pour chaque classe) et calculez la métrique. Cela vous donne un plancher à dépasser dès les premiers essais.

À rédiger dans le rapport

  • M0. Donnez la performance classe majoritaire et la performance aléatoire (avec la métrique choisie). Expliquez en 2 lignes ce que ces chiffres impliquent pour votre tâche.

2.1 Implémenter le modèle

Références dépôt : src/model.py (fonction build_model(config)), src/utils.py (fonctions utilitaires), configs/config.yaml (section model).

  1. Implémentez build_model(config) selon la description du projet qui vous est assigné (couches, ordres, paramètres par défaut, etc.). Utilisez exclusivement des modules PyTorch standards (voir les liens dans votre fiche projet).
  2. Assurez-vous que la forme de sortie est correcte :
    • Classification multi-classe : logits de forme (batch_size, num_classes).
    • Classification multi-label : logits de forme (batch_size, num_attributes).
  3. Initialisez une graine (seed) stable via src/utils.py et loggez-la (TensorBoard ou texte).
  4. Comptez les paramètres entraînables et vérifiez que le modèle respecte des contraintes raisonnables (pas de réseau gigantesque). Utilisez count_parameters(model) (à implémenter) pour obtenir un entier.

À rédiger dans le rapport

  • M1. Décrivez l’architecture (liste de couches, tailles, ordres) et donnez le nombre total de paramètres. Expliquez brièvement le rôle des 2 hyperparamètres propres au modèle que vous allez régler (ceux fournis dans la fiche projet).

2.2 Vérification « premier batch » et perte initiale

Références dépôt : src/train.py (prépare un mini-batch), src/data_loading.py (formes).

  1. Chargez un batch d’entraînement et faites un forward pass avec le modèle.
  2. Calculez la loss sur ce batch en utilisant la loss définie par votre projet :
    • Multi-classe : CrossEntropyLoss.
    • Multi-label : BCEWithLogitsLoss.
  3. Attendu (multi-classe) : si vos logits initiaux sont proches de 0 (softmax ≈ uniforme), la perte initiale s’approche typiquement de -log(1/num_classes). Exemple : 100 classes ⇒ ~4.61.
  4. Effectuez un pas de rétropropagation sur ce batch et vérifiez que les normes de gradients ne sont pas nulles (loggez une valeur simple, p.ex. somme des normes).

À rédiger dans le rapport

  • M2. Donnez la loss initiale sur un batch et dites si elle est cohérente avec l’intuition ci-dessus. Indiquez la forme du batch (données et cibles) et la forme de sortie du modèle.

2.3 Overfit sur un très petit échantillon

Références dépôt : src/train.py (flag --overfit_small), configs/config.yaml (section train), runs/ (TensorBoard).

  1. Sélectionnez un très petit sous-ensemble du train (par ex. 16 à 64 exemples). Vous pouvez implémenter un sampler dédié ou un mode « overfit_small » qui tronque le DataLoader.
  2. Choisissez des hyperparamètres (ceux propres au modèle fournis dans votre fiche projet) et un learning rate suffisamment grand pour que la loss train tende vers 0 sur ce petit set. Vous pouvez utiliser un weight decay faible (p.ex. 0 ou 1e-5).
  3. Entraînez quelques époques (jusqu’à sur-apprendre). Loggez train/loss à chaque itération ou époque dans TensorBoard.

À rédiger dans le rapport

  • M3. Indiquez la taille du sous-ensemble, les hyperparamètres du modèle utilisés (les 2 à régler) et la courbe train/loss montrant l’overfit (capture TensorBoard). Expliquez en 2 lignes ce qui prouve l’overfit.

2.4 Trouver un learning rate qui fait descendre la loss

Références dépôt : src/lr_finder.py (génère un balayage LR → loss), runs/ (tags lr_finder/lr et lr_finder/loss).

  1. Exécutez un LR finder : faites varier le LR de très petit à plus grand (échelle logarithmique) sur un petit nombre d’itérations, et loggez (LR, loss) pour tracer la courbe.
  2. Repérez une fenêtre de LR stable où la loss diminue sans divergence (évitez la zone où la loss explose).
  3. Fixez un pair (LR, weight decay) raisonnable pour les prochains essais rapides (ex. weight decay dans {1e-4, 1e-5}).

À rédiger dans le rapport

  • M4. Donnez le LR choisi et le weight decay retenu pour la suite, avec la courbe LR→loss (capture TensorBoard). Expliquez votre choix en 2–3 phrases.

2.5 Mini grid search (rapide) autour des paramètres trouvés

Références dépôt : src/grid_search.py (lit hparams dans la config), runs/ (HParams/Scalars), configs/config.yaml (section hparams).

  1. Définissez de petites grilles :
    • LR : 2–3 valeurs autour de celle choisie (ex. ×0.5, ×1, ×2).
    • Weight decay : {1e-5, 1e-4} (si pertinent pour la tâche).
    • Hyperparamètres du modèle (2) : utilisez exactement ceux de votre fiche projet (ex. « nombre de blocs », « largeur des stages », « taille cachée du RNN », etc.) avec 2 valeurs chacun.
  2. Lancez des essais courts (1 à 5 époques selon le dataset) pour comparer rapidement. Conservez le même seed pour isoler l’effet des hyperparamètres.
  3. Nommez les exécutions de façon univoque (ex. runs/projXX_lr=1e-3_wd=1e-4_blocks=3_width=256) et loggez les hparams dans TensorBoard (onglet HParams si vous l’implémentez).

À rédiger dans le rapport

  • M5. Présentez un tableau récapitulatif (ou capture HParams) avec les combinaisons testées et la meilleure métrique de validation atteinte par combinaison. Commentez brièvement ce que changent vos 2 hyperparamètres de modèle sur les courbes (stabilité, vitesse de convergence, overfit).

2.6 Entraînement complet sur les meilleures configurations

Références dépôt : src/train.py (flags --max_epochs/--max_steps), runs/, artifacts/.

  1. Sélectionnez 1–2 configurations gagnantes d’après la grid search.
  2. Entraînez 10 à 20 époques (selon dataset) sans scheduler (pas de LR decay pour cette phase, sauf si explicitement demandé par votre fiche projet).
  3. Sauvegardez le meilleur checkpoint (selon validation) sous artifacts/best.ckpt et exportez la courbe d’apprentissage (train/val loss, métriques val) dans TensorBoard avec des noms de tags exacts :
    • train/loss, val/loss (obligatoires)
    • au moins une métrique de classification si applicable : val/accuracy ou val/f1 (obligatoire pour classification)

À rédiger dans le rapport

  • M6. Donnez la configuration finale (LR, weight decay, les 2 hyperparamètres de modèle), et montrez les courbes train/val (loss + métrique). Interprétez : sous-apprentissage, sur-apprentissage, stabilité.

2.7 Comparaisons de courbes et analyse

Dans TensorBoard, affichez plusieurs runs superposés pour comparer l’effet :

  • du LR (courbe train/loss au début d’entraînement) ;
  • du weight decay (écart train/val) ;
  • des 2 hyperparamètres de modèle (vitesse de convergence, plateau, overfit/underfit).

Exportez 2–3 figures lisibles (captures d’écran) pour le rapport.

À rédiger dans le rapport

  • M7. Trois comparaisons commentées (une phrase chacune) : (i) variantes de LR, (ii) variantes de weight decay, (iii) variantes des hyperparamètres de modèle. Dites ce que vous attendez de la courbe et ce que vous observez réellement.

2.8 Boucle « Répéter » (si temps)

Si le temps le permet, refaites une mini grid en resserrant les valeurs autour de la meilleure configuration, ou testez l’autre valeur des hyperparamètres de modèle que vous n’avez pas encore explorée. Conservez un suivi clair des runs et des configs (sauvegardez un snapshot YAML à chaque essai dans artifacts/ via save_config_snapshot).

À rédiger dans le rapport

  • M8. Décrivez une itération supplémentaire (qu’avez-vous modifié, pourquoi, résultat).

2.9 Évaluation finale sur test

Références dépôt : src/evaluate.py (argument --checkpoint artifacts/best.ckpt), runs/ (vous pouvez logguer une matrice de confusion/PR curve si utile).

  1. Chargez le meilleur checkpoint et évaluez sur le split test (aucune augmentation).
  2. Rapportez les métriques demandées par votre tâche (accuracy / F1 macro / mAP…).

À rédiger dans le rapport

  • M9. Donnez les résultats test (métriques) et interprétez-les au regard de vos courbes de validation (écart attendu / surprenant ?).

2.10 Bonnes pratiques de journalisation

  • Utilisez des noms de runs explicites incluant LR, weight decay et vos 2 hyperparamètres de modèle.
  • Logguez systématiquement train/loss, val/loss et au moins une métrique de validation (val/accuracy ou val/f1).
  • Ajoutez au besoin : learning rate courant, gradient norm global (une valeur), temps par époque.
  • Nettoyez runs/ en fin de projet pour ne garder que les exécutions utiles au rapport.

Raccourcis dépôt (où brancher votre code)

  • src/model.py — construire le modèle (build_model).
  • src/train.py — entraînement complet (supporte --config, --seed, --max_epochs, --overfit_small, etc.).
  • src/lr_finder.py — balayage LR et logging.
  • src/grid_search.py — mini grille (lit hparams de la config), enchaîne plusieurs runs courts.
  • src/evaluate.py — évaluation du meilleur checkpoint sur test.
  • src/utils.py — seed, device, comptage des paramètres, sauvegarde d’un snapshot de config.

Checklist rapide (modèle & hparams)

  • ✅ Le modèle compile et les shapes sont correctes (entrée/sortie, loss adaptée).
  • ✅ La loss initiale est cohérente (et débuggée sur un batch).
  • Overfit small obtenu (train/loss ↓ vers 0 sur un mini-subset).
  • LR choisi via LR finder, grid rapide effectuée (LR, weight decay, 2 hyperparamètres de modèle).
  • ✅ Entraînement 10–20 époques sur la/les meilleure(s) config(s), best.ckpt sauvegardé.
  • ✅ Courbes comparatives claires dans TensorBoard + captures dans le rapport.
  • ✅ Évaluation finale sur test rapportée et interprétée.

Contraintes techniques (obligatoires)

  • Arborescence et chemins :
    • Logs TensorBoard : runs/
    • Meilleur checkpoint : artifacts/best.ckpt
    • Config principale : configs/config.yaml
  • Tags TensorBoard (scalars) à fournir :
    • Obligatoires : train/loss, val/loss
    • Classification (au moins un) : val/accuracy ou val/f1
    • LR Finder (recommandé) : lr_finder/lr, lr_finder/loss
  • Scripts à utiliser :
    • Entraînement : python -m src.train --config configs/config.yaml
    • LR finder : python -m src.lr_finder --config configs/config.yaml
    • Grid search : python -m src.grid_search --config configs/config.yaml
    • Évaluation : python -m src.evaluate --config configs/config.yaml --checkpoint artifacts/best.ckpt
  • Reproductibilité :
    • Fixer une graine unique (section train.seed).
    • Consigner un snapshot de config avec vos runs (fonction utilitaire prévue).

Budget compute & temps

  • Durée visée pour un run complet (meilleure config) : 60-120 min sur GPU standard.
  • Garde-fous :
    • Époques : 10–20 pour l’entraînement final (voir procédure).
    • Paramètres du modèle : rester raisonnable (< ~10M recommandé selon le projet).
    • Grid search : runs courts (1–5 époques).

Barème (100 pts)

  • Procédure en 6 étapes documentée (60 pts) — 10 pts par étape :
    1. Baselines et perte initiale (captures/explications)
    2. Overfit sur petit échantillon
    3. LR finder et choix de la fenêtre
    4. Mini grid (LR, weight decay, 2 hyperparamètres de modèle)
    5. Entraînement complet + meilleur checkpoint
    6. Courbes d’apprentissage et interprétation
  • Correction technique (15 pts) — shapes, pertes adaptées, métriques, pas de fuites de labels.
  • Expérimentation (10 pts) — comparaisons claires, noms de runs explicites, cohérence des essais.
  • Analyse (10 pts) — liens avec sous/sur-apprentissage, effet des hyperparamètres du modèle.
  • Reproductibilité (5 pts) — config snapshot, seed, scripts utilisables.
  • Bonus (+5 pts) — rapport particulièrement clair et soigné.

Checklist finale

  • report_template.md rempli, avec captures (baselines, overfit small, LR finder, grid, courbes finales).
  • runs/ contient uniquement les runs utiles avec les tags exigés.
  • artifacts/best.ckpt présent et chargeable par src/evaluate.py.
  • configs/config.yaml cohérent avec la meilleure config reportée.
  • ✅ Noms de runs explicites (LR, WD, hyperparamètres modèle).

Intégrité académique (rappel)

Les outils d’assistance de code sont autorisés, mais votre évaluation porte sur vos expériences (logs, checkpoints, courbes) et votre analyse. Citez les ressources externes si vous en utilisez. Toute forme de plagiat de code/rapport est proscrite.