27.3 Dice, IoU és aggregálás

27.3.1 Cél, előismeret és induló kérdés

A 27.2. U-Net, encoder–decoder és skip egységben felépítettük az encoder–decoder és a skip-kapcsolatos U-Net-alapú szegmentáló architektúrát. Ott a térbeli alakok és a csatornaszámok összeillesztése volt a fő kérdés. Most azt vizsgáljuk, hogyan mérjük a kimenő, pixelszintű bináris maszk minőségét. Egyetlen skalár pontosság nem elég: egy 24×24-es GlyphLab-képen a háttér gyakran a pixelek 80–90%-át teszi ki, így az „üres maszkot jósolok” stratégia is magas pixel-accuracyt kaphat, miközben a tényleges előtér-alakzatot teljesen elhibázza.

A szükséges előismeret: halmazművelet, a 27.2. U-Net, encoder–decoder és skip alfejezetből a bináris maszk mint 0/1 előtér-térkép fogalma, valamint a 23.3. Páros összehasonlítás és csoportszintű intervallum alfejezetből a csoportos kiértékelés és a jelenet-mintavételi egység. Ez az egység önálló matematikai fogalmat épít fel, ezért először a metrika bináris halmaz-definícióját rögzítjük, utána térünk a numerikus és aggregálási kérdésekre.

Induló becslés: ha egy 6 pixeles célmaszkra a predikció 6 találatot és 30 téves előtér-pixelt tartalmaz, akkor a pixel-accuracy 242−30242≈0,948\frac{24^2-30}{24^2}\approx 0{,}948, tehát kiválónak tűnik. Vajon a Dice vagy az IoU is ezt mondja? A második szakasz definíciói után ezt a példát ellenőrizzük.

27.3.2 Definíció: Dice és IoU bináris maszkon

Legyen Ω\Omega a képpontok véges halmaza, |Ω|=H⋅W|\Omega|=H\cdot W egyetlen bináris maszkra. A target maszk által kijelölt előtér-halmaz legyen A⊆ΩA\subseteq\Omega, a predikált maszké B⊆ΩB\subseteq\Omega. A két halmaz közös része A∩BA\cap B, uniója A∪BA\cup B. Jelölje

a=|A|,b=|B|,i=|A∩B|.a=|A|,\qquad b=|B|,\qquad i=|A\cap B|.

A Jaccard-index, a szegmentálásban elterjedt angol nevén Intersection over Union (IoU):

J(A,B)=|A∩B||A∪B|=ia+b−i,J(A,B)=\frac{|A\cap B|}{|A\cup B|}=\frac{i}{a+b-i},

feltéve, hogy az unió nem üres. A Sørensen–Dice-együttható (röviden Dice):

D(A,B)=2|A∩B||A|+|B|=2ia+b,D(A,B)=\frac{2|A\cap B|}{|A|+|B|}=\frac{2i}{a+b},

feltéve, hogy a+b>0a+b>0. Mindkét metrika [0,1][0,1]-be esik, és az A=BA=B esetben 1-et, a diszjunkt halmazokra 0-t ad. A nevezőben az IoU az uniót használja, a Dice pedig a két halmaz méretének összegét; ez okozza, hogy a Dice mindig legalább akkora, mint az IoU.

A definíció számosságokat használ, ezért a maszkok tárolási formátuma lényegtelen: ugyanazt az eredményt adják a uint8 0/1 tömbök, a bool tömbök és a küszöbölt float32 logitok is, ha a küszöbölés bináris döntést adott.

27.3.3 Tensoralak, jelölés és az üres eset konvenciója

A GlyphLab-ban a maszk alakja (N,1,H,W)(N,1,H,W), uint8, ahol NN a képek száma, a csatorna mérete 1, a többi a térbeli kiterjedés. A kk-adik képre AkA_k a célmaszk, BkB_k a predikciós maszk. A számítás során a (N,1,H,W)(N,1,H,W)-t a (N,1)(N,1)-re redukáljuk a (H,W)(H,W) tengelyek összegzésével; többosztályos esetben minden osztályra külön binarizált Akc,BkcA_k^c, B_k^c párt képzünk.

