[Deep Learning] WaveNetの解説

今回の記事では、Google傘下のDeep Mindが開発したDeep LearningのモデルであるWaveNetについて説明していきます。信号処理の分野を研究している筆者からするとWaveNetはかなり画期的な提案だと思います。最近だとWaveRNNというモデルが同社によって開発されていて、WaveNetと同等の性能でより高速にTTS(text-to-speech)可能だと報告されています。次の記事でWaveRNNについて説明するので今回はWaveNetの画期的な提案について解説していきます。

はじめに

WaveNetは音声波形を直接モデリングするネットワークです。従来の手法ではパワースペクトルに対して2D-Convolutionを用いたCNNで周波数領域をモデリングしていました。この手法では推論したパワースペクトルから音声信号に復元するために位相情報を学習前の音声から推論するため品質の劣化が問題となってました。そこで、パワースペクトルを使わずに、音声を直接学習するネットワークがいくつか提案されました。この手法の問題点としてはネットワークの受容野を広くするために多層化して居たため学習の収束に時間がかかるのと、スペクトルベースの学習と比較して性能が向上しませんでした。この問題を解決するために開発されたのがWaveNetです。

WaveNetとは

WaveNetのネットワークの全体像は下画像です。WaveNetの主な提案としては時系列データの学習にdelated convolutionとゲート付き活性化関数を用いたことで、出力層では各層をskip connectionした結果の総和を取っています。delated convolutionで解像度の異なる畳み込みをした後にskip connectionにより効果的な特徴抽出を可能にしています。またWaveNetはかなり深い層で学習しているので各層で残差を取って勾配消失の対策もしています。DeepMindは上記の構造をもつネットワークであるWaveNetを提案しTTSなどのタスクでSOTAなスコアを出しています。

応用例

TTS(WaveNetの論文)

音声波形合成

音声のノイズ除去

音声の広帯域化

上記のタスクではWaveNetを用いることで従来のCNNベースまたはフィルタリングベースのパフォーマンスより上回ったことが報告されています。WaveNetは様々なタスクに応用可能なように設計されており、他のタスクでの効果も期待できますね。

まとめ

今回の記事では時間域信号から直接音声特徴をモデリングするWaveNetの解説をしました。時間域信号のパターンは無数にあり、このパターンをそのまま解析するのは無謀過ぎますがそれをしたのがWaveNetです。結果として従来手法より性能が向上しているので素晴らしすぎる提案だと思います。2017年10月にはGoogle Assistantにも搭載されたと記事になっていて、WaveNetは今後しばらくは信号処理の分野でDeep Learningを活用する研究に影響を与えそうです。次回の記事ではWaveRNNについて解説していきたいと思います。

現状のappleのsiriについてまとめてみた

今回の記事ではappleのsiriに使われている音声認識の技術に関する論文が発表されていたのでまとめました. 参考にしたニュース記事はこちらです. 今までのsiriではlocalのお店の名前などのフレーズに関しては認識できなかったです. このようなフレーズは学習データに出現回数が少ないと考えられるし, 世界的に使用可能な音声認識システムを構築するためにはlocalな単語を認識することは考えないのが普通だと思います. しかし, 今回の論文では位置情報を利用して自分が今いる地域のlocalな単語の辞書を作成し活用することで認識精度が向上したらしいです(現在は英語限定です). どのようなことをして実現したのかを解説していきたいと思います.

従来の音声認識と問題点

一般的な音声認識は主に音響モデルと言語モデルの二つの要素で構成されています.

  • 音響モデルは音声の要素と単語の要素の関係性を捉えたモデルのこと.
  • 言語モデルは音響モデルで捉えた単語の要素の繋がりを決定するモデルのこと.

少し分かりにくいので具体的な音声認識の流れを図に示します.

マイクから取得した音声を音響モデルで単語に変換します. 音響モデルで変換した単語を言語モデルで意味のある語の連なりに変換します. 図の例で説明すると, 音声を[t,h,a,n,k,s]と文字に変換し言語モデルで文字から[thanks]と意味のある語のつながりに変換するイメージです.しかし, このような音声認識システムの問題点としては大きく二つあります.

  • ユーザー依存のよくわからない発音を表現できない.
  • 学習データに一回もしくは一回も出てきていない単語は認識することが困難.

