読者です 読者をやめる 読者になる 読者になる

PGは電子羊の夢を見るのか?

データとパターンのあいだ

音声から特徴抽出して学習するもろもろツールと学習機を実装しました。

機械学習

音声からメル周波数ケプストラム係数(以下、mfcc)を抽出し、ニューラルネットモデルで学習する機械を実装しました。

github.com

実装環境は以下のとおり。

  • Python 2.7.10
  • numpy 1.9.2
  • progressbar2 2.7.3
  • PyBrain 0.3
  • scikits.talkbox 0.2.5
  • scipy 0.16.0
  • ffmpeg
  • sox

使用言語はPython。mfccの抽出にはscikits.talkboxを使い、ニューラルネットの構築にはPyBrainを使用しました。
ffmpegsoxは動画から音声ファイルを抽出するとき、抽出した音声ファイルを分割するとき、に使っています。

使い方としては以下のとおり。

初めに、スクリプトを実行するためにいくつかフォルダを作ります。

mkdir mov wav wav2 voice voice2 doc

次に、「mov」フォルダに音声データを抽出したい動画ファイルを置きます。この時、ひとつの動画ファイルにつき一人分の音声のみが入ったファイル(例えば、声優さんのボイスサンプルとか)を想定しています。

ここまで出来たら「convert_mov_to_wav.sh」を実行して、音声ファイルを抽出します。引数に「元データの入ったフォルダ」と「出力先のフォルダ」を指定します。

./convert_mov_to_wav.sh mov wav

「split_wav.sh」を使用して、先ほど抽出した音声ファイルを1秒毎に分割します。先ほど同様に、入力元と出力先のフォルダを指定します。
このとき、音声データのファイル名を元にして、出力先フォルダ内で分割元ファイルごとにフォルダ分けします。
例えば、以下のコマンドでactor.wavという音声ファイルからsolit_wav.shを使って分割を行った場合、「voice/actor/*.wav」という階層構造で分割されたファイルが保存されます。学習時、この階層構造を元にラベル付けするようにしています。

./split_wav.sh wav voice

先ほど分割した音声ファイルからmfccを抽出し訓練データとするために、「make_train_data.py」を実行します。
抽出されたmfccはtrain.txt, test.txtに, フォルダの階層構造を元にしたラベル一覧をlabels.txtにそれぞれ保存しdocフォルダの中に置きます。(入力ソースは、voiceフォルダを見るように実装しています。)

python make_train_data.py

このtrain.txtとtest.txtを元に、ニューラルネットを訓練します。
これには「train_mfcc_data.py」を実行し、訓練されたモデルは「NN.xml」というxmlファイルとして出力されます。

python train_mfcc_data.py

以上で、mfccを認識して話者を識別するニューラルネットモデルが出来ました。

次に、別の音声ファイルを使って先ほどのモデルで識別する、というのをやってみます。

まずは、先ほど同様に動画ファイルから音声を抽出しこれを分割するところまでをやります。
この時、movフォルダには識別に使用したい動画ファイルだけを置くようにしてください。また、入出力のフォルダ指定が先ほどと違うので注意。

./convert_mov_to_wav.sh mov wav2
./split_wav.sh wav2 voice2

今度は、「make_recog_data.py」を使って、voice2フォルダに入っている音声データを元に、識別用のデータテキストを生成します。
先ほどの「make_train_data.py」との違いは、こちらのスクリプトはクラスラベルを持たないデータ(教師なしデータ)を生成します。

python make_recog_data.py

このスクリプトによって「recog.txt」というファイルがdocフォルダ内に作られます。
「recog_mfcc_data.py」では、NN.xmlに記録されているニューラルネットモデルを再生し、このrecog.txtに保存されているを読み込んで、その識別結果を「labels.txt」に書かれているラベル情報に当てはめて出力します。

こんな感じで音声からmfccを抽出して学習・認識する学習機を実装しました。
これで動きますが、ツールがシェルだったりツールのインストールが必要だったりするので、もうちょっと洗練させていこうと思います。


参考リンク

音声データの抽出や分割、mfccの抽出方法はこちらで書いたあったものを参考にさせていただきました。

qiita.com

音声データを格納したフォルダの階層構造を元に訓練データ・テストデータ・ラベルの仕分けをしたかったので、下記のリンクにある「make_train_data.py」を使わせていただきました。

github.com