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