Aller au contenu

Entraîner des modèles de détection et de segmentation sur des annotations d'images

Affinez un détecteur sur les boîtes de votre étude, montrez les boîtes prédites aux annotateurs comme pré-étiquettes, réentraînez sur les corrections et adaptez l'exécution aux lames et aux cellules.

Nouveauté de la v2.14.0

Ce tutoriel entraîne un détecteur d'objets sur les boîtes englobantes d'une étude et montre les boîtes du détecteur aux annotateurs suivants comme pré-étiquettes à corriger. Il s'adresse aux responsables d'étude qui ont un schéma image_annotation et qui ont lu Entraîner votre premier modèle ou connaissent la page Training de l'administration. La première moitié exécute une boucle complète avec torchvision-detect (boîtes sur des images, une exécution d'entraînement, l'écriture en retour, des corrections et une seconde exécution), et chaque étape y a tourné sur le processeur d'un portable. La seconde moitié adapte la boucle à YOLO, aux contours, à l'affinage par SAM, aux classes d'images entières, aux lames entières, à la microscopie, aux cartes, aux cellules, aux pages de documents et aux modèles vision-langage, une section chacun.

Installer les modules d'entraînement pour la vision

torchvision-detect affine un détecteur Faster R-CNN de torchvision. Le module a besoin de torch et de torchvision. Potato laisse les deux hors de l'installation par défaut, car torch est un téléchargement de plusieurs gigaoctets. Installez l'extra pour la vision sur la machine qui entraîne :

bash
pip install "potato-annotation[train-vision]"

Le même extra couvre torchvision-segment, hf-image-classification, sam-finetune, layoutlmv3 et vlm-sft. Un module dont les paquets manquent apparaît sur la page Training avec la mention « not installed » et la commande qui installe les paquets.

Un GPU est facultatif pour le petit projet ci-dessous. Sur un Mac à puce Apple, torchvision-detect et torchvision-segment s'entraînent sur le processeur plutôt que sur Metal (mps), et le journal de l'exécution consigne le changement avec l'avertissement « torchvision-detect does not run on Apple's Metal (mps) with this torch; using the CPU ». Dans les mesures de l'équipe Potato, un pas d'entraînement sur Metal à la taille d'image par défaut a duré plus longtemps qu'une époque complète sur le processeur. Pour des images plus grandes ou une étude plus grande, entraînez sur un serveur GPU comme le décrit l'entraînement à distance.

Préparer un projet d'images

Le projet a besoin de trois éléments : les images, un fichier de données qui liste les images et une configuration. Placez les images dans un dossier nommé media à l'intérieur du dossier du projet, car Potato sert <task_dir>/media/ au chemin d'URL /media/ par défaut. Un autre dossier convient quand la configuration le nomme avec media_directory.

text
shapes/
  config.yaml
  data/images.jsonl
  media/img_001.png
  media/img_002.png
  ...

Chaque ligne de data/images.jsonl est un item avec un identifiant et le chemin d'URL de l'image :

json
{"id": "img_001", "image_url": "/media/img_001.png"}

La configuration définit un schéma image_annotation avec l'outil bbox et deux étiquettes, et active l'entraînement de modèles avec l'écriture en retour. La configuration passe python -m potato.validate_cli --strict :

yaml
annotation_task_name: "Shape detection (model training)"
task_dir: "."
data_files:
  - "data/images.jsonl"
item_properties:
  id_key: "id"
  text_key: "image_url"
output_annotation_dir: "annotation_output"
 
require_password: false
admin_api_key: "demo-admin-key"
num_annotators_per_item: 1
 
annotation_schemes:
  - annotation_type: "image_annotation"
    name: "objects"
    description: "Draw a box around every circle and every square."
    source_field: "image_url"
    tools: ["bbox"]
    labels:
      - name: "circle"
        color: "#e6194b"
      - name: "square"
        color: "#4363d8"
 
model_training:
  enabled: true
  writeback:
    schemas: ["objects"]
    include_unlabeled: true
    min_confidence: 0.5

