Faza 04 · lecția 06

Detectarea obiectelor — YOLO de la zero

Scopul lecției: Detectarea este clasificare plus regresie, executate în fiecare poziție a unei hărți de caracteristici, apoi curățate prin suprimarea non-maximelor.

Versiunea curentă AlexBred.com: primele 100 de lecții ale programului în limba română.

Curs
AI Engineering from Scratch
Fază
Viziune computerizată
Lectură
20 min.
Verificat
Cuprinsul lecției
  1. Obiective de învățare
  2. Problema
  3. Conceptul
  4. Detectarea ca predicție densă
  5. De ce grile și ancore
  6. Decodarea predicțiilor
  7. IoU
  8. Suprimarea non-maximelor
  9. Pierderea
  10. Metrici de detectare
  11. Construiți-l
  12. Pasul 1: IoU
  13. Pasul 2: Suprimarea non-maximelor
  14. Pasul 3: Codarea și decodarea casetelor
  15. Pasul 4: Un cap YOLO minimal
  16. Pasul 5: Atribuirea adevărului de referință
  17. Pasul 6: Cele trei pierderi
  18. Pasul 7: Fluxul de inferență
  19. Folosiți-l
  20. Livrați-l
  21. Exerciții
  22. Termeni-cheie
  23. Lecturi suplimentare

Detectarea este clasificare plus regresie, executate în fiecare poziție a unei hărți de caracteristici, apoi curățate prin suprimarea non-maximelor.

Tip: Construcție Limbaje: Python Cerințe preliminare: Faza 4, Lecția 03 (CNN-uri), Faza 4, Lecția 04 (Clasificarea imaginilor), Faza 4, Lecția 05 (Învățare prin transfer) Timp: ~75 de minute

Obiective de învățare

  • Explicați proiectarea cu grilă și ancore care transformă detectarea într-o problemă de predicție densă și precizați semnificația fiecărui număr din tensorul de ieșire
  • Calculați intersecția-peste-reuniune dintre casete și implementați de la zero suprimarea non-maximelor
  • Construiți un cap minimal în stil YOLO deasupra unui backbone preantrenat, inclusiv pierderile de clasificare, de prezență a obiectului și de regresie a casetelor
  • Citiți un rând de metrici de detectare (precision@0.5, recall, mAP@0.5, mAP@0.5:0.95) și alegeți următorul parametru care trebuie ajustat

Problema

Clasificarea spune „această imagine este un câine”. Detectarea spune „există un câine la pixelii (112, 40, 280, 210), există o pisică la (400, 180, 560, 310) și nimic altceva în cadru”. Acea singură schimbare structurală — prezicerea unui număr variabil de casete etichetate în locul unei etichete per imagine — este baza fiecărui sistem autonom, produs de supraveghere, parser de structură a documentelor și linie de viziune din fabrică.

Detectarea este și locul unde apar simultan toate compromisurile de inginerie din viziune. Sunt necesare casete precise (capul de regresie), clasa potrivită pentru fiecare casetă (clasificare), capacitatea modelului de a ști când nu este nimic de detectat (scorul de prezență a obiectului, objectness) și exact o predicție pentru fiecare obiect real (suprimarea non-maximelor). Dacă lipsește oricare dintre acestea, fluxul fie ratează obiecte, raportează casete halucinate, fie prezice același obiect de cincisprezece ori în poziții puțin diferite.

YOLO (You Only Look Once, Redmon et al. 2016) a fost proiectarea care a făcut ca toate acestea să ruleze în timp real printr-o singură propagare înainte într-o rețea convoluțională, iar aceleași decizii structurale sunt încă fundamentul detectoarelor moderne (YOLOv8, YOLOv9, YOLO-NAS, RT-DETR). Învățați nucleul, iar fiecare variantă devine o rearanjare a acelorași părți.

Conceptul

Detectarea ca predicție densă

