代码编织梦想

目录

1 BERT VS Transformer

1.1 图示

1.2 输入

1.3 模型

1.4 任务

1.4.1 BERT 预训练

1.5 附录待续


论文发布于2019 

1 BERT VS Transformer

1.1 图示

Transformer

BERT

 

1.2 输入

Transformer: 位置 encoder + token embedding,在训练的时候 Transformer 有两个输入部分(对应于论文中的 源语言输入 和 目标语言输入)这两个输入是一起全部输入给模型的,预测的时候,源语言 的输入也是一下子给到模型,但是目标语言是一个一个给到的(自回归)。

BERT:位置 embedding + token embedding + segment embedding 。其中 segment embedding 是因为 BERT 预训练有两个任务,其中有一个是预测后一个句子是否是前一个句子的下一句,这边 segment embedding 就是用来区分两个句子的 ,句子对之间放置一个 [SEP] 的 token 也是用来区分两个句子的。[CLS] 这个 token 的作用是为了我们可以用该 token 对应的一层输出来做分类任务(可以理解为该 token 对应的一层输出融合了整句话的表达)。位置 embedding 对应 Transformer 中的 位置 encoder 。

BERT 的输入可以是一个句子(此时的 segment Embedding均是一样的,如图中的 E_{A} ),也可以是句子对 (此时的 segment Embedding 是两种,如图中的 E_{A}, E_{B} )。关于输入的 token 无论是与训练阶段还是 fine-tuning 阶段,句子开始要放置一个 [CLS] ,句子末尾要放置一个 [SEP],若是句子对,句子之间放置一个 [SEP] 。

  • 数据
    • 预训练,无标签的数据集,BooksCorpus (800M words,8亿个单词)和 English Wikipedia (2,500M words , 25亿个单词,仅保留长文本,忽略 标题、表格、列表等,因为想要抽取连续的长文本信息)
    • 下游任务,利用下游任务的数据(带标签)来 fine-tuning 【由预训练初始化的】 参数。

1.3 模型

Transformer:编码器 + 解码器架构,其中编码器是由6个相同的 Encoder 块组成的,解码器也是由6个相同的 Decoder 块组成的。

BERT:仅有 Transformer 中的 Encoder 块堆叠而成,不过诸如 堆叠的块数、隐藏层的单元数等超参不同,BERT的参数量更大。

参数量,L - Encoder 块的数目,H - embedding 的维度,A - multi-head 的个数。

  • {BERT}_{BASE} , L = 12, H = 768,A = 12,共计 110M 约1.1亿个参数
  • {BERT}_{LARGE} ,  L = 24, H = 1024,A = 16,共计 340M 约3.4亿个参数

1.4 任务

Transformer : sequence to sequence ,原论文中主体部分是用于机器翻译,也可推广到其它序列到序列的任务,或用于其他场景的一个模块。

BERT:分为 预训练 和 用作下游任务 两个部分,用作下游任务的使用姿势多种多样,预训练好的BERT的参数作为下游任务该模块的参数的初始化,例如用最后一个 Encoder 块的输出、最后一个块的 #CLS# 的输出 或 多个 Encoder 块的输出 等后续接其它网络结构,例如情感分析,我们可以仅使用最后一个块的 #CLS# 的输出接一个全连接层,再接一个 sigmoid 激活函数。

1.4.1 BERT 预训练

Masked LM ( MLM ) 任务,以往的 NLP 场景多是用 conditional 语言模型,但是 BERT 使用的是 self-attention ,且是 编码器 部分的 self-attention ,即经过 L 个 Encoder 块后,我们所有的隐藏层都能看见 该位置对应的输入 token 前面、后面甚至该 token 本身的信息。所以此处用的是 MLM 任务,即 随机的 masked 掉部分的输入token ,然后损失函数也仅考虑被 masked 掉的 token 对应的输出和 label ( 该处若不被 masked 掉的原始值) 的交叉熵损失。

