バイセル Tech Blog

バイセル Tech Blogは株式会社BuySellTechnologiesのエンジニア達が知見・発見を共有する技術ブログです。

Pytorch(skorch)で学習したモデルを使い、iOSで画像分類をする [3/3]

テクノロジー開発部の村上です。
前回、Core MLのモデルを作成したので、それを使ってXcodeのPlaygroundで画像分類を実際に試してみます。

モデルのコンパイル

通常のiOSのアプリではモデルをドラッグ&ドロップするだけでプログラム上で使えるようになるのですが、
Playgroundの場合は自分でコンパイルをする必要があります。

/Applications/Xcode.app/Contents/Developer/usr/bin/coremlc compile CoreMLModel.mlmodel ~

ちなみに前回RGBのバイアスを入れ替えましたが、その結果は~/CoreMLModel.mlmodelc/model.espresso.netを見ると確認できます。
bias_g, bias_r, bias_bの値が意図通りになっているかと思います。

Playgroundの準備

Xcodeを開くと"Get started with a playground"という選択肢があるので、"Blank"というtemplateを選んでPlaygroundを作成します。
そして作成したPlaygroundで使えるように、先程コンパイルしたモデルを移します。

mkdir ~/MyPlayground.playground/Resources
mv ~/CoreMLModel.mlmodelc ~/MyPlayground.playground/Resources

画像分類

まず、分類したい犬か猫の画像を用意して、Resourcesディレクトリに移します。
今回はpro.fotoのゴールデンリトリバー画像
を使用させていただきました。

そして以下のコードをPlaygroundに記し実行します。

import UIKit
import CoreML
import Vision

var image = UIImage(named: "dog0143-002.jpg")!
let url = Bundle.main.url(forResource: "CoreMLModel", withExtension: "mlmodelc")!
let model = try MLModel(contentsOf: url)
let coreMLModel = try! VNCoreMLModel(for: model)
let request = VNCoreMLRequest(model: coreMLModel) { request, error in
    guard let results = request.results as? [VNClassificationObservation] else { return }
    for result in results {
        print(result.confidence * 100, result.identifier)
    }
}
request.imageCropAndScaleOption = .centerCrop
let ciImage = CIImage(image: image)
let handler = VNImageRequestHandler(ciImage: ciImage!)

do {
    try handler.perform([request])
} catch {
    print(error)
}

今回はPlaygroundということで非同期処理などの工夫をしていないので、シンプルなものとなっています。
主なポイントは以下の2つです。

  1. .centerCropはresizeした上で最後にcropしてくれるので、画像のサイズがモデルの入力より大きい分には、特に気にする必要がありません
  2. results は confidence の高い(そのオブジェクトである可能性が高い)順番に sort された Array で返ってきます
    • 各resultはconfidenceとidentifier (前回ラベルとして指定したもの)をフィールドとして持っています

resultを順に出力しているので、コンソールに以下のように出力され、正しく分類されていることがわかります。

99.99634 dogs
0.003655881 cats

参考資料