本学习报告是作为2018年春季学期《机器翻译》课程的部分笔记和实验报告。参考书为 Philipp Koehn 的 Statistical Machine Translation1。完整代码见于我的GitHub Repo。
说明
其中实验所使用的运行环境如下:
- 操作系统:Linux
- Python版本:3.6
- 可选:
csvkit
(pip3 install csvkit
)
基于词的翻译模型
简介
基于词的翻译模型起源于上世纪IBM关于统计机器翻译的原创性工作,教材主要介绍的是IBM Model 1模型。该模型能够从大量句对齐的语料中自动实现词对齐。
显然这个任务中,我们即不知道英文词和外文词的对齐方式,也不知道他们两两之间的对齐概率。虽然对齐方式和对齐概率我们都不知道,但是如果我知道其中一个,问题就解决了:知道对齐方式,直接得到答案;知道对齐概率,则通过统计可以得到不同对齐方式的概率,取最大概率的对齐方式即可(极大似然估计)。
我们称“对齐”在这个任务中是隐变量,而解决包含隐变量的训练算法是期望最大算法(EM算法)。EM算法的工作流程如下:
- 初始化模型,通常从均匀分布开始。
- 将模型应用于数据(求期望步骤)。
- 从数据中学习模型(最大化步骤)。
- 重复迭代步骤2和3直至收敛。
详细的推导详见教材第4章。
词对齐(IBM Model 1)实验
代码解释
本小节我们基于Python使用EM算法实现一个IBM Model 1模型,算法的伪代码位于教材图4.3。
由于使用EM算法,实验需要迭代多轮,直至轮数达到预设值或者误差小于设定阈值。每一轮的训练函数如下所示:
|
|
代码中比较重要的地方标注了教材对应的公式,方便对照查阅。
总训练函数train
在每一轮训练中调用以上train_iter
函数,代码如下(结果输出部分省略):
|
|
程序使用argparse
来输入参数,需要输入的参数有:
--f-corpus
:外语语料路径,每行一句(中文语料需分好词)。--e-corpus
:英语语料路径,每行一句,须与外语语料句对齐。--save-dir
:结果保存路径。--epsilon
:设定误差阈值。(默认值=1e3)--iter-num
:设定训练轮数。(默认值=10)--save-iteration
/--no-save-iteration
:是否保存每一轮迭代后的词翻译概率(语料较大勿用,内存容易溢出,仅作为演示用)--save-alignment
/--no-save-alignment
:是否保存词对齐的结果。
小语料运行演示
我们可以先使用教材上的例句来进行实验,这时输入语料为:
|
|
在终端按如下参数输入命令即可开始训练,输出的日志会记载每一轮的时间和误差:
|
|
输出的结果中的iterations.csv
文件记录每一个词对齐的翻译概率,可以看到和教材图4.4一致:
|
|
输出结果中的alignment.txt
文件记录了每一个英文词对应概率最大的外文词:
|
|
以上试运行表明程序设计正确,接下来我们将程序运行于较大的语料上。
大语料运行演示
我们使用的FBIS语料为中英对齐语料,数量为10k,内容如下:
|
|
在终端使用如下参数训练:
|
|
查看输出的alignment.txt
可见:
|
|
当然为了下一章的短语抽取实验,我们还需要记录每个英文词所有的对齐候选词以及翻译概率,这个文件以json格式输出存储,内容较杂乱,这里不再展示。
基于短语的翻译模型
简介
基于词的翻译模型并不符合语言学,可以使用短语来作为基本的翻译单元。显然,基于短语的翻译系统性能取决于从基于词的翻译模型中得到的短语翻译表。得到词对齐后,每输入一个句对,可以将其表示为教材图5.3所示矩阵,使用黑色方块表示词的对齐。我们的任务是从这个含有黑色方块的矩阵中,用灰色矩形框出满足一致性(“一致性”从视觉上很容易理解,详见图5.4;其形式化定义见公式(5.3))的一个或者多个黑色方块。
算法思想比较简单,即使用两层for循环遍历矩阵,遇到符合的区域就提取其中的短语。但是需要处理一些边角情形,如对空的情况等。
短语抽取实验
代码解释
本小节我们使用Python实现一个短语抽取的模型,该模型能根据之前实验得到的词对齐,从大量句对齐的语料中通过实现短语自动抽取(抽取的短语不一定具有语言学意义)。算法的伪代码位于教材图5.5。
|
|
该函数内双重for循环不断调整着预计抽取短语对的开始、结束下标。每找到一组可行的下标(e_start
,e_end
,f_start
, f_end
),就进入第11行使用extract
函数进行抽取。例如输入的对齐A=[(1,1), (2,2)]
(即教材上的黑格子坐标),则可以进行三次抽取,每次抽取的下标范围为(1,1,1,1)
、(1,2,1,2)
、(2,2,2,2)
(即教材上的灰矩形坐标,由两个顶点确定)。
抽取的函数代码如下:
|
|
注意教材上伪代码第4行(对应此代码第6行)缺少条件,这里添加了后半个条件,否则输出将是整个句对。
抽取给定的下标范围的短语后,还要检测其前后有无对空的可能性。is_aligned
函数用于检测这种情况:
|
|
程序使用argparse
来输入参数,需要输入的参数有:
--f-corpus
:外语语料路径,每行一句(中文语料需分好词)。--e-corpus
:英语语料路径,每行一句,须与外语语料句对齐。--save-dir
:结果保存路径。--alignment
:对齐文件路径,json格式,可由上一个实验自动生成。内容为一个嵌套字典,如下所示:
小语料运行演示
我们使用以上程序演示一下教材图5.6的实例:
|
|
在终端执行后可以得到和教材完全一致的结果:
|
|
大语料运行演示
仍旧使用的FBIS语料为中英对齐语料,在终端以如下参数执行程序:
|
|
抽取的短语如下:
|
|
结果基本正确,但由于部分词没有相应的对齐,以及没有对抽取行为做限制,仍有较多瑕疵。后续可以通过训练更好的词对齐(如正反训练一遍做并集)、对抽取短语的长度做限制等,可以提升抽取结果的质量。
结语:神经机器翻译与其他
机器翻译从形式上来说,是序列到序列的任务,但是和序列标注任务(如词性标注)不同的是,大多属情况下,源端序列和目标端序列长度不一致。因此序列标注任务中使用的HMM、CRF等模型不再适用,需要有其他的翻译模型。
在机器翻译的课堂上,除了传统的统计机器翻译(SMT)外,我们也涉猎了若干前沿的神经机器翻译(NMT)模型。神经机器翻译基于深度的神经网络模型,比如CNN和RNN。RNN擅长处理时序模型,可以从输入端随着时序喂入一个分词的句子(以词向量形式),RNN能够在内部维持一个隐状态参数矩阵,用于将上一个时刻的输出,通过该参数矩阵传入下一个时刻,以此解决长程依赖。
为了解决RNN在长距离上梯度传递的消失和爆炸,可以引入LSTM。LSTM在内部使用三个具有可学习参数的门控来决定哪些信息该输入、遗忘、输出,从而解决梯度消失和爆炸的问题。
神经机器翻译模型一般采用seq2seq模型2,seq2seq模型采用encoder-decoder的结构,这里的encoder和decoder可以是CNN也可以是RNN。encoder将输入的句子转化(编码)为一个中间状态向量,decoder则通过此中间状态向量和前面已经翻译好的词汇解码出下一个翻译词汇。seq2seq模型还可以搭配attention机制,可以得到更优秀的、更具有语言学意义的翻译模型。
尽管NMT全面胜出SMT,但NMT参数过多,运行时间过长的缺点也不容小觑,课堂上也讨论了众多的方案。可以使用简单但同样强大的结构来提速,如FAIR提出的纯CNN翻译模型3;也有通过改进梯度传导过程中类似“剪枝”的手段来避免无用部分的梯度传导等根本性的改进4。NMT有比较大的潜力,后续有精力将尝试研究和实现。
参考文献
Koehn, P., 2009. Statistical machine translation. Cambridge University Press.↩
Sutskever, I., Vinyals, O. and Le, Q.V., 2014. Sequence to sequence learning with neural networks. In Advances in neural information processing systems (pp. 3104-3112).↩
Gehring, J., Auli, M., Grangier, D., Yarats, D. and Dauphin, Y.N., 2017. Convolutional sequence to sequence learning. arXiv preprint arXiv:1705.03122.↩
Sun, X., Ren, X., Ma, S. and Wang, H., 2017. meProp: Sparsified back propagation for accelerated deep learning with reduced overfitting. arXiv preprint arXiv:1706.06197.↩