Faza 04 · lecția 07

Segmentarea semantică — U-Net

Scopul lecției: Segmentarea este clasificare pentru fiecare pixel. U-Net face această sarcină posibilă prin asocierea unui codificator care reduce rezoluția cu un decodor care o mărește și prin legarea dintre ele a conexiunilor de salt.

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

Curs
AI Engineering from Scratch
Fază
Viziune computerizată
Lectură
21 min.
Verificat
Cuprinsul lecției
  1. Obiective de învățare
  2. Problema
  3. Conceptul
  4. Semantică vs. pe instanțe vs. panoptică
  5. Structura U-Net
  6. Supraeșantionare transpusă vs. biliniară
  7. Entropia încrucișată pe o grilă de pixeli
  8. Pierderea Dice și de ce este necesară
  9. Metrici de evaluare
  10. Compromisul rezoluției intrării
  11. Construiți-l
  12. Pasul 1: Blocul codificatorului
  13. Pasul 2: Blocurile de reducere și de extindere
  14. Pasul 3: U-Net
  15. Pasul 4: Pierderile
  16. Pasul 5: Metrica IoU
  17. Pasul 6: Set de date sintetic pentru verificarea end-to-end
  18. Pasul 7: Bucla de antrenare
  19. Utilizați-l
  20. Livrați-l
  21. Exerciții
  22. Termeni-cheie
  23. Lecturi suplimentare

Segmentarea este clasificare pentru fiecare pixel. U-Net face această sarcină posibilă prin asocierea unui codificator care reduce rezoluția cu un decodor care o mărește și prin legarea dintre ele a conexiunilor de salt.

Tip: Construcție Limbaje: Python Cerințe prealabile: Faza 4, lecția 03 (CNN-uri), Faza 4, lecția 04 (Clasificarea imaginilor) Timp: ~75 de minute

Obiective de învățare

  • Deosebiți segmentarea semantică, pe instanțe și panoptică și alegeți sarcina potrivită pentru o problemă dată
  • Construiți de la zero în PyTorch un U-Net cu blocuri de codificare, un bottleneck, un decodor cu convoluții transpuse și conexiuni de salt
  • Implementați entropia încrucișată pe pixeli, pierderea Dice și pierderea combinată, care reprezintă valoarea implicită actuală pentru segmentarea medicală și industrială
  • Citiți metricile IoU și Dice pentru fiecare clasă și diagnosticați dacă un scor slab provine din recall-ul obiectelor mici, acuratețea contururilor sau dezechilibrul claselor

Problema

Clasificarea produce o etichetă pentru fiecare imagine. Detecția produce câteva casete pentru fiecare imagine. Segmentarea produce o etichetă pentru fiecare pixel. Pentru o intrare de dimensiune H x W, ieșirea este un tensor cu forma H x W (semantică) sau H x W x N_instances (pe instanțe). Acestea sunt milioane de predicții pentru fiecare imagine, nu una singură.

Structura segmentării explică de ce ea susține aproape fiecare produs de viziune cu predicție densă: imagistică medicală (măști de tumori), conducere autonomă (drum, bandă, obstacol), imagini satelitare (amprente ale clădirilor, limitele culturilor), analiză de documente (zone de aspect), robotică (regiuni care pot fi apucate). Niciuna dintre aceste sarcini nu poate fi rezolvată punând o casetă în jurul obiectului; au nevoie de silueta exactă.

Problema arhitecturală este simplu de formulat și nu este simplu de rezolvat: rețeaua trebuie să observe simultan contextul global al imaginii (ce tip de scenă este aceasta) și detaliul local al pixelilor (care pixel este exact drum și care este trotuar). Un CNN standard comprimă spațiul pentru a obține context, ceea ce elimină detaliul. U-Net a fost proiectarea care a obținut ambele lucruri.

Conceptul

Semantică vs. pe instanțe vs. panoptică

Диаграмма к уроку «Segmentarea semantică — U-Net»

  • Semantică spune „acest pixel este drum, acel pixel este mașină”. Două mașini alăturate se unesc într-o singură regiune.
  • Pe instanțe spune „acest pixel este mașina nr. 3, acel pixel este mașina nr. 5”. Ignoră elementele de fundal („stuff” = cer, drum, iarbă).
  • Panoptică le unifică pe ambele: fiecare pixel primește o etichetă de clasă, fiecare instanță primește un id unic, iar atât regiunile „stuff”, cât și obiectele („things”) sunt segmentate.

