课程向:深度学习与人类语言处理 ——李宏毅,2020 (P24-1)

Text Style Transfer

李宏毅老师2020新课深度学习与人类语言处理课程主页:
http://speech.ee.ntu.edu.tw/~tlkagk/courses_DLHLP20.html
视频链接地址:
https://www.bilibili.com/video/BV1RE411g7rQ
图片均截自课程PPT、且已得到李宏毅老师的许可:)

考虑到部分英文术语的不易理解性,因此笔记尽可能在标题后加中文辅助理解,虽然这样看起来会乱一些但更好读者理解,以及文章内部较少使用英文术语或者即使用英文也会加中文注释,望见谅



前言

上篇中(P23)我们讲解了非自回归模型 的序列生成,将讲述有关问题、实现方法、和模型结构

而在本篇P24-1中,我们将进入 Text Style Transfer 文字风格转换,我们将类比语音、图像风格转换,进而实现文字风格转换,其实三者方法大同小异。以及在使用无监督学习方法做文字风格转换时会遇到的问题,解决方法等。

I Text Style Transfer

1.1 Image、Audio&Text Style Transfer 图像语音文字 风格转换

在这里插入图片描述
讲到风格转换,对于影像来说,影像的风格转换大家都很熟悉了,对于语音的风格转换就是这门课里讲过的Voice Conversion(P10P11)。

1.2 supervised 有监督方法

而本篇将讲解的是文字的风格转换,文字风格转换,顾名思义是改文字的风格,但其实这里的风格涵盖的范围很广,其应用是比我们能想象的还多。举例来说,可以由悲观的书写风格转为乐观的书写风格,或者八卦版的书写风格转为撒花版的书写风格等等,总之就是我们有两堆不同风格的文字,希望能够训练一个模型可以把这两种书写风格互相转换。

如果我们有成对的数据集,那对于这个问题我们只需要用一个seq2seq的模型把一种风格转为另一种风格的文字。但问题就是,在文字风格转换领域,通常我们是没有成对的训练资料的,比如将负面句子转为正面句子,我们根本不知道一个负面的句子究竟应该对应到哪一个正面的句子,所以我们很难用supervised learning有监督方法来训练这种seq2seq模型。

在这里插入图片描述

1.3 unsupervised 无监督方法

所以我们需要用unsupervised learning无监督方法来训练一个模型,从两种风格的文字里面但没有成对的训练资料里面去学习文字风格转换。但其实像这样的技术对于我们来说也并不陌生,因为影像风格转换或者是语音风格转换就是这么做的,之后你会发现我们用在文字风格转换的技术和用在语音、影像上的技术其实是大同小异的,你甚至可以在Voice Conversion(P10P11)中找到对应的技术。

举例来说,如上图,假设我们要训练一个消极风格转积极风格的文字转换,如Cycle GAN
  首先我们需要训练一个Discriminator 裁判,它在看过很多积极的句子后会知道积极的句子长什么样子,之后再输入给它判断这个句子是否是积极的句子。
  之后,希望我们的Generator 转换器能把消极的句子转成积极的句子,将转换后的句子交给Discriminator 裁判判断,希望它可以判断为积极的句子。
  最后,我们还需要一个Reconstructor 还原器,将转换出的积极句子再转为原始的消极的句子,其训练目标便是最小化两个消极句子的差异,这样可以确保文字的内容不会被模型丢掉,就比如模型的Generator 生成器可以全部生成同样的积极的句子,如“Good”来不管输入完美骗过Discriminator 裁判判断。

综上,这就是文字风格转换的Cycle GAN,这里的Cycle GAN和影像上、语音上所使用的没有什么太大的不同。但是如果我们直接把Cycle GAN应用到文字上,有一点是和语音不同的,仍然是值得拿来和大家分享的。
在这里插入图片描述

1.4 non-differentiable part 不可微分问题

一般而言,这种文字转文字的模型,我们首先都会考虑seq2seq模型。如上图,假设我们已经得到经过attention的Context vector 输入内容向量,上图左下的红框框,接下来的过程也是很常规的seq2seq生成的过程,将<BOS>和Context vector输入给RNN,会产生一个token distribution 词汇表中各个字或词的概率分布,取出其中最大的或者beam search的方法取,依次生成,这就是一个seq2seq的基本过程。在seq2seq模型生成"BAA"后,将这个输出丢到Discriminator 裁判中进行判断这个句子是否积极的。

如果是一般的GAN的话,我们接下来要做的就是调整Generator 生成器部分的参数,使得Discriminator 裁判 判断句子为积极的scalar分数变大。并且,我们会将Generator 生成器和 Discriminator 裁判 放在一起训练,用gradient descent 梯度下降的方法逐步调整参数到输入。

