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