1 00:00:04,720 --> 00:00:09,280 Certains bogues dans votre code sont très simples. Vous essayez de l'exécuter, 2 00:00:09,280 --> 00:00:14,720 vous obtenez une erreur de syntaxe quelque part, Python vous indique exactement où et vous la corrigez. C'est 3 00:00:14,720 --> 00:00:22,240 génial : c'est simple et satisfaisant. Parfois, cependant, les choses se bloquent et l'erreur est impossible 4 00:00:22,240 --> 00:00:27,360 à comprendre. Cela se produit souvent en apprentissage automatique pour plusieurs raisons : vous travaillez avec 5 00:00:27,360 --> 00:00:33,920 des structures de données volumineuses, utilisez des bibliothèques volumineuses et complexes avec de nombreuses pièces mobiles, et vous faites également 6 00:00:33,920 --> 00:00:41,600 beaucoup de calcul GPU qui sont en génrénal les plus durs à corriger. Dans Keras, il y a le problème supplémentaire que vos modèles sont souvent compilés 7 00:00:41,600 --> 00:00:46,080 avant l'exécution, ce qui est excellent pour les performances mais rend leur débogage très difficile. 8 00:00:47,920 --> 00:00:56,160 Ce sera une vidéo sur ce qu'il faut faire lorsque vous rencontrez l'un de ces bugs cauchemardesques et avez aucune idée de comment les déboguer. 9 00:00:56,400 --> 00:01:07,600 Pour vous donner une idée des choses les plus courantes de ce qui peut mal tourner et où chercher la source des bogues que 10 00:01:07,600 --> 00:01:13,360 vous rencontrez, utilisons cet exemple de script. Je vais vous le montrer ici en deux parties. Tout d'abord, 11 00:01:13,360 --> 00:01:19,280 nous effectuons toutes nos importations, nous chargeons un jeu de données, nous créons notre tokenizer et nous tokenisons le jeu de données. 12 00:01:20,160 --> 00:01:28,320 Ensuite, nous convertissons nos jeux de données en jeux de données TensorFlow, c'est le `to_tf_dataset`, afin de pouvoir leur appliquer `fit()`, 13 00:01:28,320 --> 00:01:34,640 puis nous chargeons notre modèle à partir d'un checkpoint pré-entraîné, le compilons et pouvons appliquer `fit` sur le jeu de données. Cela semble 14 00:01:34,640 --> 00:01:42,880 assez simple, similaire à ce qu'on a vu dans le cours avant, mais attention ! Ce code effrayant cache de nombreux secrets sombres et mystérieux. 15 00:01:43,760 --> 00:01:52,880 Que se passe-t-il lorsque nous l'exécutons ? Eh bien, ce n'est pas génial. Nous obtenons ce message d'erreur. Qu'est-ce que cela signifie? Nous avons essayé de nous entraîner 16 00:01:52,880 --> 00:01:59,600 sur nos données, mais nous n'avons pas obtenu de gradient ? C'est assez déroutant. Comment pouvons-nous même commencer à déboguer 17 00:02:00,400 --> 00:02:04,880 quelque chose comme ça ? Lorsque l'erreur que vous obtenez ne suggère pas immédiatement où se situe le problème, 18 00:02:05,440 --> 00:02:11,040 la meilleure solution consiste souvent à parcourir les éléments dans l'ordre, en s'assurant à chaque étape 19 00:02:11,040 --> 00:02:19,120 que tout semble correct. Que tout est ok à ce point. Et bien sûr, le point de départ consiste toujours à vérifier vos données. 20 00:02:20,720 --> 00:02:28,960 La meilleure façon de le faire est de récupérer un batch à partir de `tf.data.Dataset` sur lequel votre modèle s'entraîne, 21 00:02:30,560 --> 00:02:41,840 juste à la fin du pipeline d'entraînement. Et si votre sortie est bonne, cela garanti que votre pipeline de données fonctionne bien. Et nous pouvons faire cela comme ça, en bouclant 22 00:02:41,840 --> 00:02:50,320 le jeu de données pendant une itération, puis en interrompant. Alors, qu'obtenons-nous lorsque nous inspectons ce batch ? 23 00:02:50,320 --> 00:02:54,800 Nous constatons que nous n'obtenons aucun gradient car nous ne transmettons pas d'étiquettes à Keras ! 24 00:02:55,520 --> 00:03:00,800 Nos étiquettes se trouvent dans le batch, mais il s'agit d'une clé dans le dictionnaire d'entrée, et non d'une étiquette distincte. 25 00:03:02,400 --> 00:03:06,160 Il s'agit de l'un des problèmes les plus courants que vous rencontrerez lors de l'entraînement de vos transformers 26 00:03:06,160 --> 00:03:12,960 avec TensorFlow. Nos modèles peuvent tous calculer la perte en interne, mais pour utiliser cette perte pour l'entraînement, 27 00:03:12,960 --> 00:03:16,880 les étiquettes doivent être transmises dans le dictionnaire d'entrée, où le modèle peut les voir. 28 00:03:17,760 --> 00:03:23,200 Cette perte interne est la perte que nous utilisons lorsque nous ne spécifions pas de valeur de perte à `compile()`. 29 00:03:26,640 --> 00:03:30,960 Keras, d'autre part, s'attend généralement à ce que les étiquettes soient transmises séparément du 30 00:03:30,960 --> 00:03:36,720 dictionnaire d'entrée et qu'elles ne soient pas visibles par le modèle, et les calculs de perte échouent généralement si vous 31 00:03:36,720 --> 00:03:43,040 ne le faites pas. Nous devons choisir l'un ou l'autre. Soit nous utilisons la perte interne du modèle et conservons 32 00:03:43,040 --> 00:03:49,120 les étiquettes là où elles se trouvent, soit nous continuons à utiliser les pertes de Keras, mais nous déplaçons les étiquettes à l'endroit où Keras les 33 00:03:49,120 --> 00:03:57,680 attend. Pour plus de simplicité, utilisons les pertes internes du modèle, en supprimant l'argument 34 00:03:57,680 --> 00:04:06,000 de perte lors de l'appel de `compile()`. Donc que se passe-t-il si nous essayons ré-entraînons. Et bien nous recompilons en appelant `model.fit()` à nouveau. 35 00:04:06,560 --> 00:04:13,840 Que se passe t'il ? Eh bien, il fonctionne cette fois... mais maintenant nous obtenons une perte de `nan`. Ce n'est pas bon. 36 00:04:16,240 --> 00:04:22,160 `nan` signifique « not a number » et ce n'est pas une bonne perte à avoir en général. En fait, si nous inspectons notre modèle maintenant, nous verrons que non seulement toutes 37 00:04:22,160 --> 00:04:30,640 les sorties sont `nan` , mais que toutes les poids sont également `nan` comme pour la perte. Une fois qu'un seul `nan` se glisse dans vos calculs, 38 00:04:30,640 --> 00:04:37,280 il a tendance à se propager, car il se propage depuis la perte jusqu'à votre gradient 39 00:04:37,280 --> 00:04:48,320 puis dans les mises à jour de poids et donc à chaque mise à jour vous avez des `nan`. Donc `nan` détruit notre modèle. Mais où s'est-il glissé en premier ? 40 00:04:49,600 --> 00:04:57,760 Pour le savoir, nous devons réinitialiser le modèle et examiner les résultats du premier batch uniquement. 41 00:04:58,400 --> 00:05:04,160 Et lorsque nous faisons cela, nous voyons que `nan` apparaît d'abord dans la perte, mais seulement dans certains échantillons ! 42 00:05:04,960 --> 00:05:08,480 Vous pouvez voir cela plus en détail dans la section du cours qui nous accompagneme, je vais très vite ici. 43 00:05:11,040 --> 00:05:17,120 Mais nous constatons que si nous regardons les étiquettes, les échantillons avec une perte de `nan` ont tous une étiquette de 2 ! 44 00:05:17,760 --> 00:05:24,400 Cela nous donne un indice très fort. Si nous vérifions le modèle, avec `model.config.num_labels`, nous voyons que 45 00:05:24,400 --> 00:05:30,080 le modèle pense qu'il n'y a que 2 étiquettes, mais si nous voyons une valeur de 2, cela signifie qu'il y a au moins 46 00:05:30,080 --> 00:05:36,400 3 étiquettes, car 0 c'est aussi une étiquette ! Nous avons donc perdu `nan` parce que nous avons obtenu une étiquette impossible dans notre jeu de données 47 00:05:36,400 --> 00:05:43,040 Pour résoudre ce problème, nous devons revenir en arrière et configurer le modèle pour qu'il ait le bon nombre d'étiquettes. 48 00:05:43,680 --> 00:05:52,240 Nous pouvons définir `num_labels=3` lorsque nous initialisons le modèle avec `from_pretrained`. Alors maintenant, nous pensons que nos 49 00:05:52,240 --> 00:05:58,000 données sont bonnes et que notre modèle est bon, donc l'entraînement devrait fonctionner. Et si nous essayons d'exécuter `model.fit()`, 50 00:05:58,000 --> 00:06:07,600 nous obtenons... hmm. Nous obtenons une perte, c'est un nombre, cela diminue, mais cela ne diminue pas très rapidement. Et si nous continuons, 51 00:06:07,600 --> 00:06:13,600 nous constaterons que cela se fige à une valeur assez élevée. Que se passe-t-il ? Eh bien, lorsque les choses fonctionnent pour la 52 00:06:13,600 --> 00:06:19,280 plupart mais que l'entraînement est simplement lent, cela peut être un bon moment pour examiner votre optimiseur 53 00:06:19,280 --> 00:06:24,560 et les hyperparamètres d'entraînement. Et c'est là que je veux mentionner l'une des sources les plus courantes 54 00:06:24,560 --> 00:06:30,480 de problèmes lorsque vous travaillez avec Keras. Vous pouvez nommer des choses comme des optimiseurs avec des chaînes, Keras supporte ça et c'est très utile, 55 00:06:32,960 --> 00:06:37,680 mais si vous faites cela, toutes les options sont silencieusement définies sur leurs valeurs par défaut. 56 00:06:38,240 --> 00:06:43,920 Nous avons donc spécifié Adam comme optimiseur, mais au cours du processus, nous avons obtenu de manière invisible le taux d'apprentissage par défaut, 57 00:06:43,920 --> 00:06:51,440 qui est de 1e-3, soit 10 à la puissance moins 3. C'est bien trop élevé pour entraîner des transformers. 58 00:06:51,440 --> 00:06:59,120 Nous devrions revenir en arrière et spécifier directement le taux d'apprentissage sans utiliser une chaîne. Les bonnes valeurs se situent entre 1e-5 59 00:06:59,760 --> 00:07:06,800 et 1e-4. Séparons en deux et choisissons 5e-5. Et si vous recompilez avec cela, 60 00:07:06,800 --> 00:07:16,880 vous constaterez que l'entraînement fonctionne enfin. La perte diminue efficacement et converge vers une valeur basse. Encore une fois, je suis passé ici assez rapidement, et je vous 61 00:07:16,880 --> 00:07:20,720 recommande de consulter les notes de cours pour voir cela plus en détail et d'expérimenter 62 00:07:20,720 --> 00:07:28,840 le code vous-même pour regarder à quoi l'erreur ressemble et comment l'approcher. 63 00:07:20,720 --> 00:07:28,840 J'espère que cela vous a donné un bref résumé des bugs les plus fréquents et des approches de deboguage les plus fréquentes pour les résoudre. Bonne chance et n'oubliez pas de faire des pauses si votre code vous donne du fil à retordre !