#! https://zhuanlan.zhihu.com/p/463766834

title: NLP重大发展历程:从word2vec到Bert的演变
date: 2022-01-29
categories: 深度学习
cover: true
toc: true
tags:
- summary
- NLP


NLP发展至今,Bert成了一个里程碑式的模型,它类似与CV中的ImageNet,将NLP带入了一个全新的时代。很多新入坑的NLP萌新,包括我,在学习Bert模型的时候,可能都会先接触一下Transformer,或者深入点的会接触一下ELMo,最后再接触Bert,但是看完模型架构后会陷入迷茫,好像懂了数据是怎么流动的,训练策略也略知一二,但是为什么要这么做,Transformer和Bert为什么引起那么大的轰动,预训练模型在CV也经常用,很多领域的任务都用在imagenet上预训练的Resnet、VGG等模型作为backbond,为什么在NLP一直那么强调预训练?

总而言之,就是一种似懂非懂的状态,如果你也跟我一样对Bert久仰大名,但又是刚刚入门NLP,那么我推荐你读一下这篇博客,这篇文章不会先不讲解那些锱铢必较的模型细节,而是从一个较为宏观的角度,告诉你Transform、Bert等模型的设计理念。之后你再去看那些模型,可能会更有体会。

这篇文章会先从词向量入手,从前的word2vec和Glove等词向量已经无法满足需求,需要一种更加灵活的词向量作为下游任务的输入,随后会介绍TagLM和ELMo对于这方面的贡献,顺便带过和ELMo同期出现的ULMfit模型;然后介绍Transformer,它开创性地抛弃掉LSTM和RNN这类过于耗时的网络结构,仅仅保留Attention,相比起ELMo它显得更加简约高效;最后再介绍GPT和Bert,它们都是在Transformer的基础上进行不同的改进,尤其是Bert,在推出的时候可谓是NLP领域的集大成之作。

这篇文章需要你对传统的词向量至少是word2vec有所了解,知道什么是语言模型,对RNN、LSTM、Transformer结构有大概的认识。

多义词难题的出路——动态词向量

NLP领域不管是进行文本分类、翻译、文本生成等任务,词向量都是绕不开的一个话题,要实现目标任务,往往需要先训练一份词向量,作为目标任务模型的输入,比起采用随机初始化的词向量作为模型输入,一份预先训练过的良好的词向量总是能给目标任务带来一些增益。

在2018年之前,一般都是用word2vec、Glove这类词向量。先回忆一下这类词向量的原理,在训练的时候,会设定一个大小合适的窗口,挖去窗口中心的词,用周边的词来预测该词,或者是用中心词去预测周边词;而在训练完成后,一个词就对应一个特定的词向量,不再随上下文会改变,即使有时候用于下游任务,可能会跟模型一起进行finetune,但是最终仍然是一个词对应一个特定的词向量,我们称这种词向量是一种静态的词向量。

静态词向量的最大问题在于它无法解决一词多义问题,这里举个例子加深理解“静态”:

  1. 这本书很深,不太容易理解
  2. 这衣服颜色太深,不太好看

在这两句话中都有“深”字,第一句话的表示“深奥”,第二句话的表示一种“程度”,人是怎么判断这两句话的”深“要怎么理解的呢?自然是通过上下文的一些语境。

现在假设已经训练好了一份word2vec词向量,通过查词典,可以很容易地找到“深”这个字对应的词向量是vRdv \isin R^{d}。如果我们要利用这份词向量再进行下游任务,比如情感分类,采用最简单的方式——将一句话中的所有词向量做加权平均后送入分类层,这时候弊端就显现出来了,两句话中“深”这个字明明不是一个意思,但是我们却都用vv去表示它,这自然是不太符合常理。

这便是静态词向量的弊端,同一个词不管处于什么语境,都只能对应同一个固定的词向量。我们希望能有更灵活的表示,即一个词在不同的语境中,是可以对应不同词向量的,套用到上面那个例子,即两句话的“深”可能分别对应v1,v2v_1,v_2两个词向量,它们编码了“深”的不同意思,我们称这种词向量为动态词向量。

那么动态词向量怎么获得?一般还是会用word2vec作为初始词向量,将它送入到一个模型中,设定某种模型优化目标,让词向量随着模型一起优化,模型的输出不仅有预测目标,还有每个初始词向量对应的新词向量,新的词向量是与上下文相关的,对于不同的上下文,输出的新词向量是不一样的。当优化目标达到后,这个训练好的模型就是一个转化器,它将原始word2vec词向量转换为与上下文相关的词向量。

当然这里的模型优化目标是什么并没有限定,可以是机器翻译,也可以是语言模型(给定一段话预测下一个词)等等,我们只是想得到一份词向量,训练词向量时的模型优化目标跟我们下游任务的优化目标,本质上是没有关系的,需要特别注意这一点。另外,语言模型的初始词向量从哪里来?一般来说,可以一切静态词向量比如word2vec,这个初始词向量也被称为原型向量(prototype vector),一个词的一切动态变化都是从这个初始的原型向量衍生出来的。

