立委随笔:机器翻译,从学者到学员

学了神经翻译网课,感慨良多。回想一下觉得有些好笑:30多年前好歹也是科班机器翻译出身(社科院语言所研究生院机器翻译专业硕士,1986),大小也可以说是个学“者”。河东河西,现在乖乖成了机器翻译学“员”了。机器翻译翻天覆地的变化是有目共睹的。如果NLP其他方面的变化也达到机器翻译的程度,那才真叫不废江河万古流。

机器翻译课讲义编得真心不错。这一段讲解有点意思:

3. Trained model
During the training of the Teacher-Forced model, you provided the French sentences to the decoder as inputs. What are the decoder inputs when performing a new translation? You cannot provide the translation as an input because that's what you want the model to generate.

4. Decoder of the inference model
You can solve this by building a recursive decoder which generates predictions for a single time step. First, it takes in some onehot encoded input word and some previous state as the initial state. The GRU layer then produces an output and a new state. Then, this GRU output goes through a Dense layer and produces an output word. In the next time step, the output and the new GRU state from the previous step become inputs to the decoder.

就是说在训练神经翻译模型的时候,源语与目标语都在,都作为 decoder 的 inputs 来帮助模型训练。但是到了应用模型来翻译的时候,目标语作为 input 的条件不在了,那么怎么来保证目标语的影响呢?

讲义中所谓 recursive decoder 就是把目标语的语言模型带入翻译过程。这时候与训练的时候有所不同,不再是具体的目标语的句子来制约,而是用目标语预测下一词的语言模型来介入。这就是为什么神经翻译可以通顺地道的主要原因。因为有了目标语语言模型的引导。

神经翻译常常通顺有余,精准不足。这其实是一对矛盾的反映,本质上是因为 decoder 解码的时候,有两股力量在影响它,一个是源语encoder 编码的输入(上下文的 vectors),另一个是目标语语言模型(next word prediction)的输入,这两个因素一个管精准,一个管通顺,协调起来难免出现偏差或偏向。

尝试把上述讲义自动翻译(谷歌MT)后编辑说明一下:

培训模型在“教师强制”模型的培训过程中,提供给译码器的法语句子作为输入。当执行新的翻译时,解码器的输入是什么?您不能将翻译作为输入来提供,因为这是您希望模型生成的结果。推理模型可以通过构建一个递归解码器来解决这个问题,该递归解码器可以生成针对 “单个时间步长“(即:词) 的预测。首先,它接受一个热编码的输入词(这是指的源语输入文句的词)和一些以前的状态(这是指该词的上文隐藏层的内部表示)作为初始状态。接着,GRU 神经层生成一个输出(指的是下一词的向量表示)和一个新状态。然后,这个 GRU 输出通过全连接稠密层产生一个输出词(这是目标语下一词)。在下一个时间步长中,前一步骤的输出(目标语的词)和新的 GRU 状态成为解码器的输入。

目标语的语言模型是生成模型,生成模型本性就是发散的,可能步步走偏。制约它不走(太)偏的约束来自于根据源语文句编码的上下文状态。这里面还有个魔鬼细节,那就是原文句子的启动是反向的,reverse=True,就是说,原文句子的输入做了逆序操作:

sos we love cats eos --> eos cats love we sos

这样一来,当 sos(句首标志)作为解码器启动的初始单元的时候,伴随它的前文(上下文中的上文部分)不再是空(没有逆序的原句,前文是空的),而是整个句子的浓缩状态来支持它。这就说明了为什么一个 sos 的启动操作,可以依据前文生成下一个词,与 we 对应的 nous,后面就是“链式反应”了,直到生成句末标志 eos,完成一个句子的翻译。在这个递归的链式反应的每一步,每生成一个词,“前文” 就少了一个词,前文的状态因此也在步步更新作为下一步的输入,而所生成的目标语词也作为下一步的输入带入了目标语的生成模型,二者的相互作用造成了精准和通顺的妥协和平衡。目前看来,目标语的生成模型对于翻译的作用容易大于前文状态的作用,造成错译(张冠李戴、指鹿为马,人间蒸发,鬼影乍现等等问题)。但原则上,应该有办法去做平衡配置,就好比在精准和召回之间做平衡配置一样。

