字符级机器翻译

最近利用神经网络的机器翻译很火,我认为NMT(Neural machine translation)能有所发展的原因有以下几点:

  1. 数据丰富,WMT15算是与ImageNet同样量级的数据,是训练大型神经网络所必须的。
  2. Bahdanau提出的Attention关系将机器翻译的性能推进一大步。
  3. 很明显能产生经济效益,市场巨大。
  4. 存在很多问题,即研究前景。毕竟相对CNN给图像识别带来的巨大提升,NMT的提升并不是很明显。

我针对的是其中的一个问题:规避大词典。原来都是先把一个数据集中所有单词找出来,把最常用的一些(如90%)做成一个大词典,显然这是冗余的,words和word完全没必要区分。动不动就是50K的单词表,非常耗内存,在像Czech这类语言上更加不行。关键是冗余不优雅。很多研究者都注意到这个问题:

  • subword,就是统计一下符号的频率,如“est”可能是一个符号,能组成“w est,b est”等词,因此称为subword。我觉得还是不够自然,而且效果并不是很好。
  • Hybrid Word-Character Models,相当于把未知的词训练成RNN小单元,据说华为很早就申请专利了。我表示,不能有word。
  • Junyoung Chung提出的不需要显式分隔的模型。提出bi-scale的RNN,我觉得很有意思,但我有个疑问,这跟base的RNN有什么区别?论文中也显示,确实差不多。我不知道为什么性能那么好。由于没有训练时间、训练所用内存等更多信息我无法作出判断。
  • 还有Wang Ling提出的,但是完全不是NMT,需要借助IBM model来对齐和分层训练,而且效果不好。

综上,利用RNN编码一个单词是比较合理自然的想法。可以说人人都能想到,关键是给出高效可行的实现。我实现了个高效纯字符级的机器翻译——Deep Character-Level Neural Machine Translation(DCNMT)。但是有个缺点,需要知道分隔符,也就是空格。不要太苛刻了,对于人来说,阅读“itisalsomoredifficultforhumantoreadwithoutthedelimiter”这种也是不方便的。而且对于中文日文这种没有分隔符的语言,没有必要使用大词典,直接上字符级,因为句子短啊,不存在训练难的问题。所以先将就着用吧。总得来说,DCNMT有几个优点:

  1. 所需训练循环周期比词级的少,在EN-FR上,只要遍历4次数据就差不多了,而词级大概要5次,这很容易get。但是因为更新速度慢一点,导致所花时间差不多。
  2. 内存用的不多。但还是很多,因为theano为了计算快,RNN的中间结果是缓存的,导致有5个RNN的DCNMT用了很多内存(跟词级的差不多)。但这容易解决,见chen的paper还有deepmind的一篇
  3. 能翻译错拼的单词,在论文中我只给出了几个例子,后续给出定量分析。我觉得这是一个diǎo点。

详见论文(An Efficient Character-Level Neural Machine Translation),我也不玩虚的,代码和训好的模型都在github上,反正我也没有毕业问题,管他能不能发呢。

总的架构看图:

我也很佩服自己,怎么能写出这么复杂结构的代码,写完之后改了3个bug(我太tm diǎo了)。多亏了巨人Bahdanau等写的好框架Blocksexamples。我的偶像啊!很高兴,他也star了我的实现。仔细看,有5个RNN子模型,其实跟bi-scale思想类似,先把组成词的字符用RNN编码后,只向上传最后的编码(相当与词级模型的embedding),而不是原来的全部(字符的embedding),因此能节约Encoder和Decoder的内存,也容易训练。 整个流程应该很清楚吧,不清楚可以看论文。。。

训练模型

被爱可可老师发到微博之后,关注的人一下子多了点,有点诚惶诚恐。我觉得很多哥们会在训练的时候遇到问题。如有哥们遇到数据集问题,有哥们遇到版本问题(TypeError: __init__() got an unexpected keyword argument ‘children’)。这是我写这篇博客的原因,我希望能实现更好的实用的模型。几个注意点:

  1. 必须先手动下载对应的数据啊,就在wmt15上,还可能要对validation set和test set做一些处理。可以先选数据量小如en-fi的测试测试,一测就是1周。然后就方便了运行Github仓库中的train.sh就行了。
  2. 务必保持库的更新啊,Blocks更新还算快的,API随时改。我会尽量与最新保持兼容,而不兼顾老版本。
  3. 如果还有问题,请在评论中提问。

测试模型

我训练了几个模型,由于机器和时间受限,没来得及训练其他模型,详见论文github。我希望有人能帮忙训练更深的模型。我不知道这个模型的上限是多少。

如果对机器翻译不敢兴趣,也可以从中学点什么。这个代码中,用了GRU,stacked GRU,stacked Bidirectional GRU以及GRU的变种,关于RNN的几乎的用到了(苦笑)。还有关键的Attention,虽然有点复杂。

欢迎提问,以及改善这个模型。机器翻译很有意义,所以想能做点什么。