但今天在做文字的GAN的时候,我们是没有办法使用梯度下降的,因为在Generator 生成器和 Discriminator 裁判 之间有一个已经生成的Sample 样本序列,如上图的“BAA”,而像这样的样本是不能微分的
在这里插入图片描述
为解决上述问题,在文献上就有各式各样的方法试图解决这个问题,这其实是一个非常大的主题,这里提供给大家一些文献参考学习,本课中将这些解决方法大致分为三类,如上图。

II Solutions

2.1 Gumbel-softmax 使Sample可微分

在这里插入图片描述
Gumbel-softmax这个方法老师没有细讲,直接进入结论:主要的想法就是用了这个 reparameterization 的技巧,这个想法和 VAE 很像。用了这个技巧后,本来生成sample这样的文本序列,上述例子中的“BAA”,是不能微分的,可以变成是可微分的。

2.2 Continuous Input for Discriminator 给裁判连续值

在这里插入图片描述
第二招是给 给Discriminator 裁判连续值作为输入,这个想法是这样,既然sample 生成的文本序列,如“BAA”没办法微分,那我们何不避开sample。不要给Discriminator 裁判看这个sample的结果,直接给Discriminator 看概率分布,而且这个概率分布是连续值。这样在整个模型中就没有离散值了,就可以用backpropagation反向传播去更新Generator 生成器 和 Discriminator 裁判的参数了。

这是个很简单、直接的方法,那为什么大家还要研究那些复杂的方法呢?因为这个解法有个非常严重的问题。
在这里插入图片描述
Discriminator 裁判,看到的真实的积极的句子是向量表示的,可以是one-hot独热编码的。但是对Generator 生成器的输出是一连串的概率分布,如果把这个概率分布丢给裁判,这样的输入是与训练时不一样的。因此,对于 Discriminator 裁判来说,要分辨生成的和真实的积极句子太容易了,看是否是独热编码即可。这样 Discriminator 裁判 什么都没有学到。如果 Generator为了骗过Discriminator 裁判,最先考虑的也会是将生成的概率分布越接近独热编码越好。

WGAN弱化Discriminator 裁判的能力可以解决上述问题。

在此,你和我一定也会有这样的问题:那为什么要用独热编码表示句子呢?用一些语言模型BERT等做embedding表示不就好了么。
  对于真实的句子我们完全可以用embedding表示,对于生成的可以将概率分布换成embedding的加权和,这样就得到了两种类似的表示法,这样就可以混淆Discriminator 裁判判断生成和真实的区别,不能只看数据的格式,也会考虑语义有关的。其实用word embedding这招也可以,往往也会有不错的结果。

2.3 Reinforcement Learning 强化学习

在这里插入图片描述
最后一招是Reinforcement Learning 强化学习,强化学习的想法其实就是遵循一个秘诀:什么东西不能微分,就用强化学习 Policy Gradient 硬train一发。总而言之就是,

你看什么东西不能微分,就用强化学习解就结束了。

具体而言,将Generator 生成器 换成 强化学习里的 Agent,sample出来的文字序列变成这个Agent所采取的action行为,这里可以想为每个token就相当于游戏中的上下左右和开火的行为。Discriminator 裁判就是 Environment,就是Agent互动的环境,输出的分数就是Reward。此时,就可以用 Policy Gradient来训练Agent。

与GAN不同的是,在GAN中 Discriminator 裁判就是 Environment 是固定的,也就是说根据action计算出Reward是固定的。但现在的Discriminator 的参数也是会随着训练改变的,这样的Reward就是不断改变的,这样也就会导致强化学习的训练变得更加困难。所以,今天的强化学习方法表面上看上去好像可行,实际上做起来很困难。

所以,如果我们一定要使用强化学习的方法训练模型的话,我们是需要一些tips技巧的。

2.3.1 ScratchGAN 训练技巧

在这里插入图片描述
FED评价指标越小越好

有一个非常重要的技巧,叫做 ScratchGAN ,如果不使用这个技巧甚至根本训练不起来。baseline是有用这个技巧的,用大的batchsize是有效的,给Discriminator加regularization正则化有用,加预训练模型做embedding有用,用一些强化学习的技巧也有用。

接下来我们将详细讲解这个技巧的实现。
在这里插入图片描述
首先,我们要先考虑为什么我们的强化学习训练如此困难,尤其是把强化学习放在GAN的里面,因为在GAN的训练里,Discriminator 裁判要根据Generator生成器产生一段完整的文字以后,才会给这段完整的文字一个分数。

举例来说,Gnerator 生成器在产生一个很烂的句子“You is good”,丢给Discriminator会输出一个很低的分数。但对于生成器而言,它只知道它在产生整个句子以后才会得到一个很低的分数,而不知道究竟是在产生哪个词时分数变低。

