La perte : à quel point le réseau se trompe-t-il?
- Leçon 7
- 50 min
- Module 3 : Comment les réseaux de neurones apprennent
Leçon 7 sur 23 · L'apprentissage profond et les transformeurs expliquésLa perte : à quel point le réseau se trompe-t-il?
1. Ce qu'est un réseau de neurones
2. Les tenseurs et PyTorch
3. Comment les réseaux de neurones apprennent
4. Diagnostiquer les problèmes d'entraînement
5. Représenter les séquences et le sens
6. Assembler un transformeur
7. Utiliser des modèles préentraînés
8. Sous le capot : les mathématiquesFacultatif
Ce que vous saurez faire
Mesurez les erreurs du réseau de billets de soutien avec un nombre que l’entraînement peut réduire : la perte. L’exactitude compte seulement les bonnes réponses. Elle ne distingue donc pas une réponse chanceuse d’une réponse certaine, et le réseau ne peut pas apprendre avec elle.
Carnet JupyterFaites cette leçon dans un carnet Jupyter
Le carnet (notebook) Jupyter contient chaque cellule de code, tâche et vérification de cette leçon. Il calcule softmax à la main, la perte du réseau de billets non entraîné, puis la perte et l’exactitude côte à côte. Il montre aussi l’erreur d’appliquer softmax deux fois. Ses cellules de préparation téléchargent les billets et le code du cours. Aucune installation locale n’est donc nécessaire. Environ 25 minutes.
Le carnet est en anglais. Colab et Kaggle ouvrent votre propre copie. Il faut un compte Google ou Kaggle gratuit. Vous êtes bloqué ? Consultez le carnet de solution.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- La propagation avant du réseau de billets : fréquences des mots → 64 neurones cachés avec ReLU → 5 scores, un par équipe, dans La propagation avant.
- La perte logarithmique, −ln p, dans Logarithmes des probabilités du cours de mathématiques.
- La fonction logistique, qui transforme un score en nombre de 0 à 1, dans Comprendre la classification du cours d’apprentissage automatique.
Ce qu’il vous faut sur votre ordinateur
- Rien si vous utilisez le carnet.
- Pour travailler localement : PyTorch et le dossier
ticket-routeravecdata/etticketnet.py, présentés dans Installer PyTorch. La section Les billets sous forme de nombres, ci-dessous, donne les lignes de préparation qui commencent chaque fichier de code de ce module. Siimport torchéchoue, préparez de nouveau l’environnement comme le montre cette leçon.
Testé avec Python 3.12 et PyTorch 2.14.1 sur un processeur.
Deux prévisions météo
Section intitulée « Deux prévisions météo »Deux applications météo font une prévision pour demain. La première annonce « 90 % de probabilité de pluie ». La deuxième annonce « 55 % de probabilité de pluie ». Il pleut. Les deux applications jugeaient la pluie plus probable que son absence. Si vous comptez seulement les bonnes et les mauvaises réponses, les deux avaient raison.
Mais vous faites davantage confiance à la première application. Elle était certaine, et elle avait raison. S’il n’avait pas plu, vous lui reprocheriez aussi davantage son erreur : elle était certaine, et elle avait tort. Un score équitable tient compte de la probabilité attribuée à ce qui s’est réellement produit, pas seulement du résultat gagnant.
Le problème : les scores ne sont pas des probabilités
Section intitulée « Le problème : les scores ne sont pas des probabilités »Le réseau de billets de La propagation avant produit cinq nombres, un pour chaque équipe. Pour le premier billet de validation, le réseau non entraîné donne ceci :
| Équipe | delivery | returns | payment | warranty | account |
|---|---|---|---|---|---|
| Score | −0.129 | 0.023 | 0.107 | 0.024 | 0.065 |
Ces nombres ne sont pas des probabilités. L’un est négatif, et leur somme n’est pas 1. Vous ne pouvez donc pas dire « le réseau est certain à 10 % que c’est payment ».
La bonne équipe pour ce billet est payment, et payment a le score le plus élevé. Si vous comptez les bonnes et les mauvaises réponses, le réseau a donc bien classé ce billet. Mais le réseau a des poids aléatoires et n’a rien appris. Il a eu de la chance, et l’exactitude ne le détecte pas. L’entraînement a besoin d’un nombre qui mesure à quel point le réseau était certain de la bonne équipe.
Softmax : des scores aux probabilités
Section intitulée « Softmax : des scores aux probabilités »Softmax transforme toute liste de scores en probabilités, en deux étapes. Prenez trois scores inventés pour trois équipes : 2,0, 1,0 et 0,1.
- Rendez chaque score positif : calculez e à la puissance du score (
exp), où e ≈ 2,718. Vous obtenez 7,389, 2,718 et 1,105. Un score plus élevé donne toujours un nombre plus élevé. - Divisez chaque résultat par leur somme, 11,212. Vous obtenez 0,659, 0,242 et 0,099, dont la somme est 1.
Le premier score vaut deux fois le deuxième, mais sa probabilité est 2,7 fois plus grande. Softmax tient compte des différences entre les scores : un point de plus multiplie toujours la probabilité par e ≈ 2,718. Ajouter le même nombre à chaque score ne change donc rien.
Le nom décrit son fonctionnement. Le simple « max » des scores choisit un gagnant et lui donne tout. Softmax est une version plus douce : le gagnant reçoit la plus grande part, et les autres gardent une part plus petite. Avec seulement deux équipes, softmax correspond à la fonction logistique de la régression logistique du cours d’apprentissage automatique.
L’entropie croisée : la surprise devant la bonne réponse
Section intitulée « L’entropie croisée : la surprise devant la bonne réponse »Passons maintenant au score de la prévision. Prenez la probabilité p que le réseau a attribuée à la bonne équipe, et calculez −ln p. C’est la perte d’un exemple : un nombre qui mesure à quel point le réseau se trompe. C’est la perte logarithmique que vous avez vue dans Mathématiques et statistiques essentielles pour l’IA.
Lisez la courbe de droite à gauche. Une bonne réponse certaine (p proche de 1) coûte presque rien. Une réponse au hasard entre cinq équipes (p = 0,2) coûte 1,609. Une mauvaise réponse certaine (p proche de 0) coûte beaucoup, et ce coût n’a aucune limite supérieure.
Description textuelle du graphique
La courbe commence haut à gauche : à p = 0,01, la perte vaut 4,6; à p = 0,02, elle vaut 3,9. Elle descend vite, puis lentement : 1,609 à p = 0,2 (un choix au hasard entre cinq équipes) et 0,693 à 0,5. Puis 0,417 à 0,659, 0,105 à 0,9 et 0 à p = 1.
Dans l’exemple à trois équipes, si la bonne équipe est la première, la perte est −ln 0,659 = 0,417. Si la bonne équipe est la troisième, la perte est −ln 0,099 = 2,317. Le réseau était certain de la mauvaise équipe, alors il est très surpris.
Cette perte s’appelle entropie croisée. Le mot « entropie » vient de la théorie de l’information, où −ln p mesure la surprise d’un événement de probabilité p. « Croisée » signifie qu’elle compare deux choses : les probabilités du réseau et la bonne réponse. Pour un ensemble de billets, la perte est la moyenne des pertes de chaque billet. Voici la formule, où s représente les scores et « right » la bonne équipe :
Les billets sous forme de nombres
Section intitulée « Les billets sous forme de nombres »Le code de ce module utilise les billets sous forme de fréquences de mots, comme dans La propagation avant. Cette fois, le fichier ticketnet.py du cours les construit avec le même code que vous y avez écrit. Dans le carnet, les cellules de préparation exécutent ces lignes pour vous. Sur votre ordinateur, placez-les au début de chaque fichier de code de ce module, dans le dossier ticket-router :
import torchfrom torch import nnfrom ticketnet import * # the course's code: TEAMS, load_split, Vocab, bag_of_words, labels, BagOfWordsNet, set_seed, evaluate, train ...
train_rows, valid_rows = load_split("data/train.csv"), load_split("data/valid.csv")vocab = Vocab([r["text"] for r in train_rows]) # the vocabulary: training tickets onlyx_train, y_train = bag_of_words(train_rows, vocab), labels(train_rows)x_valid, y_valid = bag_of_words(valid_rows, vocab), labels(valid_rows)loss_fn = nn.CrossEntropyLoss() # the loss of this lessonprint("x_train", tuple(x_train.shape), " x_valid", tuple(x_valid.shape), " vocabulary", len(vocab))La sortie :
x_train (4696, 2864) x_valid (600, 2864) vocabulary 2864labels() transforme l’équipe de chaque billet en sa position dans TEAMS, de 0 (delivery) à 4 (account). BagOfWordsNet est le réseau de La propagation avant, et set_seed(0) lui donne les mêmes poids de départ.
Le réseau de billets non entraîné
Section intitulée « Le réseau de billets non entraîné »Passons maintenant au vrai billet. Le schéma suit les quatre étapes pour le premier billet de validation, avec les vrais nombres du réseau non entraîné.
Description textuelle du diagramme
Le premier billet de validation passe dans le réseau non entraîné. Étape 1, les cinq scores : delivery −0,129, returns 0,023, payment 0,107, warranty 0,024, account 0,065. Étape 2, exp de chaque score : 0,879, 1,023, 1,113, 1,024 et 1,067; leur somme est 5,107. Étape 3, chaque valeur divisée par la somme donne les probabilités 0,172, 0,200, 0,218, 0,201 et 0,209. Leur somme est 1. Étape 4, la bonne équipe est payment, donc p = 0,218 et la perte est −ln 0,218 = 1,523.
Dans PyTorch, torch.softmax(scores, dim=1) calcule les probabilités selon la dimension 1, soit les cinq équipes de chaque billet. nn.CrossEntropyLoss() calcule la perte. Cette fonction prend les scores, pas les probabilités, et l’indice de la bonne équipe; elle applique elle-même softmax. Priya exécute les deux fonctions sur le premier billet de validation :
set_seed(0)model = BagOfWordsNet(len(vocab))scores = model(x_valid[:1])print("scores: ", scores)print("probabilities:", torch.softmax(scores, dim=1))print("right team: ", TEAMS[y_valid[0]])print("loss: ", loss_fn(scores, y_valid[:1]))La sortie :
scores: tensor([[-0.1288, 0.0228, 0.1072, 0.0242, 0.0647]], grad_fn=<AddmmBackward0>)probabilities: tensor([[0.1722, 0.2003, 0.2180, 0.2006, 0.2089]], grad_fn=<SoftmaxBackward0>)right team: paymentloss: tensor(1.5234, grad_fn=<NllLossBackward0>)La partie grad_fn=… est une note que PyTorch garde pour l’entraînement; La rétropropagation et autograd l’explique. La perte est de 1,523, comme dans le calcul à la main. Passons maintenant à toutes les données de validation. La fonction evaluate() du fichier ticketnet.py du cours renvoie la perte moyenne et l’exactitude :
import math
valid_loss, valid_acc = evaluate(model, x_valid, y_valid)print("validation loss:", round(valid_loss, 4), "| ln 5 =", round(math.log(5), 4))print("validation accuracy:", round(valid_acc, 4))La sortie :
validation loss: 1.624 | ln 5 = 1.6094validation accuracy: 0.1817Un réseau qui attribue exactement 0,2 à chaque équipe a une perte de −ln 0,2 = ln 5 = 1,609. Le réseau non entraîné atteint 1,624, une valeur très proche : il choisit presque au hasard, avec des probabilités égales. Son exactitude de 18,2 % est aussi un résultat dû au hasard; même « toujours delivery » atteint 27,5 %. L’entraînement doit réduire la perte. Après l’entraînement dans ce module, le même réseau atteint une perte de validation d’environ 0,06.
Pourquoi entraîner avec la perte, mais présenter l’exactitude
Section intitulée « Pourquoi entraîner avec la perte, mais présenter l’exactitude »Omar demande : « Les clients veulent des bonnes réponses. Pourquoi ne pas entraîner le réseau avec l’exactitude? » Priya lui montre une expérience. Elle change un nombre du réseau non entraîné, le biais du score de payment, de −3 à 3. Pour chaque valeur, elle mesure la perte et l’exactitude sur les 4 696 billets d’entraînement.
Description textuelle du graphique
La perte forme une vallée lisse. À un biais de −3, elle vaut 2,06; à 0, elle vaut 1,624, son minimum; à 3, elle vaut 2,54. Le vrai biais du réseau, 0,087, est proche du minimum.
Description textuelle du graphique
L’exactitude reste à 14,7 % pour un biais allant de −3 à environ 0. Entre environ 0 et 0,3, elle saute à 21,3 %, puis reste constante jusqu’à 3. À 21,3 %, le réseau répond « payment » pour chaque billet.
Partout, la perte répond à la question « ce petit changement améliore-t-il ou aggrave-t-il un peu le résultat? ». L’exactitude reste constante : sur la majeure partie de l’intervalle, un petit changement ne la modifie pas du tout. Elle ne peut donc pas indiquer dans quelle direction aller. Priya montre la même chose en code. Elle réduit le score de payment de chaque billet de 0,3, 0,2 et 0,1. Cela revient à réduire le biais de payment :
scores = model(x_train)for change in [-0.3, -0.2, -0.1]: shifted = scores.clone() shifted[:, 2] += change # every ticket's payment score, a little lower loss = loss_fn(shifted, y_train).item() accuracy = (shifted.argmax(dim=1) == y_train).float().mean().item() print(f"change {change:.2f} loss {loss:.5f} accuracy {accuracy:.4f}")La sortie :
change -0.30 loss 1.63139 accuracy 0.1469change -0.20 loss 1.62730 accuracy 0.1469change -0.10 loss 1.62467 accuracy 0.1469scores.clone() crée une copie, donc les scores d’origine restent intacts. .item() transforme un tenseur contenant un seul nombre en nombre Python. La perte indique que −0,1 est meilleur que −0,2; l’exactitude ne distingue pas les trois cas. La prochaine leçon utilise précisément cela : l’entraînement suit la pente de la perte, et une ligne horizontale n’a aucune pente.
La perte voit aussi ce que l’exactitude cache. Après deux époques d’entraînement (passages sur tous les billets d’entraînement), le réseau du cours a une exactitude de validation de 98,2 %. Sa perte est de 0,206. Après douze époques, l’exactitude est presque identique, à 98,3 %, mais la perte est de 0,063. Le réseau est devenu beaucoup plus certain de ses bonnes réponses, et seule la perte le montre. Donc :
- Entraînez avec la perte. Elle varie de façon lisse avec chaque poids et récompense les bonnes réponses certaines.
- Présentez l’exactitude (et les autres mesures du cours d’apprentissage automatique) aux gens. « 98 billets sur 100 arrivent à la bonne équipe » veut dire quelque chose pour Grace; « une perte de 0,063 », non.
Quand utiliser l’entropie croisée, et ses limites
Section intitulée « Quand utiliser l’entropie croisée, et ses limites »Utilisez l’entropie croisée quand le réseau choisit une classe parmi plusieurs, comme le routeur : une bonne équipe par billet. Pour un nombre, comme des minutes ou un prix, utilisez une perte adaptée aux nombres. Par exemple, l’erreur quadratique moyenne de Mathématiques et statistiques essentielles pour l’IA.
Ses limites : la perte est difficile à expliquer aux gens, alors présentez toujours une autre mesure à côté. De plus, une mauvaise réponse certaine coûte si cher que quelques mauvais exemples peuvent peser lourd. Un billet avec p = 0,001 pour l’équipe qui lui est attribuée coûte 6,9, autant que 66 billets à p = 0,9. Les données d’entraînement contiennent volontairement 70 billets avec une mauvaise équipe. La leçon Déboguer l’expérience utilise cet effet pour les trouver.
Exercice guidé : la perte à la main
Section intitulée « Exercice guidé : la perte à la main »- Utilisez les probabilités du premier billet de validation : delivery 0,172, returns 0,200, payment 0,218, warranty 0,201, account 0,209.
- Supposez que la bonne équipe est account. Notez p pour la bonne équipe.
- Calculez −ln p sur une calculatrice (la touche
ln, logarithme naturel) ou en Python avec-math.log(p). Vous devriez obtenir environ 1,565. - Supposez maintenant que la bonne équipe est delivery. Calculez de nouveau la perte. Vous devriez obtenir environ 1,760.
- Dans le carnet, complétez
loss_for()à la section 6. Exécutez sa cellule de vérification, qui utilise delivery comme bonne équipe.
Afficher la réponse
Pour account, p = 0,209 et la perte est −ln 0,209 = 1,565. Pour delivery, p = 0,172 et la perte est −ln 0,172 = 1,760. Le carnet donne 1,759, à partir de la probabilité non arrondie 0,1722. Delivery a la plus faible probabilité, donc la perte la plus élevée. Le réseau serait le plus surpris si le billet était destiné à delivery.
À vous de jouer : une mauvaise réponse certaine
Section intitulée « À vous de jouer : une mauvaise réponse certaine »Reprenez les trois scores inventés : 2,0, 1,0 et 0,1. Avant de calculer, faites une prédiction : la perte est-elle plus grande si la bonne équipe est la deuxième ou la troisième? Calculez ensuite les deux pertes, à la main et avec loss_fn(torch.tensor([[2.0, 1.0, 0.1]]), torch.tensor([1])) (et [2] pour la troisième).
Afficher la réponse
La deuxième équipe a p = 0,242, donc la perte est −ln 0,242 = 1,417. La troisième équipe a p = 0,099, donc la perte est de 2,317. La troisième perte est plus grande : le réseau a donné la plus petite part à la bonne équipe. Il est donc le plus surpris.
Erreur courante
Softmax deux fois
Symptôme : Tomás ajoute torch.softmax() à la fin du réseau « pour qu’il donne des probabilités », et garde nn.CrossEntropyLoss(). L’entraînement fonctionne, et l’exactitude semble bonne. Mais la perte reste élevée. Quand Priya exécute sa version, après 3 époques, l’exactitude de validation atteint 98,8 %, mais la perte reste à 0,96.
Cause : nn.CrossEntropyLoss() applique elle-même softmax. Avec le changement de Tomás, les probabilités passent une deuxième fois dans softmax, et la perte est incorrecte. Dans l’exemple à trois équipes, la perte calculée à partir des scores est de 0,417. Celle calculée à partir des probabilités est de 0,802. Même une réponse parfaite, 1,0 pour la bonne équipe parmi cinq, donne ainsi une perte de 0,905. La perte ne peut donc jamais descendre sous 0,905, et tous les nombres qui l’utilisent sont incorrects.
Solution : laissez le réseau renvoyer les scores bruts, et passez-les à nn.CrossEntropyLoss(). Appliquez torch.softmax() seulement quand vous voulez lire ou afficher les probabilités.
Ce que cela signifie pour un vrai service d’IA : lisez la documentation d’une fonction de perte avant de l’utiliser. Vérifiez les entrées attendues (scores ou probabilités) et les opérations qu’elle effectue elle-même. L’exactitude d’un modèle peut sembler bonne, même si toutes les pertes dans le journal d’entraînement sont incorrectes.
Vérification des connaissances
Section intitulée « Vérification des connaissances »Vérifiez votre compréhension
Dans vos mots : que mesure la perte d'entropie croisée d'un billet? Pourquoi est-elle élevée quand le réseau choisit avec certitude la mauvaise équipe?
Afficher la réponse
Elle mesure à quel point la bonne réponse surprend le réseau : −ln p, où p est la probabilité attribuée à la bonne équipe. Si le réseau choisit avec certitude une mauvaise équipe, la bonne équipe reçoit un petit p, par exemple 0,01. Alors, −ln p est élevé (4,6), car le logarithme d’un petit nombre est un grand nombre négatif. Une bonne réponse donnée avec certitude (p proche de 1) ne coûte presque rien.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Prédisez : un réseau donne les scores 3, 3, 3, 3, 3 aux cinq équipes. Quelles probabilités softmax donne-t-il, et quelle est la perte? Ajoutez ensuite 10 à chaque score : qu'est-ce qui change?
Afficher la réponse
Les cinq scores sont égaux, donc softmax donne 0,2 à chaque équipe. La perte est −ln 0,2 = ln 5 = 1,609, soit la perte d’une prédiction qui donne une probabilité égale à chaque équipe. Ajouter 10 à chaque score ne change rien : softmax tient compte seulement des différences entre les scores. Ces différences sont toujours de 0. Les probabilités restent à 0,2 et la perte reste à 1,609.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Omar veut entraîner le réseau directement sur l'exactitude, car c'est ce que les clients perçoivent. Donnez une raison d'utiliser plutôt la perte pour l'entraînement.
Afficher la réponse
L’exactitude change seulement quand une réponse passe à une autre équipe. Elle reste donc inchangée pour la plupart des petits changements d’un poids. Une valeur constante ne donne aucune direction : l’entraînement ne peut pas déterminer si un petit changement améliore ou aggrave le résultat. La perte varie de façon continue avec chaque poids. Elle indique donc toujours quelle direction améliore le résultat. Elle récompense aussi le réseau quand il est plus certain des bonnes réponses, ce que l’exactitude ne montre pas. Nous présentons quand même l’exactitude aux gens, car elle est facile à comprendre.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Softmax transforme les scores du réseau en probabilités : l’exponentielle de chaque score, divisée par la somme de ces exponentielles. Seules les différences entre les scores comptent.
- La perte d’un exemple est −ln p pour la bonne équipe : c’est l’entropie croisée. Elle est faible pour une bonne réponse donnée avec certitude et élevée pour une mauvaise réponse donnée avec certitude. La perte d’un ensemble est la moyenne.
- Le réseau non entraîné pour les billets a une perte de validation de 1,624, soit environ ln 5 = 1,609. C’est la perte d’une prédiction qui donne une probabilité égale à chaque équipe. Son exactitude est de 18,2 %.
- Entraînez sur la perte, présentez l’exactitude. La perte varie de façon continue avec chaque poids; l’exactitude reste constante entre ses sauts.
nn.CrossEntropyLoss()prend des scores, pas des probabilités. Appliquer softmax deux fois rend la perte incorrecte.
Ensuite, réduisez la perte : modifiez les poids par petits pas, toujours dans le sens de la descente.
Leçon suivante : La descente de gradient