recognition/voice-input-sphinx)
Python の SpeechRecognition で CMU Sphinx を使用して音声入力してみました。
そのままでは認識率が悪いので音響モデルの適応をして認識率を上げました。
音響モデルの適応のやり方を紹介します。
Apple の Siri や Google アシスタント、 Amazon Alexa などの音声認識のように音声アシスタントで何かを操作したいと思いませんか?
そのもととなる音声認識を CMUSphinx で実現してみました。
ここでは、Windows での使い方を紹介していますが、Unix ライクな環境でも似たように対応できると思います。
Raspberry Pi などへの応用ができるのではないかと想像しています。
目次
- ◆CMUSphinx による音声認識
- ◆音響モデルを適応するやり方
- ◆音声データの作成
- ◆適応に使うツールの作成
- ◆SpeechRecoginitionでの適応した音響モデルの使い方
- ◆日本語への対応
- ◆pocketshinxと音声認識
- ◆ソースの取得
- ◆さいごに
- ◆参考
音声認識を応用することの一つに音声アシスタントがあります。
音声アシスタントを実現する時に考慮したいことの一つにオフラインでも動作することがあります。
パソコンで使うのであればそのような考慮は不要ですが、そうでない機器(Raspberry Pi などを使った機器)で使うのであれば必要になります。
Python の音声認識パッケージ SpeechRecognition は、いくつかの音声認識エンジに対応しています。
その中でオフラインでの音声認識に無料で対応しているのは、CMU Sphinx ただ一つです。 1
◆CMUSphinx による音声認識
以前、Python で SpeechRecognition パッケージを使用して音声入力するプログラムを作成しました。 2
このプログラムで音声認識エンジンを CMUSphinx に変更することは簡単です。
音声認識に使うメソッドを recognize_google()
から recognize_sphinx()
に変更するだけです。
※事前に pocketsphinx のインストールが必要です。
pip install pocketsphinx
使用してみると次の様なことが分かります。
- 英単語をなかなか認識しない
- 英語の文章もなかなか認識しない
- ネイティブが話す英語の文章でも認識率はそれほど高くない
この結果を受けて調査した結果、CMUSphinx を快適に使用するには何らかのチューニングが必要なのだと判断しました。
チューニングの方法には2つ用意されています。
しかし、実質的な選択肢は「音響モデルの適応」のみになります。
- 音響モデルの適応
- 音響モデルのトレーニング
CMUSphinx の説明によるとトレーニングを行うには次の要件が必要になります。 3
私にはこれらの要件は満たせないので音響モデルの適応でチューニングすることにします。
◇音響モデルの適応の効果
『CMUSphinx のチュートリアルサイト 』によると音響モデルの適応の効果には次のようなものがあります。
【音響モデルの適応の効果】
- 適応は必ずしも特定の話者に適応するわけではなく、特定の録音環境、またはアクセントなどに適応できる
- 言語間の適応も意味があり、英語のモデルを別の言語の音に適応させることができる
- 適応プロセスは、トレーニングよりも堅牢で、適応データが小さい場合でも良い結果が得られる可能性がある
これらのことから、音響モデルを適応させることで、CMUSphinx を音声アシスタントとして使用できると判断しました。
◆音響モデルを適応するやり方
◇音声アシスタント向け音響モデルの適応に必要なこと
音声アシスタント用に単純な言語モデルを用意して既存の英語の音響モデルを適応します。
音響モデルを適応するには次のプロセスが必要です。
- 適応に使うツールの作成⤵
- 単純な言語モデルの作成⤵
- 適応データの作成⤵
transcription
ファイルとfileids
ファイルの作成- 音声データの作成⤵
- 音響モデルの適応の実施⤵
◇単純な言語モデルの作成
単純なコマンドなどを認識するのが目的の場合、単純な言語モデルを作成するのが良いです。
作成にはWeb サービスを利用できてお手軽です。
Web サービスで言語モデルを作成するのに用意するのは、コマンドを列挙したコーパスだけです。
コーパスとは、本来、自然言語の文章を構造化し大規模に集積したもの 4 ですが、単純なコマンドだけを認識する音声アシスタントでは、認識する単語の列挙だけで済みます。
【単純な言語モデルの作成手順】
◎コーパスファイルの作成
ここでの「コーパス」は、音響モデルの適応に使用する文の単なるリストです。
言い換えると音声アシスタントで使用するコマンドの列挙です。
例として、ブラウザを制御するコマンドを想定します。
▽作成例
down next page up top bottom next link back see search stop
これを例えば corpus.txt
というファイルに作成します。
◎コーパスから言語モデルの作成
次の Web サービスでコーパスファイルから言語モデルを作成します。
言語モデル作成サービス:Sphinx Knowledge Base Tool VERSION 3
表示されたサイトで以下を実施します。
- 「参照」ボタンを押して、作成した corpus.txt をファイル選択
- 「COMPILE KNOWLEDGE BASE」ボタンを押します
- 「Sphinx knowledge base generator」というタイトルのページが表示されます
「TARnnnn.tgz」ファイルをダウンロードします
※nnnnは4桁の数字、中にdic、lm、log_pronounce、sent、vocab、HEADER.htmlファイルが含まれます
◇適応データの作成
音響モデルの適応を行うには次のデータが必要です。
transcription
ファイル:単語と音声データのマッピングを記述したテキストfileids
ファイル:音声データファイル名一覧のテキストwav
ファイル:音声データ
※transcription
ファイルと fileids
ファイルは音声データのファイル名の記述の順番を合わせます。
【各ファイルの説明】
transcription
ファイル
拡張子がtranscription
のテキストファイル
ファイル名の例:data.transcription
音声ファイルで発音している単語(大文字)と音声ファイル名(拡張子なし)を記述します
データの例:
<s> DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN </s> (down10) <s> NEXT PAGE NEXT PAGE NEXT PAGE NEXT PAGE NEXT PAGE NEXT PAGE NEXT PAGE NEXT PAGE NEXT PAGE NEXT PAGE </s> (next_page10) <s> UP UP UP UP UP UP UP UP UP UP </s> (up10)
fileids
ファイル
拡張子がfileids
のテキストファイル
ファイル名の例:data.fileids
音声ファイル名(拡張子なし)を列挙します
データの例:
down10 next_page10 up10
wav
ファイル
後節「音声データの作成⤵」を参照してください
※すでにある録音データからそれを文章に分割して transcription
ファイルと fileids
ファイルを作成する方法もあります。
◇音響モデルの適応の実施
音響モデルの適応とは、適応データとモデルの間の適応性を向上させて適応データの元になっている話し方を認識しやすくします。
次の手順で実施します。
- 作業フォルダの作成
作業フォルダを作成し、音響モデル、辞書、言語モデル、適応データ、バイナリをコピーします- デフォルト音響モデルのコピー
- 音響モデルを取得
取得先:CMU Sphinx Files
取得ファイル:cmusphinx-en-us-ptm-5.2.tar.gz
(ptmはモバイル用のこと)
※解凍後、中にmixture_weights
があること、mdef
がテキストファイルであることを確認
※本来、pocketsphinx インストール先のpocketsphinx\model\en-us\en-us
フォルダをコピーしますが
これは圧縮版で配布されているため上記から未圧縮のフルバージョンを取得します - 作業フォルダに
en-us
フォルダを作成し取得した音響モデルの全ファイルを格納
ファイル:feat.params、mdef、means、mixture_weights、noisedict、README、sendump、transition_matrices、variances
- 音響モデルを取得
- 辞書(nnnn.dic)と言語モデル(nnnn.lm)を作業フォルダにコピー
「コーパスから言語モデルの作成⤴」で説明した取得物 - 適応データを作業フォルダにコピー
「適応データの作成⤴」で作成した
fileids
、transcription
、wav
ファイルをコピーします - バイナリのコピー
「適応に使うツールの作成⤵」で作成した
sphinx_fe.exe
、bw.exe
、map_adapt.exe
、mllr_solve.exe
を作業フォルダにコピーします
- デフォルト音響モデルのコピー
- 音響特徴ファイル(mfcファイル)の生成
sphinx_fe プログラムの実行
sphinx_fe -argfile en-us/feat.params -samprate 16000
-c a_data.fileids -di . -do . -ei wav -eo mfc -mswav yes
- 観測カウントの累積
bw プログラムの実行
※bw の引数が音響モデルのフォルダ内の feat.params と合っていることを確認
※bw で次のエラーが出る場合、録音した内容とtranscription
ファイルに記述した単語の数があっていません。
transcription
ファイルを見直します。
エラー:Failed to align audio to transcript: final state of the search is not reached
bw
-hmmdir en-us
-moddeffn en-us/mdef
-ts2cbfn .ptm.
-feat 1s_c_d_dd
-svspec 0-12/13-25/26-38
-cmn current
-agc none
-dictfn 8811.dic
-ctlfn my_small_model.fileids
-lsnfn my_smoll_madel.transcription
-accumdir .
【オプション(一部)】- -hmmdir:音響モデルのフォルダ
- -moddeffn:モデル定義ファイル(「コーパスから言語モデルの作成⤴」で作成した場合は mdef)
- -dictfn:辞書のファイル名
- -ctlfn:
fileids
ファイルのファイル名 - -lsnfn:
transcription
ファイルのファイル名 - -accumdir:出力先
- MLLRによる変換(mllr_matrix を作成)
mllr_solve プログラムの実行
mllr_solve -meanfn en-us/means -varfn en-us/variances
-outmllrfn mllr_matrix -accumdir .
- 音響モデルフォルダをコピー(ここではen-us-adaptとする)
en-us
フォルダをコピーしてen-us-adapt
フォルダを作成 - MAP による音響モデルファイルの更新(en-us-adapt 内のファイル更新)
map_adapt プログラムの実行
map_adapt -moddeffn en-us/mdef -ts2cbfn .ptm. -meanfn en-us/means
-varfn en-us/variances -mixwfn en-us/mixture_weights
-tmatfn en-us/transition_matrices -accumdir .
-mapmeanfn en-us-adapt/means -mapvarfn en-us-adapt/variances
-mapmixwfn en-us-adapt/mixture_weights
-maptmatfn en-us-adapt/transition_matrices
◆音声データの作成
◇音声の録音
録音は、Windows 付属のソフトで録音します。
※もちろん何を使用しても大丈夫です。
Windows 付属の「ボイスレコーダー(サウンドレコーダー) 5」はファイル形式 m4a (サウンドレコーダの場合は wma)の音声ファイルを作成します。
音響モデルの適応ツールでは、wav 形式のファイルを要求しています。
したがって、ファイル形式の変換が必要になります。
◇m4a(wma)からwavへ変換
オーディオファイルの変換ツール ffmpeg
を使用した Python の変換プログラムを作成しました。
簡単なコードなのでここに紹介します。
あるフォルダ内の m4a ファイルを順番に wav ファイルに変換します。
import glob import subprocess ffmpeg_path = r"C:\temp\ffmpeg\bin\ffmpeg.exe" # ffmpeg.exeのパス target_path = r"C:\temp\音声\*.m4a" # 変換前音声データのパス for path in glob.iglob(target_path): print(path) cmd = f"{ffmpeg_path} -i {path} -ac 1 -ar 16000 {path.replace('.m4a', '.wav')}" subprocess.call(cmd, shell=True) print("finish")
作成する wav ファイルは、適応ツールの要件に合ったものにします。
【wav ファイルの要件】
単一チャンネルのモノラルで16kHzのサンプリングレート
- bit resoulution:16
- sample rate:16000
- audio channels:mono
▼ffmpeg での指定方法
ffmpeg -i xx.m4a -ac 1 -ar 16000 xx.wav
※上記を1ファイルずつ手入力で実行し、変換することもできます。
▼ffmpeg のオプションの一部
-ac
:音声のチャンネル数-ar
:サンプリングレート
▼このやり方にした経緯
m4a(wma)からwavへ変換する方法を調べました。
Python に「pydub · PyPI 」というパッケージがあります。
使用してみた結果、次のことが分かりました。
- 内部で
ffmpeg
というライブラリを使用している ffmpeg
をダウンロードしないと動作しない
これなら、直に ffmpeg
を起動するプログラムを作成したほうが分かりやすいと思いました。
◇ffmpegのダウンロード
ffmpeg は次のサイトから取得できます。
- 取得先:Releases · GyanD/codexffmpeg
- ファイル:
ffmpeg-5.1.2-essentials_build.zip
(バージョンは最新のもの)
readme.txt にどのような音声ファイルに対応しているか(サポートタイプ)が出ています。
【サポートタイプの例】
aac
:m4aファイルで使われるファイル形式alac
:m4aファイルで使われるファイル形式wmav1
:wma7に対応している模様wmav2
:wma8およびwma9に対応している模様
◆適応に使うツールの作成
ツールはバイナリで提供されていないので、sphinxtrain ソースからビルドする必要があります。 6
適応には次のツールを使います。
sphinx_fe.exe
bw.exe
mllr_solve.exe
map_adapt.exe
◇sphinxtrain ソースの取得
適応に使用するツールは、新しく sphinxtrain
としてソースがリリースされています。
sphinxtrain
を次のサイトから取得します。
- 取得先(GitHub):Releases · cmusphinx/sphinxtrain
- ファイル:
Source code(zip)
またはSource code(tar.qz)
ダウンロードしたら解凍して使います。
sphinxtrain-5.0.0
フォルダ以下が作成されます。
◇sphinxtrain ソースコードからビルド
sphinxtrain ソースのビルドには、CMake と C、Perl、Python が必要です。
◎コンパイラなどの準備
- CMakeのインストール
公式サイトからインストーラをダウンロードしてインストールします
取得先:Download | CMake - perlのインストールと関連付け
- perl のインストールは外部サイトを参考にしました 7
- perl とファイル拡張子の関連付け
次のコマンドを使って関連付けができます(管理者で実行)- 関連付けを設定(ファイルタイプを設定して関連付ける)
FTYPE SPerl="C:\strawberry\Perl\bin\perl.exe" "%1" %*
ASSOC .pl=SPerl
- 関連付けを確認
コマンド:assoc .拡張子
結果表示:.拡張子=ファイルタイプ名
コマンド:ftype ファイルタイプ名
結果表示:ファイルタイプ名=オープンコマンド文字列
- コマンドの説明
ASSOC [.拡張子[=[ファイル タイプ]]]
ファイル拡張子の関連付けの表示または変更FTYPE [ファイル タイプ[=[オープンコマンド文字列]]]
ファイル拡張子の関連付けに使われるファイルタイプの表示または変更
- 関連付けを設定(ファイルタイプを設定して関連付ける)
- C のインストール
C のインストールは外部サイトを参考にしました 8
◎CMakeでビルド
sphinxtrain には、CMakeLists.txt が提供されています。(取得したソースの sphinxtrain-5.0.0
フォルダ)
したがって、CMake でビルドすることが可能です。
CMake は、まずビルドファイルを作成して、次にバイナリの作成を行います。
- CMake でビルドファイルの作成
build フォルダを作成し、build フォルダに移動して CMake を実行します
※build フォルダを作成するのは cmake が多数のファイルを作成するので元のソースのフォルダを汚さないためです
例:mkdir build
cd build
cmake .. -A x64
※カレントフォルダは build フォルダなので CMakeLists.txt ファイルがある親のフォルダを..
で指定します。
オプションの指定-G
:ジェネレータ(対象のコンパイラ)を指定
デフォルトは、Visual Studio 17 2022
C コンパイラを VSCode にインストール済みであれば指定不要
MinGW を指定する場合は、-G MinGW Makefiles
--fresh
:再構築する場合に付加-A
:プラットフォームを指定(ジェネレータがサポートしている場合)
「Visual Studio 17 2022」のデフォルトは「Win32」
値:Win32, x64, ARM, ARM64-DCMAKE_BUILD_TYPE=Release
:モード変更
- CMake でバイナリの作成
cmake --build .
1.で作成されたビルドファイルを使ってバイナリを作成します。
※デフォルトはDebugモードなのでDebugフォルダにバイナリができます
※.
はビルドファイルが作られたフォルダです。ここではカレントの build フォルダです
◆SpeechRecoginitionでの適応した音響モデルの使い方
適応した音響モデルを SpeechRecognition で次のように指定して使用します。
recognize_sphinx()
メソッドに language
引数を指定します。
【language 引数】
language=(en-us-adaptフォルダ, nnnn.lmファイル, nnnn.dicファイル)
▼コード例
self.r.recognize_sphinx(audio , language=(r"C:\my_model\en-us-adapt" , r"C:\my_model\1347.lm" , r"C:\my_model\1347.dic"))
◆日本語への対応
「音響モデルの適応の効果⤴」で触れましたが、CMUSphinx は他国語の音響モデルを使用しても日本語を認識をさせることができる可能性があります。
実際、使えるめどが立ちました。
音声アシスタントのような短い単語を認識させる場合に有効です。
日本語の音響モデルが提供されていないこともあるので、この方法で日本語の対応をします。
適応方法は英語で音響モデルの適応を行うのと同じです。
用意するコーパスを日本語(ローマ字)にするだけです。
ただし、次のような考慮をしてあげるとより認識されやすくなるようです。
- 単語は3文字以上の方が認識されやすい
例:「うえ」より「うえへ」 - 母音より子音の方が認識されやすい
例:「うえへ」より「うえに」 - 複数単語の方が認識されやすい
例:「うえに」より「うえに いどう」
◇日本語で認識できるようになるまでの単語選びの遷移
単語選びで試行錯誤した内容を紹介します。
3回目の単語では、かなり認識してくれますが、十分ではありません。
1回目 | ← | 2回目 | ← | 3回目 | ← |
---|---|---|---|---|---|
shita | 下 | shitae | 下へ | shitani idou | 下に移動 |
jipeiji | 次ページ | jipeiji | 次ページ | jipeiji | 次ページ |
ue | 上 | uee | 上へ | ueni idou | 上に移動 |
toppu | トップ | ichiban uee | 一番上へ | ichiban ueni | 一番上に |
soko | 底 | ichiban shitae | 一番下へ | ichiban shitani | 一番下に |
tabu | タブ | tsugino rinku | 次のリンク | tsugino rinku | 次のリンク |
modoru | 戻る | modoru | 戻る | modoru | 戻る |
miru | 見る | hyouji | 表示 | hyouji | 表示 |
kensaku | 検索 | kensaku | 検索 | kensaku | 検索 |
owari | 終わり | owari | 終わり | owari | 終わり |
- 1回目:次ページや検索、戻るは認識されやすい
- 2回目:上へや下へは認識されにくい
- 3回目:6-7割認識される(調子の良い時と悪い時がある)
認識率を上げる単語選びが課題です。
何となく、五十音の行と段の異なる音で始まる単語を使うと良いのかなと想像しています。
◆pocketshinxと音声認識
pocketshinx は音声認識の技術を使っています。
音声認識技術の詳しいところは解説できませんが、知っていた方が良い用語などを『CMUSphinx Tutorial For Developers – CMUSphinx Open Source Speech Recognition 』からの抜粋で紹介します。
◇認識方法
◇モデル
CMUSphinx は、音響モデル、言語モデル、音声辞書の 3 つのモデルを使用します。
- 音響モデル:音声を音素(語の意味を区別できる音声の最小単位)に変換するベースとなるもの
一般的な音響モデルは、数千人/数千時間の音声データを統計的に処理したものをベースとしている - 音声辞書:単語を音素の並びにマッピングしたもの
パターンマッチングで音素の並びから単語を判断する - 言語モデル:人間が話したり書いたりする「言葉」を、単語の出現確率でモデル化したもの 9
◇言語モデル
言語モデルの実装に2つの形式があります。
- テキストARPA形式
- ARPAフォーマットは、編集することができる
- ARPAファイルの拡張子は、
.lm
- バイナリBIN形式
- バイナリ形式は、読み込みを高速化
- バイナリ ファイルの拡張子は、
.lm.bin
※これらのフォーマット間の変換も可能
◆ソースの取得
全体のソースはこちらから取得できます。
- ソース:voice_input_Sphinx.py
- 取得先:GitHub juu7g/Python-voice-input
※ソースにはデバッグ用のコードが含まれていますのでご容赦ください。
デバッグには logging モジュールを使用しています。
logging モジュールの使い方については、別の記事で解説する予定です。
◆さいごに
今回、この作業をやって気付いたことがあります。
音声認識には、単語一つより、複数ある方が認識しやすいんだなということです。
そういえば、グーグルは「OK Google」だし、メルセデスは「はい、メルセデス」でした。関連している気がします。
日本語は一つ一つの音がはっきりしていますが、英語は単語が繋がると発音のされ方が変わるからなのかなと思います。
音声認識もそこを考慮して作られているようです。
音声認識の専門家ではないので想像ですが。
日本語の音声認識は、仮名にするだけなら簡単なんじゃないかと思います。
仮名を漢字にするのが大変なんじゃないかと思います。
そこは音声認識じゃなくて意味解析ですね。
◇ご注意
本記事は次のバージョンの下で動作した内容を基に記述しています。
- Python 3.8.5
- pocketsphinx 5.0.0
◇免責事項
ご利用に際しては、『免責事項』をご確認ください。
お気づきの点がございましたら『お問い合わせ』からお問い合わせください。
◆参考
- Sphinx:CMUSphinx Tutorial For Developers – CMUSphinx Open Source Speech Recognition
- 音響モデルの適応:Adapting the default acoustic model – CMUSphinx Open Source Speech Recognition
- コーパスとは:コーパスを知れば英語学習が変わる!明日から使えるコーパスガイド| Kimini英会話
- 音声認識:音声認識(speech recognition)とは
- 音声認識の仕組み:音声認識の仕組み|音声認識の株式会社アドバンスト・メディア
- 📖 ◇対応している音声認識エンジン/API - 音声入力で文章作成するアプリの作り方【Python】 🔗↩
- 📖 音声入力で文章作成するアプリの作り方【Python】 🔗↩
- トレーニングの要件はこちらを参照:Training an acoustic model for CMUSphinx – CMUSphinx Open Source Speech Recognition ↩
- ウィキペディア参照:コーパス - Wikipedia ↩
- Windws の録音用ツールは、Windows のバージョンによって名称が変更されています。ボイスレコーダー(windows10以降)、サウンドレコーダー(Windows8まで)↩
- 本来は SphinxTrain を実行すれば良いように作られているようなのですが、実行の仕方やその時に実行されるものが何かが理解できなかったので、ビルドしたツールを使うようにしました。↩
- Perl のインストールはこちらを参考にしました:Strawberry PerlをWindowsにインストールする - Perlゼミ|Perlの基礎をインストールからサンプルで丁寧に解説 ↩
- C のインストールはこちらのサイトを参考にしました:詳解[GCC]VScodeでC/C++をコンパイル・実行する | クロステ ↩
- 言語モデル(GPT についても):言語モデル:朝日新聞社メディア研究開発センター 人工知能研究の取り組み ↩