iOSで機械学習！！ CreateMLを使ってみた

# はじめに！

<br>

**「iOS ＋ 機械学習の面白さが伝えればいいな」**

そんな思いでこの記事を書いてます

<br>

今回紹介するのは**CreateML**っていうiOSアプリに機械学習ぶちこめるサービスみたいなやつです。

https://developer.apple.com/jp/machine-learning/create-ml/


これが使えるようになれば、例えばカメラで物体を検出したり、心拍数を計測してヘルスケアアプリ的なのを作ったり、アプリの幅が広がってリッチな開発ができるはずです^ - ^


# この記事で書くこと


- CreateMLの概要
- 使い方
    - データの収集方法
    - モデルの作成方法
    - iOSへの組み込み方法
- 感想

<br>
です。具体的なところまでつっこんでます

ではどうぞ

# createMLってな〜〜〜〜〜に

そいつはWWDC19で発表された、mac上で動作する機械学習モデルをtrainingし、そのモデルを簡単にiOSアプリに組み込めるバカ便利なサービスでございます

<br>

↓とってもわかりやすい公式紹介video

https://developer.apple.com/videos/play/wwdc2019/426/


<br>

どうやって使うんって感じなんですけど、元々テンプレートみたいなやつがあって、そこからGUIでデータ選択とか学習とかするだけです。

例えばこんな感じのテンプレートが用意されてます。

![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/3441cc5e-5e6b-fb58-380f-aa85e768f13c.png)

tensorflowとかだと自分で考えてモデルを構成する必要がありますが、やりたい機械学習を頭の中で考えて選ぶだけなので簡単ですね

UIもappleって感じがしてLOVE！かわいい

<br>

テンプレートから進むとこんなワークスペース画面になります。概要なので詳細は省きますが、GUIでいろいろ操作できるっていうことだけイメージしてもらって！

