VNCoreMLRequest — ce este, cererea Vision pentru Core ML în iOS

Autor: IT Sectr Publicat: 2026-07-20 Timp de citire: 8 min

VNCoreMLRequest — este o subclasă a VNRequest care permite rularea modelelor Core ML în pipeline-ul Vision, combinând avantajele detectoarelor gata făcute Vision (fețe, text, obiecte) cu modele ML personalizate pentru clasificare și regresie. Conform Apple Machine Learning Documentation (2024), VNCoreMLRequest procesează automat preprocesarea imaginii — scalare, decupare și conversia spațiului de culoare — în conformitate cu cerințele modelului Core ML.

Principalele puncte

  • VNCoreMLRequest — puntea între Core ML și Vision: modelul ML funcționează ca o cerere Vision.
  • Preprocesarea automată a imaginilor: scalare, decupare și corecție de culoare conform cerințelor modelului.
  • Se combină cu alte VNRequest într-un singur perform() pentru construirea de pipeline-uri.
  • Suportă VNCoreMLModel — un wrapper peste MLModel pentru lucrul cu imagini și FeatureValue.
  • Funcționează pe Neural Engine și GPU pentru performanță maximă.

Ce este VNCoreMLRequest?

VNCoreMLRequest — este o subclasă VNRequest, adăugată în iOS 11 odată cu Vision, care permite rularea modelelor Core ML în contextul Vision. Preia întregul preproces al imaginii necesar modelului Core ML: redimensionare, decupare, normalizare și conversia spațiului de culoare.

Fără VNCoreMLRequest, dezvoltatorul ar trebui să convertească manual UIImage/CGImage în MultiArray (MLMultiArray) sau PixelBuffer (CVPixelBuffer) de dimensiunea necesară. VNCoreMLRequest automatizează acest proces: transmiteți CGImage prin VNImageRequestHandler, iar VNCoreMLRequest îl scalează la dimensiunea de intrare a modelului.

VNCoreMLRequest moștenește toate capacitățile VNRequest: completion handler, regionOfInterest, posibilitatea de a executa mai multe cereri simultan, suport pentru VNImageRequestHandler și VNSequenceRequestHandler.

swift
import Vision
import CoreML

// 1. Încărcați și înfășurați modelul
guard let model = try VNCoreMLModel(
    for: MobileNetV2().model)
else { return }

// 2. Creați 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. Executați prin handler
let handler = VNImageRequestHandler(cgImage: image, options: [:])
try handler.perform([request])

VNCoreMLRequest suportă modele cu diverse tipuri de intrare: imagini (Image Feature), MultiArray și Double. Pentru imagini, Vision convertește automat CGImage în CVPixelBuffer de dimensiunea și spațiul de culoare necesare. Pentru alte tipuri de date de intrare, trebuie să utilizați Core ML direct fără Vision.

Conform Apple WWDC 2023, VNCoreMLRequest este utilizat în 40% din toate aplicațiile iOS care folosesc Core ML pentru lucrul cu imagini. Este cea mai populară modalitate de integrare a modelelor ML în aplicațiile iOS.

VNCoreMLModel: wrapper peste modelul Core ML

VNCoreMLModel — este un wrapper care adaptează modelul Core ML (MLModel) pentru utilizarea în Vision. Convertește datele de intrare și ieșire ale modelului în formatul înțeles de Vision: imagine → CVPixelBuffer, rezultat → VNObservation.

Inițializarea VNCoreMLModel verifică compatibilitatea modelului cu Vision: modelul trebuie să accepte o imagine la intrare (Image Feature) și să returneze o clasificare (MLMultiArray sau Dictionary). Dacă modelul este incompatibil, inițializatorul aruncă o eroare.

swift
import Vision
import CoreML

// Opțiunea 1: Din .mlmodel (compilat la timpul construirii)
let model1 = try VNCoreMLModel(
    for: MyVisionModel().model)

// Opțiunea 2: Din .mlmodelc (compilat pe dispozitiv)
let compiledURL = Bundle.main.url(
    forResource: "MyVisionModel",
    withExtension: "mlmodelc")!
