系列文章目录
文章目录
NLP里的迁移学习
- 之前是使用预训练好的模型来抽取词、句子的特征,例如 word2vec 或语言模型这种非深度学习的模型
- 一般抽完特征后,在做迁移学习时不更新预训练好的模型
- 迁移学习前做好的工作所抽取的特征是个比较底层的特征,一般当作embedding用,做自己的工作时需要构建新的网络来抓取新任务需要的信息。之前的工作,比如Word2vec忽略了时序信息,语言模型只看了一个方向,RNN不好处理特别长的序列,所以他也就看了很短的一段东西而已。
Bert的动机
想研发相似于CV方面的,基于微调的NLP模型,除了输出层,其他层的参数我是可以复用的,我可以挪到其他任务中去。
预训练的模型抽取了足够多的信息
新的任务只需要增加一个简单的输出层
Bert架构
Bert从结构上来讲就是一个只保留了编码器的Transformer,创新很简单,后面在输入和 L o s s Loss Loss上还有创新。
两个版本:
- Base:#blocks=12,hidden size=768,#heads = 12
#parameters=110M 参数相比较Transformer大很多,模型深很多。 - Large:#blocks=24, hidden size= 1024,#heads = 16
#parameter=340M
在大规模数据上训练>3B 词
对输入的修改
之前Transformer是比如说把一个句子和他的翻译当作数据和标签进行训练,在encoder中放入数据,decoder中放入标签。现在bert只有encoder,怎么办?
这个<CLS>用来表示句子开头,<sep>表示这个句子结束,后面是下一个句子,所以可以输入多个句子。但只是这样对Transformer不太好区分哪几个词是一个句子,所以加了Segment Embeddings,通过不同标志来标记句子。最上面是一个可以学的Position Embedddings。
预训练任务
1、带掩码的语言模型
Transfomer的编码器是双向,标准语言模型要求单向 。Transformer 的编码器是双向的:在 Transformer 架构中,编码器能够同时考虑输入序列中所有单词的上下文信息。这意味着在处理某个单词时,编码器不仅依赖于该单词之前的单词,还考虑之后的单词,从而获得更全面的语义理解。标准语言模型要求单向:传统的语言模型(如 n-gram 模型或某些 RNN 模型)通常是单向的,意味着在预测当前单词时,只考虑该单词之前的单词(即左侧上下文)。这种限制使得模型无法利用当前单词之后的上下文信息。总结:整体而言,这句话强调了 Transformer 编码器的双向特性与传统语言模型的单向特性之间的区别。双向编码器能够更全面地理解上下文,而单向模型则局限于仅考虑过去的信息。
之前在Transfomer中Decoder是单向的,但是bert只用了Transfomer的Encoder,所以我要做出下面的改变才可以学习数据的特征。
带掩码的语言模型每次随机(15%概率)将一些词元换成<mask> ,然后来预测这个mask到底是谁,我现在就是做完形填空,所以可以看双向的信息。但这样会有一个问题,在bert训练时候可以通过<mask>来学习,但是在下游任务微调的时候,也就是fine-tuning时候,数据中没有<mask>这个东西,所以有了下面的东西。
因为微调任务中不出现<mask>:(1)80%概率下,将选中的词元变成<mask>。(2)10%概率下换成一个随机词元。(3)10%概率下保持原有的词元。 我在训练的时候,我让bert模型不会看到mask就预测,当我选择一个词要遮住的时候,我不会每个都变成<mask>。这是在微调任务中使用掩蔽语言模型(Masked Language Model,MLM)时对输入文本进行处理的策略。具体来说:
- 80% 概率下将选中的词元变成
<mask>
:- 这是主要的掩蔽策略。通过将大部分选中的词元替换为
<mask>
,模型被迫学习如何根据上下文来预测被掩蔽的词。这种方式有助于模型学习到更丰富的上下文信息和语义关系。
- 这是主要的掩蔽策略。通过将大部分选中的词元替换为
- 10% 概率下换成一个随机词元 :
- 这种策略的目的是增加模型的鲁棒性。通过引入随机性,模型不能仅仅依赖于掩蔽信息来进行预测,而是需要学习更广泛的上下文关联。这有助于防止模型过拟合于特定的掩蔽模式。
- 10% 概率下保持原有的词元 :
- 这种做法允许模型在某些情况下看到原始的词元,从而保持一定的上下文完整性。这有助于模型理解词元在句子中的实际用法,进一步提升其预测能力。
总结:这种掩蔽策略通过结合掩蔽、随机替换和保留原词元的方式,促使模型在训练过程中获得更全面的上下文理解能力,从而提高其在微调任务中的表现。
2、下一句子预测
预测一个句子对中两个句子是不是相邻。
训练样本中:
50%概率选择相邻句子对:this movieis great<sep>i like it<sep>
50%概率选择随机句子对:this movie is great<sep>hello world <sep>
将对应的输出放到一个全连接层来预测。
为什么是<cls>?在这种上下文中,使用 <cls>
是为了实现句子对分类任务。具体原因如下:
- 句子对分类 :
<cls>
是一个特殊的标记,用于表示整个输入序列的开始。在 BERT 等 Transformer 模型中,通常将其放在输入的最前面,用于聚合整个序列的信息,以便进行分类任务。
- 信息聚合 :
- 通过将
<cls>
作为输入的起始标记,模型能够在编码过程中综合考虑整个句子对的上下文信息。最终,模型会生成一个对应于<cls>
的输出向量,这个向量包含了对整个句子对的理解。
- 通过将
- 全连接层预测 :
- 将
<cls>
对应的输出向量传递到全连接层,可以用来进行二分类(即判断两个句子是否相邻)。全连接层会基于这个向量输出一个概率值,表示句子对是相邻的可能性。
总结 :因此,使用<cls>
是为了便于模型在句子对分类任务中有效地聚合信息,并通过全连接层进行预测。这种设计符合 BERT 等模型的架构和训练策略。
- 将
总结
BERT针对微调设计。基于Transformer的编码器做了如下修改
(1)模型更大,训练数据更多
(2)输入句子对,片段嵌入,可学习的位置编码
(3)训练时使用两个任务:带掩码的语言模型、下一个句子预测
后面针对模型实现、预训练数据怎么形成、怎么训练三部分进行代码讲解。