Quatre réglages façonnent la boucle :

  • source_field: "image_url" indique au widget d'image et au module d'entraînement quel champ de l'item contient l'image.
  • num_annotators_per_item: 1 donne un annotateur à chaque image, donc les étiquettes de départ couvrent le plus grand nombre possible d'images différentes.
  • writeback.include_unlabeled: true fait prédire à chaque exécution sur les images que personne n'a encore étiquetées. Sans ce réglage, une exécution ne prédit que sur les images réservées val et test, et ces images ont déjà des boîtes humaines.
  • writeback.min_confidence: 0.5 retient la prédiction d'une image quand le score moyen de ses boîtes est inférieur à 0,5. Le seuil s'applique à l'image entière, donc les annotateurs ne voient jamais la moitié des boîtes d'une image.

Démarrez le serveur depuis l'intérieur du dossier du projet :

bash
potato start config.yaml -p 8000

Étiqueter un jeu de départ

torchvision-detect refuse de s'ajuster avec moins de 20 images annotées dans la partition train, et la partition par défaut place 70 % des images étiquetées dans train. Étiquetez au moins 30 images, et davantage si les objets varient. Dessinez les boîtes à la main à http://localhost:8000. Une image sans boîte est écartée de l'entraînement, car un détecteur ne peut pas distinguer une image sans objet d'une image que personne n'a terminée. Dessinez chaque objet d'une image que vous soumettez.

Pour essayer la boucle avant qu'une personne étiquette quoi que ce soit, le simulateur d'utilisateurs peut dessiner des boîtes à partir d'un fichier de référence. Chaque entrée de référence donne l'identifiant de l'image et les formes du schéma en coordonnées normalisées :

json
[
  {"id": "img_001", "objects": [
    {"type": "bbox", "label": "circle",
     "coordinates": {"x": 0.158, "y": 0.849, "width": 0.106, "height": 0.146}}
  ]}
]
bash
python -m potato.simulator --server http://localhost:8000 --users 3 \
  --strategy gold_standard --competence good=1.0 --max-annotations 20 \
  --gold-file data/gold.json --sequential --fast-mode --no-export

Le simulateur redessine chaque boîte de référence avec quelques pixels de gigue, et au niveau good il oublie ou étiquette aussi mal certains objets, comme le fait parfois un annotateur soigneux. Dans notre test sur 80 images synthétiques, trois annotateurs simulés ont étiqueté 60 images en une seconde environ.

Entraîner torchvision-detect

Ouvrez http://localhost:8000/admin, saisissez la clé d'administration demo-admin-key, puis ouvrez http://localhost:8000/admin/training. Choisissez objects comme schéma et torchvision-detect comme module d'entraînement, laissez Parameters vide et cliquez sur Train now. La même exécution démarre depuis un script avec :

bash
curl -X POST -H "X-API-Key: demo-admin-key" -H "Content-Type: application/json" \
  http://localhost:8000/admin/training/api/runs \
  -d '{"trainer": "torchvision-detect", "schemas": ["objects"]}'

L'exécution part des poids COCO de torchvision et place une nouvelle tête de boîtes sur le détecteur pour les deux étiquettes du schéma. Torch télécharge les poids COCO dans son cache à la première exécution. Les valeurs par défaut sont la petite architecture fasterrcnn_mobilenet_v3_large_fpn, 15 époques, 4 images par pas et un arrêt anticipé après 4 époques sans meilleur mAP sur val. Chaque forme s'entraîne comme sa boîte englobante, donc une étude dont les annotateurs ont dessiné des polygones entraîne tout de même un détecteur de boîtes. Avec plusieurs annotateurs par image, l'exécution s'entraîne sur l'unique réponse entière que model_training.aggregation retient pour l'image, car les boîtes de deux personnes coïncident rarement exactement.

Sur le processeur Apple M4 Pro que nous avons utilisé, 37 images d'entraînement de 320 sur 240 pixels se sont entraînées en 106 secondes environ, et l'exécution s'est arrêtée après 5 époques. Les fichiers de l'exécution se trouvent dans annotation_output/training/runs/<run_id>/, avec le détecteur ajusté dans artifacts/model/detector.pt. Les paramètres de l'exécution et l'appareil utilisé figurent dans artifacts/model_card.json.

Lire le score sur items réservés

Chaque exécution évalue le détecteur sur les images qu'il n'a jamais vues à l'entraînement. Le score principal pour un schéma image_annotation est map_50, la précision moyenne COCO où une boîte prédite compte comme correspondante quand elle recouvre la boîte englobante d'un objet annoté avec un IoU d'au moins 0,5. La page de l'exécution enregistre aussi map_50_95, la moyenne sur les seuils d'IoU de 0,5 à 0,95. Les boîtes de deux annotateurs pour un même objet se recouvrent rarement à un IoU de 0,9, donc les seuils plus stricts mesurent en partie la cohérence du dessin humain. Potato met donc le seuil de 0,5 en avant. Mesurer l'accord sur des boîtes englobantes montre comment vérifier directement cette cohérence.