Un clasificator produce C numere per imagine. Un detector în stil YOLO produce (S x S x (5 + C)) numere per imagine, unde S este dimensiunea spațială a grilei.

Диаграмма к уроку «Detectarea obiectelor — YOLO de la zero»

Fiecare dintre cele S * S celule ale grilei prezice B casete. Pentru fiecare casetă:

  • 4 numere descriu geometria: tx, ty, tw, th.
  • 1 număr este scorul de prezență a obiectului: „există un obiect centrat în această celulă?”
  • C numere sunt probabilitățile claselor.

Totalul per celulă: B * (5 + C). Pentru VOC cu S=13, B=2, C=20, sunt 50 de numere per celulă.

Notă tehnică a traducerii: Această formă este un cap YOLO simplificat, cu o singură scară și ancore. Detectoarele YOLO moderne pot folosi mai multe scări, capete decuplate și chiar predicții fără ancore; nu există un tensor universal (S, S, B * (5 + C)) pentru întreaga familie.

De ce grile și ancore

Regresia simplă ar prezice (x, y, w, h) pentru fiecare obiect ca coordonate absolute. Aceasta este dificilă pentru o rețea convoluțională, deoarece translația imaginii nu ar trebui să transleze toate predicțiile cu aceeași valoare — fiecare obiect este ancorat spațial. Grila rezolvă aceasta atribuind fiecare casetă a adevărului de referință celulei de grilă în care îi cade centrul; numai acea celulă răspunde de obiect.

Ancorele rezolvă o a doua problemă. O convoluție 3x3 nu poate regresa ușor o casetă de 500 de pixeli lățime pornind de la o celulă de caracteristici cu câmp receptiv de 16 pixeli. În schimb, predefinim B forme de casete anterioare (ancore) per celulă și prezicem diferențe mici față de fiecare ancoră. Modelul învață să aleagă ancora potrivită și să o ajusteze, în loc să regreseze de la nimic.

Notă tehnică a traducerii: Dimensiunea nucleului 3x3 al capului nu determină singură câmpul receptiv efectiv: acesta este construit de întregul backbone și de calea de caracteristici. Ancorele sunt forme anterioare utile pentru parametrizare și atribuire, nu o limită impusă direct de câmpul receptiv al acelui nucleu.

Forme anterioare de casete-ancoră (exemplu pentru intrare 416x416):

  mică:   (30,  60)
  medie:  (75,  170)
  mare:   (200, 380)

În fiecare celulă a grilei, fiecare ancoră emite (tx, ty, tw, th, obj, c_1, ..., c_C).

Detectoarele moderne folosesc adesea FPN cu seturi de ancore diferite pentru fiecare rezoluție — ancore mici pe hărți superficiale de înaltă rezoluție, ancore mari pe hărți profunde de rezoluție mică. Aceeași idee, mai multe scări.

Decodarea predicțiilor

Valorile brute tx, ty, tw, th nu sunt coordonate de casetă; sunt ținte de regresie care trebuie transformate înainte de trasare:

centrul x = (sigmoid(tx) + cell_x) * stride
centrul y = (sigmoid(ty) + cell_y) * stride
lățimea   = anchor_w * exp(tw)
înălțimea = anchor_h * exp(th)

sigmoid menține deplasările centrului în interiorul celulei. exp permite lățimii să se scaleze liber față de ancoră, fără inversarea semnului. stride scalează coordonatele grilei înapoi în pixeli. Această decodare este aceeași în fiecare versiune YOLO de la v2.

Notă tehnică a traducerii: Formula cu anchor_w și anchor_h este specifică detectoarelor YOLO bazate pe ancore, precum YOLOv2/v3; ea nu este comună tuturor versiunilor ulterioare. De exemplu, documentația Ultralytics descrie YOLOv8 ca având un cap fără ancore.

IoU

Metrica universală de similaritate a detectării între două casete:

IoU(A, B) = aria(A intersect B) / aria(A reuniune B)