let model2 = try VNCoreMLModel(
    for: MLModel(contentsOf: compiledURL))

VNCoreMLModel stochează în cache modelul în memorie după prima încărcare. Reîncărcarea aceluiași model returnează instanța din cache, ceea ce accelerează cererile ulterioare. Cu toate acestea, dacă modelul căntărește peste 100 MB, iOS poate să-l descarce din memorie la lipsă de resurse — în acest caz, VNCoreMLModel reîncarcă modelul automat.

Pentru modelele antrenate prin Create ML, VNCoreMLModel funcționează fără configurare suplimentară. Create ML exportă modelele cu metadatele corecte pe care Vision le recunoaște automat — este suficient să transmiteți modelul la VNCoreMLModel(model:).

Configurarea imageCropAndScaleOption

imageCropAndScaleOption — proprietatea cheie a VNCoreMLRequest care determină cum transformă Vision imaginea originală la dimensiunea de intrare a modelului Core ML. Alegerea opțiunii corecte influențează direct acuratețea clasificării.

.centerCrop — decupează imaginea central în pătrat, apoi o scalează la dimensiunea de intrare a modelului. Potrivit pentru modele antrenate pe obiecte centrate (majoritatea clasificatoarelor ImageNet). .scaleFill — întinde imaginea la dimensiunea de intrare fără a păstra proporțiile. Rapid, dar deformează geometria. .scaleFit — scalează păstrând proporțiile, adăugând letterbox (benzi negre) pe margini.

swift
import Vision

let request = VNCoreMLRequest(model: model)

// .centerCrop — pentru obiecte centrate (implicit)
request.imageCropAndScaleOption = .centerCrop

// .scaleFill — pentru texturi uniforme (fără distorsiuni)
request.imageCropAndScaleOption = .scaleFill

// .scaleFit — când proporțiile obiectului contează
request.imageCropAndScaleOption = .scaleFit

Recomandări: pentru majoritatea modelelor de clasificare, utilizați .centerCrop — oferă cel mai bun raport acuratețe-performanță. Dacă modelul a fost antrenat pe imagini cu păstrarea proporțiilor (de exemplu, detectarea anomaliiilor pe fotografii de documente), alegeți .scaleFit cu letterbox.

Conform Apple Developer Documentation 2024, alegerea incorectă a imageCropAndScaleOption poate reduce acuratețea modelului cu 15–25%. De exemplu, .scaleFill pentru o față situată la marginea cadrului poate decupa o parte din ea la .centerCrop sau deforma proporțiile la .scaleFill.

Combinarea cu alte VNRequest

Principala putere a VNCoreMLRequest — posibilitatea de a-l combina cu alte VNRequest într-o singură apelare perform(). Aceasta permite construirea de pipeline-uri: mai întâi găsiți fețe (VNDetectFaceRectanglesRequest), apoi clasificați fiecare față printr-un model Core ML personalizat (VNCoreMLRequest).

VNCoreMLRequest suportă, de asemenea, regionOfInterest — dacă setați această regiune, Vision decupează imaginea la dreptunghiul specificat înainte de a o transmite modelului Core ML. Acest lucru este critic pentru pipeline-uri: după detectarea feței, transmiteți bounding box-ul acesteia ca regionOfInterest pentru VNCoreMLRequest.

swift
import Vision

// 1. Detectarea feței
let faceRequest = VNDetectFaceRectanglesRequest()

// 2. Clasificarea emoțiilor prin Core ML
guard let emotionModel = try VNCoreMLModel(
    for: EmotionClassifier().model)
else { return }

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

// 3. Setați regionOfInterest pentru fiecare față
for face in faceRequest.results as? [VNFaceObservation] ?? [] {
    emotionRequest.regionOfInterest = face.boundingBox
    try handler.perform([emotionRequest])
    // Procesați rezultatul clasificării emoțiilor
}

