機械学習で有名なPythonを使って「音声認識」をしてみます。今回は初心者が最も導入しやすいSpeechRecognitionをインストールし、Googleのサービスを使ったGoogle Speech Recognitionによる音声認識プログラミング事例を紹介します。
こんにちは。wat(@watlablog)です。ここではライブラリの力を借りて音声認識プログラミングをトライします!
Speech Recognitionとは?
複数の音声認識サービスを使用できる
SpeechRecognitionはその名の通り音声認識を扱うライブラリです。PyPIとGitHubの公式ページはこちら。
・https://pypi.org/project/SpeechRecognition/
・https://github.com/Uberi/speech_recognition#readme
2023年現在利用できるサービスは以下のとおりです。
- CMU Sphinx (works offline)
- Google Speech Recognition
- Google Cloud Speech API
- Wit.ai
- Microsoft Azure Speech
- Microsoft Bing Voice Recognition (Deprecated)
- Houndify API
- IBM Speech to Text
- Snowboy Hotword Detection (works offline)
- Tensorflow
- Vosk API (works offline)
- OpenAI whisper (works offline)
- Whisper API
様々な音声認識エンジンやWeb APIがありますが、トークンを必要とせずにかなり精度の良いサービスとして中でもGoogle Speech Recognitionが特に人気のようです。
今回は全サービスの精度比較が目的ではなく、手っ取り早く使ってみることを主眼に置くためGoogle Speech Recognitionのみを使っていきたいと思います。
動作環境
今回はWindowsとMacの両方で動作を確認しました。PythonもWindowsの方で現時点の最新版3.11.4を試してみました。PyAudioやPySoundFileはマイクやwavファイルを扱うために使っています。すでに手持ちのwavファイルを使ったSpeechRecognitionの確認には必要ありません。
SpeechRecognitionはpip install SpeechRecognitionでインストールします。
Windows | OS | Windows10 64bit |
---|---|---|
CPU | Intel 11th Core i7-11800H:2.3[GHz] | |
メモリ | 16[GB] |
Mac | OS | macOS Ventura 13.2.1 |
---|---|---|
CPU | 1.4[GHz] | |
メモリ | 8[GB] |
GitHubのReadmeを見ると、Pythonは3.8以上、PyAudioは0.2.11以上が要件のようです。
Python | Python 3.9.6&3.11.4 |
---|---|
PyCharm (IDE) | PyCharm CE 2020.1 |
PySoundFile | 0.9.0.post1 |
PyAudio | 0.2.13 |
SpeechRecognition | 3.10.0 |
wavファイルによる音声認識コード
サンプルのwavファイル
この記事を読んでいる人がすぐにコード検証できるように、サンプルwavファイルを置いておきます。
このwavファイルは「音読さん:https://ondoku3.com/ja/」によって作成しました。テキストを入力するだけでかなり滑らかな日本語を話してくれます(驚き)。
本日はWATLABブログの記事を読んで頂き誠にありがとうございます。
※原文
この記事で使っている音声は「音読さん」によって作成しました。
Pythonで自動文字起こしの検証をするために利用しましたが、かなり滑らかな発音でびっくりです。
クレジット表記としてURLを載せればブログにも載せて良いとの神仕様!音読さんありがとうございます!
全コード
こちらが全コードです。ダウンロードしたwavファイル(または自分で用意したファイル)を.pyファイルのあるフォルダに置き実行することで、コンソールに音声認識結果のテキストが表示されます。
テキストは通常1行で出力されますが、区切りで改行する等少しケアする関数を作ってみました。
自分で用意したwavファイルを使う場合は、filename=の所にファイル名を書いてから実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import speech_recognition as sr def run_recognition(filename): """ wavファイルを受け取って音声認識をする関数 """ # Recognizerをインスタンス化 r = sr.Recognizer() # wavファイルを開いてGoogle Speech Recognitionを実行→テキスト化 with sr.AudioFile(filename) as source: audio = r.record(source) text = r.recognize_google(audio, language='ja') return text def text_formatting(text): """ テキストを空白文字で改行整形する関数 """ # 分割 text_list = text.split() # 文を結合して1つのテキストにする text_join = '\n'.join(text_list) return text_join if __name__ == '__main__': """ Main """ # wavファイルのファイル名 filename = 'sample-speech.wav' # 音声認識を実行 text = run_recognition(filename) # 空白文字で改行する text = text_formatting(text) print(text) |
以下が音声認識結果です。おしい!このブログはWATLABブログなので1箇所間違いですね(単純にMATLABが有名なので、統計的に変換されてしまった??)。
それでもすごい精度です!
本日は
※音声認識結果
MATLAB
ブログの記事を読んで頂き誠にありがとうございます
この記事で使っている音声は音読
さんによって作成しました
Python
で自動文字起こし
の検証をするために利用しましたが
かなり
滑らかな発音でびっくりです
Pythonでwavファイルを作成する方法
PyAudioで録音するコード
上記は模範的なナレーションを使った場合ですが、自分で音声ファイルを作るためのコードも紹介しておきます。こちらのコードはPyAudioを使ってtimeで指定した秒数だけ録音するものです。
「PythonのPyAudioで音声録音する簡単な方法」で紹介した内容ですね。
音が小さくならないようにスケーリング関数も作っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
import pyaudio import numpy as np import soundfile as sf def record(index, samplerate, fs, time): """ 録音する関数 """ pa = pyaudio.PyAudio() # ストリームの開始 data = [] dt = 1 / samplerate stream = pa.open(format=pyaudio.paInt16, channels=1, rate=samplerate, input=True, input_device_index=index, frames_per_buffer=fs) # フレームサイズ毎に音声を録音していくループ for i in range(int(((time / dt) / fs))): frame = stream.read(fs) data.append(frame) # ストリームの終了 stream.stop_stream() stream.close() pa.terminate() # データをまとめる処理 data = b"".join(data) # データをNumpy配列に変換/時間軸を作成 data = np.frombuffer(data, dtype="int16") / float((np.power(2, 16) / 2) - 1) t = np.arange(0, fs * (i + 1) * (1 / samplerate), 1 / samplerate) return data, t def get_mic_index(): """ マイクチャンネルのindexをリストで取得する """ # 最大入力チャンネル数が0でない項目をマイクチャンネルとしてリストに追加 pa = pyaudio.PyAudio() mic_list = [] for i in range(pa.get_device_count()): num_of_input_ch = pa.get_device_info_by_index(i)['maxInputChannels'] if num_of_input_ch != 0: mic_list.append(pa.get_device_info_by_index(i)['index']) return mic_list def scaling(wave): """ 音声データを絶対値の最大値をフルレンジにするようスケーリングする """ # 絶対値波形から最大値を取得 wave_abs = np.abs(wave) wave_max = np.max(wave_abs) # スケーリング wave_norm = wave * (1 / wave_max) return wave_norm if __name__ == '__main__': """ Main """ # 計測条件を設定 time = 5 samplerate = 44100 fs = 1024 # マイクチャンネルを自動取得 index = get_mic_index()[0] # 録音する関数を実行 data, t = record(index, samplerate, fs, time) # 波形をスケーリング(絶対値の最大をフルレンジに設定:音が小さくならないよう) data = scaling(data) # wav保存 sf.write('sample.wav', data, samplerate) |
mp3ファイルをwavファイルにするコード
音読さんやmp3レコーダーで録音した音声はmp3ファイルで提供されています。対してSpeechRecognitionはwavファイルが必要なので、ファイル変換が必要です。
ファイル変換はffmpegをインストールして以下のコードを打ち込むのが最も簡単でしょう。
1 |
ffmpeg -i "sample.mp3" -vn -ac 2 -ar 44100 -acodec pcm_s16le -f wav "sample.wav" |
以下の記事でPythonとの連携をやってみましたが、やはりちょっと使いは素のffmpegで処理する方が良いです。
・Python/pydubでmp3をwavファイルに変換する方法
・ファイル変換はffmpegが本当に便利!Pythonでも使える
マイク入力による音声認識コード
全コード
次はマイクで入力した音声をそのままテキスト変換する方法です。これは裏でPyAudioをインストールしている必要があります。ちなみにやっていることは以下の公式GitHubのexampleをほぼそのまま流用しているだけですのでN番煎じですね。
Say something!の後に発声してください。発声が終わったらサイレンスを検知して勝手に止まるらしいです(すごい)。
https://github.com/Uberi/speech_recognition/blob/master/examples/microphone_recognition.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import speech_recognition as sr def run_recognition_mic(): """ マイクを使って音声認識をする関数 """ # Recognizerをインスタンス化 r = sr.Recognizer() # print文が表示されたらマイクに話しかける with sr.Microphone() as source: print("Say something!") audio = r.listen(source) try: # Google Speech Recognitionを実行→テキスト化 text = r.recognize_google(audio, language="ja") except sr.UnknownValueError: text = "Google Speech Recognition could not understand audio" except sr.RequestError as e: text = "Could not request results from Google Speech Recognition service; {0}".format(e) return text def text_formatting(text): """ テキストを空白文字で改行整形する関数 """ # 分割 text_list = text.split() # 文を結合して1つのテキストにする text_join = '\n'.join(text_list) return text_join if __name__ == '__main__': """ Main """ # 音声認識を実行 text = run_recognition_mic() # 空白文字で改行する text = text_formatting(text) print(text) |
こちらが結果です。先ほど音読さんに読んでもらった文章を筆者であるwatが読んでみました。「ワトラボ」と発音したのですがワットラブと変換されました。
MATLABが英語圏ではマットラブと発音するらしいのでこれは100点!
本日はワットラブ
※watの肉声を音声認識した結果(文章は音読さんに読んでもらったものを流用)
ブログの記事を読んで頂き誠にありがとうございます
この記事で使っている音声は音読
さんによって作成しました
Python
で自動文字起こし
の検証するために利用しましたが
かなり
滑らかな発音でびっくりです
ちょっと「ワ」に力を込めた気がします(音声の公開はしませんよ)。
まとめ
本日はここまで!
この記事ではwavファイルとマイクを使ったSpeechRecognitionライブラリによる音声認識の方法を紹介しました。
たった数行のコードで精度の良い音声認識サービスが使えるとは…すごい世の中になりましたね。
記事ではSpeechRecognitionに読み込ませるwavファイルの作り方も併せて紹介しましたが、必要最低限のコンパクトさでまとまったと思います。
音声認識サービス違いの精度検証は他の方に任せて、まずはGoogle Speech Recognition使ってみることを主眼に置きました。
ここでは音声認識の結果をただ表示させるだけで終わりましたが、アウトプットをさらに加工すれば面白いアプリが作れるのではないかと思います。筆者も何かしらの形でアプリを紹介できればと考えています。
音声認識もライブラリを使えば思ったより簡単にできるとは、さすがPython!
Twitter(今はXと呼ぶ?)でも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!