这一段讲义讲得蛮明白:

11. Generating translations
Now you can start recursively generating French words. First you define a variable fr_sent to hold the full sentence. Then for fr_len steps in a loop you do the following. First you predict a word using the decoder. Remember that, the inputs to the decoder are, a word from the French vocabulary and the previous state of the decoder. In the fist step, the input will be "sos" and the input state will be the context vector from the encoder. This model then outputs a word, as a probability distribution and a new state. The new state will be recursively assigned to de_s_t. This means, at every time step, the previous decoder state will become an input to the model. Then in the next step you get the actual word string using probs2word() function. probs2word() is a function that accepts a probability distribution and a tokenizer and outputs the corresponding French word. After that, you convert that word to an onehot encoded sequence using the word2onehot() function. This is assigned back to de_seq which becomes an input to the model in the next step. And you keep iterating this process until the output word is "eos" or, until the end of the for loop.

这是最后的实际译文的(词循环)生成过程。利用浏览器Chrome自带的谷歌翻译(plu-g-in)如下:

给点说明:

11. 生成翻译
现在您可以开始递归生成法语译文了。首先,您定义一个变量 fr_sent 来保存完整的译文句子。然后对于循环中的 fr_len 步骤,您执行以下操作。首先,您使用解码器预测一个单词。请记住,解码器的输入是法语【即目标语】词汇表中的一个单词和解码器的先前状态【即源语的前文】。在第一步中,输入将是“sos”【句首标志】,输入的状态将是来自编码器的(源语文句的)上下文向量。然后该模型输出一个(目标语)单词【在目标语词汇表中的概率分布】和一个新状态【上下文动态更新】。新状态将递归赋值给 de_s_t。这意味着,在每个(单词生成的)时间步,之前的解码器状态都将成为模型的输入【这是译文精准的源头】。然后在下一步中,您使用 probs2word() 函数(从所预测的词的词汇概率分布)获取实际的单词字符串。probs2word() 是一个接受概率并输出相应法语单词的函数。之后,您使用 word2onehot() 函数将该单词转换为 onehot 编码序列【把生成的词重新编码以便模型下一步使用:这是引入目标语生成模型的关键输入,它是译文地道通顺的保证】。这将被分配回 de_seq,后者将在下一步中成为模型的输入。然后你不断地迭代这个过程,直到输出单词是“eos”【句末标志】,或者直到 for 循环结束。

是不是很有意思?

欣赏一下课件的图示:

 
课程最后的讲义总结如下:
Got It!
1. Wrap-up and the final showdown
You've learned a great deal about machine translation and maybe a little bit of French as well. Let's have a look back at what you've learned.

2. What you've done so far
First, in chapter 1 you learned what the encoder decoder architecture looks like and how it applies to machine translation. You then played around with a sequential model known as GRU, or, gated recurrent units. In chapter 2 you looked more closely at the encoder decoder architecture and implemented an actual encoder decoder model in Keras. You also learned how to use Dense and TimeDistributed layers in Keras to implement a prediction layer that outputs translation words.

3. What you've done so far
In chapter 3, you learned various data preprocessing techniques. You then trained an actual machine translation model and used it to generate translations. Finally in chapter 4 you learned about a training method known as "teacher forcing" which gives even better performance. You trained your own model using teacher forcing and then generated translations. At the end, you learned about word embeddings and how they can be incorporated to the machine translation model.

4. Machine transation models
In this course, you implemented three different models for an English to French translation task. Model 1 was the most basic model. The encoder consumed the English words as onehot encoded vectors and produced a context vector. Next the decoder consumed this context vector and produced the correct translation. In model 2, the encoder remained the same. The decoder in this model predicted the next word in the translation, given the previous words. For model 3, we replaced onehot vectors with word vectors. Word vectors are much more powerful than onehot vectors and enables the model to learn semantics of words. For example, word vectors capture that a cat is more similar to a dog than a window.

