Where GAN/RL meets NMT

Where GAN/RL meets NMT

从 ICLR'15 上的 [1409.0473] Neural Machine Translation by Jointly Learning to Align and Translate 引入 attention mechanism 起,端对端的机器翻译模型开始超越模型、成为主流。

不过这些方法大多都是基于 MLE (最大似然)的。而 MLE 仅仅是一种词级别的训练目标,两个句子即使只有一词之差,意思可能也千差万别,所以这可能不是一个足够好的训练目标。于是,有人引入 MRT (Minimum Risk Training) [1512.02433] Minimum Risk Training for Neural Machine Translation ,引入了句子级别训练目标 (sentence-level BLEU),希望借此提升模型效果。

但是即便是句子级别的训练目标(例如 sentence-level BLEU),仍然有一个问题:就是这些指标多是基于 n-gram 匹配的,但是 n-gram 匹配得好并不代表句子翻译得好(虽然正相关性很强)。比如说翻译结果漏了一个介词短语(漏翻),这时 n-gram precision 也很高,但是其实没翻译好;再比如模型翻译的结果和参考答案之间差了一个同义词替换,会导致这个词附近的 n-gram 都匹配失败,但是其实翻译质量是很高的。

于是,一个很自然的想法就是说,把 NMT 和 GAN 结合起来。生成器 G 用一个 NMT 模型生成候选翻译,判别器 D 用来给翻译结果打分。然后在训练的过程中,G 不断提高翻译质量,使得 D 难以区分翻译结果到底是 G 自己生成的还是人工翻译的;而 D 不断加强鉴别能力,尽可能地区分出喂给它的 (x, y) 到底是不是人工翻译的。在理想情况下,G 最终将学到完美的翻译,而 D 无法再区分出翻译结果到底来自哪里,或者说给一个 (x, y) pair,D 会觉得这个句对来自人工翻译的概率为 50%。

这个方法的好处在于,假如 D 训练得足够好,它给出的打分就会比字面上的 n-gram 匹配更好,因为它不是比较字符串级别的相似,而是能够提取语义信息判断句子是否相似。这是一个更好的翻译质量评价指标。


今天要介绍的就是两个这样的工作,分别是:

[1] [1704.06933] Adversarial Neural Machine Translation

[2] [1703.04887] Improving Neural Machine Translation with Conditional Sequence Generative Adversarial Nets

(第二篇文章时间稍早于第一篇,不过第二篇介绍起来更麻烦一些,因此放在后面)


虽说是 GAN 和 NMT 的结合,可是实际上说是 RL 和 NMT 的结合也没啥问题,因为他们用的都是 gradient policy method,把给定句子 x (或者再加上部分翻译结果 y_{1:t})视为 agent 的状态,把下一个词(或者是一整句话)的预测结果作为 action,然后通过优化预测单词的方式(随机策略)来最大化期望的收益(在各种策略下 D 对 G 的平均打分)。

两篇文章里,G 都是 RNNSearch(本文开头提的那篇论文) ,D 都是接受一个 (x, y) pair 然后判断这个 pair 是人工翻译还是生成器 G 翻译的。训练流程都是用 MLE 预训练好生成器 G,然后用 G 生成的假句对 + 语料里真句对预训练判别器 D,最后交替训练 G 和 D(G 用 policy gradient 训练)直至收敛。主要的区别在于 reward 的设计和一些实验得到的 insight 上。


【第一篇】

这篇还额外提到了用 D 做打分的一个好处:打分是随着 G 一起进化的,而非 BLEU 或者什么指标是一成不变的。不过这个到底算不算好处我觉得还不太好说,只能说在 GAN 这个框架下是有好处的,可以平衡 G 和 D 的学习进度。

有一篇文章(《Adversarial Neural Machine Translation》阅读笔记)已经介绍得比较详细了,我在这里只总结一下最关键的部分:

1、感觉 CNN 也没怎么设计,反正就是 3*3 卷积 + 2*2 池化这样重复两遍,然后接一个 MLP 和 sigmoid。文章有一点似乎没说清楚,就是它是怎么处理变长序列问题的?后面有一个 Global Average Pooling 吗?还是所有输入都 padding 到同一维度?(补:经过和作者邮件沟通,文中的做法是把所有句子 padding 到同一长度)

2、G 的优化目标和更新方式如下:


可以看到它是基于最基本的 GAN 的(和 GAN 的目标函数都长得一样)。最终推导出的更新公式和 MLE 几乎一样,只有两点区别:一是有一个动态的步长 -log(1-D(x, y')),二是在采样出的样本 (x, y') 而非真实样本上面训练。

如果把 -log(1-D(x, y')) 定义成 reward,公式 (7) 里的 log(1-D(x, y')) 就是一个负的 reward;公式 (7) 要求最小化 log(1-D(x, y')) 的期望,也就相当于最大化 reward 的期望。在公式 (9) 里,相当于用 log(1-D(x,y')) 对生成器的似然比进行加权。从直觉上讲,如果模型对句子 x 翻译结果已经很准了,D(x, y') 就接近 1,log(1-D(x, y')) 的绝对值就比较大,模型鼓励这样的行为,让 G 的参数多更新一点。(以上是论文里对公式 (9) 的解释,但是我觉得这个公式有点反直觉……应该是困难样本多更新一点才对啊,类似于 online hand example mining 或者是 focal loss 那样。补:作者在评论区指出,因为模型不是在真实样本上训练,而是在自己采出来的样本上训练的,所以应该以假乱真的样本权重更大,这样一旦模型试出来一个比较好的翻译就能尽快把它记住,毕竟模型在胡乱瞎试的过程中试到一个好翻译不容易)


