Sari la conținut
Danube Labs

Antrenare YOLOv8 pe date proprii, cu metrici reale și lecții

Ghid pas cu pas pentru antrenarea YOLOv8 pe date proprii, cu rezultate reale: precizie 0,84, recall 0,50 și mAP@50 de 0,59. Vezi ce înseamnă recall mic și de ce datele variate contează mai mult.

De Alexandru Secureanu7 min de citit
Imagini de validare cu casete și scoruri de încredere desenate de un detector YOLOv8

Pentru antrenare YOLOv8 pe date proprii, etichetezi imaginile în format YOLO, descrii folderele într-un fișier YAML de dataset, pornești de la un model pre-antrenat nano sau small și apelezi model.train(data="data.yaml", epochs=30, imgsz=640). Apoi citești results.png și valorile de precizie, recall și mAP ca să decizi ce repari. În proiectul nostru, cea mai bună rulare a avut precizie 0,84, dar recall de doar 0,50, deci pasul următor a fost să adunăm imagini mai variate.

Cum pregătești un dataset propriu pentru YOLOv8?

Fluxul este scurt: colectezi, etichetezi, împarți, descrii, antrenezi, validezi, repeți. L-am parcurs în 2024 pentru un proiect de cercetare în computer vision care detectează personaje în înregistrări din jocuri video. Imaginile din jocuri sunt un teren bun de test, pentru că cadrele se colectează ieftin, iar scenele se schimbă constant. Am antrenat două modele de detecție pe dataseturi proprii, iar fiecare dataset a trecut prin mai multe versiuni, de la sub 100 de imagini la câteva mii, pe măsură ce analiza erorilor arăta ce îi scăpa modelului. Cea mai bună rulare a folosit 719 imagini de antrenare și 70 de validare.

Ultralytics enumeră aceste reguli pentru dataset în sfaturile lor de antrenare:

  • Folosește imagini care seamănă cu situația reală: ore diferite din zi, lumină, unghiuri și surse diferite.
  • Etichetează fiecare instanță din fiecare clasă, cu casete care încadrează strâns obiectul.
  • Țintește cel puțin 1.500 de imagini și 10.000 de instanțe etichetate pe clasă.
  • Adaugă circa 0–10% imagini de fundal fără obiecte, care ajută la reducerea falselor pozitive.

Ca reper, 719 imagini de antrenare sunt sub această recomandare, iar asta contează mai târziu în articol. Etichetele folosesc un fișier text pe imagine, cu o linie per obiect în forma class x_center y_center width height, toate coordonatele normalizate la 0–1. Pune imaginile și etichetele în foldere paralele, apoi indică-le dintr-un fișier YAML, așa cum arată documentația despre formatul datasetului de detecție:

dataset_root/
  images/train   images/val
  labels/train   labels/val
# data.yaml
path: dataset_root
train: images/train
val: images/val
names:
  0: character

Adaugă câte o linie sub names pentru fiecare clasă în plus.

Ce model YOLOv8 și ce setări de antrenare alegi?

YOLOv8 vine în cinci mărimi: n, s, m, l și x. Cele două mici sunt punctele de plecare obișnuite pentru lucrul în timp real:

ModelPonderi pre-antrenateParametrimAP pe COCO (Ultralytics)
YOLOv8n (nano)yolov8n.pt3,2M37,3
YOLOv8s (small)yolov8s.pt11,2M44,9

Pornește mereu de la ponderi pre-antrenate. Ultralytics o recomandă, iar pe un dataset mic e mai rapid decât antrenarea de la zero. Noi am antrenat atât variante nano, cât și small, iar cea mai bună rulare a folosit modelul small. Iată tot apelul de antrenare:

from ultralytics import YOLO

model = YOLO("yolov8s.pt")                         # pornire pre-antrenată
model.train(data="data.yaml", epochs=30, imgsz=640)

# echivalent în CLI
# yolo detect train data=data.yaml model=yolov8s.pt epochs=30 imgsz=640

Valorile implicite Ultralytics sunt 100 de epoci, 640 de pixeli, batch 16 și oprire timpurie după 100 de epoci fără îmbunătățire. Cea mai bună rulare a noastră a folosit 30 de epoci la 640 px, adică mai puțin decât implicitul, deci tratează cifrele noastre ca pe o singură rulare. Ultralytics notează că rezoluții mai mari, precum 1280, ajută la dataseturi cu obiecte mici. Fiecare rulare scrie în runs/detect/train: weights/best.pt, weights/last.pt, results.png și results.csv. Documentația actuală Ultralytics folosește în aceleași comenzi nume de modele mai noi, precum yolo26n.pt, deci fluxul se aplică și dacă schimbi fișierul de ponderi.

Cum citești results.png și metricile YOLOv8?

