ichou1のブログ

主に音声認識、時々、データ分析のことを書く

音声合成メモ(tacotron2その4)

レーニング時におけるmodelの内部処理を見てみる。

Embedding/Encoderレイヤ

Embeddingレイヤに渡す前に、テキスト文字はidに置き換えられる。

idはゼロ始まりの148個。
ARPAbetの発音記号も含まれる。

{'_': 0, '-': 1, '!': 2, "'": 3, '(': 4, ')': 5, ',': 6, '.': 7, ':': 8, ';': 9, '?': 10, ' ': 11, 'A': 12, 'B': 13, 'C': 14, 'D': 15, 'E': 16, 'F': 17, 'G': 18, 'H': 19, 'I': 20, 'J': 21, 'K': 22, 'L': 23, 'M': 24, 'N': 25, 'O': 26, 'P': 27, 'Q': 28, 'R': 29, 'S': 30, 'T': 31, 'U': 32, 'V': 33, 'W': 34, 'X': 35, 'Y': 36, 'Z': 37, 'a': 38, 'b': 39, 'c': 40, 'd': 41, 'e': 42, 'f': 43, 'g': 44, 'h': 45, 'i': 46, 'j': 47, 'k': 48, 'l': 49, 'm': 50, 'n': 51, 'o': 52, 'p': 53, 'q': 54, 'r': 55, 's': 56, 't': 57, 'u': 58, 'v': 59, 'w': 60, 'x': 61, 'y': 62, 'z': 63, '@AA': 64, '@AA0': 65, '@AA1': 66, '@AA2': 67, '@AE': 68, '@AE0': 69, '@AE1': 70, '@AE2': 71, '@AH': 72, '@AH0': 73, '@AH1': 74, '@AH2': 75, '@AO': 76, '@AO0': 77, '@AO1': 78, '@AO2': 79, '@AW': 80, '@AW0': 81, '@AW1': 82, '@AW2': 83, '@AY': 84, '@AY0': 85, '@AY1': 86, '@AY2': 87, '@B': 88, '@CH': 89, '@D': 90, '@DH': 91, '@EH': 92, '@EH0': 93, '@EH1': 94, '@EH2': 95, '@ER': 96, '@ER0': 97, '@ER1': 98, '@ER2': 99, '@EY': 100, '@EY0': 101, '@EY1': 102, '@EY2': 103, '@F': 104, '@G': 105, '@HH': 106, '@IH': 107, '@IH0': 108, '@IH1': 109, '@IH2': 110, '@IY': 111, '@IY0': 112, '@IY1': 113, '@IY2': 114, '@JH': 115, '@K': 116, '@L': 117, '@M': 118, '@N': 119, '@NG': 120, '@OW': 121, '@OW0': 122, '@OW1': 123, '@OW2': 124, '@OY': 125, '@OY0': 126, '@OY1': 127, '@OY2': 128, '@P': 129, '@R': 130, '@S': 131, '@SH': 132, '@T': 133, '@TH': 134, '@UH': 135, '@UH0': 136, '@UH1': 137, '@UH2': 138, '@UW': 139, '@UW0': 140, '@UW1': 141, '@UW2': 142, '@V': 143, '@W': 144, '@Y': 145, '@Z': 146, '@ZH': 147}


短めの音声(LJ030-0109.wav、テキスト「The Vice-Presidential car」)を例に見てみる。

テキスト「The Vice-Presidential car」はスペースも含めてidに置き換えられる(アルファベットは小文字へ変換してからidに置き換え)

[57, 45, 42, 11, 59, 46, 40, 42,  1, 53, 55, 42, 56, 46, 41, 42, 51, 57, 46, 38, 49, 11, 40, 38, 55]
Embeddingレイヤ

トークン数は「148」、ベクトルサイズは「512」次元。

(embedding): Embedding(148, 512)  # (n_symbols, symbols_embedding_dim)

アウトプットの形状は下記となる。

[batch_size, seq_len, 512]
# --> Transpose(1, 2)
[batch_size, 512, seq_len]
encoderレイヤ

5文字ずつ畳み込みを3回繰り返して、Bi-LSTM。

(encoder): Encoder(
  (convolutions): ModuleList(
    (0): Sequential(
      (0): ConvNorm(
        (conv): Conv1d(in_channels=512,
                       out_channels=512,
                       kernel_size=(5,),
                       stride=(1,),
                       padding=(2,))
      )
      (1): BatchNorm1d(num_features=512,
                       eps=1e-05,
                       momentum=0.1,
                       affine=True,
                       track_running_stats=True)
    )
    (1): Sequential(
      省略
    )
    (2): Sequential(
      省略
    )
  )
  (lstm): LSTM(input_size=512,
               hidden_size=256,
               batch_first=True,
               bidirectional=True)
)

アウトプットの形状は下記となる。

[batch_size, 512, seq_len]

Decoderレイヤ

Decoderの最初の入力として、値がALLゼロのをTensorを使う。

(1, batch_size, 80)

これをlog-mel spectrogramのTensorと結合する。

# decoder_inputs.shape
(1 + frame_len, batch_size, 80)

Prenet(Linear変換2回)を通した後のTensor

# decoder_inputs.shape
(1 + frame_len, batch_size, 256)

上記の「decoder_inputs」に対して、frame分、ループを回す。
1回のループにおける処理を図示すると下記のとおり(丸枠がTensor、角枠が演算)
f:id:ichou1:20201012082538p:plain
"B"は「batch_size」を表す

「attention_weights」と「attention_context」は次ループでのインプットとして使用する。

Attentionに関しては、queryが「log-mel spectrum」(*)、memoryが「テキスト文字列」(Encode結果)に該当する。

(*)1frame分なので、「spectrogram」ではなく、「spectrum」としている