【Conditional Variational Autoencoder with Adversarial Learning for End-to-End Text-to-Speech 论文阅读】

《Conditional Variational Autoencoder with Adversarial Learning for End-to-End Text-to-Speech》

ICML 2021 Jaehyeon Kim, Jungil Kong, Juhee Son

  1. 摘要
    一些基于单阶段训练和并行解码的端到端语音合成模型取得了不错的效果,但是它们的语音质量与两阶段训练的语音合成模型相比还有一定差距。本文提出了一个完全并行化的语音合成模型,与两阶段模型相比可以生成更加自然的合成语音。模型采用基于标准化流模型 (normalizing flows) 的变分推理 (variational inference) 策略和对抗学习策略来提升生成模型的表现力。我们还提出随机时长预测模块来提升合成语音的韵律多样性。凭借变分推理隐变量和随机时长预测模块的不确定性建模,我们的模型可以很好的处理语音合成中的一对多问题,从而可以为给定文本生成具有多种多样基频和韵律表现的合成语音。在LJSpeech数据上的主观MOS实验结果表明,我们的模型优于目前所有的公开TTS模型,并且MOS分数与Ground Truth相当。

  2. 引言
    不考虑前端文本处理的情况下,语音合成 (text-to-Speech, TTS) 的主要建模过程被简化为两个主要阶段。第一阶段:将前端文本处理得到的规范文本序列转换为中间特征表示,如mel-spectrograms声学特征或语言学特征表示。第二阶段:将中间特征表示重构为语音波形。

    自回归语音合成模型可以合成高质量的语音,但是自回归的序列生成方式限制了模型的并行处理能力。因此,非自回归模型应运而生。

    针对第一阶段,非自回归语音合成模型需要先使用预训练的自回归 (教师) 语音合成模型提出“文本-声学参数”的注意力对齐关系,来指导非自回归模型训练时的时长对齐学习。最近,一些基于似然 (likelihood) 的方法通过最大化目标声学参数的似然概率来学习时长对齐,从而消除了对之前预训练自回归模型的依赖。

    针对第二阶段,一些方法采用基于多判别器的生成对抗网络进行语音波形的重建。其中,不同的判别器用来对不同尺度 (scale) 或不同周期 (period)的声学参数进行建模。

    尽管并行化的TTS系统蓬勃发展,但两阶段模型仍然存在一些问题1.由于第二阶段需要依赖于第一阶段的输出进行训练,因此序列化或微调的训练方式仍然必不可少;2. 可学习的特征表示有助于提升TTS的表现,但是两阶段模型中第一阶段和第二阶段的衔接依赖于预先定义好的中间特征表示,模型表现仍然有进一步提升的空间。

    一些工作对基于可学习特征表示的TTS方法进行了研究,例如:FastSpeech2、EATS等模型中:使用音频片段取代之前的完整语音波形作为学习波形重建的学习目标、提出mel-spectrogram decoder来辅助文本特征表示的学习、设计新的spectrogram loss来解决生成语音和原始语音的长度不匹配问题。但是它们的语音合成整体质量与两阶段模型相比仍有一些差距

    本文提出了一个合成质量优于两阶段模型的完全并行化TTS方法。1. 为了实现直接有效的端到端训练,我们基于变分自编码器,使用隐变量作为中间特征表示将两阶段模型融合为单阶段模型;2.为了提升合成语音波形的表现力,提出基于标准化流模型的条件先验分布和对抗学习策略进行语音波形的重建;3. 为了更好的解决语音合成中的一对多问题 (即:TTS模型可以为给定文本合成具有多种多样基频和时长信息的合成语音) ,提出随机时长预测器为给定文本预测多样化的韵律信息。凭借隐变量和随机时长预测的不确定性优势,我们的模型可以更好的学习到文本表示体现不出来的语音韵律变化。

  3. 方法
    提出的方法:1.条件VAE,2.基于条件推理的对齐估计,3.对抗训练。
    图1a 和图1b分别展示了VITS的训练和推理过程。
    在这里插入图片描述
    模型整体结构包括:1.后验编码器(posterior encoder), 2.先验编码器(prior encoder),3.解码器,4.解码器,5.随机时长预测器。其中后验编码器和判别器仅用于模型训练阶段,模型推理阶段不使用。

    Posterior encoder: 在训练时后验编码器以线性谱为输入,输出隐变量z。推理阶段隐变量z则由流模型产生。VITS的后验编码器采用WaveGlow和Glow-TTS中的非因果WaveNet残差模块。应用于多人模型时,可以将说话人向量添加到残差模块。

    Prior encoder: 先验编码器包括文本编码器和提升先验分布多样性的标准化流。文本编码器为基于相对位置编码的transformer编码器。将线性层添加到文本编码器的最后一层用来生成构建先验分布的均值和方差。标准化流模块包含若干WaveNet的残差块。应用于多人模型时,可以向标准化流的残差模块添加说话人向量。

    Decoder: 解码器的结构与HiFi-GAN V1的生成器结构相同,应用于多人模型时,将说话人向量线性变换后与隐变量z拼接在一起。

    Discriminator: 判别器的结构与HiFI-GAN中的多周期判别器结构相同。

    Stochastic duration predictor: 随机时长预测器以文本音素表示的隐状态htext为条件输入,估计音素的时长分布。应用于多人模型时,将说话人向量线性变换后与隐状态htext拼接在一起。

  4. 实验
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    5.总结:
    本文提出全新的并行化端到端TTS模型,VITTS。提出了随机时长预测模块来生成具有多样性韵律变化的语音。VITS不需要中间声学特征表示便可直接为文本生成高自然度的合成语音。实验结果表明我们的模型优于两阶段TTS建模方法,并且与真人发音效果相当。我们期望本文的方案可以服务于其他两阶段的语音生成任务,在简化模型训练流程的同时提升语音生成的表现。虽然我们的方法将两阶段TTS模型融合为单阶段,但是在文本处理方面仍然存在问题。研究基于自监督的文本表示方法对于简化文本处理环节仍有待探索。

