VNCoreMLRequest — co to je, Vision požadavek pro Core ML v iOS

Autor: IT Sectr Publikováno: 2026-07-20 Doba čtení: 8 min

VNCoreMLRequest — je podtřída VNRequest, která umožňuje spouštět modely Core ML v rámci pipeline Vision, kombinující výhody hotových detektorů Vision (obličeje, text, objekty) s vlastními ML modely pro klasifikaci a regresi. Podle Apple Machine Learning Documentation (2024) VNCoreMLRequest automaticky zpracovává předzpracování obrazu — změnu měřítka, oříznutí a převod barevného prostoru — v souladu s požadavky modelu Core ML.

Hlavní body

  • VNCoreMLRequest — most mezi Core ML a Vision: ML model funguje jako Vision požadavek.
  • Automatické předzpracování obrazu: změna měřítka, oříznutí a korekce barev podle požadavků modelu.
  • Kombinovatelný s dalšími VNRequest v jednom perform() pro vytváření pipeline.
  • Podporuje VNCoreMLModel — obal kolem MLModel pro práci s obrázky a FeatureValue.
  • Pracuje na Neural Engine a GPU pro maximální výkon.

Co je VNCoreMLRequest?

VNCoreMLRequest — je podtřída VNRequest, přidaná v iOS 11 spolu s Vision, která umožňuje spouštět modely Core ML v kontextu Vision. Převzímá veškeré předzpracování obrazu potřebné pro model Core ML: změnu velikosti, oříznutí, normalizaci a převod barevného prostoru.

Bez VNCoreMLRequest by vývojář musel ručně převádět UIImage/CGImage na MultiArray (MLMultiArray) nebo PixelBuffer (CVPixelBuffer) požadované velikosti. VNCoreMLRequest tento proces automatizuje: předáte CGImage přes VNImageRequestHandler a VNCoreMLRequest jej sám změní na vstup modelu.

VNCoreMLRequest dědí všechny schopnosti VNRequest: completion handler, regionOfInterest, možnost provádět několik požadavků současně, podporu VNImageRequestHandler a VNSequenceRequestHandler.

swift
import Vision
import CoreML

// 1. Načtení a zabalení modelu
guard let model = try VNCoreMLModel(
    for: MobileNetV2().model)
else { return }

// 2. Vytvoření 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. Provedení přes handler
let handler = VNImageRequestHandler(cgImage: image, options: [:])
try handler.perform([request])

VNCoreMLRequest podporuje modely s různými typy vstupu: obrázky (Image Feature), MultiArray a Double. Pro obrázky Vision automaticky převádí CGImage na CVPixelBuffer požadované velikosti a barevného prostoru. Pro jiné typy vstupních dat musíte použít Core ML přímo bez Vision.

Podle Apple WWDC 2023 se VNCoreMLRequest používá ve 40% všech iOS aplikací, které používají Core ML pro práci s obrázky. Toto je nejoblíbenější způsob integrace ML modelů do iOS aplikací.

VNCoreMLModel: obal kolem modelu Core ML

VNCoreMLModel — je obal, který přizpůsobuje model Core ML (MLModel) pro použití ve Vision. Převádí vstupní a výstupní data modelu do formátu srozumitelného pro Vision: obrázek → CVPixelBuffer, výsledek → VNObservation.

Inicializace VNCoreMLModel kontroluje kompatibilitu modelu s Vision: model musí přijímat obrázek jako vstup (Image Feature) a vracet klasifikaci (MLMultiArray nebo Dictionary). Pokud model není kompatibilní, inicializátor vyvolá chybu.

swift
import Vision
import CoreML

// Možnost 1: Z .mlmodel (zkompilováno při sestavení)
let model1 = try VNCoreMLModel(
    for: MyVisionModel().model)

// Možnost 2: Z .mlmodelc (zkompilováno na zařízení)
let compiledURL = Bundle.main.url(
    forResource: "MyVisionModel",
    withExtension: "mlmodelc")!