注1:损失函数也仅考虑被 masked 掉那部分的交叉熵损失,真正在实现的时候,我们可以将所有输出均映射到字典长度空间,再过 softmax ,然后一起来算损失,不过我们会在输入的时候做处理,其实编码器也是可以用来做 seq2seq 的,即它们的输入和输出在序列长度这个维度不会发生变化,则我们可以在做 label 的时候给没有被 masked 掉的那些 token 对应的 label 赋一个特殊的 token ,此处我们假设该特殊 token 对应的索引为 0 ,我们只要在计算损失的时候跳过 索引 为 0 的那部分 label 即可。

class BertForPreTraining(BertPreTrainedModel):
    def __init__(self, config):
        super(BertForPreTraining, self).__init__(config)
        self.bert = BertModel(config)
        self.cls = BertPreTrainingHeads(config,                 
             self.bert.embeddings.word_embeddings.weight)
        self.apply(self.init_bert_weights)
        self.vocab_size = config.vocab_size
        self.next_loss_func = CrossEntropyLoss()
        self.mlm_loss_func = CrossEntropyLoss(ignore_index=0)
    def forward(self, input_ids, positional_enc, token_type_ids=None,
                attention_mask=None, masked_lm_labels=None, next_sentence_label=None):
        sequence_output, pooled_output = self.bert(input_ids, positional_enc, 
             token_type_ids, attention_mask,output_all_encoded_layers=False)
        # 全都送进loss,然后在loss中实现只计算被masked掉的那部分的逻辑
        # sequence_output: 预训练是最后一个 encoder 块的输出
        # pooled_output:pooled_output为隐藏层中[CLS]对应的token的一条向量
        mlm_preds, next_sen_preds = self.cls(sequence_output, pooled_output)
        return mlm_preds, next_sen_preds

    def compute_loss(self, predictions, labels, num_class=2, ignore_index=-100):
        # 这边调用的时候ignore_index 传0即可
        loss_func = CrossEntropyLoss(ignore_index=ignore_index)
        return loss_func(predictions.view(-1, num_class), labels.view(-1))

class BertPreTrainingHeads(nn.Module):
    """
    BERT的训练中通过隐藏层输出Masked LM的预测和Next Sentence的预测
    """
    def __init__(self, config, bert_model_embedding_weights):
        super(BertPreTrainingHeads, self).__init__()
        # 把transformer block输出的[batch_size, seq_len, embed_dim]
        # 映射为[batch_size, seq_len, vocab_size]
        # 用来进行MaskedLM的预测
        self.predictions = BertLMPredictionHead(config, bert_model_embedding_weights)
        # 用来把pooled_output也就是对应#CLS#的那一条向量映射为2分类
        # 用来进行Next Sentence的预测
        self.seq_relationship = nn.Linear(config.hidden_size, 2)

    def forward(self, sequence_output, pooled_output):
        # 预训练只取最后一层
        prediction_scores = self.predictions(sequence_output)
        seq_relationship_score = self.seq_relationship(pooled_output)
        return prediction_scores, seq_relationship_score

注2: 随机 masked 掉15%的 token ,若仅仅将 masked 的 token 替换为 [MASK] ,则会造成预训练和 fine-tuning 的不匹配,因为下游任务中不出现 [MASK] 。所以随机 masked 的过程为

  • 先对每个 token 以15%的概率进行 masked ,若该 token 未被 masked ,则不参与最终的损失计算,我们通过将其 label 的 index 设置为0,并在调用交叉熵损失的时候给 ignore_index 传0来实现。一旦一个 token 被选中,则该 token 参与损失计算,将对应的 label 设置为该token ,则该输入 token 如下:
    • 以80%的概率将该 token 替换为 [MASK]
    • 以10%的概率随机选择一个 token
    • 剩下10%的概率维持原样

我们的目的是还原被 masked 掉的 token ,至于为啥还有10%的几率不变,因为不这么做的话,意味着模型的输出应该永远不等于输入,这是不对的。