Az üres unió pontosan akkor fordul elő, ha A=B=⌀A=B=\varnothing. A nevező ekkor nulla, ezért a fenti osztás nem ad értelmes számot. Ebben a könyvben a páronkénti konvenció a következő: ha mindkét maszk üres, akkor J(A,B)=D(A,B)=1J(A,B)=D(A,B)=1, mert a predikció és a cél tökéletesen megegyezik. Ha az egyik üres, a másik nem, akkor az unió nem üres, így i=0i=0 és a+b>0a+b>0, tehát J=D=0J=D=0. A globális aggregálásnál viszont az üres–üres pár egyetlen tagot sem ad a közös számlálóba; ha a teljes adathalmazon az összes unió üres, a globális metrika nem definiált, és ezt hibával jelezzük, nem pedig 1-gyel.

Ez a konvenció értelmezés kérdése, nem tétel. A szakirodalmi implementációk gyakran inkább kihagyják az üres–üres párokat az átlagból; a kettő nem azonos, mert a mi konvenciónk 1-es járulékot ad a képenkénti átlaghoz. A laborban ez láthatóvá válik.

27.3.4 Tétel és levezetés: Dice kapcsolata az IoU-val

A két metrika nem független: ugyanazt a i,a,bi, a, b statisztikát rendezi más skálán.

Tétel (Dice–IoU azonosság). Legyenek A,B⊆ΩA,B\subseteq\Omega véges pixelhalmazok, a=|A|a=|A|, b=|B|b=|B|, i=|A∩B|i=|A\cap B|, és tegyük fel, hogy a+b>0a+b>0. Ekkor az unió is nemüres, az IoU J=i/(a+b−i)J=i/(a+b-i) definiált, és

D(A,B)=2J(A,B)1+J(A,B).D(A,B)=\frac{2J(A,B)}{1+J(A,B)}.

Bizonyítás. Az a+b>0a+b>0 feltételből a+b−i=|A∪B|≥1a+b-i=|A\cup B|\geq 1 is következik, mert ha a két halmaz közül legalább az egyik nem üres, akkor az unió is nem üres. Ezért JJ nevezője nem nulla. Helyettesítsünk be a jobb oldalba:

2J1+J=2ia+b−i1+ia+b−i=2ia+b−ia+b−i+ia+b−i=2ia+b−i⋅a+b−ia+b=2ia+b=D. \frac{2J}{1+J} =\frac{2\,\frac{i}{a+b-i}}{1+\frac{i}{a+b-i}} =\frac{\frac{2i}{a+b-i}}{\frac{a+b-i+i}{a+b-i}} =\frac{2i}{a+b-i}\cdot\frac{a+b-i}{a+b} =\frac{2i}{a+b}=D.

Az utolsó egyszerűsítésben a+b−i>0a+b-i>0, tehát a tört elhagyása megengedett. ▫\square

Az állítás típusa tétel, a bizonyítás elemi algebra. A feltétel fontos: az üres–üres párt a tétel nem fedi le, mert ott a+b=0a+b=0. Az imént bevezetett 1-es konvenció nem következik a tételből, hanem külön definíció. A következő egyenlőtlenség szintén levezethető, és a gyakorlatban magyarázza, miért „szigorúbb” az IoU:

D−J=2J1+J−J=J(1−J)1+J≥0, D-J=\frac{2J}{1+J}-J=\frac{J(1-J)}{1+J}\geq 0,

mert 0≤J≤10\leq J\leq 1. Egyenlőség pontosan J=0J=0 (diszjunkt maszkok) vagy J=1J=1 (tökéletes egyezés) esetén áll; közbülső átfedésnél a Dice szigorúan nagyobb.

27.3.5 Aggregálás: per-image, global pixel, class imbalance

A metrikák egyetlen maszkpárra definiáltak. Egy tesztkészletre több aggregálási út létezik, és ezek különböző kérdésekre válaszolnak.

Képenkénti (per-image) átlag. Minden kk képre kiszámítjuk JkJ_k és DkD_k értékét, majd

J¯img=1N∑k=1NJk,D¯img=1N∑k=1NDk.\overline{J}_{\text{img}}=\frac1N\sum_{k=1}^N J_k,\qquad \overline{D}_{\text{img}}=\frac1N\sum_{k=1}^N D_k.

