VNCoreMLRequest — มันคืออะไร คำขอ Vision สำหรับ Core ML ใน iOS

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-20 เวลาอ่าน: 8 นาที

VNCoreMLRequest — เป็นคลาสย่อยของ VNRequest ที่ช่วยให้สามารถเรียกใช้โมเดล Core ML ภายในไปป์ไลน์ของ Vision รวมข้อดีของตัวจับที่เตรียมพร้อมของ Vision (ใบหน้า ข้อความ วัตถุ) กับโมเดล ML ที่กำหนดเองสำหรับการจัดหมวดหมู่และการถดถอย โดยอัตโนมัติ VNCoreMLRequest จะจัดการประมวลผลภาพล่วงหน้า — การปรับขนาด การตัด และการแปลงพื้นที่สี — ตามข้อกำหนดของโมเดล Core ML

ประเด็นสำคัญ

  • VNCoreMLRequest — สะพานระหว่าง Core ML และ Vision: โมเดล ML ทำงานเหมือนคำขอ Vision
  • การประมวลผลภาพล่วงหน้าโดยอัตโนมัติ: การปรับขนาด การตัด และการแก้ไขสีตามข้อกำหนดของโมเดล
  • รวมกับ VNRequest อื่นๆ ใน perform() เดียวสำหรับการสร้างไปป์ไลน์
  • รองรับ VNCoreMLModel — ตัวห่อหุ้มเทอร์ MLModel สำหรับการทำงานกับภาพและ FeatureValue
  • ทำงานบน Neural Engine และ GPU เพื่อประสิทธิภาพสูงสุด

VNCoreMLRequest คืออะไร?

VNCoreMLRequest เป็นคลาสย่อยของ VNRequest ที่เพิ่มใน iOS 11 พร้อมกับ Vision ซึ่งช่วยให้สามารถเรียกใช้โมเดล Core ML ในบริบทของ Vision โดยจัดการประมวลผลภาพล่วงหน้าทั้งหมดที่โมเดล Core ML ต้องการ: การเปลี่ยนขนาด การตัด การทำให้เป็นปกติ และการแปลงพื้นที่สี

หากไม่มี VNCoreMLRequest นักพัฒนาจะต้องแปลง UIImage/CGImage เป็น MultiArray (MLMultiArray) หรือ PixelBuffer (CVPixelBuffer) ด้วยตนเอง VNCoreMLRequest จะทำให้กระบวนการนี้เป็นอัตโนมัติ: คุณส่ง CGImage ผ่าน VNImageRequestHandler และ VNCoreMLRequest จะปรับขนาดให้เหมาะกับอินพุตของโมเดล

VNCoreMLRequest สืบทอดความสามารถทั้งหมดของ VNRequest: ตัวจัดการเสร็จสิ้น regionOfInterest ความสามารถในการดำเนินการหลายคำขอพร้อมกัน การรองรับ VNImageRequestHandler และ VNSequenceRequestHandler

swift
import Vision
import CoreML

// 1. โหลดและห่อหุ้มโมเดล
guard let model = try VNCoreMLModel(
    for: MobileNetV2().model)
else { return }

// 2. สร้าง VNCoreMLRequest
let request = VNCoreMLRequest(model: model) { req, _ in
    guard let results = req.results
        as? [VNClassificationObservation]
    else { return }
    for r in results.prefix(3) {
        print("\\(r.identifier): \\(r.confidence)")
    }
}

// 3. ดำเนินการผ่านตัวจัดการ
let handler = VNImageRequestHandler(cgImage: image, options: [:])
try handler.perform([request])

VNCoreMLRequest รองรับโมเดลที่มีประเภทอินพุตต่างๆ: ภาพ (Image Feature) MultiArray และ Double สำหรับภาพ Vision จะแปลง CGImage เป็น CVPixelBuffer ในขนาดและพื้นที่สีที่ต้องการโดยอัตโนมัติ สำหรับประเภทข้อมูลอินพุตอื่นๆ ให้ใช้ Core ML โดยตรงโดยไม่ต้องผ่าน Vision

