こんにちは、9月からCerevoでプロジェクトマネージャーをしている後藤です。
子供の頃に秘密基地を作って遊んだ時、ノックのパターンを決めて「ひみつのあんごう」なんていってましたよね?
そんな「ひみつのあんごうノック」で開く箱を作ってみました。
この箱の仕組みについて、今回紹介していきます。
目次
「ひみつのあんごうノック」の仕組み
巷ではAIという言葉が氾濫していますが、エンジニアとして実際着手するとなると特にこの分野は学習コストが高く結構とっつきにくいですよね。
でも去年あたりからマイコンでも機械学習モジュールが動くようになってきたので触ってみることにしました。今回使ったEdge Impulseというサービスでは機械学習で必要になるデータ収集や可視化ツールがそろっており、マイコンから直接学習データがサンプリングできたり、非常に使いやすい印象を受けました。
せっかく機械学習を使ってみるのでマイコンでは扱いにくいデータがいいなと思い、今回の「ひみつのあんごうノック」を検出するものを作りました。
※とは言いつつ、結論から言うと、必ずしも機械学習処理は必要の無いものになりました。下記「おわりに」参照。
機械学習で「ひみつのあんごうノック」の箱作り
マイコンは家に転がっていたSeeed StudioのWioTerminalがEdge Impulseに対応していたためそれを使用しました。
データ集め
まずEdge Impulseでデータを集めます。音の場合1ラベルあたり10分程度のサンプルが必要とのことなので、サンプリング長が1秒で1ラベルあたり600サンプル程度必要になります。幸いEdge Impulseのページに音のデータセットがあり、その中から10分程度のnoiseおよびunknownデータを利用しました。
今回はテーブルのノック音が特定のリズムの時にだけ開けたいので特定のリズムの音をrhythmとラベリングし、それ以外のノック音をknockとしたものをそれぞれ10分程度集めました。
Seeed Studioが用意しているWioTerminalのサンプリング用ファームウェアをデバイスにロードしシリアル経由でサンプリングしましたが、通信が遅く1分ぶんのデータを作るのも非常に時間がかかったため、平行してスマホ経由でサンプリングできる機能も利用してサンプリングしました。サンプリングしたデータは該当部分だけこのように切り出してラベリングします。
そしてこの作業をrhythmラベルとknockラベル2種類分、計20分/1200サンプル程度録音、切り分けを行いました。
と、簡単に書きましたがもちろんとても時間がかかりました。
処理方式の選択
データ収集が完了したところでデータの処理方式を選びます。
基本的に一定間隔でデータにFFT処理をしていくのですが、今回は声以外音の選別によく使われるMFEと、人間の声の帯域に特化したMFCCを比べてみました。結果的にMFCCの方が成績が良かったためMFCCを使用しました。(詳しく調べていないのですが、MFEのモジュールは時系列情報が入っていない?)
この辺りもWebインターフェース上でモジュールを選択していくだけなので非常に簡単にできます。
機械学習モジュールの選択
次のステップでは機械学習モジュールを選びます。
今回は基本の1D Convolution Arrayを使いました。設定もデフォルトのままで認識率90%前後が達成できました。
学習結果はConfusion Matrixと3次元グラフで表示され、一つ一つのデータにもアクセスできる大変わかりやすいインターフェースになっていました。裏ではKerasが動いておりExpert ModeにするとPythonスクリプトを操作出来るようになっています。
下のスクリーンショットを見ると予想通りknockとrhythmの切り分けが難しいようです。
学習結果のテスト
Edge Impulse上ではテスト用データとリアルタイム判定で学習結果をテストすることができます。試行錯誤した結果、今回80後半~90%近い正答率を得ることが出来ました。
学習結果をEdge Impulse上からC++またはArduinoのコードとしてダウンロードすることができます。
今回はそのコードをArduinoライブラリとしてダウンロードし、PlatformIOでライブラリとして読み込んだ上でコードを動かすことにしました。
箱(ケース)作り
ケースはAutodesk® Fusion 360でデザインして3Dプリントすることにしました。ボックスはWioTerminalのサイズ基準(ほぼ名刺サイズ)としました。
ピンヘッダに直接基板が挿さるようにし、サーボモーターも基板の上に固定することにして簡易的に箱として組めるようにしています。
ヒンジの支点が箱の内側にくるようにすることで外側ヒンジ構造が見えない構造とし、また指を引っ掛けてふたを無理やり開けることができないよう、ふたが箱の側面と同じ高さまで埋まるようにしました。
時間がない中、慌てて作ったためヒンジ構造にピンを開け忘れたり、部品同士にあたりがある状態でプリントしてしまい、結果色々と追加加工することになりました。
ノックに反応して開く箱、完成!
いろいろありましたが完成したものがこちらです。
現状のコードでは音のサンプリング部分がブロッキングで動いており理想的ではないのですが、一応特定のノックに反応して開く箱が完成しました!
中にアメを入れておくとなかなか取り出せなくて面白いです。
おわりに
で、ここまで読んでいただいた方は気づいたかも知れませんが、ノックの様なパルスパターンに反応するだけであればパルスの間隔を判定すれば良いわけで、実は機械学習をさせなくてもパターンマッチングロジックが書ければ実現できそうです。
機械学習アプローチの場合は、もしノックのパターンが変わってしまった場合、再度大量のデータを取り直さないといけないですね(転移学習がこのワークフローでも適用できればいいのですが)。また誤認識もそれなりにありました。
ただし他の音、例えば機械の特定の異音を測定したい場合はどうでしょう?
機械学習のアプローチであれば、十分なデータが用意できれば判定ロジックを試行錯誤して実装するより有効かもしれません。
今までは機械学習による判定を行うには最低限RaspberryPiクラスのデバイスが必要だったのですが、マイコンクラス(今回はARM-Cortex M4F)のMCUで使えるようになってくると用途が広がりそうです。その一方でこのようなデータドリブン型の処理は従来のやり方と非常にアプローチが違い、戸惑うところも多いと感じました。
機械学習系の処理が増えてくるとエンジニアリング時のマインドセットも切り替えていかないといけないですね。引き続き勉強します!
エンジニア積極採用中
現在Cerevoでは各種エンジニアの採用、またハードウェア共同開発・受託開発を絶賛募集しております。それぞれご関心お持ちいただける方は、以下の専用お問い合わせフォームよりご連絡お待ちしております。
- 現在募集している職種
https://cerevo.com/recruit/
- ハードウェア共同開発および受託開発のご相談
https://cerevo.com/contact/sales/
著者プロフィール
- 開発部でプロジェクトマネージャをしています。