5. Performance of different models
Here you can see the performance of those three models. You can see that the models trained with teacher forcing give the best results. You should note that the model that uses word vectors gets to a higher accuracy much quicker than the model that is not using word vectors.

6. Latest developments and further reading
Though you used the accuracy to evaluate model performance, there is a better metric known as BLEU which tries to imitate how a human would assess the translation. Another important thing to know is how out-of-vocabulary words are treated in productionized models. For example, Google cannot simply replace unknown words with a special token. To address this problem these models use a word piece model. A word piece model will identify most frequent sub-words in a corpus. For example, if the model has seen the words "low" and "newer", and has learned the sub-words "low" and "er", the model can represent the unseen word "lower". One of the most important developments in the field of NLP is the Transformer. Transformer is based on the encoder-decoder architecture. However it does not use any sequential models like GRUs. Rather, it uses something known as attention which is more light-weight than a GRU.

7. All the best!
I hope this has been a fruitful journey about machine translation and I wish you all the best.
 
【相关】
 

李维 郭进《自然语言处理答问》(商务印书馆 2020)

预告:李维《巴别塔影:符号自然语言处理之旅》(人民邮电出版社 2022)

立委随笔:上网课也可以上瘾吗?

可以的 -- 如果所学刚好是你的兴趣和热情所在。

马斯克说,university 主要不是学知识。如今的信息社会,知识不需要上大学。知识是免费的,只要你愿意学,它永远在那里等你。

那大学干啥呢?马斯克说,大学主要是玩(fun),还有社交和关系(connections)。顺带一个用作业和考试磨炼一个人耐心的副作用:证明你能抗造。

现在想来,老马说的有些道理。在线的免费或低费课程 by nature 比大学设置的课程平均水平高,因为它可以不断迭代,精心设计,personalize 根据学生的表现因材施教。

最近试了几门网上的电脑软件课程,虽然网课也有参差不齐,但总体感觉这是教育的大方向。其中的优秀者,从教学内容和方式上,几乎超出了我对于“理想教育”的一切想象。没想到这几年在线教育进步这么快。

真地 very impressed。才100 多美元的年费,我注册了一个有几百门课程的网站 Datacamp,发现里面很多宝藏,让人流连忘返。它会根据你的进度、错误,自动调整给你的建议,针对性补缺。再笨也能被提升。无材不可教。完成一门课,发个小红旗,美滋滋的,跟过年吃上牛轧糖一样,吃了还想吃。

certificate5-OOP

看来,教育扁平化、优质教育普及到每个角落的愿景,不是梦。穷乡僻壤也一样可以够得着一流的教育,至少从知识传播的角度看是如此(至于心智情操的教育,可能较难离开人类教师的参与)。

这两天在寻思信息时代的学费问题:不少学校是按照课程收费,一个学期一门课收费 x 美元等等。伯克利这样的公立学校是按照学期收费,无论选几门课,学费是固定的。有一次我问:那多选课的学生岂不是占了大便宜?如果一学期选个七八门课,岂不是两年的学费就毕业了。得到的回答是:是的,可以这样做,如果你不怕死。还的确有极少数人做成了的。但到了期末的 dead week,脑容量不够装那么多东西来应付考试。

到了网课时代,成本趋近于零。那天我算了一笔账,年费100多美元的网站,有几百门(还在增加中)精心准备的课程 offering,如果凭着兴趣专心去学,一年下来学50门课没有问题。这样算下来的学费,每门课不到一杯咖啡钱。不禁有点心痒:这个大便宜不占,不是太亏了吗。网站也赚,因为是规模化经营,每门课都成千上万源源不断的生源。也因此他们可以聘请最好的老师,编制特别讲究的课件,配以精心设计的个性化动态配置的学习环境。

certificate-7

