7.15. كتابة معالجك الخاص#
عندما لا يغطّي الكتالوج نموذجاً ما -- شبكة بحثية تخطيط ناتجها مُفصَّل خصيصاً، أو تعديل على بنية قائمة، أو موتر تفسيره الدلالي خاص بالتطبيق -- يوفّر التطبيق معالجه اللاحق الخاص. البروتوكول بسيط: كائن قابل للاستدعاء يأخذ (model, inputs, outputs) ويعيد ما يتوقعه التطبيق من predict().
الفئة ذات __call__ هي الصيغة المتعارَف عليها:
class MyPostprocessor:
def __init__(self, threshold=0.5):
self.threshold = threshold
def __call__(self, model, inputs, outputs):
...
return result
تعمل الدالة العادية أيضاً -- يتحقق المحرك فقط من أن الكائن قابل للاستدعاء.
7.15.1. ربطه في النظام#
نقطتا ربط. توسيطة postprocess= على البانِي تربط الكائن القابل للاستدعاء بكل استدعاء predict() على النموذج:
model = ml.Model("/rom/my_model.tflite",
postprocess=MyPostprocessor())
لتجاوز الربط لاستدعاء واحد -- تبديل المفكِّكات دون إعادة تحميل النموذج -- مرّر callback= إلى predict مباشرةً:
result = model.predict([img], callback=MyOtherPostprocessor())
تكون توقيعة الكائن القابل للاستدعاء واحدة في كلتا الحالتين.
7.15.2. ما يستقبله الكائن القابل للاستدعاء#
model-- مثيلModel، مفيد لمعاملات التكميم (output_scale،output_zero_point،output_dtype) وأبعاد المدخلات (input_shape).inputs-- قائمة المدخلات التي مرّرها التطبيق إلىpredict(). العنصر الأول عادةً هو مثيلNormalizationالمربوط؛ وسمتهroiهي ما تتوقعهNMSلإعادة تخطيط المربعات إلى الصورة الأصلية.outputs-- الموترات الناتجة الخام على هيئة قائمة من كائناتndarray، بنوع بياناتها الأصلي. تصل المخرجات العائمة كما هي؛ وتصل المخرجات الصحيحة مُكمَّمة.
7.15.3. الحساب المُكمَّم#
تلجأ المفكِّكات المشحونة جميعها إلى المساعِدات نفسها في ml.utils، وعادةً ما يريد المفكِّك المخصص النمط ذاته: ترفع quantize() عتبة عائمة إلى الفضاء المُكمَّم للنموذج، وتُرشّح threshold() دون فكّ تكميم الموتر بأكمله، وتعمل dequantize() مرة واحدة على الناجين. تتوفر sigmoid() و logit() للشبكات التي تكون قنوات ناتجها لوغيتات ما قبل السيغمويد (كواشف MediaPipe هي الحالة النموذجية).
بالنسبة للنماذج ذات المخرجات العائمة -- رؤوس الانحدار، أو النماذج بطبقة فكّ تكميم نهائية مدمجة -- تمرّر مساعِدات التكميم القيم دون تغيير، فيعمل كود المعالج اللاحق نفسه مع أي من نوعَي البيانات دون معالجة حالة خاصة.
7.15.4. القيمة المُعادة#
أيّاً كان ما يعيده الكائن القابل للاستدعاء فهو ما تعيده predict(). بالنسبة للمفكِّكات التي تُصدر مربعات، يقضي العرف بدفع المرشحين عبر NMS وإعادة قوائمه لكل فئة -- شكل الاستدعاء الذي يوثّقه كبت غير الحد الأقصى ويبنيه شرح YOLOv8 المفصّل في سياقه. لأي شيء آخر، أعِد ما يجده التطبيق ملائماً: ndarray واحد، أو سلسلة تسمية، أو صف (class, score, embedding)، أو قاموس.