二つ目の問題に関して, 一般的な言語モデルではとても確率が低いと判断されてしまうため認識が困難であると考えられます. この論文では二つ目の問題を解決することで認識精度の向上を図っています. 方法としては出現頻度の少ない単語に関して特別な辞書を作成し(この辞書は地域によって異なる), ユーザーの位置情報を利用して適切な辞書を適用するというものです.

Geo-LM

この論文では位置情報を考慮した辞書で学習したモデルのことをGeo-LMと呼んでいます. 現状ではこのGeo-LMがどのように構成されていてどう音声認識を制御しているのかを理解しきれていないので理解できたら追加しておきます・・・.

実験結果

実験に使用したは5000時間の英語の音声データでモデルはCNN-HMMモデルを使用していました. 音響モデルの入力特徴量はフィルターバンクで言語モデルのn-gramは4-gramを使用して学習していました. 実験結果が下の図なのですがGeneral LM errorがGeo-LMを用いない手法を用いた時のエラー率でGeo-LM errorが提案手法を用いた時のエラー率です. 結果としてはそれぞれの地域でエラー率を9%~12%程度削減できていることがわかります. 従来手法では4回に1回は認識できていなかったのに対して, 提案手法では9回に1回の認識ミスになっているのでかなりエラー率を削減できていると思います.

感想

今回はappleのsiriについての論文が出ていたのでまとめてみました. 今までよりかなりエラー率が削減できていることが分かりますし, 今回提案している考え方は地域別の適用だけではなく職業別や環境別にも適用しやすいのかなと思いました. もちろん多言語への適用も簡単にできると思います. アメリカでは実際に使えるようになっていて, いい結果を出した手法はすぐに取り入れてユーザのフィードバックなどをもらえるのもappleの強みだと思います. 今後も認識率向上のために様々な手法が取り入れられていくと思うので楽しみなところです.

[python] multiprocessingにおける共有変数の使い方

前回の投稿でpythonにおけるmultiprocessingの基本的な使い方をまとめました. multiprocessingでは複数のプロセスで同時に処理するので基本的に同一変数のメモリの共有は行いません。しかし、実際に使用する時は同一の処理を複数プロセスで行い一つの変数に格納したいことが多いと思います. このような場合はプロセス間で共有の変数を定義することで解決することができます.今回はmultiprocessingにおける共有変数の使い方についてまとめていきます.

共有変数を定義する方法

共有変数を定義する時はValueクラスかArrayクラスを用います. 単純にスカラー値を共有したい時はValueクラスを, 配列を共有したい時はArrayクラスを用いて変数を定義します.また定義した共有変数をPoolクラスのinitializerに引き渡すことでプロセス開始時に変数の共有を行います. 今回は配列を用意して配列の値をインデックスごとにマイナスにする処理を並列処理させました.

ValueクラスやArraykクラスで指定したdは型のタイプで今回はdouble型です。他にもf(float)やi(int)が指定可能です。function内でshared_count.acquire()とありますがこれは変数のアクセスをロックするメソッドで, プロセス間で同一の変数の書き換えを行う場合は処理を始める前にロックしておかないと処理中に変数の値が他のプロセスによって書き換えられてしまうので気をつけてください.

実行結果としては11805-11808の四つのサブプロセスで正しく実行できていることが分かります.

まとめ

今回はpythonのmultiprocessingにおいて共有変数を定義し複数プロセス間で同一の変数にアクセスする方法をまとめました. 複雑な処理になってくるとロックする位置などを間違えると処理結果などが変わってきてしまうため少し面倒ですが使いこなせばかなり便利だと思います. まだまだ使い方の理解が不十分なので分かったことがあったらまとめていきたいと思います.

[python] multiprocessingの基本的な使い方

