7.15. การเขียนตัวประมวลผลหลังของตัวเอง

เมื่อแคตตาล็อกไม่ครอบคลุมโมเดล -- โครงข่ายวิจัยที่มีเค้าโครงขาออกเฉพาะ การปรับแต่งสถาปัตยกรรมที่มีอยู่ เทนเซอร์ที่การตีความเชิงความหมายขึ้นอยู่กับแอปพลิเคชัน -- แอปพลิเคชันจะจัดหาตัวประมวลผลหลังของตัวเอง โปรโตคอลนั้นเรียบง่าย คือ callable ที่รับ (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. การเชื่อมต่อ

จุดเชื่อมต่อสองจุด kwarg postprocess= บนตัวสร้างผูก callable สำหรับทุกการเรียก predict() บนโมเดล:

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

ในการแทนที่การผูกสำหรับการเรียกครั้งเดียว -- สลับตัวถอดรหัสโดยไม่ต้องโหลดโมเดลใหม่ -- ส่ง callback= ไปยัง predict โดยตรง:

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

ลายเซ็น callable เหมือนกันในทั้งสองกรณี

7.15.2. สิ่งที่ callable ได้รับ

  • model -- อินสแตนซ์ Model ซึ่งมีประโยชน์สำหรับพารามิเตอร์การ quantization (output_scale, output_zero_point, output_dtype) และมิติอินพุต (input_shape)

  • inputs -- รายการอินพุตที่แอปพลิเคชันส่งไปยัง predict() องค์ประกอบแรกมักจะเป็นอินสแตนซ์ Normalization ที่ผูกไว้ แอตทริบิวต์ roi ของมันคือสิ่งที่ NMS คาดหวังสำหรับการแมปกรอบกลับไปยังภาพต้นฉบับ

  • outputs -- เทนเซอร์ขาออกดิบเป็นรายการของออบเจ็กต์ ndarray ใน dtype ดั้งเดิม ขาออก float จะมาถึงตามเดิม ขาออก integer จะมาถึงแบบ quantized

7.15.3. การคำนวณแบบ Quantized

ตัวถอดรหัสที่ส่งมาทั้งหมดใช้ตัวช่วยเดียวกันใน ml.utils และตัวแบบกำหนดเองมักต้องการรูปแบบเดียวกัน quantize() ยก threshold แบบ float ขึ้นสู่พื้นที่ quantized ของโมเดล threshold() กรองโดยไม่ต้อง dequantize เทนเซอร์ทั้งหมด และ dequantize() รันครั้งเดียวบนผู้รอดพ้น sigmoid() และ logit() มีให้สำหรับโครงข่ายที่ช่องขาออกเป็น pre-sigmoid logits (ตัวตรวจจับ MediaPipe เป็นกรณีตัวอย่างหลัก)

สำหรับโมเดลที่มีขาออก float -- regression heads โมเดลที่มีเลเยอร์ dequantize สุดท้ายฝังอยู่ -- ตัวช่วย quantization จะผ่านโดยไม่เปลี่ยนแปลง ดังนั้นโค้ดตัวประมวลผลหลังเดียวกันจะทำงานกับ dtype ใดก็ได้โดยไม่ต้องแยกกรณีพิเศษ

7.15.4. ค่าที่ส่งคืน

สิ่งที่ callable ส่งคืนคือสิ่งที่ predict() ส่งคืน สำหรับตัวถอดรหัสที่ส่งออกกรอบ การแบบแผนคือการผลักผู้สมัครผ่าน NMS และส่งคืนรายการต่อคลาสของมัน -- รูปร่างการเรียกที่ non-max suppression บันทึกไว้และ YOLOv8 walkthrough สร้างในบริบท สำหรับสิ่งอื่น ๆ ส่งคืนสิ่งที่แอปพลิเคชันพบว่าสะดวก ไม่ว่าจะเป็น ndarray เดี่ยว สตริง label tuple ของ (class, score, embedding) หรือ dictionary