プログラムでおかえしできるかな

定年を過ぎて何かの役に立てないかなと始めた元SEのブログです

CMU Sphinx音響モデルの適応【Python】

このエントリーをはてなブックマークに追加

recognition/voice-input-sphinx) Python の SpeechRecognition で CMU Sphinx を使用して音声入力してみました。
そのままでは認識率が悪いので音響モデルの適応をして認識率を上げました。
音響モデルの適応のやり方を紹介します。

Apple の Siri や Google アシスタント、 Amazon Alexa などの音声認識のように音声アシスタントで何かを操作したいと思いませんか?
そのもととなる音声認識を CMUSphinx で実現してみました。

ここでは、Windows での使い方を紹介していますが、Unix ライクな環境でも似たように対応できると思います。
Raspberry Pi などへの応用ができるのではないかと想像しています。

目次

音声認識を応用することの一つに音声アシスタントがあります。
音声アシスタントを実現する時に考慮したいことの一つにオフラインでも動作することがあります。
パソコンで使うのであればそのような考慮は不要ですが、そうでない機器(Raspberry Pi などを使った機器)で使うのであれば必要になります。
Python音声認識パッケージ SpeechRecognition は、いくつかの音声認識エンジに対応しています。
その中でオフラインでの音声認識に無料で対応しているのは、CMU Sphinx ただ一つです。 1

◆CMUSphinx による音声認識

以前、Python で SpeechRecognition パッケージを使用して音声入力するプログラムを作成しました。 2
このプログラムで音声認識エンジンを CMUSphinx に変更することは簡単です。
音声認識に使うメソッドを recognize_google() から recognize_sphinx() に変更するだけです。

※事前に pocketsphinx のインストールが必要です。
pip install pocketsphinx

使用してみると次の様なことが分かります。

  1. 英単語をなかなか認識しない
  2. 英語の文章もなかなか認識しない
  3. ネイティブが話す英語の文章でも認識率はそれほど高くない

この結果を受けて調査した結果、CMUSphinx を快適に使用するには何らかのチューニングが必要なのだと判断しました。

チューニングの方法には2つ用意されています。
しかし、実質的な選択肢は「音響モデルの適応」のみになります。

  • 音響モデルの適応
  • 音響モデルのトレーニン

CMUSphinx の説明によるとトレーニングを行うには次の要件が必要になります。 3

  • 言語の音声構造に関する知識がある
  • レーニングするデータがたくさんある
    一人の話者のコマンドの録音が1時間以上など
  • モデルをトレーニングしてパラメータを最適化する十分な時間がある

私にはこれらの要件は満たせないので音響モデルの適応でチューニングすることにします。

◇音響モデルの適応の効果

CMUSphinx のチュートリアルサイト 』によると音響モデルの適応の効果には次のようなものがあります。

【音響モデルの適応の効果】

  • 適応は必ずしも特定の話者に適応するわけではなく、特定の録音環境、またはアクセントなどに適応できる
  • 言語間の適応も意味があり、英語のモデルを別の言語の音に適応させることができる
  • 適応プロセスは、トレーニングよりも堅牢で、適応データが小さい場合でも良い結果が得られる可能性がある

これらのことから、音響モデルを適応させることで、CMUSphinx を音声アシスタントとして使用できると判断しました。

◆音響モデルを適応するやり方

◇音声アシスタント向け音響モデルの適応に必要なこと

音声アシスタント用に単純な言語モデルを用意して既存の英語の音響モデルを適応します。

音響モデルを適応するには次のプロセスが必要です。

◇単純な言語モデルの作成

単純なコマンドなどを認識するのが目的の場合、単純な言語モデルを作成するのが良いです。
作成にはWeb サービスを利用できてお手軽です。

Web サービスで言語モデルを作成するのに用意するのは、コマンドを列挙したコーパスだけです。

コーパスとは、本来、自然言語の文章を構造化し大規模に集積したもの 4 ですが、単純なコマンドだけを認識する音声アシスタントでは、認識する単語の列挙だけで済みます。

【単純な言語モデルの作成手順】

  1. コーパスファイルの作成
  2. コーパスから言語モデルの作成

コーパスファイルの作成

ここでの「コーパス」は、音響モデルの適応に使用する文の単なるリストです。
言い換えると音声アシスタントで使用するコマンドの列挙です。
例として、ブラウザを制御するコマンドを想定します。

▽作成例

down
next page
up
top
bottom
next link
back
see
search
stop

これを例えば corpus.txt というファイルに作成します。

コーパスから言語モデルの作成

次の Web サービスでコーパスファイルから言語モデルを作成します。

言語モデル作成サービス:Sphinx Knowledge Base Tool VERSION 3

表示されたサイトで以下を実施します。

  1. 「参照」ボタンを押して、作成した corpus.txt をファイル選択
  2. 「COMPILE KNOWLEDGE BASE」ボタンを押します
  3. 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

※すでにある録音データからそれを文章に分割して transcription ファイルと fileids ファイルを作成する方法もあります。

◇音響モデルの適応の実施

