スマートウォッチの加速度計データとニューラルネットワークを利用してヨガのポーズを区別できるか?


Rebuild: Aftershow 126: Everything Except Mayonnaise (higepon)で紹介したプロジェクト。Machine Learning | Coursera機械学習のクラスを修了した。理解を確認するために小さなプロジェクトを作っていたので紹介。実用性はいまのところない。

まとめ

  • Pebble Time Round(スマートウォッチ)の加速度系データ (x, y, z) を入力にしてヨガのポーズを区別できるようになるか試してみた
  • Supervised Learning なので training/test/validation set データを手動で作成
  • Hidden layer 1 つのニューラルネットワークで学習させた
  • ヨガ以外の活動(徒歩、スマホをいじってる)、Downward dog ポーズ、Warrior 2 ポーズの 3 つをある程度区別できるようになった

Training data の準備

簡単な Pebble のアプリを C で書いて加速度計データ (x, y, z) を 50 msec 毎に記録。約 4 秒の time window に対して正解データを用意した。
例)4 秒かけて Downward dog ポーズをして加速度計データを入力として、正解データを Downward dog とする
なお僕は左利きなので、これらは Pebble を右手につけたデータである。

データ例

ニューラルネットワークで学習

Training data を Hidden Layer 1つのニューラルネットワークで学習させる(=Theta を得る)。Regularization 項 lambda は validation curve を描いて最適なものを決定した。当初は入力を加速度の delta (x, y, z) としていたが、じつはユークリッド距離を使ったほうが精度が出ることが分かったので x^2 + y^2 + z^2 を利用した。また学習がうまく行っているかは Learning Curve を描いて確認した。
Octaveスクリプトdownward_dog/train.m)を書き学習し、cross validation を行い未知のデータに対して正しい Prediction ができるかを確認。最終的にその Theta Matrix を利用した。

validation curve


Pebble で Prediction

想定しているユースケースは Pebble でアプリを立ち上げる。ヨガポーズをとる。正しく分類できているか確認。という流れなので Pebble アプリで Prediction をしないといけないのだがハマった。組み込みの罠。当初は Theta Matrix を C のヘッダーファイルに定義された double の配列でアプリにリンクしようとした。しかしアプリバイナリの上限サイズに引っかかり失敗。その後アプリのリソースファイルとして外出ししたがやはりメモリが足りず失敗。PCA でデータ量を方針に転換し、実際にデータ量を減らせたがまだ足りず。結局 Pebble の Companion アプリとして iPhone アプリを作って bluetooth でデータを送り iPhone 側で計算してもらうことにした。パイプラインが一段複雑になったので実装が面倒だった。

結果

  • あらかじめ用意した Training data で学習した結果、100% の精度で Predict ができた
  • すべてのパイプラインをつなげて動的に Predict させるとそこまでの精度ではない。8割くらいかな。(Precision/Recall を計算すべきだがしてない)。


Prediction

1: 非ヨガ活動中
2: Downward dog
3: Warrior2。

Answer           Prediction
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 1.000000       1.000000
 2.000000       2.000000
 2.000000       2.000000
 3.000000       3.000000
 3.000000       3.000000

苦労した点

  • Coursera の Machine Learning コースで Octave を何回もさわって慣れていると思ったが甘かった。課題はデータやグラフが正しく御膳立てされていることがよく分かった
  • Matrix の次元があわず。ということが頻出した。細部まで理解していないことが発覚
  • Objective-C の Prediction 側でバグを入れてしまい。なかなかそれに気づけなかった
  • 組み込みの罠
  • Training/アプリともに同じプログラミング言語で書くとかなり楽になると思う。C, Objective-COctave 3つでやるのはオーバーヘッドがあった。

リソース

UI はほとんどない。コードも全く整理していないので注意。