Yappli Tech Blog

株式会社ヤプリの開発メンバーによるブログです。最新の技術情報からチーム・働き方に関するテーマまで、日々の熱い想いを持って発信していきます。

Core MLが今になって気になり触ってみる

iOSチームの菅(カン)です。
この記事は ヤプリ #2 Advent Calendar 2022 - Adventar の8日目として僭越ながら投稿させていただきます。

Core MLって

公式によると、

Core MLを使って、機械言語モデルをAppに統合します。Core MLはすべてのモデルを統一された方法で扱えます。Appは、Core ML APIとユーザーデータを使用して、予測の作成、モデルのトレーニングや微調整をすべてユーザーのデバイス上で行います。

developer.apple.com

だそうで、要はAppleで作成するアプリに機械学習を取り入れるフレームワークということですね。

対応しているのは下記になります。

  • iOS 11.0+
  • macOS 10.13+
  • Mac Catalyst 13.0+
  • tvOS 11.0+
  • watchOS 4.0+

iOS11以降で対応していれば、今からの導入で制限となることはなさそうですね。

ちなみにiOS13以前を使用してるユーザーは現時点(2022年12月)で4%以下になっています。

developer.apple.com

何ができる?

大きく3つあります。

  1. モデルの実行デバイス上で完結
  2. Core MLへのモデルの変換
  3. オンデバイスでのモデルのパーソナライズ

それぞれに関して自分なりの言葉に起こしてみようと思います。

1. モデルの実行デバイス上で完結

CoreMLモデルとしてアプリに組み込むと、データをデバイス外に出すことなくデバイス内で判定ができます。 そのため、ユーザーの情報をプライバシーを担保して扱うことが可能になります。

例えば、 アプリで顔を撮影した画像から表情認識をするようなアプリを考えてみます。

判定モデルをデバイス外のサーバーに置いてある場合、

のような流れになるかと思います。 利用時にはユーザーにデータをどう扱うかであったりを明記して、同意を別途得る必要があります。

その場合、ユーザーにとっては”同意文があるなんて、、、””自分の顔画像はどこにいくんだろう、、”、といった利用時に不安感があります。

しかし、CoreMLモデルでアプリに組み込むと「→サーバーに画像を送信→サーバー側にあるモデルで判定」が「CoreMLで判定」に置き換わるためデータがアプリ外に出てしまうことがありません。

これは、ユーザーにとって利用障害を取り除くことにつながるかと思います。

2. Core MLへのモデルの変換

Core ML以外で学習されたモデルを変換することもできます。

機会学習/ディープラーニングを何かしら利用されたことのある人なら、TensorFlowなど別のフレームワークで作成したモデルや、既存の研究で公開されているモデルを使用したいと思うかもしれません。

そこもカバーされており、TensorFlowやPyTorchなどのライブラリからのモデルを、Core MLコンバータを使用してCore MLに変換することができます。

3. オンデバイスでのモデルのパーソナライズ

アプリにバンドルされているモデルは、ユーザーデータを使ってオンデバイスでアップデートすることができます。

つまり、リリースした後もアプリ側で、ユーザードメインの情報をもとに再学習することができるということです。

実際に動かしてみる

今回は公式のAppleDeveloperで紹介されているサンプルコードを試してみようかと思います。

developer.apple.com

内容は火星の居住地価格を予測するアプリとして提供されています。

予測には学習済みモデルMarsHabitatPricer.mlmodelを使用します。

let model = MarsHabitatPricer()

UIPickerView(シリンダーのように回転して選択するメニュー部)からSolar Panels, Greenhouses, Acresの3つの要素を入力とします。

// UIPickerViewの選択要素を取得
func selectedRow(for feature: Feature) -> Int {
    return pickerView.selectedRow(inComponent: feature.rawValue)
}

let solarPanels = pickerDataSource.value(for: selectedRow(for: .solarPanels), feature: .solarPanels)
let greenhouses = pickerDataSource.value(for: selectedRow(for: .greenhouses), feature: .greenhouses)
let size = pickerDataSource.value(for: selectedRow(for: .size), feature: .size)

Solar Panels, Greenhouses, Acresをモデルに入力してOutputとして、火星の居住地価格の予測値が得られます。

guard let marsHabitatPricerOutput = try? model.prediction(solarPanels: solarPanels, greenhouses: greenhouses, size: size) else {
    fatalError("Unexpected runtime error.")
}

let price = marsHabitatPricerOutput.price
priceLabel.text = priceFormatter.string(for: price)

モデルへの誤った入力ではerrorがthrowされるようになっています。

入力するデータ形式はモデルによって決まっているため、形式の誤りにはerrorが返ります。

今回のMarsHabitatPricer.mlmodelでは、Double型の入力3つとなっていることがXcode上で確認できます。

シンプルなモデルを使用していることもありますが、予想値の取得に通信などがないため、結果が得られるまでの時間もスムーズでした。

まとめ

今回はCore MLをAppleが提供する学習済みモデルを使用して試してみました。

Core MLを使用することへのメリットは

  • 端末完結でモデル結果が得られる
  • iOSデバイスの性能を最大限活かすことができる

の2つが大きいかと思います。

別のCore MLを利用する場合にも、Xcodeに.mlmodelファイルをドラッグアンドドロップするだけで導入できるため、かなり容易に様々な学習済みのモデルを扱うことができます。

今回は紹介できませんでしたが、Create MLを使って独自のデータセットを用いて、コードを触ることなくモデル作成をすることもできます。

developer.apple.com

機械学習/ディープラーニングがよりローカライズできるような可能性を秘めたCore MLをみなさんも試されてはいかがでしょうか?