编辑推荐: |
本文简单回顾了传统统计机器翻译中的难题,过渡到利用GRU和LSTM来救场,最后介绍了一些较新的改进工作。希望对您的学习有所帮助。
本文来自于码农场,由火龙果软件Linda编辑、推荐。 |
|
机器翻译
对于情感分析这类还算简单的任务,你可以整理一个情感极性词典、编写一堆规则做出一个勉强能用的系统。但到了机器翻译这个高级应用,就无法完全依靠规则了。现代机器翻译手段都是基于统计的,在平行语料上学习语言知识。世界上第一个平行语料库是罗塞塔石碑:
传统机器翻译系统非常复杂,因为不同阶段用到了不同的机器学习方法。hankcs.com 2017-06-23
上午11.04.04.pnghankcs.com 2017-06-23 上午11.15.38.pnghankcs.com
2017-06-23 下午4.03.58.pngGRU.pngLSTM.pngLSTM3-chain.pnghankcs.com
2017-06-23 下午5.41.49.pnghankcs.com 2017-06-23 下午5.50.03.png
传统统计机器翻译系统
定义一些符号:
原文$f$
译文$e$
机器翻译定义为找到使如下条件概率最大的$e$:
$$\hat{e}=\text{argmax}_ep(e|f)=\text{argmax}_ep(f|e)p(e)$$
这里利用了贝叶斯公式。翻译模型$p(f|e)$在平行语料上训练得到,语言模型$p(e)$在未对齐的原文语料上训练(是非常廉价的)。
公式描述的翻译过程如下:
第一步:对齐
找到原文中的哪个句子或短语翻译到译文中的哪个句子或短语,这个第一步已经够难了。
对齐时,原文中可能有部分词语没有对应的译文:
也可能在译文中有部分词语没有对应的原文,根据模型不同,可能有一对多的对齐方式:
也可能有多对一的对齐方式:
还可能有多对多的对齐方式:
所有的对齐方式数量是组合数级的。
有时候还要通过句法分析,来进行不同颗粒度的对齐:
对齐之后
原文中每个单词都有多个备选单词,导致了许多短语的组合方式:
解码:在海量假设中搜索最佳选择
这是一个特别复杂的搜索问题,涉及到许多语言模型。
传统机器翻译
这还只是传统机器翻译系统的冰山一角,有许多细节没有涉及到,还需要大量的人肉特征工程,总之是非常复杂的系统。其中每个环节都是独立不同的机器学习问题。这些独立的模型各自为政,并不以一个统一的优化目标为最终目标。
而深度学习则提供了一个统一的模型,一个统一的最终目标函数。在优化目标函数的过程中,得到一个end
to end的完整的joint模型。传统机器翻译系统与深度学习是截然相反的,对齐模型、词序模型、语言模型……一堆独立的模型无法联合训练。
深度学习来救场
也许可以直接用RNN来接受原文,预测译文“下一个单词”:
红圈所示特征表示必须能捕捉整个原文短语的语义,但是RNN无法记住太久之前的事情,大概五六个单词就到极限了。所以这不是个实用的模型。
在这个最简单的模型中,
Encoder是:
$$\begin{equation} h_t = \phi (h_{t-1}, x_t) = f
(W^{(hh)} h_{t-1} + W^{(hx)} x_t) \end{equation}$$
Decoder是:
$$\begin{equation} h_t = \phi (h_{t-1}) = f (W^{(hh)}
h_{t-1}) \end{equation}$$
$$\begin{equation}y_t = softmax (W^{(S)}h_t)\end{equation}$$
最小化所有训练实例上的交叉熵误差:
$$\begin{equation}\max_{\theta} \dfrac {1}{N} \sum_{n=1}^{N}
\log p_{\theta} (y^{(n)}|x^{(n)})\end{equation}$$
记号 $\phi(v_1,v_2)$ 一般代表接受的两个向量的权值不同。
softmax分类器中必须有个代表句子终止的“单词”,不然模型会无休止地输出下去。
但神经网络机器翻译模型没有这么简单,必须加一些拓展。
1、编码器和解码器训练不同的权值矩阵
红蓝代表不同的权值。
2、decoder中的隐藏层的输入来自3个方面:
前一个时刻的隐藏层
encoder的最后一个隐藏层($c = h_T$)
前一个预测结果 $\hat{y}_{t-1}$
这样导致decoder函数变为:
$$\begin{equation} h_{t} = \phi (h_{t-1}, c, y_{t-1})
\end{equation}$$
这可以辅助训练softmax的权值矩阵,防止模型重复生成同一个单词。
上图还有一个复杂版本,表达的是同一个意思:
其中,带黑点的表示离散的向量表示,否则表示连续的向量空间。
3、使用深度RNN
4、使用 bi-directional encoder
5、不再用$\textit{A B C} \to \textit{X Y}$作为训练实例,而是逆转原文词序:$\textit{C
B A} \to \textit{X Y}$。因为A更可能翻译为X,而梯度消失导致A无法影响输出,倒过来A离输出近一些。逆转词序不会带来“语法语义上的改变”,因为模型学习的就是如何从逆序的原文翻译顺序的译文。但相应的,C就离Y更远了
主要改进:更好的单元
引入Gated Recurrent Units (GRU),这种单元可以让模型学习何时遗忘从而将记忆保持很久、允许误差根据输入的不同而不同。
标准的RNN直接计算隐藏层:
$$h_t = \sigma(W^{(hh)} h_{t-1} + W^{(hx)} x_{t})$$
GRU先根据当前输入的词向量和隐藏层计算一个update gate(另一个层):
$$z_t=\sigma\left(W^{(z)}x_t+U^{(z)}h_{t-1}\right)$$
利用相同的方法不同的权值计算reset gate
$$r_t=\sigma\left(W^{(r)}x_t+U^{(r)}h_{t-1}\right)$$
然后利用reset gate计算新的记忆
$$\tilde{h}_{t} = \operatorname{tanh}(r_{t}\circ
Uh_{t-1} + Wx_{t} )$$
这里的意思是,之前的记忆由reset gate控制,如果reset gate元素都是0,则遗忘之前的事情。比如电影评论的情感分析,“有个文艺的少男爱死了一个平凡的少女,这个平凡的少女也爱死了那个文艺的少男,可两个人就是无法相会巴拉巴拉,真是个无聊的电影”。无论前面说了多少话,起决定性作用的可能就是“无聊”这个词。那么一些GRU可能会说,我遇到了一个情感强烈的词语,我不想让它被之前的记忆冲淡(求和),所以我把reset
gate设为0,之前的记忆不起作用,把这个情感词汇写成新的记忆。
而update gate的作用是调节最后的更新,到底时刻$t$的记忆多少来自之前,多少来自当前:
$$h_{t} = (1 - z_{t}) \circ \tilde{h}_{t} + z_{t}
\circ h_{t-1}$$
如果$z_t$是单位向量的话,则隐藏层只是复制前一个时刻的隐藏层,梯度不发生变化(衰减)。
这些公式写在一起已经非常直观了:
$$\begin{align*}
z_{t} &= \sigma(W^{(z)}x_{t} + U^{(z)}h_{t-1})&~\text{(Update
gate)}\\
r_{t} &= \sigma(W^{(r)}x_{t} + U^{(r)}h_{t-1})&~\text{(Reset
gate)}\\
\tilde{h}_{t} &= \operatorname{tanh}(r_{t}\circ
Uh_{t-1} + Wx_{t} )&~\text{(New memory)}\\
h_{t} &= (1 - z_{t}) \circ \tilde{h}_{t} + z_{t}
\circ h_{t-1}&~\text{(Hidden state)}
\end{align*}$$
有些人觉得示意图更直观:
上图中,虚线代表某个gate的调节作用。隐藏层取决于上一个时刻的隐藏层和新的记忆,而update
gate负责调节它们的比例,reset gate和输入共同决定新的记忆……
有人问这个reset gate是不是多余的,是不是可以直接让$h_{t} = z_{t} \circ
h_{t-1}$。做是的确可以这么做,但$x_t$永远无法把之前的记忆$h_{t-1}$“挤出去”,因为$z_t$是个求和的形式。
下面又是一张故弄玄虚的图:
由于gate的调控作用是连续的而不是0或1,所以上图中的开关并不合理。
对于短距离的依存来讲,reset gate经常是激活的。
LSTM(Long-Short-Term-Memories)
LSTM与GRU动机相似,只不过单元结构有点不同。GRU的单元结构如下:
LSTM单元结构如下:
上图用公式描述如下:
$$\begin{align*}
i_{t} &= \sigma(W^{(i)}x_{t} + U^{(i)}h_{t-1})&~\text{(Input
gate)}\\
f_{t} &= \sigma(W^{(f)}x_{t} + U^{(f)}h_{t-1})&~\text{(Forget
gate)}\\
o_{t} &= \sigma(W^{(o)}x_{t} + U^{(o)}h_{t-1})&~\text{(Output/Exposure
gate)}\\
\tilde{c}_{t} &= \operatorname{tanh}(W^{(c)}x_{t}
+ U^{(c)}h_{t-1})&~\text{(New memory cell)}\\
c_{t} &= f_{t} \circ c_{t-1} + i_{t} \circ \tilde{c}_{t}&~\text{(Final
memory cell)}\\
h_{t} &= o_{t} \circ \operatorname{tanh}(c_{t})
\end{align*}$$
LSTM的计算可以分为如下步骤
New memory generation 与GRU的New memory generation类似。使用当前词语$x_t$
和之前的隐状态$h_{t_1}$来生成新的记忆$\tilde{c}_{t}$。于是新记忆里面就包含了当前词语$x^{(t)}$的属性。
Input Gate 使用当前词语和之前的隐状态决定当前词语是否值得保留来gate新记忆,这个“是否”是通过$i_{t}$来体现的
Forget Gate 与input gate类似,只不过它不是用来衡量输入单词的有用与否,而是衡量过去的记忆对计算当前记忆有用与否。它接受输入单词和上一刻的隐状态产生输出
$f_{t}$。
Final memory generation 根据forget gate的建议$f_{t}$来遗忘过去的记忆$c_{t-1}$。类似地,根据input
gate的建议$i_{t}$来gate信的记忆 $\tilde{c}_{t}$,然后把两者加起来得到最终记忆
$c_{t}$。
Output/Exposure Gate 这是GRU中不显式存在的门,用处是将最终记忆与隐状态分离开来。记忆
$c_{t}$ 中的信息不是全部都需要存放到隐状态中,隐状态是个很重要的使用很频繁的东西,LSTM中每个gate都需要隐状态的参与。Output
Gate产生 $o_{t}$,用来gate记忆的tanh激活值。
一些可视化
一张最清晰的图示:
一些把简单问题复杂化的图示:
都没有公式一目了然
LSTM很潮
是序列标注、seq2seq任务的首选模型,可以层叠起来形成更深的模型。在数据量特别大的时候特别有用。
比如与传统MT模型的比较:
那时候的NN模型还是仅限于重新排序传统MT模型产生的结果,而最新的研究就是完全甩开了MT模型:
前三用的都是NN。
深度LSTM用于机器翻译
输入原文序列,将最后一个时刻的隐藏层向量PCA降维后可视化:
发现无论词序如何,意义相同的句子在向量空间中更接近。
进一步改进:更多门!
我感觉跟小孩玩乐高似的,拿着现有的单元拼拼凑凑成一个系统,跑出更高的分数就发paper了。至于为什么要这么拼这么改,不像理论完备的概率图模型,很少有人说得清楚吧。
RNN的最新改进
softmax的问题:无法出新词
对分类问题来讲,你无法指望分类模型给你分出一个训练集中不存在的类。即便是训练集中存在的类,如果样本数很少,模型也很难预测出该类。
对于预测下一个单词的语言模型来讲,也是如此。比如某某女士巴拉巴拉,然后自我介绍说我叫某某。如果某某不存在于训练集中,则模型无法预测出某某。
虽然可以用字符级的模型,但代价实在太大。
用指针来解决问题
如果把某某替换为“向前数第10个单词”这样的指针,问题就迎刃而解了。
具体做法是,以前100个时刻的隐藏层作为输入,用一个softmax去计算前100个单词是pointer的概率,与原来的词表上的分布混合。
使用了pointer之后,困惑度下降了零点几个百分点:
总结
RNN很强大
有很多进行中的工作
GRU更强大
LSTM又更强大 |