Aller au contenu
Apprendre.
  • M1 · toutes les matières15 matières : Préparation de données, API & sécurité, CI/CD, Docker, Merise, Dataviz, KNIME, ML appliqué : projet LoL, SQL & UML, SQL avancé, Machine Learning, Git, IA frugale & responsable, Qualité des données, MathématiquesAnnée
  • M2 · toutes les matières4 matières : Deep Learning, AI Act, Comex & Fundraising, Gouvernance & DataMeshAnnée
  • Deep LearningM2 · 4 modules · Réseaux de neurones, CNN, texte, modèles génératifs.Matière
  • Préparation de donnéesM1 · 3 modules · Nettoyer, transformer et fusionner des données avec Python.Matière
  • API & sécuritéM1 · 2 modules · Consommer, concevoir et sécuriser des API.Matière
  • CI/CDM1 · 1 module · Intégration et livraison continues.Matière
  • DockerM1 · 3 modules · Conteneurs, images, volumes, réseaux, Compose.Matière
  • MeriseM1 · 2 modules · Modéliser une base : MCD, MLD, MPD.Matière
  • DatavizM1 · 2 modules · Visualiser pour comprendre et décider.Matière
  • KNIMEM1 · 1 module · Explorer et nettoyer des données en workflow.Matière
  • ML appliqué : projet LoLM1 · 2 modules · Du besoin métier au POC de vision par ordinateur.Matière
  • SQL & UMLM1 · 3 modules · Modèles UML et requêtes SQL.Matière
  • SQL avancéM1 · 3 modules · Jointures, fenêtres, CTE, optimisation.Matière
  • Machine LearningM1 · 3 modules · Régression, classification, segmentation, projet.Matière

↑↓ naviguer↵ ouvre le résultat en surbrillanceesc fermer

Partie 4 · Apprendre

Un neurone pour la pneumonie

Jusqu'ici tu as calculé à la main (et avec PyTorch) un neurone sur six patients. Place au premier vrai modèle entraîné sur de vraies images : un neurone qui lit les 784 pixels d'une radiographie (PneumoniaMNIST, 28 × 28) et donne une probabilité de pneumonie. L'objectif de l'exercice 4 : faire mieux qu'un programme qui répond toujours « pneumonie ».

Les données : 4 708 images pour apprendre, 524 pour la validation. Chaque image devient un tenseur de forme (1, 28, 28) : 1 canal (niveaux de gris), 28 lignes, 28 colonnes. Les pixels sont ramenés entre −1 et 1 (Normalize(mean=0.5, std=0.5)).

D'abord, la note à battre

Un programme qui répond toujours « pneumonie » a pour note la part de radiographies avec pneumonie. Sur les images de validation : 74,2 % de bonnes réponses. C'est la note à battre : un modèle à 70 % serait pire que ce programme sans intelligence. Les étiquettes valent 1 pour une pneumonie, 0 sinon, donc la part se calcule par une moyenne (en .float() avant .mean()).

Les images sont distribuées par paquets (DataLoader) : train_loader par paquets de 64, mélangés à chaque époque ; val_loader par paquets de 256, sans mélange.

À toi de coder

Paquets et note à battre

Pourquoi : avant d'entraîner, il faut savoir combien de pas fait une époque et quelle note battre. Complète nb_paquets (paquets d'entraînement de 64 images, sur n_train = 4 708) et nb_paquets_val (paquets de 256, sur n_val = 524) : le dernier paquet peut être incomplet mais il compte. Puis calcule note_a_battre : la part de 1 dans la petite liste etiquettes (exemple ajouté de 8 radiographies).

Ctrl/⌘+Entrée
Exemple ajouté (2 pixels au lieu de 784, 12 images inventées) : tourne les poids et le biais. La droite z = 0 sépare « pneumonie » de « normale ». Bats la stratégie qui répond toujours « pneumonie » (8 / 12 ici). Le vrai neurone fait pareil dans un espace à 784 dimensions.

