RNN、LSTM和ELMo
笔记来源:
Transformer、GPT、BERT,预训练语言模型的前世今生(目录) - B站-水论文的程序猿 - 博客园
ShusenWang的个人空间-ShusenWang个人主页-哔哩哔哩视频(RNN模型与NLP应用)
一、RNN(Recurrent Neural Network)
传统的神经网络无法获取时序信息,然而时序信息在自然语言处理任务中非常重要。
上图左边部分称作 RNN 的一个 timestep,在这个 timestep 中可以看到,在 𝑡 时刻,输入变量 𝑥𝑡,通过 RNN 的一个基础模块 A,输出变量 ℎ𝑡,而 𝑡 时刻的信息,将会传递到下一个时刻 𝑡+1。
如果把模块按照时序展开,则会如上图右边部分所示,由此可以看到 RNN 为多个基础模块 A 的互连,每一个模块都会把当前信息传递给下一个模块。
RNN 解决了时序依赖问题,但这里的时序一般指的是短距离的,首先我们先介绍下短距离依赖和长距离依赖的区别:
- 短距离依赖:对于这个填空题 “我想看一场篮球____”,我们很容易就判断出 “篮球” 后面跟的是 “比赛”,这种短距离依赖问题非常适合 RNN。
- 长距离依赖:对于这个填空题 “我出生在中国的瓷都景德镇,小学和中学离家都很近,……,我的母语是____”,对于短距离依赖,“我的母语是” 后面可以紧跟着 “汉语”、“英语”、“法语”,但是如果我们想精确答案,则必须回到上文中很长距离之前的表述 “我出生在中国的瓷都景德镇”,进而判断答案为 “汉语”,而 RNN 是很难学习到这些信息的。
详细的RNN模型结构:
RNN模型不适合处理长句子:
二、LSTM(Long Short Term Memory)
为了解决 RNN 缺乏的序列长距离依赖问题,提出了LSTM:
详细LSTM模型:
三、ELMo (Embeddings from Language Models)
在前面讲解 Word Embedding 中,每一个词都有一个唯一确定的词向量,不能根据句子的不同而改变,无法处理自然语言处理任务中的多义词问题。
针对 Word Embedding 中出现的多义词问题,ELMo 提供了一个解决方案。
ELMo 采用了典型的两阶段过程:
- 第一个阶段是利用语言模型进行预训练;
- 第二个阶段是在做下游任务时,从预训练网络中提取对应单词的网络各层的 Word Embedding 作为新特征补充到下游任务中。
第一阶段:
上图展示的是其第一阶段预训练过程,它的网络结构采用了双层双向 LSTM,目前语言模型训练的任务目标是根据单词 𝑤𝑖 的上下文去正确预测单词 𝑤𝑖,𝑤𝑖 之前的单词序列 Context-before 称为上文,之后的单词序列 Context-after 称为下文。
图中左端的前向双层 LSTM 代表正方向编码器,输入的是从左到右顺序的除了预测单词外 Wi𝑊𝑖 的上文 Context-before;右端的逆向双层 LSTM 代表反方向编码器,输入的是从右到左的逆序的句子下文Context-after;每个编码器的深度都是两层 LSTM 叠加。
这个网络结构其实在 NLP 中是很常用的。使用这个网络结构利用大量语料做语言模型任务就能预先训练好这个网络,如果训练好这个网络后,输入一个新句子 𝑠𝑛𝑒𝑤 ,句子中每个单词都能得到对应的三个 Embedding:
- 最底层是单词的 Word Embedding;
- 往上走是第一层双向 LSTM 中对应单词位置的 Embedding,这层编码单词的句法信息更多一些;
- 再往上走是第二层 LSTM 中对应单词位置的 Embedding,这层编码单词的语义信息更多一些。
第二阶段:
上图展示了下游任务的使用过程,比如我们的下游任务仍然是 QA 问题,此时对于问句 X:
- 我们可以先将句子 X 作为预训练好的 ELMo 网络的输入,这样句子 X 中每个单词在 ELMO 网络中都能获得对应的三个 Embedding;
- 之后给予这三个 Embedding 中的每一个 Embedding 一个权重 a,这个权重可以学习得来,根据各自权重累加求和,将三个 Embedding 整合成一个;
- 然后将整合后的这个 Embedding 作为 X 句在自己任务的那个网络结构中对应单词的输入,以此作为补充的新特征给下游任务使用。
- 对于上图所示下游任务 QA 中的回答句子 Y 来说也是如此处理。
因为 ELMo 给下游提供的是每个单词的特征形式,所以这一类预训练的方法被称为 “Feature-based Pre-Training”。
至于为何这么做能够达到区分多义词的效果,原因在于在训练好 ELMo 后,在特征提取的时候,每个单词在两层 LSTM 上都会有对应的节点,这两个节点会编码单词的一些句法特征和语义特征,并且它们的 Embedding 编码是动态改变的,会受到上下文单词的影响,周围单词的上下文不同应该会强化某种语义,弱化其它语义,进而就解决了多义词的问题。