จากข้อมูลของ Apple WWDC 2023 VNCoreMLRequest ถูกใช้ใน 40% ของแอป iOS ทั้งหมดที่ใช้ Core ML สำหรับการประมวลผลภาพ นี่เป็นวิธีที่ได้รับความนิยมมากที่สุดในการผนวกโมเดล ML เข้ากับแอป iOS

VNCoreMLModel: ตัวห่อหุ้มเทอร์เหนือโมเดล Core ML

VNCoreMLModel เป็นตัวห่อหุ้มเทอร์ที่ปรับโมเดล Core ML (MLModel) สำหรับใช้ใน Vision โดยแปลงข้อมูลอินพุตและเอาต์พุตของโมเดลให้อยู่ในรูปแบบที่ Vision เข้าใจ: ภาพ → CVPixelBuffer ผลลัพธ์ → VNObservation

การเริ่มต้นของ VNCoreMLModel จะตรวจสอบความเข้ากันได้ของโมเดลกับ Vision: โมเดลต้องรับภาพเป็นอินพุต (Image Feature) และส่งกลับการจัดหมวดหมู่ (MLMultiArray หรือ Dictionary) หากโมเดลไม่เข้ากัน ตัวเริ่มต้นจะแสดงข้อผิดพลาด

swift
import Vision
import CoreML

// ตัวเลือก 1: จาก .mlmodel (คอมไพล์ตอน build)
let model1 = try VNCoreMLModel(
    for: MyVisionModel().model)

// ตัวเลือก 2: จาก .mlmodelc (คอมไพล์บนอุปกรณ์)
let compiledURL = Bundle.main.url(
    forResource: "MyVisionModel",
    withExtension: "mlmodelc")!
let model2 = try VNCoreMLModel(
    for: MLModel(contentsOf: compiledURL))

VNCoreMLModel เก็บแคชโมเดลไว้ในหน่วยความจำหลังจากโหลดครั้งแรก การโหลดโมเดลเดียวกันซ้ำจะส่งคืนอินสแตนซ์ที่แคชไว้ ซึ่งช่วยเร่งคำขอถัดไป อย่างไรก็ตาม หากโมเดลมีขนาดใหญ่กว่า 100 MB iOS อาจนำออกจากหน่วยความจำเมื่อทรัพยากรไม่เพียงพอ — ในกรณีนี้ VNCoreMLModel จะโหลดโมเดลใหม่โดยอัตโนมัติ

สำหรับโมเดลที่ฝึกผ่าน Create ML VNCoreMLModel ทำงานโดยไม่ต้องตั้งค่าเพิ่มเติม Create ML จะส่งออกโมเดลที่มีเมตาดาต้าที่ถูกต้องซึ่ง Vision จดจำได้โดยอัตโนมัติ — เพียงส่งโมเดลไปยัง VNCoreMLModel(model:)

การตั้งค่า imageCropAndScaleOption

imageCropAndScaleOption เป็นคุณสมบัติหลักของ VNCoreMLRequest ที่กำหนดว่า Vision แปลงภาพต้นฉบับให้เหมาะกับขนาดอินพุตของโมเดล Core ML อย่างไร การเลือกตัวเลือกที่ถูกต้องส่งผลโดยตรงต่อความแม่นยำของการจัดหมวดหมู่

.centerCrop ตัดภาพจากศูนย์กลางเป็นสี่เหลี่ยมจัตุรัส จากนั้นปรับขนาดเป็นขนาดอินพุตของโมเดล เหมาะสำหรับโมเดลที่ฝึกบนวัตถุที่อยู่กึ่งกลาง (ส่วนใหญ่ของตัวแยกประเภท ImageNet) .scaleFill ยืดภาพไปยังขนาดอินพุตโดยไม่รักษาสัดส่วน รวดเร็ว แต่บิดเบือนรูปทรง .scaleFit ปรับขนาดโดยรักษาสัดส่วน เพิ่ม letterbox (แถบสีดำ) ที่ขอบ