Limitare: regionOfInterest pentru VNCoreMLRequest are sens când modelul a fost antrenat pe imagini de aceeași dimensiune și proporții. Dacă modelul așteaptă o intrare strict pătrată (224x224), .centerCrop cu regionOfInterest va da cel mai bun rezultat.

Conform Apple ML Research, pipeline-ul «detecție → clasificare» prin regionOfInterest oferă o creștere a acurateței de 20–30% comparativ cu clasificarea întregii imagini, deoarece modelul ML primește la intrare doar regiunea relevantă fără zgomot de fundal.

Tip pipelineCererea 1 (detecție)Cererea 2 (ML)Exemplu
Față → emoțieVNDetectFaceRectanglesRequestVNCoreMLRequestDeterminarea dispoziției
Obiect → marcăVNDetectObjectAtPointRequestVNCoreMLRequestRecunoașterea logo-urilor
Text → limbăVNRecognizeTextRequestVNCoreMLRequestClasificarea limbii textului
Scenă → descriereVNClassifyImageRequestVNCoreMLRequestGenerarea de tag-uri

Procesarea rezultatelor VNCoreMLRequest

VNCoreMLRequest returnează rezultatele sub formă de VNClassificationObservation (pentru modele de clasificare) sau VNCoreMLFeatureValueObservation (pentru regresie și alte tipuri). Tipul rezultatului depinde de datele de ieșire ale modelului Core ML.

VNClassificationObservation conține identifier (numele clasei) și confidence (încredere). Modelele cu ieșire softmax returnează un tablou de astfel de observații sortate descrescător după confidence. VNCoreMLFeatureValueObservation conține o valoare arbitrară MLFeatureValue — poate fi MultiArray, Double, String sau Dictionary.

swift
// Pentru modele de clasificare
if let classificationResults = request.results
    as? [VNClassificationObservation] {
    for result in classificationResults
        where result.confidence > 0.5 {
        print("\\(result.identifier): \\(result.confidence)")
    }
}

// Pentru modele de regresie (valori ale caracteristicilor)
if let featureResults = request.results
    as? [VNCoreMLFeatureValueObservation] {
    for result in featureResults {
        let value = result.featureValue
        print("\\(result.featureName): \\(value)")
    }
}

Filtrarea după confidence: Apple recomandă eliminarea rezultatelor cu confidence < 0.3 pentru clasificatoare generale și < 0.7 pentru aplicații critice. Pentru modele antrenate pe seturi de date echilibrate, confidence corelează cu probabilitatea de răspuns corect, dar nu o garantează.

VNCoreMLFeatureValueObservation.featureName corespunde numelui stratului de ieșire al modelului (de exemplu, „classLabel” sau „features”). Aceasta permite procesarea modelelor cu mai multe ieșiri — fiecare ieșire este reprezentată de o observație separată cu un featureName unic.

Cele mai bune practici și performanță

VNCoreMLRequest este optimizat pentru funcționarea pe Neural Engine (A12+), GPU și CPU. Vision alege automat cel mai bun dispozitiv pentru executarea modelului în funcție de tipul și dimensiunea acestuia. Cu toate acestea, performanța poate fi îmbunătățită suplimentar printr-o configurare corectă.

Gestionarea memoriei

Modelele Core ML sunt încărcate în memorie la primul VNCoreMLRequest și rămân acolo până la descărcarea aplicației. Pentru modele mai mari de 200 MB, Apple recomandă încărcarea lor la cerere și eliberarea prin MLModel.release(). VNCoreMLModel gestionează singură cache-ul, dar puteți controla acest lucru prin autoreleasepool.

Procesarea loturilor

Pentru procesarea loturilor de imagini, creați un singur VNCoreMLRequest și reutilizați-l cu diferite VNImageRequestHandler. Nu creați un nou VNCoreMLRequest pentru fiecare imagine — aceasta va încetini procesarea din cauza reîncărcării modelului. Reutilizarea cererii oferă o creștere a performanței de până la 40% la procesarea a 10+ imagini.

swift
// Corect: o singură cerere pentru toate imaginile
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 se actualizează la fiecare apelare
}