Le détecteur garde le point de contrôle de l'époque au meilleur score sur val, donc le score principal vient de la partition test quand celle-ci contient des images. Le tableau Runs affiche le score principal dans la colonne Held-out score. La page de l'exécution liste n_train, n_boxes, la taille et la couverture de chaque partition, ainsi que le nombre d'objets annotés et prédits sur val et test. Dans notre exécution de test sur les 80 images synthétiques de cercles et de carrés colorés, le détecteur a obtenu 0,99 en map_50 sur test. Des formes synthétiques sont bien plus faciles à trouver que de vrais objets, donc jugez le score sur vos propres images.

Vérifier les pré-étiquettes

Après une exécution réussie, Potato écrit les boîtes du détecteur dans le champ predictions de chaque image éligible. GET /admin/training/api/status rapporte le résultat dans le champ writeback de la réponse, avec n_written pour les images qui ont reçu des pré-étiquettes et un compte pour chaque raison de retenue d'une image, par exemple n_skipped_low_confidence sous min_confidence et n_skipped_train_split pour les images sur lesquelles l'exécution s'est entraînée. Les images de la partition train ne reçoivent jamais de pré-étiquettes, car la confiance d'un modèle sur ses propres données d'entraînement ne dit rien sur de nouvelles images.

Connectez-vous à http://localhost:8000 avec un nouveau nom d'utilisateur. Chaque image non étiquetée qui a passé les vérifications d'écriture en retour s'ouvre avec les boîtes du détecteur déjà dessinées. Chaque boîte est stockée avec source: ai et le score du détecteur comme confidence. L'annotateur déplace ou redimensionne une boîte, change une étiquette, supprime une fausse détection et dessine tout objet que le détecteur a manqué. Les boîtes deviennent la réponse de l'annotateur quand celui-ci les modifie ou passe à l'image suivante. Une pré-étiquette n'est jamais enregistrée tant que l'annotateur ne fait que regarder l'image. La file de relecture des modèles sert les images pré-étiquetées en commençant par les moins sûres, et le verdict correct d'un relecteur place l'image dans la partition train de toutes les exécutions suivantes.

Réentraîner sur les boîtes corrigées

Chaque image corrigée devient une étiquette humaine pour l'exécution suivante. Lancez une autre exécution torchvision-detect depuis la page Training une fois que les annotateurs ont traité un lot d'images pré-étiquetées. Une nouvelle exécution remplace la prédiction de l'exécution précédente sur chaque image, et la pré-étiquette d'une image sur laquelle la nouvelle exécution s'entraîne est retirée.

Pour réentraîner sans cliquer, ajoutez un bloc auto_retrain. Ce fragment étend le bloc model_training ci-dessus et démarre une exécution après chaque lot de 25 nouvelles annotations, au plus une fois toutes les 10 minutes :

yaml
model_training:
  enabled: true
  auto_retrain:
    enabled: true
    trainer: torchvision-detect
    schemas: [objects]
    update_frequency: 25
    min_interval_s: 600
  writeback:
    schemas: [objects]
    include_unlabeled: true
    min_confidence: 0.5

Les pré-étiquettes ancrent les annotateurs sur les boîtes du modèle. Activez l'écriture en retour pour les annotateurs une fois que le score sur items réservés justifie les pré-étiquettes, et voyez Détecter les pré-étiquettes validées sans examen pour une façon de vérifier si les annotateurs acceptent des boîtes sans les regarder.

Détection plus rapide avec Ultralytics YOLO

ultralytics-detect entraîne un détecteur Ultralytics YOLO à partir d'un point de contrôle préentraîné sur COCO (yolo11n.pt par défaut) sur les mêmes boîtes. YOLO s'entraîne et prédit plus vite que torchvision-detect, et les pré-étiquettes sont les mêmes boîtes modifiables. Ultralytics est sous licence AGPL-3.0, et un modèle entraîné et distribué avec Ultralytics porte les conditions de l'AGPL. Ultralytics vend une licence d'entreprise distincte pour un usage fermé. Les extras de Potato laissent Ultralytics de côté, donc installez le paquet vous-même :

