Analyse des courbes

Nous allons tester cet outil permettant de monitorer en live l’évolution d’un apprentissage.

Installation

Rappel, cet outil s’installe comme un package Python standard. Pour ceux qui ont effectué l’installation sur le bureau, il suffit d’écrire :

C:\Users\...\Desktop\Pytorch314\python.exe -m pip install tensorboard

Prise en main

Lancement

  • Ouvrez une fenêtre de commande (cmd)

  • Si tensorboard.exe n’est pas dans votre PATH, vous devez déterminer son chemin d’accès. Normalement, il se trouve dans le répertoire Scripts de votre installation.

  • Ajoutez en paramètre le répertoire de script

Astuce

C:\Users\Lilian\Desktop\Pytorch314\Scripts\tensorboard.exe --logdir C:\Log\test1

Ainsi, TensorBoard démarre un serveur web local :

../_images/tboard.png

Ouvrez votre navigateur préféré et allez à l’adresse :

Astuce

localhost:6006

Code test

Afin de tester Tensorboard, nous utilisons un entrainement sur MNIST (pour la facilité de calcul) avec un faible learning rate pour avoir une centaine d’epochs à afficher. Vous pouvez télécharger le code test ci-dessous :

code exemple

Exécutez le programme si vous voulez tester.

Configuration

Dans Tensorboard, il y a quelques options à activer pour améliorer l’interface :

  • Les graphiques construisent pour chaque tracé une deuxième version lissée. Pour alléger les vues, désactivez la version lissée en faisant : rubrique SCALARS sur la droite, mettre le smoothing à 0.

    ../_images/smo.png
  • Pour rafraîchir les graphiques vous pouvez appuyer sur le bouton icon2.

  • Pour activer le raffraîchissement automatique des graphiques, cliquez sur la roue dentée et choisissez Reload data :

    ../_images/reload.png
  • Pour éviter qu’une partie des courbes soit tronquée, désactivez l’option Ignore outliers :

    ../_images/outliers.png

Prise en main

  • Sur le bandeau de gauche, vous pouvez activer/désactiver les courbes affichées

  • Au niveau des graphiques, cliquez sur l’icone icon pour l’élargir horizontalement

Résultat

Si tout est configuré correctement, vous devriez obtenir le tracé dynamique ci-dessous (accéléré ici en x40)

../_images/demo.gif

En positionnant votre curseur sur un point de la courbe, vous obtenez une lecture précise des valeurs :

../_images/cursor.png

Seaborn

Une fois les données exportées en csv, vous pouvez opter pour la librairie Seaborn pour afficher vos résultats.

Idée générale :

  • Associée toutes les courbes d’un même run à une même couleur

  • Convention :

    • Train : trait continu

    • Validation : trait pointillé

Grâce à cela, nous obtenons des graphiques permettant de comparer les 4 courbes par run, ceci pour 4/5 runs différents. Au delà, le graphique devient très/trop chargé.

Nous vous proposons un code exemple qui charge les csv et affiche les graphiques associés en utilisant la librairie Seaborn. Vous pouvez télécharger les csv des exemples.

Voici le code exemple :

import os
import glob

folder    = r"C:\log\test1"
csv_files = glob.glob(os.path.join(folder, "*.csv"))
plot_loss_acc_runs(csv_files)
../_images/seaborn.png

Il est possible de limiter le nombre d’epochs :

plot_loss_acc_runs(csv_files,30)
../_images/seaborn2.png

Analyse train/val

Nous montrons dans cette partie que l’analyse de la courbe de loss/train seule ne permet pas une interprétation fiable.

Généralisation

En apprentissage automatique, le terme généralisation désigne la capacité d’un modèle à produire des prédictions correctes sur des données non observées durant l’entraînement (set de validation). La notion de généralisation s’oppose à celle de surapprentissage. On peut ainsi formuler les observations suivantes :

  • Lorsque le modèle surapprend, on peut dire de manière équivalente que le réseau ne parvient pas à généraliser.

  • Si les performances restent bonnes à la fois sur le jeu d’entraînement et sur le jeu de validation, le réseau généralise correctement, car ce qu’il a appris sur le jeu d’entraînement se transfère efficacement au jeu de validation.

Mauvaise approche

Monsieur X décide d’afficher sur le même graphique les courbes de loss/train associées à différents learning rates (LR).

../_images/lr.png

Sa conclusion erronée est : plus on augmente le LR, mieux l’entraînement se passe car on constante :

  • Une décroissance plus rapide

  • Une meilleure valeur de loss à la fin de l’entrainement

Où est le problème ?

Examiner uniquement une courbe de loss/train sans avoir l’information de la loss/validation associée est dangereux. En effet, la loss/validation est la seule courbe permettant de savoir si le modèle apprend réellement. Les optimiseurs modernes sont efficaces et arrivent très souvent à diminuer la loss/train. Par contre la loss/validation, c’est une autre histoire…

