美文网首页
BERT(二) BERT解读及应用

BERT(二) BERT解读及应用

作者: blackmanba_084b | 来源:发表于2021-03-26 17:25 被阅读0次

    前面已经说了transformer(BERT(一) Transformer原理理解)的模型以及具体结构中每一个component的作用,那么今天这一篇我将会总结BERT(Bidirectional Encoder Representations from Transformers)是如何利用transformer的结构进行自然语言处理的。关于BERT与transformer的关系大家要能理解.\color{red}{其实BERT就tramsformer中decoder的部分, 简单的理解就是输入一句话,该模型吐出字的embedding, 其目的也是如何训练得到embedding}, 这里的embedding其实就是我们encoder输出的隐藏层,其shape是[batch_size, length, embedding_size], 后面的自然语言处理任务则是根据这个embedding的特征编码进行任务处理,如回归分类等。

    \color{red}{我们在训练BERT的过程的过程也是一个无监督的模型},但是我们可以利用BERT可以做很多自然语言处理的很多事情。这里我将会通过两个方向来解释BERT,分别是:
    【1】 如何训练我们的BERT模型
    【2】如何利用我们的BERT模型进行自然语言处理任务

    一、 训练BERT模型

    1、 训练方法一: 使用MLM(Masked Language Model)方法


    比如上面的一句话 今天 [mask] 玩 DOTA,我们不知道这里的 [mask]究竟指代的是什么,有可能指代的是咱们,有可能是你们,我们希望我们的模型去预测这里的mask, 从图中可以很明显的看出我们在输出embedding乘上[embedding_size, 单词数量]的矩阵,再经过一个softmax就可以预测出该字是什么。

    如果还是有点迷惑,那我们继续往下面去看。

    就是随机遮盖或替换一句话里面任意字或词, 然后让模型通过上下文的理解预测那一个被遮盖或替换的部分, 之后Loss的时候只计算被遮盖部分的Loss** , 其实是一个很容易理解的任务。

    论文中是这样说的我们在输入这句话的时候需要将一句话中15%的 单词进行mask,也就是说不仅仅是这一个 mask,当然在这15%的mask中对于mask的编码有三种方式:
    【1】 80%直接将mask统一编码成unknow的编码形式作为模型输入,然后去预测该输出emdedding的单词
    【2】10%直接将mask替换成其他的单词编码输入,比如说"小狗",让模型预测其对应的embedding的输出
    【3】10%保持不变的方式直接输入到模型中去
    这里摘用论文的demo

    Masked LM and the Masking Procedure Assuming the unlabeled sentence is my dog is
    hairy, and during the random masking procedure
    we chose the 4-th token (which corresponding to
    hairy), our masking procedure can be further illustrated by

    • 80% of the time: Replace the word with the [MASK] token, e.g., my dog is hairy → my dog is [MASK]

    • 10% of the time: Replace the word with a random word, e.g., my dog is hairy → my dog is apple

    • 10% of the time: Keep the word unchanged, e.g., my dog is hairy → my dog is hairy. The purpose of this is to bias the representation towards the actual observed word.

    这里我简要说明一下具体矩阵是怎么计算的。首先在我们进行mask机制之后,让模型预测和还原呗遮盖或替换掉的部分,模型最终输出的隐藏层的计算结果的维度是:
    \color{red}{X_{hidden}: [batch_size, sequence_len, embedding_dim]}
    我们初始化一个映射层的权重W_{vocab}
    \color{red}{W_{vocab}:[embedding_{dim}, vocab_{size}]}
    这里的vocab就是字典中字的数量,简单理解就是字典one-hot编码。我们在用W_{vocab}完成隐藏维度到子向量数量的映射,只要求X_{hidden}W_{vocab}的矩阵进行矩阵乘法(点积)。这样我们就进行如下计算
    \color{red}{X_{hidden}W_{vocab}:[batch_{size}, seq_{len}, vocab_{size}]}
    之后把上面的计算结果在vocab_{size}(最后一个维度)做softmax,是每个字对应的vocab_size的和为1, 我们就可以通过vocab_{size}里概率最大的字来得到模型的预测结果,就可以和我们准备好的Label做损失并反传梯度。注意在损失的时候,值计算句子中随机遮盖或替换的部分,其余部分不做损失,对于其他部分,模型输出什么东西,我们并不在意。

    这里这么用的好处总结如下:
    1、首先, 如果所有参与训练的token被100%的[MASK], 那么在fine-tunning的时候所有单词都是已知的, 不存在[MASK], 那么模型就只能根据其他token的信息和语序结构来预测当前词, 而无法利用到这个词本身的信息, 因为它们从未出现在训练过程中, 等于模型从未接触到它们的信息, 等于整个语义空间损失了部分信息. 采用80%的概率下应用[MASK], 既可以让模型去学着预测这些单词, 又以20%的概率保留了语义信息展示给模型。

    2、保留下来的信息如果全部使用原始token, 那么模型在预训练的时候可能会偷懒, 直接照抄当前token信息. 采用10%概率下random token来随机替换当前token, 会让模型不能去死记硬背当前的token, 而去尽力学习单词周边的语义表达和远距离的信息依赖, 尝试建模完整的语言信息.

    3、最后再以10%的概率保留原始的token, 意义就是保留语言本来的面貌, 让信息不至于完全被遮掩, 使得模型可以"看清"真实的语言面貌。

    2、 训练方法二: NSP(Next Sentence Prediction)方法

    首先我们拿到属于上下文的一对句子, 也就是两个句子, 之后我们要在这两段连续的句子里面加token
    \color{red}{[cls]上一话[sep]下一句话[sep]},也就是在句子开头加一个[cls], 在两句话这之中和句子的末尾加[sep], 具体如下图所示。

    1. 我们看到上图中两句话是[cls] my dog is cute [sep] he likes playing [sep], [cls]我的狗很可爱[sep]他喜欢玩耍[sep], 除此之外, 我们还要准备同样格式的两句话, 但他们不属于上下文关系的情况;
      [cls]我的狗很可爱[sep]企鹅不擅长飞行[sep], 可见这属于上下句不属于上下文关系的情况; 在实际的训练中, 我们让上面两种情况出现的比例为1:1, 也就是一半的时间输出的文本属于上下文关系, 一半时间不是.
    2. 我们进行完上述步骤之后, 还要随机初始化一个可训练的segment \ embeddings, 见上图中, 作用就是用embeddings的信息让模型分开上下句, 我们一把给上句全0token, 下句啊全1token, 让模型得以判断上下句的起止位置, 例如:
      [cls]我的狗很可爱[sep]企鹅不擅长飞行[sep]
      0 \quad \ 0 \ \ 0 \ \ 0 \ \ 0 \ \ 0 \ \ 0 \ \ 0 \ \ \ 1 \ \ 1 \ \ 1 \ \ 1 \ \ 1 \ \ 1 \ \ 1 \ \ 1
      上面01就是segment \ embeddings.
    3. 还记得我们上节课说过的, 注意力机制就是, 让每句话中的每一个字对应的那一条向量里, 都融入这句话所有字的信息, 那么我们在最终隐藏层的计算结果里, 只要取出[cls]token所对应的一条向量, 里面就含有整个句子的信息, 因为我们期望这个句子里面所有信息都会往[cls]token所对应的一条向量里汇总:
      模型最终输出的隐藏层的计算结果的维度是:
      我们X_{hidden}: [batch\_size, \ seq\_len, \ embedding\_dim]
      我们要取出[cls]token所对应的一条向量, [cls]对应着\ seq\_len维度的第0条:
      cls\_vector = X_{hidden}[:, \ 0, \ :]
      cls\_vector \in \mathbb{R}^{batch\_size, \ embedding\_dim}
      之后我们再初始化一个权重, 完成从embedding\_dim维度到1的映射, 也就是逻辑回归, 之后用sigmoid函数激活, 就得到了而分类问题的推断。

    二、 如何使用BERT模型

    1. 实例1

    Case1

    预测出输出的分类,输出句子分类,比如在情感分类我们就可以使用这种BERT模型案例。Linear Classifier是随机初始化的,但是在训练的时候可以让Linear Classifier调节, BERT进行微调就好。

    2. 实例2

    Case2

    这里就需要去得到每个词汇是什么词类型,只要我们得出词的embedding, 然后在接上分类网络,我们就可以得出每个词的词类型。

    3. 实例3

    Case3

    这里我们输入两个句子输出是表示根据第一句的假设,第二个是进行表示是否第二个句子可以根据第二个句子可以判断。如果可以就是True, 不可以就是False, 不知道就是Unknow。也就是我们之前说的 NSP(Next Sentence Prediction)类型很相似,预测两个句子的关联程度。

    4. 实例4

    Case4

    第四个案例其实就是为了解决QA 问题,但是此QA问题中的answer的前提条件就是能在文章中找到。如图中的橘色的weight就是预测出answer start position, 而图中蓝色的weight就是为了预测出answer的end position,后面可以接一个softmax进行分类,这样我们可以得到概率醉大的位置索引。我们就可以根据start position 以及end position的索引得到文章中的索引,但是如果start position小于end position我们可以理解中文章没有结果。

    三、 额外补充

    3.1 ERNIE

    ERNIE

    ERNIE模型是专门针对中文的进行的语言模型,考虑的维度不仅仅是字的维度而是单词的维度。

    3.2 BERT不同层所表示的意义


    通过上图我们可以看到随着NLP任务难度的加深,BERT越深层的权重越高(重要性),越简单的任务,BERT越浅层的权重越小。(浅层和文本有关,深层和语义有关)

    哈哈~ 终于说完了BERT,这里我会提供一个基于BERT进行情感分类的代码,这里的代码有很多注释,可以方便去学习。
    code 地址:Semantic Analysis(Pytorch)

    参考

    1. 唐宇迪 Bert教程
    2. 李宏毅 Bert教程
    3. 汉语自然语言处理-BERT的解读语言模型预训练
    4. The Illustrated Transformer【译】
    5. 【NLP】Transformer模型原理详解
    6. BERT的MLM任务中为什么采用了80%, 10%, 10%的策略?

    相关文章

      网友评论

          本文标题:BERT(二) BERT解读及应用

          本文链接:https://www.haomeiwen.com/subject/coxrhltx.html