A 26.3. NMS, confidence és AP egységben a detektálás utófeldolgozását (NMS, score-küszöb) és az AP-metrikát tárgyaltuk, de nem kérdeztük meg: hogyan jut el a nyers kép a detektor bemenetéig úgy, hogy a doboz annotációk is érvényesek maradjanak? Amikor egy képet átméretezünk, kivágunk vagy tükrözünk, a pixelkoordinátákban megadott dobozok külön transzformációt igényelnek. Ez az egység a synchronized transform fogalmát, a dataset contract-ot és az objektumszintű hibajegyzéket építi fel. Előismeret: a 26.3. NMS, confidence és AP IoU-, NMS- és AP-definíciói; a 22.4. Augmentációs kísérlet és domainváltozás alfejezetből a train augmentáció és a rögzített tesztkorrupció elkülönítése; a 25.4. Nyílt halmaz és ismeretlen input alfejezetből a nyílt halmaz szemlélete, amely itt a negatív, objektum nélküli képek kezelésében tér vissza.
Induló kérdés: ha egy -es képen a dobozt tartalmazó képet -re resize-oljuk, de a dobozt változatlanul hagyjuk, akkor a betanított detektor melyik koordinátarendszerben értelmezi a dobozt, és ez hogyan torzítja az IoU-t?
A felhasznált konvenciók a fejezet elején bevezetett 26.1. Dobozkoordináta, IoU és lokalizációs loss dobozdefiníciót követik. Egy kép , ahol a magasság, a szélesség pixelben. Egy doboz félig nyílt xyxy intervallum:
A doboz területe
.
A detektálási target egy képen
objektumot ír le; a leggyakoribb szerződés szerint a dobozok tömbje
float32, a címkék vektora
int64, ahol a
osztályhalmaz a háttérosztályt nem tartalmazza. A torchvision-stílusú
target dict ezt boxes és labels kulcsokkal
tárolja; az üres képet
,
azaz
alakú üres doboztömb és
hosszú címkevektor jelöli [D18].
Definíció (detektálási adathalmaz szerződés). A tanító és kiértékelő pipeline-ra érvényes szerződés:
Az utolsó pont a 22.4. Augmentációs kísérlet és domainváltozás alfejezetben bevezetett elvet viszi át: a train policy a cél-eloszlás mintavételét módosítja, míg a tesztkorrupció a befagyasztott modell értékelésére szolgáló rögzített leképezés.
Definíció (synchronized transform). Legyen képtranszformáció, amely egy térbeli leképezésből származik, azaz minden pixelpozícióra módon viselkedik. A szinkronizált alkalmazása a párra a következő: , és minden dobozra
ahol a két sarokpontot külön-külön transzformáljuk, majd a koordinátákat a képbe vágjuk. Ha a levágás után a doboz érvénytelen ( vagy ), akkor az objektum eltűnik a targetből, és csökken.
Lemma (resize geometriája). Legyen a kép eredeti mérete , az átméretezett méret , és legyen , . Az átméretezés, mint , a térbeli leképezést indukálja. Ekkor egy doboz szinkronizált transzformáltja
és .
Bizonyítás. Az átméretezés definíciója szerint a bemeneti kép pixelpozíciója a kimeneti kép pozíciójára kerül, tehát a sarokpontokra a fenti lineáris leképezés. Az érvényességhez ellenőrizzük a határokat: mivel és , ezért ; továbbá miatt , így az új doboz a kép határain belül marad. Ugyanez áll az -koordinátára. A terület:
Ezzel a lemma bizonyítását befejeztük. A bizonyítás során kihasználtuk, hogy a doboz sarokpontokkal adott; a félig nyílt intervallum jellege a lineáris leképezés alatt megmarad, mert nyílt intervallum képe nyílt, zárt határpont képe zárt. Az állítás bias nélküli, konstans eltolást nem tartalmazó resize-ra vonatkozik; ha a resize-t crop követi vagy előzi meg, a kompozíciót külön kell kezelni.
Crop. Legyen a kivágott ablak , ahol , . A crop önmagában eltolás: . Mivel a doboz egy része kieshet az ablakból, a szinkronizált transzformáció után a dobozt a tartományra vágjuk:
Ha vagy , a doboz eltűnik.
Kompozíció. A pipeline gyakran crop + resize sorozatot alkalmaz. Mivel a leképezések kompozíciója a leképezések egymás utáni alkalmazása, a dobozokra ugyanazt a sorrendet kell alkalmazni, mint a képre. A következő feladat (F2) ezt számszerűen begyakoroltatja.
Empty target. A negatív kép
eset. A pipeline-nak ez nem hibás állapot, hanem érvényes adatpont: a
boxes tömb (0,4) alakú, a labels
üres. A transzformációs függvényeknek ezt az esetet explicit módon
kezelniük kell, mert az üres tömbön végzett koordináta-művelet
shape-hibához vezethet, vagy ami rosszabb, csendben üres marad, és a
downstream összehasonlítás félreértelmezi.
A 26.3. NMS, confidence és AP greedy matching eljárása után minden ground truth (GT) doboz vagy kapott predikciót (, tipikusan ), vagy nem; minden predikció vagy kapott GT-párt, vagy nem. Ebből a következő objektumszintű hibakategóriákat definiáljuk:
| Kategória | Definíció | Következmény |
|---|---|---|
| Missed detection | GT doboz, amelyhez nem tartozik predikció | False negative, recall-csökkenés |
| Duplicate detection | Ugyanahhoz a GT-hez több predikció is kapcsolódna | Precision-csökkenés, kettős számlálás |
| Localization error | A predikció osztálya helyes, a legközelebbi GT-vel | False positive, rossz doboz |
| False positive (háttér) | Predikció, amelyhez nincs azonos osztályú GT | Precision-csökkenés |
A lokalizációs hiba és a téves osztály (classification error) megkülönböztetése fontos, mert a javítás módja eltér: a lokalizáció a regressziós fej, az osztálytévesztés a klasszifikációs fej problémájára utal. A fenti táblázat csak a greedy matching utáni durva osztályozás; a részletes hibaelemzés a predikció score-ját és az IoU hisztogramját is vizsgálja.
Heurisztika (hibajegyzék célja). A hibajegyzék nem helyettesíti az AP-metrikát, hanem diagnosztikai eszköz: megmutatja, hogy a detektor mely hibatípusban veszít. A diagnózis akkor megbízható, ha a jegyzéket ugyanazon a rögzített teszthalmazon, ugyanazzal a matching konvencióval számoljuk, mint az AP-t. Ez heurisztika, nem tétel: a hibatípusok aránya nem azonosítható egyetlen okkal.
Kézi példa. Legyen , , tehát . A doboz . A transzformált: . Terület: , . A doboz a -es kép belsejében marad.
Minimális kód. A következő függvény a resize
szinkronizált doboztranszformációját valósítja meg NumPy-ban. Az input
és a futtatási környezet: munkakönyvtár lab/det_pipeline,
CPU, NumPy 2.x, dtype float32, seed 20261020 (a seed a szintetikus adat
előállításához használatos, maga a transzformáció determinisztikus).
# resize_boxes.py
"""Szinkronizált resize doboztranszformáció, NumPy referencia."""
import numpy as np
def resize_boxes(boxes: np.ndarray, old_hw: tuple[int, int],
new_hw: tuple[int, int]) -> np.ndarray:
"""Dobozok átméretezése a kép resize-zal együtt.
boxes: float32, shape (M, 4), félig nyílt xyxy.
old_hw: (H, W), new_hw: (H', W').
Visszatér: float32, shape (M, 4).
Üres M=0 esetén (0,4) alakú tömböt ad vissza.
"""
boxes = np.asarray(boxes, dtype=np.float32)
if boxes.shape[0] == 0:
return boxes.reshape(0, 4).astype(np.float32)
H_old, W_old = old_hw
H_new, W_new = new_hw
alpha_y = H_new / H_old
alpha_x = W_new / W_old
out = boxes.copy()
out[:, 0] *= alpha_x
out[:, 2] *= alpha_x
out[:, 1] *= alpha_y
out[:, 3] *= alpha_y
return out
if __name__ == "__main__":
# Ellenőrző példa
boxes = np.array([[2, 3, 6, 7]], dtype=np.float32)
result = resize_boxes(boxes, (8, 8), (4, 4))
print(result) # várható [[1. 1.5 3. 3.5]]Futtatási parancs: python resize_boxes.py. A várt
kimenet [[1. 1.5 3. 3.5]], tolerancia
abszolút hibahatárral ellenőrizhető, mert a műveletek szorzásból állnak
és float32-ben a
pontosan reprezentálható.
A következő labor nem futtatott kimenet, hanem a Futtatás és tudományos bizonyíték szerződésnek megfelelően jelölt szemléltető terv. A tényleges futtatáshoz a kódot külön kell végrehajtani.
Kérdés. Hogyan változik az objektumszintű hibajegyzék, ha a tesztképeket -ről -re resize-oljuk, és a dobozokat (a) nem transzformáljuk, (b) szinkronizáltan transzformáljuk?
Hipotézis. Az (a) változatban a dobozok a régi koordinátarendszerben maradnak, ezért a predikciók és a GT közötti IoU szisztematikusan csökken; a lokalizációs hibák aránya megnő. A (b) változatban a hibajegyzék a transzformáció előttihez hasonló marad.
Adat és split. 40 szintetikus kép, , egy csatorna, float32, seed 20261020. Minden képen 0–3 egyszerű téglalap objektum, osztályok . Legalább 10 kép üres (). A split: 20 train, 10 val, 10 test, az objektumok számára rétegezve, a scene_id csoportosítással (ha több nézet van). A test annotációt a protokoll végéig nem nézzük.
Baseline és változó. A baseline egy egyszerű csúszóablakos detektor, amely rögzített méretű ablakot csúsztat, és osztályoz + regresszál. A változó tényező a pipeline transzformációja: (a) kép resize doboztranszformáció nélkül, (b) szinkronizált resize a fenti függvénnyel. Minden más paraméter rögzített.
Metrika. Objektumszintű hibajegyzék: missed, duplicate, localization, false positive darabszám; valamint AP @ a 26.3. NMS, confidence és AP konvencióval. A kiértékelés a befagyasztott, val halmazon kiválasztott modellen történik.
Ellenőrzés. A szinkronizált transzformáció után minden dobozra ellenőrizzük, hogy és . Az üres képeknél megmarad.
Szemléltető hibajegyzék. A következő számpélda a módszer formáját mutatja, nem futtatott eredmény. Tegyük fel, hogy a test halmaz 4 képet tartalmaz, összesen 5 GT dobozzal. A detektor 6 predikciót ad; a greedy matching után a hibák: 1 missed, 1 duplicate, 1 localization, 1 false positive. Ekkor a jegyzék:
| Kép | GT | Predikció | Eredmény |
|---|---|---|---|
| 1 | 1 | 2 | 1 TP, 1 duplicate |
| 2 | 1 | 1 | 1 localization (IoU 0,3) |
| 3 | 2 | 1 | 1 missed, 1 FP |
| 4 | 1 | 2 | 2 TP, 0 hiba |
A példa számsorai kézzel konstruáltak; a kísérleti következtetéshez tényleges futtatás és nyers számok szükségesek.
F1 (fogalmi, nehézség 1). Adott egy kép egyetlen GT dobozzal , osztály 0, és a detektor egyetlen predikciója , osztály 0. Számítsa ki az IoU-t (), és sorolja be a predikciót a fenti hibajegyzékbe. Adja meg, miért nem missed detection, és miért nem duplicate.
F2 (levezetési, nehézség 2). Vezesse le a crop + resize kompozíció doboztranszformációját. Bemenet: -es kép, crop ablak , , , majd resize -re. A bemeneti doboz . Adja meg a transzformált dobozt lépésről lépésre, és ellenőrizze az érvényességet.
F3 (implementációs, nehézség 2). Írjon
crop_boxes függvényt, amely a crop doboztranszformációját
végzi el: bemenet boxes
float32, a crop ablak
;
a kimenet a levágott, érvényes dobozok
alakban. Kezelje az
és a teljesen kieső doboz esetét. Ellenőrizze a fenti F2 példa crop
lépésén.
F4 (hibakeresési, nehézség 2). Adott a következő pipeline-részlet:
def transform(image, boxes):
image = resize(image, (12, 12))
# itt hiányzik valami
return image, boxesMagyarázza el, mi a hiba, mi a következménye a tanításra és az AP-számításra, és adja meg a javítást. Visszaellenőrzésként mondja ki, milyen invariánsnak kell teljesülnie a javított függvény kimenetére.
F5 (kísérleti, nehézség 3). Tervezzen kísérletet annak számszerűsítésére, hogy a csak pozitív képeken mért AP mennyiben torzítja a detektor értékelését a teljes teszt halmazon mért AP-hez képest. Adja meg a kérdést, a hipotézist, az adat összetételét (pozitív/negatív arány), a baseline detektort, a változó tényezőt, a metrikát és a következtetés érvényességi korlátját.
F1 megoldás. Az interszekció: a két doboz közös része a négyzet, területe . Az unió: . Tehát . A greedy matching során ez a predikció nem kap GT-párt, tehát false positive a matching szerint. Mivel a predikció osztálya megegyezik az egyetlen GT osztályával, és az IoU pozitív, de alatt van, a hibajegyzékben localization error kategóriába esik. Nem missed detection, mert van predikció; nem duplicate, mert csak egy predikció van, és az sem érte el a küszöböt.
F2 megoldás. Első lépés, crop az eltolással: , . A doboz: . Levágás a ablakra: ; ; ; . Tehát a crop utáni doboz , érvényes, mert és . Második lépés, resize -re: . A szorzás után . Ellenőrzés: , , a doboz érvényes a -es képen. A terület a crop után , a resize után , ami megfelel a lemma állításának.
F3 megoldás. A függvény kódja:
import numpy as np
def crop_boxes(boxes: np.ndarray, crop: tuple[int, int, int, int]) -> np.ndarray:
"""Crop doboztranszformációja.
boxes: float32, shape (M, 4), xyxy.
crop: (x0, y0, W_c, H_c) félig nyílt ablak.
Visszatér: float32, shape (M', 4), M' <= M.
"""
boxes = np.asarray(boxes, dtype=np.float32)
if boxes.shape[0] == 0:
return boxes.reshape(0, 4).astype(np.float32)
x0, y0, W_c, H_c = crop
out = boxes.copy()
out[:, 0] -= x0
out[:, 2] -= x0
out[:, 1] -= y0
out[:, 3] -= y0
out[:, 0] = np.maximum(out[:, 0], 0.0)
out[:, 1] = np.maximum(out[:, 1], 0.0)
out[:, 2] = np.minimum(out[:, 2], float(W_c))
out[:, 3] = np.minimum(out[:, 3], float(H_c))
valid = (out[:, 2] > out[:, 0]) & (out[:, 3] > out[:, 1])
return out[valid].astype(np.float32)
if __name__ == "__main__":
boxes = np.array([[1, 3, 9, 11]], dtype=np.float32)
result = crop_boxes(boxes, (2, 2, 8, 8))
print(result) # várható [[0. 1. 7. 8.]]A függvény az
esetben üres tömböt ad, a teljesen kieső dobozokat kiszűri. A
valid maszk a szigorú egyenlőtlenséget használja, mert a
félig nyílt intervallum akkor érvényes, ha
.
F4 megoldás. A hiba: a transform a
képet resize-olja, de a dobozokat nem transzformálja a szinkronizált
módon. A dobozok koordinátái az eredeti
-es
képre vonatkoznak, míg a kép már
-es.
Következmény: a training során a regressziós loss téves
célokat lát, mert a dobozok a képen kívülre vagy rossz helyre mutatnak;
a kiértékelésnél az IoU hamis, az AP alábecsült, a lokalizációs hibák
aránya mesterségesen megnő. Javítás: a
resize_boxes hívása a resize után:
def transform(image, boxes):
H, W = image.shape[-2], image.shape[-1]
image = resize(image, (12, 12))
boxes = resize_boxes(boxes, (H, W), (12, 12))
return image, boxesVisszaellenőrzés: a kimeneti dobozoknak teljesíteniük kell, hogy minden dobozra és ; az üres képeknél a dobozok tömbje alakú marad.
F5 megoldásminta. Kérdés: mennyivel nagyobb a detektor AP-ja, ha a tesztből eltávolítjuk a negatív (objektum nélküli) képeket? Hipotézis: a csak pozitív képeken számolt AP magasabb, mert a false positive-ok nagy része a negatív képekről származik. Adat: 100 szintetikus tesztkép: 20 pozitív, 80 negatív, seed 20261020, a pozitív képeken 1–3 objektum. Baseline: egy egyszerű detektor, amely minden pozitív képen 1 helyes dobozt ad (IoU 0,7 felett), de minden negatív képen is ad 1 hamis dobozt. Változó: a kiértékelés halmaza — csak pozitív képek (20) vs. az összes kép (100). Metrika: AP @ . Várható számítás: a csak pozitív halmazon a precision , míg a teljes halmazon , így a teljes AP lényegesen alacsonyabb. Következtetési korlát: a szintetikus baseline nem valós detektor; a kísérlet csak a torzítás mechanizmusát mutatja, nem ad általános nagyságrendet. A valós értékeléshez a negatív képeket is tartalmazó, rögzített teszt szükséges.
A gyakori hiba az, hogy a detektálási teljesítményt olyan teszt halmazon mérik, amely csak objektumot tartalmazó képeket tartalmaz. Ez nem teljes detektálási értékelés. A fenti F5 ellenpéldája mutatja: ha a baseline mind a 80 negatív képen hamis dobozt ad, akkor a csak pozitív halmazon mért AP 1,0, míg a teljes halmazon 0,2 körüli. A torzítás oka, hogy a false positive-ok jelentős része a negatív képekből származik, és a csak pozitív képek kiértékelése ezt a hibaforrást kizárja.
Az állítás formálisan: legyen a pozitív képek halmaza, a teljes teszt. Ha egy detektor minden képen legalább egy false positive predikciót ad, akkor az -n számolt empirikus precision nagyobb vagy egyenlő, mint az -n számolt, feltéve, hogy a true positive-ok száma azonos. A bizonyítás közvetlen: a precision nevezője , és a -ra szűkítés az FP-k egy részét eltávolítja, így a nevező nem nő, a hányados nem csökken. Ez levezetés, nem empirikus állítás; a konkrét különbség mértéke adatfüggő.
Önellenőrző kérdések. (1) Miért marad a félig nyílt intervallum jelleg a resize alatt? (2) Mi történik, ha a crop ablak teljesen levág egy dobozt? (3) Melyik hibakategóriába esik az a predikció, amelyik ugyanazt a GT-t másodikként fedi le értékkel?
Válaszok. (1) A lineáris leképezés a nyílt/zárt határokat megtartja, mert pozitív skalárral szorzunk. (2) A doboz kikerül a targetből, csökken, és az objektum missed detectionnek számít, ha a detektor nem találja. (3) Duplicate detection, amennyiben a greedy matching után a második predikció FP-ként jelenik meg, de a hibajegyzékben a közeli azonos GT miatt duplicate-ként tartjuk számon.
Visszahívás. A 26.3. NMS, confidence és AP egységben a greedy matching, az NMS és az AP fogalmát építettük fel; a mostani hibajegyzék az ottani matching konvenciót használja. A 22.4. Augmentációs kísérlet és domainváltozás egység a train augmentációt és a tesztkorrupciót különítette el: itt a train synchronized augmentáció címkemegőrző, a test transzformáció pedig determinisztikus és befagyasztott modellre vonatkozik. A 25.4. Nyílt halmaz és ismeretlen input egység a nyílt halmazú döntést tárgyalta; a detektálásban a negatív, üres kép hasonló szerepet tölt be, mint az ismeretlen input az osztályozóban, mert a “nincs objektum” explicit kimenet. A 14.4. Csoportos és depthwise konvolúció egység a grouped konvolúció blokkszerkezetét elemezte; a mostani pipeline-szerződés ugyanazt a modularitási elvet követi absztrakt szinten: az adatpipeline és a modell belső transzformációi különválasztva ellenőrizhetők.
A detektálási pipeline a képet és a dobozokat szinkronizáltan transzformálja, hogy a koordinátarendszer mindig az aktuális képhez igazodjon. A resize a doboz sarokpontjait a képméret-aránnyal szorozza; a crop eltolásból és levágásból áll, a kieső dobozok eltűnnek. Az üres cél explicit állapot, amelyet a kódnak kezelnie kell. Az objektumszintű hibajegyzék a greedy matching után missed, duplicate, localization és false positive kategóriákat ad, és az AP-t diagnosztikailag egészíti ki. A csak pozitív képeken mért AP torzít, mert kihagyja a negatív képek false positive-jait. A transzformációs hibák közvetlenül lokalizációs hibának látszanak, ezért a pipeline ellenőrzés a kísérlet része. A tanult transzformációk nélküli AP összehasonlítás félrevezető.
A 27.1. Pixelszintű klasszifikáció és FCN egység a szemantikus szegmentálásba lép át: ott a doboz helyett minden pixel kap osztálycímkét, és a synchronized transform a képet és a maszkot együtt transzformálja. A pipeline-szerződés és a hibaelemzés gondolata átvihető, de a metrika IoU-ból pixel-alapú Dice/IoU lesz.
[P12] Ren, S. et al. (2015). Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks. arXiv:1506.01497. https://arxiv.org/abs/1506.01497.
[P13] Redmon, J. et al. (2015). You Only Look Once: Unified, Real-Time Object Detection. arXiv:1506.02640. https://arxiv.org/abs/1506.02640.
[D18] PyTorch contributors (online). TorchVision Object Detection Finetuning Tutorial. https://docs.pytorch.org/tutorials/intermediate/torchvision_tutorial.html.
Saját levezetés: a resize és crop doboztranszformáció lemmája és bizonyítása.
Saját példa: a kézi számolás, a hibajegyzék szemléltető táblázata
és a resize_boxes/crop_boxes kód.