当前位置: 代码迷 >> 综合 >> 2019年CS224N课程笔记-Lecture 13: Contextual Word Representations and Pretraining
  详细解决方案

2019年CS224N课程笔记-Lecture 13: Contextual Word Representations and Pretraining

热度:17   发布时间:2024-02-01 22:44:39.0

资源链接:https://www.bilibili.com/video/BV1r4411

之前大部分都是课件内容翻译+自己的一些总结,以后更倾向于自己的总结咯~

正课内容

词的表示方法

一开始时学过的单词向量 Word2vec, GloVe, fastText都可以表示词,甚至是ont-hot编码也可以表示(只不过不是很恰当)

两个人大概花了七周时间训练无人监督的单词表示/词向量,生成的向量只有100维(也就是图中88.87的那个),几乎和基于特征的分类器效果一样好,后面一些人机遇这个又进行改进,最后达到了89.59(这些在无监督学习中是重大的突破)

预先训练的词向量:2014-2019

我们可以从随机的词向量开始,然后训练它们完成我们感兴趣的任务,但在大多数情况下,使用预先训练好的词向量是有帮助的,因为我们可以在更多的数据上训练它们获得更多的单词(历史上也是使用有监督的数据集训练比较多)

单词向量未知词表示

其实就是将出现频率小于5个的词认为是<UNK>,但是这样也存在一个问题,无法区分不同的<UNK>的含义,这个问题在问答系统中非常常见。

解决方案:

  1. 上次说的,单词由字母表示,可以用字符表示单词进行训练,但是非常复杂~
  2. 遇见<UNK>时随机给他分配一个词向量,并添加到词汇表中~

假如我们使用word2vec向量,存在一个非常严重的问题,虽然word2vec具有语义表示,但是它所代表的词的语义是重叠的。这个地方解释一下就是,一个词语有很多语义,但是只有一个词向量表示,那么该词向量表示的是哪个语义呢?事实上所有语义都包含,但是往往我们使用的时候只是一个语义。

解决思路:一个单词有很多意思,我们可以根据词性来选择,假设一个词的动词语义生成的向量是xxx,名词语义生成的向量是xxx,然后嵌入词向量时,进行选择匹配的(如何训练的时候进行区分,如果潜入的时候进行选择,好像都没事哟);另一种则是,根据语义训练词向量,也就是假设旅游即使去旅游的动词意思,也是一个名词代表一种放松活动,然后使用时加载的语义向量,也就是别的词语代表去旅游的动词意思时,也会加载相同的语义向量(本来是训练词,词即语义,现在变成训练语义,词是多个语义,不过也没具体说如何实现等)

我们一直都有解决这个问题的办法吗?

在模型中,我们通过LSTM层(也许只在语料库上训练),那些LSTM层被训练来预测下一个单词,但这些语言模型在每一个位置生成特定于上下文的词表示

Peters et al. (2017): TagLM – “Pre-ELMo”

看一篇2017年的论文,我们希望在命名实体识别任务中做的更好,想要了解一个词在上下文中的语义,可能我们会训练50w数据,但是对于了解语义来说这并不是很多,为什么不采用半监督的方式呢?(可以有更多的数据)。word2vec是无监督数据集中训练出来的,那么我们为什么不能使用该方法训练神经网络模型呢?

模型如下:

Char CNN / RNN + Token Embedding 作为 bi-LSTM 的输入,得到的 hidden states 与 Pre-trained bi-LM(冻结的,也就是不会训练的,参数已经固定的) 的 hidden states 连接起来输入到第二层的 bi-LSTM 中

Named Entity Recognition/NER/命名实体识别

最出名的命名实体识别数据集是CoNLL 2003,下面是他的一些相关数据(有很多语言,如果没提就是英语的)

Peters et al. (2017): TagLM – “Pre-ELMo”

语言模型在“Billion word benchmark”的8亿个训练单词上训练

语言模型观察结果

  • 在监督数据集上训练的LM并不会受益
  • 双向LM仅有助于 forward 过程,提升约0.2
  • 具有巨大的 LM 设计(困惑度 30) 比较小的模型(困惑度 48)提升约0.3

任务特定的BiLSTM观察结果

  • 仅使用LM嵌入来预测并不是很好:88.17 F1 
    • 远低于仅在标记数据上使用 BiLSTM 标记器

Also in the air: McCann et al. 2017: CoVe

课程中跳过了~