Notă tehnică a traducerii: În segmentarea panoptică, toți pixelii au o clasă semantică, însă numai instanțele de tip „thing” — obiecte individuale numărabile — au id-uri de instanță distincte. Regiunile „stuff”, cum sunt cerul sau drumul, nu au un id de instanță. Convenția este definită în Panoptic Segmentation.

Această lecție tratează segmentarea semantică. Lecția următoare (Mask R-CNN) tratează segmentarea pe instanțe.

Structura U-Net

Диаграмма к уроку «Segmentarea semantică — U-Net»

Codificatorul înjumătățește rezoluția spațială de patru ori și dublează canalele. Decodorul face invers: dublează rezoluția spațială de patru ori și înjumătățește canalele. Conexiunile de salt concatenează caracteristicile corespunzătoare ale codificatorului cu caracteristicile decodorului la fiecare rezoluție. Convoluția finală 1x1 mapează 64 -> num_classes la rezoluția completă.

De ce sunt necesare conexiunile de salt: decodorul a văzut numai hărți mici de caracteristici până când încearcă să producă predicții la nivel de pixel. Fără conexiunile de salt, el nu poate localiza corect marginile, deoarece acea informație a fost comprimată în codificator. Conexiunile de salt îi oferă hărțile de caracteristici de înaltă rezoluție pe care codificatorul le-a calculat pe parcursul reducerii.

Supraeșantionare transpusă vs. biliniară

Decodorul trebuie să extindă dimensiunile spațiale. Există două opțiuni:

  • Convoluție transpusă (nn.ConvTranspose2d) — supraeșantionare care poate fi învățată. Valoarea implicită istorică a U-Net. Poate produce artefacte în tablă de șah dacă stride-ul și dimensiunea kernelului nu se împart uniform.
  • Supraeșantionare biliniară + convoluție 3x3 — supraeșantionare netedă urmată de o convoluție. Mai puține artefacte, mai puțini parametri, în prezent valoarea implicită modernă.

Ambele apar în practică. Pentru primul U-Net, varianta biliniară este mai sigură.

Notă tehnică a traducerii: nn.Upsample biliniar nu are parametri antrenabili, dar convoluția 3x3 care îl urmează are un număr de parametri dependent de canalele de intrare și de ieșire; comparația cu nn.ConvTranspose2d depinde de arhitectura exactă. Niciuna dintre variante nu este o valoare implicită universală. Consultați documentația oficială pentru Upsample și ConvTranspose2d.

Entropia încrucișată pe o grilă de pixeli

Pentru segmentare semantică cu C clase, ieșirea modelului este (N, C, H, W). Ținta este (N, H, W) cu id-uri întregi de clasă. Entropia încrucișată este identică cu cazul clasificării, doar că este aplicată la fiecare poziție spațială:

Pierdere = media peste (n, h, w) a -log( softmax(logits[n, :, h, w])[target[n, h, w]] )

F.cross_entropy din PyTorch gestionează nativ această formă. Nu este necesară nicio rearanjare a formei.

Pierderea Dice și de ce este necesară

Entropia încrucișată tratează fiecare pixel în mod egal. Aceasta este greșită atunci când o clasă domină cadrul (imagistică medicală: 99% fundal, 1% tumoră). Rețeaua poate obține o acuratețe de 99% prezicând fundal peste tot și totuși să fie inutilă.

Pierderea Dice rezolvă această problemă optimizând direct suprapunerea dintre masca prezisă și cea adevărată:

Dice(p, y) = 2 * sum(p * y) / (sum(p) + sum(y) + epsilon)
Dice_loss = 1 - Dice

unde p este harta de probabilități sigmoid/softmax pentru o clasă, iar y este masca binară de adevăr de referință (ground truth). Pierderea este zero numai când suprapunerea este perfectă. Deoarece se bazează pe un raport, dezechilibrul claselor este irelevant.

Notă tehnică a traducerii: Pierderea Dice atenuează efectul dezechilibrului, însă acesta nu devine irelevant: clasele absente, modul de agregare și probabilitățile foarte mici pot schimba semnificativ comportamentul optimizării. Pierderea Dice generalizată propusă de Sudre și colaboratorii a fost concepută explicit pentru dezechilibrul mare dintre etichete: Generalised Dice overlap.

În practică, utilizați pierderea combinată:

L = L_cross_entropy + lambda * L_dice       (lambda ~ 1)