bash
pip install ultralytics

Potato vous demande de confirmer la licence avant chaque exécution. La page Training affiche une confirmation, une exécution par l'API demande "accept_licence": true dans le corps de la requête, et un réentraînement automatique demande auto_retrain.accept_licence: true. Sans la confirmation, l'API refuse l'exécution avec HTTP 400, needs_licence_ack: true et le message « ultralytics-detect is licensed AGPL-3.0 ». La requête ci-dessous confirme la licence et démarre l'exécution :

bash
curl -X POST -H "X-API-Key: demo-admin-key" -H "Content-Type: application/json" \
  http://localhost:8000/admin/training/api/runs \
  -d '{"trainer": "ultralytics-detect", "schemas": ["objects"], "accept_licence": true}'

Pendant une exécution, le module d'entraînement désactive les statistiques d'usage d'Ultralytics, Ultralytics HUB, les intégrations d'outils de suivi d'expériences et les installations automatiques de paquets. Les changements s'appliquent en mémoire pour le processus de l'exécution, et votre fichier de réglages Ultralytics reste inchangé. Les points de contrôle se téléchargent dans ~/.cache/potato/ultralytics. Les valeurs par défaut sont 50 époques à 640 pixels avec un arrêt anticipé après 10 époques.

Des contours au lieu de boîtes

torchvision-segment entraîne un Mask R-CNN de torchvision sur des contours en polygone, en ellipse, à main levée et en masque de pinceau. Les boîtes sont écartées de l'entraînement de segmentation, car une boîte ne dit pas quels pixels appartiennent à l'objet. Donnez aux annotateurs un outil de contour tel que polygon ou brush. Comment annoter des masques de segmentation d'images explique quand chaque outil convient.

Chaque masque prédit est tracé en un polygone d'au plus 64 sommets, donc l'annotateur corrige la pré-étiquette point par point. Quand un masque sort en morceaux, le plus grand morceau est conservé. Le score_threshold par défaut est 0,5 plutôt que le 0,25 du détecteur. Les secondes hypothèses de Mask R-CNN pour un même objet obtiennent entre 0,25 et 0,6, et chaque hypothèse serait une forme de plus à supprimer pour l'annotateur. Les scores sur items réservés comparent les polygones prédits aux contours annotés. Sur un Mac, torchvision-segment s'entraîne sur le processeur. Avec torch 2.8, l'équipe Potato a mesuré un pas d'entraînement sur une image de 256 pixels à 57 secondes sur Metal et 2,3 secondes sur le processeur. Utilisez un serveur GPU pour de vraies études. ultralytics-segment est la version YOLO (yolo11n-seg.pt), avec les mêmes polygones de 64 sommets et la même confirmation de licence AGPL-3.0.

Transformer des boîtes en contours avec sam-finetune

Les boîtes se dessinent vite et les contours lentement. sam-finetune affine le décodeur de masques de Segment Anything (SAM) pour transformer une boîte en contour que vos annotateurs dessineraient. L'encodeur d'image reste figé, et le plongement de chaque image est calculé une seule fois, donc une époque coûte peu. L'entraînement sollicite chaque contour annoté avec sa boîte englobante. L'exécution déplace et redimensionne chaque boîte de sollicitation d'au plus box_jitter (5 % par défaut), donc le décodeur apprend à partir de boîtes aussi lâches que celles d'un détecteur.

sam-finetune affine des boîtes et a besoin de boîtes pour commencer. La séquence habituelle sur un schéma comporte deux exécutions :

  1. Exécutez torchvision-detect ou ultralytics-detect avec writeback.include_unlabeled: true, pour que les images non étiquetées portent des pré-étiquettes de boîtes.
  2. Exécutez sam-finetune sur le même schéma. Chaque pré-étiquette de boîte devient une pré-étiquette de polygone, et les polygones remplacent les boîtes.

Le schéma a besoin de contours dont SAM puisse apprendre, donc donnez aux annotateurs un outil de contour à côté de bbox. Sur les images réservées, les boîtes propres des annotateurs servent de sollicitations, donc val_mask_iou rapporte l'IoU moyen du contour quand la boîte est juste. Ces prédictions sur items réservés sont évaluées mais jamais stockées ni publiées, car elles sont faites à partir de la réponse d'un autre annotateur. Le rapport d'écriture en retour compte les prédictions sur items réservés dans n_skipped_heldout_only. Le point de contrôle par défaut est facebook/sam-vit-base (Apache-2.0). Le décodeur affiné ne sert que des pré-étiquettes. Le clic pour segmenter de l'outil d'image exécute des poids ONNX distincts dans le navigateur, et une exécution sam-finetune ne remplace pas ces poids.