swift
import Vision

let request = VNCoreMLRequest(model: model)

// .centerCrop — สำหรับวัตถุที่อยู่กึ่งกลาง (ค่าเริ่มต้น)
request.imageCropAndScaleOption = .centerCrop

// .scaleFill — สำหรับพื้นผิวที่สม่ำเสมอ (ไม่บิดเบือน)
request.imageCropAndScaleOption = .scaleFill

// .scaleFit — เมื่อสัดส่วนของวัตถุมีความสำคัญ
request.imageCropAndScaleOption = .scaleFit

คำแนะนำ: สำหรับโมเดลการจัดหมวดหมู่ส่วนใหญ่ ให้ใช้ .centerCrop — ให้ความสมดุลที่ดีที่สุดระหว่างความแม่นยำและประสิทธิภาพ หากโมเดลถูกฝึกบนภาพที่มีสัดส่วนที่ถูกรักษาไว้ (เช่น การตรวจจับความผิดปกติบนภาพถ่ายเอกสาร) ให้เลือก .scaleFit กับ letterbox

จากข้อมูลของ Apple Developer Documentation 2024 การเลือก imageCropAndScaleOption ที่ไม่ถูกต้องสามารถลดความแม่นยำของโมเดลได้ 15–25% ตัวอย่างเช่น .scaleFill สำหรับใบหน้าที่อยู่ขอบภาพอาจตัดส่วนหนึ่งของมันด้วย .centerCrop หรือบิดเบือนสัดส่วนด้วย .scaleFill

การรวมกับ VNRequest อื่นๆ

จุดแข็งหลัก ของ VNCoreMLRequest คือความสามารถในการรวมกับ VNRequest อื่นๆ ในการเรียก perform() เดียวกัน ซึ่งช่วยให้สามารถสร้างไปป์ไลน์: เริ่มจากการตรวจจับใบหน้า (VNDetectFaceRectanglesRequest) จากนั้นจัดหมวดหมู่แต่ละใบหน้าผ่านโมเดล Core ML ที่กำหนดเอง (VNCoreMLRequest)

VNCoreMLRequest รองรับ regionOfInterest ด้วย — หากคุณตั้งค่าพื้นที่นี้ Vision จะตัดภาพตามสี่เหลี่ยมผืนผ้าที่ระบุก่อนส่งต่อไปยังโมเดล Core ML ซึ่งมีความสำคัญอย่างยิ่งสำหรับไปป์ไลน์: หลังจากการตรวจจับใบหน้า คุณจะส่งกรอบขอบเขตของมันเป็น regionOfInterest สำหรับ VNCoreMLRequest

swift
import Vision

// 1. การตรวจจับใบหน้า
let faceRequest = VNDetectFaceRectanglesRequest()

// 2. การจัดหมวดหมู่อารมณ์ผ่าน Core ML
guard let emotionModel = try VNCoreMLModel(
    for: EmotionClassifier().model)
else { return }

let emotionRequest = VNCoreMLRequest(model: emotionModel)
try handler.perform([faceRequest, emotionRequest])

// 3. ตั้งค่า regionOfInterest สำหรับแต่ละใบหน้า
for face in faceRequest.results as? [VNFaceObservation] ?? [] {
    emotionRequest.regionOfInterest = face.boundingBox
    try handler.perform([emotionRequest])
    // ประมวลผลผลลัพธ์การจัดหมวดหมู่อารมณ์
}

ข้อจำกัด: regionOfInterest สำหรับ VNCoreMLRequest จะมีประโยชน์เมื่อโมเดลถูกฝึกบนภาพที่มีขนาดและสัดส่วนเดียวกัน หากโมเดลต้องการอินพุตสี่เหลี่ยมจัตุรัสอย่างเคร่งครัด (224x224) .centerCrop กับ regionOfInterest จะให้ผลลัพธ์ที่ดีที่สุด