IoU = 1 înseamnă că sunt identice; IoU = 0 înseamnă că nu se suprapun. IoU dintre predicție și caseta adevărului de referință decide dacă o predicție este considerată pozitiv adevărat (de regulă IoU >= 0.5). IoU dintre două predicții este ceea ce folosește NMS pentru a elimina duplicările.

Suprimarea non-maximelor

O rețea convoluțională antrenată pe ancore adiacente va prezice adesea casete suprapuse pentru același obiect. NMS păstrează predicția cu cea mai mare încredere și șterge orice altă predicție cu IoU peste un prag.

NMS(casete, scoruri, prag_iou):
    sortează casetele după scor descrescător
    păstrează = []
    cât timp casetele nu sunt goale:
        alege caseta cu scorul cel mai mare, adaug-o în păstrează
        elimină fiecare casetă cu IoU > prag_iou față de caseta aleasă
    returnează păstrează

Pragul tipic este 0.45 pentru detectarea obiectelor. Detectoarele recente înlocuiesc NMS standard cu soft-NMS, DIoU-NMS sau învață suprimarea direct (RT-DETR), însă scopul structural este același.

Pierderea

Pierderea YOLO este suma a trei pierderi cu ponderi:

L = lambda_coord * L_box(pred, țintă, unde obj=1)
  + lambda_obj   * L_obj(pred, 1,     unde obj=1)
  + lambda_noobj * L_obj(pred, 0,     unde obj=0)
  + lambda_cls   * L_cls(pred, țintă, unde obj=1)

Numai celulele care conțin un obiect contribuie la pierderile de regresie a casetelor și de clasificare. Celulele fără obiecte contribuie numai la pierderea de prezență a obiectului (învățând modelul să rămână tăcut). lambda_noobj este de obicei mică (~0.5), deoarece marea majoritate a celulelor sunt goale și ar domina altfel pierderea totală.

Variantele moderne schimbă pierderea MSE a casetei cu CIoU / DIoU (care optimizează IoU direct), folosesc focal loss pentru dezechilibrul claselor și echilibrează prezența obiectului cu quality focal loss. Structura cu trei componente rămâne neschimbată.

Notă tehnică a traducerii: Nu există o pierdere YOLO modernă universală cu această structură sau cu aceste ponderi. De exemplu, detectoarele bazate pe potrivire dinamică pot folosi atribuiri și termeni de clasificare/regresie diferiți, iar detectoarele end-to-end precum RT-DETR nu au aceeași etapă NMS de inferență.

Metrici de detectare

Acuratețea nu se transferă la detectare. Iată patru numere care se transferă:

  • Precision@IoU=0.5 — dintre predicțiile considerate pozitive, câte sunt de fapt corecte.
  • Recall@IoU=0.5 — dintre obiectele reale, câte au fost găsite.
  • AP@0.5 — aria curbei precizie–recall la pragul IoU 0.5; un număr per clasă.
  • mAP@0.5:0.95 — media AP peste pragurile IoU 0.5, 0.55, …, 0.95. Metrica COCO; cea mai strictă și mai informativă.

Raportați-le pe toate patru. Un detector puternic la mAP@0.5, dar slab la mAP@0.5:0.95 localizează aproximativ, nu strâns; corectați-l cu o pierdere mai bună pentru regresia casetelor. Un detector cu precizie mare și recall scăzut este prea conservator; reduceți pragul de încredere sau creșteți ponderea prezenței obiectului.

Notă tehnică a traducerii: Precizia și recall-ul nu sunt numere unice fără a preciza pragul de scor și regula de potrivire a detecțiilor. AP ordonează predicțiile după scor și agregă curba rezultată; protocolul COCO evaluează zece praguri IoU de la 0,50 la 0,95, cu pas 0,05, folosind niveluri de recall discrete.

Construiți-l

Pasul 1: IoU

