Spaces:
Sleeping
Sleeping
File size: 7,425 Bytes
b510add | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | # 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
```bash
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é :
```bash
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) :
```bash
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
```bash
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.json` contient
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
```bash
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é dans `yely_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 dans
`yely_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é dans `preprocessing.py` — corrigé aussi. Pour
tester le pipeline réellement livré (avec règles métier, API), utiliser
`yely_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 :
1. **Quel script a été utilisé ?** `train/infer.py` et `yely_ai_module/app/`
ont des logiques de détection d'écran différentes (`detect_lcd_region`
vs `detect_screen_region`) — l'un peut réussir là où l'autre échoue sur
la même photo.
2. **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.
3. **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.
4. **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é.
|