7.15. Saját megírása

Amikor a katalógus nem fed le egy modellt – egy kutatási hálózat, amelynek kimeneti elrendezése egyedi, egy meglévő architektúra módosítása, egy tenzor, amelynek szemantikai értelmezése alkalmazásspecifikus –, az alkalmazás saját utófeldolgozót biztosít. A protokoll egyszerű: egy hívható objektum, amely (model, inputs, outputs) argumentumokat vesz át, és bármit visszaad, amit az alkalmazás a predict() metódustól vár.

A konvencionális forma egy __call__ metódussal rendelkező osztály:

class MyPostprocessor:
    def __init__(self, threshold=0.5):
        self.threshold = threshold

    def __call__(self, model, inputs, outputs):
        ...
        return result

Egy egyszerű függvény is működik – a motor csak azt ellenőrzi, hogy az objektum hívható-e.

7.15.1. Bekötése

Két csatlakozási pont. A konstruktoron lévő postprocess= kulcsszó-argumentum a hívható objektumot a modell minden predict() hívásához köti:

model = ml.Model("/rom/my_model.tflite",
                 postprocess=MyPostprocessor())

Ahhoz, hogy egyetlen hívásra felülírd a kötést – dekódolók cseréjéhez a modell újratöltése nélkül –, add át a callback= argumentumot közvetlenül a predict hívásnak:

result = model.predict([img], callback=MyOtherPostprocessor())

A hívható objektum szignatúrája mindkét esetben ugyanaz.

7.15.2. Mit kap a hívható objektum

  • model – a Model példány, amely hasznos a kvantálási paraméterekhez (output_scale, output_zero_point, output_dtype) és a bemeneti dimenziókhoz (input_shape).

  • inputs – a bemenetek listája, amelyet az alkalmazás a predict() metódusnak átadott. Az első elem általában a kötött Normalization példány; annak roi attribútuma az, amit a NMS vár a dobozok eredeti képbe való visszaképezéséhez.

  • outputs – a nyers kimeneti tenzorok ndarray objektumok listájaként, a natív dtype-jukban. A lebegőpontos kimenetek úgy érkeznek, ahogy vannak; az egész kimenetek kvantáltan érkeznek.

7.15.3. Kvantált aritmetika

A szállított dekódolók mind ugyanazokhoz a segédfüggvényekhez nyúlnak az ml.utils modulban, és egy egyéni dekódoló általában ugyanezt a mintát szeretné: a quantize() egy lebegőpontos küszöbértéket emel a modell kvantált terébe, a threshold() szűr a teljes tenzor dekvantálása nélkül, a dequantize() pedig egyszer fut le a túlélőkön. A sigmoid() és a logit() azon hálózatokhoz áll rendelkezésre, amelyek kimeneti csatornái sigmoid előtti logitok (a MediaPipe detektorok a kanonikus eset).

A lebegőpontos kimenetű modelleknél – regressziós fejek, a végén beépített dekvantáló réteggel rendelkező modellek – a kvantálási segédfüggvények változatlanul mennek át, így ugyanaz az utófeldolgozó-kód mindkét dtype-pal működik külön kezelés nélkül.

7.15.4. Visszatérési érték

Bármit ad vissza a hívható objektum, azt adja vissza a predict() is. A dobozt kibocsátó dekódolóknál a konvenció az, hogy a jelölteket egy NMS objektumon tolják át, és annak osztályonkénti listáit adják vissza – azt a hívási alakzatot, amelyet a non-max suppression dokumentál, és a YOLOv8 áttekintés épít fel összefüggéseiben. Bármi máshoz adj vissza bármit, amit az alkalmazás kényelmesnek talál: egyetlen ndarray objektumot, egy címkesztringet, egy (class, score, embedding) rendezett hármast, egy szótárt.