Entropia încrucișată oferă gradienți stabili la începutul antrenării; Dice concentrează finalul antrenării asupra potrivirii efective a formei măștii. Această combinație este valoarea implicită în imagistica medicală și greu de depășit pe orice set de date cu clase dezechilibrate.

Notă tehnică a traducerii: Combinația dintre entropia încrucișată și Dice este frecventă, dar nu este un standard universal și nu există o pierdere care să fie optimă pentru toate seturile de date dezechilibrate. Alegerea și ponderarea pierderii se validează pe sarcina-țintă; analiza configurabilă din nnU-Net este o referință primară utilă.

Metrici de evaluare

  • Acuratețea pe pixeli — procentul pixelilor prezis corect. Ieftină. Neadecvată pentru date dezechilibrate din același motiv ca acuratețea în clasificare.
  • IoU pentru fiecare clasă — intersecția peste reuniune pentru masca fiecărei clase; media între clase = mIoU.
  • Dice (F1 pe pixeli) — similară cu IoU; Dice = 2 * IoU / (1 + IoU). Imagistica medicală preferă Dice, comunitatea de conducere preferă IoU; ele sunt legate monoton.
  • F1 pe contur — măsoară cât de apropiate sunt contururile prezise de contururile de adevăr de referință, penalizând chiar și deplasările mici. Importantă pentru sarcini de mare precizie, cum ar fi inspecția semiconductorilor.

Notă tehnică a traducerii: Un scor F1 pe contur nu este definit fără regula de potrivire a contururilor, inclusiv toleranța de distanță sau de dilatare și rezoluția imaginii. Raportați aceste detalii împreună cu scorul; evaluarea semantică prin F-measure depinde de un prag de potrivire, așa cum arată Csurka, Larlus & Perronnin.

Raportați IoU pentru fiecare clasă, nu numai mIoU. IoU medie ascunde o clasă la 15% atunci când alte nouă sunt la 85%.

Compromisul rezoluției intrării

Codificatorul U-Net înjumătățește rezoluția de patru ori, astfel încât intrarea trebuie să fie divizibilă cu 16. Imaginile medicale sunt adesea 512x512 sau 1024x1024. Decupajele pentru conducere autonomă au 2048x1024. Costul de memorie al U-Net se scalează cu H * W * C_max, iar la 1024x1024 cu 1024 de canale în bottleneck, propagarea înainte consumă deja gigaocteți de VRAM.

Notă tehnică a traducerii: Codul din această lecție nu impune ca dimensiunile de intrare să fie divizibile cu 16: pentru dimensiuni suficient de mari încât să treacă prin cele patru operații de max-pooling, verificarea shape[-2:] și F.interpolate realiniază hărțile spațiale înaintea concatenării. Consultați documentația primară PyTorch pentru MaxPool2d și interpolate.

Două soluții standard:

  1. Împărțiți intrarea în plăci — procesați plăci de 256x256 cu suprapunere și reasamblați-le.
  2. Înlocuiți bottleneck-ul cu convoluții dilatate care păstrează rezoluția spațială mai mare, dar lărgesc câmpul receptiv (familia DeepLab).

Pentru primul model, o intrare de 256x256 cu un U-Net cu bază de 64 de canale se antrenează confortabil pe 8 GB de VRAM.

Notă tehnică a traducerii: Cei 8 GB nu reprezintă o garanție: memoria necesară depinde cel puțin de dimensiunea lotului, precizie, implementarea operatorilor, activările păstrate pentru backward și allocatorul dispozitivului. Măsurați consumul în mediul concret; consultați semantica CUDA din PyTorch.

Construiți-l

Pasul 1: Blocul codificatorului

Două convoluții 3x3 cu normalizare pe lot (batch norm) și ReLU. Prima convoluție schimbă numărul de canale; a doua îl păstrează.

import torch
import torch.nn as nn
import torch.nn.functional as F

class DoubleConv(nn.Module):
    def __init__(self, in_c, out_c):
        super().__init__()
        self.net = nn.Sequential(
            nn.Conv2d(in_c, out_c, kernel_size=3, padding=1, bias=False),
            nn.BatchNorm2d(out_c),
            nn.ReLU(inplace=True),
            nn.Conv2d(out_c, out_c, kernel_size=3, padding=1, bias=False),
            nn.BatchNorm2d(out_c),
            nn.ReLU(inplace=True),
        )

    def forward(self, x):
        return self.net(x)

Acest bloc este reutilizat peste tot. bias=False, deoarece beta din BN gestionează biasul.

Pasul 2: Blocurile de reducere și de extindere

