4. Detecció d'objectes
1. Introducció. Descripció breu de YOLO
https://docs.ultralytics.com/es
YOLO (You Only Look Once) és una família de models de deep learning enfocats en la detecció d'objectes en imatges o vídeos. Es caracteritza per la seva velocitat i precisió en temps real, ja que el model processa tota la imatge d'una sola vegada per predir les regions on es troben els objectes i la seva classe.
Com s'entrena un model YOLO:
- Recopilació de dades: Es recullen imatges etiquetades amb les coordenades dels objectes i les seves categories.
- Preparació de dades: Es estructuren les etiquetes en un format compatible (per exemple, COCO o YOLO).
- Configuració de l'entrenament: Es tria l'arquitectura YOLO (p. ex. YOLOv5, YOLOv7, YOLOv8, etc.), la mida del lot (batch size) i els hiperparàmetres (èpoques, taxa d'aprenentatge, etc.).
- Procés d'entrenament: Amb cada batch d'imatges, la xarxa ajusta els pesos per minimitzar la diferència entre les prediccions i les etiquetes reals.
- Validació i ajust: S'avalua el rendiment en un conjunt de validació per ajustar hiperparàmetres i evitar sobreajust.*
2. Dataset
La estructura del dataset se divide en dos carpetas y archivos de configuración
| Bash | |
|---|---|
on:
- Per cada
fotoX.jpgaimages/train, hi ha un corresponentfotoX.txtalabels/trainque descriu totes les caixes d'objectes d'aquesta imatge (una línia per objecte). - El mateix per a la carpeta de validació
val.
Pots trobar un exemple aquí https://universe.roboflow.com/vc/matriculas-espanolas/dataset/1
2.1. Format txt
El format TXT que utilitza YOLO (tant v5, v7, v8, etc.) per a les etiquetes de detecció d'objectes segueix una estructura molt concreta. Cada imatge té associat un fitxer .txt amb el mateix nom (excepte l'extensió). Dins del fitxer d'etiquetes, cada línia descriu un bounding box (caixa delimitadora) d'un objecte detectat/anotat a la imatge. La línia es compon de:
| Bash | |
|---|---|
tots els valors estan normalitzats en el rang 0-1 respecte a les dimensions de la imatge:
- class_id: Identificador de la classe (objecte) en format enter (0, 1, 2...).
- Si només tens una classe (p. ex.
license_plate), serà sempre 0. Si, per exemple, tens matrícules i faro-izq i faro-der, matrícula seria el 0, faro_izq seria el 1 i faro_der seria el 2. - x_center: Coordenada X del centre de la caixa, normalitzada (dividida entre l'amplada de la imatge).
- y_center: Coordenada Y del centre de la caixa, normalitzada (dividida entre l'altura de la imatge).
- width: Amplada de la caixa, també normalitzada (dividida entre l'amplada de la imatge).
- height: Altura de la caixa, normalitzada (dividida entre l'altura de la imatge).
Exemple d'una BB
Imagina que la teua imatge té una amplada de 1280 px i una altura de 720 px, i la caixa delimitadora que t'interessa va de (x1=600, y1=200) a (x2=750, y2=300).
Valors reals:
- Amplada de la caixa → x2 - x1 = 150 px
- Altura de la caixa → y2 - y1 = 100 px
- Centre X → (x1 + x2)/2 = (600 + 750)/2 = 675 px
- Centre Y v (y1 + y2)/2 = (200 + 300)/2 = 250 px
Valors normalitzats: - Amplada normalitzada → 150 / 1280 ≈ 0.1172 - Altura normalitzada → 100 / 720 ≈ 0.1389 - Centre X normalitzat → 675 / 1280 ≈ 0.5273 - Centre Y normalitzat → 250 / 720 ≈ 0.3472
Si class_id=0, la línia al teu fitxer .txt seria:
| Text Only | |
|---|---|
En definitiva, quan YOLO entrena (o infereix), buscarà aquests fitxers .txt per saber on es troben els objectes (en el teu cas, les matrícules) i amb quina classe associar-los. Això és fonamental perquè el model aprengui de manera supervisada.
Després, en inferència o predicció, el model generarà les seves pròpies coordenades de sortida, també normalment en un sistema similar, però te les proporcionarà en escala absoluta o normalitzada segons la llibreria que estiguis utilitzant.
2.2. data.yaml
En el cas de YOLO (especialment en variants com YOLOv5 o YOLOv8), l'arxiu .yaml que es troba a la carpeta principal (o a l'arrel del dataset) serveix per descriure la configuració del conjunt de dades.
En general, aquest arxiu .yaml conté informació com:
- Rutes de les dades:
- La ruta o path on es troben les imatges d'entrenament (train).
- La ruta on es troben les imatges de validació (val).
- (Opcionalment) la ruta a les imatges de prova (test).
- Quantitat i nom de les classes:
- Un llistat amb els noms de cada classe (per exemple, ['gos', 'gat', 'persona']).
- El nombre total de classes al dataset.
- Paràmetres addicionals (opcional):
- Rutes d'anotacions, si es gestionen en diferents carpetes.
- Configuracions específiques per a l'entrenament (encara que aquest tipus d'informació a vegades es troba en un altre arxiu diferent).
- Identificadors o camps extres que permetin integrar el dataset en un flux de treball més complex.
Un exemple senzill d'un arxiu data.yaml (per a YOLOv5, per exemple) es veuria així:
| YAML | |
|---|---|
Atenció
En algunes versions ens podrà apareixer un error de la ruta del dataset. Això és degut a que te una referència al "datasets_dir": "",. Haurem de comprovar-ho cas de mostrar el missatge que no troba el dataset. Podem veure-ho amb el comandament yolo settings
2.3. Augmentació del Dataset
Com sabem, una de les parts més complicades és la generació del dataset. Podem incrementar la quantitat d'imatges de dues maneres:
2.3.1. Augmentació en línea (on-the-fly)
Aquest tipus d'augmentació es fa durant l'entrenament. La majoria d'implementacions recents de YOLO (p. ex., YOLOv5, YOLOv7, YOLOv8) ja inclouen una sèrie de transformacions aplicades automàticament.
Configuració d'hiperparàmetres
En molts repositoris (com el de YOLOv5), trobes un fitxer d'hiperparàmetres, sovint anomenat hyp.yaml o similar. Dins d'aquest fitxer, pots ajustar diferents paràmetres d'augmentació com:
- hsv_h, hsv_s, hsv_v: Augments de to, saturació i valor en espai de color HSV.
- degrees: Rotació.
- translate: Translació (moviment de la imatge).
- scale: Escalat.
- shear: Efecte de cisallament (shear).
- flipud: Volteig vertical.
- fliplr: Volteig horitzontal.
Per exemple, a YOLOv5 (dins del seu repositori oficial) existeix un fitxer hyp.yaml amb paràmetres predefinits. Pots editar-lo per ajustar la intensitat de cada transformació.
| YAML | |
|---|---|
Al entrenar el teu model (per exemple python train.py --hyp hyp.yaml ...) o mitjançant un script python, YOLO aplicarà automàticament aquestes transformacions en carregar cada lot (batch) d'imatges.
2.3.2. Augmentació prèvia (offline)
La idea aquí és crear còpies augmentades de les imatges (i les seves etiquetes corresponents) abans d'iniciar l'entrenament. Per a això, es poden utilitzar llibreries com Albumentations, imgaug o les transformacions de torchvision.
Flux general amb Albumentations
Instal·lació:
| Bash | |
|---|---|
Configurar un script d'augmentació:
- Definir les transformacions que desitges aplicar (p. ex., rotacions, flips, canvis de brillantor, etc.).
- Carregar cada imatge i la seva anotació, aplicar la transformació i després exportar la imatge augmentada i la seva nova anotació. Després de cada transformació, és probable que les caixes delimitadores (bounding boxes) canviïn, per la qual cosa has de guardar-les amb el nou format (per exemple, en un fitxer .txt amb format YOLO).
- Guardar imatges augmentades: Pots emmagatzemar-les en carpetes com images/train_aug, per exemple, i utilitzar aquesta carpeta ampliada per entrenar.
Aquest mètode crea nous fitxers al disc, augmentant explícitament el nombre d'imatges al teu dataset. No obstant això, tingues en compte que això ocupa més espai i requereix temps addicional per a la generació. A canvi, pot ser beneficiós si vols realitzar un control molt precís de les teves dades o si entrenes amb plataformes que no admeten fàcilment l'augmentació en línia.
Per etiquetar un conjunt d'imatges, podem utilitzar eines com:
2.4. Eina d'etiquetat local del dataset
Investiga i etiqueta un conjunt d'imatges teues amb l'eina https://labelstud.io
3. Configuració del model
Ara ha arribat el moment de entrenar el model. Aquest pas és molt senzill si hem definit el arxiu yaml d'abans, el qual completarem. Anem a veure un exemple al qual descriurem alguna de les parts:
model_type: Aquest paràmetre especifica el tipus de model de YOLO que s'utilitzarà. Els models de YOLO es presenten en diverses variants amb diferents mides i capacitats:yolo_vX_[mida]-opt:vxés la versió: 8, 9, 11, etc.midaés una lletra que defineix la mida del model preentrenat. Com més gran sigui, millor serà el resultat, però també augmentarà el cost d'entrenament per la quantitat d'hiperparàmetres. Valors possibles (la inicial): nano, small, medium, large i xtraLarge.optés per escollir el tipus de detecció que es farà amb el model.
batch_size: És el nombre d'imatges que es processen en cada pas d'entrenament abans d'actualitzar els pesos del model. Un valor de 16 significa que el model processarà 16 imatges alhora. Unbatch_sizemés gran pot accelerar l'entrenament, però també requereix més memòria GPU, mentre que un valor petit farà que el model sigui més estable però més lent.img_size: La mida de la imatge a la qual es redimensionaran totes les imatges d'entrada abans de ser alimentades al model. En aquest cas. Una resolució més gran permet que el model capti més detalls, però també requereix més memòria i pot ser més lent.epochs: És el nombre total de vegades que el model passarà per tot el conjunt de dades durant l'entrenament. Si el model no millora després de diverses èpoques, pots aturar l'entrenament per evitar el sobreajust.learning_rate: La taxa d'aprenentatge és la mida del pas que l'optimitzador fa per ajustar els pesos del model en cada iteració. Un valor de 0.001 significa que l'optimitzador ajustarà els pesos amb un pas petit en cada iteració. Un valor més alt pot fer que el model aprengui més ràpid, però pot ser menys estable. Un valor més baix pot fer que el model aprengui de manera més estable, però més lentament.momentum: És un paràmetre que ajuda a accelerar l'entrenament, especialment en les primeres etapes. Un valor de 0.937 és força comú i millora la convergència de l'optimitzador, ajudant que el model no quedi atrapat en mínims locals.weight_decay: És una tècnica de regularització utilitzada per prevenir el sobreajust, penalitzant els pesos grans durant l'entrenament. Un valor de 0.0005 és força baix i és una regularització moderada. Un valor més alt deweight_decaypot reduir el risc de sobreajust, però també pot evitar que el model aprengui massa dels dades.pretrained_weights: Especifica si s'utilitzarà un model preentrenat. Utilitzar pesos preentrenats accelera el procés d'entrenament i millora la precisió del model, especialment si el conjunt de dades és petit. Els models preentrenats s'entrenen amb grans datasets com COCO, cosa que ajuda que el model tingui una bona base per aprendre a detectar objectes.train: Especifica la ruta al directori que conté les imatges d'entrenament. Les imatges d'entrenament s'utilitzen per entrenar el model a reconèixer objectes.val: Especifica la ruta al directori que conté les imatges de validació. Les imatges de validació s'utilitzen per avaluar el model durant l'entrenament, assegurant-se que no estigui sobreajustant les dades d'entrenament.nc: Aquest paràmetre especifica el nombre de classes en el conjunt de dades. En aquest cas, 7 classes. És important que el nombre de classes coincideixi amb el nombre de classes definides als fitxers d'etiquetes.names: Aquest és un diccionari que mapeja un índex de classe (començant des de 0) al seu nom corresponent. Pot ser una llista numerada com l'exemple o algunes versions permeten un array:names: ["Chewbacca", "Leia", "Luke", "ObiWan", "Solo", "StormTrooper", "Vader"]
3.2. Entrenament del model
Al següent exemple podem veure com queda un programa per entrenar el model
Entrenament del model
| Python | |
|---|---|
Com podem veure:
- Es fa servir el model
yolov8s. La primera execució es descarrega desde ultralycs i es guarda en la carpeta model - Posteriorment comença l'entrenament i va mostrant per pantalla les iteracions i les èpoques
Ademès
Altres arguments interesants son:
save_period=nper a guardar el estat dels hiperparàmetres cadanèpoques iresume=Trueper a reprendre l'entrenament. L'entrenament pot parar-se en força bruta (CTRL+C, CTRL+Z).
També comentar que els models parcials i finals es guarden dins d'una carpeta que es crea anomenada runs i on es creen train_n on n indica el número d'execucions o llançaments que fem del model.
Dins d'aquest run trobarem al final un model anomenat best.pt amb la millor versió dels hiperparàmetres
Per guardar el millor model, per example de l'execució numero 5 (train5):
Aquest model és el que farem servir a continuació per a les prediccions
Tota la informació la pots trobar a https://docs.ultralytics.com/modes/train/
4. Predicció del modelo
Finalment ha arribat el moment de probar el model, a veure si funciona de manera adequada.
Els passos a seguir son:
- Carregar el model entrenat
- Indicar quina imatge volem processar
- Fer la predicció
- Analitzar els resultats
- Mostrar els resultats
Mirem-ho pas a pas:
Com podem veure la carrega del model i la predicció no te complicació. Fixar-se que podem fer la predicció per a una o diverses imatges, i el resultat dependrà d'això. La variable result contindrà un llistat amb variables de tipus Results, una per imatge que fem predicció. Tens la informació completa a la seua web en aquest link
Aquesta variable depenent del model que hem entrenat tindrà uns resultats o altres. En el cas que ens segueix, que és la detecció d'objectes, ens interessen els elements:
names: diccionari amb les classes de objectes que detecta el nostre model. Coincideix amb les classes que hem entrenat.boxes: un objecte que conté els elements detectats, que son de tipusBoxeslen(Results): ens dona quants elements s'han detectat.
Per a cada element de tipus boxes trobarem, per avaluar el resultat:
cls: la id de la classe del objecte detectatconf: la confiança en tant per 1 del objecte detectatxyxy: les coordenades dels extrems de la BB, en valors realsxyxyn: igual que l'anterior però normalitzat segons el tamany de la imatge d'entradaxywh: la coordenada del centre de la caixa, ample i llargxywhn: el mateix, però normalitzat al tamany de la imatge d'entrada
::: note
| Text Only | |
|---|---|
1 | |
Pintem la informació sobre la imatge