pythonで処理を早く終わらせたい場面などがあると思います. 基本的にpythonのプログラムを実行すると1つのプロセスが立ち上がって処理をします. この処理を高速化するために複数のプロセスを立ち上げて並列処理することで実行時間を削減することができます. 少し難しいように感じますがpythonでは標準ライブラリにmultiprocessingというライブラリがあり, これを使うことで簡単に並列処理することができます. 今回はこのライブラリの簡単な使い方を紹介していきます.

pythonにおけるmultiprocessingの立ち位置

pythonでは処理を高速化する方法が大きく分けて2つあります. 複数のプロセスを立ち上げて並列処理するmultiprocessingを使用する方法と1つのプロセスを立ち上げて複数のスレッドで並列処理するthreadingがあります. threadingは実装するのが難しい上にそれぞれのクラスを正しく使用していないと多少の高速化をしかできないなど扱いづらい印象があります. その上プログラムがスレッドセーフでないと予期せぬ動作をしてしまいます. 一方, multiprocessingは実装が簡単であり高速化も容易にできます. また, スレッドを使用する代わりにサブプロセス(子プロセス)を使用することで,GILの問題を効率的に回避できるようになっているみたいです. このような理由から, 個人的にpythonで高速化するならmultiprocessingをおすすめします.

multiprocessingの使い方

pythonの標準ライブラリであるmultiprocessingを使い並列処理をする方法を説明していきます。multiprocessingでは並列処理したい処理を関数化し、その定義した関数をPoolクラスを用いて並列処理します。

最初にPoolクラスを生成しますが, その際に使用するコア数を指定します. 今回はマシンの最大使用可能コア数を指定しました. 並列処理したい内容を定義したfunction関数をPoolクラスのmapメソッドの引数で渡すことで実行することができます. mapメソッドの第二引数が並列処理する関数の引数となります. function関数内でsleep関数を使用していますが今回は処理が簡単だったので表示順が前後してしまうのでsleepさせました. 終了したらPoolクラスのcloseメソッドでプロセスを閉じます。closeを忘れると並列処理していたメモリが解放されずに残り続けるので気をつけてください.

子プロセス数は4つで, 親プロセスIDの2618に対して子プロセスIDは2621~2624の4つで実行されていることが分かります.

まとめ

今回は基本的なmultiprocessingの使い方を紹介しました. 実際に使うときは並列処理した結果を1つとして扱いたい場合がほとんどだと思います(並列処理した結果を配列に格納するなど). この場合は複数プロセスの間でメモリを共有することで, それぞれのプロセスの結果を共有することができます. 次回は複数プロセスの間でメモリを共有する方法を紹介します.

Macにaudacity, inkscapeをインストールする方法

4年間ほどubuntuをメインOSとして開発をしてきたのですが最近Mac OSに移行したので, ubuntuで使用していたツールがなかったりして不便していました. なので元々使用していた便利なツールなどをMacにインストールする方法をまとめていきたいと思います. 今回の記事ではubuntu16.04にデフォルトでインストールされているaudacityとinkscapeのインストール手順を紹介します.

audacityのインストール手順

audacityのインストールは簡単でした. まず公式サイトからdmgファイルをダンウロードします.dmgファイルを右クリック(二本指クリック)で開きます. audacityのアイコンが出てくるのでダブルクリックするとインストールが開始します. 特に問題がなければ正常にインストールが完了しaudacityが使えるようになります.

inkscapeのインストール手順

inkscapeはbrewコマンドを使用すればインストールされます. しかし,  2018/07/03時点でinkscapeをbrewでインストールすると以下のエラーが出ます.(おそらく公式のバグかと…)

ダウンロードしてきたファイルのハッシュ値と公式が提供しているハッシュ値が異なっているためエラーが出てしまっています. 解決方法としてはこちらのサイトを参考にしました. 少し強引なやり方ですが公式が提供しているハッシュ値を書き換えます.

上記のコマンドでinkscapeのファイルを編集します. 6行目にあるsha256の値を下記のように変更して保存してください.

そしたら, 再度brew install caskformula/caskformula/inkscapeを実行するとインストールが正常に完了します.

まとめ

今回はインストールが簡単なツールのインストール手順を紹介しました. ubuntu16.04で使っていた便利なツールをこれからMacにインストールしていくのでブログに残していこうと思っています.