Ez minden képet azonos súllyal vesz, függetlenül az előtér méretétől. A 23.3. Páros összehasonlítás és csoportszintű intervallum alfejezetben bevezetett jelenet-bootstrap ehhez illeszkedik: először képenként számolunk, majd a két view eredményét jelenetenként átlagoljuk, és a bootstrap a független scene-egységeken húz. Így az intervallum a jelenetek közötti szórást becsli, nem a pixelek közötti függést.

Globális pixel-aggregálás. Az összes képet egyetlen, nagy pixelgyűjteménynek tekintjük. Legyen

TP=∑k|Ak∩Bk|,FP=∑k|Bk\Ak|,FN=∑k|Ak\Bk|.\mathrm{TP}=\sum_k |A_k\cap B_k|,\quad \mathrm{FP}=\sum_k |B_k\setminus A_k|,\quad \mathrm{FN}=\sum_k |A_k\setminus B_k|.

Ekkor

Jglob=TPTP+FP+FN,Dglob=2TP2TP+FP+FN.J_{\text{glob}}=\frac{\mathrm{TP}}{\mathrm{TP}+\mathrm{FP}+\mathrm{FN}},\qquad D_{\text{glob}}=\frac{2\,\mathrm{TP}}{2\,\mathrm{TP}+\mathrm{FP}+\mathrm{FN}}.

A globális verzió minden pixelt azonos súllyal vesz, ezért a nagy előtérrel rendelkező képek dominálják. Az üres–üres párok a globális számlálóba semmit sem tesznek, míg a képenkénti átlagban 1-ként jelennek meg; ez önmagában is eltérést okoz.

Osztályegyensúly (class imbalance). Ha Ω\Omega nagy és az AA előtér kicsi, akkor a pixel-accuracy a domináns háttér miatt megtévesztő. A Dice és az IoU ezt kiküszöböli, mert a nevező az AA és BB összhosszához, illetve uniójához viszonyít. Hátrányuk viszont, hogy ugyanaz az abszolút hiba egy kis objektumon sokkal nagyobb büntetést kap, mint egy nagyon: ha AA 4 pixeles és BB 8 pixeles teljes lefedéssel, akkor D=8/12≈0,667D=8/12\approx0{,}667; ha AA 400 pixeles és BB 404 pixeles teljes lefedéssel, akkor D=800/804≈0,995D=800/804\approx0{,}995. Ez a tulajdonság a relatív átfedést méri, nem az abszolút tévedés költségét.

Határ (boundary). A Dice és az IoU kizárólag halmaz-kardinalitásokat használ, ezért nem bünteti közvetlenül a kontúr alakját. Két azonos IoU-jú hiba teljesen más irányú is lehet: egy 2×2-es célblokkra a tőle jobbra 1 pixellel eltolt 2×2-es predikció és a tőle lefelé 1 pixellel eltolt 2×2-es predikció egyaránt i=2i=2, a+b=8a+b=8, tehát J=2/6=1/3J=2/6=1/3 és D=4/8=0,5D=4/8=0{,}5. Az egyik hibát a közös függőleges határon követjük el, a másikat a vízszintesen. Aki a határvonal pontos lefutását akarja mérni, kiegészítő metrikát használhat (például boundary-IoU vagy felületi távolság), de ez nem része a jelen egység főútjának; a területalapú metrika érvényességi korlátját mindig ki kell mondani.

27.3.6 Kézi példa három maskpár

Legyen a tér 4×4, tehát |Ω|=16|\Omega|=16. Három maszkpárt vizsgálunk.

  1. pár: A1A_1 a bal felső 2×2-es blokk, tehát

A1={(0,0),(0,1),(1,0),(1,1)},a1=4. A_1=\{(0,0),(0,1),(1,0),(1,1)\},\quad a_1=4.

B1B_1 a bal felső 3×3-as blokk, tehát b1=9b_1=9. A metszet i1=4i_1=4, az unió a1+b1−i1=4+9−4=9a_1+b_1-i_1=4+9-4=9. Így

