復現兩篇論文, 結構實現細節進行說明.代碼備份, 報告完成並備份.

Google: Voice clone and code-switching cross multi-language

 

1.再仔細讀一遍google論文中的language id和speaker id送入Decoder大結構的細節.

目前用法可能比較弱, 使得音質不好, 或者口音clone不好, 但如沒有說明, 則目前版本可以代表復現版本, 再加上另一篇(好多處加結構的對比試驗), 可以言之有理. 追求平等/控制變量的話, 以後的實驗language id也較弱使用, 然後多跑一個強使用language id的就行. 並且要參考DeepVoice2和interspeech19的那篇對比位置的.

Paper augments the base Tacotron 2 model with additional speaker and, optionally, language embedding inputs (bottom right), an adversarially-trained speaker classifier (top right), and a varia-tional autoencoder-style residual encoder (top left) which con-ditions the decoder on a latent embedding computed from the target spectrogram during training (top left). Finally, similar to Tacotron 2, we separately train a WaveRNN

首先, 沒說明白speaker id, language id的具體用法.

optionally: 說明有的時候他是沒有用的, 換句話說, paper着重於口音是通過adLoss來的. 是和綁定的解釋性文本有關的, 和我們的factor思路並不完全一致.

2. 總是在音色clone, 口音clone的剛開始階段不好, 容易"竄頻道"到另一個, 需要特殊處理.

3. 實驗1: no_vae_no_ref_has_language: 音色+口音綁定到了一起, 音色clone很好, 但是口音不能實現clone, 並且會影響到stop_token等的不良產生. 

數據在v100文件夾下的output和外面的text文本. 訓練到20w步 (目前版本的所有超參數和結構) 就不再訓練了, 除非結構上和論文出入很大, 如1, 則目前默認爲復現實驗成功反饋出了單語單人不能解綁, 但音色(+口音)可clone的事實. 

CUHK: LDE and SPE for code-switching

 

1. CBHG-T1版本的訓練很慢, 是因爲CBHG很慢嗎, 那是不是後端取消了post_net就會訓練得更快. 然後阻止post_net回傳的技巧也還沒有關注. 先總結別的實驗.

雖然LDE和SPE結構有些不同, 但是差的有點多, v100更慢, 很奇怪. 有空都在lab10跑跑.   可能是因爲一個GPU拆開了跑的原因.

2. 爲什麼寫代碼的時候是錯的, 就是cbhg叫一個名字, 但是訓練時候可以, 合成的時候就不可以了.

Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at

結論: 在訓練的時候, 採用的是tf.AUTO_REUSE, 而合成的時候, 版本比較舊, 在create model那裏, 套上tf.AUTO_REUSE就好了.

問題: 爲啥改了之後有的有聲音可辨識, 有的不能? 想着應該都可以的.

小技巧, 複製文件夾

http://bbs.chinaunix.net/thread-2077235-1-1.html

https://blog.csdn.net/yuan882696yan/article/details/45894549

3. LDE的結果很不好, 音色影響效果太小, 沒有clone, 而口音必須要和文本一樣纔行, 不然會明顯的有別的文字夾渣, 確實是google那篇用text的adLoss的例子! 爲了表明效果, 嚴格按照CUHK的參數, 並且batch從16變爲和google的32, 但是其實我實現的時候, 就很謹慎了, 所以說明是解不開, 因此至少要像論文中一樣使用(1) 多說話人數據集 (2) 增強speaker id在decoder部分的力度, 因爲有可能是Tacotron-2實現不好的問題. 在v100上跑. 同時lab10繼續修正shared的SPE, 來真實反映SPE的能力.

2. 和老師討論的:

單獨的英文句子, 用英文language id, 英文說話人, 合成還可以, 但是有顫音.

但是混合的句子, 英文部分仍然是英文language id, 英文說話人, 按理說應該發出英文音色的聲音, 至少和上面一樣, 但是卻不對.