Calul de povară al întregii lecții. Funcționează pe două tablouri de casete în formatul (x1, y1, x2, y2).

import numpy as np

def box_iou(boxes_a, boxes_b):
    ax1, ay1, ax2, ay2 = boxes_a[:, 0], boxes_a[:, 1], boxes_a[:, 2], boxes_a[:, 3]
    bx1, by1, bx2, by2 = boxes_b[:, 0], boxes_b[:, 1], boxes_b[:, 2], boxes_b[:, 3]

    inter_x1 = np.maximum(ax1[:, None], bx1[None, :])
    inter_y1 = np.maximum(ay1[:, None], by1[None, :])
    inter_x2 = np.minimum(ax2[:, None], bx2[None, :])
    inter_y2 = np.minimum(ay2[:, None], by2[None, :])

    inter_w = np.clip(inter_x2 - inter_x1, 0, None)
    inter_h = np.clip(inter_y2 - inter_y1, 0, None)
    inter = inter_w * inter_h

    area_a = (ax2 - ax1) * (ay2 - ay1)
    area_b = (bx2 - bx1) * (by2 - by1)
    union = area_a[:, None] + area_b[None, :] - inter
    return inter / np.clip(union, 1e-8, None)

Returnează o matrice (N_a, N_b) de IoU-uri perechi. Folosiți-o față de o singură casetă a adevărului de referință făcând unul dintre tablouri de forma (1, 4).

Pasul 2: Suprimarea non-maximelor

def nms(boxes, scores, iou_threshold=0.45):
    order = np.argsort(-scores)
    keep = []
    while len(order) > 0:
        i = order[0]
        keep.append(i)
        if len(order) == 1:
            break
        rest = order[1:]
        ious = box_iou(boxesi, boxes[rest])[0]
        order = rest[ious <= iou_threshold]
    return np.array(keep, dtype=np.int64)

Este deterministă, are O(N log N) din sortare și reproduce comportamentul torchvision.ops.nms pentru intrări identice.

Notă tehnică a traducerii: Sortarea costă O(N log N), însă această implementare NMS poate calcula IoU față de aproape toate casetele rămase la fiecare iterație; în cel mai nefavorabil caz, costul total al comparațiilor este O(N²). De asemenea, torchvision.ops.nms nu garantează aceeași selecție pe CPU și GPU când scorurile sunt egale.

Pasul 3: Codarea și decodarea casetelor

Convertiți între coordonate în pixeli și țintele (tx, ty, tw, th) pe care le regresează efectiv rețeaua.

def encode(box_xyxy, cell_x, cell_y, stride, anchor_wh):
    x1, y1, x2, y2 = box_xyxy
    cx = 0.5 * (x1 + x2)
    cy = 0.5 * (y1 + y2)
    w = x2 - x1
    h = y2 - y1
    tx = cx / stride - cell_x
    ty = cy / stride - cell_y
    tw = np.log(w / anchor_wh[0] + 1e-8)
    th = np.log(h / anchor_wh[1] + 1e-8)
    return np.array([tx, ty, tw, th])


def decode(tx_ty_tw_th, cell_x, cell_y, stride, anchor_wh):
    tx, ty, tw, th = tx_ty_tw_th
    cx = (sigmoid(tx) + cell_x) * stride
    cy = (sigmoid(ty) + cell_y) * stride
    w = anchor_wh[0] * np.exp(tw)
    h = anchor_wh[1] * np.exp(th)
    return np.array([cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2])


def sigmoid(x):
    return 1.0 / (1.0 + np.exp(-x))

Test: codați o casetă, apoi decodați-o — ar trebui să obțineți ceva foarte apropiat de original (până la faptul că inversa sigmoid nu este perfect inversabilă când tx nu se află în intervalul post-sigmoid).