J1=49≈0,4444,D1=813≈0,6154. J_1=\frac49\approx0{,}4444,\qquad D_1=\frac{8}{13}\approx0{,}6154.

  1. pár: A2=⌀A_2=\varnothing, B2={(0,0),(3,3)}B_2=\{(0,0),(3,3)\}, tehát a2=0a_2=0, b2=2b_2=2, i2=0i_2=0. Ekkor J2=D2=0J_2=D_2=0.

  2. pár: A3=B3=⌀A_3=B_3=\varnothing. Az unió üres, a páronkénti konvenció szerint J3=D3=1J_3=D_3=1.

A három pár képenkénti átlaga:

J¯img=4/9+0+13=13/93=1327≈0,4815, \overline{J}_{\text{img}}=\frac{4/9+0+1}{3}=\frac{13/9}{3}=\frac{13}{27}\approx0{,}4815,

D¯img=8/13+0+13=21/133=713≈0,5385. \overline{D}_{\text{img}}=\frac{8/13+0+1}{3}=\frac{21/13}{3}=\frac{7}{13}\approx0{,}5385.

A globális pixel-számításhoz:

TP=4+0+0=4,FP=5+2+0=7,FN=0+0+0=0, \mathrm{TP}=4+0+0=4,\qquad \mathrm{FP}=5+2+0=7,\qquad \mathrm{FN}=0+0+0=0,

Jglob=44+7+0=411≈0,3636,Dglob=88+7=815≈0,5333. J_{\text{glob}}=\frac{4}{4+7+0}=\frac{4}{11}\approx0{,}3636,\qquad D_{\text{glob}}=\frac{8}{8+7}=\frac{8}{15}\approx0{,}5333.

A globális IoU lényegesen kisebb, mint a képenkénti átlag, mert a globális változat nem kap 1-es járulékot az üres–üres pártól, és a 3×3-as téves predikció FP-pixeleit teljes súllyal számolja. A számok mutatják, hogy a két aggregálás nem felcserélhető.

27.3.7 Kód: metrikaszámítás és aggregálás

A kód a saját NumPy-referenciánk stílusát követi. Bináris maszkpárokra számol, a bemenet (N,1,H,W) alakú uint8 vagy bool. A csatornatengely 1 méretű, ezért a térbeli összegzés az utolsó két tengelyen történik.

# dice_iou_lab.py
import numpy as np

def binary_mask_metrics(pred, target, empty_empty_value=1.0):
    """Per-image IoU es Dice binaris (N,1,H,W) maszkparokra.

    Konvencio: ha mindket maszk ures, mindket metrika empty_empty_value.
    Ha az egyik ures, a masik nem, akkor a nevezo pozitiv, a metszet 0.
    """
    p = np.asarray(pred).astype(bool)
    t = np.asarray(target).astype(bool)
    # shape ellenorzes
    assert p.shape == t.shape and p.ndim == 4 and p.shape[1] == 1

    inter = np.logical_and(p, t).sum(axis=(-2, -1)).astype(np.float64)
    sum_a = np.logical_and(t, np.ones_like(t)).sum(axis=(-2, -1)).astype(np.float64)
    sum_b = p.sum(axis=(-2, -1)).astype(np.float64)
    union = np.logical_or(p, t).sum(axis=(-2, -1)).astype(np.float64)

    with np.errstate(divide='ignore', invalid='ignore'):
        iou = np.where(union > 0, inter / union, empty_empty_value)
        dice = np.where(sum_a + sum_b > 0,
                        2.0 * inter / (sum_a + sum_b),
                        empty_empty_value)
    return iou, dice  # mindkettó alakja (N,1)


def global_binary_metrics(pred, target):
    """Globális pixel-IoU/Dice az összes képre együtt."""
    p = np.asarray(pred).astype(bool).reshape(pred.shape[0], -1)
    t = np.asarray(target).astype(bool).reshape(target.shape[0], -1)
    TP = np.logical_and(p, t).sum().astype(np.float64)
    FP = np.logical_and(p, np.logical_not(t)).sum().astype(np.float64)
    FN = np.logical_and(t, np.logical_not(p)).sum().astype(np.float64)
    # Üres unió az összes képre együtt: a metrika nem definialt.
    union = TP + FP + FN
    if union == 0:
        raise ValueError("A globális IoU/Dice nem definialt: ures unió.")
    iou = TP / union
    dice = 2.0 * TP / (2.0 * TP + FP + FN)
    return iou, dice


