7.13. Potiskivanje koje nije najveće (non-max suppression)

Mreža za detekciju obično oko istog stvarnog objekta proizvede nekoliko preklapajućih kandidata za okvire: svako sidro u blizini objekta okida sa sličnim rezultatom, a naknadni procesor vidi ih sve. Potiskivanje koje nije najveće (NMS) je korak koji taj skup pretvara u jedan okvir.

Algoritam je kratak: poredaj okvire kandidate po rezultatu, uzmi onaj s najvišim rezultatom, potisni svaki drugi okvir koji se s njim preklapa iznad odabranog praga, zatim uzmi sljedeći najviši od onoga što ostaje i ponovi. Mjera preklapanja je presjek-preko-unije (IoU) – zajednička površina dvaju okvira podijeljena s njihovom ukupnom površinom, vrijednost između 0 (nema preklapanja) i 1 (identični okviri). Argument konstruktora nms_threshold na svakom isporučenom naknadnom procesoru granica je iznad koje se okviri tretiraju kao duplikati već zadržanog okvira.

Lijevo, tri preklapajuća granična okvira oko jednog subjekta, označena rezultatima 0.92, 0.83 i 0.71. Strelica pokazuje udesno, gdje ostaje jedan preživjeli okvir s rezultatom 0.92. Dva okvira s nižim rezultatom potisnuta su onim s višim rezultatom jer njihov presjek-preko-unije s njim premašuje prag.

NMS sažima skup preklapajućih detekcija na onu s najvišim rezultatom.

7.13.1. Soft-NMS

Isporučena klasa ml.utils.NMS implementira Soft-NMS, poboljšanje koje smanjuje rezultat preklapajućeg okvira za iznos koji ovisi o tome koliko se preklapa, umjesto da okvir potpuno odbaci. Ako sniženi rezultat padne ispod praga, okvir se odbacuje; inače preživljava sa smanjenim rezultatom i natječe se u sljedećem krugu.

Parametar nms_sigma upravlja time koliko je smanjenje agresivno. S malim nms_sigma (isporučena zadana vrijednost 0.1) smanjenje je strmo: okviru s jakim preklapanjem rezultat se spušta gotovo na nulu i Soft-NMS se svodi na klasični NMS. S većim nms_sigma smanjenje je blago i preklapajući okviri različitih objekata češće preživljavaju, što je važno kada se stvarni objekti iste klase doista preklapaju (gomila lica, skup dlanova).

Postavljanje nms_sigma na <= 0 u potpunosti onemogućuje smanjenje: preklapajući okviri prolaze sa svojim izvornim rezultatima, a samo ih prag rezultata filtrira.

7.13.2. Izravna izgradnja

Svaki isporučeni naknadni procesor po zaključivanju gradi novi NMS, dodaje mu svakog kandidata i na kraju poziva get_bounding_boxes(). Prilagođeni naknadni procesor slijedi isti obrazac:

from ml.utils import NMS

iw = model.input_shape[0][2]
ih = model.input_shape[0][1]

nms = NMS(iw, ih, inputs[0].roi)
for box, score, class_idx in candidates:
    nms.add_bounding_box(box.xmin, box.ymin,
                         box.xmax, box.ymax,
                         score, class_idx)
result = nms.get_bounding_boxes(threshold=nms_threshold,
                                sigma=nms_sigma)

Konstruktor uzima ulaznu širinu i visinu mreže u pikselima te ROI izvorne slike na kojoj se model izvodio; add_bounding_box() uzima koordinate okvira u tom pikselskom prostoru mrežnog ulaza, a get_bounding_boxes() preživjele okvire vraća natrag u koordinate slike koristeći ROI. Ponovno mapiranje automatski uzima u obzir razvlačenje normalizacije – isti ROI koji je predviđač vidio koristi se za projiciranje okvira natrag – pa su vraćeni okviri spremni za crtanje na uhvaćenu sličicu.

Vraćeni oblik je lista listi po klasi, indeksirana prema label_index proslijeđenom u add_bounding_box. Prazne liste klasa zadržane su tako da se indeks podudara s indeksom klase modela; enumerate(result) prolazi kroz klase zajedno s njihovim detekcijama.