Notă tehnică a traducerii: În codul de mai sus, encode salvează deplasarea liniară a centrului, iar decode îi aplică sigmoid; prin urmare, ele nu sunt inverse, nici măcar în general „aproape” inverse. Pentru o pereche inversabilă cu această decodare, ținta tx/ty trebuie să fie logit-ul deplasării fracționare din celulă, cu deplasarea strict între 0 și 1.

Pasul 4: Un cap YOLO minimal

O singură convoluție 1x1 pe o hartă de caracteristici, remodelată la (B, S, S, num_anchors, 5 + C).

import torch
import torch.nn as nn

class YOLOHead(nn.Module):
    def __init__(self, in_c, num_anchors, num_classes):
        super().__init__()
        self.num_anchors = num_anchors
        self.num_classes = num_classes
        self.conv = nn.Conv2d(in_c, num_anchors * (5 + num_classes), kernel_size=1)

    def forward(self, x):
        n, _, h, w = x.shape
        y = self.conv(x)
        y = y.view(n, self.num_anchors, 5 + self.num_classes, h, w)
        y = y.permute(0, 3, 4, 1, 2).contiguous()
        return y

Forma ieșirii: (N, H, W, num_anchors, 5 + C). Ultima dimensiune conține [tx, ty, tw, th, obj, cls_0, ..., cls_{C-1}].

Pasul 5: Atribuirea adevărului de referință

Pentru fiecare casetă a adevărului de referință, decideți ce (cell, anchor) răspunde de ea.

def assign_targets(boxes_xyxy, classes, anchors, stride, grid_size, num_classes):
    num_anchors = len(anchors)
    target = np.zeros((grid_size, grid_size, num_anchors, 5 + num_classes), dtype=np.float32)
    has_obj = np.zeros((grid_size, grid_size, num_anchors), dtype=bool)

    for box, cls in zip(boxes_xyxy, classes):
        x1, y1, x2, y2 = box
        cx, cy = 0.5 * (x1 + x2), 0.5 * (y1 + y2)
        gx, gy = int(cx / stride), int(cy / stride)
        bw, bh = x2 - x1, y2 - y1

        ious = np.array([
            (min(bw, aw) * min(bh, ah)) / (bw * bh + aw * ah - min(bw, aw) * min(bh, ah))
            for aw, ah in anchors
        ])
        best = int(np.argmax(ious))
        aw, ah = anchors[best]

        target[gy, gx, best, 0] = cx / stride - gx
        target[gy, gx, best, 1] = cy / stride - gy
        target[gy, gx, best, 2] = np.log(bw / aw + 1e-8)
        target[gy, gx, best, 3] = np.log(bh / ah + 1e-8)
        target[gy, gx, best, 4] = 1.0
        target[gy, gx, best, 5 + cls] = 1.0
        has_obj[gy, gx, best] = True
    return target, has_obj

Selectarea ancorei este „cea mai bună IoU de formă cu adevărul de referință” — un proxy ieftin care corespunde atribuirii YOLOv2/v3. v5 și versiunile ulterioare folosesc strategii mai sofisticate (potrivire aliniată la sarcină, k dinamic) care rafinează aceeași idee.

Notă tehnică a traducerii: Implementarea didactică nu tratează coliziunile în care două obiecte aleg aceeași pereche (cell, anchor) — a doua țintă o suprascrie pe prima — și nu verifică marginile grilei. În plus, torch.from_numpy creează ținte pe CPU; pentru un pred pe GPU, țintele și masca trebuie mutate explicit pe același dispozitiv.

Pasul 6: Cele trei pierderi