จากงานวิจัยของ Apple ML Research ไปป์ไลน์ "การตรวจจับ → การจัดหมวดหมู่" ผ่าน regionOfInterest ช่วยเพิ่มความแม่นยำได้ 20–30% เมื่อเทียบกับการจัดหมวดหมู่ภาพทั้งหมด เนื่องจากโมเดล ML ได้รับเฉพาะพื้นที่ที่เกี่ยวข้องโดยไม่มีสัญญาณรบกวนพื้นหลัง

ประเภทไปป์ไลน์คำขอ 1 (การตรวจจับ)คำขอ 2 (ML)ตัวอย่าง
ใบหน้า → อารมณ์VNDetectFaceRectanglesRequestVNCoreMLRequestการตรวจจับอารมณ์
วัตถุ → แบรนด์VNDetectObjectAtPointRequestVNCoreMLRequestการรู้จำโลโก้
ข้อความ → ภาษาVNRecognizeTextRequestVNCoreMLRequestการจัดหมวดหมู่ภาษาข้อความ
ฉาก → คำอธิบายVNClassifyImageRequestVNCoreMLRequestการสร้างแท็ก

การประมวลผลลัพธ์ VNCoreMLRequest

VNCoreMLRequest ส่งคืนผลลัพธ์ในรูปแบบ VNClassificationObservation (สำหรับโมเดลการจัดหมวดหมู่) หรือ VNCoreMLFeatureValueObservation (สำหรับการถดถอยและประเภทอื่นๆ) โดยประเภทของผลลัพธ์ขึ้นอยู่กับข้อมูลเอาต์พุตของโมเดล Core ML

VNClassificationObservation ประกอบด้วย identifier (ชื่อคลาส) และ confidence โมเดลที่มีเอาต์พุต softmax จะส่งคืนอาร์เรย์ของการสังเกตเหล่านี้ที่เรียงลำดับตาม confidence จากมากไปน้อย VNCoreMLFeatureValueObservation ประกอบด้วย MLFeatureValue ที่กำหนดเอง — สามารถเป็น MultiArray Double String หรือ Dictionary

swift
// สำหรับโมเดลการจัดหมวดหมู่
if let classificationResults = request.results
    as? [VNClassificationObservation] {
    for result in classificationResults
        where result.confidence > 0.5 {
        print("\\(result.identifier): \\(result.confidence)")
    }
}

// สำหรับโมเดลการถดถอย (ค่าคุณลักษณะ)
if let featureResults = request.results
    as? [VNCoreMLFeatureValueObservation] {
    for result in featureResults {
        let value = result.featureValue
        print("\\(result.featureName): \\(value)")
    }
}

การกรองตาม confidence: Apple แนะนำให้ทิ้งผลลัพธ์ที่มี confidence < 0.3 สำหรับตัวแยกประเภททั่วไปและ < 0.7 สำหรับแอปพลิเคชันที่สำคัญ สำหรับโมเดลที่ฝึกบนชุดข้อมูลที่สมดุล confidence จะสัมพันธ์กับความน่าจะเป็นของคำตอบที่ถูกต้องแต่ไม่รับประกัน

VNCoreMLFeatureValueObservation.featureName ตรงกับชื่อเลเยอร์เอาต์พุตของโมเดล (เช่น "classLabel" หรือ "features") ซึ่งช่วยให้สามารถจัดการกับโมเดลที่มีหลายเอาต์พุต — แต่ละเอาต์พุตจะแสดงด้วย observation แยกต่างหากที่มี featureName ไม่ซ้ำกัน

แนวทางปฏิบัติที่ดีและประสิทธิภาพ