参考:
原文更详细
原文链接

image-to-Image Translation with Conditional Adversarial Networks(条件对抗网络的图像到图像转换)是一种用于图像转换的深度学习方法。它通过训练一个生成器网络和一个判别器网络来实现图像的转换。生成器网络将输入图像转换为目标图像,而判别器网络则试图区分生成的图像和真实的目标图像。 这种方法的关键是使用对抗性训练。生成器网络和判别器网络相互竞争,以提高生成器网络生成逼真图像的能力。生成器网络通过最小化判别器网络对生成的图像的判别误差来学习生成逼真的图像。判别器网络则通过最大化对生成的图像和真实图像的判别能力来学习区分真实图像和生成图像。 在条件对抗网络中,生成器网络和判别器网络都接收额外的条件输入,以指导图像转换的过程。这个条件输入可以是任何与图像转换任务相关的信息,例如标签、语义分割图或其他图像。 通过训练生成器网络和判别器网络,条件对抗网络可以实现各种图像转换任务,例如将黑白图像转换为彩色图像、将马的图像转换为斑马的图像等。 这是一个使用条件对抗网络进行图像到图像转换的示例代码: ```python import tensorflow as tf from tensorflow.keras import layers # 定义生成器网络 def build_generator(): # 定义生成器网络结构 generator = tf.keras.Sequential() generator.add(layers.Conv2DTranspose(64, (4, 4), strides=(2, 2), padding='same', input_shape=(256, 256, 3))) generator.add(layers.BatchNormalization()) generator.add(layers.ReLU()) generator.add(layers.Conv2DTranspose(32, (4, 4), strides=(2, 2), padding='same')) generator.add(layers.BatchNormalization()) generator.add(layers.ReLU()) generator.add(layers.Conv2DTranspose(3, (4, 4), strides=(2, 2), padding='same', activation='tanh')) return generator # 定义判别器网络 def build_discriminator(): # 定义判别器网络结构 discriminator = tf.keras.Sequential() discriminator.add(layers.Conv2D(64, (4, 4), strides=(2, 2), padding='same', input_shape=(256, 256, 3))) discriminator.add(layers.LeakyReLU()) discriminator.add(layers.Conv2D(128, (4, 4), strides=(2, 2), padding='same')) discriminator.add(layers.BatchNormalization()) discriminator.add(layers.LeakyReLU()) discriminator.add(layers.Conv2D(256, (4, 4), strides=(2, 2), padding='same')) discriminator.add(layers.BatchNormalization()) discriminator.add(layers.LeakyReLU()) discriminator.add(layers.Conv2D(1, (4, 4), strides=(1, 1), padding='same')) return discriminator # 定义条件对抗网络 class cGAN(tf.keras.Model): def __init__(self, generator, discriminator): super(cGAN, self).__init__() self.generator = generator self.discriminator = discriminator def compile(self, g_optimizer, d_optimizer, loss_fn): super(cGAN, self).compile() self.g_optimizer = g_optimizer self.d_optimizer = d_optimizer self.loss_fn = loss_fn def train_step(self, real_images, labels): # 生成器网络生成假图像 with tf.GradientTape() as tape: fake_images = self.generator([real_images, labels], training=True) # 判别器网络判别真实图像和假图像 real_output = self.discriminator([real_images, labels], training=True) fake_output = self.discriminator([fake_images, labels], training=True) # 计算生成器和判别器的损失 g_loss = self.loss_fn(fake_output, tf.ones_like(fake_output)) d_loss_real = self.loss_fn(real_output, tf.ones_like(real_output)) d_loss_fake = self.loss_fn(fake_output, tf.zeros_like(fake_output)) d_loss = d_loss_real + d_loss_fake # 更新生成器和判别器的参数 g_gradients = tape.gradient(g_loss, self.generator.trainable_variables) d_gradients = tape.gradient(d_loss, self.discriminator.trainable_variables) self.g_optimizer.apply_gradients(zip(g_gradients, self.generator.trainable_variables)) self.d_optimizer.apply_gradients(zip(d_gradients, self.discriminator.trainable_variables)) return {"g_loss": g_loss, "d_loss": d_loss} # 创建生成器和判别器 generator = build_generator() discriminator = build_discriminator() # 创建条件对抗网络 cgan = cGAN(generator, discriminator) # 编译条件对抗网络 cgan.compile( g_optimizer=tf.keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5), d_optimizer=tf.keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5), loss_fn=tf.keras.losses.BinaryCrossentropy(from_logits=True) ) # 训练条件对抗网络 cgan.fit(dataset, epochs=100) # 使用生成器网络进行图像转换 input_image = ... label = ... output_image = generator([input_image, label]) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值