Classer des images entières

Pour une question sur l'image entière, par exemple un schéma radio qui demande quel animal montre une photo, utilisez un classifieur plutôt qu'un détecteur. hf-image-classification affine tout modèle que AutoModelForImageClassification de Hugging Face charge, comme ViT, DeiT, BEiT, ConvNeXt, Swin ou DINOv2. Le modèle par défaut est google/vit-base-patch16-224-in21k. Le module retourne les images d'entraînement au hasard par défaut. Définissez flip à false dans Parameters quand un retournement change l'étiquette, comme pour du texte dans l'image ou la gauche et la droite. lora: true entraîne un adaptateur LoRA et la tête de classification au lieu de tous les poids.

Un schéma de choix compte comme un corpus d'images quand au moins 80 % des items étiquetés du schéma portent un chemin d'image se terminant par .jpg, .jpeg, .png, .bmp, .webp, .tif, .tiff ou .gif. Sur un tel corpus, sklearn-text sans vectoriseur nommé ajuste un classifieur linéaire sur des plongements d'images CLIP. La référence CLIP n'a pas besoin de GPU, seulement de pip install "potato-annotation[embeddings]" pillow.

Chemins d'images et images distantes

Les modules d'entraînement pour les images lisent le champ que nomme le source_field du schéma. Sans source_field, un module prend le premier champ d'item non vide parmi image_url, image, image_path, file_name, url, path, et les équivalents audio et vidéo. Les images doivent être des fichiers locaux à l'intérieur du projet :

  • Un chemin relatif se résout par rapport à task_dir, ou par rapport à media_directory quand le fichier n'est pas trouvé sous task_dir.
  • Un chemin d'URL tel que /media/img_001.jpg se résout par rapport à media_directory. La page d'annotation charge l'image au même endroit.
  • Un fichier qu'un chemin absolu, ../ ou un lien symbolique place hors du répertoire de la tâche et de media_directory est écarté avec un avertissement.
  • Les images distantes en http(s) ne sont jamais téléchargées. Une exécution écarte chaque item dont l'image est distante ou absente, le journal de l'exécution indique combien, et ces items ne reçoivent aucune prédiction.

Téléchargez les images distantes dans media_directory pour vous entraîner dessus. La page des formats de vision et potato import expliquent comment amener des jeux de données d'images existants dans un projet.

Lames entières et autres grandes images