音響モデルの適応とは、適応データとモデルの間の適応性を向上させて適応データの元になっている話し方を認識しやすくします。
次の手順で実施します。

  1. 作業フォルダの作成
    作業フォルダを作成し、音響モデル、辞書、言語モデル、適応データ、バイナリをコピーします
    • デフォルト音響モデルのコピー
      1. 音響モデルを取得
        取得先:CMU Sphinx Files
        取得ファイル:cmusphinx-en-us-ptm-5.2.tar.gz (ptmはモバイル用のこと)
        ※解凍後、中に mixture_weights があること、mdef がテキストファイルであることを確認
        ※本来、pocketsphinx インストール先の pocketsphinx\model\en-us\en-us フォルダをコピーしますが
         これは圧縮版で配布されているため上記から未圧縮のフルバージョンを取得します
      2. 作業フォルダに en-us フォルダを作成し取得した音響モデルの全ファイルを格納
        ファイル:feat.params、mdef、means、mixture_weights、noisedict、README、sendump、transition_matrices、variances
    • 辞書(nnnn.dic)と言語モデル(nnnn.lm)を作業フォルダにコピー
      コーパスから言語モデルの作成⤴」で説明した取得物
    • 適応データを作業フォルダにコピー
      適応データの作成⤴」で作成した
      fileidstranscriptionwav ファイルをコピーします
    • バイナリのコピー
      適応に使うツールの作成⤵」で作成した
      sphinx_fe.exebw.exemap_adapt.exemllr_solve.exe を作業フォルダにコピーします
  2. 音響特徴ファイル(mfcファイル)の生成
    sphinx_fe プログラムの実行
    sphinx_fe -argfile en-us/feat.params -samprate 16000
    -c a_data.fileids -di . -do . -ei wav -eo mfc -mswav yes
  3. 観測カウントの累積
    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:出力先
  4. MLLRによる変換(mllr_matrix を作成)
    mllr_solve プログラムの実行
    mllr_solve -meanfn en-us/means -varfn en-us/variances
    -outmllrfn mllr_matrix -accumdir .
  5. 音響モデルフォルダをコピー(ここではen-us-adaptとする)
    en-us フォルダをコピーして en-us-adapt フォルダを作成
  6. 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 は次のサイトから取得できます。

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 を次のサイトから取得します。

ダウンロードしたら解凍して使います。
sphinxtrain-5.0.0 フォルダ以下が作成されます。

◇sphinxtrain ソースコードからビルド

sphinxtrain ソースのビルドには、CMake と C、PerlPython が必要です。

コンパイラなどの準備

  • 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 は、まずビルドファイルを作成して、次にバイナリの作成を行います。

  1. 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:モード変更
  2. 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

※これらのフォーマット間の変換も可能

◆ソースの取得

全体のソースはこちらから取得できます。

※ソースにはデバッグ用のコードが含まれていますのでご容赦ください。
デバッグには logging モジュールを使用しています。
 logging モジュールの使い方については、別の記事で解説する予定です。

◆さいごに

今回、この作業をやって気付いたことがあります。
音声認識には、単語一つより、複数ある方が認識しやすいんだなということです。
そういえば、グーグルは「OK Google」だし、メルセデスは「はい、メルセデス」でした。関連している気がします。
日本語は一つ一つの音がはっきりしていますが、英語は単語が繋がると発音のされ方が変わるからなのかなと思います。
音声認識もそこを考慮して作られているようです。

音声認識の専門家ではないので想像ですが。
日本語の音声認識は、仮名にするだけなら簡単なんじゃないかと思います。
仮名を漢字にするのが大変なんじゃないかと思います。
そこは音声認識じゃなくて意味解析ですね。


あわせて読みたい 📖 音声入力で文章作成するアプリの作り方【Python】 🔗

◇ご注意

本記事は次のバージョンの下で動作した内容を基に記述しています。

  • Python 3.8.5
  • pocketsphinx 5.0.0

◇免責事項

ご利用に際しては、『免責事項』をご確認ください。
お気づきの点がございましたら『お問い合わせ』からお問い合わせください。

◆参考

投稿:

  1. 📖 ◇対応している音声認識エンジン/API - 音声入力で文章作成するアプリの作り方【Python】 🔗
  2. 📖 音声入力で文章作成するアプリの作り方【Python】 🔗
  3. レーニングの要件はこちらを参照:Training an acoustic model for CMUSphinx – CMUSphinx Open Source Speech Recognition
  4. ウィキペディア参照:コーパス - Wikipedia
  5. Windws の録音用ツールは、Windows のバージョンによって名称が変更されています。ボイスレコーダー(windows10以降)、サウンドレコーダー(Windows8まで)
  6. 本来は SphinxTrain を実行すれば良いように作られているようなのですが、実行の仕方やその時に実行されるものが何かが理解できなかったので、ビルドしたツールを使うようにしました。
  7. Perl のインストールはこちらを参考にしました:Strawberry PerlをWindowsにインストールする - Perlゼミ|Perlの基礎をインストールからサンプルで丁寧に解説
  8. C のインストールはこちらのサイトを参考にしました:詳解[GCC]VScodeでC/C++をコンパイル・実行する | クロステ
  9. 言語モデル(GPT についても):言語モデル:朝日新聞社メディア研究開発センター 人工知能研究の取り組み