此时,就需要我们刚刚提到的技巧了,ScratchGAN,也叫做Reward for Every Generation Step每一步都做奖励。顾名思义,Discriminator 裁判不仅要给整句的分数,还要在每一个子句给出分数。如上图,Discriminator 裁判要先衡量“You” 好不好,再衡量“You is”好不好,最终衡量“You is good”好不好。这样Gnerator 生成器就会知道在生成哪个词汇时分数变低了,就可以比较快的修正参数。

那该怎么实现让Discriminator 裁判给每一个子句一个分数呢?

2.3.2 Methods 生成子句分数方法

在这里插入图片描述
这边就不细讲,列明文献供大家学习。在文献上,大致有三种实现方法:

  1. Monte Carlo (MC) Search蒙特卡洛搜索法,和AlphaGo使用的方法很像,就比如生成第一个"You"后,接下来采样很多的句子接在”You“后面,将这些句子统统再丢给Discriminator 裁判进行一一衡量,输出分数,分数平均起来就是这个子句的分数。有效但运算量太大了。
  2. Discriminator For Partially Decoded Sequences :训练一个特别的Discriminator 裁判,它可以直接判断一个子句的分数。效果比较差。
  3. Step-wise evaluation :训练一个特殊的Discriminator 裁判,它看到一整个sequence序列时,一边读一边输出分数。往往可以达到蒙特卡洛搜索法一样好的效果。

2.3.3 Application 应用

在这里插入图片描述
文字风格转换可不仅仅是消极句转积极句,还可以做更广泛的转换。如
  放松转成烦躁风格
  男性转成女性风格,这里有趣的是,作者为了避免有性别歧视这样的问题,在论文中加入了非常非常长的注脚来进行声明。
  18-24岁转成65岁风格

2.4 CycleGAN -> StarGAN 两种风格->多种风格

在这里插入图片描述

对于两种风格的转换,CycleGAN可以很好的解决。但如果是多种风格的转换,此时我们就不能两两单独训练一个CycleGAN了。在语音转换篇(P10P11),我们也有讲过这个问题的,那时我们讲了一个模型StarGAN来解决语音领域的多风格转换。

同样,我们也有针对文本的StarGAN,如上图,Style Transformer就是文字版的StarGAN,方法是一样的。之后的作业会有更详细的说明。

2.5 Feature Disentangle 分离信息法

在这里插入图片描述
讲到这边,大家有没有想起在语音转换中其实有两种实现方法的,一种是CycleGAN,另一种就是Feature Disentangle 分离信息法,将输入的声音讯号通过两种不同Encoder编码,内容Encoder将只抽取语音中的内容讯息,语者Encoder将只抽取语音中语者的特征讯息,风格转换时只需替换语者讯息即可。

那对于文字而言,我们能不能也仿照上面,做两种Encoder,一个内容Encoder仅保留句子内容讯息,一个风格Encoder仅保留句子风格讯息,转换风格只需把风格讯息替换即可。训练的时候当作auto-encoder训练即可。

其实在文字风格转换里面,我们也是有机会训练得到一个一样的模型。

在这里插入图片描述
在文字风格转换中,有个蛮有趣的想法,把一个句子用一个向量来表示或者向量序列来表示有点困难。但我们能不能直接用文字当作Content内容使用,也就是说我们希望Encoder抽出来的结果不再是向量,而是一个句子,如上图上侧,在输入给Encoder “The food is delicious”后,Content Encoder就把除了风格的词都抽取出来,只留下“The food is”。再把这个有残缺的句子,加上style风格向量还原原来的句子。

又比如NAACL‘18的论文,上图左下角,给模型输入一个完整的句子,然后使模型删除所有的attribute markers有关的,即风格有关的词汇。再给模型输入目标的风格,进而恢复一个完整的句子。不过这篇文章用的是Rule-based 基于规则的方法,直接决定哪些词汇是与风格有关的。

而ACL’18的这篇论文,上图右下角,它可以做到端到端训练。它由两个module 模块:Neutralization Module 和 Emotionalization Module组成,第一个模块,可以让句子变中性的模块,决定了模型要删除哪些与风格有关的词汇,类似于一个Content Encoder,而删除哪个词汇的训练也是通过强化学习训练得到的,且在训练初加了一个分类器给模型一个比较好的初始化,加快训练速度。第二个模块,就相当于一个Decoder,通过选择不同的风格,如积极和消极输出不同的句子。


至此,上半篇的文本风格转换已结束。下半篇将讲述几种无监督的自然语言处理方法与模型。

猜你喜欢

转载自blog.csdn.net/qq_44574333/article/details/108415146
今日推荐