站在巨人的锁骨上,BERT模型的理解

在BERT出现前,有很多人已经根据自己的假设完成了NLP的相关任务,BERT的出现也不是凭空出现的,现在从三个方面来谈一下我理解下的BERT

一.BERT的简介

二.BERT的“刀刃”

三.为什么被叫做预训练模型

第一点:BERT的简介

BERT全称Bidirectional Encoder Representation from Transformers,从命名上我们就能知道他依托的是Transformer架构,并且在文本的处理上采用的是双向文本的向量化,这两个概念一形成我们就抓住了他的重点,而另一个问题就是为什么,为什么他选择这样做,下面是我们看一下Transformer架构:

Transformer的模型讲解出自论文《Attention is All You Need》:https://arxiv.org/abs/1706.03762

原文中所展示的模型结构(Figure 1)乍一看特别的复杂,但是仔细看后发现大多步骤都是重复的,在这里我们只用重点关注以下两点:

1.mask

2.Multi-Head Attention

当然我们不是说其他地方不重要,但是可以说,这两个步骤是BERT发挥强大本领的“刀刃”。

第二点:BERT的“刀刃” 

1)首先解释下mask机制:

对比CNN、RNN、LSTM等经典模型的做法,我们发现他们常常会将关注点放在字或者词语上,就比如“我在实验室不如回家陪女朋友打游戏”这句话,经典模型往往认为文本本身就是一条“长虫”,要么抓住他的头往后缕,要么抓他的尾巴,再或者打蛇打七寸,抓住关键词“女朋友”一顿“胡思乱想”。当然也有人说小孩才做选择题,我全部都要。

这是没问题的,理论上只要公式足够复杂,这句话是能够被计算机理解的,但是有一个问题摆在这里,对于这句话所给出的信息,我们怎么处理才合适呢。

举一个不贴切的例子:我在实验室做实验,跟朋友抱怨中说了这句话,刚好这时候导师悄无声息的飘到我的附近,听到这句话...不言而喻。

所以我们能够发现对于文本而言,女朋友,啊呸!人类对于文本的理解一定程度上都结合了不同的语境。

严格来说,文本的理解受到语序和上下文的影响。

那BERT是怎么来解决这个事的,首先拿到一个无标注文本,BERT就对他进行随机的遮盖【mask】,然后结合上下文,对文本进行还原,还是以上面那句话为例,如果MASK“女朋友”这个词,按照人类的理解进行完形填空,根据前文的回家,这个mask部分就可能为:父母、狗、猫、男朋友、兄弟、长辈等等,联系后面的打游戏一词,范围开始缩小,最终会对他进行补全。

mask机制在学术上我们缩写为MLM(masked language model),而这个模型能做到的就是通过随机遮盖词语的方式,将词与文本之间建立更好的联系,使词语更专注于这句话本身。

那么我们又想到一个问题,我们怎么让计算机知道这句话的开头呢

BERT模型在进行海量无标注文本训练的时候,对于每个序列的第一个标记总是给予一个特殊的分类标记【CLS】。使用此标记会使分类器在聚合序列时区分出每个句子的开头。之后句子将被打包成一个单一的序列。

说到这里我们发现这个做法特别像BiLstm模型所做的事情,与之不同的就是加了个无所谓的“【CLS】”标签,为什么mask也要做,【CLS】也要做,是不是有点像在文本上不断剪开口子,又要给每个句子印上“logo”,这个统一的“logo”的用处在哪里呢?

2)引入了NSP机制:

在这里,BERT又做了一件事,将前后文看做一个句子对,用一个特殊的标记【SEP】将它们分开。其次,我们添加一个嵌入以表示它是属于句子A还是属于句子B的标记,具体如下图:

这是BERT做的另一个事情,通过句子与句子搭配的方式,以学习到句子之间的联系,是不是有点像问答对,又有点像我们英语考试的句子关系排序预测。

那做完这些所得到的词向量是否就是好的呢?当然不是,相比于传统的词向量训练方法,无非就是采用了自编码的方式训练海量无标注数据,真正让BERT模型获得更强大的动态词向量的是后面的Multi-Head Attention机制

3)Multi-Head Attention

这个Multi-Head Attention一句话概括就是:Attention使用了“多重影分身”

文本中每个词对于结果的影响是不同的,可以认为他们应当被赋予不同的权重,这种权重也可以称为Attention

这里的Attention机制采用的是Self-Attention,所做的就是计算每个字与句内所有字之间的关联,加强了全局特征的提取。Self-Attention的公式比较乱:

 

 我的理解是:

