Partie 5 · Apprendre
Le réseau des organes
Place au réseau de la partie 4 du cours : 784 → 128 → 64 → 11, entraîné sur les coupes de scanner d'OrganAMNIST : 34 561 images d'entraînement, soit 541 paquets par époque (paquets de 64). Il y a 11 organes à reconnaître : le réseau renvoie 11 scores, un par organe. Tu feras d'abord deux vérifications avant d'entraîner, puis tu suivras les courbes, puis tu compareras zéro, une et deux couches cachées.
Le réseau : nn.Flatten(), nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 64), nn.ReLU(), nn.Linear(64, 11). Pas de softmax à la fin : nn.CrossEntropyLoss reçoit les scores bruts et l'applique elle-même (donner des probabilités serait l'erreur de la « double softmax »). Pourquoi une fonction creer_reseau() ? Pour fabriquer un réseau neuf, aux poids tirés au hasard, à chaque appel.
Compter les paramètres
Une couche nn.Linear(entrées, sorties) a entrées × sorties poids et sorties biais. Pour le réseau complet : 784 × 128 + 128 = 100 480, puis 128 × 64 + 64 = 8 256, puis 64 × 11 + 11 = 715. Total : 109 451 paramètres. Le réseau sans couche cachée (784 → 11) en a 8 635 ; avec une seule couche cachée de 128 neurones, 101 899.
À toi de coder
Deux vérifications avant d'entraîner (partie 9)
1. La perte au départ. Un réseau neuf donne à peu près le même score à chaque organe : sa perte doit valoir environ −log(1/11) ≈ 2,40. Sur le premier paquet, le notebook obtient 2,37 (le contrôle accepte ±0,25). Une valeur très différente signale un mauvais format d'étiquettes ou une softmax en trop.
2. Un seul paquet, appris par cœur. Avec un réseau neuf, 100 pas d'apprentissage sur le même paquet de 64 images : avec 109 451 paramètres, le réseau doit le retenir, et la perte tomber près de 0. Le notebook passe de 2,366 à 0,0013. Si ce n'est pas le cas, la boucle a un problème (étapes 3, 4 ou 5).
Autre piège de format : MedMNIST range les numéros d'organes en colonne, de forme (64, 1), alors que CrossEntropyLoss les attend en liste d'entiers : d'où etiquettes.squeeze(1).long().
À toi de coder
Entraîner et suivre les courbes
La fonction evaluer est celle de l'exercice 4, adaptée aux 11 organes : le réseau choisit l'organe au plus grand score, avec argmax(dim=1). Après 5 époques d'entraînement, le notebook affiche :
| Époque | Perte entraînement | Perte validation | Accuracy validation |
|---|---|---|---|
| 1 | 0,627 | 0,388 | 90,1 % |
| 2 | 0,246 | 0,406 | 90,3 % |
| 3 | 0,132 | 0,459 | 90,0 % |
| 4 | 0,082 | 0,467 | 90,5 % |
| 5 | 0,056 | 0,547 | 89,2 % |
Compare avec la note à battre : répondre toujours l'organe le plus fréquent donne 15,9 %. Le réseau fait donc bien mieux (89,2 %). Mais lis les courbes : la perte d'entraînement baisse sans cesse, alors que celle de validation remonte dès l'époque 2. Les deux pertes ne baissent pas ensemble : c'est le signe du sur-apprentissage, objet de la partie suivante.
Zéro, une ou deux couches cachées ?
L'exercice 5.2 du notebook demande d'entraîner « trois réseaux » 3 époques chacun. Mais le code rendu appelle trois fois entrainer_et_noter(creer_reseau(), 3), et creer_reseau() renvoie toujours le même réseau 784 → 128 → 64 → 11 (109 451 paramètres). Les trois accuracy de validation (90,7 %, 89,7 %, 90,0 %) sont donc trois entraînements du même réseau : elles montrent seulement l'écart dû au hasard, environ 1 point, et ne comparent aucune architecture.
Pour comparer 0, 1 et 2 couches cachées, il faudrait passer sans_couche (784 → 11, 8 635 paramètres), une_couche (784 → 128 → 11, 101 899 paramètres), puis creer_reseau() (109 451 paramètres). Le notebook ne donne aucun résultat chiffré pour cette comparaison ; ce que tu peux retenir, ce sont les nombres de paramètres : 11,8 fois plus pour une couche, 12,7 fois plus pour deux. Et qu'on juge un modèle sur la validation, pas sur le nombre de paramètres.
À toi de coder
Pour aller plus loin (notebook) : remplace Adam par torch.optim.SGD(modele.parameters(), lr=0.1) dans entrainer_et_noter, puis essaie lr=0.01 et lr=1. Quel pas marche le mieux ? (Lien avec la partie 3 : un pas trop petit avance lentement, un pas trop grand fait remonter la perte.) Le notebook ne donne pas de résultat chiffré.