class Down(nn.Module):
    def __init__(self, in_c, out_c):
        super().__init__()
        self.net = nn.Sequential(
            nn.MaxPool2d(2),
            DoubleConv(in_c, out_c),
        )

    def forward(self, x):
        return self.net(x)


class Up(nn.Module):
    def __init__(self, in_c, out_c):
        super().__init__()
        self.up = nn.Upsample(scale_factor=2, mode="bilinear", align_corners=False)
        self.conv = DoubleConv(in_c, out_c)

    def forward(self, x, skip):
        x = self.up(x)
        if x.shape[-2:] != skip.shape[-2:]:
            x = F.interpolate(x, size=skip.shape[-2:], mode="bilinear", align_corners=False)
        x = torch.cat([skip, x], dim=1)
        return self.conv(x)

Verificarea formei numai pe dimensiunile spațiale (shape[-2:]) gestionează intrările ale căror dimensiuni nu sunt divizibile cu 16; un apel sigur la F.interpolate aliniază tensorul înainte de concatenare. Compararea formei complete s-ar declanșa și la diferențele dintre numărul de canale, care ar trebui să fie o eroare evidentă, nu o interpolare tăcută.

Pasul 3: U-Net

class UNet(nn.Module):
    def __init__(self, in_channels=3, num_classes=2, base=64):
        super().__init__()
        self.inc = DoubleConv(in_channels, base)
        self.d1 = Down(base, base * 2)
        self.d2 = Down(base * 2, base * 4)
        self.d3 = Down(base * 4, base * 8)
        self.d4 = Down(base * 8, base * 16)
        self.u1 = Up(base * 16 + base * 8, base * 8)
        self.u2 = Up(base * 8 + base * 4, base * 4)
        self.u3 = Up(base * 4 + base * 2, base * 2)
        self.u4 = Up(base * 2 + base, base)
        self.outc = nn.Conv2d(base, num_classes, kernel_size=1)

    def forward(self, x):
        x1 = self.inc(x)
        x2 = self.d1(x1)
        x3 = self.d2(x2)
        x4 = self.d3(x3)
        x5 = self.d4(x4)
        x = self.u1(x5, x4)
        x = self.u2(x, x3)
        x = self.u3(x, x2)
        x = self.u4(x, x1)
        return self.outc(x)

net = UNet(in_channels=3, num_classes=2, base=32)
x = torch.randn(1, 3, 256, 256)
print(f"output: {net(x).shape}")
print(f"params: {sum(p.numel() for p in net.parameters()):,}")

Forma ieșirii este (1, 2, 256, 256) — aceeași dimensiune spațială ca intrarea, cu num_classes canale. Aproximativ 7,7 M parametri la base=32.

Pasul 4: Pierderile

def dice_loss(logits, targets, num_classes, eps=1e-6):
    probs = F.softmax(logits, dim=1)
    targets_one_hot = F.one_hot(targets, num_classes).permute(0, 3, 1, 2).float()
    dims = (0, 2, 3)
    intersection = (probs * targets_one_hot).sum(dim=dims)
    denom = probs.sum(dim=dims) + targets_one_hot.sum(dim=dims)
    dice = (2 * intersection + eps) / (denom + eps)
    return 1 - dice.mean()


def combined_loss(logits, targets, num_classes, lam=1.0):
    ce = F.cross_entropy(logits, targets)
    dc = dice_loss(logits, targets, num_classes)
    return ce + lam * dc, {"ce": ce.item(), "dice": dc.item()}

Dice se calculează pentru fiecare clasă, apoi se face media (Dice macro). eps previne împărțirea la zero pentru clasele absente din lot.

Pasul 5: Metrica IoU

@torch.no_grad()
def iou_per_class(logits, targets, num_classes):
    preds = logits.argmax(dim=1)
    ious = torch.zeros(num_classes)
    for c in range(num_classes):
        pred_c = (preds == c)
        true_c = (targets == c)
        inter = (pred_c & true_c).sum().float()
        union = (pred_c | true_c).sum().float()
        ious[c] = (inter / union) if union > 0 else torch.tensor(float("nan"))
    return ious

Returnează un vector de lungime C. nan marchează clasele absente din lot — nu faceți media acestora atunci când calculați mIoU.

Notă tehnică a traducerii: În acest cod, nan apare numai când union == 0, deci clasa lipsește atât din predicție, cât și din țintă. Dacă ținta nu conține clasa, dar predicția o conține, reuniunea este pozitivă și IoU este 0. Pentru mIoU pe întregul set de evaluare, agregați intersecțiile și reuniunile pe set sau precizați explicit procedura macro aleasă; nan_to_num(0) din bucla de antrenare poate coborî artificial media.