Le neurone : 785 paramètres

Avec nn.Sequential : nn.Flatten() met l'image à plat en 784 nombres, puis nn.Linear(784, 1) : un neurone avec 784 poids et 1 biais, soit 785 paramètres. Il renvoie un score, pas de sigmoïde à la fin : la perte s'en charge. nn.BCEWithLogitsLoss() applique la sigmoïde puis l'entropie croisée de BCELoss (exercice 2), en une seule étape plus stable ; elle attend les étiquettes en décimaux (etiquettes.float()). L'optimiseur : Adam, pas par défaut 0,001.

Perte de départ. Un neurone qui n'a rien appris donne environ 0,5 à chaque image, donc une perte proche de −log(0,5) ≈ 0,69 (le notebook accepte un écart de 0,25 autour de 0,69).

À toi de coder

La perte BCE depuis des scores

Pourquoi : BCEWithLogitsLoss n'a rien de magique, tu peux la refaire. Elle reçoit des scores : on les transforme en probabilité avec la sigmoïde 1 / (1 + e−z), puis on prend −log de la probabilité de la bonne réponse (a pour une pneumonie, 1 − a sinon), en moyenne. Complète sigmoide(z) et perte(scores, etiquettes). depart est la perte de 4 scores nuls (le neurone neuf) ; apres celle de scores plus raisonnables.

Ctrl/⌘+Entrée

Mesurer la note : evaluer

La fonction evaluer calcule la perte moyenne et l'accuracy (la part de bonnes réponses) sur un jeu d'images, sans calculer de pentes (torch.no_grad()). Piège classique : le modèle renvoie des scores, pas des probabilités. Le modèle répond « pneumonie » quand sa probabilité dépasse 0,5, c'est-à-dire quand le score dépasse 0 (la sigmoïde vaut 0,5 en 0) : choix = (scores > 0).long(). Comparer le score à 0,5 est une erreur.

À toi de coder

Choisir et compter les bonnes réponses

Pourquoi : c'est le cœur de evaluer. Huit radiographies ont reçu les scores de la liste scores ; les vraies étiquettes sont dans etiquettes. Complète choix (1 si le score dépasse 0, sinon 0), puis bonnes (nombre de cas où le choix égale l'étiquette) ; accuracy est la part de bonnes réponses.

Ctrl/⌘+Entrée

L'entraînement : cinq étapes, cinq époques

La boucle d'une époque, pour chaque paquet : (1) prédire scores = modele(images), (2) mesurer l'erreur loss_fn(scores, etiquettes.float()), (3) effacer les anciennes pentes optimizer.zero_grad(), (4) calculer les pentes perte.backward(), (5) faire un pas optimizer.step(). À chaque époque on note la perte d'entraînement (moyenne sur les paquets) et la perte de validation. Les 74 paquets défilent 5 fois.

Résultats du notebook :

ÉpoquePerte entraînementPerte validationAccuracy validation
10,3760,26691,8 %
20,2300,20394,1 %
30,1920,17994,8 %
40,1750,16395,6 %
50,1640,15695,0 %

Les deux pertes baissent ensemble : le neurone apprend sans sur-apprendre.

Les chiffres exacts du notebook (exercice 4) : fais avancer les époques. Après 5 époques le neurone atteint 95,0 % de bonnes réponses sur la validation, contre 74,2 % pour « toujours pneumonie ».

La limite du neurone

Le neurone fait mieux que la note à battre (95,0 % contre 74,2 %, question 5.2 du notebook), mais il lit les pixels un par un, sans savoir lesquels sont voisins : il donne un poids à chaque case, comme s'il n'y avait pas de formes. Qu'est-ce qui pourrait l'aider ? Des couches cachées, qui repèrent des motifs (partie suivante), puis, en J2, des réseaux faits pour les images.

Pour aller plus loin (notebook) : entraîne 10 époques au lieu de 5. La perte de validation continue-t-elle de baisser ? Ce résultat n'est pas dans le notebook : à toi de l'observer.