每个字、词在向量化后本身都有一个原始的向量,根据语境的不同,字、词所表达的含义不一样,也可以这样说:隔行如隔山,要想得到最终理想的结果,我们认为最终的结果与原始向量是有联系的,而联系就在这句话里的每一个字。

公式中,Q代表的是查询向量,K代表的是键向量,V代表的就是文本中的值向量;如果要得到一个好的结果,那么“老师”和“同学”就是通向成功的钥匙,所谓的“老师”就像这里的Q,“同学”就是你身边的K,Self-Attention使用Q和K对你产生影响,告诉你方向,不断的影响你,最终你成为了你认为的想要的样子。

也不知道解释清楚没有,我尽力了。

回到公式中,这里我们又注意到,Q、K下有一个dk,这个dk代表的是向量的维度,在这里我的理解呢就是,我们一生中形形色色的Q、K,他们对我这个V产生了影响,但是如果这个影响过大的话,可能会让我变的不像从前。

说着说着有点像“不忘初心,方得始终”了。

前面也说过,BERT模型采用的是海量的无标注的文本,那么我们在预测一个字、词的时候,其难度可想而知,由于文本本身具有的稀疏性与高维性,为了不遗失原来句子中某些字对句子的影响,更好的做到站在全局中考虑句子,我们就考虑除以一个标度,这个标度就是Q、K下的dk。

概括了Self-Attention,下面就说一下Multi-Head

这个就简单多了,就拿NLP经典案例举例:“长江市长江大桥。”,这句话可以被理解成“长江市/长江大桥”和“长江市长/江大桥”,多头机制就是将各种情况都独立的输入模型,供机器学习。

Multi-Head机制是多个独立的Attention计算,以学习到一句话中丰富的语意。目的在于防止过拟合。下面是Multi-Head Attention的一个过程,大家可以参考一下。

#多头机制
def transpose_for_scores(x, attention_head_size, num_attention_heads):
    max_len, hidden_size = x.shape
    x = x.reshape(max_len, num_attention_heads, attention_head_size)
    x = x.swapaxes(1, 0) 
    attention_head_size]
    return x

#self attention的计算
def self_attention(q_w,
                   q_b,
                   k_w,
                   k_b,
                   v_w,
                   v_b,
                   attention_output_weight,
                   attention_output_bias,
                   num_attention_heads,
                   hidden_size,
                   x):
    q = np.dot(x, q_w.T) + q_b  
    k = np.dot(x, k_w.T) + k_b  
    v = np.dot(x, v_w.T) + v_b  
    attention_head_size = int(hidden_size / num_attention_heads)
    q = transpose_for_scores(q, attention_head_size, num_attention_heads)
    k = transpose_for_scores(k, attention_head_size, num_attention_heads)
    v = transpose_for_scores(v, attention_head_size, num_attention_heads)
    qk = np.matmul(q, k.swapaxes(1, 2))
    qk /= np.sqrt(attention_head_size)
    qk = softmax(qk)
    qkv = np.matmul(qk, v)
    qkv = qkv.swapaxes(0, 1).reshape(-1, hidden_size)
    attention = np.dot(qkv, attention_output_weight.T) + attention_output_bias
    return attention

文章的最后就来讲一下我认为的,为什么说被叫做预训练模型

第三点:为什么被叫做预训练模型

以往的自然语言处理领域,都使用的是人工标注数据,当时大多数人认为根据任务的不同,我让计算机直接将文本向量化后根据我设计的数据,最终一定能获得好的效果,但是这样做,明显存在以下问题:

1.人工标注数据耗费了大量的人力和时间,而且人工标注还会出现错误,这些错误从一开始就影响着结果:并且根据任务的不同,我们的标注方法也不会相同,“我在实验室不如回家陪女朋友打游戏”,有人希望知道我现在在哪里,有人想知道我接下来想去干嘛,有人又想知道我对学习是否感兴趣,根据这不同的出发点,我们如果每次都人为的处理一遍数据,简直就是在不断的重复。

2.数据量有限:面对一个领域或者一个具体的问题,无论我们人工标注的再多,总会觉得什么叫多,什么又叫少。

3.训练的词向量还是相对静态的:在有限的时间和资源的基础上,训练出的词向量,是不能够表示一种语言的所有特性的

综上所述,BERT能利用到无标注的数据,理论上我们拥有的是无限的数据,那么训练出来的词向量理论上就是一个动态的,当我们在下游具体任务的时候,耗费一点时间标注出一定量的数据对BERT的词向量再进行一个微调,那岂不是美哉。

这就是我理解的BERT预训练模型

最后解释下,之所以叫这个题目呢,也是现在我的理解,是不断的查资料,看视频,站在大佬的肩膀上的看到的风景,如有哪里不对的,欢迎大家指正!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

理想程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值