![Untitled (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/2df177bb-1569-dd01-e19f-f69509f56490.png)


# さあ実際に使ってみようかしら

今回は「スマホで円を描くモーションを検知する」を例として実際にやってみます


## テンプレートの選択

「円のモーションを検知するには？」
↓
いろいろ調べた結果ジャイロセンサが良さげでした

<br>

それゆえ今回は生体データを時系列的に扱うことができる、**Activity Classifier**を使ってみることにします！こいつ！

![Untitled (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/b1aa8d5d-db86-1be1-2a7a-fb7062b1d58f.png)


### データセットの用意

テンプレートを選択するとこんな画面になります

![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/bbed1bdd-805f-1376-2645-42f7ec2fc015.png)


さあ機械学習モデルを作るにはデータが必要です。

<br>
<br>
<br>
<br>
<br>


「どうやって収集する？」

<br>
<br>
<br>



「収集アプリなんてあるわけがない」

<br>
<br>
<br>


「エンジニアだし作っちゃいましょか」

<br>


![thGVKRNB98.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/b4af1e16-1cbf-809f-6ad6-4aa6a3917018.jpeg)



## データ収集アプリ

作りました

https://github.com/miyakooti/motion_detect_createML/tree/master/motion_detect_collect_data_app

- 使用ライブラリ
    - coreMotion
    - uikit

円モーションのジャイロデータを収集できるアプリです。

![Untitled (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/e4b8d0b8-45ba-5aa7-4bc2-cd9c4d5149d2.png)


流れとしては、

<br>

タップして計測開始

↓

振動でインターバルを提示

↓

データがcsvとしてiPhoneのローカルに保存される


<br>


みたいな感じ！

このデータを「ファイル」アプリからAirDropとかでPCに共有してcreateMLに持っていきます。

<br>

※ もし「ファイル」アプリからアプリ内フォルダが見えない場合は以下リンクを参照してください。セキュリティ上info.plistで許可してないと見えないようになってます。僕はsandboxって概念知らなくて結構ハマりました、、

https://tech.amefure.com/swift-permission-documents



# よしゃモデルを作っていこう

さて学習データが集まりました！

ここからそのデータを使ってモデルを作成し、モーション分類をしていきましょう。

<br>


今回自分は円モーションを検知するというよりは、

「円モーションと円モーション以外のクラスを用意して、その中でどれになるか分類する」

みたいな感じで作りました。

<br>


モデル作成の前にまずデータをフォルダ分けしましょう

構造こんな感じにしておくと便利です。shellとかでよしなに操作してください

```
- hoge
    - train
        - stay
        - walk
        - circle
    - test
        - stay
        - walk
        - circle
```

こんな感じでフォルダごとに整理できたら、createMLを使用してモデルを作成していきます。

<br>


さあ左に訓練、右にテストデータを入れましょーーー

![Untitled (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/278eeb23-8a73-b633-1550-c32bd64f0038.png)


UIわかりやすいからよしなにできるはず

<br>


下のparametersってなんぞやって感じですが

- Maximum Iterations
    - 繰り返しの数
- Batch Size
    - １回の学習で何回データセット回すか？
- prediction window size
    - 分類サイズの単位
- rate
    - １秒間何回サンプリングしてるか

みたいな感じです！機械学習の詳細は本題じゃないのでさらっと流します

<br>

あとは左上のtrain▶️ボタンを押せば学習開始します。何回かイレテーションとかbatchとか調整して精度あげてみましょう〜〜

![Untitled (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/5eac4974-378c-d990-a887-215e565fd7a7.png)


ちょっとOver Fitting気味だけどまあいいや！

<br>


学習できたらOutputタブからGetボタンで.mlmodelを出力して、これで作成完了！

![Untitled (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/dc1bad38-d65c-c04a-1305-408d8441a824.png)

👍👍👍👍

# iOSアプリへ取り込んでみる

モデル作ったらテストしたいですよねそりゃあ

さあエンジニアなので作りました検証アプリ

https://github.com/miyakooti/motion_detect_createML/tree/master/predict_motion_detect_collect_data_app

さっきのやつと大体仕組み同じなので説明省略

![Untitled (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/02e8cd58-5313-8159-1bb9-5469146aab17.png)


ここからはこのアプリにどうやってモデルを組み込んだかを手順踏んで説明してきます

<br>

まず.mlmodelmをどこでもいいのでドラッグandドロップで置いときましょう

![Untitled (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/ae51e282-00db-5413-e70d-0963818bb128.png)

<br>

モデルのprediction詳細をみてみると、デフォルトでは入力にLSTMのstateInが必須になってます。今回はそんな高度なことしないのでオプショナルにしていきましょう。(使わんでも十分精度出るので、、)


![Untitled (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/cbdac759-c20b-9f57-0824-b7b9f07fb346.png)


ここでオプショナルにするために大分ハマりました、、というのもxcodeから操作できないぽいです多分

<br>

めちゃめちゃ探したらpython使ってできるみたいでした。これ以外にできる方法があったら教えてほしいです。

```python
import coremltools

mlmodel = coremltools.models.MLModel('your_ml_model.mlmodel')
spec = mlmodel.get_spec()

# 3はstateInのindexなので自分に合わせて変更する
input3 = spec.description.input[3]
input3.type.isOptional = True

# save the spec back out
mlmodel = coremltools.models.MLModel(spec)
mlmodel.save('your_ml_model.mlmodel')
```

参考issue

https://github.com/apple/coremltools/issues/388

<br>
<br>

オプショナルにできたらコードをゴリゴリ書いて検知部分を実装していきます！

一部抜粋

```swift
private func setUpSensor() {
        
        if !motionManager.isAccelerometerAvailable {
            print("Accelerometer is not available on this device.")
        }
        
        motionManager.gyroUpdateInterval = AppParameters.samplingRate
        
        let queue = OperationQueue()
      
       var count = 0
        
        motionManager.startGyroUpdates(to: queue) { (gyroData, error) in
            if let data = gyroData {
                // Process accelerometer data
              self.classifier.process(deviceMotion: data)
              count += 1
              
            }
            if let error = error {
                print("Error reading accelerometer data: \(error)")
            }
        }
      classifier.delegate = self

    }
```

これをビルドして、、

![Untitled (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861241/e89b0010-8de9-9a09-033d-d6d06ae3a32a.png)

<br>

検知できました👍

<br>

# おわりでございます

めちゃ簡単ですよねcreateMLすばらしい

本来であればsklearnとかでモデル作成して、どーやってモデル組み込むか調べて、、って感じですが、これ使うと親和性高くてびっくりです。。


<br>

今回はジャイロセンサのみ使って簡単なモーションを検知しただけですが、他にも加速度センサとか心拍数のデータとかいろんなのあります！！そいつらとcreateML組み合わせればヘルスケアアプリでもなんでも作れそうでわくわくでございますね

<br>

までもモーション検知についてはまだいろんな課題があるみたいです、、

https://www.ai-gakkai.or.jp/resource/my-bookmark/my-bookmark_vol36-no2/

<br>

とにかく、他にもいろんなワークスペースあるので興味あったらやってみてください〜〜

長くなりましたが読んでくれてありがとうございました