Tacotron2で始める日本語音声合成

#はじめに
最も気になるのはやはりどの程度のものができるのかだと思うので、まずは[こちら](https://drive.google.com/file/d/1rvO55iqeGkpOu3Of5mrfy8uHJhnvS1f-/view?usp=sharing)をお聞きください。

このモデルは

- pre-trained model を使用した転移学習
- 約一時間の前処理済みのデータ
- WaveGlow (published model)

で学習、推論しています。
これから始める方の参考になるように私のやり方を紹介します。

Tacotron2についてはこちらが参考になります。
[Tacotron2を用いた日本語TTS(Text-to-Speech)の研究・開発【まとめ】](https://qiita.com/yukari120/items/70cdea43743f4a35d85c)

※デモを既に動かしていることを前提としています。

#用意するもの
##音声ファイル  
- 22050Hz 16bit モノラル wav
- 音声区間毎に分割  

ノイズが多いもの、笑い声等のテキストにしづらいものは除外します。
長過ぎるものは学習時にメモリエラーが出ることがあります。私は10秒以内のもののみにしています。

##テキスト  
###train.txt val.txt を作成  
 [ljs_audio_text_val_filelist.txt](https://github.com/NVIDIA/tacotron2/blob/master/filelists/ljs_audio_text_val_filelist.txt) を参考に
`FILE PATH|TEXT`
と表記していきます。
trainとvalのバランスは私は9：1にしています。音素バランスなどは考慮していません。
###音素表記  
 TEXTは下記を参考に音素で表記していきます。
[wiki 日本語の音素](https://ja.wikipedia.org/wiki/音素#日本語の音素)
[声優統計コーパス 音素バランス文](https://github.com/voice-statistics/voice-statistics.github.com/blob/master/assets/doc/balance_sentences.txt)

使用できる文字は[symbols.py](https://github.com/NVIDIA/tacotron2/blob/master/text/symbols.py#L9#L12)の要素のみです。

このとき注意する点として`koNnichiwa`と入力するとTacotron2の内部では`['k','o','n','n','i','c','h','i','w','a']`と変換されます。
もし`['k','o','N','n','i','ch','i','w','a']`としたいのであれば`{}`で囲う必要があります。
ただし使用できるのは[cmudict.py](https://github.com/NVIDIA/tacotron2/blob/master/text/cmudict.py#L6#L14)の`valid_symbols`内の要素のみです。
ですので`ko{N}ni{CH}iwa`とする必要があります。

また`k o {N} n i {CH} i w a`というような表記でも良いかとおもいます。私は`konnnichiwa`としています。
###文末にEOSを追加
[Model can not converge #254](https://github.com/NVIDIA/tacotron2/issues/254#issuecomment-523707805)
学習時にattentionの収束が加速されるそうです。  

###例
私はこのようにしています。

```text:train.txt
/wav/0126.wav|na&tanndesukedo-.
/wav/0022.wav|biyo-inndake-yoyakuwasimasita.
/wav/0149.wav|tasikani,ari!.
/wav/0092.wav|sositara-.
/wav/0063.wav|teyu-ne.
/wav/0202.wav|donndonn,tama&tekunndesuyo.
```

#設定
###hparams.pyを編集

- iters_per_checkpoint  
好きな数値に変更
- training_files  
train.txtのpath
- validation_files  
val.txtのpath
- text_cleaners  
`['basic_cleaners']`に変更  
transliteration_cleaners についてはこちらが参考になります。  
[Tacotron2系における日本語のunidecodeの不確かさ](https://qiita.com/nishiha/items/6e2a2ddaafe03fa7f924)
- batch_size  
私は`32`にしています。issuesなどを見ると`8~16`くらいにしてる方が多いようです。GPUと相談して決めてください。

###train.pyにexponential learning rate decayを追加
[Model can not converge #254](https://github.com/NVIDIA/tacotron2/issues/254#issuecomment-526005735)

#学習
pre-trained model を使用して学習していきます。
10k iterの結果です。Colab T4で約6時間半でした。
**grad.norm**
![grad.norm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655259/a1d62bc6-a301-177a-39e2-e30d9623fcfd.png)

**training.loss**
![training.loss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655259/08b9bfe6-97af-6474-8261-90f55dafa22a.png)


#推論
各checkpointの結果です。
sigma=1,denoiser未使用

- また東寺のように五大明王と呼ばれる主要な明王の中央に配されることも多い  
[2500](https://drive.google.com/file/d/1khnnsPh7lZTIGh-33f7BsKJvPi7AFPQ2/view?usp=sharing) | [5000](https://drive.google.com/file/d/1OJQrbWVIz4HzZGsnpWdEEUqrv6TGgh1H/view?usp=sharing) | [7500](https://drive.google.com/file/d/1Y6OB9J7PljoJKhLP8AWv83aeoxtSMbtG/view?usp=sharing) | [10000](https://drive.google.com/file/d/1QCtfQEU6DyMLp9dmyZIRVmxysXBopoQQ/view?usp=sharing)
- ニューイングランド風は牛乳をベースとした白いクリームスープでありボストンクラムチャウダーとも呼ばれる  
[2500](https://drive.google.com/file/d/1MB0_jSNBR6P4Ezb4l_Uh3wXcOutxc-rY/view?usp=sharing) | [5000](https://drive.google.com/file/d/1D8jaJfgIWVqHawMV18Jjf861ArydWNqG/view?usp=sharing) | [7500](https://drive.google.com/file/d/1VT-F8FG_qLjvzwKjMPEj5okrYwbv1eVo/view?usp=sharing) | [10000](https://drive.google.com/file/d/1zCsc7kupsh7Tlc8owGwR3fpMtxpCJgb2/view?usp=sharing)
- コンピュータゲームのメーカーや業界団体などに関連する人物のカテゴリ  
[2500](https://drive.google.com/file/d/13jpmfSUKUqmh8fLJzFDR59Yvg8eTs08D/view?usp=sharing) | [5000](https://drive.google.com/file/d/1byH1qxPLKxrFgZG4gSZliCrcD2NK-0G4/view?usp=sharing) | [7500](https://drive.google.com/file/d/1IGRmcz9poebye1lplkW7L_hQFZ3NMHwe/view?usp=sharing) | [10000](https://drive.google.com/file/d/1LUfkZ3ojvm52yBgcRnXy1-a4RKhIrQJl/view?usp=sharing)