let model2 = try VNCoreMLModel(
    for: MLModel(contentsOf: compiledURL))

VNCoreMLModel ukládá model do mezipaměti po prvním načtení. Opětovné načtení stejného modelu vrátí uloženou instanci, což urychluje následující požadavky. Pokud však model váží více než 100 MB, iOS jej může uvolnit z paměti při nedostatku zdrojů — v tomto případě VNCoreMLModel model automaticky znovu načte.

Pro modely natrénované pomocí Create ML funguje VNCoreMLModel bez dodatečné konfigurace. Create ML exportuje modely se správnými metadaty, která Vision automaticky rozpozná — stačí předat model do VNCoreMLModel(model:).

Nastavení imageCropAndScaleOption

imageCropAndScaleOption — klíčová vlastnost VNCoreMLRequest, která určuje, jak Vision transformuje původní obrázek na velikost vstupu modelu Core ML. Správná volba možnosti přímo ovlivňuje přesnost klasifikace.

.centerCrop — ořízne obrázek ze středu na čtverec, poté změní měřítko na velikost vstupu modelu. Vhodné pro modely natrénované na centrovaných objektech (většina klasifikátorů ImageNet). .scaleFill — roztáhne obrázek na velikost vstupu bez zachování proporcí. Rychlé, ale deformuje geometrii. .scaleFit — změní měřítko při zachování proporcí, přidá letterbox (černé pruhy) po okrajích.

swift
import Vision

let request = VNCoreMLRequest(model: model)

// .centerCrop — pro centrované objekty (výchozí)
request.imageCropAndScaleOption = .centerCrop

// .scaleFill — pro jednotné textury (bez deformace)
request.imageCropAndScaleOption = .scaleFill

// .scaleFit — když záleží na proporcích objektu
request.imageCropAndScaleOption = .scaleFit

Doporučení: pro většinu klasifikačních modelů použijte .centerCrop — poskytuje nejlepší poměr přesnosti a výkonu. Pokud byl model natrénován na obrázcích se zachováním proporcí (například detekce anomálií na fotografiích dokumentů), zvolte .scaleFit s letterboxem.

Podle Apple Developer Documentation 2024 může nesprávná volba imageCropAndScaleOption snížit přesnost modelu o 15–25%. Například .scaleFill pro obličej umístěný na okraji snímku může oříznout jeho část při .centerCrop nebo deformovat proporce při .scaleFill.

Kombinace s dalšími VNRequest

Hlavní síla VNCoreMLRequest — možnost kombinovat jej s dalšími VNRequest v jednom volání perform(). To umožňuje vytvářet pipeline: nejprve najít obličeje (VNDetectFaceRectanglesRequest), poté klasifikovat každý obličej přes vlastní model Core ML (VNCoreMLRequest).

VNCoreMLRequest také podporuje regionOfInterest — pokud nastavíte tuto oblast, Vision ořízne obrázek na určený obdélník před předáním modelu Core ML. To je kritické pro pipeline: po detekci obličeje předáte jeho bounding box jako regionOfInterest pro VNCoreMLRequest.

swift
import Vision

// 1. Detekce obličeje
let faceRequest = VNDetectFaceRectanglesRequest()

// 2. Klasifikace emocí přes Core ML
guard let emotionModel = try VNCoreMLModel(
    for: EmotionClassifier().model)
else { return }

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

// 3. Nastavení regionOfInterest pro každý obličej
for face in faceRequest.results as? [VNFaceObservation] ?? [] {
    emotionRequest.regionOfInterest = face.boundingBox
    try handler.perform([emotionRequest])
    // Zpracování výsledku klasifikace emocí
}

Omezení: regionOfInterest pro VNCoreMLRequest má smysl, když je model natrénován na obrázcích jedné velikosti a proporcí. Pokud model očekává striktně čtvercový vstup (224x224), .centerCrop s regionOfInterest poskytne nejlepší výsledek.