Les modules de détection et de segmentation redimensionnent chaque image à quelques centaines de pixels, et les objets d'une lame de pathologie de 100 000 pixels ou d'une scène satellite disparaissent à cette taille. Pour un schéma image_annotation, microscopy ou geo_annotation, Potato découpe donc les grandes images en tuiles quand les données d'entraînement de l'exécution sont construites. Le découpage est automatique pour les formats de lame (.svs, .ndpi, .mrxs, .scn et d'autres) et pour les images dont le grand côté fait 4 096 pixels ou plus. Les lames demandent openslide :

bash
pip install "potato-annotation[wsi]"

L'entraînement utilise les tuiles qui contiennent un objet annoté plus un échantillon de tuiles vides, et chaque objet est rogné à sa tuile. La prédiction couvre chaque tuile sur du tissu, jusqu'à max_predict_tiles par image. La partition de chaque image est décidée avant le découpage, donc les tuiles d'une même lame n'atterrissent jamais dans deux partitions. Les prédictions des tuiles sont refusionnées sur l'image entière, et un objet que deux tuiles qui se chevauchent ont trouvé est conservé une seule fois. Les pré-étiquettes utilisent les coordonnées de l'image entière, les mêmes que stocke le visionneur à zoom profond. Les scores sur items réservés sont calculés sur des images entières. Un backend distant télécharge les tuiles plutôt que la lame.

Les réglages se trouvent sous model_training.tiling. Ce fragment entraîne une lame en 40x à 20x sur des tuiles de 1 024 pixels :

yaml
model_training:
  enabled: true
  tiling:
    tile_size: 1024
    overlap: 128
    downsample: 2

Gardez overlap au moins aussi grand que les objets, car un objet plus grand est trouvé en morceaux, un par tuile. Pour une lame qui enregistre sa résolution, mpp fixe les microns par pixel de tuile et l'emporte sur downsample. Deux réglages demandent de l'attention sur certaines lames. Les tuiles d'entraînement vides supposent que chaque objet d'une image annotée a été dessiné, donc définissez background: 0 quand les annotateurs n'ont dessiné que certaines régions d'une lame. Le tissu est détecté par le seuil d'Otsu sur la vignette de la lame, donc une lame sans verre nu perd sa moitié la plus pâle, et tissue_threshold: 0 prédit sur chaque tuile. Le tableau tiling liste chaque clé et sa valeur par défaut.

Microscopie et cartes

Les ROI d'un schéma microscopy entraînent torchvision-detect, ultralytics-detect, torchvision-segment, ultralytics-segment et cellpose. Chaque coupe z et chaque instant avec des ROI est rendu avec les canaux et le contraste par défaut du schéma et devient une image d'entraînement distincte. Le moteur de rendu est le compositeur qu'utilise le visionneur. Une image où rien n'a encore été dessiné est prédite à la coupe z médiane et au premier instant, là où s'ouvre le visionneur. Les prédictions reviennent sous forme de ROI de microscopie avec le z et le t de chaque ROI. Les classifications de cellules renvoient à une image d'étiquettes plutôt qu'à une forme, et les modules d'entraînement écartent les classifications de cellules.

Les entités d'un schéma geo_annotation entraînent les mêmes modules de détection et de segmentation sur le fond de carte raster de l'item. Un GeoTIFF est placé par la transformation et le code EPSG des balises du fichier et reprojeté avec pyproj quand il est projeté. Une image simple avec une étendue est placée en longitude et latitude. Les polygones, rectangles, lignes et points deviennent des formes sur le raster, les trous des polygones étant remplis. Les prédictions reviennent sous forme d'entités GeoJSON en EPSG:4326 avec source: model. La carte propose les entités comme suggestions, et les suggestions ne comptent comme une réponse que lorsque l'annotateur en modifie ou en accepte une. Une carte dont le fond est un serveur de tuiles ou un contour GeoJSON n'a aucun raster sur lequel s'entraîner, et l'exécution écarte ces items avec un avertissement.

Cellules avec cellpose

cellpose affine Cellpose sur des contours de cellules ou de noyaux dans un schéma image_annotation ou microscopy. Installez séparément Cellpose 3 ou 4 :

bash
pip install cellpose

Le modèle de base par défaut est cyto3. nuclei et cyto2 fonctionnent aussi avec Cellpose 3, et cpsam avec Cellpose 4. Définissez diameter au diamètre typique d'une cellule en pixels quand l'estimation propre de Cellpose est fausse. Cellpose segmente sans classes, donc chaque cellule prédite reçoit le paramètre label, ou l'étiquette la plus courante du schéma quand label n'est pas défini. Entraînez un modèle par étiquette quand les classes diffèrent d'aspect. Chaque masque prédit revient sous forme de polygone avec la probabilité moyenne de la cellule comme confiance de la pré-étiquette. cellpose n'a besoin que de 5 images annotées dans la partition train, contre 20 pour les détecteurs. Le code de Cellpose est sous BSD-3-Clause, et les poids viennent des auteurs de Cellpose selon leurs conditions.

Spectrogrammes

Les boîtes d'un schéma spectrogram_annotation entraînent torchvision-detect et ultralytics-detect sur chaque enregistrement rendu sous forme d'image de spectrogramme. Le tutoriel sur les modèles audio traite la détection sur spectrogrammes de bout en bout, avec les réglages de rendu et les formats d'enregistrement que lisent les modules d'entraînement.

Mise en page de documents avec layoutlmv3

layoutlmv3 affine LayoutLMv3 pour trouver les régions que les annotateurs dessinent sur des images de pages à partir des mots de la page et de leurs positions. Une région est tout bloc étiqueté, par exemple un titre, un tableau ou un total. Potato n'exécute aucun OCR, donc chaque item porte les mots de la page avec des boîtes en pixels de l'image de la page ou de 0 à 1 :

json
{"id": "page_001", "image": "pages/page_001.png",
 "words": [{"text": "INVOICE", "bbox": [40, 52, 180, 82]},
           {"text": "Total", "bbox": [300, 700, 380, 730]}]}

Un import PAGE XML en mode regions remplit words à partir des éléments Word du fichier. Des mots issus de la couche de texte d'un PDF ou d'un autre outil d'OCR fonctionnent de la même façon. Chaque mot est étiqueté par la région où tombe son centre, les mots prédits sont refusionnés en régions, et chaque région devient une pré-étiquette de boîte autour de ses mots. Les scores sur items réservés sont le mAP des boîtes. Une boîte prédite s'arrête aux mots de la région, donc des régions dessinées bien plus grandes que les mots obtiennent un score plus bas que les boîtes ne le méritent.

Les poids de LayoutLMv3 sont sous licence CC BY-NC-SA 4.0 et ne servent pas à un usage commercial. Comme pour les modules YOLO, la page Training demande une confirmation avant une exécution, une exécution par l'API demande accept_licence: true, et un réentraînement automatique demande auto_retrain.accept_licence: true.

Modèles vision-langage avec vlm-sft

vlm-sft affine un modèle vision-langage sur les réponses des annotateurs à propos d'images, avec un adaptateur LoRA par défaut et Qwen/Qwen2.5-VL-3B-Instruct comme modèle par défaut. Le module apprend de quatre schémas :

SchémaUn exemple d'entraînement parCe que le modèle apprend à produire
text sur des items imageitemLa réponse de l'annotateur à la question du schéma
region_captionrégion légendéeLa légende d'une région dessinée comme une boîte rouge
grounding_evalexpression répondueLa région sous forme de JSON, un point ou {"absent": true}
gui_trajectoryétape jugée correct avec un clicLe clic, sous la forme {"point": [x, y]}

Les coordonnées sont sur une grille de 0 à 1 000 de l'image, donc n'importe quel point de contrôle peut apprendre le format à partir des exemples. Une exécution sur du texte publie la réponse générée comme pré-étiquette de texte. Une exécution de grounding publie une région ou une absence pour chaque expression, et l'ancrage VLM traite le schéma grounding_eval. Une exécution sur trajectoires d'interface suggère un verdict pour chaque étape d'après l'endroit où le modèle cliquerait, et Évaluer des agents d'utilisation d'ordinateur traite les traces d'interface. Une exécution de légendes est évaluée avec le F1 par jeton et le BLEU-4 mais jamais publiée, car les régions légendées sont la réponse d'un annotateur.

Les vrais points de contrôle demandent un GPU. L'équipe Potato a entraîné deux époques de Qwen/Qwen3-VL-2B-Instruct avec LoRA sur 26 images en 46 secondes sur le GPU Metal d'un Mac. {"lora": {"quantize": "4bit"}} dans Parameters entraîne un adaptateur QLoRA sur des poids de base de 4 bits. Vérifiez la licence du modèle que vous choisissez. Qwen2.5-VL-3B porte la licence de recherche Qwen, et le modèle 7B est sous Apache-2.0. Le tutoriel d'affinage de LLM traite de LoRA, de QLoRA et de la publication d'un modèle sur le Hugging Face Hub.

Pour aller plus loin

Références

  • Ren, S., He, K., Girshick, R., and Sun, J. (2017). Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks. IEEE Transactions on Pattern Analysis and Machine Intelligence, 39, 1137–1149. doi:10.1109/TPAMI.2016.2577031
  • He, K., Gkioxari, G., Dollár, P., and Girshick, R. (2017). Mask R-CNN. 2017 IEEE International Conference on Computer Vision (ICCV), 2980–2988. doi:10.1109/ICCV.2017.322
  • Kirillov, A., Mintun, E., Ravi, N., Mao, H., Rolland, C., Gustafson, L., Xiao, T., Whitehead, S., Berg, A. C., Lo, W.-Y., Dollár, P., and Girshick, R. (2023). Segment Anything. 2023 IEEE/CVF International Conference on Computer Vision (ICCV), 3992–4003. doi:10.1109/ICCV51070.2023.00371
  • Stringer, C., Wang, T., Michaelos, M., and Pachitariu, M. (2021). Cellpose: a generalist algorithm for cellular segmentation. Nature Methods, 18, 100–106. doi:10.1038/s41592-020-01018-x
  • Huang, Y., Lv, T., Cui, L., Lu, Y., and Wei, F. (2022). LayoutLMv3: Pre-training for Document AI with Unified Text and Image Masking. Proceedings of the 30th ACM International Conference on Multimedia, 4083–4091. doi:10.1145/3503161.3548112