def yolo_loss(pred, target, has_obj, lambda_coord=5.0, lambda_obj=1.0, lambda_noobj=0.5, lambda_cls=1.0):
    has_obj_t = torch.from_numpy(has_obj).bool()
    target_t = torch.from_numpy(target).float()

    # box-regression loss: only on cells with objects
    box_pred = pred[..., :4][has_obj_t]
    box_true = target_t[..., :4][has_obj_t]
    loss_box = torch.nn.functional.mse_loss(box_pred, box_true, reduction="sum")

    # objectness loss
    obj_pred = pred[..., 4]
    obj_true = target_t[..., 4]
    loss_obj_pos = torch.nn.functional.binary_cross_entropy_with_logits(
        obj_pred[has_obj_t], obj_true[has_obj_t], reduction="sum")
    loss_obj_neg = torch.nn.functional.binary_cross_entropy_with_logits(
        obj_pred[~has_obj_t], obj_true[~has_obj_t], reduction="sum")

    # classification loss on cells with objects
    cls_pred = pred[..., 5:][has_obj_t]
    cls_true = target_t[..., 5:][has_obj_t]
    loss_cls = torch.nn.functional.binary_cross_entropy_with_logits(
        cls_pred, cls_true, reduction="sum")

    total = (lambda_coord * loss_box
             + lambda_obj * loss_obj_pos
             + lambda_noobj * loss_obj_neg
             + lambda_cls * loss_cls)
    return total, {"box": loss_box.item(), "obj_pos": loss_obj_pos.item(),
                   "obj_neg": loss_obj_neg.item(), "cls": loss_cls.item()}

Cinci hiperparametri pe care fiecare tutorial YOLO fie îi fixează în cod, fie îi explorează. Raporturile contează: lambda_coord=5, lambda_noobj=0.5 oglindesc lucrarea YOLOv1 originală și încă funcționează ca valori implicite rezonabile.

Pasul 7: Fluxul de inferență

Decodați ieșirea brută a capului, aplicați sigmoid/exp, pragul pentru prezența obiectului și NMS.

def postprocess(pred_tensor, anchors, stride, img_size, conf_threshold=0.25, iou_threshold=0.45):
    pred = pred_tensor.detach().cpu().numpy()
    grid_h, grid_w = pred.shape[1], pred.shape[2]
    num_anchors = len(anchors)

    boxes, scores, classes = [], [], []
    for gy in range(grid_h):
        for gx in range(grid_w):
            for a in range(num_anchors):
                tx, ty, tw, th, obj, *cls = pred[0, gy, gx, a]
                score = sigmoid(obj) * sigmoid(np.array(cls)).max()
                if score < conf_threshold:
                    continue
                cls_idx = int(np.argmax(cls))
                cx = (sigmoid(tx) + gx) * stride
                cy = (sigmoid(ty) + gy) * stride
                w = anchors[a][0] * np.exp(tw)
                h = anchors[a][1] * np.exp(th)
                boxes.append([cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2])
                scores.append(float(score))
                classes.append(cls_idx)

    if not boxes:
        return np.zeros((0, 4)), np.zeros((0,)), np.zeros((0,), dtype=int)
    boxes = np.array(boxes)
    scores = np.array(scores)
    classes = np.array(classes)
    keep = nms(boxes, scores, iou_threshold)
    return boxes[keep], scores[keep], classes[keep]

Aceasta este calea completă de evaluare: cap → decodare → prag → NMS.

Notă tehnică a traducerii: Acest postprocess aplică NMS tuturor claselor împreună, astfel încât o casetă dintr-o clasă poate elimina în mod greșit o casetă suprapusă din altă clasă. Pentru detectare multi-clasă, aplicați NMS separat pe fiecare clasă sau folosiți torchvision.ops.batched_nms, care nu aplică NMS între categorii diferite.

Folosiți-l

torchvision.models.detection furnizează detectoare de producție cu aceeași structură conceptuală. Încărcarea unui model preantrenat necesită trei linii.

import torch
from torchvision.models.detection import fasterrcnn_resnet50_fpn_v2

model = fasterrcnn_resnet50_fpn_v2(weights="DEFAULT")
model.eval()
with torch.no_grad():
    predictions = model([torch.randn(3, 400, 600)])
