事前機械学習モデル Sound Classifier を使う
音に応答ページで説明したプログラムは、 コンピュータの内蔵マイク、あるいは接続されたマイクから入力した音の大きさだけに応答するものでした。 入力した音声を識別して、特定の言葉で処理を指示するようにしてみよう。それには ml5.jsライブラリが提供する音声識別のための、 事前機械学習モデル SoundClassiferを使います。
ml5.jsは、Googleが開発した機械学習システムTensorFlowを活用して開発されており、自分のスケッチに機械学習機能を組み込み、簡単な「AI」プログラムを作ることを助けるライブラリです。
SoundClassifierには、事前に学習させた学習モデル"SpeechCommands18w"が用意されています。 "SpeechCommands18w"は、"0"から"9"までの10個の数字、"up"、"down"、 "left"、"right"、"go"、 "stop"、"yes"、"no"の18個の言葉、そして、"未知の単語"と "バックグラウンドノイズ"を認識します。
ml5.jsライブラリを使うために、次のscriptタグをindex.html内に指定します。
<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"> </script>ネットワークを経由してライブラリを配信する仕組みであるCDN(Contents Delivery Network)のサイトを通じて、ml5.jsライブラリを参照する指定です。
SoundClassifierを使う
(1) SoundClassfierを作るまず、変数を用意し、
let classfier;preload()関数内で、ml5.soundClassifier()を使って、SoundClassfierを作ります。引数には学習済モデル"SpeechCommands18w"を指定します。
function preload() { classifier = ml5.soundClassifier('SpeechCommands18w'); }SoundClassfierは、デフォルトで、PCの内臓マイクを通して音声を入力します。
(2) SoundClassfierにコールバック関数を設定する
SoundClassfierは音声を認識したら、コールバック関数として設定されている関数を実行します。 コールバック関数とは、ある処理が終了したタイミングで実行される関数(処理)のことを指します。
setup()関数内で、SoundClassfierに対して、classifyStart()メソッドを使って、コールバック関数を設定します。
classifier.classifyStart(gotResult); //コールバック関数の名前を指定
(3) コールバック関数を定義する
音声を認識したらどのような処理をするかをコールバック関数内に定義します。 SoundClassfierのコールバック関数の第1引数はエラー、第2引数は結果の配列です。
function gotResult(results) { console.log(results); //認識結果が配列results[]に入る、テストとしてコンソールに出力 }結果の配列の要素は連想配列と呼ばれるJavaScriptのデータ構造で、その数は20です。認識した語(label)とその判定の信頼度(confidence)が、信頼度の順に次のように格納されています。
[{label: 'one', confidence: 0.9905231595039368}, {label: 'no', confidence: 0.009330233559012413}, ......]連想配列はキーと値をコロンで繋いだセットからなり、そのセットをカンマで区切って並べ、{と}で囲んだ形をしています。
{ キー1: 値1, キー2: 値2, ……}
連想配列の値を取り出すには、ピリオドの後ろにキーを指定します(これをドット記法といいます)。 例えば、一番信頼度の高い語(結果配列の最初の要素のキーlabelの値)は次のように得られます。
results[0].labelあるいは、キーを配列のインデックスとして使って次のようにも書けます。ここではドット記法を使います。
results[0]["label"]
(4) 必要なら、SoundClassfierにオプションを設定する
SoundClassfierを作る時に、オプションを指定することができます。 例えば、音声の認識の信頼度が高い時だけ、コールバック関数を実行するように指定できます。
下のように認識確率の閾値を指定すると、認識した言葉の確率が0.9以上の時にだけコールバック関数が呼び出されます。
function preload() { let options = { probabilityThreshold: 0.9 }; //0.9以上の信頼度の時だけ処理をする classifier = ml5.soundClassifier('SpeechCommands18w', options); }
言葉を認識して反応
マイクからの入力音声を識別し、認識した数の円を描くスケッチが、リスト7_1です。一番高い信頼度で識別した語がoneからnineまでの数字であれば、その数の円を描き、それ以外の場合は描きません。どのような言葉が識別されたかを示すために、信頼度の一番高い語のラベルと信頼度を表示しています。
【リスト7-1】 let classifier; let num = 0; //何個円を描くか let x = 50; //最初の円のx座標 let label = ""; //一番信頼度の高い語 let conf = 0; //一番高い信頼度 function preload() { let options = { probabilityThreshold: 0.9 }; classifier = ml5.soundClassifier('SpeechCommands18w', options); } function setup() { createCanvas(300, 100); classifier.classifyStart(gotResult); noStroke(); } function gotResult(results) { label = results[0].label; conf = results[0].confidence; if (results[0].label == "one") { num = 1; } else if (results[0].label == "two") { num = 2; } else if (results[0].label == "three") { num = 3; } else if (results[0].label == "four") { num = 4; } else if (results[0].label == "five") { num = 5; } else if (results[0].label == "six") { num = 6; } else if (results[0].label == "seven") { num = 7; } else if (results[0].label == "eight") { num = 8; } else if (results[0].label == "nine") { num = 9; } else { num = 0; } } function draw() { background(220); fill(200, 0, 0); for (let i=0; i<num; i++) { ellipse(x+i*20, height/2, 10, 10); } fill(0); text("label: " + label + ", confidence: " + conf, 10, height-10); }