並且最明顯的是: 17和25(text)中, 後半段都是000的英文, 說話人都是0, 但是17是英國, 25是中國. 並且25應該是英國的音色啊, 怎麼回事. 而20(text)後半段英文, 說話人是中文, 就有些不清楚, 音色也不遷移了. 27(text)中國人說英文, 仍是中國口音.

https://zhuanlan.zhihu.com/p/28196873

https://www.tensorflow.org/versions/r1.14/api_docs/python/tf/nn/dynamic_rnn

language ID在bi-rnn中是選取最多的那個作爲初始狀態. 但是不知道怎麼改; 討論應該怎麼放, 分析在羣裏.

假設:

先拿最開始 (first) 的一個作爲最多的, 在訓練的時候沒問題, 測試的時候儘量以最多的那個語言打頭.

具體到實現:

https://www.tensorflow.org/versions/r1.14/api_docs/python/tf/nn/dynamic_rnn

https://www.tensorflow.org/versions/r1.14/api_docs/python/tf/nn/bidirectional_dynamic_rnn

#first select first:
most_but_now_first_language_id = embedded_language_id[:, 0]
#then gru:
gru_init_state = tuple([init_state])

###############because:
#our self GRU:

def init_state(self, batch_size, dtype):
        if self.__init_state is not None:
            return tuple([self.__init_state])
        else:
            return self.zero_state(batch_size, dtype)
############tensorflow source code use init_state directly:
if initial_state is not None:
      state = initial_state

另外, 

Discriminative Embeddings, 放的地方很謹慎, T2少了一個DecoderRNN, 討論應該怎麼放, 分析在羣裏.

假設:

在attentionRnn前加, 在attention得到的context vec加, 但沒有了decoderRnn. 其實少了個RNN. 去查看:

https://github.com/NVIDIA/tacotron2

說得很清楚, 而且代碼可讀性和質量都很高, 說明:

self.prenet = Prenet(
            hparams.n_mel_channels * hparams.n_frames_per_step,
            [hparams.prenet_dim, hparams.prenet_dim])

        self.attention_rnn = nn.LSTMCell(
            hparams.prenet_dim + hparams.encoder_embedding_dim,
            hparams.attention_rnn_dim)

        self.attention_layer = Attention(
            hparams.attention_rnn_dim, hparams.encoder_embedding_dim,
            hparams.attention_dim, hparams.attention_location_n_filters,
            hparams.attention_location_kernel_size)

        self.decoder_rnn = nn.LSTMCell(
            hparams.attention_rnn_dim + hparams.encoder_embedding_dim,
            hparams.decoder_rnn_dim, 1)

        self.linear_projection = LinearNorm(
            hparams.decoder_rnn_dim + hparams.encoder_embedding_dim,
            hparams.n_mel_channels * hparams.n_frames_per_step)

#forword的時候:
cell_input = torch.cat((decoder_input, self.attention_context), -1)
        self.attention_hidden, self.attention_cell = self.attention_rnn(
            cell_input, (self.attention_hidden, self.attention_cell))
        self.attention_hidden = F.dropout(
            self.attention_hidden, self.p_attention_dropout, self.training)

        attention_weights_cat = torch.cat(
            (self.attention_weights.unsqueeze(1),
             self.attention_weights_cum.unsqueeze(1)), dim=1)
        self.attention_context, self.attention_weights = self.attention_layer(
            self.attention_hidden, self.memory, self.processed_memory,
            attention_weights_cat, self.mask)

        self.attention_weights_cum += self.attention_weights
        decoder_input = torch.cat(
            (self.attention_hidden, self.attention_context), -1)
        self.decoder_hidden, self.decoder_cell = self.decoder_rnn(
            decoder_input, (self.decoder_hidden, self.decoder_cell))
        self.decoder_hidden = F.dropout(
            self.decoder_hidden, self.p_decoder_dropout, self.training)

        decoder_hidden_attention_context = torch.cat(
            (self.decoder_hidden, self.attention_context), dim=1)
        decoder_output = self.linear_projection(
            decoder_hidden_attention_context)

        gate_prediction = self.gate_layer(decoder_hidden_attention_context)
        return decoder_output, gate_prediction, self.attention_weights