Podle Apple ML Research pipeline "detekce → klasifikace" přes regionOfInterest poskytuje zvýšení přesnosti o 20–30% ve srovnání s klasifikací celého obrázku, protože ML model dostává pouze relevantní oblast bez šumu pozadí.

Typ pipelinePožadavek 1 (detekce)Požadavek 2 (ML)Příklad
Obličej → emoceVNDetectFaceRectanglesRequestVNCoreMLRequestUrčení nálady
Objekt → značkaVNDetectObjectAtPointRequestVNCoreMLRequestRozpoznávání log
Text → jazykVNRecognizeTextRequestVNCoreMLRequestKlasifikace jazyka textu
Scéna → popisVNClassifyImageRequestVNCoreMLRequestGenerování tagů

Zpracování výsledků VNCoreMLRequest

VNCoreMLRequest vrací výsledky ve formě VNClassificationObservation (pro klasifikační modely) nebo VNCoreMLFeatureValueObservation (pro regresní a jiné typy). Typ výsledku závisí na výstupních datech modelu Core ML.

VNClassificationObservation obsahuje identifier (název třídy) a confidence (jistotu). Modely s výstupem softmax vracejí pole takových pozorování seřazených sestupně podle confidence. VNCoreMLFeatureValueObservation obsahuje libovolnou hodnotu MLFeatureValue — může být MultiArray, Double, String nebo Dictionary.

swift
// Pro klasifikační modely
if let classificationResults = request.results
    as? [VNClassificationObservation] {
    for result in classificationResults
        where result.confidence > 0.5 {
        print("\\(result.identifier): \\(result.confidence)")
    }
}

// Pro regresní modely (hodnoty prvků)
if let featureResults = request.results
    as? [VNCoreMLFeatureValueObservation] {
    for result in featureResults {
        let value = result.featureValue
        print("\\(result.featureName): \\(value)")
    }
}

Filtrování podle confidence: Apple doporučuje zahazovat výsledky s confidence < 0.3 pro obecné klasifikátory a < 0.7 pro kritické aplikace. U modelů natrénovaných na vyvážených datových sadách confidence koreluje s pravděpodobností správné odpovědi, ale nezaručuje ji.

VNCoreMLFeatureValueObservation.featureName odpovídá názvu výstupní vrstvy modelu (například 'classLabel' nebo 'features'). To umožňuje zpracování modelů s několika výstupy — každý výstup je reprezentován samostatným pozorováním s jedinečným featureName.

Nejlepší postupy a výkon

VNCoreMLRequest je optimalizován pro práci na Neural Engine (A12+), GPU a CPU. Vision automaticky vybírá nejlepší zařízení pro provádění modelu v závislosti na jeho typu a velikosti. Výkon lze však dále zlepšit správnou konfigurací.

Správa paměti

Modely Core ML se načítají do paměti při prvním VNCoreMLRequest a zůstávají tam až do uvolnění aplikace. Pro modely větší než 200 MB Apple doporučuje načítat je na vyžádání a uvolňovat přes MLModel.release(). VNCoreMLModel sama spravuje ukládání do mezipaměti, ale můžete to řídit pomocí autoreleasepool.

Dávkové zpracování

Pro dávkové zpracování obrázků vytvořte jeden VNCoreMLRequest a znovu jej použijte s různými VNImageRequestHandler. Nevytvářejte nový VNCoreMLRequest pro každý obrázek — zpomalí to zpracování kvůli opětovnému načítání modelu. Opětovné použití požadavku poskytuje zvýšení výkonu až o 40% při zpracování 10+ obrázků.

swift
// Správně: jeden požadavek pro všechny obrázky
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 aktualizuje při každém volání
}

