Raspberry Pi Mic HAT 上で TensorFlow Lite を用いたキーワードスポッティング
はじめに
このプロジェクトでは、TensorFlow Lite を使用して ReSpeaker 2-Mics Pi HAT v2 上でキーワードスポッティングを行う方法を紹介します。キーワードスポッティングは、音声入力からあらかじめ定義された単語をリアルタイムに検出する技術であり、音声制御デバイスやインタラクティブシステムなどのアプリケーションを実現できます。ここでは、TensorFlow Lite モデルを学習し、ReSpeaker HAT にデプロイし、ローカルで音声認識を実行するまでの手順を順を追って説明します。
ハードウェアおよびソフトウェア要件
- ハードウェア: ReSpeaker 2-Mics Pi HAT v2 を搭載した Raspberry Pi
- ソフトウェア: TensorFlow Lite、Google Colab、Python、および関連ライブラリ
応用例
キーワードスポッティングは次のような用途に利用できます:
- スマートホームデバイス
- 音声制御ロボット
- インタラクティブキオスク
TensorFlow Lite とは?
TensorFlow Lite は、モバイルおよび組み込みデバイス向けに設計された TensorFlow の軽量版です。低レイテンシかつ小さなバイナリサイズで機械学習の推論を実行できるため、Raspberry Pi のようなエッジデバイス上でモデルを動作させるのに最適です。
TensorFlow Lite モデルの学習と取得
データセット
学習には Speech Commands データセットのサブセットを使用します。このデータセットには、人々がさまざまな単語を発話した WAV 音声ファイルが含まれており、Google によって収集され、CC BY ライセンスの下で公開されています。データセットはここからダウンロードできます。データセットの詳細については、このガイドを参照してください。
なぜ Google Colab を使うのか?
Google Colab は、Jupyter Notebook を実行するためのクラウドベースのプラットフォームです。GPU リソースに無料でアクセスできるため、ローカルの計算能力を必要とせずに機械学習モデルを学習させるのに最適な選択肢です。
手順
ここでは Google Colab Notebook を使用してデータの学習を行い、.tflite 形式の TensorFlow Lite モデルを生成します。
-
Step 1. この Python Notebook を開きます

デフォルトでは、Speech Commands データセットの小規模版である mini Speech Commands データセット が読み込まれます。元のデータセットは、35 種類の単語を人々が発話した、WAV(Waveform)音声ファイル形式の 105,000 以上の音声ファイルで構成されています。このデータは Google によって収集され、CC BY ライセンスの下で公開されています。
-
Step 2. Changing runtime type -> CPU -> Save を選択して新しいランタイムに接続し、その後 Connect をクリックします。

-
Step 3.
Runtime > Run allに移動して、すべてのコードセルを実行します。この処理には約 10 分かかります。
-
Step 4. すべてのコードセルの実行が完了したら、新しいセルを追加し、次のコードを実行して
.tfliteモデルファイルを生成します。converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
with open('model.tflite', 'wb') as f:
f.write(tflite_model)
-
Step 5. 生成された
model.tfliteファイルを右クリックし、Download を選択してコンピュータに保存します。
ローカル推論
推論スクリプトの実行
スクリプト inference.py は、次の手順を実行します:
- 学習済みの TensorFlow Lite モデルを読み込みます。
- 入力音声を推論に適したスペクトログラムに変換します。
- 推論を実行し、検出されたキーワードと各ラベルの信頼度スコアを出力します。
実行手順
-
model.tfliteモデルファイルを Pi にアップロードします。この例では~/speech_recognition/model.tfliteに配置します。 -
次のスクリプトを
~/speech_recognition/inference.pyとして保存します:import numpy as np
from scipy import signal
from tflite_runtime.interpreter import Interpreter
import soundfile as sf
MODEL_PATH = 'model.tflite'
LABELS = ['no', 'yes', 'down', 'go', 'left', 'up', 'right', 'stop']
def get_spectrogram(waveform, expected_time_steps=124, expected_freq_bins=129):
_, _, Zxx = signal.stft(
waveform,
fs=16000,
nperseg=255,
noverlap=124,
nfft=256
)
spectrogram = np.abs(Zxx)
if spectrogram.shape[0] != expected_freq_bins:
spectrogram = np.pad(spectrogram, ((
0, expected_freq_bins - spectrogram.shape[0]), (0, 0)), mode='constant')
if spectrogram.shape[1] != expected_time_steps:
spectrogram = np.pad(spectrogram, ((
0, 0), (0, expected_time_steps - spectrogram.shape[1])), mode='constant')
if spectrogram.shape != (expected_freq_bins, expected_time_steps):
raise ValueError(
f"Invalid spectrogram shape. Got {spectrogram.shape}, expected ({expected_freq_bins}, {expected_time_steps})."
)
spectrogram = np.transpose(spectrogram)
return spectrogram
def preprocess_audio(file_path):
waveform, sample_rate = sf.read(file_path)
if sample_rate != 16000:
raise ValueError("Expected sample rate is 16 kHz")
if len(waveform.shape) > 1:
waveform = waveform[:, 0]
spectrogram = get_spectrogram(waveform)
spectrogram = spectrogram[..., np.newaxis]
spectrogram = spectrogram[np.newaxis, ...]
return spectrogram
def run_inference(file_path):
spectrogram = preprocess_audio(file_path)
interpreter = Interpreter(MODEL_PATH)
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
input_shape = input_details[0]['shape']
if spectrogram.shape != tuple(input_shape):
raise ValueError(
f"Expected input shape {input_shape}, got {spectrogram.shape}"
)
interpreter.set_tensor(
input_details[0]['index'], spectrogram.astype(np.float32))
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])[0]
prediction = np.argmax(output_data)
confidence = np.exp(output_data) / \
np.sum(np.exp(output_data))
print(f"command: {LABELS[prediction].upper()}")
for label, conf in zip(LABELS, confidence):
print(f"{label}: {conf:.2%}")
if __name__ == "__main__":
audio_file_path = 'test_audio.wav'
run_inference(audio_file_path) -
次のコマンドを使用して音声を録音します。利用可能なキーワードは
no,yes,down,go,left,up,right,stopです。$ arecord -D "plughw:2,0" -f S16_LE -r 16000 -d 1 -t wav ~/speech_recognition/test_audio.wav -
スクリプトを実行します:
$ python3 inference.py
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
command: YES
no: 8.74%
yes: 21.10%
down: 5.85%
go: 14.57%
left: 11.02%
up: 8.25%
right: 10.53%
stop: 19.94%
結果の解釈
スクリプトは、検出されたコマンド(例: YES)と、すべてのラベルに対する信頼度スコアを出力します。これにより、モデルの予測内容を把握し、その性能を評価することができます。
技術サポートと製品ディスカッション
当社の製品をお選びいただきありがとうございます。私たちは、製品をできるだけスムーズにご利用いただけるよう、さまざまなサポートを提供しています。お好みやニーズに応じてお選びいただける、複数のコミュニケーションチャネルをご用意しています。