results.png desenează pierderile de antrenare și validare, plus precizia, recall-ul și mAP pentru fiecare epocă. Tiparul de prins este pierderea de antrenare care scade în continuare în timp ce pierderea de validare începe să crească, semn de supraînvățare. Pentru cifrele finale folosește metricile de validare. Ultralytics le definește în ghidul de metrici de performanță, iar mai jos le vezi lângă cea mai bună rulare din proiectul nostru (YOLOv8s, 30 de epoci, 640 px, 70 de imagini de validare):

MetricăCe măsoarăCea mai bună rulare
PrecizieCâte detecții au fost corecte0,84
RecallCâte dintre obiectele reale au fost găsite0,50
mAP@50Precizia medie (mean average precision) la un prag IoU de 0,500,59
mAP@50-95Media mAP pe praguri IoU de la 0,50 la 0,950,36

IoU (intersection over union) este suprapunerea dintre caseta prezisă și caseta etichetată. La 0,50 și o casetă aproximativă contează ca reușită. La 0,95 contează doar una aproape perfectă. Rularea validării salvează și o curbă F1, o curbă precizie-recall și o matrice de confuzie, care arată unde confundă modelul clasele sau unde ratează obiecte.

Ce înseamnă recall mic când precizia e mare?

Precizia 0,84 înseamnă că atunci când modelul desenează o casetă, de obicei are dreptate. Recall 0,50 înseamnă că găsește circa jumătate din obiectele etichetate și le ratează pe cealaltă jumătate. Cele două depind de pragul de încredere: dacă îl ridici, dispar detecțiile șubrede, deci precizia crește și recall-ul scade. Compară rulările la același prag. Ca simplă aritmetică, media armonică dintre 0,84 și 0,50 este de circa 0,63. Ultralytics descrie tiparul direct: când recall-ul este cifra slabă, modelul poate rata obiecte reale, iar mai multe date pot ajuta.

Diferența dintre mAP@50 (0,59) și mAP@50-95 (0,36) spune o a doua poveste. Casetele se suprapun suficient de bine peste obiecte la IoU 0,50, dar scorul scade pe măsură ce suprapunerea cerută se strânge, deci localizarea este mai lejeră decât detecția. Încă o precauție la cifrele noastre: 70 de imagini de validare sunt un set mic, așa că vreo câteva imagini grele mută vizibil recall-ul. Tratează 0,50 ca pe o poziție aproximativă.

De ce bat datele mai variate un model mai mare?

Când recall-ul este limita, cauza obișnuită este că modelul n-a văzut niciodată situațiile pe care le ratează: altă distanță, altă lumină, obiect parțial ascuns, alt fundal. Un model mai mare are mai multă capacitate, dar învață din aceleași 719 imagini și le poate memora mai repede. Varietatea adaugă situațiile lipsă. Asta a fost concluzia noastră din această rulare: precizia era bună, recall-ul era limita, iar pasul următor erau date de antrenare mai variate, înaintea oricărui model mai mare. Se potrivește și cu ghidul Ultralytics de mai sus, care cere imagini variate și cel puțin 1.500 pe clasă, mai mult decât dublul celor 719 ale noastre în total.

Bucla pe care am folosit-o și pe care o recomandăm:

  1. Rulează validarea și deschide imaginile de validare unde modelul a ratat obiecte sau a desenat casete greșite.
  2. Grupează ratările după cauză: distanță, lumină, vedere blocată, fundal, poziție neobișnuită.
  3. Colectează și etichetează mai multe imagini pentru grupul cel mai mare.
  4. Reantrenează și compară pe același set de validare, neatins.
  5. Schimbă mărimea modelului abia când datele adăugate nu mai mișcă cifrele.

Ține setul de validare fix și în afara antrenării, altfel orice comparație devine fără sens. Este același obicei ca setul fix de evaluare din lucrul nostru la costurile LLM. Citește asta ca pe o ordine de priorități pentru experimente. Raportăm aici o singură rulare, iar sfatul de a adăuga întâi date este o ipoteză ieftin de testat în proiectul tău.

Cum rulezi YOLOv8 în timp real pe captura de ecran?

Detecția de obiecte în timp real este o buclă: iei un cadru, rulezi modelul, desenezi rezultatul. Ultralytics acceptă cadre numpy (BGR, HWC, uint8) și o sursă screen, iar documentația modului predict listează setările care contează aici. conf este implicit 0,25 și fixează încrederea minimă pentru o detecție. imgsz este implicit 640. vid_stride sare cadre la intrările video ca să accelereze procesarea, cu prețul rezoluției temporale.

Bucla noastră a aplicat manual aceleași două idei: sare cadre și filtrează după încredere. Desena rezultatele într-un overlay transparent. O variantă minimă arată așa, unde frames() produce matrici numpy BGR din codul tău de captură, iar draw_overlay() îl scrii tu:

from ultralytics import YOLO

model = YOLO("best.pt")
SKIP = 3                 # rulează modelul pe fiecare al 3-lea cadru
CONF = 0.4               # valoare de exemplu, reglează-o pe imaginile tale de validare
boxes = []