if __name__ == "__main__":
    # Három 4x4-es példa, NCHW alakban.
    t0 = np.array([[[[1,1,0,0],
                     [1,1,0,0],
                     [0,0,0,0],
                     [0,0,0,0]]]], dtype=np.uint8)
    p0 = np.ones((1,1,3,3), dtype=np.uint8)  # bal felső 3x3, padding nélkül 3x3
    # A 3x3 blokkot 4x4-re kell helyezni, a jobb alsó részt nullázva nem kell,
    # de az alaknak egyeznie kell; készítsünk 4x4-et:
    p0 = np.pad(p0, ((0,0),(0,0),(0,1),(0,1)), mode='constant')

    t1 = np.zeros((1,1,4,4), dtype=np.uint8)
    p1 = np.zeros((1,1,4,4), dtype=np.uint8)
    p1[0,0,0,0] = 1
    p1[0,0,3,3] = 1

    t2 = np.zeros((1,1,4,4), dtype=np.uint8)
    p2 = np.zeros((1,1,4,4), dtype=np.uint8)

    targets = np.concatenate([t0, t1, t2], axis=0)  # (3,1,4,4)
    preds = np.concatenate([p0, p1, p2], axis=0)

    iou, dice = binary_mask_metrics(preds, targets)
    print("per-image IoU  :", iou.ravel())
    print("per-image IoU mean:", iou.mean())
    print("per-image Dice :", dice.ravel())
    print("per-image Dice mean:", dice.mean())

    gi, gd = global_binary_metrics(preds, targets)
    print("global IoU :", gi)
    print("global Dice:", gd)

A kódból várt kimenet – a fenti kézi számítás alapján, nem jelen környezetben futtatott mérésként jelölve:

per-image IoU  : [0.44444444 0.         1.        ]
per-image IoU mean: 0.48148148148148145
per-image Dice : [0.61538462 0.         1.        ]
per-image Dice mean: 0.5384615384615384
global IoU : 0.36363636363636365
global Dice: 0.5333333333333333

27.3.8 Labor: három maskpár metrikája és az aggregálási eltérés

A labor célja, hogy a kézi példát a fenti kóddal saját környezetben lefuttassa, és számszerűen lássa a képenkénti és a globális aggregálás eltérését.

27.3.9 F1–F5 feladatok

27.3.9.1 F1 (fogalmi, nehézség 1)

Adott AA és BB ugyanazon a 10×10-es rácson: |A|=10|A|=10, |B|=8|B|=8, |A∩B|=6|A\cap B|=6. Számítsa ki JJ és DD értékét, és igazolja a levezetett D=2J/(1+J)D=2J/(1+J) azonosságot. Adjon olyan két halmazpárt, ahol D=JD=J, és indokolja, miért.

Elvárt átadandó eredmény: a két számérték, a behelyettesítés, és a két egyenlőségi eset megnevezése.

27.3.9.2 F2 (levezetési, nehézség 2)

Bizonyítsa be a D−JD-J különbségre vonatkozó állítást: ha a+b>0a+b>0, akkor D(A,B)≥J(A,B)D(A,B)\geq J(A,B), és az egyenlőség pontosan i=0i=0 vagy a=b=ia=b=i esetén áll fenn.

Elvárt átadandó eredmény: teljes levezetés a JJ definíciójából, az egyenlőség feltételének indoklása, és egy olyan számpélda, ahol 0<J<10<J<1.

27.3.9.3 F3 (implementációs, nehézség 2)

Írjon dice_iou_multi(pred, target) függvényt, amely (N,C,H,W) alakú, 0/1 uint8 többosztályos maszkokat fogad, és osztályonként visszaadja a képenkénti IoU-átlagot, valamint a mean IoU-t (a CC osztály átlagát). Az üres–üres párokra minden osztályban 1-gyel számoljon. Ellenőrizze a fenti három bináris példán C=1C=1 esetben, hogy a függvény a binary_mask_metrics kimenetével egyezik.