print(predictions[0].keys())
print(f"boxes:  {predictions[0]['boxes'].shape}")
print(f"scores: {predictions[0]['scores'].shape}")
print(f"labels: {predictions[0]['labels'].shape}")

Notă tehnică a traducerii: fasterrcnn_resnet50_fpn_v2 este un detector în două etape, nu un cap YOLO cu o singură etapă. Apelul cu torch.randn verifică forma API-ului, nu inferența semantică: ponderile preantrenate documentate acceptă imagini cu valori în [0.0, 1.0].

Pentru fluxurile de inferență în timp real, ultralytics (YOLOv8/v9) este standardul: from ultralytics import YOLO; model = YOLO('yolov8n.pt'); model(img). Modelul gestionează intern decodarea și NMS și întoarce același triplet boxes / scores / labels construit mai sus.

Livrați-l

Această lecție produce:

  • outputs/prompt-detection-metric-reader.md — un prompt care transformă un rând precision, recall, AP, mAP@0.5:0.95 într-un diagnostic de o linie și cel mai util experiment următor.
  • outputs/skill-anchor-designer.md — o abilitate care, dat fiind un set de date cu casete ale adevărului de referință, rulează k-means pe (w, h) și întoarce seturi de ancore per nivel FPN, plus statisticile de acoperire necesare pentru a alege numărul potrivit de ancore.

Exerciții

  1. (Ușor) Implementați box_iou și rulați-o față de torchvision.ops.box_iou pe 1.000 de perechi aleatoare de casete. Verificați că diferența absolută maximă este sub 1e-6.
  2. (Mediu) Portați yolo_loss la o versiune care folosește pierderea de casetă CIoU în loc de MSE. Arătați pe un set de date sintetic de 100 de imagini că CIoU converge la un mAP@0.5:0.95 final mai bun decât MSE în același număr de epoci.
  3. (Dificil) Implementați inferența la mai multe scări: transmiteți aceeași imagine la trei rezoluții prin model, reuniți predicțiile de casete și rulați un singur NMS la final. Măsurați creșterea mAP față de inferența la o singură scară pe un set păstrat pentru evaluare.

Notă tehnică a traducerii: Exercițiile 2 și 3 formulează rezultate dorite, nu garanții. CIoU sau inferența la mai multe scări pot îmbunătăți ori degrada mAP, în funcție de date, antrenare, praguri, costul de calcul și protocolul de evaluare; comparația trebuie raportată experimental pe același set păstrat pentru evaluare.

Termeni-cheie

Termen Ce spun oamenii Ce înseamnă de fapt
Ancoră „Formă anterioară de casetă” O formă de casetă predefinită în fiecare celulă a grilei, de la care rețeaua prezice diferențe în loc de coordonate absolute
IoU „Suprapunere” Intersecția-peste-reuniune a două casete; măsura universală de similaritate în detectare
NMS „Eliminarea duplicatelor” Algoritm lacom care păstrează predicțiile cu scor maxim și le elimină pe cele suprapuse peste un prag
Prezența obiectului „Este ceva aici” Scalar per ancoră și per celulă care prezice dacă un obiect este centrat în acea celulă
Stride-ul grilei „Factorul de subeșantionare” Pixeli per celulă de grilă; o intrare de 416 px cu un cap de grilă 13 are stride 32
mAP „Precizia medie medie” Media ariei de sub curba precizie–recall, peste clase și (pentru COCO) praguri IoU
AP@0.5 „AP PASCAL VOC” Precizia medie cu prag IoU 0.5; versiunea permisivă a metricii
mAP@0.5:0.95 „AP COCO” Media peste pragurile IoU 0.5..0.95 cu pas 0.05; versiunea strictă și standardul actual al comunității

Lecturi suplimentare

Sursă: Originalul în limba engleză

Navigare: ← Lecția 04.05 — Învățare prin transfer și ajustare fină · Faza 4 — Viziune computerizată · Lecția 04.07 — Segmentarea semantică — U-Net → · Catalog complet