for i, frame in enumerate(frames()):
    if i % SKIP == 0:
        result = model(frame, conf=CONF, imgsz=640, verbose=False)[0]
        boxes = result.boxes.xyxy.tolist()
    draw_overlay(boxes)  # refolosește ultimele casete pe cadrele sărite

Un CONF mai mare dă mai puține casete false și mai multe ratări, iar un SKIP mai mare dă mai multă viteză și casete mai vechi. O notă despre utilizare: este o conductă de computer vision, iar capturarea ecranului unui software terț poate fi restricționată de termenii acelui software. Analizează înregistrări și aplicații pe care ai voie să le analizezi.

Cum accelerezi inferența YOLOv8 cu TensorRT?

Pe un GPU NVIDIA, exportă ponderile antrenate într-un engine TensorRT și încarcă acel fișier în loc de fișierul .pt. Ghidul Ultralytics pentru TensorRT arată apelul:

from ultralytics import YOLO

YOLO("best.pt").export(format="engine")      # cere un GPU cu suport CUDA
model = YOLO("best.engine")                  # apoi îl folosești ca pe orice alt model

Ultralytics avertizează că engine-urile TensorRT sunt specifice hardware-ului și runtime-ului. Engine-ul este reglat pe GPU-ul pe care a fost construit, deci construiește-l pe GPU-ul pe care vei face deploy și potrivește runtime-ul TensorRT și CUDA. În proiectul nostru am scris un script de conversie pentru acest pas. Măsoară accelerarea pe hardware-ul tău, pentru că depinde de GPU și de mărimea modelului, și rulează validarea pe engine-ul exportat ca să confirmi că metricile rămân la fel ca la fișierul .pt.

Ce face Danube Labs în computer vision?

Proiectul a pornit ca cercetare a fondatorului la Danube Labs: două modele de detecție antrenate de noi, inferență în timp real și un rezultat măsurat, inclusiv cifra slabă. Aceeași disciplină se aplică și în lucrul pentru clienți. Un proiect de AI ar trebui să înceapă cu un studiu de fezabilitate și un set fix de evaluare, ca să știi ce recall poți aștepta înainte să angajezi buget. Dacă ai imagini și o problemă de detecție, programează un apel introductiv gratuit.

Întrebări frecvente

Câte imagini îți trebuie pentru a antrena YOLOv8 pe un dataset propriu?
Ultralytics recomandă cel puțin 1.500 de imagini și 10.000 de instanțe etichetate pe clasă, cu imagini variate ca lumină, unghi, oră din zi și sursă. Poți porni un flux cu mult mai puține, iar cea mai bună rulare a noastră a folosit 719 imagini de antrenare, dar așteaptă-te la recall mai mic până când datele acoperă situațiile din utilizarea reală.
Ce înseamnă precizie, recall și mAP în YOLOv8?
Precizia arată câte detecții au fost corecte. Recall-ul arată câte dintre obiectele reale a găsit modelul. mAP@50 este precizia medie la un prag IoU de 0,50, iar mAP@50-95 o mediază pe praguri de la 0,50 la 0,95, deci răsplătește casetele mai strânse. Precizie mare cu recall mic înseamnă că modelul ratează obiecte reale.
Ce mAP@50 e bun pentru un model YOLOv8 propriu?
Nu există un prag universal. Depinde de obiecte, de calitatea imaginilor și de ce poate tolera aplicația ta, așa că ia ca reper rulări comparate pe același set de validare. În proiectul nostru, cea mai bună rulare a avut mAP@50 de 0,59 și mAP@50-95 de 0,36 pe 70 de imagini de validare, iar recall-ul de 0,50 era limita de reparat.
Să folosesc YOLOv8 nano sau small?
Nano are 3,2M parametri și 37,3 mAP pe COCO, small are 11,2M parametri și 44,9. Nano este punctul de plecare mai ușor, iar small e mai precis pe COCO, cu un cost de calcul mai mare. Alege cel mai mic model care atinge viteza dorită, verifică recall-ul pe imaginile de validare și adaugă date variate înainte să treci la o mărime mai mare.
Cum exporți YOLOv8 în TensorRT?
Încarci ponderile antrenate și apelezi model.export(format="engine") pe o mașină cu GPU NVIDIA cu suport CUDA, apoi încarci fișierul .engine rezultat ca pe orice alt model. Engine-urile TensorRT sunt legate de GPU-ul și runtime-ul pe care au fost construite, deci construiește-le pe GPU-ul de deploy și potrivește versiunile TensorRT și CUDA.
Cum rulezi detecția YOLOv8 în timp real?
Încarci best.pt, iei cadre din sursa ta, rulezi modelul pe fiecare al N-lea cadru și refolosești ultimele detecții între ele. Reglează conf ca să echilibrezi falsele pozitive cu ratările, ține imgsz la 640 dacă obiectele nu sunt mici și exportă în TensorRT dacă ai un GPU NVIDIA. Ultralytics acceptă și cadre numpy și o sursă de tip screen.
Distribuie

Articole similare