学完这门课,讲师超级棒。学到的技巧包括对 code 做 profiling,找到时间、空间瓶颈。本来这些工程优化的细节问题不是我感兴趣的点,但是无奈这个讲师讲得太好了,开始听了就停不下来。可以体会和观察到优秀讲师与课件的高明之处在哪里。

学 RNN 课程的时候,记下了零星的笔记:

多层神经训练跟玩积木似的,原来可以这样大杂烩地堆积起来(见课件中的下图),弄得跟化学制剂的配方似的。某教授说,就跟码字的人一不留神就整出个《新红楼梦》一样,码农也可能一不留神就弄出来个数据质量特牛逼的系统出来。

据说,meta training 就是这么个思路。就是说,不仅仅训练模型自动化,连模型本身的结构和超参数的选择也自动化了。如果可以控制组合爆炸,那就让机器来玩积木,保不定玩出一个模型是人想不到的。

这几天跟着RNN课程玩模型也跟小孩玩积木一样,让人着迷。着迷其过程,可以暂时不问结果,权当是 fitness 健身。

还学了神经翻译课程,感慨良多。回想一下觉得有些好笑:30年前好歹也是科班机器翻译出身,大小也可以说是个学“者”。河东河西,现在乖乖成了机器翻译学“员”了。机器翻译翻天覆地的变化是有目共睹的。如果NLP其他方面的变化也达到机器翻译的程度,那才真叫不废江河万古流。

两分钟讲解,10分钟练习这种迭代方式很赞。神经翻译课程与其他电脑课程类似,大约分 10-20 次讲解,说是4小时的课程。机器翻译课讲义编得真心不错。

Did you know that in 2017, Google translate served more than 500 million users daily? 原来 2017年谷歌机器翻译就每日服务5亿人次,超出想象。也许是仅次于搜索服务人次的第二大应用了。网上的语言屏障基本被扫除,现如今任何网页都是点击之间便化为母语。

这个必须晒一晒:

哈哈 疯了啊。前几天给我个notice 说我的疯狂coding的效率超越了社区的95%,今天接到的 note 更新为 超越 100% 这也太夸张了吧 : 社区成千上万的学员,怎么就全超越呢?再者:100% 中包括自己吗?

无论如何 积分远远高出一般 是得到认可的。统计不骗人吧。好,再接再厉,keep coding:老夫聊发少年狂,码农学员coding忙。想起来师姐曾经写过一篇《疯狂世界语》,描述我当年学习世界语过分投入的疯狂,有如昨天。

【相关】
 
 

李维 郭进《自然语言处理答问》(商务印书馆 2020)

预告:李维《巴别塔影:符号自然语言处理之旅》(人民邮电出版社 2022)

关于NLP 落地以及冷启动的对话

友:我比较好奇一个问题,方便的话请教一下李老师。像您开发的那一套parser或者引擎,一旦您离开了,还有人能持续提升么?我个人感觉能有人维护好就不错了。毕竟那套涉及很多语言学的东西,想深入到里面去改进或者维护,应该不容易。

李:基本不能,但是在NLP落地所需要的抽取层面可以继续。就是 NLP-core 一般人不要动。但是 NLP-IE 是可以的。

友:明白,就是如何利用nlp core的输出,这是和业务紧密联系的

李:IE 那些下游任务,可以假设 NLP-core 为空,选择不利用 NLP-core 的结果,也是可以的:那就成了大号的正则表达式。但比正则表达式还是强得多,因为内部有本体知识库对于词的特征支持,可以泛化。而且,虽然不要动 NLP-core,但是下游可以选择去 leverage 其潜力,因为可以根据 core 的输出结构来决定部分利用结构。就是说 core parser 不必预设它是正确的,只要其中有一些正确的部分 下游就可以选择利用。这样的灵活性都 build in 在引擎里面了。

友:nlp-core为空,那就是不要那些词之间细节关系了?然后大号的regex是否可以理解成一种所谓的end2end,给一个句子,得到整体大概是个什么意思。

李:同一条 IE 规则也可以一半用物理上下文(窗口距离限制),一半用结构,例如宾语比主语可靠。宾语就可以作为条件利用,而主语可以通过窗口限制找前面的合适的词。

