VNCoreMLRequest — είναι μια υποκλάση του VNRequest που επιτρέπει την εκτέλεση μοντέλων Core ML μέσα στο pipeline του Vision, συνδυάζοντας τα πλεονεκτήματα των έτοιμων ανιχνευτών Vision (πρόσωπα, κείμενο, αντικείμενα) με προσαρμοσμένα μοντέλα ML για ταξινόμηση και παλινδρόμηση. Σύμφωνα με το Apple Machine Learning Documentation (2024), το VNCoreMLRequest χειρίζεται αυτόματα την προεπεξεργασία εικόνας — κλιμάκωση, περικοπή και μετατροπή χρωματικού χώρου — σύμφωνα με τις απαιτήσεις του μοντέλου Core ML.
Βασικά σημεία
VNCoreMLRequest — είναι μια υποκλάση του VNRequest, που προστέθηκε στο iOS 11 μαζί με το Vision, η οποία επιτρέπει την εκτέλεση μοντέλων Core ML στο περιβάλλον του Vision. Αναλαμβάνει όλη την προεπεξεργασία εικόνας που απαιτείται για το μοντέλο Core ML: αλλαγή μεγέθους, περικοπή, κανονικοποίηση και μετατροπή χρωματικού χώρου.
Χωρίς VNCoreMLRequest ο προγραμματιστής θα έπρεπε να μετατρέψει χειροκίνητα το UIImage/CGImage σε MultiArray (MLMultiArray) ή PixelBuffer (CVPixelBuffer) του κατάλληλου μεγέθους. Το VNCoreMLRequest αυτοματοποιεί αυτή τη διαδικασία: μεταφέρετε το CGImage μέσω του VNImageRequestHandler και το VNCoreMLRequest το κλιμακώνει μόνο του στην είσοδο του μοντέλου.
VNCoreMLRequest κληρονομεί όλες τις δυνατότητες του VNRequest: completion handler, regionOfInterest, δυνατότητα εκτέλεσης πολλαπλών αιτημάτων ταυτόχρονα, υποστήριξη για VNImageRequestHandler και VNSequenceRequestHandler.
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. Εκτέλεση μέσω του handler
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 (MLModel) για χρήση στο Vision. Μετατρέπει τα δεδομένα εισόδου και εξόδου του μοντέλου σε μορφή κατανοητή από το Vision: εικόνα → CVPixelBuffer, αποτέλεσμα → VNObservation.
Η αρχικοποίηση του VNCoreMLModel ελέγχει τη συμβατότητα του μοντέλου με το Vision: το μοντέλο πρέπει να δέχεται εικόνα ως είσοδο (Image Feature) και να επιστρέφει ταξινόμηση (MLMultiArray ή Dictionary). Εάν το μοντέλο δεν είναι συμβατό, ο αρχικοποιητής εκπέμπει σφάλμα.
import Vision
import CoreML
// Επιλογή 1: Από .mlmodel (μεταγλωττισμένο κατά τη δημιουργία)
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 — βασική ιδιότητα του VNCoreMLRequest που καθορίζει πώς το Vision μετασχηματίζει την αρχική εικόνα στο μέγεθος εισόδου του μοντέλου Core ML. Η σωστή επιλογή της επιλογής επηρεάζει άμεσα την ακρίβεια της ταξινόμησης.
.centerCrop — περικόπτει την εικόνα από το κέντρο σε τετράγωνο και στη συνέχεια κλιμακώνει στο μέγεθος εισόδου του μοντέλου. Κατάλληλο για μοντέλα που εκπαιδεύτηκαν σε κεντραρισμένα αντικείμενα (οι περισσότεροι ταξινομητές ImageNet). .scaleFill — τεντώνει την εικόνα στο μέγεθος εισόδου χωρίς διατήρηση αναλογιών. Γρήγορο, αλλά παραμορφώνει τη γεωμετρία. .scaleFit — κλιμακώνει με διατήρηση αναλογιών, προσθέτοντας letterbox (μαύρες λωρίδες) στις άκρες.
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.
Κύρια δύναμη του VNCoreMLRequest — η δυνατότητα συνδυασμού του με άλλα VNRequest σε μία κλήση perform(). Αυτό επιτρέπει τη δημιουργία pipelines: πρώτα εντοπισμός προσώπων (VNDetectFaceRectanglesRequest), στη συνέχεια ταξινόμηση κάθε προσώπου μέσω προσαρμοσμένου μοντέλου Core ML (VNCoreMLRequest).
VNCoreMLRequest υποστηρίζει επίσης το regionOfInterest — αν ορίσετε αυτή την περιοχή, το Vision θα περικόψει την εικόνα στο καθορισμένο ορθογώνιο πριν τη μεταφέρει στο μοντέλο Core ML. Αυτό είναι κρίσιμο για pipelines: μετά τον εντοπισμό προσώπου, μεταφέρετε το bounding box του ως regionOfInterest για το VNCoreMLRequest.
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, το pipeline 'ανίχνευση → ταξινόμηση' μέσω regionOfInterest δίνει αύξηση ακρίβειας 20–30% σε σύγκριση με την ταξινόμηση ολόκληρης της εικόνας, καθώς το μοντέλο ML λαμβάνει μόνο τη σχετική περιοχή χωρίς θόρυβο φόντου.
| Τύπος Pipeline | Αίτημα 1 (ανίχνευση) | Αίτημα 2 (ML) | Παράδειγμα |
|---|---|---|---|
| Πρόσωπο → συναίσθημα | VNDetectFaceRectanglesRequest | VNCoreMLRequest | Προσδιορισμός διάθεσης |
| Αντικείμενο → μάρκα | VNDetectObjectAtPointRequest | VNCoreMLRequest | Αναγνώριση λογότυπων |
| Κείμενο → γλώσσα | VNRecognizeTextRequest | VNCoreMLRequest | Ταξινόμηση γλώσσας κειμένου |
| Σκηνή → περιγραφή | VNClassifyImageRequest | VNCoreMLRequest | Δημιουργία ετικετών |
VNCoreMLRequest επιστρέφει αποτελέσματα με τη μορφή VNClassificationObservation (για μοντέλα ταξινόμησης) ή VNCoreMLFeatureValueObservation (για παλινδρόμηση και άλλους τύπους). Ο τύπος αποτελέσματος εξαρτάται από τα δεδομένα εξόδου του μοντέλου Core ML.
VNClassificationObservation περιέχει το identifier (όνομα κλάσης) και confidence (βεβαιότητα). Τα μοντέλα με έξοδο softmax επιστρέφουν μια συστοιχία τέτοιων παρατηρήσεων, ταξινομημένων κατά φθίνουσα confidence. VNCoreMLFeatureValueObservation περιέχει μια αυθαίρετη τιμή MLFeatureValue — μπορεί να είναι MultiArray, Double, String ή Dictionary.
// Για μοντέλα ταξινόμησης
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+ εικόνων.
// Σωστά: ένα αίτημα για όλες τις εικόνες
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 ms, στο GPU — 8–12 ms, στο CPU — 20–30 ms. Η διαφορά γίνεται κρίσιμη για εφαρμογές πραγματικού χρόνου που επεξεργάζονται 30+ καρέ ανά δευτερόλεπτο.
Συχνές Ερωτήσεις
Ναι, το Core ML μπορεί να χρησιμοποιηθεί απευθείας μέσω του MLModel.prediction(), χωρίς Vision. Ωστόσο, το VNCoreMLRequest αυτοματοποιεί την προεπεξεργασία εικόνας (κλιμάκωση, περικοπή, μετατροπή σε CVPixelBuffer). Εάν το μοντέλο δέχεται όχι εικόνα, αλλά MultiArray ή Double — χρησιμοποιήστε το Core ML απευθείας. Το VNCoreMLRequest είναι μόνο για μοντέλα με Image Feature στην είσοδο.
Δημιουργήστε ένα νέο VNCoreMLModel από το ενημερωμένο MLModel και ένα νέο VNCoreMLRequest. Το παλιό αίτημα θα συνεχίσει να χρησιμοποιεί την παλιά έκδοση του μοντέλου. Για απομακρυσμένη ενημέρωση μοντέλων, χρησιμοποιήστε το MLModel.compileModel(at:) για μεταγλώττιση του μοντέλου στη συσκευή από το αρχείο .mlmodelc που λήφθηκε από τον διακομιστή.
VNCoreMLRequest υποστηρίζει μόνο μοντέλα με μία είσοδο Image Feature. Εάν ένα μοντέλο έχει πολλαπλές εισόδους (για παράδειγμα, εικόνα + κείμενο), χρησιμοποιήστε το Core ML απευθείας μέσω MLModel. Το Vision δεν μπορεί να μεταφέρει πρόσθετες παραμέτρους εκτός από την εικόνα.
Το όριο είναι 8192 x 8192 pixel για CGImage που μεταφέρεται στο VNImageRequestHandler. Ωστόσο, τα μοντέλα Core ML συνήθως αναμένουν είσοδο 224x224, 299x299 ή 512x512. Το Vision κλιμακώνει αυτόματα τη μεγάλη εικόνα στο μέγεθος εισόδου. Εάν η αρχική εικόνα είναι πολύ μεγάλη, μειώστε την εκ των προτέρων μέσω CGImage για εξοικονόμηση μνήμης.
Ναι, ορίστε preferBackgroundProcessing = true στο VNRequest. Αυτό θα επιτρέψει στο Vision να καθυστερήσει την εκτέλεση του αιτήματος εάν το σύστημα βρίσκεται σε λειτουργία έντονης χρήσης πόρων (για παράδειγμα, φόρτωση περιεχομένου). Επίσης, είναι υποχρεωτική η χρήση του DispatchQueue.global(qos: .background) για την κλήση του handler.perform().
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης