VNCoreMLRequest — a VNRequest egy alosztálya, amely lehetővé teszi Core ML modellek futtatását a Vision csővezetéken belül, ötvözve a kész Vision detektorok (arcok, szöveg, objektumok) előnyeit az egyedi ML modellekkel klasszifikációhoz és regresszióhoz. Az Apple Machine Learning Documentation (2024) szerint a VNCoreMLRequest automatikusan kezeli a kép előfeldolgozását — méretezést, vágást és színtér-konverziót — a Core ML modell követelményeinek megfelelően.
Főbb pontok
VNCoreMLRequest — a VNRequest egy alosztálya, amelyet az iOS 11-ben adtak hozzá a Vision-nal együtt, és amely lehetővé teszi Core ML modellek futtatását a Vision kontextusában. Elvégzi a Core ML modell számára szükséges összes kép-előfeldolgozást: méretváltoztatást, vágást, normalizálást és színtér-konverziót.
VNCoreMLRequest nélkül a fejlesztőnek manuálisan kellene konvertálnia a UIImage/CGImage-t MultiArray-be (MLMultiArray) vagy PixelBuffer-be (CVPixelBuffer) a megfelelő méretben. A VNCoreMLRequest automatizálja ezt a folyamatot: Ön a CGImage-t a VNImageRequestHandler-en keresztül adja át, a VNCoreMLRequest pedig maga méretezi azt a modell bemenetére.
VNCoreMLRequest örökli a VNRequest összes képességét: completion handler, regionOfInterest, több kérés egyidejű végrehajtásának lehetősége, VNImageRequestHandler és VNSequenceRequestHandler támogatása.
import Vision
import CoreML
// 1. Modell betöltése és becsomagolása
guard let model = try VNCoreMLModel(
for: MobileNetV2().model)
else { return }
// 2. VNCoreMLRequest létrehozása
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. Végrehajtás a handler-en keresztül
let handler = VNImageRequestHandler(cgImage: image, options: [:])
try handler.perform([request])
VNCoreMLRequest támogatja a különböző bemeneti típusú modelleket: képek (Image Feature), MultiArray és Double. Képek esetén a Vision automatikusan konvertálja a CGImage-t a megfelelő méretű és színterű CVPixelBuffer-ré. Más típusú bemeneti adatokhoz közvetlenül a Core ML-t kell használni Vision nélkül.
Az Apple WWDC 2023 szerint a VNCoreMLRequest az összes olyan iOS-alkalmazás 40%-ában használatos, amelyek Core ML-t alkalmaznak képekkel való munkához. Ez a legnépszerűbb módja az ML modellek iOS-alkalmazásokba való integrálásának.
VNCoreMLModel — egy burkoló, amely adaptálja a Core ML modellt (MLModel) a Vision-ban való használatra. Konvertálja a modell bemeneti és kimeneti adatait a Vision által érthető formátumba: kép → CVPixelBuffer, eredmény → VNObservation.
A VNCoreMLModel inicializálása ellenőrzi a modell kompatibilitását a Vision-nal: a modellnek képet kell fogadnia bemenetként (Image Feature) és klasszifikációt kell visszaadnia (MLMultiArray vagy Dictionary). Ha a modell nem kompatibilis, az inicializáló hibát dob.
import Vision
import CoreML
// 1. lehetőség: .mlmodel-ből (build időben lefordítva)
let model1 = try VNCoreMLModel(
for: MyVisionModel().model)
// 2. lehetőség: .mlmodelc-ből (eszközön lefordítva)
let compiledURL = Bundle.main.url(
forResource: "MyVisionModel",
withExtension: "mlmodelc")!
let model2 = try VNCoreMLModel(
for: MLModel(contentsOf: compiledURL))
VNCoreMLModel eltárolja a modellt a memóriában az első betöltés után. Ugyanazon modell újratöltése a gyorsítótárazott példányt adja vissza, ami felgyorsítja a későbbi kéréseket. Ha azonban a modell nagyobb, mint 100 MB, az iOS kirakhatja a memóriából erőforráshiány esetén — ebben az esetben a VNCoreMLModel automatikusan újratölti a modellt.
A Create ML segítségével tanított modellek esetén a VNCoreMLModel külön konfiguráció nélkül működik. A Create ML olyan metaadatokkal exportálja a modelleket, amelyeket a Vision automatikusan felismer — elég átadni a modellt a VNCoreMLModel(model:) számára.
imageCropAndScaleOption — a VNCoreMLRequest kulcsfontosságú tulajdonsága, amely meghatározza, hogy a Vision hogyan alakítja át az eredeti képet a Core ML modell bemeneti méretére. A helyes opció kiválasztása közvetlenül befolyásolja a klasszifikáció pontosságát.
.centerCrop — a képet középről négyzetre vágja, majd a modell bemeneti méretére méretezi. Középre igazított objektumokon tanított modellekhez alkalmas (a legtöbb ImageNet osztályozó). .scaleFill — a képet a bemeneti méretre nyújtja az arányok megtartása nélkül. Gyors, de torzítja a geometriát. .scaleFit — az arányok megtartásával méretez, letterbox-ot (fekete csíkokat) adva a szélekhez.
import Vision
let request = VNCoreMLRequest(model: model)
// .centerCrop — középre igazított objektumokhoz (alapértelmezett)
request.imageCropAndScaleOption = .centerCrop
// .scaleFill — egységes textúrákhoz (torzítás nélkül)
request.imageCropAndScaleOption = .scaleFill
// .scaleFit — ha az objektum arányai számítanak
request.imageCropAndScaleOption = .scaleFit
Ajánlások: a legtöbb klasszifikációs modellhez használja a .centerCrop-ot — ez adja a legjobb pontosság-teljesítmény arányt. Ha a modellt arányokat megtartó képeken tanították (például anomáliadetektálás dokumentumfotókon), válassza a .scaleFit-et letterbox-szal.
Az Apple Developer Documentation 2024 szerint az imageCropAndScaleOption helytelen megválasztása 15–25%-kal csökkentheti a modell pontosságát. Például a .scaleFill a képkocka szélén elhelyezkedő arc esetén levághatja annak egy részét .centerCrop-nál vagy torzíthatja az arányokat .scaleFill-nél.
A VNCoreMLRequest fő ereje — az a képesség, hogy más VNRequest-ekkel kombinálható egyetlen perform() hívásban. Ez lehetővé teszi csővezetékek építését: először arcok keresése (VNDetectFaceRectanglesRequest), majd az egyes arcok klasszifikálása egyedi Core ML modellen (VNCoreMLRequest) keresztül.
VNCoreMLRequest támogatja a regionOfInterest tulajdonságot is — ha beállítja ezt a területet, a Vision a megadott téglalapra vágja a képet, mielőtt átadná a Core ML modellnek. Ez kritikus a csővezetékeknél: az arc detektálása után annak bounding box-át adja át regionOfInterest-ként a VNCoreMLRequest számára.
import Vision
// 1. Arc detektálása
let faceRequest = VNDetectFaceRectanglesRequest()
// 2. Érzelem klasszifikáció Core ML-en keresztül
guard let emotionModel = try VNCoreMLModel(
for: EmotionClassifier().model)
else { return }
let emotionRequest = VNCoreMLRequest(model: emotionModel)
try handler.perform([faceRequest, emotionRequest])
// 3. regionOfInterest beállítása minden archoz
for face in faceRequest.results as? [VNFaceObservation] ?? [] {
emotionRequest.regionOfInterest = face.boundingBox
try handler.perform([emotionRequest])
// Az érzelem klasszifikáció eredményének feldolgozása
}
Korlátozás: a regionOfInterest a VNCoreMLRequest esetében akkor van értelme, ha a modellt egy méretű és arányú képeken tanították. Ha a modell szigorúan négyzet alakú bemenetet vár (224x224), a .centerCrop regionOfInterest-tel adja a legjobb eredményt.
Az Apple ML Research szerint a regionOfInterest-en keresztüli „detektálás → klasszifikáció“ csővezeték 20–30%-os pontosságnövekedést ad a teljes kép klasszifikációjához képest, mivel az ML modell csak a releváns területet kapja meg háttérzaj nélkül.
| Csővezeték típusa | 1. kérés (detektálás) | 2. kérés (ML) | Példa |
|---|---|---|---|
| Arc → érzelem | VNDetectFaceRectanglesRequest | VNCoreMLRequest | Hangulat meghatározása |
| Objektum → márka | VNDetectObjectAtPointRequest | VNCoreMLRequest | Logók felismerése |
| Szöveg → nyelv | VNRecognizeTextRequest | VNCoreMLRequest | Szöveg nyelvének klasszifikációja |
| Jelenet → leírás | VNClassifyImageRequest | VNCoreMLRequest | Címkék generálása |
VNCoreMLRequest az eredményeket VNClassificationObservation (klasszifikációs modellek esetén) vagy VNCoreMLFeatureValueObservation (regressziós és más típusok esetén) formájában adja vissza. Az eredmény típusa a Core ML modell kimeneti adataitól függ.
VNClassificationObservation tartalmazza az identifier-t (osztály neve) és confidence-t (bizonyosság). A softmax kimenetű modellek az ilyen megfigyelések tömbjét adják vissza, csökkenő confidence sorrendben rendezve. VNCoreMLFeatureValueObservation tetszőleges MLFeatureValue értéket tartalmaz — lehet MultiArray, Double, String vagy Dictionary.
// Klasszifikációs modellekhez
if let classificationResults = request.results
as? [VNClassificationObservation] {
for result in classificationResults
where result.confidence > 0.5 {
print("\\(result.identifier): \\(result.confidence)")
}
}
// Regressziós modellekhez (jellemző értékek)
if let featureResults = request.results
as? [VNCoreMLFeatureValueObservation] {
for result in featureResults {
let value = result.featureValue
print("\\(result.featureName): \\(value)")
}
}
Szűrés confidence alapján: az Apple azt ajánlja, hogy a confidence < 0.3 értékű eredményeket az általános osztályozók, és < 0.7 értékűeket a kritikus alkalmazások esetén dobja el. A kiegyensúlyozott adatkészleteken tanított modellek esetén a confidence korrelál a helyes válasz valószínűségével, de nem garantálja azt.
VNCoreMLFeatureValueObservation.featureName megfelel a modell kimeneti rétegének nevének (például „classLabel“ vagy „features“). Ez lehetővé teszi több kimenettel rendelkező modellek feldolgozását — minden kimenetet egy külön observation képvisel egyedi featureName-nel.
VNCoreMLRequest Neural Engine (A12+), GPU és CPU használatára optimalizált. A Vision automatikusan kiválasztja a legjobb eszközt a modell végrehajtásához annak típusától és méretétől függően. A teljesítmény azonban tovább javítható megfelelő konfigurációval.
Core ML modellek az első VNCoreMLRequest alkalmával töltődnek be a memóriába, és az alkalmazás kirakásáig ott maradnak. A 200 MB-nál nagyobb modellek esetén az Apple azt ajánlja, hogy igény szerint töltse be és rakja ki őket az MLModel.release() segítségével. A VNCoreMLModel maga kezeli a gyorsítótárazást, de Ön szabályozhatja ezt az autoreleasepool segítségével.
Kötegelt képfeldolgozáshoz hozzon létre egy VNCoreMLRequest-et, és használja újra különböző VNImageRequestHandler-ekkel. Ne hozzon létre új VNCoreMLRequest-et minden egyes képhez — ez lelassítja a feldolgozást a modell újratöltése miatt. A kérés újrafelhasználása akár 40%-os teljesítménynövekedést ad 10+ kép feldolgozásakor.
// Helyes: egyetlen kérés az összes képhez
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 minden híváskor frissül
}
Eszközválasztás: alapértelmezés szerint a Vision a Neural Engine-t választja a kompatibilis modellekhez A12+ eszközökön. Ha a modell nem támogatja a Neural Engine-t, a Vision GPU-t vagy CPU-t használ. Kényszerítheti az eszköz megadását az MLModelConfiguration.computeUnits segítségével, de az Apple az automatikus kiválasztás meghagyását ajánlja.
Az Apple Performance Benchmarks 2024 szerint a VNCoreMLRequest Neural Engine-en (iPhone 15 Pro) 3–5 ms alatt dolgozza fel a MobileNetV2 klasszifikációt, GPU-n — 8–12 ms, CPU-n — 20–30 ms alatt. A különbség kritikussá válik a valós idejű alkalmazásoknál, amelyek 30+ képkockát dolgoznak fel másodpercenként.
Gyakran Ismételt Kérdések
Igen, a Core ML használható közvetlenül az MLModel.prediction() segítségével, Vision nélkül. Azonban a VNCoreMLRequest automatizálja a kép-előfeldolgozást (méretezés, vágás, konvertálás CVPixelBuffer-ré). Ha a modell nem képet, hanem MultiArray-t vagy Double-t fogad — használja közvetlenül a Core ML-t. A VNCoreMLRequest csak Image Feature bemenettel rendelkező modellekhez való.
Hozzon létre egy új VNCoreMLModel-t a frissített MLModel-ből és egy új VNCoreMLRequest-et. A régi kérés továbbra is a modell régi verzióját fogja használni. Modellek távoli frissítéséhez használja az MLModel.compileModel(at:) parancsot a modell eszközön történő fordításához a szerverről letöltött .mlmodelc fájlból.
VNCoreMLRequest csak egy Image Feature bemenettel rendelkező modelleket támogat. Ha egy modellnek több bemenete van (például kép + szöveg), használja a Core ML-t közvetlenül az MLModel segítségével. A Vision nem tud további paramétereket átadni a képen kívül.
A korlát 8192 x 8192 pixel a VNImageRequestHandler-nek átadott CGImage esetén. A Core ML modellek azonban általában 224x224, 299x299 vagy 512x512 bemenetet várnak. A Vision automatikusan méretezi a nagy képet a bemeneti méretre. Ha az eredeti kép túl nagy, előzetesen csökkentse a méretét CGImage segítségével a memória megtakarítása érdekében.
Igen, állítsa be a preferBackgroundProcessing = true értéket a VNRequest-en. Ez lehetővé teszi a Vision számára, hogy elhalassza a kérés végrehajtását, ha a rendszer erőforrás-igényes módban van (például tartalom betöltése). Továbbá kötelező a DispatchQueue.global(qos: .background) használata a handler.perform() meghívásához.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is