ディープラーニング で音声データのノイズリダクション 〜 その①

公開日:2019-05-13
最終更新:2019-05-13

ディープラーニングを使って音声データのノイズリダクションに挑戦してみることにしました。

ソツーで音声認識をやる上で、入力値となる音声データのノイズを事前に減らしておけると良いのではと思ったのと、単純に面白そうで勉強にもなるかなと思ったのが動機です。
上手いこと動いてくれれば、上記以外でも使い道がありそうっていうのも魅力的です。

折角なので、Tensorflowを使ってend-to-endのモデルがトレーニング出来たら良いなと思っています。

1週間もあれば、成果を出せるかなと思ったのですが、舐めてました。end-to-endの音声のノイズ除去は調べてみると中々大変。また、取り組んでいる開発者が少ないせいか、説明してくれているウェブサイトもGithubのソースコードも少ないかったです。

というわけで、一気にやり切ることは断念し、3回か4回にわけてプロジェクトを進めることにしました。

作戦

  1. 調査
  2. ベースとなるプロジェクトを見つけて、とりあえずトレーニング
  3. 自分なりの工夫を凝らしてみる

第一回目の今回のテーマは調査です。

まずは既存のプロダクト、あるいはプロジェクトをチェックしてみましょう。

友人に聞いたところ、CmusphinxとKaldiという2つのプロジェクトを教えて頂きました。

  1. Cmusphinx
    https://cmusphinx.github.io/wiki/asr/vad/
    カーネギーメロン大学の研究からうまれたオープンソースの音声認識関連のツールキットです。ツールキットにはVAD(ボイスアクティビティ検知)やノイズリダクションが含まれ、全てオープンソースで提供されています。ディープラーニングで実装されているようですが、TensorflowやPyTorchといった今流行りのフレームワークは使っていないように見えます。僕はTensorflowを主に使っていますが、いくらオープンソースになっているとはいえ、フレームワークなしで実装されているものを弄るのは流石に敷居が高いかなと思いました。なので、ノイズリダクションの部分だけをコマンドラインのツールとして、特に変更はせずに使うだけならできるかもしれませんが、それでは面白くないので一旦パスすることにしました。

  2. Kaldi
    https://www.idiap.ch/software/bob/docs/bob/bob.kaldi/master/guide.html
    元々友人に、ノイズリダクションというより「音声の中の会話の部分だけを際立たせる方法はないか?」と質問をしていたせいもあるのですが、こちらのオープンソースプロジェクトにもVAD(ボイスアクティビティ検知)機能がついています。KaldiもTensorflowベースとかそういったことは記載されていないので、より低レベルの部分からコツコツ実装されている感じがします。こちらもやや敷居が高そうに感じました。

ということで、Googleで検索してみます。
「end-to-end」「Tensorflow」「Audio」「Noise Reduction」「Noise Suppression」などで検索してみました。

と、ここで問題が。検索結果が少ない。画像向けのノイズ除去モデルはいくつも引っかかりますが、音声を扱ったものはほとんどない。記事が見つかってもソースコードは公開されていなかったり、ちょっと僕の意図とはずれてしまっていたりと中々ベースにしたいと思えるソースコードが見つかりません。それでもいくつか参考にできるウェブサイトが見つかりました。

  1. Mozilla RNNoise
    https://hacks.mozilla.org/2017/09/rnnoise-deep-learning-noise-suppression/
    Mozillaのエンジニアがやっているプロジェクト。Githubにソースコードもあって良い感じ。でも2年間ソースコードがアップデートされていないのがちょっと不安。厳密にはend-to-endではない。オンライン会議などのリアルタイムでの利用を念頭においているので、従来のテクニックとディープラーニングを併用することで軽量化しているのが特徴。第一候補かな。

  2. Krisp
    https://devblogs.nvidia.com/nvidia-real-time-noise-suppression-deep-learning/
    Nvidiaのブログに掲載されていました。ずばり音声向けのノイズ除去をどうやらend-to-endでやっています。かつ性能も出ているようです。が、残念ながらソースコードは非公開で、細かな技術的な詳細も非公開でした。でもざっくりとした概要は伝えてくれています。

  3. Acoustics Research Centreの記事
    https://acousticsresearchcentre.no/speech-enhancement-with-deep-learning/
    このブログもずばりend-to-endでノイズ除去をやっています。残念ながらソースコードは公開してくれていませんが、アーキテクチャについての説明とペーパーは公開してくれています。

  4. FFmpegコマンドで一部の周波数の音声を削除する
    https://stackoverflow.com/questions/21659207/filter-out-voice-frequency-with-ffmpeg
    全然ディープラーニングベースではなく、かつベストプラクティスも不明ですが、一部の周波数を削除するのはFFmpegで出来そうです。MozillaのRNNoiseは削除する周波数を見つけるためにディープラーニング を使っているようなので、組み合わせて使うツールとしては良さそうです。

  5. University of RochesterのGregory Hunkinsさんのプロジェクト
    https://github.com/ghunkins/Voice-Denoising-AN
    GANのような仕組みで音声のノイズ除去をやっています。ソースコードもあるのでこちらが本命かも。

  6. Ale Koretzkyさんのブログ
    https://towardsdatascience.com/audio-ai-isolating-vocals-from-stereo-music-using-convolutional-neural-networks-210532383785
    この記事もend-to-endでノイズ除去に挑戦しています。ソースコードは公開してくれていませんが、解説は詳しいです。

