Écrivez votre propre boucle d'entraînement dans PyTorch.
Dans cette vidéo, nous verrons comment nous pouvons faire le même finetuning que dans la
vidéo sur l'API Trainer, mais sans compter sur cette classe.
De cette façon, vous pourrez facilement personnaliser chaque étape de la boucle d'entraînement en fonction de vos besoins.
Ceci est également très utile pour déboguer manuellement quelque chose qui n'allait pas avec l'
API Trainer.
Avant de nous plonger dans le code, voici une esquisse d'une boucle d'entraînement : nous prenons un batch de
données d'entraînement et le transmettons au modèle.
Avec les étiquettes, nous pouvons alors calculer une perte.
Ce nombre n'est pas utile en soi, mais est utilisé pour calculer les gradients de nos
poids de modèle, c'est-à-dire la dérivée de la perte par rapport à chaque poids de modèle.
Ces gradients sont ensuite utilisés par l'optimiseur pour mettre à jour les poids du modèle et les
améliorer un peu.
Nous répétons ensuite le processus avec un nouveau batch de données d'apprentissage.
Si tout cela n'est pas clair, n'hésitez pas à reprendre votre
cours d'apprentissage profond préféré.
Nous utiliserons à nouveau le jeu de données GLUE MRPC, et nous avons vu comment prétraiter les données
à l'aide de la bibliothèque Datasets avec le rembourrage dynamique.
Découvrez les vidéos liées ci-dessous si vous ne les avez pas déjà vues.
Cela fait, nous n'avons plus qu'à définir les DataLoaders PyTorch, qui seront chargés de
convertir les éléments de notre jeu de données en batchs.
Nous utilisons notre `DataCollatorForPadding` comme fonction d'assemblement et mélangeons l'ensemble d'entraînementpour s'assurer que nous voyons pas tous les échantillons dans le même ordre.
Pour vérifier que tout fonctionne comme prévu, nous essayons de récupérer un batch de données et de l'
inspecter.
Comme nos éléments de jeu de données, c'est un dictionnaire, mais cette fois les valeurs ne sont pas une seule
liste d'entiers, mais un tenseur de forme de taille de batch par longueur de séquence.
L'étape suivante consiste à envoyer les données d'entraînement dans notre modèle.
Pour cela, nous devrons créer notre modèle.
Comme on l'a vu dans la vidéo sur l'API des modèles, nous utilisons la méthode `from_pretrained` et ajustons le nombre
d'étiquettes au nombre de classes que nous avons sur cet jeu de données, ici deux.
Encore une fois, pour être sûr que tout se passe bien, nous passons le batch que nous avons saisi à notre modèle
et vérifions qu'il n'y a pas d'erreur.
Si les étiquettes sont fournies, les modèles de la bibliothèque Transformers renvoient toujours
directement la perte.
Nous pourrons faire `loss.backward()` pour calculer tous les gradients, et nous aurons alors besoin d'un optimiseur
pour faire l'étape d'apprentissage.
Nous utilisons ici l'optimiseur AdamW, qui est une variante d'Adam avec une décroissance de poids appropriée,
mais vous pouvez choisir n'importe quel optimiseur PyTorch que vous aimez.
En utilisant la perte précédente et en calculant les gradients avec `loss.backward()`, nous vérifions que
nous pouvons faire l'étape d'optimisation sans aucune erreur.
N'oubliez pas de mettre `zero_grad()` par la suite, sinon à l'étape suivante, ils seront ajoutés
aux gradients que vous calculez !
Nous pourrions déjà écrire notre boucle d'entraînement, mais nous ajouterons deux autres choses pour la rendre
aussi bonne que possible.
Le premier est un planificateur de taux d'apprentissage, pour réduire progressivement notre taux d'apprentissage à
0.
La fonction `get_scheduler` de la bibliothèque Transformers n'est qu'une fonction pratique pour
créer facilement un tel planificateur0 Vous pouvez à nouveau utiliser n'importe quel planificateur de taux d'apprentissage PyTorch à la place.
Enfin, si nous voulons que notre entraînement prenne quelques minutes au lieu de quelques heures,
nous devrons utiliser un GPU.
La première étape consiste à en obtenir un, par exemple en utilisant un notebook Colab.
Ensuite, vous devez réellement envoyer votre modèle et les données d'entraînement à l'aide d'un appareil Torch.
Vérifiez les lignes suivantes pour avoir un appareil CUDA ou préparez vous à ce que votre entraînement dure plus d'une heure.
Nous pouvons maintenant tout assembler !
Nous mettons d'abord notre modèle en mode d'entraînement (ce qui activera le comportement d'entraînement pour certaines
couches comme la Dropout), puis parcourons le nombre d'époques que nous avons sélectionnées et toutes les données dans
notre chargeur de données d'entraînement.
Ensuite, nous passons par toutes les étapes que nous avons déjà vues : envoyer les données au GPU, calculer
les sorties du modèle, et en particulier la perte.
Utilisez la perte pour calculer les gradients, puis effectuez une étape d'apprentissage avec l'optimiseur.
Mettez à jour le taux d'apprentissage dans notre planificateur pour la prochaine itération et mettez à 0 les gradients
de l'optimiseur.
Une fois cela terminé, nous pouvons évaluer notre modèle très facilement avec une métrique de la
bibliothèque Datasets.
Nous mettons d'abord notre modèle en mode d'évaluation, puis parcourons toutes les données dans le
chargeur de données d'évaluation.
Comme nous l'avons vu dans la vidéo sur l'API Trainer, le modèle génère des logits et nous devons appliquer
la fonction argmax pour les convertir en prédictions.
L'objet `metric` a alors une méthode `add_batch` que nous pouvons utiliser pour lui envoyer ces prédictions intermédiaires.
Une fois la boucle d'évaluation terminée, nous n'avons plus qu'à appeler la méthode de calcul pour obtenir nos
résultats finaux !
Félicitations, vous avez maintenant finetuné un modèle tout seul !