def random_char(self, sentence):
    char_tokens_ = list(sentence)
    # 拿到句子文本的索引表示
    char_tokens = self.tokenize_char(char_tokens_)

    output_label = []
    for i, token in enumerate(char_tokens):
        prob = random.random()
        # 30% 的概率进行选中该token进行 MLM,需要计算loss
        if prob < 0.30:
            prob /= 0.30
            # 被选中,则需要计算loss
            output_label.append(char_tokens[i])
            # 80% randomly change token to mask token
            if prob < 0.8:
                # 选中该token的情况下,80%的概率输入进行masked
                char_tokens[i] = self.mask_index
            # 10% randomly change token to random token
            elif prob < 0.9:
                # 选中该token的情况下,10%的概率随机选择一个token做输入
                char_tokens[i] = random.randrange(len(self.word2idx))
            # else:
                # 选中该token的情况下,10%的概率输入不变,这一块无需写出来
            #     char_tokens[i] = char_tokens[i]
        else:  # 70%的概率不选中该token进行MLM,所以无须计算loss
            output_label.append(0)
    return char_tokens, output_label

Next Sentence Prediction( NSP )任务。很多下游任务需要理解句子之间的关系,但是这种关系无法被语言模型捕获。为了建模这种关系,预训练了一个二分类任务,预测句子对中后面一句是否是前面一句的下一句。训练数据,以50%的概率将句子 A 的下一句作为句子 B , label 是 IsNext ;剩下的50%的概率从语料库中随机选择一句作为句子 B , label 是 NotNext 。论文里证明了该任务的添加有助于 QA 【问答(Question answer, QA),它可以近似为排名候选答案的句子或短语,基于其相似性的原始问题(Yang et al., 2015)】任务 和 NLI 【自然语言推理(NLI),也被称为识别文本蕴涵(RTE),它关注一个假设是否可以从一个前提中推断出来,需要理解假设和前提之间的语义相似性(Dagan et al., 2006;Bowman等人,2015)】任务。

1.5 附录待续

参考:

https://arxiv.org/pdf/1810.04805.pdf

GitHub - aespresso/a_journey_into_math_of_ml: 汉语自然语言处理视频教程-开源学习资料

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_xuanshuang/article/details/127346260

阅读笔记:bert: pre-training of deep bidirectional transformers for language understanding-爱代码爱编程

简介 转自:https://baijiahao.baidu.com/s?id=1619193829009842342&wfr=spider&for=pc google AI 团队发布,被NLP业内公认为里程

《BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding》-爱代码爱编程

目录 《BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding》1、Bert研究意义2、摘要3、Bert衍生模型以及Elmo、GPT、Bert对比3.1 RoBERTa3.2 ALBERT3.3 其它3.4 ELMO、GPT、BERT比较4、Mo

BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding-爱代码爱编程

Bert历史意义: 1、获取了left-to-right和right-to-left的上下文信息 2、nlp领域正式开始pretraining+finetuning的模型训练方式 nlp领域(各个下游任务都有自身的模型) -------2018(Bert) --------nlp领域(各个下游任务统一使用Bert模型)   Bert衍生模型 衍

BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 论文解读-爱代码爱编程

BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding 1. BERT模型1.1 Pre-training BERT1.2 Fine-tuning BERT1.3 Comparison of BERT, ELMo ,OpenAI GPT1.4 E

2019-BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding-爱代码爱编程

文章目录 1. Title2. Summary3. Problem Statement4. Method(s)4.1 BERT4.1.1 Model Architecture4.1.2 Input/Output Representations4.2 Pre-Training BERT4.2.1 Masked Language Model (MLM)

BERT: Pre-training of Deep Bidirectional Transformers for Language Understading-爱代码爱编程

Abstract BERT: Bidrectional Encoder Representations from Transformers. BERT与之前的语言表示模型不同,它通过在所有层同时依赖左边和右边的上下文来预训练一个深度双向语言表示。 通过这种方式预训练的表示只需要一个额外的输出层来fine-tune一下就可以在众多任务上实现SOTA。