对于动态词向量的尝试,最早可以追溯到CoVe,他们在序列到序列的机器翻译任务上训练了一个深度 LSTM 编码器,然后用它生成根据上下文变化的词向量,再在下游任务中应用这些词向量。随后就是接下来要讲的TagLM。

TagLM——ELMo的前身

CoVe在训练词向量时用的是一个机器翻译模型,机器翻译需要大量标注的双语预料,这是很耗费人力的一项工作。TagLM简单得多,我们想要的只是一份能随着上下文语义动态变化的词向量,一个简单的语言模型是不是也能实现类似的功能?再重温一下语言模型的定义——给定一段话,预测下一个词。最重要的是,如果是训练语言模型,也就不需要人为地做什么标注了,可以说是一种无监督的训练方式。

milestone/Untitled.png

上图右侧就是TagLM在训练词向量,它是一个双向RNN模型,模型的输入是Token representation,可以是word2vec这类静态词向量,输出是编码了上下文语义的词向量。在完成训练后,它的参数会被固定住,输入一句话New York is located …中每个词的Token representation,输出的是每个词的重新编码的词向量h1LMh_{1}^{LM}(LM就是language model 语言模型的意思),当然还有一个细节就是这个h1LMh_{1}^{LM}是将两个方向RNN中输出concat在一起。

图的左侧是用于目标任务——命名实体识别的模型,除了将右侧的上下文相关词向量h1LMh_{1}^{LM}作为输入外,还将Token representation和字符级词向量也作为输入,个人感觉后面这两种输入主要是为了堆性能,TagLM最大的贡献是发现可以用无监督方法训练语言模型获得与上下文相关的动态词向量,该词向量对下游任务也有帮助。

ELMO

ELMo是TagLM的升级版,实际上也是同一批人做的。总的来说,它只是改变了TagLM的预训练词向量方法,即原TagLM示意图的右侧pretrained bi-LM:

milestone/Untitled%201.png

具体来说做了以下改变:

  1. bi-rnn 变成 bi-lstm,而且是多层的bi-lstm
  2. 不止取bi-lstm的顶层作为词向量,而是将多层的输出合并在一起作为词向量

ELMo取得了很好的性能,在TagLM基础上又更进一步,但是其最大的意义仍然是告诉大家用无监督预训练语言模型能得到随上下文变化的动态词向量,对于绝大部分下游的NLP任务都能获得一致地提升,因为训练词向量是无监督的,这几乎是白给的增益。

ULMfit

ULMfit是和ELMo同期的模型,都是在Tag LM上改进,它改进的思路和ELMo不一致,它考虑了两点:

  1. 预训练的词向量可能和目标域有差别,考虑在目标域的数据集上对词向量进行finetune
  2. 进行下游任务真的需要另外搭一个模型吗?可以考虑在训练词向量的模型上直接进行下游任务的finetune

milestone/Untitled%202.png

Transformer

前面CoVe、TagLM、ELMo、ULMfit基本定下了NLP任务的范式,先预训练好一份随上下文动态变化的词向量,然后用该词向量作为下游任务模型的输入。预训练词向量可以是用无监督策略,节省人力,但又能带来良好的效果,从功能层面上看它也确实能随上下文变化,能解决一词多义的问题。

Transformer开始对模型的基本组件动刀——即LSTM和RNN,这两者都是时序相关的模型,很难充分利用GPU的并行计算,因此时间效率很差。Transformer的作者做出了大胆的设计,LSTM和RNN的模型大多都会加上Attention机制,这能带来很好的增益,那么可不可以只保留Attention这种机制就行了,LSTM和RNN的架构全部推倒重来,专门设计一种能够实现并行计算的Attention模型。

此时再想想Transformer的论文题目——Attention Is All You Need,不是强调Attention很重要,而是很激进地认为,有Attention就够了,LSTM和RNN等结构都可以丢弃了。

文章最重要的贡献就是设计了一种较为复杂的Attention子模块,整个模型就是这种子模块的堆叠,但是却能取得很好的效果,这也印证了作者所说的只要有Attention就行了。该模型由于是一次性将一整段预料一起丢进去的,也就没有LSTM和RNN那种t时刻推理t+1时刻的机制,GPU的并行计算得以更充分地发挥。当然一整段一起丢进去会损失每个词位置的位置,因此又加了了位置编码这个的输入。这些都是模型的细节层面了,这里就不展开叙述了。

milestone/Untitled%203.png

GPT

有了Transformer简单高效的模块,财大气粗的OpenAI开始整活了,既然Transformer这么好用,而且都不用设计什么模型结构直接堆就行了,那么就堆多点让网络更深点吧。

Bert

作为Transformer的提出者,Google也不甘示弱,谁家还没个庞大的GPU群,我也堆Transformer,Transformer很好,加深一点吧;Bi-LSTM双向机制在Transformer中用不了了,我们加入一个Mask训练机制,强行上双向机制;finetune时似乎只要encoder就够了,decoder都可以丢了。

可以看到,GPT和Bert都是在Transformer上做一些修修补补,没有再有大的变化,他们的贡献是提供了用大量数据预训练的大模型,使得整个NLP领域的下游任务都可以获得性能增益。

参考文献:

  1. http://blog.itpub.net/69946223/viewspace-2685459/
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码

请我喝杯咖啡吧~

支付宝
微信