也有使用训练好的序列模型为其他NLP模型提供上下文的想法,想法是:机器翻译是为了保存意思,所以这也许是个好目标?
使用seq2seq + attention NMT system中的Encoder,即 2层 bi-LSTM ,作为上下文提供者,所得到的 CoVe 向量在各种任务上都优于 GloVe 向量,但是,结果并不像其他幻灯片中描述的更简单的NLM培训那么好,所以似乎被放弃了 ,也许NMT只是比语言建模更难?或许有一天这个想法会回来?

Peters et al. (2018): ELMo: Embeddings from Language Models

2018年提出的改进系统,word token vectors or contextual word vectors 的突破性版本
使用长上下文而不是上下文窗口学习 word token 向量(这里,整个句子可能更长)
学习深度Bi-NLM,并在预测中使用它的所有层,训练一个双向LM,目标是 performant 但LM不要太大,使用2个biLSTM层,仅使用字符CNN构建初始单词表示,2048 个 char n-gram filters 和 2 个 highway layers,512 维的 projection,4096 dim ,hidden/cell LSTM状态,使用 512 dim的对下一个输入的投影,使用残差连接,绑定 token 的输入和输出的参数(softmax),并将这些参数绑定到正向和反向LMs之间,ELMo学习biLM表示的特定任务组合,这是一个创新,TagLM 中仅仅使用堆叠LSTM的顶层,ELMo 认为BiLSTM所有层都是有用的

量ELMo对任务的总体有用性,是为特定任务学习的全局比例因子,是 softmax 归一化的混合模型权重,是 BiLSTM 的加权平均值的权重,对不同的任务是不同的,因为不同的任务对不同层的 BiLSTM 的

Peters et al. (2018): ELMo: Use with a task/ELMo:用于任务

首先运行 biLM 获取每个单词的表示,然后让(无论什么)最终任务模型使用它们,冻结ELMo的权重,用于监督模型,将ELMo权重连接到特定于任务的模型中,细节取决于任务。像 TagLM 一样连接到中间层是典型的,可以在生产输出时提供更多的表示,例如在问答系统中

序列标记中使用的ELMo

使用ELMo在命名实体识别中仅提高了3%,但是也是一种突破~

ELMo结果:适用于所有任务

这里这些任务都是用数据集来表示的,分布解释下哈~

SQuAD 是斯坦福大学于2016年推出的数据集,一个阅读理解数据集,给定一篇文章,准备相应问题,需要算法给出问题的答案

有点麻烦,直接来个整理比较全的,具体含义不理解的也可以去百度

1.CCG 超级标记
CCGBank
2.分块
Penn Treebank
3.选区解析
Penn Treebank
4.指代消歧
CoNLL 2012
5.依存解析
Penn Treebank
6.对话
第二对话状态追踪挑战赛
7.域适应
多领域情感数据集
8.语言建模
Penn Treebank
WikiText-2
9.机器翻译
WMT 2014 EN-DE
WMT 2014 EN-FR
10.多任务学习
GLUE
11.命名实体识别
CoNLL2003
12.自然语言推理
SNLI
MultiNLI
SciTail
13.词性标注
UD
WSJ
14.阅读理解
ARC
CNN/Daily Mail
QAngaroo
RACE
SQuAD
Story Cloze Test
Winograd Schema Challenge
15.语义文本相似性
SentEval
Quora Question Pairs
16.情感分析
IMDb
Sentihood
SST
Yelp
17.情感解析
WikiSQL
18.语义作用标记
OntoNotes
19.自动摘要
CNN/Daily Mail
20.文本分类
AG News
DBpedia
TREC

还有:ULMfit/面向文本分类的通用语言模型微调

Howard and Ruder (2018) Universal Language Model Fine-tuning for Text Classification. https://arxiv.org/pdf/1801.06146.pdf

传递NLM知识的总体思路相同,此处应用于文本分类(大概思路就是假设有一个10分类的、别公司或者实验室训练准确率非常高的模型,正好你要进行6分类,且该6类包含在之前的10类里面,你可以在别人的好的模型上进行微调,这里为什么不直接使用而是微调呢?首先,你可以用别人的模型直接完成自己的需要,但是可能会预测出不存在的4类,其实这个问题不大,因为预测出不存在的和预测错误是一样的;其次,你的数据集和别人的数据集肯定是不一样,就是可能存在风格问题,所以自己还是要进行微调,已适应自己数据集的风格的;机器视觉方面也有微调~也往往是分类~;分类中往往是加载别人的输出层和中间层(结构+参数),自定义输出层,然后微调参数/先微调输出层和中间层参数,再调整输出层)

