You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

champi_rapport_2_modelisation.md 40 KiB

2 days ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. # 🍄 Projet de groupe 2024 sur la reconnaissance de champignons 🍄
  2. > Auteurs : *[Heuzef](https://heuzef.com), Yvan Rolland, Viktoriia Saveleva, Florent Constant*
  3. ---
  4. # Rendu N°2 : Modelisation
  5. > Date : *10/2024*
  6. # 1. Introduction
  7. Dans le cadre du projet de reconnaissance de champignons, nous abordons un problème de deep learning qui s’apparente principalement à une tâche de **classification**.
  8. L’objectif est de classifier différentes espèces de champignons en fonction de leurs caractéristiques visuelles, ce qui s’inscrit dans le domaine de la **reconnaissance d'image**.
  9. Pour évaluer la performance des modèles développés, nous utilisons principalement la métrique de **l'accuracy (précision)**, car elle permet de mesurer le pourcentage de classifications correctes effectuées. Cette métrique est particulièrement adaptée pour ce projet, car elle fournit une évaluation claire et directe de l’efficacité du modèle à distinguer les différentes espèces de champignons.
  10. Dans ce rapport, nous décrivons nos démarches, réflexions et erreurs. Nous analysons également l'effet de la détéction et de l'augmentation des données sur les résultats de nos entrainements.
  11. Un premier model naïf LeNet est utilisé pour l'expérimentation, puis finalement des algorithmes de transfert learning sont adoptés pour leur efficacités.
  12. La comparaison des résultats est effectuée en introduisant la partie MLflow dans les algorithmes, ce qui nous permet de suivre la traçabilité et de faciliter l'échange et la comparaison des résultats.
  13. # 2. Pré-traitement des données
  14. ## Première approche
  15. Pour rappel, le stockage des données se fait comme suit :
  16. ```
  17. data
  18. ├── LAYER0
  19. │ ├── MO
  20. │ ├── MO
  21. │ │ └── dataset.csv
  22. │ └── MO_106
  23. │ ├── MO_106
  24. │ ├── class_stats.csv
  25. │ ├── dispersion.csv
  26. │ └── image_stats.csv
  27. ├── LAYER1
  28. │ └── MO
  29. │ ├── MO
  30. │ ├── dataset.csv
  31. └── LAYER2
  32. └── MO
  33. ├── MO
  34. ├── dataset.csv
  35. └── names.csv
  36. ```
  37. La répartion de ces données intervient dans le but précis de s'assurer de la qualité des donnés avant l'apprentissage pour optimiser les résultats.
  38. **LAYER0** : Obtenu par une sélection manuelle et un webscraping, ce qui nous a permis de constituer un dataset comportant 23 classes. L'objectif était d'avoir au moins une centaine de photos par classe.
  39. Dans le dossier MO, les photos extraites du site Mushroom Observer.
  40. Dans le dossier MO_106, les photos extraites par Webscraping du site : https://www.mycodb.fr/ (utilisées uniquement pour des tests).
  41. **LAYER1** : Lancement de la detection effectuée par YoloV5 (boxing), nous perdons environ 60% des images qui n'ont malheureusement pas été detectée par YoloV5. L'objectif est d'obtenir une base de donnée contenant des images de champignons les plus précises. La base de donnée étant l'élément le plus important pour l'apprentissage, il nous apparaissant pertinent de procéder par une détection et un boxing, focus sur le champignon pour limiter le bruit.
  42. ![Boxing Error](./img/boxing_error.png)
  43. Le traitement effectue également des modifications sur l'image nécessaire au Deep Learning : redimensionnement en 224 X 224 px selon les coordonnées du rectangle de détection.
  44. **LAYER2** : Créé suite à une augmentation des données.
  45. Cela entraînerait une précision excellente (>0.99) dès la première époque sans optimisation, ce que nous souhaitons éviter.
  46. La séparation initiale garantie que les données d'entraînement et de validation sont distinctes, permettant une évaluation plus précise et une généralisation correcte du modèle.
  47. En résumé, LAYER2 représente les données d'entraînement augmentées, tandis que les ensembles de validation et de test restent intacts et non modifiés pour une évaluation juste et précise du modèle. La figure ci-dessous montre schématiquement la structure des couches.
  48. ![Layers_structure_rapport2_v1.png](./img/Layers_structure_rapport2_v1.png)
  49. ## Deuxième approche
  50. Nos premiers essais montre des performances absolument incroyables, cependant, ceci s'explique par une erreur dans notre approche.
  51. En effet, si nous procédons d'abord par l'augmentation des données puis la division, les ensembles de validation contiendrons des images trop proches de l'entrainement, car simplement modifiées par l'augmentation des données.
  52. À ce stade, il est nécessaire d'effectuer l'inverse, en effectuant l'augmentation des donnés exclusivement sur le jeu d'entrainement divisé en amont, sans toucher au jeu de validation et de test.
  53. Notre nouvelle arboresence se présente donc ainsi :
  54. ```bash
  55. data
  56. ├── LAYER0
  57. │   ├── dataset.csv
  58. │   └── MO
  59. │   ├── 1174
  60. │   ├── 15162
  61. │   ├── 1540
  62. │   ├── (...)
  63. │   └── 939
  64. ├── LAYER1
  65. │   └── MO
  66. │   ├── 1174
  67. │   ├── 15162
  68. │   ├── 1540
  69. │   ├── (...)
  70. │   └── 939
  71. └── LAYER2
  72. ├── MO
  73. │   ├── test
  74. │   │   ├── 1174
  75. │   │   ├── 15162
  76. │   │   ├── 1540
  77. │   │   ├── (...)
  78.   │   | └── 939
  79. │   ├── train
  80. │   │   ├── 1174
  81. │   │   ├── 15162
  82. │   │   ├── 1540
  83. │   │   ├── (...)
  84.   │   | └── 939
  85. │   └── validation
  86. │   ├── 1174
  87. │   ├── 15162
  88. │   ├── 1540
  89. │   ├── (...)
  90.   │   └── 939
  91. └── names.csv
  92. ```
  93. Nous prenons à ce stade la décision de ne plus effectuer la detection des champignons via le model YoloV5 pour 2 raisons :
  94. 1. La quantitée d'image brutes perdues de 60% est trop importante.
  95. 2. Nous ne constatons pas d'amélioration des performances suite à cette detection.
  96. Les données de notre base de donnés "MO" seront divisées un jeu d'entrainement, de validation et de test (directement opéré par le code modèle).
  97. Finalement, nos modèles entrainés seront évalués sur le jeu de test afin de les optimisers pour obtenir la meilleur précision possible.
  98. ![Layers_structure_rapport2_v2.png](./img/Layers_structure_rapport2_v2.png)
  99. # 3. Algorithmes de Deep Learning sélectionnés et Optimisation
  100. Les champignons présentent une diversité visuelle significative, avec des variations subtiles de forme, de couleur, et de texture. Les algorithmes de Deep Learning, notamment les **réseaux de neurones convolutifs (CNN)**, sont particulièrement efficaces pour extraire et apprendre des caractéristiques pertinentes à partir d'images, ce qui en fait l'approche idéale pour identifier correctement les différentes espèces de champignons.
  101. Une première expérimentation est effectuée avec un modèle naïf **LeNet**, ce dernier permet d'obtenir des résultats interessants, bien que moindre face aux méthodes de **Transfert learning**, qui offres des performances nettement supérieurs.
  102. En effet, c'est une stratégie clé dans notre approche. En utilisant des modèles pré-entraînés sur de vastes ensembles de données comme ImageNet, nous avons pu adapter ces modèles à notre problème spécifique de reconnaissance des champignons, ce qui a considérablement amélioré les performances des modèles.
  103. Pour cette tâche, nous avons testé plusieurs architectures : VGG16, EfficientNetB1, ResNet50.
  104. Finalement, nous décidons de concevoir un modèle avec une architecture sur mesure: JarviSpore.
  105. Ce dernier est partagé sur HuggingFace: https://huggingface.co/YvanRLD
  106. ## 3.1. VGG16
  107. VGG16 est une architecture de réseau de neurones convolutifs (CNN) développée par l'équipe Visual Geometry Group de l'Université d'Oxford. Ce modèle se distingue par sa structure simple et uniforme, composée de 16 couches profondes dont 13 couches convolutives et 3 couches entièrement connectées. Grâce à sa conception, VGG16 a démontré une grande efficacité dans la classification d'images, comme en témoigne ses performances remarquables lors de la compétition ImageNet 2014. Dans le cadre du transfer learning, VGG16 est fréquemment utilisé avec des poids préentraînés sur des ensembles de données étendus tels qu'ImageNet. Cette stratégie permet d'adapter les caractéristiques apprises par le modèle à des tâches spécifiques avec des ensembles de données plus petits, offrant ainsi une précision accrue même avec des données limitées.
  108. ![VGG16_layover.jpg](img/VGG16_layover.jpg)
  109. Le "16" dans VGG16 fait référence aux 16 couches qui ont des poids. Dans VGG16, il y a treize couches convolutives, cinq couches de max pooling, et trois couches denses, ce qui fait un total de 21 couches, mais seulement seize couches avec des poids, c'est-à-dire des couches avec des paramètres apprenables.
  110. VGG16 prend en entrée un tenseur de taille 224 x 224 px avec 3 canaux RGB. La particularité de VGG16 est qu’au lieu d'avoir un grand nombre d'hyperparamètres, le modèle se concentre sur des couches de convolution avec des filtres de 3x3 avec un stride de 1, en utilisant systématiquement un padding constant et des couches de max pooling avec des filtres de 2x2 et un stride de 2.
  111. Les couches de convolution et de max pooling sont disposées de manière cohérente tout au long de l'architecture. La couche Conv-1 possède 64 filtres, Conv-2 en a 128, Conv-3 en a 256, et Conv-4 et Conv-5 ont 512 filtres chacun.
  112. Trois couches entièrement connectées (FC) suivent une pile de couches convolutives : les deux premières ont chacune 4096 canaux, et la troisième effectue une classification ILSVRC à 1000 classes, contenant ainsi 1000 canaux (un pour chaque classe). La couche finale est la couche softmax.
  113. **Les entrainement réalisés**
  114. De nombreux entrainements en transfert learning ont été réalisés en utilisant les poids imagenet disponibles directement via keras.
  115. Ces entrainements ont permis d'expérimenter deux architectures distinctes ainsi que l'influence de certains hyperparametres :
  116. La première série d'essai a été réalisée avec une architecture comportant une seule couche dense pour la classification.
  117. Les expérimentations menées consistaient à faire varier le batch size et le taux d'augmentation des données.
  118. Les résultats semblent indiquer globalement que le batch size influence de manière importante la precision du modèle. Dans les essais menés plus la taille du batch size était importante, plus la précision était grande. Les limite de mémoire de la machine de test n'ont pas permis d'expérimenter un batch size au delà de 128.
  119. Par ailleur on note que l'augmentation de données n'a quasiement aucune influence sur le résultats.
  120. Cette architecture a permis d'obtenir des scores compris entre 66% et 76% de précision.
  121. La seconde serie d'essais a été réalisée sur une architecture comportant trois couches denses, comme le modèle vgg16 original mais entrecoupées de couches dropout. Les expérimentations menées, en plus de faire varier le batch size et le taux d'augmentation des données, consistaient à faire varier le nombre de cannaux et et le taux de dropout des différentes couches.
  122. Les combinaisons suivantes ont été testées :
  123. * Batch size 32 et 64
  124. * Nombre de cannaux dans les 2 premières couches de classification: 64,128,256,512,1024,2048
  125. * Taux de dropout entre chaque couches: 0%, 10%, 20%
  126. Cette architecture a permis d'obtenir des scores compris entre 70% et 77% de précision.
  127. Ces entrainements ont révélé une très forte tendance du modèle à faire du sur-apprentissage sur notre jeu de données, avec une précision sur les données de test rapidement à 100% quelque soit l'architecture et les paramètres employés:
  128. ![newplot.png](img/newplot.png)
  129. ## 3.2. EfficientNetB1
  130. ### 3.2.1 Environnement de travail
  131. L'entraînement du model EfficientNetB1 a été réalisé sur un environnement sans GPU, ce qui pose certaines contraintes en termes de performance (en particulier sur la mémoire vive). Afin d'entraîner un modèle efficace malgré ces limitations, tout en optimisant l'usage des ressources disponibles. Une astuce fournit par Google est utilisé pour permettre un entrainement sur CPU, [en configurant la fonction expérimental AutoShardPolicy](https://www.tensorflow.org/datasets/performances).
  132. ### 3.2.2 Préparation à la prédiction
  133. Les labels des images ont été récupérés à partir de `.class_names`, fournissant ainsi une liste ordonnée des classes.
  134. Une fonction Python personnalisée `get_champi_name()` a été utilisée pour organiser les noms des labels en fonction des besoins spécifiques du projet pour la prédiction.
  135. ### 3.2.3 Entrainement du modèle
  136. Les images d’entrée ont été redimensionnées en 224x224 pixels, conformément aux attentes du modèle pré-entraîné. Ce format est communément utilisé pour des modèles basés sur **ImageNet**.
  137. Le modèle utilisé est pré-entraîné sur le dataset ImageNet, qui contient plus de 14 millions d'images et 1000 classes. Ce modèle, comprenant environ 9 millions de paramètres, permet d’obtenir une base solide pour la classification des images.
  138. Le `batch_size` est fixé à 32, un compromis entre la vitesse d’entraînement et l’utilisation de la mémoire vive. La structure du modèle a été adaptée pour intégrer la couche finale de classification avec activation softmax, en fonction du nombre de classes cibles.
  139. ### 3.2.4 Évaluation des résultats
  140. Sur 23 classes, le modèle a atteint une précision moyenne de 98 % lors de l'entraînement, indiquant une forte capacité à généraliser sur les données d'entraînement.
  141. Les résultats sur les données de validation varient entre 80 % et 90 %, en fonction des ajustements apportés aux hyperparamètres. Cela montre que le modèle a une bonne capacité de généralisation, mais pourrait être affiné pour éviter le surapprentissage.
  142. Certaines classes de champignion sont visiblement très problèmatique avec ce modèle et ne parviennent quasiment jamais à effectuer des prédictions juste.
  143. ![efficientnetb1_matrice_01](./img/efficientnetb1_matrice_01.png)
  144. Il est noté que certaines espèces de champignons, comme par exemple le Stropharia ambigua *(classe 14)* est souvent prédite comme une autre espece, la seule nuance qui permette de différencier étant la couleur jaunâtre propre a cette espèce, nous pouvons en déduire que ce modèle n'est pas très performant sur la prise en compte des nuances de couleurs.
  145. ![champi_diff](./img/champi_diff.png)
  146. *Les Stropharia ambigua sont prédites sans prendre en compte leur couleur jaunâtre.*
  147. ### 3.2.5 Optimisation
  148. De nouveaux essais sont effectuées sur 16 classes uniquement pour volontairement exclure les classes problématiques, avec une augmentation des donnés et un nombre d'epoch plus généreux.
  149. ![dataset](./img/efficientnetb1_dataset.png)
  150. Ajout de callbacks : **ReduceLROnPlateau** pour améliorer la décente de gradient et **EarlyStopping** pour eviter le sur-entrainement.
  151. Deux couches Dropout avec un taux de 0.5 ont est ajoutés au réseau pour le rendre plus robuste.
  152. Les précédents résultats montrent que les predictions sont clairement moins fiables sur les dernières classes. Ceci est causé car les données ne sont pas mélangés aléatoirement sur les différents jeux de donné. Ainsi, un Shuffle est activé pour forcer l'entrainement des données dans un ordre aléatoire.
  153. L'entrainement s'arrête après seulement 4 epochs grâce au EarlyStopping, le sur-entrainement sur ce modèle interevient très rapidement de par sa nature, mais offre de bonnes perfomances.
  154. ![metrics](./img/efficientnetb1_metrics.png)
  155. ![matrix_02](./img/efficientnetb1_matrix_02.png)
  156. ![predictions](./img/efficientnetb1_predictions.png)
  157. ### 3.2.6 Conclusion
  158. L'entraînement du modèle EfficientNetB1 sur un environnement sans GPU a permis d'obtenir des résultats satisfaisants malgré les limitations matérielles. En optimisant l'utilisation des ressources, notamment grâce à l'astuce de la configuration `AutoShardPolicy`, le modèle a pu tirer parti d'un environnement CPU tout en maintenant de bonnes performances.
  159. L'utilisation d'un modèle pré-entraîné sur ImageNet fourni une base solide pour la classification. De plus, la gestion personnalisée des labels a permis une adaptation efficace aux besoins spécifiques du projet. Nous constatons cependant que ce modèle n'est malheureusement pas très performant lorsqu'il s'agit de nuancer les couleurs des différentes éspèces.
  160. Les performances du modèle ont montré une précision d'entraînement remarquable à 96% et une précision de validation de 86%.
  161. Sur le jeu de test, les scores sont cependant plus interessants :
  162. | Accuracy | Precision | Recall | F1-score |
  163. | --------------- | --------------- | --------------- | --------------- |
  164. | 0.9286764705882 | 0.9336224871829 | 0.9286764705882 | 0.9290201971718 |
  165. Bien que ces résultats soient encourageants, ils révèlent également des marges de progression, notamment pour affiner les scores de précision sur le jeu d'évaluation.
  166. Ces conclusions ouvrent la voie à des pistes d'amélioration, telles que l'optimisation des hyperparamètres et une meilleure gestion des données pour minimiser le risque de sur-apprentissage, EfficientNetB1 étant particulièrement senssible au sur-entrainement.
  167. Bien que l'entrainement sur CPU est satisfaisant, effectuer ces expérimentations avec un GPU devrais offrir un gain de vitesse.
  168. ## 3.3 ResNet50
  169. Après avoir exploré EfficientNetB1, nous avons décidé de tester ResNet50. Cette architecture se distingue par ses blocs résiduels qui facilitent l'entraînement de réseaux très profonds en ajoutant des connexions directes entre les couches. Pour la reconnaissance des champignons, ResNet50 peut être particulièrement intéressant en raison de sa capacité à extraire des caractéristiques complexes tout en maintenant une efficacité computationnelle, ce qui est crucial pour des tâches de classification fines comme celle-ci.
  170. ### 3.3.1. Modèle de base
  171. Le modèle est basé sur **ResNet50**, pré-entraîné sur le jeu de données **ImageNet**. Nous avons enlevé la partie supérieure du modèle (le "top") pour adapter le réseau pré-entraîné à notre tâche spécifique de reconnaissance des champignons. La partie supérieure d'un modèle pré-entraîné est généralement conçue pour des classes spécifiques du jeu de données d'origine, comme ImageNet. En retirant cette partie, nous pouvons ajouter des couches adaptées à notre propre ensemble de classes, ce qui permet au modèle de s'ajuster aux spécificités de notre tâche de classification multiclasse. Nous avons ajouté une couche de **GlobalAveragePooling2D** suivie d'une couche **Dense** de 1024 neurones (taille couramment utilisée dans de nombreux réseaux de neurones pour les couches cachées) avec activation **ReLU**. La dernière couche de sortie est une couche **Dense** avec autant de neurones que de classes dans les données, utilisant une activation **softmax** pour la classification multiclasse.
  172. Les couches du modèle pré-entraîné ResNet50 ont été gelées (non-entraînables) pour conserver les poids appris précédemment et éviter de modifier ces paramètres durant l'entraînement. Le modèle a été compilé avec l'optimiseur **Adam** et une faible valeur d'apprentissage (learning rate = 1e-4). La perte utilisée est **categorical crossentropy**, avec une métrique d’évaluation sur la **précision**.
  173. ![resnet50_model1.png](img/resnet50_model1.png)
  174. **Résultats** obtenus :
  175. Précision d'entraînement : Le modèle montre une précision qui commence à 71 % et atteint presque 100 % (99,96 %) à la fin de l’entraînement. Cela montre que le modèle apprend très bien les données d’entraînement, mais cela suggère aussi un risque de **surapprentissage** (overfitting).
  176. Précision de validation : La précision de validation commence relativement élevée à 81 %, mais fluctue au fil des époques, se stabilisant autour de 84 %. Le modèle généralise relativement bien, mais ne montre pas d'amélioration significative après quelques itérations, suggérant un plateau dans l'apprentissage.
  177. Perte de validation : La perte de validation diminue légèrement au début, mais à partir de la cinquième époque, elle commence à augmenter. Cela reflète encore une fois un surapprentissage, car la perte d’entraînement continue de baisser tandis que la perte de validation augmente. Cela signifie que le modèle se spécialise trop sur les données d’entraînement et ne parvient pas à bien généraliser sur de nouvelles données.
  178. ### 3.3.2. Modèles ajustés
  179. 1) **Ajout de Dropout (0.5)**
  180. Le Dropout a été ajouté après la couche de GlobalAveragePooling2D et après la couche Dense, avec un taux de 0,5. Cela permet de réduire le surapprentissage (overfitting) en désactivant aléatoirement 50 % des neurones pendant l'entraînement. Cela rend le modèle moins dépendant de certains neurones spécifiques et améliore sa capacité de généralisation.
  181. **Régularisation L2 (0.001)**
  182. Une régularisation L2 a été appliquée sur la couche Dense. Cette technique pénalise les poids excessivement élevés, contribuant à réduire le surapprentissage en encourageant des poids plus petits. Cela aide à créer un modèle plus stable et capable de mieux généraliser aux nouvelles données.
  183. **Résultats** :
  184. La précision d'entraînement atteint 77 %, tandis que la précision de validation passe de 70 % à 80 % avec une perte de validation en baisse constante, montrant que la régularisation par Dropout et L2 aide à mieux généraliser et à réduire le surapprentissage.
  185. 2) **Unfreezed layers**
  186. Les 10 dernières couches du modèle de base ResNet50 ont été "défigées" pour être entraînables, ce qui permet à ces couches d'affiner leurs poids pendant l'entraînement. L'apprentissage est effectué avec un taux d'apprentissage plus bas (1e-5) pour éviter une mise à jour trop rapide des poids, et ce sur 10 époques.
  187. **Résultats** : Le surapprentissage est probable, car l'exactitude en entraînement est très élevée, mais l'exactitude en validation stagne et la perte en validation ne diminue pas significativement.
  188. 3) **Régularisation et Dropout** : Deux couches de Dropout à 50% et la régularisation L2 sont ajoutées pour limiter le surapprentissage, en réduisant la dépendance du modèle à certaines connexions spécifiques.
  189. **Optimisation de l'entraînement**
  190. **Early Stopping** : Le modèle arrête l'entraînement si la perte en validation ne s'améliore plus après 3 époques, tout en restaurant les meilleurs poids, évitant un surapprentissage inutile.
  191. **Réduction du taux d'apprentissage (ReduceLROnPlateau)** : Ce callback diminue progressivement le taux d'apprentissage si la validation stagne, permettant des ajustements plus fins dans les dernières étapes d'entraînement.
  192. **Augmentation des epochs** :
  193. Le nombre d'époques est passé à 50, en combinaison avec les mécanismes de contrôle du surapprentissage, pour permettre au modèle d'explorer un espace plus large de solutions tout en conservant une bonne généralisation.
  194. **Résultats** : L'exactitude d'entraînement dépasse 94%, mais l'exactitude de validation progresse lentement et se stabilise, indiquant un possible surapprentissage. La perte d'entraînement diminue, tandis que la perte de validation augmente après quelques époques, renforçant l'hypothèse de surapprentissage. Le taux d'apprentissage, initialement à 1e-5, a été réduit à 2e-6 après la 7e époque, montrant que le modèle a atteint un plateau tôt.
  195. 4) **Augmentation du taux de dropout** à 0,7 pour réduire la dépendance excessive aux neurones spécifiques et prévenir le surapprentissage. 5 couches de ResNet50 sont désormais dégelées pour affiner davantage l'apprentissage.
  196. Le **callback EarlyStopping** a une patience augmentée à 5 pour permettre au modèle de continuer l'entraînement plus longtemps avant d'arrêter si la validation ne s'améliore pas, et le **ReduceLROnPlateau** réduit le taux d'apprentissage plus progressivement, avec un plancher fixé à 1e-6.
  197. Augmentation de la **régularisation L2** dans la couche de sortie à 0.01 pour mieux contrôler le surapprentissage.
  198. ![resnet50_model_last.png](img/resnet50_model_last.png)
  199. **Résultats** L'exactitude d'entraînement atteint 95%, mais la précision de validation stagne autour de 80%, suggérant un surapprentissage. La perte de validation diminue au début mais augmente ensuite, ce qui confirme également un surapprentissage. Le taux d'apprentissage réduit considérablement après la 12e époque, montrant que le modèle a atteint un plateau précoce dans l'entraînement.
  200. ### Conclusion
  201. Malgré une haute précision d'entraînement (95%), le modèle montre encore du **surapprentissage**, avec une précision de validation stagnante autour de 80% et une perte de validation croissante.
  202. Causes possibles :
  203. - Le modèle pré-entraîné sur ImageNet peut ne pas capturer suffisamment les caractéristiques spécifiques des champignons.
  204. - Les données d'entraînement pourraient être insuffisantes pour une généralisation efficace.
  205. - Le taux d'apprentissage pourrait ne pas être optimal pour ce problème spécifique.
  206. Prochaines étapes :
  207. - Augmenter la taille et la diversité des données d'entraînement sur les champignons.
  208. - Ajuster ou simplifier l'architecture du modèle.
  209. - Ajouter des techniques de régularisation supplémentaires.
  210. - Expérimenter avec des modèles spécifiquement entraînés sur des données de champignons ou utiliser des techniques de transfert learning adaptées.
  211. ## 3.4. ResNet18
  212. ResNet18 est comme ResNet50 un réseau de neurones convolutifs utilisant des connexions résiduelles, mais avec une profondeur de 18 couches seulement.
  213. Les essais menés avec ResNet18 ont été immédiatement concluants avec un score de précision d'environs 97% sur notre dataset (23 classe avec en moyenne 166 images par classe).
  214. ![resnet18_01](./img/resnet18_01.png)
  215. Différents essais on permis d'estimer le nombre d'images necessaires pour obtenir un niveau de précision satsfaisant. Ainsi on constate qu'avec un dataset comprenant seulement 80 images par classe on atteint une précision de 97%. Avec seulement 30 images par classe on reste au dessus de 90% de précision, et même avec seulement 10 images par classe on reste au dessus de 80% de précision.
  216. ![resnet18_02](./img/resnet18_02.png)
  217. ## 3.5 JarviSpore
  218. Suite aux résultats mitigés sur le transfert Learning, nous avons pris l'initiative de créer un modèle de zéro avec comme support les cours DataScientest et des livres.
  219. Nous avons investi dans un PC avec carte graphique RTX 3090 disposant de 24 Go de VRAM. Notre PC dispose de 192 Go de RAM. Processeur i9 14900k.
  220. Nous avons ensuite pris le parti de tester dans un environnement WSL2. Cela nous permettait d'utiliser les dernières versions de TensorFlow, Cuda, Cudnn et Keras.
  221. Après l'installation, nous avons construit le modèle dans VSCode, mais lors des entraînements, des problèmes de mémoire nous ont compliqués la tâche.
  222. Nous avons déployé un environnement sous Windows en utilisant d'anciennes versions de TensorFlow, Cuda …
  223. Pour assurer la compatibilité des bibliothèques utilisées et de leurs versions, car la compatibilité TensorFlow sous Windows s'arrête à la version 2.10 :
  224. ```
  225. numpy : 1.26.4
  226. tensorflow : 2.10.0
  227. matplotlib : 3.9.2
  228. scikit-learn : 1.5.2
  229. PIL : 10.4.0
  230. cv2 : 4.10.0
  231. pandas : 2.2.3
  232. ```
  233. Ce modèle effectue l'entraînement, l'évaluation et l'interprétation d'un modèle de réseau de neurones convolutif (CNN) pour une tâche de classification d'images. Voici les différentes étapes et le processus utilisés :
  234. 1. Importation des Bibliothèques
  235. Nous commençons par importer les bibliothèques nécessaires pour la manipulation des données, l'entraînement du modèle, l'évaluation et la visualisation des résultats. Les bibliothèques incluent TensorFlow pour la construction du modèle, NumPy pour les calculs numériques, Pandas pour la gestion des données et OpenCV pour le traitement des images.
  236. 2. Extraction des Versions des Bibliothèques
  237. Nous vérifions les versions des bibliothèques utilisées afin d'assurer la compatibilité des versions.
  238. 3. Chargement des Datasets (structurées et non structurées)
  239. Nous définissons les chemins pour les datasets d'entraînement, de validation et de test. Nous utilisons la fonction image_dataset_from_directory pour charger les images en les redimensionnant à la taille (224, 224) avec un batch size de 32 images. Les ensembles de données sont ensuite configurés pour être mis en cache en mémoire vive, préchargés et optimisés.
  240. 4. Chargement des Classes
  241. Nous chargeons les noms des classes à partir d'un fichier CSV (API MushroomObserver) pour obtenir la liste des classes disponibles. Cela permet au modèle d'associer les indices des classes avec les noms réels lors de l'affichage des résultats.
  242. 5. Construction du Modèle Convolutionnel
  243. Nous construisons un CNN personnalisé avec plusieurs couches de convolution suivies de la normalisation par lots (Batch Normalization), du sous-échantillonnage (MaxPooling) et d'une couche de sortie utilisant softmax pour la classification des 23 classes. Les couches de convolution permettent d'extraire les caractéristiques des images, tandis que les couches denses à la fin effectuent la classification.
  244. 6. Compilation du Modèle
  245. Le modèle est compilé avec l'optimiseur Adam et la fonction de perte sparse_categorical_crossentropy, adaptée à la classification multi-classes avec des étiquettes sous forme d'entiers.
  246. 7. Ajout de l'Early Stopping et du Model Checkpoint
  247. Nous configurons des callbacks pour arrêter l'entraînement si la précision de validation n'augmente plus après 5 époques (early stopping) et pour sauvegarder le meilleur modèle lors de l'entraînement (ModelCheckpoint).
  248. 8. Gestion du Déséquilibre des Classes
  249. Nous vérifions le déséquilibre des classes dans l'ensemble d'entraînement. Si certaines classes sont moins représentées, nous utilisons des pondérations de classe (class_weight) pour accorder plus d'importance aux classes sous-représentées afin d'améliorer la généralisation du modèle.
  250. 9. Entraînement du Modèle
  251. Le modèle est entraîné sur 20 époques, en utilisant les pondérations de classe pour mieux gérer les déséquilibres. Les callbacks configurés permettent de surveiller la performance et de sauvegarder le meilleur modèle.
  252. 10. Génération de la Matrice de Confusion
  253. Après l'entraînement, nous générons une matrice de confusion sur l'ensemble de validation pour évaluer la capacité du modèle à classifier correctement les images. La matrice de confusion est affichée avec les noms des classes pour faciliter l'interprétation des résultats.
  254. 11. Visualisation des Courbes d'Entraînement
  255. Nous affichons les courbes de précision et de perte pour les ensembles d'entraînement et de validation, ce qui nous permet de visualiser l'évolution des performances du modèle pendant l'entraînement.
  256. 12. Sauvegarde du Modèle et Métadonnées
  257. Nous sauvegardons le modèle entraîné au format .keras ainsi que les métadonnées (date d'entraînement, précision sur l'ensemble de test, nombre d'époques). Cela permet de documenter le modèle pour un suivi ultérieur.
  258. 13. Test et Évaluation du Modèle sur l'Ensemble de Test
  259. Nous testons le modèle sur le jeu de données de test pour obtenir la précision finale et évaluer sa performance générale.
  260. 14. Affichage Grad-CAM
  261. Nous implémentons Grad-CAM pour visualiser les activations des couches de convolution du modèle. Cette technique permet d'afficher les régions de l'image qui ont le plus contribué à la décision du modèle. Les résultats sont affichés pour cinq images aléatoires du jeu de test.
  262. Résultats Attendues
  263. - Précision du Modèle : La métrique mesurée est la précision, elle permet de mesurer le pourcentage de classifications correctes effectuées.
  264. - Interprétabilité avec Grad-CAM : Les heatmaps générées par Grad-CAM doivent indiquer les parties pertinentes de l'image, ce qui aide à comprendre le fonctionnement du modèle.
  265. - Généralisation : Avec l'utilisation des callbacks et des pondérations de classe, le modèle doit éviter le sur-apprentissage et bien généraliser sur les données de validation et de test.
  266. Ces étapes permettent de construire un modèle performant pour la classification d'images, tout en prenant en compte les déséquilibres de classe et en offrant des outils d'interprétation des résultats.
  267. Lien vers le modèle sur Hugging Face : https://huggingface.co/YvanRLD/JarviSpore
  268. ![jarvispore_001](./img/jarvispore_001.png)
  269. ![jarvispore_002](./img/jarvispore_002.png)
  270. ![jarvispore_002](./img/jarvispore_003.png)
  271. # 4. Interprétation des résultats avec Grad-CAM
  272. Pour mieux comprendre les résultats et les décisions prises par les algorithmes, nous avons utilisé **Grad-CAM** (Gradient-weighted Class Activation Mapping), une technique puissante d'interprétation des modèles de deep learning, en particulier pour la classification d'images. Cette méthode permet de visualiser les régions d'une image qui influencent le plus les décisions d'un modèle. En générant des cartes thermiques (heatmaps) superposées sur les images d'entrée, Grad-CAM met en évidence les caractéristiques jugées essentielles par le modèle pour ses prédictions.
  273. Pour créer ces cartes thermiques, on commence par calculer les gradients associés à la classe prédite, en les reliant aux cartes de caractéristiques issues de la dernière couche de convolution. Ces gradients sont ensuite moyennés pour obtenir une vue d'ensemble, qui sert à ajuster les cartes de caractéristiques, mettant ainsi en lumière les zones les plus importantes pour la classification.
  274. Avec Grad-CAM, nous pouvons mieux comprendre les performances de nos modèles en analysant visuellement leurs points d'attention. Cette approche nous aide à identifier les forces et les faiblesses des modèles, à déceler d'éventuels biais et à approfondir notre compréhension des décisions prises par les algorithmes.
  275. Le graphique ci-dessous illustre des exemples de cartes thermiques obtenues via EfficientNetB1 et ResNet50 pour quatre classes différentes de champignons.
  276. ![gradcam.png](./img/gradcam.png)
  277. Les "zones chaudes" (zones rouges et jaunes des cartes thermiques) indiquent les régions sur lesquelles le modèle se concentre. En général, ces zones chaudes correspondent à certaines parties du champignon, mais la zone de concentration varie selon la classe de champignon (par exemple, la tige par rapport à la tête du champignon, le bord de la tête, etc.). Il est intéressant de noter que, pour l'image contenant deux champignons, ResNet50 performe mieux en identifiant les deux, tandis qu'EfficientNet se concentre principalement sur un seul champignon.
  278. Cependant, pour la photo avec la présence de la main, ResNet50 était complètement perdu et ne se concentrait pas du tout sur le champignon, tandis qu'EfficientNet l'identifiait mieux.
  279. En somme, ces résultats soulignent l'importance d'une analyse approfondie pour mieux comprendre les performances de chaque modèle dans des situations variées.
  280. # 5. Conclusion
  281. ## 5.1 Comparaison des resultats
  282. Les différents essais réalisés ont mis en évidence d'importantes différences de résultats obtenus avec divers modèles sur un même jeu de données. Alors que certains modèles, comme VGG16, affichent des limites significatives pour ce cas d'utilisation, d'autres, tels que ResNet18, ont démontré d'excellentes performances.
  283. En poursuivant notre analyse, nous avons également comparé ResNet18 et ResNet50. Cette comparaison montre qu'un modèle plus profond n'est pas toujours synonyme de meilleures performances ; au contraire, sur un petit jeu de données, un modèle plus complexe peut s'avérer moins performant.
  284. Dans le cadre de notre projet, nous avons intégré l'approche MLflow pour améliorer le suivi et la gestion de nos expériences en apprentissage automatique.
  285. Ce dernier est utilisé pour tracer chaque étape du processus expérimental, notamment les paramètres, les métriques, et les artefacts des modèles.
  286. Nous avons configuré un serveur de tracking, défini un projet spécifique pour organiser nos expérimentions.
  287. Cette intégration permet de centraliser et comparer les métriques et de faciliter le déploiement ultérieur des modèles retenus.
  288. Ainsi, nous pouvons suivre de manière systématique et efficace les progrès réalisés dans notre projet. Les captures suivantes résument donc les résultats de l'ensemble du projet :
  289. ![mlflow](./img/mlflow.png)
  290. ![mlflow2](./img/mlflow2.png)
  291. ## 5.2 Interpretabilité
  292. Les différentes évaluation des modèles effectués sur des données de tests montrent que de façon global, les modèles ont tous tendance à effectuer de la sur-interprétation et gèrent particulièrement mal les couleurs des champignons.
  293. En effet les méthodes Grad-Cam permettent de visualiser cette tendance à prendre en compte des zones précises, sans se concentrer sur les zones très colorés. La couleur est pourtant l'un des points les plus importants, les modèles montrent tous de grandes faiblesse pour différencier deux champignons physiquement identique avec la couleur comme seul élément de différenciation ou encore de simplement localiser un champigon, même de couleur vive, si le fond de la photo contient des éléments avec une forte luminosité proche du blanc.
  294. ![jarvispore_004](./img/jarvispore_004.png)
  295. ## 5.3 Technique
  296. Nous pouvons noter que si les modèles avec une architeture les plus basiques (Lenet) offre des resultats très moyen, ceux en transfert learning offrent cependant des resultats performants même si rapidement sujet à un sur-apprentissage malgrès nos essais avec différentes technique d'optimisation.
  297. Nous concluons sur le fait que la conception d'un modèle sur-mesure, avec une architecture complexe, bien que très fastidieux, permet d'obtenir des métriques et rapports de classification plus performant à tout les niveaux.
  298. En effet, décision est prise d'implémenter un modèle nommé JarviSpore, solution modulable au fur et à mesure de l'avancée de nos connaissances. Celui-ci est arrivé à maturité et présente des performances supérieures.
  299. # 6. Pour aller plus loin
  300. ## Modèles Open-Source
  301. L'utilisation de modèles plus récents accessible sur HuggingFace nous permettrais très surement d'obtenir encore de meilleurs performance de précision.
  302. Nous expérimentons l'utilisation d'un modèle communautaire de classification pré-entrainé sur 100 espèces de champignons russe.
  303. Ce modèle, partagé par Dmytro Iakubovskyi, est entrainé sur 233480 images et se base sur l'architecture ViT (85.9M de paramètres).
  304. [🤗 Mid-ViT par dima806 - HuggingFace](https://huggingface.co/dima806/mushrooms_image_detection)
  305. ## Réseaux Kolmogorov-Arnold
  306. Les MLP (réseaux de neurones multicouches), bien qu'utilisés dans de nombreux contextes, sont souvent sujets à l'overfitting en raison de leur grande flexibilité, et comportent de nombreux paramètres difficiles à interpréter, ce qui limite leur utilité dans certaines applications.
  307. Récemment, les réseaux Kolmogorov-Arnold (KAN) ont été proposés comme une alternative prometteuse (article : https://arxiv.org/abs/2404.19756, GitHub : https://github.com/KindXiaoming/pykan).
  308. Contrairement aux MLP, qui utilisent des fonctions non linéaires fixes comme ReLU ou Tanh, les KAN exploitent des B-splines, des polynômes par morceaux, pour modéliser les données de manière plus souple et ajustée. Cela permet d'améliorer l'interprétabilité des modèles et de réduire le nombre de paramètres, rendant les KAN plus efficaces et potentiellement moins sensibles à l'overfitting.
  309. Cependant, bien que les KAN présentent de nombreux avantages théoriques, ils restent instables, avec des résultats sensibles aux hyperparamètres choisis, ce qui nécessite des ajustements soigneux pour chaque tâche.
  310. Pour les prochains tests, il sera crucial d'explorer davantage cette nouvelle architecture, de tester son potentiel de généralisation sur des données variées, et d'évaluer dans quelle mesure elle peut remplacer les MLP dans des architectures complexes.