Výběr zařízení: ve výchozím nastavení Vision vybírá Neural Engine pro kompatibilní modely na zařízeních A12+. Pokud model nepodporuje Neural Engine, Vision používá GPU nebo CPU. Můžete vynutit určení zařízení pomocí MLModelConfiguration.computeUnits, ale Apple doporučuje ponechat automatický výběr.

Podle Apple Performance Benchmarks 2024 VNCoreMLRequest na Neural Engine (iPhone 15 Pro) zpracovává klasifikaci MobileNetV2 za 3–5 ms, na GPU — 8–12 ms, na CPU — 20–30 ms. Rozdíl se stává kritickým pro aplikace v reálném čase zpracovávající 30+ snímků za sekundu.

Často kladené otázky

Lze VNCoreMLRequest použít bez Vision — přímo s Core ML?

Ano, Core ML lze použít přímo přes MLModel.prediction(), bez Vision. Nicméně VNCoreMLRequest automatizuje předzpracování obrazu (změna měřítka, oříznutí, převod na CVPixelBuffer). Pokud model přijímá nikoli obrázek, ale MultiArray nebo Double — použijte Core ML přímo. VNCoreMLRequest je pouze pro modely s Image Feature na vstupu.

Jak aktualizovat VNCoreMLRequest při nové verzi modelu?

Vytvořte nový VNCoreMLModel z aktualizovaného MLModel a nový VNCoreMLRequest. Starý požadavek bude nadále používat starou verzi modelu. Pro vzdálenou aktualizaci modelů použijte MLModel.compileModel(at:) pro kompilaci modelu na zařízení ze souboru .mlmodelc staženého ze serveru.

Podporuje VNCoreMLRequest modely s několika vstupy?

VNCoreMLRequest podporuje pouze modely s jedním vstupem Image Feature. Pokud má model několik vstupů (například obrázek + text), použijte Core ML přímo přes MLModel. Vision nemůže předat další parametry kromě obrázku.

Jaká je maximální velikost obrázku pro VNCoreMLRequest?

Limit je 8192 x 8192 pixelů pro CGImage předávaný VNImageRequestHandler. Modely Core ML však obvykle očekávají vstup 224x224, 299x299 nebo 512x512. Vision automaticky změní měřítko velkého obrázku na velikost vstupu. Pokud je původní obrázek příliš velký, předem jej zmenšete přes CGImage pro úsporu paměti.

Lze VNCoreMLRequest spustit na pozadí?

Ano, nastavte preferBackgroundProcessing = true na VNRequest. To umožní Vision odložit provedení požadavku, pokud je systém v režimu náročném na zdroje (například načítání obsahu). Také je povinné použít DispatchQueue.global(qos: .background) pro volání handler.perform().

Shrnutí

  • VNCoreMLRequest — podtřída VNRequest pro spouštění modelů Core ML v pipeline Vision s automatickým předzpracováním obrazu.
  • VNCoreMLModel obaluje MLModel pro Vision, automaticky převádí CGImage na CVPixelBuffer požadované velikosti a barevného prostoru.
  • imageCropAndScaleOption (centerCrop, scaleFill, scaleFit) určuje strategii změny měřítka a ovlivňuje přesnost modelu o 15–25%.
  • Kombinace s VNDetectFaceRectanglesRequest a dalšími VNRequest umožňuje vytvářet pipeline "detekce → klasifikace" s regionOfInterest.
  • Výsledky jsou vráceny jako VNClassificationObservation (pro klasifikaci) nebo VNCoreMLFeatureValueObservation (pro regresi/jiné typy).
  • Opětovné použití jednoho VNCoreMLRequest pro dávkové zpracování poskytuje až 40% zvýšení výkonu ve srovnání s vytvářením nového pro každý obrázek.
  • Výkon na Neural Engine (3–5 ms na MobileNetV2) je 4–6krát vyšší než na CPU, což je kritické pro aplikace v reálném čase.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také