Elvárt átadandó eredmény: futtatható kód, a három példán adódó [4/9,0,1][4/9,0,1] vektor és a J¯img=13/27\overline{J}_{\text{img}}=13/27, továbbá a shape-ellenőrzés.

27.3.9.4 F4 (hibakeresési, nehézség 2)

Adott a következő kódrészlet:

def iou_bad(pred, target):
    inter = (pred * target).sum(axis=(-2, -1))
    union = pred.sum(axis=(-2, -1)) + target.sum(axis=(-2, -1)) - inter
    return (inter / union).mean()

Tegyük fel, hogy a függvényt a hálózat nyers sigmoid-kimenetére hívjuk, amely float32 értékeket tartalmaz [0,1][0,1]-ben. Mi a hiba, mi a következménye, és hogyan javítaná? Ellenőrizze a javítást azzal a kétpixeles példával, ahol pred=[0.6,0.4], target=[1,0].

Elvárt átadandó eredmény: a hiba oka, a numerikus következmény, a küszöbölést tartalmazó javított függvény, és a javított kimenet.

27.3.9.5 F5 (kísérleti/transzfer, nehézség 3)

A GlyphLab szegmentáló laborban a cél a 24×24-es előtér-maszk rekonstrukciója. Tervezzen kiértékelési protokollt, amely a 23.3. Páros összehasonlítás és csoportszintű intervallum alfejezetbeli class-stratified scene bootstrapet használja a képenkénti IoU átlagához. Adja meg:

Elvárt átadandó eredmény: protokoll-leírás, a baseline indoklása, és legalább egy konkrét korlát (például a bootstrap csak a tesztminta-mintavételi bizonytalanságot közelíti).

27.3.10 Megoldások és indoklás

27.3.10.1 F1 megoldása

Az unió mérete a+b−i=10+8−6=12a+b-i=10+8-6=12, tehát J=6/12=0,5J=6/12=0{,}5. A Dice D=2⋅6/(10+8)=12/18=2/3D=2\cdot6/(10+8)=12/18=2/3. Az azonosság: 2J/(1+J)=1/(1,5)=2/32J/(1+J)=1/(1{,}5)=2/3, egyezik.

A D=JD=J esetek a levezetett D−J=J(1−J)/(1+J)D-J=J(1-J)/(1+J) képletből: J=0J=0, azaz i=0i=0 (diszjunkt halmazok, például AA a bal felső, BB a jobb alsó sarok), vagy J=1J=1, azaz a=b=ia=b=i (a két halmaz azonos). Ha AA üres és BB nem üres, az i=0i=0 esethez tartozik, és J=D=0J=D=0; az üres–üres pár külön konvenció.

27.3.10.2 F2 megoldása

A tétel szerint D=2J/(1+J)D=2J/(1+J), feltéve, hogy a+b>0a+b>0. Ekkor

D−J=2J1+J−J=2J−J(1+J)1+J=J(1−J)1+J. D-J=\frac{2J}{1+J}-J=\frac{2J-J(1+J)}{1+J}=\frac{J(1-J)}{1+J}.

Mivel J=|A∩B|/|A∪B|∈[0,1]J=|A\cap B|/|A\cup B|\in[0,1], a számláló nemnegatív, a nevező 1+J≥1>01+J\geq1>0. Így D≥JD\geq J. Az egyenlőség pontosan akkor, ha J(1−J)=0J(1-J)=0, azaz J=0J=0 vagy J=1J=1. A J=0J=0 ekvivalens i=0i=0-val, mert a nevező pozitív. A J=1J=1 ekvivalens i=a+b−ii=a+b-i-vel, azaz 2i=a+b2i=a+b. Mivel i≤ai\leq a és i≤bi\leq b, ez csak i=ai=a és i=bi=b mellett lehet, tehát a=b=ia=b=i, vagyis A=BA=B. Számpélda közbülső értékre: a=6a=6, b=6b=6, i=3i=3, ekkor J=3/9=1/3J=3/9=1/3, D=6/12=1/2D=6/12=1/2, és D>JD>J.

27.3.10.3 F3 megoldása