ULMfit

  1. 在大型通用领域的无监督语料库上使用 biLM 训练/用大量不相关的文本训练LM
  2. 在目标任务数据上调整 LM/用相关数据微调LM
  3. 对特定任务将分类器进行微调/微调分类层

ULMfit重点

使用合理大小的“1gpu”语言模型并不是真的很大

在LM微调时小心很多东西
不同的每层学习率
学习分类器时逐步分层解冻和STLR
学习分类器时使用级联进行分类

ULMfit的性能

文本分类器错误率

ULMfit的迁移学习

(刚刚上述解释微调可能有点偏差,那个其实说其实是微调+迁移学习,迁移学习大概就是直接拿别人的模型来完成自己的任务,但是往往任务有差别,所以需要微调一下~强调的是迁移学习是直接拿别人的模型用,微调是迁移学习的基础上,针对自己的场景/任务进行微调;其实说到底就是拿别人的模型约等于自己有一个非常好的初始化参数,微调就类似我们在自己的训练集上训练~)

如果使用监督数据(蓝色线)进行训练文本分类器,需要大量的数据才能学习好(蓝色是自己训练,橙色是迁移学习,绿色是迁移学习+微调,但是不是很理解。。。迁移学习不是直接拿别人的用吗,还会再训练吗??疑惑~可能自己迁移学习和微调理解有点偏差~)

微调可以针对一个小数据集进行训练且取得很好的效果,例如1天GPU就可以;GRT模型当时训练的时候大概是240个GPU天;BERT训练时大概256个TPU天或者320-560个GPU天;GPT-2大概...2048TPU版本3天。可以看出来微调。。。很强的,不过前提是有别人好的模型。

TPU介绍:TPU尽可能的将确定的指令流程,编程固定的硬件电路。在保障响应时间的情况下,能够尽可能地提高能效比这个指标。也就是进行同样多数量的推断工作,花费的整体能源要显著低于 CPU 和 GPU。Google 在 TPU 的论文里面给出了具体的一些指标。在性能上,TPU 比现在的 CPU、GPU 在深度学习的推断任务上,要快 15~30 倍,而在能耗比上,更是好出 30~80 倍。目前Google 已经用 TPU 替换了自家数据中心里 95% 的推断任务,可谓是拿自己的实际业务做了一个证明。

GPT介绍:在自然语言处理问题中,可从互联网上下载大量无标注数据,而针对具体问题的有标注数据却非常少,GPT是一种半监督学习方法,它致力于用大量无标注数据让模型学习“常识”,以缓解标注信息不足的问题。

GPT-2语言模型(cherry picked)输出

生成的文本样例(该模型如果想具体了解,可以自己去搜搜相关资料)

(玩笑话:这个模型很强,所以他们不愿意把这个分享出来)

Transformer models

绿色部分为使用Transformer的模型,Transformer结构不仅强大,从技术上来说它运行扩大到更大的尺寸上(后面课程会邀请Transformer的作者之一来讲解一下,我只能说...??,这次简单描述一下,下次找刚刚说的大佬具体讲)

Transformers的动机

我们希望事情变化的更快,以便于我们能构建更复杂的模型,例如RNNs模型,必须生成1-n个状态,也就是无法并行运算/

现实中的需要是:我们想要并行化,但是RNNs本质上是顺序的

尽管有GRUs和LSTMs这些很好的门控结构,但是RNNs仍然需要注意机制来处理长期依赖关系——否则状态之间的 path length 路径长度会随着序列增长而增长,但如果注意力让我们进入任何一个状态……也许我们可以只用注意力而不需要RNN?这也就导致了Transformers结构的想法

 

Transformer概述

Attention is all you need. 2017. Aswani, Shazeer, Parmar, Uszkoreit, Jones, Gomez, Kaiser, Polosukhin https://arxiv.org/pdf/1706.03762.pdf

Non-recurrent sequence-to-sequence encoder-decoder model/非循环序列编解码模型
任务:平行语料库的机器翻译,预测每个翻译单词
最终成本/误差函数是 softmax 分类器基础上的标准交叉熵误差

Transformer基础

如果自学的话,推荐了很多资料