VNCoreMLRequest ได้รับการปรับแต่งเพื่อทำงานบน Neural Engine (A12+) GPU และ CPU โดย Vision จะเลือกอุปกรณ์ที่ดีที่สุดสำหรับการดำเนินการโมเดลโดยอัตโนมัติขึ้นอยู่กับประเภทและขนาดของโมเดล อย่างไรก็ตาม ประสิทธิภาพสามารถปรับปรุงเพิ่มเติมได้ด้วยการตั้งค่าที่เหมาะสม

การจัดการหน่วยความจำ

โมเดล Core ML จะถูกโหลดเข้าสู่หน่วยความจำเมื่อ VNCoreMLRequest ครั้งแรกและจะอยู่ที่นั่นจนกว่าจะมีการโหลดแอปออก สำหรับโมเดลที่มีขนาดใหญ่กว่า 200 MB Apple แนะนำให้โหลดตามความต้องการและนำออกผ่าน MLModel.release() โดย VNCoreMLModel จัดการแคชเอง แต่คุณสามารถควบคุมระบบนี้ผ่าน autoreleasepool

การประมวลผลแบบแบตช์

สำหรับการประมวลผลแบบแบตช์ ของภาพ ให้สร้าง VNCoreMLRequest หนึ่งตัวและใช้ซ้ำกับ VNImageRequestHandler ที่แตกต่างกัน อย่าสร้าง VNCoreMLRequest ใหม่สำหรับแต่ละภาพ — สิ่งนี้จะทำให้การประมวลผลช้าลงเนื่องจากการโหลดโมเดลซ้ำๆ การใช้คำขอซ้ำช่วยเพิ่มประสิทธิภาพได้มากถึง 40% เมื่อประมวลผล 10+ ภาพ

swift
// ถูกต้อง: คำขอเดียวสำหรับทุกภาพ
let batchSize = 20
let batchRequest = VNCoreMLRequest(model: model)

for i in 0..<batchSize {
    let handler = VNImageRequestHandler(
        cgImage: images[i],
        options: [:])
    try handler.perform([batchRequest])
    // batchRequest.results อัปเดตในทุกการเรียก
}

การเลือกอุปกรณ์: โดยค่าเริ่มต้น Vision จะเลือก Neural Engine สำหรับโมเดลที่เข้ากันได้บนอุปกรณ์ A12+ หากโมเดลไม่รองรับ Neural Engine Vision จะใช้ GPU หรือ CPU คุณสามารถบังคับระบุอุปกรณ์ผ่าน MLModelConfiguration.computeUnits แต่ Apple แนะนำให้ปล่อยให้เป็นแบบอัตโนมัติ

จากข้อมูลของ Apple Performance Benchmarks 2024 VNCoreMLRequest บน Neural Engine (iPhone 15 Pro) ดำเนินการจัดหมวดหมู่ MobileNetV2 ภายใน 3–5 มิลลิวินาที บน GPU — 8–12 มิลลิวินาที บน CPU — 20–30 มิลลิวินาที ความแตกต่างนี้มีความสำคัญมากสำหรับแอปแบบเรียลไทม์ที่ประมวลผล 30+ เฟรมต่อวินาที

คำถามที่พบบ่อย

สามารถใช้ VNCoreMLRequest โดยไม่ต้องใช้ Vision — โดยตรงกับ Core ML ได้หรือไม่?

ได้ Core ML สามารถใช้งานโดยตรงผ่าน MLModel.prediction() โดยไม่ต้องใช้ Vision อย่างไรก็ตาม VNCoreMLRequest จะทำให้การประมวลผลภาพล่วงหน้า (การปรับขนาด การตัด การแปลงเป็น CVPixelBuffer) เป็นอัตโนมัติ หากโมเดลรับไม่ใช่ภาพแต่เป็น MultiArray หรือ Double — ให้ใช้ Core ML โดยตรง VNCoreMLRequest สำหรับโมเดลที่มี Image Feature เป็นอินพุตเท่านั้น

จะอัปเดต VNCoreMLRequest เมื่อมีเวอร์ชันใหม่ของโมเดลได้อย่างไร?