Pasul 6: Set de date sintetic pentru verificarea end-to-end

Generați forme pe fundaluri colorate, astfel încât rețeaua să fie obligată să învețe forma, nu culoarea pixelului.

import numpy as np
from torch.utils.data import Dataset, DataLoader

def synthetic_segmentation(num_samples=200, size=64, seed=0):
    rng = np.random.default_rng(seed)
    images = np.zeros((num_samples, size, size, 3), dtype=np.float32)
    masks = np.zeros((num_samples, size, size), dtype=np.int64)
    for i in range(num_samples):
        bg = rng.uniform(0, 1, (3,))
        images[i] = bg
        masks[i] = 0
        num_shapes = rng.integers(1, 4)
        for _ in range(num_shapes):
            cls = int(rng.integers(1, 3))
            color = rng.uniform(0, 1, (3,))
            cx, cy = rng.integers(10, size - 10, size=2)
            r = int(rng.integers(4, 12))
            yy, xx = np.meshgrid(np.arange(size), np.arange(size), indexing="ij")
            if cls == 1:
                mask = (xx - cx) ** 2 + (yy - cy) ** 2 < r ** 2
            else:
                mask = (np.abs(xx - cx) < r) & (np.abs(yy - cy) < r)
            images[i][mask] = color
            masks[i][mask] = cls
        images[i] += rng.normal(0, 0.02, images[i].shape)
        images[i] = np.clip(images[i], 0, 1)
    return images, masks


class SegDataset(Dataset):
    def __init__(self, images, masks):
        self.images = images
        self.masks = masks

    def __len__(self):
        return len(self.images)

    def __getitem__(self, i):
        img = torch.from_numpy(self.images[i]).permute(2, 0, 1).float()
        mask = torch.from_numpy(self.masks[i]).long()
        return img, mask

Trei clase: fundal (0), cercuri (1), pătrate (2). Rețeaua trebuie să învețe să distingă forma.

Pasul 7: Bucla de antrenare

def train_one_epoch(model, loader, optimizer, device, num_classes):
    model.train()
    loss_sum, total = 0.0, 0
    iou_sum = torch.zeros(num_classes)
    for x, y in loader:
        x, y = x.to(device), y.to(device)
        logits = model(x)
        loss, _ = combined_loss(logits, y, num_classes)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        loss_sum += loss.item() * x.size(0)
        total += x.size(0)
        iou_sum += iou_per_class(logits, y, num_classes).nan_to_num(0)
    return loss_sum / total, iou_sum / len(loader)

Rulați aceasta timp de 10–30 de epoci pe setul de date sintetic și urmăriți cum mIoU crește peste 0,9 pentru clasele de forme. Observați că nan_to_num(0) tratează clasele absente dintr-un lot ca zero; pentru IoU exact pentru fiecare clasă, mascați după prezență și utilizați torch.nanmean între loturi la evaluare, în loc să faceți media de aici.

Notă tehnică a traducerii: Pragul mIoU de 0,9 după 10–30 de epoci este un rezultat posibil al exemplului, nu un rezultat garantat. El depinde de seed, versiuni, dispozitiv, hiperparametri și procedura de agregare a metricii.

Utilizați-l

Pentru producție, segmentation_models_pytorch („smp”) încapsulează fiecare arhitectură standard de segmentare cu orice backbone torchvision sau timm. Trei linii:

import segmentation_models_pytorch as smp

model = smp.Unet(
    encoder_name="resnet34",
    encoder_weights="imagenet",
    in_channels=3,
    classes=3,
)

Notă tehnică a traducerii: Formulările „fiecare arhitectură standard” și „orice backbone” nu sunt literale: segmentation_models_pytorch oferă un catalog finit, dependent de versiune și de dependențele instalate. Verificați perechea arhitectură–encoder în registrul oficial SMP.

De asemenea, merită cunoscute pentru lucrul real:

  • DeepLabV3+ înlocuiește reducerea rezoluției bazată pe max-pool cu convoluții dilatate, astfel încât bottleneck-ul păstrează rezoluția; rafinează contururile pentru date satelitare și de conducere.
  • SegFormer schimbă codificatorul convoluțional cu un Transformer ierarhic; SOTA actuală pe multe repere.
  • Mask2Former / OneFormer unifică segmentarea semantică, pe instanțe și panoptică într-o singură arhitectură.

