Teachable Machineとは
Googleが開発した、ブラウザ上で超カンタンに機械学習できるサービスです。
くわしくはこちら
学習できるもの
すでに色々試されています!
- 画像 参考: 爆速で画像認識ができる!?Teachable Machineでカピバラとビーバー判別をしてみた
- 音 参考: toio を音で制御してみた(Audio用の Teachable Machine でベルやタンバリンの音を機械学習)
- ポーズ 「うちでヨガしよう」ヨガポーズがあっているか判定してくれるLINE bot~Node.jsに読み込む~
ポーズを学習させて、モデルデータを作る
まずはブラウザで学習させてみよう
こちらの記事が参考になります!
Teachable Machine を使った音声からの任意のキーワードの検出(ブラウザ上で機械学習)
ここでは音声を学習させていますが、今回はポーズを選択します。
注意!学習中にタブの切り替えをすると止まってしまいます!そのまま、何もせず待ちましょう!
動画入れる
ブラウザ上で、うまく動作することが確認できたら次に進みます。
Teachable Machine(つまり有言実行でQiita書いてるナウ) pic.twitter.com/Bd8mGhjwyV
— はりねずみ麺 (@hedgehog_noodl) April 24, 2020
ちなみに、今回私が学習した、ガニ股検出モデルはコチラで試せます。
モデルデータとScriptのダウンロード
- Export Modelボタンを押す
- Export your modelのDownloadを選択
- Download My modelを押してダウンロード。これが学習したモデルデータです。
作成したモデルデータをNoodlで使う
学習させるのが面倒くさい!という方はコチラからモデルデータをダウンロードしてください!
モデルデータを、Noodlプロジェクトに格納する
ダウンロードしたモデルデータを解凍しフォルダごとNoodlプロジェクトに、格納。
Noodlのプロジェクトデータの場所は、歯車アイコン→Open project folderで開くことが出来ます。
格納するデータは3つ
my-pose-model/
- metadata.json
- model.json
- weights.bin
Script Downloaderノードを作成し、ライブラリを読み込む
ScriptDownloaderノードに、<script src="...
で読み込んでいるjsライブラリのURLを入れる
この2つのライブラリを、ScriptdownloaderノードのExternal Scriptsに入力
https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js
https://cdn.jsdelivr.net/npm/@teachablemachine/pose@0.8/dist/teachablemachine-pose.min.js
Javascriptノードを作成し、下記スクリプトをコピペ
元のJSを、NoodlのJavascriptノードの一番下にコピペします。
define({
// The input ports of the Javascript node, name of input and type
inputs:{
// ExampleInput:'number',
// Available types are 'number', 'string', 'boolean', 'color' and 'signal',
loaded:'signal'
},
// The output ports of the Javascript node, name of output and type
outputs:{
// ExampleOutput:'string',
classLabel:'string',
class1:'number',
class2:'number'
},
// All signal inputs need their own function with the corresponding name that
// will be run when a signal is received on the input.
loaded:function(inputs,outputs) {
init();
},
// This function will be called when any of the inputs have changed
change:function(inputs,outputs) {
outputs.class1 = class1;
outputs.class2 = class2;
this.flagOutputDirty("class1")
this.flagOutputDirty("class2")
this.runNextFrame();
}
})
let model, webcam, maxPredictions, class1, class2;
async function init() {
console.log('init');
const modelURL = "my-pose-model/model.json";
const metadataURL = "my-pose-model/metadata.json";
model = model = await tmPose.load(modelURL, metadataURL);
maxPredictions = model.getTotalClasses();
const size = 200;
const flip = true; // whether to flip the webcam
webcam = new tmPose.Webcam(size, size, flip); // width, height, flip
await webcam.setup(); // request access to the webcam
await webcam.play();
window.requestAnimationFrame(loop);
}
async function loop(timestamp) {
webcam.update(); // update the webcam frame
await predict();
window.requestAnimationFrame(loop);
}
// run the webcam image through the image model
async function predict() {
const { pose, posenetOutput } = await model.estimatePose(webcam.canvas);
// Prediction 2: run input through teachable machine classification model
const prediction = await model.predict(posenetOutput);
class1 = prediction[0].probability.toFixed(2);
class2 = prediction[1].probability.toFixed(2);
}
ノードをつなぐ
図のようにノードを作成してつなぎ、数字が出ていれば成功です!
WebカメラをNoodl画面に表示する
自分の体がきちんと写っているかどうか、わかりにくいためカメラの映像をNoodl画面に表示します。
- 図のようにWeb Camera
ノードとVideo
ノードを作成してつなぐ
- VideoノードのAutoplay
にチェックを入れ、Size Mode
をContent Heightに変更する。
これで、クリックするとWebカメラの映像がストリーム再生されます。
自分がガニ股すると、キャラクターもガニ股するように
下記2枚のイラストをダウンロードし、Noodlプロジェクトに格納してください。(画像をNoodlにドラッグ&ドロップ)
今度は、自分がガニ股したときにガニ股している画像に切り替えるようにしていきます。
※このキャラクターはナルトの成瀬といいます。
Image
ノードを作成し、プロパティを図のようにセットします。
画像の選択は、Source
プロパティをクリックすると格納されている画像一覧が出てきて直感的に選ぶことが出来ます。
先程作ったImage
ノードをコピペし、Source
だけガニ股している画像に変更します。
2つの画像が重なっていればOKです。
さらに、Javascript
ノードとImageノード
をつなぎます。
ポーズの判定結果は、各クラスが0-1.0の数値で出力されます。それをImageノードのOpacity
につなぐことで、
ポーズに合わせて画像の切り替えを行います。
完成〜〜〜!
いい感じです。少し処理が遅れますね。
— はりねずみ麺 (@hedgehog_noodl) April 24, 2020