http://nlp.seas.harvard.edu/2018/04/03/attention.html 

TheAnnotatedTransformerbySashaRush

An Jupyter Notebook using PyTorch that explains everything!/一个Jupyter文件,用pytorch写的

现在:我们定义 Transformer 网络的基本构建块:首先是新的注意力层

Dot-Product Attention (Extending our previous def./扩展我们以前的定义)

输入:对于一个输出而言的查询 q 和一组键-值对 (k-v)
Query, keys, values, and output /查询、键、值和输出  都是向量
输出值是加权和
权重的每个值是由查询和相关键的内积计算结果
Query 和 keys 有相同维数 ,value 的维数为

通过一些线形注意力和一点点乘法注意力,前馈网络中添加一点注意力,Dot-Product Attention类似一种简单的注意力,公式中计算的其实就是q/查询和k/值的相似度,最后使用向量作为对应的值(*vi)

(下面这页ppt内容直接跳过去了)

Scaled Dot-Product Attention

人们发现了一个问题:变大时,的方差增大--->一些 softmax 中的值的方差将会变大--->softmax 得到的是峰值--->因此梯度变小了

解决方案:通过query/key向量的长度进行缩放

Self-attention in the encoder

第一个想法输入单词向量是queries, keys and values,换句话说:这个词向量自己选择彼此,我们会在系统的各个地方使用注意力,词向量堆栈= Q = K = V,我们会通过解码器明白为什么我们在定义中将他们分开

Multi-head attention

第二个想法:注意力很好,但是只有一种注意力时可能会比较糟糕,因为系统会按照某一种方式去处理事物(有些模型会比较好,有些会不好),因此对于不好的来说,人们引入了多头注意力机制,做法如下:

首先通过矩阵 W 将 Q, K, V 映射到 h = 8 的许多低维空间

然后应用注意力,然后连接输出,通过线性层即可

 

正是这种多头注意力的想法使得Transformer成为一个非常强大的框架(成功原因之一哦~)

Complete transformer block/完整的transformer模块

当一个词向量进来后,会被多层注意力给处理,其结构具体如下:(这也是我们可以在任何地方使用的最基本的transformer模块,可以通过折叠来开发完整的框架,但是没有免费的午餐,该结构可能使我们无法经常在序列中携带经常性的信息(这块不是很理解,但是大概意思就是想表达也有缺点),但是这个结构在GRU中非常有利,允许并行化计算)

每个 block 都有两个“子层”

  • 多头 attention
  • 两层的前馈神经网络,使用 ReLU

这两个子层都:残差连接以及层归一化,LayerNorm(x+Sublayer(x)),层归一化将输入转化为均值是 0,方差是 1 ,每一层和每一个训练点(并且添加了两个参数),如下:(层归一化其实就是层次归一化)

Layer Normalization by Ba, Kiros and Hinton, https://arxiv.org/pdf/1607.06450.pdf

Encoder Input/解码器的输入

实际的词表示是 byte-pair 编码,(貌似是一个消息,不知道具体实现没实现)还可以添加了一个 positional encoding 位置编码,相同的词语在不同的位置有不同的整体表征

Complete Encoder/完整的编码器结构

encoder 中,每个 block 都是来自前一层的 Q, K, V,其中Positional Encoding是人为输入的,Nx代表重叠的次数/N次
在每个阶段,你可以通过多头注意力看到句子中的各个地方(之前也解释过了单注意力的不好之处),如果Blocks 被重复 6 次(垂直方向),则会累积信息并将其推送到下一层。在任一方向上的序列逐步推送信息来计算感兴趣的值,非常善于学习语言结构的相关内容(有点疑问这个六次。。。),下面用具体的实例图来解释一下(选取的的第五层,可能上面那个模型老师的意思是6层)

不同的颜色对应不同的注意力头,上图可能不是很容易理解,下面看看代词的,在本模型中注意力头学会了如何找到其指代物,在第五层中,从 head 5 和 6 的单词“its”中分离出来的注意力。请注意,这个词的注意力是非常鲜明的。

 

Transformer Decoder

Transformer可以为我们提供完整的机器翻译神经网络模型(解码器和编码器都是Transformer造的),其他内容基本没讲,剩下的是ppt内容的翻译

decoder 中有两个稍加改变的子层
对之前生成的输出进行 Masked decoder self-attention

编码器-解码器注意,其中查询来自前一个解码器层,密钥和值来自编码器的输出

