[iOS 11] Vision.Frameworkで画像の識別を試してみました #WWDC2017
1 はじめに
iOS 11で追加された Vision.Framework では、CoreMLを利用した画像解析を、一貫性のあるインターフェイスで簡単にアプリに組み込むことが出来ます。
Vision.Frameworkには、顔追跡・検出・ランドマーク、テキスト検出、矩形検出、バーコード検出、オブジェクト追跡など各種の機能が提供されていますが、今回は、画像の識別について試してみました。
画像の識別では、CoreML用に機械学習のモデル(CoreML用に作成された.mlmodelファイル)が必要ですが、こちらは、Appleの開発者ページでダウンロードに可能なっている下記の5種類を使用させて頂きました。
- SqueezeNet
- Places205-GoogLeNet
- ResNet50
- Inception v3
- VGG16
https://developer.apple.com/machine-learning/より
本記事は Apple からベータ版として公開されているドキュメントを情報源としています。 そのため、正式版と異なる情報になる可能性があります。ご留意の上、お読みください。
2 登場するオブジェクト
Vision.Frameworkを利用した画像処理では、大きく3つのオブジェクトが登場します。
- Requests
- RequestHandler
- Observations
WWDC 2017 Session 506 Vision Framework Building on Core MLより
Requestsオブジェクトは、画像処理タスクをシステムに要求するためのオブジェクトで、解析の種類(画像識別、矩形認識、顔認識など)によって違ったものになります。
RequestHandlerは、実際のイメージを用意して、上記のリクエストをハンドルします。これは、全ての処理で共通です。
最後に、Observationsですが、こちらは、Requestの保持しているクロージャーに渡され解析結果を処理します。解析の種類によって違ってくるので、Requestとセットになっています。(例えば、顔認識では、顔認識用のObservationとなる)
3 画像解析処理
先出の3つのオブジェクトを使用して、画像の識別を行うコードは以下のとおりです。
画像の識別ということで、リクエストオブジェクトは、VNCoreMLRequestを使用し、その解析結果の処理用のオブザーバーは、VNClassificationObservationとなっています。
func coreMLRequest(image:UIImage) { // モデルの作成 guard let model = try? VNCoreMLModel(for: Inceptionv3().model) else { fatalError("Error create VMCoreMLModel") } // リクエスト(VNCoreMLRequest)の生成とハンドラ処理 let request = VNCoreMLRequest(model: model) { request, error in // オブザーバ(VNClassificationObservation)による解釈 guard let results = request.results as? [VNClassificationObservation] else { fatalError("Error results") } if let classification = results.first { print("identifier = \(classification.identifier)") print("confidence = \(classification.confidence)") } else { print("error") } } // CIImageへの変換 guard let ciImage = CIImage(image: image) else { fatalError("Error convert CIImage") } // ハンドラの生成と実行 let handler = VNImageRequestHandler(ciImage: ciImage, options: [:]) guard (try? handler.perform([request])) != nil else { fatalError("Error handler.perform") } }
Modelを生成する際のVNCoreMLModelの第1引数には、使用するモデルを指定しますが、ここを変更することで、各種のモデルに置き換える事ができます。
//Inception v3 を GoogLeNetPlaces.mlmodel に変更する //let model = try? VNCoreMLModel(for: Inceptionv3().model) let model = try? VNCoreMLModel(for: GoogLeNetPlaces().model)
4 やってみた
実際にやってみたところ、下記のような結果を得ることが出来ました。
sizeは、モデル(.mlmodel)のサイズ(MByte)であり、timeは、解析にかかった時間です。モデルごとに少し差があったようなので、秒単位で雑に計測してみました。
下記の結果ですが、処理時間などは、もちろん実機の性能に大きく依存するでしょうし、確かめたサンプル数も非常に限られたものですので、あくまで「解析の一例」程度の意味しか無いことを予めご了承下さい。
size | identifier | confidence | time | |
---|---|---|---|---|
SqueezeNet | 4.7 | snowmobile | 0.508154 | 2.0 |
Places205-GoogLeNet | 24.8 | river | 0.2156 | 4.0 |
Inception v3 | 94.7 | lakeside, lakeshore | 0.854758 | 4.0 |
ResNet50 | 102.6 | lakeside, lakeshore | 0.373168 | 4.0 |
VGG16 | 553.5 | lakeside, lakeshore | 0.38961 | 4.0 |
size | identifier | confidence | time | |
---|---|---|---|---|
SqueezeNet | 4.7 | eggnog | 0.970777 | 3.0 |
Places205-GoogLeNet | 24.8 | supermarket | 0.172011 | 3.0 |
Inception v3 | 94.7 | bakery, bakeshop, bakehouse | 0.10947 | 3.0 |
ResNet50 | 102.6 | grocery store, grocery, food market, market | 0.181952 | 4.0 |
VGG16 | 553.5 | packet | 0.117755 | 4.0 |
size | identifier | confidence | time | |
---|---|---|---|---|
SqueezeNet | 4.7 | studio couch, day bed | 0.242885 | 3.0 |
Places205-GoogLeNet | 24.8 | boat_deck | 0.644138 | 3.0 |
Inception v3 | 94.7 | wing | 0.239884 | 3.0 |
ResNet50 | 102.6 | missile | 0.541719 | 3.0 |
VGG16 | 553.5 | missile | 0.385286 | 3.0 |
size | identifier | confidence | time | |
---|---|---|---|---|
SqueezeNet | 4.7 | gasmask, respirator, gas helmet | 0.326393 | 2.0 |
Places205-GoogLeNet | 24.8 | aquarium | 0.319852 | 3.0 |
Inception v3 | 94.7 | pop bottle, soda bottle, | 0.512668 | 3.0 |
ResNet50 | 102.6 | projectile, missile | 0.108452 | 3.0 |
VGG16 | 553.5 | pop bottle, soda bottle | 0.179419 | 4.0 |
size | identifier | confidence | time | |
---|---|---|---|---|
SqueezeNet | 4.7 | nipple | 0.806034 | 2.0 |
Places205-GoogLeNet | 24.8 | clothing_store | 0.136114 | 3.0 |
Inception v3 | 94.7 | Appenzeller | 0.27724 | 3.0 |
ResNet50 | 102.6 | kelpie | 0.343134 | 4.0 |
VGG16 | 553.5 | kelpie | 0.178468 | 4.0 |
size | identifier | confidence | time | |
---|---|---|---|---|
SqueezeNet | 4.7 | handkerchief, hankie, hanky, hankey | 0.914462 | 2.0 |
Places205-GoogLeNet | 24.8 | herb_garden | 0.290646 | 3.0 |
Inception v3 | 94.7 | sulphur butterfly, sulfur butterfly | 0.289349 | 3.0 |
ResNet50 | 102.6 | pot, flowerpot | 0.443367 | 3.0 |
VGG16 | 553.5 | pot, flowerpot | 0.107249 | 4.0 |
size | identifier | confidence | time | |
---|---|---|---|---|
SqueezeNet | 4.7 | window screen | 0.390035 | 2.0 |
Places205-GoogLeNet | 24.8 | shower | 0.195312 | 3.0 |
Inception v3 | 94.7 | fountain | 0.398686 | 3.0 |
ResNet50 | 102.6 | fountain | 0.368908 | 4.0 |
VGG16 | 553.5 | fountain | 0.129674 | 3.0 |
5 最後に
ちなみに、「やってみた」のところで写真に写っていた犬は、「黒柴」なのですが、解析結果に出ていた Appenzeller とか kelpieは、google画像検索で見ると、次のような感じでした。 雰囲気、黒柴!?
コードは、下記に起きました。モデルは含まれておりませんので、別途ダウンロードが必要です。
[GitHub] https://github.com/furuya02/CoreMLSample
↓こちらで、Vision.Frameworkを使用しない場合との比較も行っております。興味があれば是非!
[iOS 11] CoreMLで画像の識別を試してみました(Vision.Frameworkを使わないパターン) #WWDC2017
6 参考リンク
WWDC 2017 Vision Framework: Building on Core ML
Apple Document > Vision Framework
Build more intelligent apps with machine learning.