Notă tehnică a traducerii: DeepLabV3+ nu impune înlocuirea generală a max-poolingului: el combină convoluțiile atrous și modulul ASPP pentru context multiscală cu un decodor pentru rafinarea contururilor; backbone-ul și output stride-ul concret rămân alegeri de implementare. Consultați lucrarea primară DeepLabV3+.

Notă tehnică a traducerii: Afirmația despre „SOTA actuală” este dependentă de reper și de moment. Lucrarea SegFormer raportează rezultate puternice la publicare, dar nu stabilește un statut SOTA permanent.

Toate trei sunt înlocuitori direcți în smp sau transformers cu același încărcător de date.

Notă tehnică a traducerii: Familiile de modele menționate nu sunt înlocuitori direcți: cer preprocesare, formate de etichete și interfețe de ieșire specifice. segmentation_models_pytorch și Transformers documentează API-uri diferite pentru segmentare; consultați documentația segmentation_models_pytorch, Mask2Former și OneFormer.

Livrați-l

Această lecție produce:

  • outputs/prompt-segmentation-task-picker.md — un prompt care alege între segmentare semantică, pe instanțe și panoptică și numește arhitectura pentru o sarcină dată.
  • outputs/skill-segmentation-mask-inspector.md — o abilitate care raportează distribuția claselor, statisticile măștilor prezise și clasele sub-prezise sau cu contururi estompate.

Exerciții

  1. (Ușor) Implementați bce_dice_loss pentru o sarcină de segmentare binară (prim-plan vs. fundal). Verificați pe un set de date sintetic cu două clase că pierderea combinată converge mai rapid decât BCE singură atunci când prim-planul reprezintă 5% dintre pixeli.
  2. (Mediu) Înlocuiți blocul de extindere nn.Upsample + conv cu un bloc nn.ConvTranspose2d. Antrenați-le pe ambele pe setul de date sintetic și comparați mIoU. Observați unde apar artefactele în tablă de șah în versiunea cu convoluție transpusă.
  3. (Dificil) Luați un set real de date pentru segmentare (Oxford-IIIT Pets, un subset Cityscapes sau un subset medical) și antrenați U-Net până la cel mult 2 puncte IoU față de referința smp.Unet. Raportați IoU pentru fiecare clasă și identificați clasele care beneficiază cel mai mult de adăugarea Dice la pierdere.

Notă tehnică a traducerii: Rezultatele sugerate în exerciții sunt ipoteze de verificat, nu promisiuni. Nicio pierdere combinată nu converge invariabil mai repede, iar o convoluție transpusă nu produce obligatoriu artefacte în tablă de șah; acestea depind de date, kernel, stride, inițializare și antrenare. Cauza suprapunerii neuniforme este analizată în Odena, Dumoulin & Olah.

Termeni-cheie

Termen Ce spun oamenii Ce înseamnă de fapt
Segmentare semantică „Etichetați fiecare pixel” Clasificare pe pixeli în C clase; instanțele aceleiași clase se unesc
Segmentare pe instanțe „Etichetați fiecare obiect” Separă instanțele distincte ale aceleiași clase; numai prim-plan
Segmentare panoptică „Semantică + pe instanțe” Fiecare pixel primește o clasă; fiecare instanță de obiect primește și un id unic
Conexiune de salt „Punte U-Net” Concatenarea caracteristicilor codificatorului în caracteristicile decodorului de rezoluție corespunzătoare; păstrează detaliul de frecvență înaltă
Convoluție transpusă „Deconvoluție” Supraeșantionare care poate fi învățată; poate produce artefacte în tablă de șah
Pierdere Dice „Pierdere de suprapunere” 1 - 2
mIoU „Intersecție peste reuniune medie” IoU medie între clase; metrica standard a comunității pentru segmentare
F1 pe contur „Acuratețea conturului” Scorul F1 calculat numai pe pixelii de contur; contează pentru sarcini cu precizie critică

Lecturi suplimentare

Notă tehnică a traducerii: segmentation_models_pytorch este un catalog util, nu o enumerare a tuturor arhitecturilor și pierderilor standard; disponibilitatea exactă depinde de versiune. Consultați registrul proiectului înainte de a trata această listă drept exhaustivă.

Sursă: Originalul în limba engleză

Navigare: ← Lecția 04.06 — Detectarea obiectelor — YOLO de la zero · Faza 4 — Viziune computerizată · Lecția 04.08 — Segmentarea instanțelor — Mask R-CNN → · Catalog complet