Voici des exemples de cas pathologiques que l’on peut détecter avec les courbes loss/train et loss/val en parallèle :

  • loss/train ↓↓↓ et loss/valid ↓ puis ↑ : overfitting (surapprentissage)

  • loss/train ↓↓↓ et loss/valid stagne dès le début : underfitting (le modèle n’apprend rien)

Une bonne généralisation du modèle est associée à deux courbes de train et validation qui ont un comportement similaire :

  • loss/train ↓↓ et loss/valid ↓↓

Il peut exister un écart, cela est normal. Cependant, plus l’écart est faible, meilleure est la généralisation, plus c’est idéal.

Loss et accuracy

Nous montrons maintenant qu’il est utile d’examiner les quatre courbes associées à un entraînement afin de mieux diagnostiquer la qualité de l’apprentissage.

Supposons que nous réalisions dix entraînements consécutifs avec les mêmes données et les mêmes paramètres. Quel réseau devons-nous conserver ?

Le réseau retenu est celui qui obtient la meilleure accuracy sur le jeu de validation. En effet, la loss est une fonction mathématique optimisée durant l’entraînement, mais elle ne correspond pas directement à un objectif métier, contrairement à l’accuracy. Ainsi :

  • un modèle peut présenter une loss très faible, proche de 0, tout en ayant une accuracy moyenne

  • un autre modèle peut avoir une loss relativement élevée, par exemple autour de 1, tout en affichant une excellente accuracy

L’accuracy constitue donc un critère pertinent pour départager plusieurs réseaux après l’entraînement. Il est par ailleurs possible de la monitorer au cours de l’entraînement, car il s’agit d’une mesure :

  • facile à interpréter

  • bornée entre 0 et 100 %

Ainsi, ces deux courbes supplémentaires apportent des informations complémentaires permettant d’affiner l’interprétation des résultats et de détecter des cas pathologiques qui ne seraient pas visibles à partir des courbes de loss.

Exemple

  • Loss train ↓

  • Loss valid ↓

  • Acc/valid : stagne à quelques pourcents

Ce que cela indique :

  • L’optimisation fonctionne, l’algorithme du gradient opère la loss/train diminue, la loss/val confirme

  • Le modèle améliore ses scores internes

  • Mais ses prédictions sont médiocres

Interprétations possibles :

  • Problème sous-jacent : features pauvres, modèle trop simple, problème trop difficile, labels erronés..

  • Nous sommes au tout début d’un apprentissage lent

Avertissement

Une loss qui baisse n’implique pas forcément une accuracy qui monte.

Le nombre d’epochs

Si vous avez travaillé sur des jeux de données comme MNIST ou CIFAR-10, vous avez sans doute constaté qu’en une dizaine epochs, on atteint déjà d’excellentes performances, parfois autour de 98 % d’accuracy. Ces jeux de données sont pratiques, car ils permettent de réaliser un entraînement complet en quelques minutes, mais ils donnent aussi, indirectement, une vision biaisée de la réalité :

  • seules quelques epochs semblent nécessaires pour entraîner un modèle

  • quel que soit le réseau ou ses hyperparamètres, tout finit par converger

En pratique, en dehors des tutoriels pour débutants, l’apprentissage nécessite plutôt de l’ordre de 100 epochs. Pour des architectures plus récentes ou plus profondes, il n’est pas rare de monter jusqu’à 300 epochs.

Avertissement

Il ne faut surtout jamais porter de jugement hâtif sur les performances d’un réseau à partir d’un graphique couvrant seulement quelques epochs. En poursuivant l’apprentissage, beaucoup de choses peuvent évoluer.

Analyse

Voici la courbe d’un apprentissage se déroulant sur 300 epochs.

../_images/result1.png

Ici, nous sommes dans un cas d’école :

  • La loss/train décroit quasiment vers 0 alors que la loss/validation augmente

  • L’accuracy du train atteint 98% de performance alors que celle de la validation stagne à 28%

Le diagnostic est sans appel : le modèle surapprend : il mémorise les données d’entraînement, mais généralise mal sur de nouvelles images.

Nous remarquons que le surapprentissage est confirmé à la fois sur le graphique de la loss et sur celui de l’accuracy.

La courbe d’accuracy/train peut être utilisée pour vérifier que le modèle parvient effectivement à apprendre. Si les deux loss diminuent mais que la courbe d’accuracy/train reste proche de zéro, on peut supposer que le modèle est insuffisant.

Remarque

Avez-vous remarqué que :

  • La courbe accuracy/valid a augmenté passant de 3% à 28%

  • Dans le même temps, la loss/validation a augmenté de 50% !

Cela peut sembler contradictoire et pourtant non !

En pratique, cela peut se produire lorsque, pour les prédictions incorrectes, la probabilité associée à la bonne classe décroît. Dans ce cas, les pénalités issues des 72 % de prédictions erronées se cumulent et font augmenter la loss globale, même si, dans le même temps, l’accuracy s’est améliorée.