3、G 对学习率的变化比较敏感,而 D 则比较 robust(就是本文的题图,不过没啥好看的 XD)。D 的学习率在很大一个范围内波动都影响不大(CNN 加了 BN 效果拔群)。这个结论其实比较好理解,毕竟生成模型难训,判别模型好训;RNN 难训,CNN 好训。另外 D 的 embedding 在预训练之后就固定不变。

4、文章还说了直接 GAN 容易崩,因此建议一半的 batch 用普通的 MLE 训,另一半用 GAN 训。(估计作者训模型的时候调参很辛苦吧……)

5、训好后几个案例分析如下:

D(x, y') 是判别器给 G 的翻译结果 y' 的打分,[0, 1] 之间,越接近 1 说明判别器越觉得这个结果像人工翻译的;BLEU 是根据模型翻译结果 y' 和人工翻译结果 y 计算的

虽然我承认翻译质量变好了,不过这个 D 的打分好像不那么 make sense……按照 Nash Equilibrium 的故事来讲,D 给 (x, y') 的打分应该是 0.5 附近才对,下面那个打分都 0.93 了,不像是纳什均衡啊!

提到 GAN 的时候很多人都说什么博弈论啊、纳什均衡啊,但是我感觉这是一个被讲烂的故事……纳什均衡固然理想,但实际达不到这种状态吧,往往是 D 更强 G 更弱。


【第二篇】

这篇文章 GAN 的味道轻一些,RL 的味道更浓。从技术手段上来讲,跟 seqGAN(SeqGAN: Sequence Generative Adversarial Nets with Policy Gradient) 一脉相承,如下设计 reward:

对于 X 生成的 Y 的最后一个词,用 D 的打分减去 bias(固定为 0.5,这样 reward 就有正有负)作为 reward;对于 Y 句子中间的词,做 20 次蒙特卡洛采样,计算 D - bias 的平均值作为 action-value function。

(注意在 RL 中,action-value function 一般用字母 Q 表示(seqGAN 中也用的 Q)。这篇文章是个奇葩,用 R 表示,不要弄混。这个 MDP 的设计是这样的:中间每一步没有 reward,最后一步给一个 reward = D - bias;折扣因子 gamma = 1,也即不折扣,因为中间步骤没有 reward,要最大化远期利益、不能短视;action-value 是未来所有 reward 加起来,所以也就是最终状态的 reward;state-transition 概率为 1,选了哪个词就生成哪个词,环境不会带来额外的随机因素)

然后 G 要优化的函数是初始状态的 action-value function,经过一番推导(详见 seqGAN 的补充材料),最后得到策略梯度如下:

至于 D 的部分,文章考虑了 CNN 和 RNN 两种判别器。这两种判别器的用法都是:先用特征提取器把输入句子 x 和 y‘ 分别变成固定维度的特征向量,然后两个特征向量拼到一起过一层 MLP 和 sigmoid 来得到它们属于人工翻译的概率。

其中 CNN 特征提取器的设计参考 Yoon Kim 的 [1408.5882] Convolutional Neural Networks for Sentence Classification,就是几个不同宽度的卷积核提不同尺度的卷积核再加 max-pooling-over-time 来解决变长问题,对一个句子得到固定维度的特征向量;而 RNN 的设计就是 LSTM 过一遍序列,然后把隐层状态求平均得到输入句子的特征向量。示意图分别如下:


最后实验发现判别器用 CNN 比 RNN 要好。文中给出的一个解释和实验证据是,RNN 判别器很容易学得太强,能够以很高的概率判断出 G 生成的句子是假的,导致 G 就弃疗不学了……


具体实验上也有一些技巧,比如说预训练 D 的时候不要把 D 训得太准,也不能训得太烂(训得太烂起不到指导作用,训得太准会导致 G 学不动弃疗),预训练到 0.82 的准确率就好了

D 预训练到的准确率和之后 G 性能的关系

再下来还用了 teacher forcing(参考文章 [1701.06547] Adversarial Learning for Neural Dialogue Generation),就是在不断从自身策略里采样计算 reward 的同时,每过一段时间强行把真正的输入暴露给模型,让它在真实句对 (x, y) 上也更新一次并把所有 reward 设成 1,好让生成器知道好的翻译是什么样的,别光自己瞎琢磨。这个作用和另一篇所说的 50% 比例用 MLE 训练是类似的:如果只用 D 提供 reward 不用真实语料训练的话,G 如果一不小心走偏了,之后就很难再回到正轨、猜出好的翻译是啥了(采样出好的翻译并更新参数)。

最后的效果大约就是比 baseline RNNSearch 好了 2 个点的 BLEU 吧。


比较有趣的是,文章还做了一些用判别器 D 清洗数据的尝试:首先把 D 的精度训得很高,然后,用 D 筛一遍语料,选取判别器打分高的句对用来做训练(判别器认为这些句对质量更好)。在同样语料规模的条件下,按这种方法筛出来的语料 比 随机抽取相同数量的语料训出来的模型好半个到一个点:

第一列是语料规模(句对数量);s1 和 s2 分别是判别器 D 挑出的优质语料和随机抽取的语料

【后记】

其实还有一些脱离了 GAN 的更纯粹的基于 RL 做机器翻译的论文,例如 Dzmitry Bahdanau 搞的 AN ACTOR-CRITIC ALGORITHM FOR SEQUENCE PREDICTION 。这些等我有时间读了再写吧……

编辑于 2017-11-23

文章被以下专栏收录