A többosztályos függvény minden cc osztályra binarizál:

def dice_iou_multi(pred, target):
    # pred, target: (N,C,H,W), uint8, 0/1 one-hot vagy index-halmaz? Jelen
    # megoldás: már binarizált C csatornás 0/1 tombot varunk.
    pred = np.asarray(pred).astype(bool)
    target = np.asarray(target).astype(bool)
    assert pred.shape == target.shape and pred.ndim == 4
    N, C, H, W = pred.shape
    ious = np.empty((C, N), dtype=np.float64)
    for c in range(C):
        p = pred[:, c, None, :, :]  # (N,1,H,W)
        t = target[:, c, None, :, :]
        iou, _ = binary_mask_metrics(p, t, empty_empty_value=1.0)
        ious[c] = iou[:, 0]
    per_class_mean = ious.mean(axis=1)   # (C,)
    miou = per_class_mean.mean()
    return per_class_mean, miou

A C=1C=1 esetben a három példa IoU-vektora [4/9,0,1][4/9,0,1], az osztályon belüli átlag 13/27≈0,481513/27\approx0{,}4815. A kód az üres–üres konvenciót az empty_empty_value=1.0 argumentummal őrzi meg. Alakellenőrzés: bemenet (3,1,4,4), kimenet per_class_mean alakja (1,), a miou skalár.

27.3.10.4 F4 megoldása

A hiba: a pred nem bináris, hanem valós [0,1][0,1]-beli sigmoid-kimenet. A pred * target ezért nem metszet-számosságot ad, hanem súlyozott összeget; a union sem halmaz-unió, hanem valós összeg. A következmény: a metrika nem IoU, és érzékeny a küszöb alatti zajra; például a kétpixeles [0.6,0.4] és [1,0] esetén az inter 0,60{,}6, a union 1,41{,}4, az IoU-hibrid 0,42860{,}4286, miközben a küszöbölt [1,0] predikcióval a valódi IoU 11.

A javítás:

def iou_fixed(pred, target):
    p = np.asarray(pred, dtype=np.float64) > 0.5
    t = np.asarray(target, dtype=np.float64) > 0.5
    inter = np.logical_and(p, t).sum(axis=(-2, -1))
    union = np.logical_or(p, t).sum(axis=(-2, -1))
    return (inter / union).mean()

A kétpixeles példán a kimenet 11. Ha a predikció valószínűség, a kiértékelés előtt rögzíteni kell a küszöböt; a 23.2. Kalibráció és döntési küszöb alfejezetben a döntési küszöb kalibrációs szerepét tárgyaljuk, itt a metrika bináris definíciója a döntés utáni maszkot várja.

27.3.10.5 F5 megoldása

A protokoll:

  1. A tesztkészlet 3030 független jelenetet tartalmaz, jelenetenként két view-val, tehát 6060 képet.
  2. Bináris szegmentáló modell minden képre ad egy BkB_k maszkot; a célmaszk AkA_k. Képenként számítjuk a képenkénti IoU-t az üres konvencióval.
  3. Jelenetszintű statisztika: minden ss jelenetre a két view IoU-jának átlaga, ms=(Js,1+Js,2)/2m_s=(J_{s,1}+J_{s,2})/2. Ezzel a megfigyelési egység a jelenet lesz, nem az egyes kép, mert a két view ugyanabból a jelenetből függő.
  4. A 3030 jelenet-értékből vett átlag a pontbecslés: μ̂=130∑sms\hat{\mu}=\frac1{30}\sum_s m_s.
  5. A class-stratified scene bootstrap a 23.3. Páros összehasonlítás és csoportszintű intervallum szerint: mind a három osztályban 1010 jelenet van; a replikátumban osztályonként 1010 jelenetet húzunk visszatevéssel. A replikátumátlagot a msm_s értékekből számítjuk, a húzott jelenetek súlyozatlan átlagaként. Az intervallum a replikátumok 2,5%–97,5% kvantilise.
  6. Baseline: mindig üres maszk. Ekkor minden nem üres célra J=0J=0; a GlyphLab képeken a célmaszk általában nem üres, ezért a baseline körülbelül 0, kivéve ha az előtér-generátor üres maszkot is ad; ha igen, az üres–üres párok 1-gyel számítanak. A baseline tehát azt méri, mennyire triviális a feladat üres predikcióval.
  7. Érvényességi korlát: a bootstrap a tesztminta jelenetek közötti mintavételi ingadozását közelíti, nem a modelltanítás seedjeinek szórását, nem az adatgenerátor bizonytalanságát, és nem az éles alkalmazásban fellépő domaineltolódást. Az üres–üres konvenció megváltoztatása megváltoztatja a pontbecslést is, ezért a protokoll közzétételekor a konvenciót a metrika képletével együtt kell rögzíteni.

