Spaces:
Sleeping
Sleeping
| # Limites identifiées — modèle CRNN (§15 du cahier des charges) | |
| ## Précision actuelle | |
| Le modèle CRNN (`crnn_vgg16_bn`, fine-tuné à partir des poids pré-entraînés | |
| Mindee) livré dans `models/crnn_fuel_pump_best.pt` atteint **70.2% de | |
| précision exacte par ligne** en validation (epoch 32, voir | |
| `train/models/v2/history.json`) — en progression depuis la version initiale | |
| à ~55% (`train/models/history.json`), grâce au correctif de redimensionnement | |
| (voir point 3) et à l'ajout de 3 images avec des valeurs inédites au jeu | |
| d'annotation. C'est encore en dessous du seuil de 90% visé initialement | |
| (`IMPLEMENTATION_PLAN.md`), mais un progrès net et mesuré sur un vrai | |
| jeu de validation (sans fuite train/val — voir point 4). | |
| ## Causes identifiées | |
| 1. **Diversité des valeurs quasi nulle dans le jeu de données.** 310 | |
| échantillons au total (155 images sources découpées en lignes), mais | |
| seulement **30 valeurs distinctes** — 8 valeurs à elles seules | |
| représentent ~89% du dataset (probablement des photos en rafale des | |
| mêmes transactions). Le modèle a donc très peu d'occasions d'apprendre à | |
| généraliser la lecture de chiffres inédits ; il est plus proche de la | |
| mémorisation d'un nombre restreint de motifs que d'une reconnaissance de | |
| caractères robuste. | |
| 2. **Découpage ligne-par-ligne imprécis pour 86% des images sources.** | |
| `annotator/dataset_lines/split_report.json` montre que seulement 22/154 | |
| images ont utilisé la détection précise par projection de texte ; 132/154 | |
| sont tombées sur le repli "proportionnel" (division en bandes de hauteur | |
| égale), qui peut couper à travers les chiffres ou inclure du bruit — | |
| corrompant l'alignement image↔label pour la majorité de l'entraînement. | |
| 3. **Incohérence corrigée entre entraînement et inférence (resize).** | |
| À l'entraînement, chaque crop était étiré de force à une largeur fixe de | |
| 256px sans préserver le ratio d'aspect (`train/finetune_doctr.py`, | |
| `collate_fn`), alors qu'à l'inférence le ratio d'aspect était préservé | |
| (`preprocess_crop`). Le modèle apprenait donc sur des chiffres déformés | |
| différemment de ce qu'il voit réellement en production. **Corrigé** : | |
| le redimensionnement d'entraînement préserve maintenant le ratio d'aspect | |
| et complète par du padding, comme à l'inférence. | |
| 4. **Fuite train/val corrigée.** Relancer `split_lines.py` après avoir | |
| ajouté des annotations réassignait des images entre train et val (le | |
| split dépend d'un tirage aléatoire sur la liste complète), mais les | |
| anciens fichiers n'étaient pas supprimés avant d'écrire les nouveaux — | |
| une même image pouvait donc se retrouver à la fois dans train ET val, | |
| gonflant artificiellement l'accuracy de validation. **Corrigé** : | |
| `split_lines.py` et `prepare_doctr_dataset.py` nettoient maintenant les | |
| dossiers de sortie avant de régénérer. Le 70.2% actuel est mesuré après | |
| ce correctif — donc fiable. | |
| ## Toujours vrai malgré l'amélioration à 70.2% | |
| Le facteur limitant reste le même : le dataset est petit et peu diversifié | |
| en valeurs. 70.2% de lignes exactement correctes n'est pas suffisant pour | |
| une mise en production telle quelle — voir §"Recommandations" ci-dessous, | |
| qui restent d'actualité. | |
| ## Recommandations pour dépasser 70% | |
| - **Collecter plus de transactions distinctes** (valeurs de prix/volume | |
| variées, pas seulement plus de photos des mêmes tickets) — c'est le levier | |
| le plus impactant, mais aussi le plus long à mettre en œuvre. | |
| - **Revoir le découpage des lignes** : ajuster les seuils de | |
| `annotator/split_lines.py::_detect_text_bands` (actuellement 86% des | |
| images tombent sur le repli proportionnel), ou annoter directement les | |
| bounding box par valeur plutôt que par écran complet. | |
| - **Vérifier visuellement** `annotator/dataset_lines/review/review_sheet.jpg` | |
| avant tout nouvel entraînement, pour écarter les crops mal découpés. | |
| - Envisager de la **data augmentation** (légères rotations, variations de | |
| luminosité/contraste) pour compenser partiellement le manque de diversité. | |
| ## Bug de classification qualité corrigé (flou vs sombre) | |
| `app/quality.py` vérifiait le flou (variance du Laplacien) avant la | |
| luminosité. Or la variance du Laplacien dépend elle-même du contraste, qui | |
| s'effondre dans une image sombre même quand les contours sont nets : une | |
| photo prise dans un environnement peu éclairé mais parfaitement stable | |
| pouvait donc être classée à tort `"blurry"` ("reprendre la photo, image | |
| floue") au lieu de `"dark"` ("reprendre la photo avec plus de lumière") — | |
| deux diagnostics qui appellent un geste correctif différent côté | |
| utilisateur. **Corrigé** : la luminosité (`dark`/`bright`) est maintenant | |
| vérifiée avant le flou, qui n'est un diagnostic fiable que sur une image | |
| déjà correctement exposée. | |
| ## Ce qui reste fiable indépendamment du modèle | |
| La détection d'écran, le contrôle qualité (flou/luminosité), le moteur de | |
| règles métier (cohérence montant/litres/prix, seuil de confiance, blocage) | |
| et l'API ne dépendent pas de la précision du CRNN — ce sont des composants | |
| séparés et testés indépendamment (voir `tests/`). Une amélioration future du | |
| modèle de reconnaissance s'intègre donc sans changer le reste du pipeline. | |