【六】BERT:Pre-training of Deep Bidirectional Transformers forLanguage Understanding-爱代码爱编程

 本文主要内容:             本课首先解释了预训练模型:是什么、为什么,引出了bert这个可知语义信息的预训练模型         自监督学习,资料分为两部分,自己跟自己学,自己产生label         bert通过transformer无限制的self-attention考虑整个序列,来预测被盖住的内容,理论上给多少

BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding-论文翻译-爱代码爱编程

BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding 摘要 我们介绍一种新的语言表达模型叫做BERT,它代表Transformers双向编码器表示。不像之前的语言表示模型(Peters et al.,2018a;Radford et al.,201

【论文笔记】Bert:Pre-training of Deep Bidirectional Transformers for Language Understanding-爱代码爱编程

原文作者:Jacob Devlin,Ming-Wei Chang,Kenton Lee,Kristina Toutanova 原文标题:Bert:Pre-training of Deep Bidirectional Transformers for Language Understanding 原文来源:谷歌AI团队 原文链接:https://arx

4:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 的自我理解-爱代码爱编程

1.Abstract 论文地址:https://arxiv.org/pdf/1810.04805.pdf         Bert最近很火,主要用于表示转换器的双向解码器表示。是一个预训练的语言表征模型。以往的方法都是采用传统的单向语言模型或者把两个单向语言模型进行浅层拼接的方法进行预训练。bert采用的是masked language model(M

论文阅读——BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding-爱代码爱编程

BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding Abstract 作者引入了一种新的语言表示模型BERT,只需增加一个输出层,就可以对预先训练的BERT模型进行微调,无需对特定于任务的架构进行重大修改。 1 Introduction 语

【论文阅读笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding-爱代码爱编程

BERT的出现使我们终于可以在一个大数据集上训练号一个深的神经网络,应用在很多NLP应用上面。 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 深的双向Transformer 摘要(Abstract):与别的文章的区别是什么?效

BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding-爱代码爱编程

摘要 BERT的全称为Bidirectional Encoder Representation from Transformers,是一个预训练的语言表征模型。它采用新的masked language model(MLM),能生成深度的双向语言表征。预训练后,只需要添加一个额外的输出层进行fine-tune,就可以在各种各样的下游任务中取得state-o

bert(一)--论文翻译:bert: pre-training of deep bidirectional transformers for language understanding_吕秀才的博客-爱代码爱编程

文章目录 1 Introduction(简介)2 Related Work(相关工作)2.1 Feature-based Approaches(基于特征的方法)2.2 Fine-tuning Approaches (微调方法)2.3 Transfer Learning from Supervised Data(在有监督数据上

bert:pre-training of deep bidirectional transformers for language understanding_kun li的博客-爱代码爱编程

BERT 论文逐段精读【论文精读】_哔哩哔哩_bilibili更多论文请见:https://github.com/mli/paper-readinghttps://www.bilibili.com/video/BV1PL411M7eQ/?spm_id_from=333.788&vd_source=4aed82e35f26bb600bc5b46e65

bert: pre-training of deep bidirectional transformers forlanguage understanding_su_zcs的博客-爱代码爱编程

题目:BERT:用于语言理解的深度双向transformers的预训练 作者:Jacob Devlin Ming-Wei Chang Kenton Lee  Kristina Toutanova 发布地方:arXiv 面向任务:自然语言处理 论文地址:https://arxiv.org/abs/1810.04805论文代码:GitHub - google-

paper小记:bert: pre-爱代码爱编程

Abstract         bert是transformer的双向编码器。BERT的设计是通过联合调节所有层的左右上下文,从未标记的文本中预训练深度双向表示。因此,预先训练过的BERT模型可以通过一个额外的输出层来进行微调,从而为广泛的任务创建最先进的模型,如问题回答和语言推理,而不需要实质性的任务特定的体系结构修改。(在很多任务上