Open Rob174 opened 3 years ago
On veut ce type de courbe :
(source )
Comme on le voit sur l'image du dessus l'erreur décroit mais fini par se stabiliser au bout d'un certain temps. Si on continue d'entrainer le modèle, l'erreur de validation réaugmentera car le modèle surrajustera. On veut donc
Interprétation générale : pas d'apprentissage, peut-être pas de généralisation
Tests pour tenter d'améliorer l'aptitude à généraliser
(chiffre petit = + prioritaire ; chiffre grand = - prioritaire)
Test | Priorité | But | Effet observé | Testé |
---|---|---|---|---|
Diminuer le nb de filtre | 4 | - de paramètres = + simple à optimiser (et + difficile de surrajuster et "mémoriser" le dataset) | toujours pas d'amélioration | ✔️ |
Augmenter le nb de filtres | 4 | si le paramètre n'a pas assez de paramètres pour apprendre à distinguer les classes | ||
Passer en Conv simple | 5 | Revenir à des couches + simples (intérêt très limité car ces couches ont l'avantage de réduire le nombre de paramètres) | ||
Augmenter le epsilon de Adam pour ralentir l'apprentissage et permettre une potentielle meilleure généralisation | 1 | Ralentir l'apprentissage pour améliorer la généralisation | Aucun changement fortement notable | ✔️ |
Diminuer la learning rate | 1 | idem | Aucun effet (par contre trop l'augmenter diminue la précision) | ✔️ |
Augmenter la batch_size | 2 | donner des échantillons + gros pour qu'ils soient + représentatif du dataset global | Aucun changement quelle que soit la taille de batch | ♻️ |
Changer la loss pour une à base de categoricalcrossentropy | 3 | Actuellement MSE (+ efficaces pour l'entrainement que MSE pour guider le modèle) | :x: tâche de régression pas de prédiction | |
Mettre le biais à false sur les couches de convolution | 1 | sur les docs indiqué comme cela | résultat non concluant | ✔️ |
Passer de l'optimizer Adam à SGB | 1 | momentum 0.9 ; lr_init = 0.045 ; ( pour le decay car on ne sait même pas 2 epochs donc on ne le change pas) | résultat non concluant | ✔️ |
Ajouter matrice de confusion
Ressource, interprétation de courbes d'entrainement d'ia : https://machinelearningmastery.com/learning-curves-for-diagnosing-machine-learning-model-performance/
lr = [10**-3,10**-4,10**-5] # 3 possibilités
eps = [10**-7,10**-5,10**-4,10**-3,10**-2] # 5 possibilités
15 possibilités x 1h = 15h
Taille d'image fournie à l'IA = 1600 // 4 x 900 //4 = 400x225 ; batch_size = 10
On notera que dans tous les diagrammes suivant l'axe des abscisses correspond au nombre d'images passées au réseau à l'instant de la mesure
lr | eps | Resultat |
---|---|---|
1e-3 | 1e-7 | ![]() |
1e-3 | 1e-2 | ![]() |
1e-5 | 1e-2 | ![]() |
1e-1 | 1e-7 | ![]() |
1e-3 | 1e-5 | ![]() |
1e-4 | 1e-7 | ![]() |
1e-2 | 1e-7 | ![]() |
1e-3 | 1e-3 | ![]() |
1e-3 | 1e-8 | ![]() |
1e-3 | 1e-1 | ![]() |
Espace exploré
Espaces explorés corrects mais précision et stabilité, indexs arbitraires à ne pas prendre en compte
https://plotly.com/~Robin123.456/1/
:dart:On a jamais de convergence quels que soient les paramètres de l'optimisateur
On laisse fixe lr=1e-3 et eps=1e-7
Batch_size | Image_size (éviter la surcharge vram) | Courbe |
---|---|---|
10 | 400x225 | ![]() |
20 | 400x225 | ![]() |
50 | 237x151 | ![]() |
100 | 178x100 | ![]() |
📝 Aucun changement quelle que soit la taille de batch
Avant MSE
Passage en categorical_cross_entropy
Que représente l'entropie croisée : Cross-entropy is a measure of the difference between two probability distributions for a given random variable or set of events.
Pb : label = vecteur de fréquence et pas proba de présence
Seule alternative envisageable (dernier recours) : GAN pour tenter de déterminer si les valeurs générées Finalement passage en MSE
Modèle complet
(clic pour voir en grand)
Modèle version synthétique
Chemin + court = 16 couches (= 6+4*1+6)
Chemin + long = 40 couches (= 6+4*7+6)
Nom du paramètre | Plage de valeurs standards | Couches concernées |
---|---|---|
nb de filtres/units | [3,1000[ | Convolution, Dense |
taille du noyau | 2 ou 3 | Convolution |
fonction d'activation | relu, prelu, selu | Convolution, Dense |
Index | Description de la modification | But | Difficulté (1 = - difficile) | Statut |
---|---|---|---|---|
0 | Enlever la softmax (pas une proba ici) | Softmax = donne un vecteur de probas (somme = 1) : pas le cas ici ❗ | 0 | ✔️ |
1 | Diminuer le nb de modules | Diminuer le nombre de paramètre et la profondeur du réseau | 1 |
batch_size | lr | eps | fonction_activation_finale | Resultat |
---|---|---|---|---|
10 | 1e-3 | 1e-7 | sigmoid | ![]() |
📝 Imprécision venait en partie de ca. On peut retenter d'ajuster le lr et epsilon
Nouvel essai avec batch_size = 10 et sigoid à la fin
lr | eps | Resultat |
---|---|---|
1e-3 | 1e-7 | ![]() |
1e-3 | 1e-2 | ![]() |
1e-5 | 1e-2 | ![]() |
1e-1 | 1e-7 | ![]() |
1e-3 | 1e-5 | ![]() |
1e-4 | 1e-7 | ![]() |
📝Amélioration globale des loss ; observation d'une convergence de la loss ; toujours pas d'amélioration de l'erreur Parfois des convergences plus évidentes mais précision finale et stabilité finale globalement équivalente
La priorité serait plus maintenant de stabiliser le modèle pour voir si il y a vraiment un apprentissage
Telle qu'elle la métrique d'erreur est calculée à partir de l'accuracy (erreur = 100 - accuracy).
L'accuracy compte le pourcentage de valeurs exatement prédites par le réseau
Cette métrique ne rend pas forcément compte d'à quel point le modèle est précis : exemple avec des fréquences pour 5 classes (juste pour expliciter l'idée (+ de classes pour nuscene et autre))
Ici l'accuracy vaut 2/5*100 = 40% donc 60% d'erreur
On ne peut pas dire avec l'erreur telle que définie actuellement à quel point le modèle se trompe. On évalue juste pour chaque résultat à combien de reprise le modèle s'est trompé pour une prédiction.
Ainsi on ne fait pas la différence entre une erreur importante sur la classe 1 et une erreur beaucoup plus faible sur la classe
On fait prédire une fréquence d'apparition d'objets sur des images. Néanmoins, on peut se poser la question de la pertinence de ce choix : en effet, on ne demande pas au réseau pour le moment de prédire le nombre d'objets présents sur l'image
2 corrections possibles :
Rappel : Idée originale : prédiction d'un vecteur indiquant pour chaque classe la fréquence d'apparition normalisée par le nombre d'objets présents sur l'image | Idée | 👍 Avantages | 👎 Inconvénients | Conclusion |
---|---|---|---|---|
originale | Le réseau indique à quel point une classse est plus présente qu'une autre | - Impossible de savoir le nombre d'objets détectés par le réseau - Valeur sans réalité concrète pour analyser si les objets sont bien détectés sur l'image ou non |
||
1 | - 1 objet présent -> P(objet)=1 ; 1 objet présent 2x -> P(objet)=1 | Du coup idée non utilisable | ||
2 | - Prédit des entiers (limite le nb de possibilités) - Valeur concrètes avec une réalité sur l'image (permettra interprétation si visualise les zones impactant le + la prédiction avec gradcam par ex) |
.... | Idée plus pertinente |
Problème : fonction d'activation de la dernière couche
Liste fonctions d'activation de keras Pros / Cons des fonctions d'activation
On fixe batch_size=10 ; lr=1e-3 ; epsilon=1e-7
Fonction d'activation | Résultat | Commentaire |
---|---|---|
linear | ![]() |
- Pas de décroissance continue de la loss - Quelques variations très importantes de la loss |
ReLU | ![]() |
- Pas de décroissance continue de la loss - Quelques variations très importantes de la loss - Erreur bloquée à 100% |
Softplus (SmoothReLU) | ![]() |
- Pas de décroissance continue de la loss - Quelques variations très importantes de la loss |
exp | ![]() |
- Pas de décroissance continue de la loss |
Comparaison des fonction
Avant d'appliquer la fonction accuracy(prediction_freq,reference_freq), on ajoute une étape qui arrondira / prendra la partie entière (?) des valeurs prédites avant d'appliquer la fonction accuracy
Pas ce qui a été fait dans tous les essais suivant : calcul effectué : calcul de l'accuracy puis arrondi/partie entière, d'où les 100% ou 0% de précision
Cela permet
(toujours lr=1e-3 ; eps=1e-7 ; batch_size=10)
Fonction d'activation | Approximation | Résultat | Commentaire |
---|---|---|---|
linear | Arrondi | ![]() |
Pics de loss + grands |
linear | Partie entière | ![]() |
Pics de loss + grands |
relu | Arrondi | ![]() |
Réduction de la taille des pixs de loss. Erreur reste bloquée à 100% |
relu | Partie entière | ![]() |
Pic encore - grands ; Erreur plus fluctuante |
softplus | Arrondi | ![]() |
Pas de changement important |
softplus | Partie entière | ![]() |
Pas de changement important |
exp | Arrondi | ![]() |
Pas de changement important |
exp | Partie entière | ![]() |
Pas de changement important |
📝Les fonctions linear, softplus ou exponential permettent d'obtenir le meilleur résultat. Ajuster l'accuracy pour ramener le nombre de classes présentes de float à int n'est pas forcément nécessaire.
On note les modules tels que précisés sur l'architecture synthétique. Recherche par dichotomie. On enchaine le nombre de filtre suivant (128 256 512 728 1024). Update c9b6966 du code pour choix via les arguments du nb de modules (ce qui permet de lancer en parallèle les tests avec != nb de modules)
Rappel de l'architecture de base (4 modules) :
Paramètres fixes : lr=1e-3 ; epsilon=1e-7 ; batch_size=10 ; adaptation de la métrique erreur avec round ; lastActivation linear (en général ce que j'ai vu sur internet pour d'autres modèles)
Modules conservés | Résultats |
---|---|
Module(128) + passage de la SeparableConv2D 44 à 256 filtres | ![]() |
Module(128) à Module(256) + passage de la SeparableConv2D 44 à 512 filtres | ![]() |
Module(128) à Module(512) + passage de la SeparableConv2D 44 à 728 filtres | ![]() |
Module(128) à Module(728) + passage de la SeparableConv2D 44 à 1024 filtres | ![]() |
Motivation : traditionnellement un réseau se termine par une couche flatten pour appliquer ensuite la/les couches denses finales. Ici une couche GlobalAveragePooling est appliquée
Différence :
On garde sinon l'architecture originale
Paramètres fixes : lr=1e-3 ; epsilon=1e-7 ; batch_size=10 ; adaptation de la métrique erreur avec round ; lastActivation linear (en général ce que j'ai vu sur internet pour d'autres modèles)
Type de réseau | Résultat |
---|---|
Architecture originale | ![]() |
Architecture avec GlobalAveragePooling remplacée par une Flatten | ![]() |
📝Plus instable au début. Peut peut-être interprété comme un apprentissage. Mêmes fluctuations après
En effet, d'après les courbes d'apprentissages le réseau ne parvient pas à apprendre. On peut tenter de lui laisser "plus de libertés" quitte à ce qu'il overfit.
On garde sinon l'architecture originale
Paramètres fixes : lr=1e-3 ; epsilon=1e-7 ; batch_size=10 ; adaptation de la métrique erreur avec round ; lastActivation linear (en général ce que j'ai vu sur internet pour d'autres modèles)
Type de réseau | Résultat |
---|---|
Modèle originale (Dropout 0.5) | ![]() |
Modèle avec Dropout de 0.2 | ![]() |
Modèle avec Dropout de 0 | ![]() |
📝Pas de grand changement
On garde sinon l'architecture originale
Paramètres fixes : lr=1e-3 ; epsilon=1e-7 ; batch_size=10 ; adaptation de la métrique erreur avec round ; lastActivation linear (en général ce que j'ai vu sur internet pour d'autres modèles)
Architecture | Résultat |
---|---|
![]() |
![]() |
![]() |
![]() |
📝Pas de grand changement : ne stabilise pas la courbe d'erreur
Paramètres fixes : lr=1e-3 ; epsilon=1e-7 ; batch_size=10 ; adaptation de la métrique erreur avec round ; lastActivation linear (en général ce que j'ai vu sur internet pour d'autres modèles)
Architecture | Commentaire sur les idées de l'archi | Résultat |
---|---|---|
![]() |
Remplacement des couches de convolution simples du début par des modules inceptions (+ de paramètres du coup) | ![]() |
📝 L'erreur stagne moins à 100 %
Version miniature de Xception (https://arxiv.org/pdf/1610.02357.pdf)
On peut noter dans le papier les éléments d'entrainement suivants :
Questions :
SGD moment 0.9 ; lr_init = 0.045 (pas de decay car on ne fait pas une epoch) Adam paramètres standards pas de biais batch_size=10 adaptation de la métrique erreur avec round ; lastActivation linear (en général ce que j'ai vu sur internet pour d'autres modèles) Architecture de base sans biais
Optimisateur | Résultat |
---|---|
Adam | ![]() |
SGD | ![]() |
Contrainte de https://keras.io/api/applications/xception/
créer le modèle xception avec le include_top avec une fonction de classification random, loader les poids imagenet
getter la couche avg_pool pour construire le nouveau modèle
Modèle transfer learning depuis xception en changeant juste la couche finale pour s'adapter au nb de couches de nuscene :
Entrainement avec SGD
loss MSE assume que les valeurs à prédire suivent une distribution normale
"For a Gaussian distribution, this is the best unbiased estimator (i.e., one with the lowest MSE among all unbiased estimators), but not, say, for a uniform distribution." (wikipedia)
Distributions dans le dossier 2021-04-19_12h06min43s_class_distribution_nuscene de data
Très clairement pas équilibré
donne plus d'importance aux classes sous-représentées : si la classe chien est sous-représentée, l'erreur pour une image contenant un chien sera diminuée pour cette classe
donne plus d'importance aux effectifs de classes sous-représentés : si il est rare que 100 chiens soit présents sur une image, si ce cas se présente on va diminuer la loss concernant le nombre de chiens
Note : gris et bleu : courbe avec erreur pondérée suivant méthode 2 (resp. optimiseur Adam et SGD avec paramètres par défaut) ; orange et rouge courbes pondérées suivant méthode 1 (resp optimiseur Adam et SGD)
Courbes d'erreur en pourcent d'entrainement (arrondi)
Courbes d'erreur en pourcent d'erreur de validation (arrondi)
📝 Pas de différence majeure avec un entrainement simple
Commit de référence : 237d4216745d90bba1c767c16456d29500173fa4
D'après publication EfficientNetV2 (partie 4.2 §3) on note que l'on peut améliorer l'apprentissage en le commençant avec des petites images (lui permettant d'apprendre les motifs simples) puis en lui fournissant après de plus grandes rendant la tâche plus difficile
Dans un premier temps nous pouvons commencer par entrainer le réseau sur de plus petites images (de l'ordre de 128 px) Pour cela, il faut adapter les labels pour exclure les bounding boxes trop petites à cause du facteur d'échelle appliqué. On fixe arbitrairement un seuil de 10px comme taille d'image minimale acceptable après redimensionnement
(Mis en place au commit 2870a38e490c6a3f0f544774016b9469bd5f1ef5)
NB : On a bien fait attention à ne pas trop diminuer la taille : en effet, le réseau réduit les dimensions de l'images à 4 reprises
📝 Aucun changement
En cours d'écriture: NORBERT'S REPORT
⚠️ Sans pondération suivant le nombre d'images tel que dans https://github.com/Rob174/PIR/issues/24#issuecomment-822012815
Orange : adam (paramètres par défaut) transfert learning : Xception (entrainement 2021-05-01_23h54min18s) Rouge : adam (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min26s) Bleu : sgd (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min22s)
📓 NB : les courbes les + opaques sont des courbes lissées à 0.6 (sur le tensorboard), les courbes réelles sont en moins opaque de la même couleur
Courbes d'erreur d'entrainement (erreur arrondie à l'entier le + près)
Courbes d'erreur de validation (erreur arrondie à l'entier le + près)
A noter que Xception est plus "gros/profond" que Norbert
lien vers image (trop grande pour être affichée)
⚠️ Rappel : à chaque étape de l'entrainement, pour chaque classe on prédit le nombre d'apparition de chaque classe sur une image.
Note : précision en % = nombre d'images tel que la prédiction est sur la diagonale sur nombre total d'images
Quelques exemples lisibles :
La classe car
est illisible (trop de valeurs) mais les matrices ont été sauvegardées au format csv
Orange : adam (paramètres par défaut) transfert learning : Xception (entrainement 2021-05-01_23h54min18s)
Rouge : adam (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min26s)
Bleu : sgd (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min22s)
Orange : adam (paramètres par défaut) transfert learning : Xception (entrainement 2021-05-01_23h54min18s)
Rouge : adam (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min26s)
Bleu : sgd (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min22s)
Orange : adam (paramètres par défaut) transfert learning : Xception (entrainement 2021-05-01_23h54min18s)
Rouge : adam (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min26s)
Bleu : sgd (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min22s)
Orange : adam (paramètres par défaut) transfert learning : Xception (entrainement 2021-05-01_23h54min18s)
Rouge : adam (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min26s)
Bleu : sgd (paramètres par défaut) : Norbert (entrainement 2021-05-01_23h54min22s)
Problème d'apprentissage
Problème
Version a2fa05f![2021-04-13 00_46_44-ImageMagick_ erreur_accuracy png@srv-gei-gpu1](https://user-images.githubusercontent.com/42274857/114472021-70f93e80-9be9-11eb-9730-47e88f269772.png)
Aucun apprentissage Loss MSE
Etapes suivies / sommaire
Raisonnement générale
Sommaire - étapes 1 à 3 : Hypothèse : modèle ok juste à régler les paramètres d'entrainement (- de possibilités à tester)
Sommaire - étape 4 : les valeurs prédites sont contraintes de se sommer à 1 par la fonction d'activation softmax retournant un vecteur de probabilités. Remplacement par une sigmoid
Sommaire - étape 5 : actualisation des tests de paramètres d'entrainement
Sommaire - étape 6 : les valeurs prédites n'indiquent pas combien d'objet de chaque classe apparaissent sur chaque image
Sommaire - étape 6.a. : changement de sortie du réseau : nouvelle sortie, effectif de chaque classe pour chaque image. Tests pour trouver une nouvelle fonction d'activation finale adaptée qui ne limite pas chaque effectif à 1 comme une fonction sigmoid.
Sommaire - étape 7-8 : Supposition : nécessité d'ajuster l'architecture
Sommaire - étape 9 : Supposition : le modèle underfit : trop contraint, pas assez de couches pour prédire correctement.
⚠️ Note importante : le dernier code à jour de cette issue est sur la branche
model_keras_graphLayers