Griffin-Limの位相復元について調べてみた。

## はじめに
信号処理の基本（STFTなど）についての説明は割愛しています。そのあたりの説明込みでしたら[こちらの記事](https://qiita.com/ma-szk/items/fe5c3d010b281dcd3537)がおすすめです。(本記事はこちらの記事となるべく被らないような内容にしているので読んだ後にまた戻って来てくれると嬉しいです)
この記事を作成するにあたり使用したPythonコードは[github](https://github.com/r-sugahara/griffin-lim)に挙げていますので参考になれば幸いです。(googlecolabで動かしたものになります)

## 位相復元とは（ざっくり）
位相復元とは、複素数で表される信号の，絶対値のみが分かっている状況において，元の複素数値の信号を復元することです。図で見てみると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543544/c6517de3-d9a7-bbf0-35ab-928aa382453b.png)
(https://www.logical-arts.jp/archives/112 より)
振幅Aだけが分かっている状況で位相θを復元することになります。

## どんな時に使うか
例えば、振幅スペクトログラムを生成するタイプの音声合成手法は、最終的な音声合成を得るのに位相復元が必要になります。ただ音の世界だと、人は位相に鈍感なのとマイクロホンは音の圧力変動をセンシングしているので位相情報も取得できるためあまり使われていません。
一方、光の世界だと周波数帯が高く光の強弱しかセンシングできないため、位相復元が重要な役割を果たす場合があるそうです。

## Griffin-Limアルゴリズム
それではどのように復元するかを見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543544/bdc541fa-32b6-ba35-d741-3461301a1acf.png)
すごいシンプル!!!振幅はわかっているので固定して、位相だけ入れ替える感じですね。(1)～(3)を繰り返すことでスペクトログラムの無矛盾性から位相が得られます。
...無矛盾性?

## スペクトログラム無矛盾性
STFTで得られるスペクトログラムには一貫した近傍共起関係がある（時間と周波数の両方向に滲んでいる）そうです。このことがスペクトログラムの無矛盾性と呼ばれています。画像で見ると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543544/ede40d77-cbc0-2d5b-3aea-6581d9d2610b.png)
(https://www.slideshare.net/DaichiKitamura/ss-244176576 より)
このようなイメージ。これはSTFTの窓関数乗算やオーバーラップシフトが原因とのこと。オーバーラップしている＝隣のフレームとは似ているべき＝滲む というようなことでしょうか。失われた値を推定するのではなく、辻褄のあった位相スペクトログラムを推定する手法だそうです。

## 本当に戻るのか？音声聞いてみた編
実際にやって聞いてみました。Qiitaに音声を埋め込む方法がわからず時間波形ですみません。([github](https://github.com/r-sugahara/griffin-lim)にあげたこのコードを動かせばご自身で聞けるかと思います。)

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543544/3a412e7d-177b-146d-f3fd-21059bc206ac.png)
上から、元信号、繰り返し1回、繰り返し100回になります。1回ではまだ不十分そうですが100回だとかなり復元できていそうに見えますね。
実際に音で聞いてみると100回は完全に元信号と同じように聞こえ、1回でもかなりいい線行っているように聞こえました。

## 本当に戻るのか？位相スペクトログラム編
続いて位相スペクトログラムを見てみます。
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543544/59d6a0cf-fc25-7069-7b56-44a0c63d0991.png)
左から、繰り返し回数1回、繰り返し回数100回、元信号です。
...これを見てもよくわからないですね。元信号との差をそれぞれ見てみます。
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543544/a6755700-19aa-15b6-3816-121dcd2e34b1.png)
左は繰り返し数1回、右は繰り返し数100回のものとそれぞれ元の信号の差を見たものになります。
繰り返し回数が1回だとランダムになっているのに対して100回のものは局所的に同じ色になっている=誤差にまとまりが出ています。
繰り返し数を増やしてみるとどうなるのかも見てみました。
![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2543544/c604fabd-ffb4-dd48-fe46-476b25681dd0.png)
左から100回、1000回、10000回です。
最初は隣同士でSTFTスペクトログラムの無矛盾性によりつじつま合わせがなされ、それが徐々に広がり、繰り返し回数を増やしまくれば最終的には1色になる（ある誤差をもって元信号と同じになる）のかな...と思っていたら1000回と10000回にはほぼ差がないように見えます。もっと時間信号が短かったりFFTサイズが小さいと変わるのかもしれないですが、あちらがたてばこちらが立たず...か繰り返されているんですかね。
いずれにせよ誤差は大きいですね、これが聞いても分からないなんて驚きです。


## おわりに
pythonで学ぶ音声合成という本を読んでいる途中に位相復元なるものにぶちあたり勉強したことの備忘録でした。
コードなしですみません。オーバーラップやFFTのフレームサイズによって実行時間も性能もかなり変わったのでよければご自身でいじってみてください。([github](https://github.com/r-sugahara/griffin-lim))
なんとなくわかった気がする...くらいの理解度なので間違っている箇所あるかもしれません。ご指摘いただけると幸いです!
聴感上は非常によく戻っているけれど、実際はつじつま合わせをしているだけなので元信号との位相スペクトログラムの差を見てみるとかなりズレがあることがよくわかりました！


## 参考文献
今回とても参考になった文献です。おすすめです。
・[短時間フーリエ変換の基礎と応用　小野順貴](https://www.jstage.jst.go.jp/article/jasj/72/12/72_764/_pdf/-char/ja)
・[音響信号処理における位相復元　矢田部浩平](https://www.jstage.jst.go.jp/article/essfr/15/1/15_25/_pdf/-char/en)
・[スペクトログラム無矛盾性を用いた独立低ランク行列分析の実験的評価　北村大地　矢田部浩平](https://www.slideshare.net/DaichiKitamura/ss-244176576)