7.15. Scrierea propriului post-procesor¶
Când catalogul nu acoperă un model – o rețea de cercetare a cărei dispunere de ieșire este personalizată, o modificare a unei arhitecturi existente, un tensor a cărui interpretare semantică este specifică aplicației – aplicația își furnizează propriul post-procesor. Protocolul este simplu: un obiect apelabil care preia (model, inputs, outputs) și returnează orice se așteaptă aplicația de la predict().
O clasă cu __call__ este forma convențională:
class MyPostprocessor:
def __init__(self, threshold=0.5):
self.threshold = threshold
def __call__(self, model, inputs, outputs):
...
return result
O funcție simplă funcționează și ea – motorul verifică doar că obiectul este apelabil.
7.15.1. Conectarea acestuia¶
Două puncte de atașare. Argumentul cu cuvânt-cheie postprocess= de pe constructor leagă obiectul apelabil pentru fiecare apel predict() de pe model:
model = ml.Model("/rom/my_model.tflite",
postprocess=MyPostprocessor())
Pentru a suprascrie legarea pentru un singur apel – schimbând decodoarele fără a reîncărca modelul – transmite callback= direct lui predict:
result = model.predict([img], callback=MyOtherPostprocessor())
Semnătura obiectului apelabil este aceeași în oricare caz.
7.15.2. Ce primește obiectul apelabil¶
model– instanțaModel, utilă pentru parametrii de cuantizare (output_scale,output_zero_point,output_dtype) și dimensiunile de intrare (input_shape).inputs– lista de intrări pe care aplicația le-a transmis luipredict(). Primul element este de obicei instanța legatăNormalization; atributul săuroieste ceea ce așteaptăNMSpentru remaparea casetelor înapoi în imaginea originală.outputs– tensorii de ieșire bruți sub forma unei liste de obiectendarray, în tipul lor de date nativ. Ieșirile în virgulă mobilă sosesc așa cum sunt; ieșirile întregi sosesc cuantizate.
7.15.3. Aritmetică cuantizată¶
Decodoarele livrate apelează toate aceiași asistenți din ml.utils, iar unul personalizat dorește de obicei același tipar: quantize() ridică un prag în virgulă mobilă în spațiul cuantizat al modelului, threshold() filtrează fără a dezcuantiza întregul tensor, iar dequantize() rulează o singură dată asupra supraviețuitorilor. sigmoid() și logit() sunt disponibile pentru rețele ale căror canale de ieșire sunt logit-uri pre-sigmoid (detectoarele MediaPipe sunt cazul canonic).
Pentru modele cu ieșiri în virgulă mobilă – capete de regresie, modele cu un strat final de dezcuantizare integrat – asistenții de cuantizare trec mai departe nemodificați, astfel încât același cod de post-procesor funcționează față de oricare tip de date fără tratare specială.
7.15.4. Valoarea returnată¶
Orice returnează obiectul apelabil este ceea ce returnează predict(). Pentru decodoarele care emit casete, convenția este să se transmită candidații printr-un NMS și să se returneze listele sale pe clase – forma de apel pe care suprimarea non-maximelor o documentează și pe care parcurgerea pas cu pas a YOLOv8 o construiește în context. Pentru orice altceva, returnează orice consideră aplicația convenabil: un singur ndarray, un șir de etichetă, un tuplu (class, score, embedding), un dicționar.