ところで、なぜ音声は難しいのでしょうか?

そもそもどんなデータを扱うのかということなのですが、ご存知の通り波です。

RNNのような時系列のモデルに入れてみるというのも手なのですが、44,100Hzの音声の場合、1秒間に44,100回データが取られているということになります。
ということは、データとしては[0, 0, 0, 0.2, 0.4, 12, 13, ...]のような単純なデータの羅列で、ただ長さが10万とか100万とかになるデータということになります。
これをRNNのような時系列のデータで扱うのは大変そうです。
※ 実はチャレンジしている研究者もいるようなので、最終的にはそういうやり方も調べないとダメかも

ということで、音声を分類したり認識したりするは、時間ベースのデータを周波数ベースのデータに変換し、変換したデータを扱うというのが一般的です。

以下に例を示します。

Spectrogram

MFCC

どちらもディープラーニングが扱い易いよう周波数ベースに変換したものですが、MFCCは人の耳の構造も考慮にいれた上で人が聞き取れる周波数限定でデータを整形しているようです。実際、パラメータの数は、図では13ですが、だいたい20個くらいと少ない割に性能が出るのが特徴です。

ところで、ここで一つ疑問が湧いてきました。

ソツーでも生の音声データ(Wave形式)をMFCCに変換してスピーチ認識を行っているので、そのメリットはわかるのですが、最終的な出力が音声の場合、出てきたデータを音声に戻す必要があります。
それはどうやるのでしょう?

ちょっと検索してやり方を探ってみたところ、一筋縄では行かないことがわかりました。
もちろん一旦MFCCにしてしまうと、MFCCからWAVE形式に戻すのは簡単なことでは無いようです。

調べを進めるといくつか有用なリンクが見つかりました。

  1. 掲示板
    https://www.kvraudio.com/forum/viewtopic.php?t=469887
    僕と同じく音声データを変更して、その後音声に戻す方法について質問している奴がいます。

  2. tensorflowの仕組みの中でSTFT(Short Time Fourier Transform)に変換したり元に戻したりできるプログラムを書いている方がいました。
    https://towardsdatascience.com/audio-processing-in-tensorflow-208f1a4103aa
    これは有難いです。仕組みから説明をしてくれていて、勉強になります。というかtensorflowのバージョン1.13.1では音声を周波数ベースに変換したり、戻したりする機能がオフィシャルにサポートされているようです。が、ちょこっと試してみたところtensorflowのオフィシャルバージョンはうまく動作してくれませんでした。きっと指定しているパラメータとかに誤りがあったんだと思います。

ということで、何れにせよ「音声とは」ってところを少し掘り下げて学ぶ必要を感じました。

  1. MFCC(Mel Frequency Cepstral Coefficient)の詳細
    http://practicalcryptography.com/miscellaneous/machine-learning/guide-mel-frequency-cepstral-coefficients-mfccs/
    MFCCについて細かい部分まで記載があります。

  2. Courseraの音楽を科学するクラス
    https://www.coursera.org/specializations/musicianship-specialization
    ミュージックをサイエンスとして扱おうってクラスなのでドンピシャリではありませんが、音声とはという部分を学ぶには良いかもしれません。問題は、まだ最後までコースが完成していないので、短期間でサクっと学び切ることができないことです。

その他、出力が音声ではないので直接的には使えないけど、「音声とは」という部分の解説が厚く、参考になる記事。

https://blogs.rstudio.com/tensorflow/posts/2019-02-07-audio-background/
https://www.analyticsvidhya.com/blog/2017/08/audio-voice-processing-deep-learning/

ここまで読み進めてきて、STFT(Short Time Fourier Transform)なら音声に戻せることがわかったきたので、なんとかそれをテストできないかと調べを更に進めます。

すると漸く、自分の環境でもテストできるやり方が見つかりました。
結論から言うと、Pythonのlibrosaというライブラリです。

# import library  
import librosa.core as lc  
import numpy as np  
import scipy  

# parameters other parameters has to work too  
_n_fft=2048  
_hop_length=512  

# I used 16000 kHz, 10 seconds sounds  
data, sampleRate = lc.load("input.wav", sr=16000, duration=10, mono=True)  

# this is the function to convert wav into stft  
stftMat = lc.stft(data, n_fft=_n_fft, hop_length=_hop_length, center=True)  

# and this is the function to convert stft into wav  
iStftMat = lc.istft(stftMat, hop_length=_hop_length)  

scipy.io.wavfile.write("output.wav", 16000, iStftMat)  

まぁ、普通に耳で聞いて同じに聞こえるので、大丈夫でしょう。

今回は、調査だけで結構時間がかかってしまいました。
次回は、何か一つ既存のプロジェクトを雛形としてピックアップして、実際にノイズリダクションの仕組みをトレーニングしてみたいと思います。

次回に続く。

記事が少しでもいいなと思ったらクラップを送ってみよう!
34
+1
@kouohhashiの技術ブログです。 主にAI、特に会話AIについて記事を書こうと思っています。

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする