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 — 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.
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 — 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.
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:).
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.
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.
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.
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 pipeline | Požadavek 1 (detekce) | Požadavek 2 (ML) | Příklad |
|---|---|---|---|
| Obličej → emoce | VNDetectFaceRectanglesRequest | VNCoreMLRequest | Určení nálady |
| Objekt → značka | VNDetectObjectAtPointRequest | VNCoreMLRequest | Rozpoznávání log |
| Text → jazyk | VNRecognizeTextRequest | VNCoreMLRequest | Klasifikace jazyka textu |
| Scéna → popis | VNClassifyImageRequest | VNCoreMLRequest | Generování tagů |
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.
// 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.
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í.
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.
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ů.
// 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
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.
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.
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.
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.
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í
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í.
Přečtěte si také