https://github.com/riverphoenix/tacotron2

很不清楚: 

# Step 1: Calculate the true inputs to the cell based on the
		# previous attention value.
		cell_inputs = self._cell_input_fn(inputs, state.attention)
		#cell_state = state.cell_state
		(cell_output, LSTM_output), next_cell_state, concat_output_LSTM =     
        self._cell(cell_inputs, state)
#省略很多, 最後直接返回:
if self._output_attention:
			return attention, next_state, LSTM_output, concat_output_LSTM
		else:
			return cell_output, next_state, LSTM_output, concat_output_LSTM


# 外部調用也很亂:
decoder_cell = TacotronDecoderWrapper(unidirectional_LSTM(training, layers=hp.dec_LSTM_layers, size=hp.dec_LSTM_size), training)

      attention_decoder = AttentionWrapper(
        decoder_cell,
        LocationBasedAttention(hp.attention_size, encoder_output),
        #BahdanauAttention(hp.attention_size, encoder_output),
        alignment_history=True,
        output_attention=False)

      decoder_state = attention_decoder.zero_state(batch_size=hp.batch_size, dtype=tf.float32)
      projection = tf.tile([[0.0]], [hp.batch_size, hp.n_mels])
      final_projection =tf.zeros([hp.batch_size, hp.T_y//hp.r, hp.n_mels], tf.float32)
      if hp.include_dones:
        LSTM_att =tf.zeros([hp.batch_size, hp.T_y//hp.r, hp.dec_LSTM_size*2], tf.float32)
      else:
        LSTM_att = 0
      step = 0

      def att_condition(step, projection, final_projection, decoder_state, mel_targets,LSTM_att):
        return step <  hp.T_y//hp.r

      def att_body(step, projection, final_projection, decoder_state, mel_targets,LSTM_att):
        if training:
          if step == 0:
            projection, decoder_state, _, LSTM_next = attention_decoder.call(tf.tile([[0.0]], [hp.batch_size, hp.n_mels]), decoder_state)
          else:
            projection, decoder_state, _, LSTM_next = attention_decoder.call(mel_targets[:, step-1, :], decoder_state)
        else:
          projection, decoder_state, _, LSTM_next = attention_decoder.call(projection, decoder_state)
        fprojection = tf.expand_dims(projection,axis=1)
        final_projection = tf.concat([final_projection,fprojection],axis=1)[:,1:,:]
        if hp.include_dones:
          fLSTM_next = tf.expand_dims(LSTM_next,axis=1)
          LSTM_att = tf.concat([LSTM_att,fLSTM_next],axis=1)[:,1:,:]
        return ((step+1), projection, final_projection, decoder_state, mel_targets,LSTM_att)
        
      res_loop = tf.while_loop(att_condition, att_body,
        loop_vars=[step, projection, final_projection, decoder_state, mel_targets,LSTM_att],
        parallel_iterations=hp.parallel_iterations, swap_memory=False)

      final_projection = res_loop[2]
      final_decoder_state = res_loop[3]
      concat_LSTM_att = res_loop[5]
      step = res_loop[0]

來得出結論.

代碼版本爲LDE_more_detail的, 按照想法改了一遍, 在1.7wsteps的時候合成不出來語音. 7w的時候可以.

並且製作了一個網頁.

 

3. 完全使用Tacotron-1的代碼, 來複現, 數據處理等配置完全一樣, 64dims的綁定可能直接擴大爲128.

使用這個版本: https://github.com/keithito/tacotron

和我看的tacotron2比較相似.

 

使用新的數據集(集合), 使得拓展單語單人爲單語多人, 復現論文

 

1. 列出來可用的數據集.

  • 標貝
  • LJSpeech1.1

 

每次實驗前, 做好實驗報告的框架, 特別是超參數的記錄, 代碼版本, 以及存在百度網盤啥的.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章