Multi-Speaker Tocotron2 + Wavenet Vocoder + Korean TTS
Tacotron2 ๋ชจ๋ธ๊ณผ Wavenet Vocoder๋ฅผ ๊ฒฐํฉํ์ฌ ํ๊ตญ์ด TTS๊ตฌํํ๋ project์ ๋๋ค. Tacotron2 ๋ชจ๋ธ์ Multi-Speaker๋ชจ๋ธ๋ก ํ์ฅํ์ต๋๋ค.
Based on
- https://github.com/keithito/tacotron
- https://github.com/carpedm20/multi-speaker-tacotron-tensorflow
- https://github.com/Rayhane-mamah/Tacotron-2
- https://github.com/hccho2/Tacotron-Wavenet-Vocoder
Tacotron 2
- Tacotron ๋ชจ๋ธ์ ๊ดํ ์ค๋ช ์ ์ด์ repo ์ฐธ๊ณ ํ์๋ฉด ๋ฉ๋๋ค.
- Tacotron2์์๋ ๋ชจ๋ธ ๊ตฌ์กฐ๋ ๋ฐ๋์๊ณ , Location Sensitive Attention, Stop Token, Vocoder๋ก Wavenet์ ์ ์ํ๊ณ ์๋ค.
- Tacotron2์ ๋ํ์ ์ธ ๊ตฌํ์ Rayhane-mamah์ ๋๋ค. ์ด ์ญ์, keithito, r9y9์ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ ๋ ๊ฒ์ด๋ค.
This Project
- Tacotron2 ๋ชจ๋ธ๋ก ํ๊ตญ์ด TTS๋ฅผ ๋ง๋๋ ๊ฒ์ด ๋ชฉํ์ ๋๋ค.
- Rayhane-mamah์ ๊ตฌํ์ Customization๋ Layer๋ฅผ ๋ง์ด ์ฌ์ฉํ๋๋ฐ, ์ ๊ฐ ๋ณด๊ธฐ์๋ ๋๋ฌด ๋ณต์กํ๊ฒ ํ ๊ฒ ๊ฐ์, Cumomization Layer๋ฅผ ๋ง์ด ์ค์ด๊ณ , Tensorflow์ ๊ตฌํ๋์ด ์๋ Layer๋ฅผ ๋ง์ด ํ์ฉํ์ต๋๋ค.
- teacher forcing ๋ฐฉ์์ train sample์ 2000 step๋ถํฐ, free forcing ๋ฐฉ์์ test sample์ 3000 step๋ถํฐ ์์๋ค์ ์ ์๋ ์ ๋์ ์์ฑ์ ๋ง๋ค๊ธฐ ์์ํฉ๋๋ค.
๋จ๊ณ๋ณ ์คํ
์คํ ์์
- Data ์์ฑ: ํ๊ตญ์ด data์ ์์ฑ์ ์ด์ repo ์ฐธ๊ณ ํ์๋ฉด ๋ฉ๋๋ค.
- ์์ฑ๋ Data๋ ์๋์ 'data_paths'์ ์ง์ ํ๋ฉด ๋๋ค.
- tacotron training ํ, synthesize.py๋ก test.
- wavenet training ํ, generate.py๋ก test(tacotron์ด ๋ง๋ค์ง ์์ mel spectrogram์ผ๋ก testํ ์๋ ์๊ณ , tacotron์ด ๋ง๋ mel spectrogram์ ์ฌ์ฉํ ์๋ ์๋ค.)
- 2๊ฐ ๋ชจ๋ธ ๋ชจ๋ train ํ, tacotron์์ ์์ฑํ mel spectrogram์ wavent์ local condition์ผ๋ก ๋ฃ์ด testํ๋ฉด ๋๋ค.
Tacotron2 Training
- train_tacotron2.py ๋ด์์ '--data_paths'๋ฅผ ์ง์ ํ ํ, trainํ ์ ์๋ค. data_path๋ ์ฌ๋ฌ๊ฐ์ ๋ฐ์ดํฐ ๋๋ ํ ๋ฆฌ๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.
parser.add_argument('--data_paths', default='.\\data\\moon,.\\data\\son')
- train์ ์ด์ด์ ๊ณ์ํ๋ ๊ฒฝ์ฐ์๋ '--load_path'๋ฅผ ์ง์ ํด ์ฃผ๋ฉด ๋๋ค.
parser.add_argument('--load_path', default='logdir-tacotron2/moon+son_2019-02-27_00-21-42')
- model_type์ 'single' ๋๋ ' multi-speaker'๋ก ์ง์ ํ ์ ์๋ค. speaker๊ฐ 1๋ช ์ผ ๋๋, hparams์ model_type = 'single'๋ก ํ๊ณ train_tacotron2.py ๋ด์์ '--data_paths'๋ฅผ 1๊ฐ๋ง ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
parser.add_argument('--data_paths', default='D:\\Tacotron2\\data\\moon')
- ํ์ดํผํ๋ผ๋ฉํฐ๋ฅผ hparmas.py์์ argument๋ฅผ train_tacotron2.py์์ ๋ค ์ค์ ํ๊ธฐ ๋๋ฌธ์, train ์คํ์ ๋ค์๊ณผ ๊ฐ์ด ๋จ์ํฉ๋๋ค.
python train_tacotron2.py
- train ํ, ์์ฑ์ ์์ฑํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ๋ฉด ๋๋ค. '--num_speaker', '--speaker_id'๋ ์ ์ง์ ๋์ด์ผ ํ๋ค.
python synthesizer.py --load_path logdir-tacotron2/moon+son_2019-02-27_00-21-42 --num_speakers 2 --speaker_id 0 --text "์ค์คํธ๋๋กํผํ ์ฟ ์ค ์ํ๋ ์์ค๋ ๋ฉธ์ข ๋ ์ฌ๋์กฑ ์ข ์ผ๋ก, ํ์ฌ์๋ ๋ผ ํ์์ด ๋ฐ๊ฒฌ๋์ด ์๋ค."
Wavenet Vocoder Training
- train_vocoder.py ๋ด์์ '--data_dir'๋ฅผ ์ง์ ํ ํ, trainํ ์ ์๋ค.
- memory ๋ถ์กฑ์ผ๋ก training ๋์ง ์๊ฑฐ๋ ๋๋ฌด ๋๋ฆฌ๋ฉด, hyper paramerter ์ค sample_size๋ฅผ ์ค์ด๋ฉด ๋๋ค. ๋ฌผ๋ก batch_size๋ฅผ ์ค์ผ ์๋ ์๋ค.
DATA_DIRECTORY = 'D:\\Tacotron2\\data\\moon,D:\\Tacotron2\\data\\son'
parser.add_argument('--data_dir', type=str, default=DATA_DIRECTORY, help='The directory containing data')
- train์ ์ด์ด์ ๊ณ์ํ๋ ๊ฒฝ์ฐ์๋ '--logdir'๋ฅผ ์ง์ ํด ์ฃผ๋ฉด ๋๋ค.
LOGDIR = './/logdir-wavenet//train//2018-12-21T22-58-10'
parser.add_argument('--logdir', type=str, default=LOGDIR)
- wavenet train ํ, tacotron์ด ์์ฑํ mel spectrogram(npyํ์ผ)์ local condition์ผ๋ก ๋ฃ์ด์ TTS์ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค.
python generate.py --mel ./logdir-wavenet/mel-moon.npy --gc_cardinality 2 --gc_id 0 ./logdir-wavenet/train/2018-12-21T22-58-10
Result
- Tacotron์ batch_size = 32, Wavenet์ batch_size=8. GTX 1080ti.
- Tacotron์ step 100K, Wavenet์ 177K ๋งํผ train.
- samples ๋๋ ํ ๋ฆฌ์๋ ์์ฑ๋ wavํ์ผ์ด ์๋ค.
- Griffin-Lim์ผ๋ก ์์ฑ๋ ๊ฒ๊ณผ Wavenet Vocoder๋ก ์์ฑ๋ sample์ด ์๋ค.
- Wavenet์ผ๋ก ์์ฑ๋ ์์ฑ์ train ๋ถ์กฑ์ผ๋ก ์ก์์ด ์์ฌ์๋ค.