Encoder-Decoder Attention,queries 来自于前一个 decoder 层,keys 和 values 来自于 encoder 的输出
Blocks 同样重复 6 次

BERT: Devlin, Chang, Lee, Toutanova (2018)

BERT(来自变压器的双向编码器表示):深度双向变压器的语言理解预培训(根据Jacob Devlin的幻灯片)(目前来说最好的词向量?个人感觉是...但是还是存在疑问的~)

问题:语言模型只使用左上下文或右上下文,但语言理解是双向的
为什么LMs是单向的?
原因1:方向性对于生成格式良好的概率分布是有必要的,我们不在乎这个
原因2:双向编码器中单词可以“看到自己”,如下图:(第二层的接受的第一层信息中已经包含对于第二层来说未来的信息了)

解决方案:mask out/遮掩k%的输入单词,然后预测 masked words(类似随机挖掉k%个单词然后预测),不再是传统的计算生成句子的概率的语言模型,目标是填空,总是使用k=15%(因为如果k过大会导致把背景语义给破坏掉),样例如下所示:

Masking 太少:训练太昂贵(别人一次训练两三个,自己才训练一个);Masking 太多:没有足够的上下文/破坏上下文背景语义

GPT 是经典的单项的语言模型
ELMo 是双向的,但是两个模型是完全独立训练的,只是将输出连接在一起,并没有使用双向的 context
BERT 使用 mask 的方式进行整个上下文的预测,使用了双向的上下文信息

BERT complication: Next sentence prediction/BERT的并发症:下一个句子的预测

学习句子之间的关系,判断句子 B 是句子 A 的后一个句子还是一个随机的句子(大致意思就是BERT在上述的填空中有很好的效果,然后尝试第二个目标,也就是预测下一个句子的关系,然后发现也很不错)

BERT sentence pair encoding/BERT的成对句子编码

token embeddings是word pieces /单词片段,把学习好的的分段嵌入表示每个句子,位置嵌入与其他Transformer结构类似,将以上三种 embedding 相加,作为最终输入的表示(如上图红+黄+绿=白色 的过程)

BERT model architecture and training/BERT模型结构与训练

Transformer encoder(和之前的一样),自注意力--->没有位置偏差(应该是没人为引入位置信息的意思),长距离上下文“机会均等”,每层乘法?GPU / TPU上高效,在 Wikipedia + BookCorpus(两个语料库)上训练,训练两种模型尺寸:

  • BERT-Base: 12-layer, 768-hidden, 12-head
  • BERT-Large: 24-layer, 1024-hidden, 16-head

在4x4或8x8 TPU切片上训练4天,先训练填空(隐藏百分之15%的那种),再训练预测下一个句子(判断下一个句子是不是该句子的下一句话)

 BERT model fine tuning/BERT 模型微调

只需学习在顶层为我们微调的每个任务构建的分类器

 

我们可以把预训练的模型/Pre-training微调成MNLI/判断语言是否相近、NER命名实体识别、SQuAD/问答、自然语言推理等,我们要做的事情和ULMFit(之前说过这个的)相同的事情,不太一样的是我们要取消最顶层预测单词和下一个句子的部分,替换成我们特定任务的预测层,事实上他们已经这么做了,下面来看看他们的成果

BERT results on GLUE tasks

GLUE benchmark 是是以自然语言推理任务为主,同时也具有句子相似度和情感
任务:MultiNLI/自然语言推理
Premise: Hills and mountains are especially sanctified in Jainism.
Hypothesis: Jainism hates nature.
Label: Contradiction/矛盾
任务:CoLa/单句二分类,判断是非可以语法上接受
Sentence: The wagon rumbled down the road. Label: Acceptable
Sentence: The car honked down the road. 
Label: Unacceptable/不可以接受

其他的一些任务成果

总的来说,人们发现BERT继承的可以给出超强的效果来~

可以看出BERT Base比ELMo效果更好,而BERT Large效果则更好,不过也有一个打败BERT Large的模型,是Flair的Transformer模型,是一个字符级模型

在SQuAD上BERT也取得了很好的胜利,如下图所示

如果我们想训练一个很好的模型,可以考虑在好的预训练模型上进行微调,这个最早发生在视觉,人们微调ResNet模型,现在我们可以微调预先训练的BERT模型

这节课内容到此结束,后续内容有兴趣的可以看看ppt

 

 

  相关解决方案