友:不过话说回来,这个可能就是李老师的方法和统计的方法最大的区别了,李老师这个讲究积累迭代,统计方法训练完模型就结束了,要新的,加数据重新来。

李:其实也有很多类似。我的方法论中 可以半自动开发迭代,这与深度学习里面的梯度下降是相通的。只不过我的迭代开发过程有 human in the loop,去判断迭代效果是否符合预期。因为是冷启动,没有标注数据,只能靠 human 做判官。实质是把开发者从 coder 解放为 judge。这是一个创新,可以大大加快开发并降低门槛。当然我这边的“梯度”是预先确立的离散的路径(否则会爆炸,只有根据以前的 best practice 找到离散的泛化路径),由开发者(知识工程师)选择执行迭代的步骤。

友:嗯嗯,明白。这个感觉是更抽象层面的统一。都需要manual work,但是在不同的阶段,统计方法里的manual work就是标注,一旦标注完成,后续不会再有明显的manual work了。但是李老师的方法尤其在前期需要持续的manual work,稳定之后也很少了。

李:就是,我的方法更靠近常规软件工程方法:低代码数据驱动迭代。而机器学习/深度学习实际是一种极端主义的方法论,因为本质上 机器学习就是要实现自动编程,追求的是全自动开发(即训练)。等于是说,要消灭码农。因为深度学习在有些地方作出了突破进展,是主流,结果其极端主义的一面 一般人看不到了,被广泛视为理所当然。

友:是的是的。统计方法的模型更适合做产品系统里的某个模块,而不是产品系统本身。李老师有没有考虑过自己干?提供这种nlp-core的服务。

李:太费力,因为提供这种小众服务有擦不完的屁股。

友:哈哈,也是,最好还是套到某个具体赚钱的业务上。

确实,人们其实并不在意机器怎么理解具体句子,人们只在意怎么指导具体的业务,也就是下游的任务。这个我想也是统计方法的优势,不在细节里纠结,直接建模输入和输出。

李:end to end。

能够端到端的前提 是有大量的标注冗余数据,但这个条件在很多领域应用场景中都不存在。这就是冷启动做业务目前的难以取代的价值所在。理论上,预训练可以代替 Parser 来节省对于大量标注数据的依赖。但是 预训练+下游 这种 transfer approach 的规模化工业落地 还有很多沟沟坎坎。如果真有大的突破,parser 的价值就会降低了,也许整个符号路线会被终结。但现在判断其前景,还是有点为时过早。

友:哈哈,所以nlp的创业公司都做不了toB,因为没数据;做toC又做不过有用户的大厂,所以nlp创业公司挣不到钱,做不大。

李:EXACTLY

 

【相关】
 

李维 郭进《自然语言处理答问》(商务印书馆 2020)

预告:李维《巴别塔影:符号自然语言处理之旅》(人民邮电出版社 2022)

《李白梁129:新年快乐的符号逻辑》

白:新年快乐!

李:有意思。形式逻辑表达式?

两个tokens,嵌套演算6次,请白老师给讲解一下其语义计算。intuitively 感觉就是 “时间”和“性状”的交集。性状作为谓词,存在一个缺省的宿主,就是祝愿的对象。当然也缺省了“祝愿”,就是说性状有一个 hidden 的虚拟语气。

白:(1)定义谓词“快乐”。它带两个约束变元,一个是时段,一个是当事主体。(2)话题化。“快乐”的当事主体不在原位,说明向外层发生了移位,在我的体系里就是管挖坑不管填坑,不饱和的坑被托管给外层。(3),用一个摹状词定义了“新年”,它是由属于“新年”的所有时点构成的时间连续统(区间)。(4)在“新年”与“快乐”结合时,把新年所界定的时段用来对“快乐”进行周遍性描述,说明是在这样一个时间连续统里当事主体都快乐。(5)把这个空缺的当事主体(萝卜)构拟出来,赋予他空缺论元(萝卜)的一切已知特性。(6)回到语境,确认这是一个祈使句(祝福语),填坑的萝卜默认为语境中的听话人。还应当有个(7),就是萝卜(语境中的听话人)一路反填回最内层的坑位,也就是当初谓词“快乐”所挖之坑。所谓话题化,只是不饱和论元向外层托管残坑而已。未必处在C-Command位置(中心词对中心词/非中心词拉飞线),也完全可以处于我们定义的M-Command位置(非中心词对非中心词拉飞线)。

