小型IoT端末開発キット「SensorTile.box」 を使って機械学習を体験①

STマイクロエレクトロニクスの小型IoT端末開発キット[「SensorTile.box」](https://www.st.com/ja/evaluation-tools/steval-mksbox1v1.html)を使用してさまざまな機能を試してみるシリーズ、今回から機械学習編スタートです。


本シリーズの関連記事はこちら
◆使ってみた編
[①セットアップと使い方](https://qiita.com/ykawano/items/9aed0be1ca919ad4551d)
[②サンプル･アプリで試す　（モーション･センサ）](https://qiita.com/ykawano/items/b8a47a6ebf91cec22c2e)
[③アプリをカスタマイズしてみる　（振動FFT　加速度センサ）](https://qiita.com/ykawano/items/e45390b235e9f54d4ea8)
[④アプリをカスタマイズしてみる　（音声FFT　マイクロフォン）](https://qiita.com/ykawano/items/b302715ab3b7edee8036)

◆機械学習編
①サンプル･データで試す　機械学習体験その１
[②サンプル･データで試す　機械学習体験その２](https://qiita.com/ykawano/items/fb3949fde6e7df8302d2)
[③データを集めて学習データを作成（学習作業）　機械学習体験その３](https://qiita.com/ykawano/items/d2c289e2b1d3cdb06734)
[④データを集めて学習データを作成（テスト）　機械学習体験その４](https://qiita.com/ykawano/items/741e92ebb8e4d0dd2dfc)

今回は、「SensorTile.box」内に実装されているMEMSモーション･センサ[「LSM6DSOX」](https://www.st.com/ja/mems-and-sensors/lsm6dsox.html)を使って機械学習を試してみます。このセンサは **機械学習コア（MLC : Machine Learning Core）** を内蔵しているので、それを利用します。はじめに、学習済みのサンプル･データを使って動作を確認してみます。
記事の冒頭は概要の紹介なので、すぐに試したい場合は **2．準備** から読み進めてください。

SensorTile.boxのセットアップ方法や基本情報については、こちらの記事を参照してください。
[小型IoT端末開発キット「SensorTile.box」 をセンサ・アプリで使ってみた①　セットアップと使い方](https://qiita.com/ykawano/items/9aed0be1ca919ad4551d)




STBLESensorにデフォルトで入っているMLC使用のサンプル例: Human Activity recognition

![000_MLCsample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/09082b7c-e4f8-fb75-5a95-a61de23dbc79.png)

こちらの機械学習関連記事も合わせてご参照ください。
[5つのステップで簡単にできる！ 機械学習コア内蔵MEMSセンサを用いたディシジョン･ツリー開発のヒント](https://qiita.com/tyonemaru/items/282e782981583aa5aea3)
[5つのステップで簡単にわかる！ 機械学習コア内蔵センサでディシジョン･ツリーを実行](https://qiita.com/tyonemaru/items/ea6f38b8c739090b6e94)

## 1．はじめに

「センサ単体で機械学習？」と思われる方もいるかもしれませんが、学習作業そのものはパソコン上で動作するソフトウェア･ツール[Unico-GUI（ユニコ-ジーユーアイ）](https://www.st.com/ja/development-tools/unico-gui.html)を使って行います。設定後（学習データ書き込み後）は、設定内容に基づいてセンサ自身が取得したセンサ･データから判断を行います。つまり、マイコン（SensorTile.boxのメイン･マイコンはSTM32L4）内で行う機械学習判断ではありません。

実装までの流れは、大きく分けて以下の5つのステップに分けられます。

##### 1.	データ収集
対象物にSensorTile.boxを取り付けて、「動き」のデータを収集します。STBLESensor内サンプル･アプリにある、Log>Data recorderを使います。

##### 2.	データ･ラベリング（Unico-GUI使用）
動きや姿勢の特徴付けができそうな統計的なパラメータ **“Features（特徴量 \*1）”** を選択します。具体的には、「ACC_Mean（加速度平均値）」、「ACC_peak-to-peak（加速度ピーク･ツー･ピーク）」などです。必要に応じてフィルタを使用します。

##### 3.	機械学習の実行（Unico-GUI使用）
クラス分類（Classification \*2） / ディシジョン･ツリー生成（Unico-GUI使用）作業です。想定するクラスに対して、どのような手順・方法に従えば判別できるかを決定する **「ディシジョン･ツリー（決定木）」** を作ります。ディシジョン･ツリー構造自体は人間が考えて設計する必要はなく、ツール側で自動作成されます。

##### 4.	センサ用ファイルの生成（Unico-GUI使用）
最終的なディシジョン･ツリー情報を含む、センサ書き込み用ファイル（xxxx.ucf: Unico Configuration File）を出力します。

##### 5.	動作確認
新たな別のデータを入力して、正しく判定されるかどうかテストします。

##### 補足解説
\*1 Features: センサからの生データを基にMLC内の演算ブロックが算出。LSM6DSOXの場合は12種類用意されています。
\*2 Classification: クラス分類。「歩いている」や「走っている」など、最終的に導きたい判定結果を **クラス** と呼びます。









![001_Figure_MLC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/6826f9de-3915-f726-036a-381e8d3bb37f.png)




ステップ1（データ収集）とステップ5（動作確認）は、STBLESensor + SensorTile.box以外のツールやキットでも可能です。ただし、例えばMEMSセンサ用の標準ボード（MEMSマザーボード: STEVAL-MKI109V3）を使った場合、USBケーブルで接続したままデータを収集する必要があるので、環境によっては難しいかもしれません。バッテリ駆動でデータ収集できるSensorTile.boxや[STWIN](https://www.st.com/ja/evaluation-tools/steval-stwinkt1b.html)などが扱いやすいため、おすすめです。

こちらは、STEVAL-MKI109V3（MEMSマザーボード）とUnico-GUIを使って、LSM6DSOX用の機械学習データを作成している動画です。動画内でSensorTile.boxやSTBLESensorは使用されていませんが、学習の流れはほとんど同じなので参考にしてみてください。


[15分で作成可能！電子ペンのモーション検出（Youtube）](https://www.youtube.com/watch?v=FqXtciXfjzw)

<iframe width="560" height="315" src="https://www.youtube.com/watch?v=FqXtciXfjzw" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" loading="lazy" allowfullscreen></iframe>

![003_youtube_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/235cd4e3-1e65-1500-80bc-dcf84f049586.png)


[MEMSマザーボード: STEVAL-MKI109V3](https://www.st.com/content/st_com/ja/products/evaluation-tools/product-evaluation-tools/mems-motion-sensor-eval-boards/steval-mki109v3.html)

[標準DIL24ソケット用LSM6DSOXアダプタ･ボード](https://www.st.com/content/st_com/ja/products/evaluation-tools/product-evaluation-tools/mems-motion-sensor-eval-boards/steval-mki197v1.html)

[機械学習コア･スペシャルサイト](https://www.st.com/content/st_com/ja/campaigns/mlc_promotion_page_apps.html)

SensorTile.boxに搭載されているセンサ「LSM6DSOX」は、ディシジョン･ツリー情報を含むコンフィギュレーション･データ（UCF）をセンサのレジスタへ書き込むことで判断作業を行えるようになります。つまり、センサで実行できるのは、シンプルに「事前学習で設計・設定された判定方法」に基づく判断です。動作中も学習して進化し続けるというわけではありませんのでご注意ください。

### LSM6DSOXで実行できる判定

サンプル･データを眺めていると、具体的にどのような判定ができるのか想像できます。詳しくは後で見ますが、2つほど取り上げて以下に紹介します（その他サンプルは下の表を参照）。

 **ポジション検知** : 置かれた6面体（直方体・立方体）がどの方向を向いているかの判定
最も簡単な例で、静止状態における各軸の **加速度平均値** を使用します。使用センサは加速度（ACC）のみ。地球重力をもとに、どの面が上を向いているかを判断します。地磁気センサは使っていないので、東や西といった方角認識はできず、単純にサイコロのような機能となります。わざわざMLCを使わなくてもできそうですが、サンプルということで用意されています。ディシジョン･ツリーも少なく、構成ノード数は8。

 **アクティビティ検知** : 人の動作状態。直立静止/ 歩行 / 走行などの判定
動きの特徴を判定に取り込むので、多少複雑です。サンプルを見るとスマホ向け用とスマートウォッチ（リストバンド）向け用の2種があります。対象機器がスマホの場合、置かれる方向がさまざまなので、より複雑なディシジョン･ツリー構造（ノード数は120）となっています。一方でリストバンド向けデータの方は、クラス数が少ないのと設置方向がある程度固定されることで、少しシンプルになっている模様（ノード数は70）。
スマホ版で使用されているFeaturesは **加速度平均値** 、 **分散** 、 **ピーク･ツー･ピーク** 、 **ゼロ・クロッシング** の4種で、動きを特徴づけるパラメータが使われています。こちらも使用センサは加速度のみ。




[GitHub ](https://github.com/STMicroelectronics/STMems_Machine_Learning_Core/tree/master/application_examples/lsm6dsox)のMachine Learning Core for LSM6DSOXページに用意されている、ディシジョン･ツリー作成済みのサンプル･データ



|コンフィグ･サンプル     |機能          |目的・判断内容         |ディシジョン･ツリー・ノード|Window/MLC_ODR（\*1）|Features|
|:------------:|:---------:|:--------:|:--------:|:--------:|:--------:|
| 6D position recognition |ポジション検知|モノ（直方体の箱のようなものを想定）がどの方向に置かれているかを6方向に対して検出|8|16/26 = 0.6s|mean signed, mean unsigned /(ACC)|
| Activity recognition for mobile        |アクティビティ検知（スマホ想定）        |人の状態検知（直立静止・歩行・走行・自転車運転・車運転）      |120|75/26 = 3s|mean, variance, peak-to-peak, zero-crossing /(ACC)|
| Activity recognition for wrist        |アクティビティ検知（スマートウォッチ想定）   |人の状態検知 （直立静止・歩行・走行）       |70|52/26 = 2s|mean, variance, energy, peak-to-peak, zero-crossing, min, max /(ACC)|
| Gym activity recognition |フォーム検知|スポーツジムでの動作状態（フォーム）を検知|30|78/26 = 3s|mean, peak-to-peak, min, max /(ACC)|
| Head gestures        |頭状態検知        |頭の動き（ヘッドセット想定）によるイエス・ノーのジェスチャ判定など       |7|26/26 = 1s|多数 /(ACC and Gyro)|
| Vehicle stationary detection       |車状態検知   |走行中 / 停止中       |30|52/52=1s|mean, variance, energy, peak-to-peak, min, max /(ACC and Gyro)|
| Vibration monitoring        |振動検知        |振動 / 静止      |2|16/26 = 0.6s|peak-to-peak /(ACC)|
| Yoga pose recognition     |ヨガ・ポーズ検知   |14種類のヨガ・ポーズ判定       |20|52/104 = 0.5s|mean /(ACC)|

\*1
Window: 下記参照
MLC_ODR（Output Data Rate）: （MLC入力用）センサ･データの出力レート
Window/MLC_ODR: 1判定に要するデータ収集時間

##### 主なFeatures（特徴量）



![005_Features.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/46113b39-f72b-b07c-d989-bacbcec3c2be.png)



WL（Window Length）: 1回のFeatures演算に使われるデータ個数（ウインドウ幅）

LSM6DSOXがセンシングできる物理量は加速度と角速度です。つまり、この2つのセンサ･データを使って得られるFeaturesに限られます。継続した動きや回転、姿勢に対して、特徴付けできそうなFeaturesを選び、それに基づいてディシジョン･ツリーを作成するという流れになります。設定後はデバイス側で判定できます。
FFTは入っていないので、振動周波数を元に判断するのは無理だろうと思いましたが、人間の動き程度であれば似たようなデータを得られるFeaturesがありました。“zero crossing”（クロス回数検出）や“peak detector”（ピーク回数検出）などを使えばある程度振動の速さに関連する特徴付けはできると思います。

判定作業は、いわゆる「パケット」のような、データのかたまりに分けて行われます。1回の判定に何個の連続データを使うのかを示すのがWindowというパラメータです。上の表内、6D position recognitionの場合、16個のデータごとにFeaturesを演算するので、MLC_ODR = 26Hzとすると約0.6秒おき（16/26）に判定されます。一方、Activity recognition for mobileなどは3秒程度かかるので、少なくとも3秒以上は動きのパターンを継続させる必要があります。このあたりの設定もディシジョン･ツリー設計のノウハウに関連するので、対象物次第だとは思います。






その他参考動画（Youtube）:
[Design Tips for Machine Learning algorithms generation (part 1)](https://www.youtube.com/watch?v=Qyq_N-dG2uI&list=PLnMKNibPkDnHPjJKRZeXCIyrHwZJctvAI&index=7)
[Design Tips for Machine Learning algorithms generation (part 2)](https://www.youtube.com/watch?v=jnbaf8kmpu4&list=PLnMKNibPkDnHPjJKRZeXCIyrHwZJctvAI&index=8)



## 2．準備

実際にデータを集めるのは色々と手間もかかるので、まずは学習済みのサンプル･データを用いて試してみます。ディシジョン･ツリー生成まで終えてできあがった、センサへの書き込み用ファイル（xxx.ucf: Unico Configuration File）を使います。これはUnico-GUIツールを使って生成されたコンフィギュレーション･ファイルです。ダウンロード方法は2つあります。

•	スマホで直接ダウンロード（ファイル毎ダウンロード）
•	パソコンからダウンロード → スマホへファイル転送（一括ダウンロード可能）

サンプル･データはいくつか用意されていますが、第3章で **ポジション検知サンプル（ 6D position recognition）** を試してみますので、ここではそのucfファイルを入手します。とりあえず必要なファイルはこちらサンプルのucfファイル1点だけなので、スマホで直接ダウンロードします。
他のサンプルや関連ファイルをまとめてダウンロードしたい場合は、パソコン経由でのダウンロードをおすすめします。zipファイルでダウンロード後に解凍すれば、全てのサンプル･ファイルを閲覧･使用可能です。補足2を参照ください。
GitHubサイトにて、STMicroelectornics/STMems_Machine_Learning_Coreのページを開きます（スマホのブラウザで、“github st mlc”などと検索してください）。 **View code** クリック後、対象のファイルの場所までフォルダを下っていきます。
該当ファイルの場所:

該当ファイルの場所： **STMems_Machine_Learning_Core/application_examples/lsm6dsox/6D position recognition/** 

![200_Github_smartphone_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/e3ba9756-e690-a6bd-cb8e-38a0d085fe65.png)


対象ファイルは **lsm6dsox_six_d_position.ucf** です。ファイルを開いたのち、以下手順でダウンロードします。


![200_Github_smartphone_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/c3788ea6-9fd1-32a7-ced3-9877803c4923.png)


ダウンロードの際に“.txt”拡張子が追加されてしまいますので、これを削除しておきます。Filesアプリなどで該当ファイルを確認後、Renameしてください。


![200_Github_smartphone_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/c19e3635-aab4-02af-e38a-e78f5273e645.png)







以上で準備完了です。



## 3．ポジション検知: 6D position recognition

それでは実際にUCFサンプル･データを使ってアプリで動かしてみましょう。今回の記事ではポジション検知サンプルを試してみます。 置かれた6面体（直方体・立方体）について、どの面が上を向いているかを判定します。

### 3-1．セットアップ


以下手順でカスタムアプリをセットアップします。
設定内容

- 入力センサ: MLC Virtual Sensor
- ファンクション: なし（ソフト仕様上、ファンクションは設定しません）
- Bluetooth®でスマホへ（スマホ側でデータを受信するようにします）



##### 新規アプリ作成
Expert modeから新規アプリ作成へ進みます。

![310_6d_setup1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/787801d8-f836-6756-baa6-8fb2b40d343b.png)


##### 入力センサ選択 & ucfファイル設定

MLC使用時は、仮想センサとして **MLC Virtual sensor** を選択後（= LSM6DSOX）、MLC用のコンフィグレーション･ファイル（.ucf）を設定します。さきほどGitHubからダウンロードしてスマホのストレージに保存しましたので（Defaultでは“Download”フォルダに入ってます）、そこから探します。ファイル･フォルダ表示はスマホによって異なります。

![311_6d_setup2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/f680c08d-cc5d-95df-8719-c8d38a02a3fb.png)



##### ucfファイル設定完了、出力先設定

![312_6d_setup3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/8e910fb2-0fc7-5070-62ec-a1e7707ce6a1.png)



##### アプリ全体セーブ後、SensorTileboxへ設定データ送信

最後にアプリ名を入力して保存します。ここでは“mlc 6d position”としました。その後自動的に再接続します。STBLESensorアプリを再起動などして最初から行う場合、Expert modeのページから今回作成した“mlc 6d position”アプリを選択して接続します。 

![313_6d_setup4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/fbecc5f0-0bfb-80da-0097-0f3a2369668e.png)


##### 設定まとめ

|           |選択アイテム        | 設定内容  |
|:------------:|:---------:|:--------:|
|Input  | MLC Virtual Sensor（LSM6DSOX）|ucf: lsm6dsox_six_d_position.ucf|
|Function  |無し||
|Output  |Stream to Bluetooth|Bluetooth経由でスマホへ演算結果送信|



### 3-2．動作確認


SensorTile.boxの置き方を変えると、 **Decision Tree 0: DT1** の値が変化（1 ~ 6の数字で表記）します。
このサンプルの試行では動作に動きが無いのであまり加速度センサMLCの恩恵を感じませんが、一応デバイスだけでサイコロのような機能を実現できます。



![320_6d_result1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/59b2d5c4-b073-3e78-91ad-b954a65f3481.png)



![321_6d_result2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/08d318a2-03e4-a631-f3b8-9dc84290788a.png)



ログを取ってエクセルで開くとこんな感じです。値が変化した時に記録されるようです。
すばやく方向を変えるとダイレクトに値が変わりますが（例: 3→6）、ゆっくり動かすと一度“ゼロ”がセットされます（例: 5→0→3）。スマホの出力表示でも同じでした。
16サンプルを１つのWindow（Features演算用のひとつのデータのかたまり。MLC_ODR=26Hz設定なので、16サンプル分→約0.6秒（16/26））として演算・判定してますので、動かし方・タイミングよっては不明値（ゼロ）と判定されるのでしょう。また、中途半端な角度（斜め状態）で維持した場合はゼロ値が継続します。


![322_6d_result_excel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/40efa427-6eda-a451-0af1-d181ac847d61.png)



##### ラベル追加
結果が数字だけではわからないので、ラベリングしました。以下手順で設定できます。“1”に対して“X up”などとラベリングするとわかりやすくなります。


![323_6d_label.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/a8d8b8a7-8bd8-c926-93c5-0dc454b5df7c.png)


![324_6d_label.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/c98207c2-3901-f17d-b7b8-1eeba4530d56.png)


### 3-3．ディシジョン･ツリー

GitHubのファイルの中にディシジョン･ツリー情報はありませんでしたが、LSM6DSOXのアプリケーション･ノート（[AN5259](https://www.st.com/content/ccc/resource/technical/document/application_note/group1/5f/d8/0a/fe/04/f0/4c/b8/DM00563460/files/DM00563460.pdf/jcr:content/translations/en.DM00563460.pdf)）を見ると、EXAMPLEの説明のところに6D position recognition用のディシジョン･ツリーの図が載っていました。判定値として使われている0.3という数値の単位については、次回実際にデータ収集を行う際に確認してみたいと思います。


![330_DicisionTree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/73641bd3-30e4-813c-ca66-3a8c6b84c5ff.png)


#### 補足1

このポジション検知サンプル（6D position recognition）ですが、実はわざわざこのようなMLC設定作業をしなくても、LSM6DSOXには同等の機能が備わっています（レジスタ: D6D_SRC（1Dh））。MLCを利用しない別のアルゴリズムのようですが、どの軸方向が上（鉛直上向き）を向いているかという検出目的としては同じです。ポジション検知の他にもいくつかイベント検出機能が入っています。
興味のある方はデータシートやアプリケーションノートを参照してください。

##### LSM6DSOXが持つイベント検出機能・ハードウェアIPによる拡張機能


|           |機能      |レジスタ|Note   |
|:------------:|:--------:|:--------:|:--------:|
|Free-fall  |落下検出|ALL_INT_SRC（1Ah） D0, WAKE_UP_SRC（1Bh）||
|Wakeup  |ウェイクアップ検出|ALL_INT_SRC（1Ah） D1, WAKE_UP_SRC（1Bh）||
|6D/4D orientation  |6D/4Dオリエンテーション（ポジション検知）|ALL_INT_SRC（1Ah） D4, D6D_SRC（1Dh）||
|Click and double-click  |クリック / ダブルクリック検出|ALL_INT_SRC（1Ah） D3-D2, TAP_SRC（1Ch）||
|Activity/Inactivity recognition & Stationary / Motion detection |アクティブ / インアクティブ検出（スリープ検知）、静止状態・動作状態検出|ALL_INT_SRC（1Ah） D5, WAKE_UP_SRC（1Bh）||
|Pedometer functions |歩数計|EMB_FUNC_EN_A register: 04h, STEP_COUNTER_H / _L: 63h-64h|（ハードウェアIP）|
|Tilt |傾き検出|EMB_FUNC_EN_A register: 04h|（ハードウェアIP）|
|Significant Motion Detection |動き検出|EMB_FUNC_EN_A register: 04h|（ハードウェアIP）|


#### 補足2

GitHub内サンプル･データを、パソコン経由で入手する方法を紹介します。
GitHub内STMicroelectronicsレポジトリにいくつかのサンプル･データが保存されてますが、ここではまとめてダウンロードします。トップページの **Code** より、zipファイルをダウンロードして解凍してください。

ダウンロードはこちら: [GitHub Machine Learning Core](https://github.com/STMicroelectronics/STMems_Machine_Learning_Core)



![400_Github.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/dedc5d41-c76b-ea85-3db6-330437044ef2.png)



次にスマホをパソコンに接続します。 **lsm6dsox** フォルダ下にいくつかサンプルフォルダがありますが、スマホのストレージに全フォルダをコピーしておけば全てのサンプルを試せます。なお、スマホでのダウンロードの際に必要だった、ファイル名のRename操作（拡張子“.txt”の削除）は不要です。

D:\...\STMems_Machine_Learning_Core-master\STMems_Machine_Learning_Core-master\application_examples\lsm6dsox



![410_lsm6dsox_examples.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/1c6daa5a-5da7-81b4-2646-7415275e4a39.png)





以上、今回は機械学習のサンプル･データを試してみました。
動きのあるものでもテストをしてみたいので、次回はもうひとつ別のサンプルを試してみます。

"「ジム･アクティビティ検出」を使って、ジムなどで行うトレーニング時のフォームを検出"
[小型IoT端末開発キット「SensorTile.box」 を使って機械学習を体験②](https://qiita.com/ykawano/items/fb3949fde6e7df8302d2)