27.3.11 Tipikus tévedés és ellenpélda

A leggyakoribb tévedés: a globális pixel-IoU-t és a képenként átlagolt IoU-t ugyanannak a statisztikának tekinti. Ez csak speciális esetben, például azonos méretű és azonos előtér-számosságú maszkoknál adhat közeli értéket; általában különböző.

Ellenpélda: két tesztkép. Az elsőn |A1|=1000|A_1|=1000, |B1|=1000|B_1|=1000, i1=1000i_1=1000, tehát J1=1J_1=1. A másodikon |A2|=10|A_2|=10, B2=⌀B_2=\varnothing, tehát J2=0J_2=0. A képenkénti átlag (1+0)/2=0,5(1+0)/2=0{,}5. A globális: TP=1000\mathrm{TP}=1000, FP=0\mathrm{FP}=0, FN=10\mathrm{FN}=10, tehát

Jglob=10001010≈0,9901. J_{\text{glob}}=\frac{1000}{1010}\approx0{,}9901.

Ugyanaz a modell egyszer 0,5-ös teljesítményűnek, másszor 0,99-esnek látszik, attól függően, hogy képenként vagy pixelenként átlagolunk. A két statisztika más kutatási kérdésre válaszol: az első arra, hogy egy átlagos kép/jelenet milyen jól van szegmentálva, a második arra, hogy a pixelek mekkora hányada helyes.

27.3.12 Önellenőrzés és korábbi fogalom visszahívása

Visszahívás a 15.3. Transposed convolution mint adjungált alfejezetből: a transposed convolution adjungált, nem általános inverz. A jelen egység kapcsolódása: az U-Net decoder a transzponált konvolúcióval állítja elő a térbeli maszklogitokat, de a metrika a logitok küszöbölése utáni bináris halmazt méri. Az inverzként való félreértés a metrikaoldalra is átvihető: a magas IoU nem azt jelenti, hogy a dekóder visszaállította az eredeti maszk minden határpixelét, csak azt, hogy a halmazátfedés nagy.

Önellenőrzés: a kézi példában i1=4i_1=4, a1+b1=13a_1+b_1=13, az unió 99; a Dice 8/138/13 és az IoU 4/94/9 közti azonosság 2(4/9)/(1+4/9)=8/9⋅9/13=8/132(4/9)/(1+4/9)=8/9\cdot9/13=8/13. A harmadik pár üres–üres, a tétel nem alkalmazható, az 1-es konvenció külön definíció. A labor kódja bool konverziót használ, ezért a np.pad után a p0 4×4-es alakú; az összegzések az utolsó két tengelyen futnak, a kimenet (3,1).

27.3.13 Rövid összefoglaló

A bináris szegmentálás két alappillére az IoU és a Dice. Az IoU a metszet és az unió, a Dice a kétszeres metszet és a méretösszeg hányadosa. Nemüres halmazokra D=2J/(1+J)D=2J/(1+J), amit a közös a,b,ia,b,i statisztikából elemi algebrával levezettünk. Az üres–üres párra a könyv páronkénti 1-es konvenciót rögzít. A képenkénti és a globális pixel-aggregálás külön statisztika: az első képenként, a második pixelenként súlyoz, és az üres konvenciót is másként kezeli. A labor három maszkpáron mutatta az eltérést. A következő alkalmazás: 27.4. Instance mask és összetett feladat alfejezetben az instance mask és az összetett feladat kapcsolja össze a detektálásból ismert IoU-t a pixelszintű előtér-meghatározással.

27.3.14 Források