李:? 新年第一语义。

句法上 英语 Happy NY 中 Happy 是定语(快乐的新年),中文 “新年快乐” 感觉上 “新年” 就直接是(拟人化的)宿主。但英语的定中结构落脚在时间实体上,而中文无论是解析为主谓结构还是状谓结构,落脚在性状(谓词),都是围绕这个谓词中心,对它做约束。其他东西(包括真正的宿主)都是身外之物。

梁:不饱和最好[ThumbsUp] 有“可延展性”! Actually 空的坑越多越好,待定状态最好!

我觉得,不同的想法(框架)不应该混。 主谓宾定状补是一种语言体系。 萝卜-坑 是另一种语言体系。

李:前者是句法,后者是(逻辑)语义。形式逻辑的演算和表示是后者的算法化。

语用角度,感觉中心概念是时间,谓词降格成为渲染情绪的性状来描述这个时间,“新年快乐” 描述的是一年中有这么一天,空气中飘荡着快乐的氛围。这刚好与英语句法是一致的。

梁:语用层面,主要是 “新年” 这个词 触发了一连串想象,一幅很有特色的图画(场景),快乐是说明这个场景的。

白:我这处理是:名词降格为副词,做状语。

李:这是时间词的常规做法。甚至可以不降格,就是兼类。

白:这不是兼类,是活用。

李:兼类的说法不宜滥用,但时间是个例外:几乎在所有语言中,时间词都是名词为本,状词为表,作状语拿来就用。这是因为,时间在 entity 的频谱中,具有极其重要的特殊性和抽象性:无事不在时间内。

白:涉及到aboutness的时候,也管不了那么多。之前我们讨论过的“这场火多亏消防队员来得及时”就是。

李:分布上看,时间词作状语是压倒性的,而作为本体被议论描述则比较罕见。所以与其降格,不如说就是副词,偶然升格为名词/实体。换句话说,如果原子性符号标注不允许兼类,也不允许分层(降格升格),那么索性标注为 RB(副词),大体齐是过得去的。

白:这个我们还是根据原理来的。名词降格为副词,语义上是有一个未命名的格标记(隐介词)以这个名词为介词宾语。我们的升格操作对应于脑补这个隐介词。如果这个名词本身具有#Time的本体标签,则隐介词为“在(时间)”就很顺畅。

李:实践中,兼类也不是一个什么要不得的做法,不过就是所谓“包容”策略的一个捷径而已。绝大多数词典都是如此标注的,无论这些符号是兼容还是不兼容,大多是混杂在一起的。这带来了简便,实际运行中虽然不完美,有逻辑破绽,但多数时候是管用的。新年:RB NN,上下文要谁给谁。(其次是只给 RB,必要时“升格”为名词)。

白:说起词典,有一个很有意思的问题。“home”有一个义项被标注为副词,因为可以说“go home"。“home”还有一个义项被标注为形容词,因为可以说“on the way home"。其实,只要把home理解为缺省了隐介词"+X/N"的介词宾语N,就不难理解这两个home其实是一个,只不过隐介词既能导向状语、也能导向定语罢了。

李:那是因为定状一家,PP 是 adjunct,无论限制什么对象。

白:对,+X向左,既可以修饰N,也可以修饰S。介词就是吃一个N,吐一个+X。

祝大家新年快乐!

 
【相关】
 

李维 郭进《自然语言处理答问》(商务印书馆 2020)

预告:李维《巴别塔影:符号自然语言处理之旅》(人民邮电出版社 2022)