Spaces:
Sleeping
Entraîner, annoter, évaluer le modèle CRNN
Ce document explique comment lancer chacune des trois étapes : annoter de
nouvelles images, ré-entraîner le modèle, évaluer sa précision. Les scripts
utilisés vivent dans le dépôt d'origine (annotator/, train/ à la racine),
pas dans yely_ai_module/ — ce dossier livrable embarque une copie de
référence de train/ pour la reproductibilité (voir §"Où ça vit" plus bas).
Vue d'ensemble du pipeline data → modèle
1. Annoter annotator/annotate.py
│ (dessine le rectangle LCD + saisit prix/volume/prix_litre)
▼
annotator/annotations/annotations.json (+ crops dans annotations/crops/)
│
2. Découper en lignes annotator/split_lines.py
│ (1 image = 3 valeurs → 3 sous-images mono-ligne)
▼
annotator/dataset_lines/{train,val}/
│
3. Convertir au format doctr train/prepare_doctr_dataset.py
▼
annotator/dataset_doctr/{train,val}/ (images/ + labels.json)
│
4. Entraîner train/finetune_doctr.py
▼
train/models/crnn_fuel_pump_best.pt (+ history.json)
│
5. Évaluer train/test_model.py
1. Annoter de nouvelles images
cd annotator
python annotate.py --images ../images/ # nouvelles photos
python annotate.py --images ../images/ --resume # reprendre où on s'était arrêté
python annotate.py --review # voir un résumé des annotations existantes
Pour chaque image : dessiner un rectangle autour de l'écran LCD (clic +
glisser), puis saisir dans le terminal les valeurs affichées (prix, volume,
prix du litre). Voir annotator/README.md pour le détail des raccourcis.
Ce qui compte le plus pour améliorer le modèle (voir docs/LIMITATIONS.md) :
annoter des photos avec des valeurs différentes de celles déjà présentes,
pas juste plus de photos des mêmes tickets. Utiliser
yely_ai_module/tools/check_seen_image.py pour vérifier qu'une photo
candidate n'est pas déjà (quasi-)présente dans le jeu annoté :
python yely_ai_module/tools/check_seen_image.py chemin/vers/nouvelle_photo.jpg
2. Régénérer le dataset d'entraînement
Toujours dans cet ordre, et jamais pendant qu'un entraînement tourne
(le chargement des images se fait à la volée pendant l'entraînement — les
régénérer en même temps fait planter le script avec un FileNotFoundError,
vécu concrètement pendant cette session) :
cd annotator
python split_lines.py # annotations.json -> dataset_lines/
cd ../train
python prepare_doctr_dataset.py # dataset_lines/ -> dataset_doctr/
Les deux scripts nettoient maintenant leur dossier de sortie avant de régénérer (corrigé cette session — une même image pouvait sinon se retrouver à la fois en train et en val d'un run à l'autre, faussant l'évaluation).
Vérification recommandée avant d'entraîner : ouvrir
annotator/dataset_lines/review/review_sheet.jpg, qui montre un échantillon
d'images découpées à côté du label attendu — permet de repérer un mauvais
découpage avant de perdre du temps à entraîner dessus.
3. Lancer l'entraînement
cd train
python finetune_doctr.py # 80 epochs par défaut
python finetune_doctr.py --epochs 60 --patience 12
python finetune_doctr.py --from-scratch # si pas de connexion internet (pas de poids pré-entraînés)
- Le modèle est sauvegardé dans
train/models/crnn_fuel_pump_best.ptà chaque fois que la perte de validation s'améliore (pas seulement à la fin) — s'arrêter en cours de route (Ctrl+C, crash) ne perd donc pas tout. --patience N: arrête l'entraînement si la perte de validation ne s'améliore plus pendant N epochs (évite de continuer à surapprendre inutilement).- Sur CPU (pas de GPU disponible), compter
1.5-3 min/epoch sur le jeu de données actuel (270 échantillons train). Un entraînement complet peut donc prendre plusieurs heures — lancer en arrière-plan (... &ou un terminal dédié) plutôt qu'en bloquant. - À la fin (ou à l'arrêt anticipé),
train/models/history.jsoncontient la courbe complète (perte/accuracy par epoch) — sert de preuve pour le rapport de test (§15 du cahier des charges).
4. Évaluer le modèle
cd train
python test_model.py # évalue sur tout le set de validation
python test_model.py --image ../images/pompe.jpg # teste une seule image
test_model.py calcule, sur le jeu de validation :
- Exact-match accuracy : proportion de lignes lues à 100% correctement
(c'est la métrique citée dans
docs/LIMITATIONS.md). - CER (Character Error Rate) et WER : à quel point une prédiction fausse est "proche" de la bonne réponse (ex. "10000" lu "1O000" a un CER faible même si l'exact-match échoue) — plus informatif que l'accuracy seule pour juger si le modèle progresse.
- La liste des erreurs (jusqu'à 15 affichées), utile pour repérer des motifs d'erreur récurrents (un chiffre systématiquement confondu, une ligne toujours mal découpée...).
Où ça vit (dépôt d'origine vs dossier livrable)
- Annotation et préparation du dataset (
annotator/) : uniquement à la racine du dépôt d'origine, pas dupliqué dansyely_ai_module/(le jeu de ~155 images sources n'est volontairement pas inclus dans le livrable). - Entraînement (
train/) : présent aux deux endroits. La copie dansyely_ai_module/train/est une référence pour la reproductibilité (documentation technique) ; pour ré-entraîner réellement, utiliser la version à la racine du dépôt, qui a accès àannotator/dataset_doctr/. - Script
train/infer.py: ancien script d'inférence autonome (antérieur àyely_ai_module/app/recognizer.py), gardé pour test rapide en ligne de commande. Avait le même bug de découpage à 2 lignes (au lieu de 3) que celui corrigé danspreprocessing.py— corrigé aussi. Pour tester le pipeline réellement livré (avec règles métier, API), utiliseryely_ai_module/app/, pas ce script.
Si le modèle donne de mauvais résultats en test manuel
Avant de conclure "le modèle n'est pas bon", vérifier dans l'ordre :
- Quel script a été utilisé ?
train/infer.pyetyely_ai_module/app/ont des logiques de détection d'écran différentes (detect_lcd_regionvsdetect_screen_region) — l'un peut réussir là où l'autre échoue sur la même photo. - La zone détectée est-elle la bonne ? Les deux scripts peuvent
confondre le bandeau de marque ("Shell FuelSave...") avec l'écran LCD sur
certaines photos (voir
docs/PREPROCESSING.md) — sauvegarder et regarder le crop intermédiaire avant d'incriminer le CRNN. - La photo est-elle inédite ou proche du jeu d'entraînement ?
(
tools/check_seen_image.py) — le modèle est attendu comme moins bon sur des valeurs qu'il n'a jamais vues, c'est documenté et mesuré (docs/LIMITATIONS.md), pas une surprise. - Quelle précision réelle attendre ? 70.2% exact-match sur les lignes
de validation (
train/models/v2/history.json) — donc environ 3 lectures sur 10 avec au moins un caractère faux sont attendues à ce stade, pas un signe que quelque chose est cassé.