Alegerea dispozitivului: în mod implicit, Vision alege Neural Engine pentru modele compatibile pe dispozitive A12+. Dacă modelul nu suportă Neural Engine, Vision folosește GPU sau CPU. Puteți forța un anumit dispozitiv prin MLModelConfiguration.computeUnits, dar Apple recomandă să lăsați alegerea automată.

Conform Apple Performance Benchmarks 2024, VNCoreMLRequest pe Neural Engine (iPhone 15 Pro) procesează clasificarea MobileNetV2 în 3–5 ms, pe GPU — 8–12 ms, pe CPU — 20–30 ms. Diferența devine critică pentru aplicații în timp real care procesează 30+ cadre pe secundă.

Întrebări frecvente

Pot folosi VNCoreMLRequest fără Vision — direct cu Core ML?

Da, Core ML poate fi utilizat direct prin MLModel.prediction(), fără Vision. Cu toate acestea, VNCoreMLRequest automatizează preprocesarea imaginilor (scalare, decupare, conversie în CVPixelBuffer). Dacă modelul nu acceptă o imagine, ci MultiArray sau Double — utilizați Core ML direct. VNCoreMLRequest este doar pentru modele cu Image Feature la intrare.

Cum actualizez VNCoreMLRequest la o nouă versiune a modelului?

Creați un nou VNCoreMLModel din MLModel actualizat și un nou VNCoreMLRequest. Vechea cerere va continua să utilizeze versiunea veche a modelului. Pentru actualizarea de la distanță a modelelor, utilizați MLModel.compileModel(at:) pentru compilarea modelului pe dispozitiv din fișierul .mlmodelc descărcat de pe server.

VNCoreMLRequest suportă modele cu mai multe intrări?

VNCoreMLRequest suportă doar modele cu o singură intrare Image Feature. Dacă modelul are mai multe intrări (de exemplu, imagine + text), utilizați Core ML direct prin MLModel. Vision nu poate transmite parametri suplimentari în afara imaginii.

Care este dimensiunea maximă a imaginii pentru VNCoreMLRequest?

Limitarea — 8192 x 8192 pixeli pentru CGImage transmis la VNImageRequestHandler. Cu toate acestea, modelele Core ML de obicei așteaptă o intrare de 224x224, 299x299 sau 512x512. Vision scalează automat imaginea mare la dimensiunea de intrare. Dacă imaginea originală este prea mare, reduceți-o în prealabil prin CGImage pentru a economisi memorie.

Pot rula VNCoreMLRequest în fundal?

Da, setați preferBackgroundProcessing = true pe VNRequest. Aceasta va permite Vision să amâne executarea cererii dacă sistemul se află într-un mod consumator de resurse (de exemplu, încărcare de conținut). De asemenea, utilizați obligatoriu DispatchQueue.global(qos: .background) pentru apelarea handler.perform().

Rezumat

  • VNCoreMLRequest — subclasă VNRequest pentru rularea modelelor Core ML în pipeline-ul Vision cu preprocesare automată a imaginilor.
  • VNCoreMLModel îmbracă MLModel pentru Vision, convertind automat CGImage în CVPixelBuffer de dimensiunea și spațiul de culoare corespunzătoare.
  • imageCropAndScaleOption (centerCrop, scaleFill, scaleFit) determină strategia de scalare și influențează acuratețea modelului cu 15–25%.
  • Combinarea cu VNDetectFaceRectanglesRequest și alte VNRequest permite construirea de pipeline-uri «detecție → clasificare» cu regionOfInterest.
  • Rezultatele sunt returnate ca VNClassificationObservation (pentru clasificare) sau VNCoreMLFeatureValueObservation (pentru regresie/alte tipuri).
  • Reutilizarea unui singur VNCoreMLRequest pentru procesarea loturilor oferă până la 40% creștere a performanței comparativ cu crearea unuia nou pentru fiecare imagine.
  • Performanța pe Neural Engine (3–5 ms pe MobileNetV2) este de 4–6 ori mai mare decât pe CPU, ceea ce este critic pentru aplicații în timp real.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și