機械学習モデルとScratchを連携! TM拡張機能使ってみた

前回：[ScratchでLEGO Mindstormsを動かしてみる](https://qiita.com/Hiroki-Fujimoto/items/4841917f81579a2d4f13)

前回に引き続いて今回もScratch上でできる機械学習を試してみる。ビジュアルプログラミング([Scratch](https://ja.wikipedia.org/wiki/Scratch_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E)))の拡張機能として、TM2Scratchというものを使ってみた。
[以前投稿した記事](https://qiita.com/Hiroki-Fujimoto/items/221d5394dc1b4887c437)で紹介したML2Scratchの開発者と同じ方が作成された拡張機能で簡単かつ様々なものを認識・識別できるような学習を施すことができる。  

## TM2Scratch  
今回利用する拡張機能であるTM2Scratchは[TeachableMachine2.0](https://teachablemachine.withgoogle.com/)を利用して、簡単に画像認識や音声認識のモデルを生成し、その生成したモデルをScratch上に反映してプログラム内で利用できるといういうものだ。今回は以下のことをしていく。

1. TeachableMachine2.0上で機械学習モデルを作成する
2. カスタマイズされたScratch3.0を使って、上記の機械学習モデルを読み込んでプログラミングをする

言葉で並べても伝わりづらいと思うので、一つずつ説明していく。
<img width="200" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/e1427483-1f7c-20d8-70b0-72a638df6fb1.png">


## TeachableMachine2.0
[TeachableMachine2.0](https://teachablemachine.withgoogle.com/)とは

* PCのカメラやマイク、画像データなどを使用して、WEB上のGUI操作で機械学習モデルを作ることができる
　(プログラミング不要)
* 作成したモデルの出来具合をすぐ確認することができる
* 作成したモデルをエクスポートしプログラムに利用することができる
* 現時点では画像分類・音声識別・ポーズ認識のモデルを作成することが可能  

## モデル作成
> 1. TeachableMachine2.0上で機械学習モデルを作成する

ではさっそくTeachableMachineでモデルを作成していく。
ML2Scratchでは画像分類を行ったので今回は音声識別のモデルを作成していくことにする。
[TeachableMachine2.0](https://teachablemachine.withgoogle.com/)のサイトにアクセスする。  
アクセスしたら「使ってみる」をクリックする。
<img width="600" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/60ec32b8-f3fe-57fc-c24e-70463e7b1a81.png">

画像、音声、ポーズからどの学習モデルを作るか選択する。
今回は音声を選択する。
<img width="600" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/771900e0-343d-fdb9-34be-b182dfcf83fa.png">

今回は以下のような音を識別させる。

* 手のひらをパーで叩いた音
* 手のひらをグーで叩いた音

<img width="100" alt="25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/32f68da0-59cb-4074-036f-76fa17b6d8d0.png">　　　 <img width="120" alt="26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/cebe43e4-3f60-c1b8-d161-ef045760e2c5.png">


以下のように、いくつかの音声サンプルを追加する画面が表示されるので、
まずはバックグラウンドノイズのデータを採取する。
<img width="600" alt="5-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/fa0ad12c-d90c-5d23-27d5-a69d8547ceee.png">



「マイク」を選択するとPCのマイクを利用して音声を集めることが出来る。
バックグラウンドノイズなので特に音を発したりはせず自然な音のみを収録する。
<img width="400" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/85c4f51e-874e-fc61-db8e-93d80317b308.png">

続いて「Class2」に「手のひらをパーで叩いた音」のデータを収録する。
歯車マークから採取するデータに合わせて収録開始のタイミングや、全体の収録時間を設定することができる。
<img width="200" alt="8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/40cee844-2d23-25a8-898a-50739ca14b78.png">


TeachableMachineでの音声の収録では毎秒ごとに区切って学習データとするので、収録時間は２秒とし、１回の収録で１秒毎に１回手を叩いて収録し合計８サンプルになるよう４回繰り返し収録した。
右の画像から2秒間で2回叩いて音を出しているのがわかる。  
<img width="400" alt="6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/19fb1d76-3e90-c3ed-cb8b-1e21d7e5cf76.png">　　　<img width="300" alt="7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/d84838e7-0fa3-cbd4-3bc7-05bcd693946c.png">


音声データの収録が完了した「Classe2」の名前をパーに変更しておく。
<img width="600" alt="9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/c613c116-4ead-fabb-1027-a37293ab4a41.png">

続いてクラスを追加して手のひらをグーで叩く音を集める。
<img width="600" alt="10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/1d9fb032-5de7-f7c2-d843-12ad57a31337.png">
<img width="600" alt="11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/56959bf1-b8fa-9f3a-1673-721ec56bb291.png">


データを集め終わるとこのような全体像になる。
<img width="800" alt="12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/cfb23257-0aff-8f35-2d7f-ecc51fa3d843.png">

集めたデータを利用して学習モデルを生成していく。「モデルをトレーニングする」を選択して訓練を開始する。
<img width="300" alt="13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/16781e2a-cbf5-4080-6b57-925ae169e6d5.png">


しばらく待ち、訓練が完了するとTeachableMachine上でモデルの動作を確認することができる。まずはここで収録した音声を認識できているか確認する。以下では収録時と同じようにパーで叩くかグーで叩いているがスライダーが認識度合いを表現しているのがわかる。
![MyVideo_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/7614a0d1-7c46-ddca-2429-bea1f165c9ed.gif)
イメージとしてはペチンという音と、ゴチッという音で認識させるには少し微妙な題材かとも思っていたが思ったよりも認識できている。

モデルの動作が確認できたらモデルをエクスポートする。
<img width="200" alt="14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/1533fc7f-e6a2-5cf3-83b7-b1391aa2ae8b.png">


以下のような画面が表示されるので、今回はURL(リンク)を利用する。メモ帳などにコピーしておくと良いだろう。
<img width="500" alt="15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/552d719d-91a4-96aa-3683-7cd39451bc6d.png">


これでモデルの作成は完了したので、続いてScratchで作業をしていく。  


## TM2Scratchを使って音声認識プログラムを作る
> 2.カスタマイズされたScratch3.0を使って、上記の機械学習モデルを読み込んでプログラミングをする  

まずは、[カスタマイズされたScratch](https://stretch3.github.io/)をChrome上で開く。この際カメラやマイクの使用を許可するか選択できるので、必要に応じて許可をする必要がある。  
拡張機能追加から「TM2Scratch」を選択してブロックを追加する。
<img width="600" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/80ca5989-8c49-7585-2c4d-79a1c95ac9ee.png">
<img width="200" alt="16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/ac207e6d-2029-22ee-a4c5-a063e378703d.png">


追加されたブロックを利用してまずは以下のようなプログラムを作る。  
「音声分類モデルURL」ブロックの空白部分には先程メモしておいたURLを貼り付ける。 
<img width="500" alt="17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/aa029295-bfe9-dee4-ba78-5faf35579f77.png">
旗マークをクリックすることで以下のブロックに先程収録する際に作成したclasse名が選択できるようになる。
(今回ではパーやグー)  

<img width="300" alt="18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/a65f71a9-6d74-222e-139a-df98a474fe4e.png">　　<img width="300" alt="19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/4e8f2617-e1ef-ff0e-ea19-c43ddac4ec5c.png">

Scratch上で現在どの音を認識しているのか表示させるために「音声ラベル」の横のチェックボックスにチェックを入れておく。
<img width="200" alt="20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/0ab021d9-dc9f-e248-3917-1e270379957a.png">　　<img width="300" alt="21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/47092972-d340-09be-6e35-a591190c0d7b.png">

モデルをブロックに反映できたので簡単なプログラムを作ってみる。
<img width="500" alt="22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/4f304a50-7a43-a697-e5d1-f26c6fad4bcd.png">


音声ラベルとしてパー、グーをそれぞれ認識した際にステージ上のネコがそれに応じてしゃべるという内容。
<img width="600" alt="23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/c6e2c22a-9d75-df34-2d3f-8ec49a299d85.png">
<img width="600" alt="24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/97aaa5fd-7080-d582-65a2-496cfb89a4a3.png">
ラベルを受け取った際にネコがそれに応じて喋っているのがわかる。  

## TeachableMachineとTM2Scratchを使ってみて
まずTeachableMachineについてだが、画像認識・音声認識・姿勢認識の3分野においてかなり簡単に学習モデルを生成できるのは驚いた。実際にファイルとして出力しJavascriptなどで実装する際に利用できるようだ。  
テキストデータやCSVなどは利用することが出来ないので、用途に応じて使い分けるのが妥当だろうか。  

またScratchへの連携だが、URLを転用するだけで反映できる点がお手軽で、Scratch利用者にもマッチしている。Scratch上でのプログラムへの応用も簡単にできるため非常にお手軽に体験することができた。  

Scratchでも機械学習分野でできることがどんどん広がっていっている。今回の音声認識をLEGO® MINDSTORMS EV3に応用してみるのも面白そうなので実践してみたいと思う。