WonderPlanet Tech Blog

アドバンストテクノロジー部やCTO室のメンバーを中心に最新の技術情報を発信しています。

Azure Custom VisionのAPIで画像分類 Swift版

ようやくAmazon Echo Dotをゲットして、毎日Alexaさんと楽しくおしゃべりしているアドバンストテクノロジー部の近藤です。

今回はMicrosoft Azure Custom Vision Serviceで作成した学習モデルをAPI経由で分類したい画像を入力して、出力をJSONで受け取る方法を紹介します。

Custom Vision Serviceについて

Microsoft Azureのサービスのひとつで、画像分類をする学習モデルを作成できるサービスです。
詳細はこちらの記事で紹介しています。 tech.wonderpla.net

Custom VisionのAPIについて

上記の記事を参考にCustom Visionで学習モデルを作成すると、API経由で分類するためのURLも発行されます。

「Performance」→「Prediction URL」のメニューを開くと、画面の右側にURLが記載されています。
今回は画像のファイルデータを送信して分類するので、「If you have an image file:」の方を利用します。 赤文字で書いてある必要なヘッダを設定してリクエストします。 f:id:HidehikoKondo:20171211163833p:plain

ドキュメント

ドキュメントはこちら
<Microsoft> developer portal

Swift版

公式サイトに各種言語でサンプルコードが公開されていますが、SwiftのサンプルコードがなかったのでSwiftで作ってみました。
パンダの画像をAPI経由で分類します。分類した結果はJSONで受け取ることが出来るので、それをそのままTextViewに表示しています。
APIのURLとPrediction-Keyは皆様のアカウントで発行されたものに差し替えてください。

Storyboardには結果の表示用のUITextVIewと分類する画像を表示したUIImageViewを配置します。
「@IBAction func prediction(_ sender: Any) 」にはStoryboardで配置したUIButtonに接続します。

import UIKit

class AzureViewController: UIViewController, URLSessionDelegate, URLSessionDataDelegate  {

    @IBOutlet weak var resultTextView: UITextView!
    @IBOutlet weak var animalPhoto: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func prediction(_ sender: Any) {
        // APIのURLをここにコピペする(スクショ参照)
        var path: NSString = "●●●●●●●"
        let image: UIImage = self.animalPhoto.image!
        let pngData: Data = UIImagePNGRepresentation(image)!
        let requestParams: NSArray = ["entities=true"]
        let parameter: String = requestParams.componentsJoined(by: "&")
        path = path.appendingFormat("?%@", parameter)

        //Httpリクエストの設定
        var request: URLRequest = URLRequest.init(url: URL.init(string: path as String)!)
        request.httpMethod = "POST"
        request.addValue("application/octet-stream", forHTTPHeaderField: "Content-Type")

        // Prediction-Keyをここにコピペする(スクショ参照)
        request.addValue("●●●●●●●", forHTTPHeaderField: "Prediction-key")
        request.httpBody = pngData

        // APIに対して画像を送って、分類した結果をJSONで受け取る
        let session: URLSession = URLSession.init(configuration: URLSessionConfiguration.default)
        let task = session.dataTask(with: request, completionHandler: {
            data, response, error in

            if let data = data, let response = response{
                print(response)
                do {
                    let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments)
                    DispatchQueue.main.async {
                        self.resultTextView.text = String.init(describing: json)
                    }
                } catch {
                    print("Serialize Error")
                }
            } else {
                print(error ?? "Error")
            }
        })
        task.resume()
    }
}

動物の画像判別

f:id:HidehikoKondo:20171204191123p:plain Custom Visionのコンソールで、「パンダ」「クマ」「コアラ」の顔を学習させたモデルを作成しました。
これをAPI経由でパンダの画像を判別させた結果がこちらです。
「Probability(確率)」が0.38.... で、「panda」であるという結果が帰ってきたのがわかります。

f:id:HidehikoKondo:20171201201431p:plain

注意事項

APIに送信して分類できる画像のサイズは4MBまでです。 4MB超えてた画像を送信すると、エラー(Bad Request)が返ってきます。

メリットとデメリット

メリット

  • 学習モデルを作成はCustom Visionのコンソール上で完結し、学習モデルを作るための環境を自分で用意する必要がありません。
  • Custom Visionで作成した学習モデルは、Webの画面上で再学習などの調整ができます。
  • Core MLに変換した学習モデルの場合は、アプリにインポートしてアプリをビルドし直す必要がありますが、API経由であれば新しい学習モデルに即切り替えることが可能となります。
  • クロスプラットフォームで利用できます!

デメリット

  • Core MLの学習モデルはローカルのみで完結するのに対し、API経由だとネットワークを使うためレスポンスは遅くなります。

まとめ

このようにCustom VisionのAPIを利用して、簡単に画像の分類をすることができます。
API経由であればスマホアプリでもWebアプリでも利用でき、いろんなプラットフォームで活用できると思います。
これだけ手軽に機械学習の機能を利用することができるようになると、いろんなサービスがこれから沢山出てくるんではないでしょうか?
機械学習界隈がこれからどんな風に盛り上がっていくか楽しみですね。