สร้าง VNCoreMLModel ใหม่จาก MLModel ที่อัปเดตและ VNCoreMLRequest ใหม่ คำขอเก่าจะใช้โมเดลเวอร์ชันเก่าต่อไป สำหรับการอัปเดตโมเดลระยะไกล ให้ใช้ MLModel.compileModel(at:) สำหรับการคอมไพล์โมเดลบนอุปกรณ์จากไฟล์ .mlmodelc ที่ดาวน์โหลดจากเซิร์ฟเวอร์

VNCoreMLRequest รองรับโมเดลที่มีหลายอินพุตหรือไม่?

VNCoreMLRequest รองรับเฉพาะโมเดลที่มีอินพุต Image Feature เดียว หากโมเดลมีหลายอินพุต (เช่น ภาพ + ข้อความ) ให้ใช้ Core ML โดยตรงผ่าน MLModel Vision ไม่สามารถส่งพารามิเตอร์เพิ่มเติมนอกเหนือจากภาพได้

ขนาดภาพสูงสุดสำหรับ VNCoreMLRequest คือเท่าไร?

ข้อจำกัดคือ 8192 x 8192 พิกเซล สำหรับ CGImage ที่ส่งไปยัง VNImageRequestHandler อย่างไรก็ตาม โมเดล Core ML โดยทั่วไปคาดหวังอินพุต 224x224 299x299 หรือ 512x512 Vision จะปรับขนาดภาพใหญ่โดยอัตโนมัติให้เหมาะกับขนาดอินพุต หากภาพต้นฉบับใหญ่เกินไป ให้ลดขนาดล่วงหน้าผ่าน CGImage เพื่อประหยัดหน่วยความจำ

สามารถเรียกใช้ VNCoreMLRequest ในพื้นหลังได้หรือไม่?

ได้ โดยตั้งค่า preferBackgroundProcessing = true ใน VNRequest ซึ่งจะช่วยให้ Vision สามารถเลื่อนการดำเนินการคำขอได้หากระบบอยู่ในโหมดที่ใช้ทรัพยากรมาก (เช่น การโหลดเนื้อหา) นอกจากนี้ ต้องใช้ DispatchQueue.global(qos: .background) สำหรับการเรียก handler.perform()

สรุป

  • VNCoreMLRequest — คลาสย่อยของ VNRequest สำหรับเรียกใช้โมเดล Core ML ในไปป์ไลน์ Vision พร้อมการประมวลผลภาพล่วงหน้าโดยอัตโนมัติ
  • VNCoreMLModel ห่อหุ้ม MLModel สำหรับ Vision โดยแปลง CGImage เป็น CVPixelBuffer ในขนาดและพื้นที่สีที่ต้องการโดยอัตโนมัติ
  • imageCropAndScaleOption (centerCrop scaleFill scaleFit) กำหนดกลยุทธ์การปรับขนาดและส่งผลต่อความแม่นยำของโมเดล 15–25%
  • การรวม กับ VNDetectFaceRectanglesRequest และ VNRequest อื่นๆ ช่วยให้สร้างไปป์ไลน์ "การตรวจจับ → การจัดหมวดหมู่" ผ่าน regionOfInterest
  • ผลลัพธ์จะถูกส่งคืนเป็น VNClassificationObservation (สำหรับการจัดหมวดหมู่) หรือ VNCoreMLFeatureValueObservation (สำหรับการถดถอย/ประเภทอื่นๆ)
  • การใช้ซ้ำ VNCoreMLRequest เดียวสำหรับการประมวลผลแบบแบตช์ช่วยเพิ่มประสิทธิภาพได้มากถึง 40% เมื่อเทียบกับการสร้างใหม่สำหรับแต่ละภาพ
  • ประสิทธิภาพบน Neural Engine (3–5 มิลลิวินาทีบน MobileNetV2) สูงกว่าบน CPU 4–6 เท่า ซึ่งสำคัญสำหรับแอปแบบเรียลไทม์

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม