Transformer And BERT Learning Is All You Need

自注意力机制(Self-Attenetion)

一个帮助模型在处理当前token的时候关注这个句子中其他token的机制。

第一步:

​   首先要明确输入到Self-Attention层中的是词向量,然后需要计算三个向量querykeyvalue。具体是使用到经过训练得到的三个矩阵 W Q W^Q WQ W K W^K WK W V W^V WV

Alt

  Self-Attention层输入/输出词向量的维度一般为512,当然上图显示的维数为4,但是这些新向量的维度要小于输入词向量维度,他们的维数是64。

  q1=x1* W Q W^Q WQ,同理可得q2,k1,k2,v1,v2。那么这三个向量是什么意思呢?querykeyvalue,他么是参数向量,是需要通过学习得到的。

第二步:

​  计算score。即计算当前token在所有位置上面的score(q* k),具体是怎么做的呢?以Thinking这个词为例。Thinking在他自己的位置上的score1=q1 * k1,在Machines位置上的score2=q1* k2。(因为只有两个token,所以每一个token只需要计算两个score即可)这是代表什么意思呢?score越大,就代表着当前token与这个位置上的token的关联就越大。一般来说,每一个token在自己位置上的score最大,但也不排除当前token与其他位置上的词 有更大的关联。同理可得Machines的score。
在这里插入图片描述

第三步第四步:

  先将分数除以8(论文中使用的key向量维度的平方根64。这会有更稳定的梯度,当然也可以是其他可能的值,但这是默认值),然后通过softmax操作传递结果。Softmax将分数标准化,使其全部为正值,加起来等于1。

在这里插入图片描述

  此softmax分数确定每个单词在此位置的表达。很明显,这个位置上的单词将具有最高的softmax分数,但有时关注与当前单词相关的另一个单词会很有用。

第五步:

  将每一个value乘上对应的Softmax,然后加和。即z1=v1* 0.88+v2 *0.12。同理可得z2。z1和z2即为self-Attention的输出。

在这里插入图片描述

  很明显,上面的计算可以并行执行,也就是说z1,z2可以同时获得,这就加快了计算的速度。

在这里插入图片描述

  self-attention计算到此结束。结果向量是我们可以发送到前馈神经网络的向量。然而,在实际实现中,这种计算是以矩阵形式进行的,以加快处理速度。现在我们来看一下,我们已经看到了单词级计算的直觉。在实际的实现过程中使用矩阵计算更加方便。

矩阵计算

第一步:计算q,k,v矩阵。将输入的X矩阵分别与参数矩阵相乘。

在这里插入图片描述

第二步至第五步:

在这里插入图片描述

多头注意力机制(MultiHead Attention)

  通过添加多头注意力机制,细分了Self-Attention层,从两个方面提高了性能。

  第一:它扩展了模型关注不同位置的能力。在上面的例子中,z 1包含了一些其他的编码信息,但是它仅仅被当前词所支配。如果我们翻译一句话,比如“The animal didn’t cross the street because it was too tired”,我们会想知道“it”指的是哪个词,这时多头注意力机制就会有所帮助。

  第二:他为注意力层提供了多个“表示子空间”。我们之前只需要训练一组QKV注意力权重,但是现在我们需要训练8组,这8组注意力权重,经过训练之后,把输入词嵌入(即输入到Self-Attention层的词嵌入或来自较低编码器/解码器的向量)投影到不同的表示子空间。

在这里插入图片描述

  我们像之前算的那样,会得到8个不同的矩阵z,但是我们的前馈层只需要一个矩阵。所以我们将这8个不同的矩阵连接,然后乘上额外的权重 W o W^o Wo。进行一次变换。

在这里插入图片描述

  这就是MultiHead Attention的全部内容了。整体的样子如下:

在这里插入图片描述


Masked Self-Attention

  为什么要改进:当我们在做生成式任务的时候,在后面的transformer中Decoder的输入就是上次预测的输出,在每一次进入Decoder时,当前位置要预测的词仅仅能够使用前面已经生成的词。

  为了保证先预测出来的词向量保持不变,我们需要保证后面生成的词不会对前面的词产生影响,所以就相当于把后面的词给"遮盖"住了。例如第一次"I"的词向量为[ 0.13 , 0.73 , . . . ],第二次却变成了[ 0.95 , 0.81 , . . . ] ,这样就可能会让网络有问题。所以我们为了不让"I"字的编码产生变化,所以我们要使用mask,掩盖住"I"字后面的字,也就是即使他能attention后面的字,也不让他attention。

在这里插入图片描述
在这里插入图片描述

那么如何进行mask掩码呢

  要进行掩码,只需要对scores动手就行了,也就是 A矩阵,举个例子:

第一次,我们只有v1变量,所以是:

在这里插入图片描述

第二次,我们有v1,v2变量,所以是:
在这里插入图片描述

  如果没有对o1进行掩码的话,那么o1的值就会发生变化,o1原本的值为o1= α 1 , 1 \alpha^{1,1} α1,1*v1,变化之后就是o1= α 1 , 1 \alpha^{1,1} α1,1*v1+ α 2 , 1 \alpha^{2,1} α2,1*v1。那这样看,我们只需要将 α 2 , 1 \alpha^{2,1} α2,1盖住即可。实际上,第二次为:

在这里插入图片描述

  依次类推,如果我们执行到第n次时,就应该变成:

在这里插入图片描述


Position Encoding

  解决Attention中词与词之间不存在顺序关系的问题,也就是线性组合

在这里插入图片描述

在这里插入图片描述


Transformer

  Transformer一个巨大的优点是:模型在处理序列输入时,可以对整个序列输入进行并行计算,不需要按照时间步循环递归处理输入序列,比之前的RNN训练速度要快,而且在效果还也得到了比较大的提升,Transformer能够一次性记录所有位置上下文的之间的关系,而RNN若想要达成这样的效果,则不仅需要使用双向的RNN,而且在记录中间状态的时候,需要把每一个状态的上一个状态记录下来,显然这会增加模型的复杂度。

整体框架

在这里插入图片描述

  NX 其中编码器中有小的编码器(一般是6)个,通过 6 个编码器,对词向量一步又一步的强化(增强)


Transform中的编码器

在这里插入图片描述

  编码器包括两个子层:Self-Attention、Feed Forward,每一个子层的传播过程中都会有一个(残差网络,归一化

在这里插入图片描述

step1:绿色的x1和x2是最普通的词向量(one-hot编码,word2vec),然后经过叠加位置编码变为黄色的x1和x2

step2:编码器的输入首先经过一个Self-Attention 层----一个帮助编码器在编码当前token时关注句子中其他token的层。即黄色的x1和x2经过Self-Attention机制(x1和x2拼接起来的一句话做),得到z1(x1与x1,x2拼接起来 的句子做自注意机制的词向量,表征仍然是thinking),此时的z1拥有位置特征,句法特征,语义特征。

step3:残差网络层(Add & Normalize),在继续之前我们需要提到的编码器架构中的一个细节是,每个编码器中的每个子层(self-attention,ffnn)在其周围都有一个残差连接,然后是一个层进行归一化步骤。这样做的目的是为了避免梯度消失(w3(w2(w1+b1)+b2)+b3),如果w1,w2,w3都特别小的话,x就会在训练的过程中趋于0,也就是说这个特征直接消失了【(w3(w2(w1+b1)+b2)+b3)+x】,归一化(LayerNorm),做标准化,限制区间。

前面的每一步都是线性变化

step4Feed Forward,f(w2(w1+b1)+b2),(前面的每一个步骤都是线性变换)通过Feed Forward中的f(x)做一次非线性变换,这样的空间便函就可以无限拟合任何一种状态,得到thinging的新的表征。

  这里看到一个博客,感觉写的挺深入的贴过来了
在这里插入图片描述


Transform中的解码器

在这里插入图片描述

解码器的输入是已经生成的单词编码,如下图:
在这里插入图片描述

  经过位置编码,使得编码具有位置特征,然后经过Masked Multi-Head Attention 使得每一个词向量具有句法特征和语义特征。为什么做Masked Multi-Head Attention呢?是因为在测试的阶段还不知道生成的下一个词是什么。然后经过残差网络,避免梯度消失。

  现在我们已经涵盖了编码器方面的大部分概念,我们基本上知道解码器的组件是如何工作的。让我们来看看它们是如何协同工作的。

  编码器首先处理输入序列。然后将顶部编码器的输出转换为一组注意向量 K 和 V。这些将由每个解码器在其“编码器-解码器注意力”层中使用,这有助于解码器专注于输入序列中的适当位置:
在这里插入图片描述

  然后重复这个过程,编码器的输出K和V是不变的,解码器的每次的输入都是上一次的输出,就像我们对编码器输入所做的那样,我们将位置编码嵌入并添加到这些解码器输入中,以指示每个单词的位置。因为当前词只能够关注之前的词,所以说要使用Masked Multi-Head Attention。

在这里插入图片描述

解码器中的自注意力层的操作方式与编码器中的方式略有不同:

  在解码器里,Self Attention 层只允许关注到输出序列中早于当前位置之前的单词。具体做法是:在 Self Attention 分数经过 Softmax 层之前,屏蔽当前位置之后的那些位置(将attention score设置成-inf)。

  解码器 Attention层是使用前一层的输出来构造Query 矩阵,而Key矩阵和 Value矩阵来自于编码器最终的输出。

线性层和softmax层

  解码器的输出就是一个浮点向量,我们如何把它变为一个词,这就要看线性层了,浮点向量经过一个线性层,线性层是一个全连接神经网络,就会映射到logits向量上面,logits向量的大小为词汇表的大小,logits每个单元格都对应一个分数,然后经过softmax层,把每一个分数变为对应的概率,概率最大的那个位置的单词就是下一个单词。

在这里插入图片描述


Bert

  从大量无标记数据集中训练得到的深度模型,可以显著提高各项自然语言处理 任务的准确率。(但是不能够完成生成式的任务)

Bert集了哪些大成:

  参考了ELMO模型的双向编码的思想,借鉴了GPT和Transform作为特征提取器的思路、借鉴了word2vec所使用的CBOW方法,也就是预训练过程中采用的Mask LM,和CBOW一样像是完型填空的思想。

在这里插入图片描述

使用的是transform的编码器端。

BERT的训练

BERT的训练过程分为预训练和微调两部分。

  预训练是BERT模型的基础部分,它包括使用大量的文本来训练语言模型。在预训练阶段,BERT模型会学习到大量的语言知识,如词汇、语法、句子结构等。预训练的目的是为了让BERT模型具有足够的语言能力来处理各种不同的自然语言任务。

  微调过程是在预训练模型的基础上,使用更小的标记数据来调整模型参数。这样可以使得模型更适合特定的任务。大部分使用BERT技术来装备NLP能力的企业,只需要通过微调来让模型更适合特定的任务,而不需要重新预训练。 而预训练过程需要大量的计算资源和时间,所以微调是一种更加高效和经济的方式。

Abstract

  提出新的model-----》BERT,指出和其他的model不同的是,BERT在预训练的时候是双向的,即BERT是一个双向语言模型。并介绍了BERT很强大,在11项自然语言处理任务上面表现很好,较以往数据提高不少。

1、Introduction

  指出预训练的优点,并引出两个基于预训练处理下游任务的两种策略–‘‘feature-base’’,‘‘fine-tuning’’,并指出他们两个的不同之处,‘‘feature-base’’,特征提取方法是将原始输入文本转化为特定的特征表示,然后将这些特征作为输入传递给下游任务的模型。这些特征可以包括词袋模型、TF-IDF向量、词嵌入等。而’‘fine-tuning’',微调是指使用预训练模型在下游任务上进行进一步的训练。预训练模型通常是在大规模的语料库上进行训练,如BERT、GPT等这两种方式在预训练的时候在之前的模型中都是单向的

  因为单向语言模型存在弊端,往往限制了预训练表示的能力所以作者说:

In this paper, we improve the fine-tuning based approaches by proposing BERT: Bidirectional Encoder Representations from Transformers.

  主要是改进了’‘fine-tuning’'方式,提出了BERT,具体是在预训练的过程中使用Masked LM方法,为了能够使训练出来的模型能够“理解”上下文,所以又在预训练的过程中加入了"next sentence prediction"。详细的步骤在下面。

  在这一部分,作者与之前的模型做了对比以突出BERT的优势:

We demonstrate the importance of bidirectional pre-training for language representations. Unlike Radford et al. (2018), which uses unidirectional language models for pre-training, BERT uses masked language models to enable pretrained deep bidirectional representations. This is also in contrast to Peters et al. (2018a), which uses a shallow concatenation of independentlytrained left-to-right and right-to-left LMs.

  第一次对比:和之前的单向语言模型进行预训练不同,BERT使用掩蔽语言模型来实现预训练的深度双向表示。

  第二次对比:这也与Peters等人(2018a)形成了对比,后者使用了独立训练的从左到右和从右到左的lm的浅层连接。这里应该说的是ELMO模型,据我了解到,ELMO模型是一个双向语言模型,其基本单位是LSTM。ELMO从左到右和从右到左两个方向对输入进行建模,ELMO模型将上下文信息通过拼接或加权求和的方式整合在同一个词向量中。这使得ELMO模型可以根据上下文调整每个词的嵌入表示。很明显这里的双向其实是“独立”的,不能算得上真正意义的双向。而BERT不同,BERT模型使用了Transformer的自注意力机制,在编码过程中对整个句子进行注意力计算,从而每个词能够综合考虑全局上下文。

  在这一部分,作者说:

BERT is the first fine-tuning based representation model that achieves state-of-the-art performance on a large suite of sentence-level and token-level tasks, outperforming many task-specific architectures.

  BERT是第一个基于微调的表示模型,为什么这么说呢?经过预训练后,BERT可以通过微调来适应各种特定的下游任务,例如文本分类、命名实体识别等。在微调阶段,BERT可以通过有标签的任务特定数据进行优化,从而获得更好的性能和泛化能力


2 、Related Work

2.1 Unsupervised Feature-based Approaches

首先说明什么是"Feature-based "?

  ‘‘feature-base’’,特征提取方法是将原始输入文本转化为特定的特征表示,然后将这些特征作为输入传递给下游任务的模型。这些特征可以包括词袋模型、TF-IDF向量、词嵌入等。

论文内容以及作者观点

  作者段首提出“几十年来,学习广泛适用的单词表征一直是一个活跃的研究领域(原句)”,而且目前已经把" word embedding"推广到了" sentence embeddings “和"paragraph embeddings”。后来又提到了ELMo,ELMo模型生成的词向量相较与之前的词向量已经有了很大进步,主要是因为“他们从一个从左到右和一个从右到左的语言模型中提取对上下文敏感的特征。每个标记的上下文表示是从左到右和从右到左表示的连接(原句)”。作者肯定了这一点事实,但是在最后作者说:

Similar to ELMo, their model is feature-based and not deeply bidirectional. Feduset al. (2018) shows that the cloze task can be used to improve the robustness of text generation models.

  作者表明自己观点即ELMo这个模型只是两个单向的连接而不是深度双向的。即为下文做了铺垫,我这个BERT才是真正意义上面的双向模型。

2.2 Unsupervised Fine-tuning Approaches

首先说明什么是’‘fine-tuning’'?

  ‘‘fine-tuning’’,微调是指使用预训练模型在下游任务上进行进一步的训练。预训练模型通常是在大规模的语料库上进行训练,如BERT、GPT等

论文内容以及作者观点

  作者先介绍了基于’fine-tuning’'的工作流程,即先从无标签的数据上面训练学的模型(预训练),然后在进行下游任务的时候,根据有标记的数据微调参数。作者很赞同这种做法,以至于提到OpenAI GPT(Radford等人,2018)在GLUE基准的许多句子提升任务上取得了最先进的结果大部分原因就是采用了这种预训练+微调的这种方式。不难猜测,本文的主角BERT也是采用这种训练方法。

2.3 Transfer Learning from Supervised Data

  前面是说预训练是在无标签的数据集中进行,可能是NLP任务中带有标签的数据集可能比较小,训练时样本数量不够。

  在这一部分作者也提到了一些任务比如"natural language inference"和"machine translation",有实验证明了这类任务预训练时采用有标签的数据效果也是不错的,主要是因为这两个任务有" large datasets"。

不知道说的对不对?

3 BERT

  分为"pre-training "and “fine-tuning”,预训练就是在不同的预训练任务上面使用无标签的数据进行训练,微调就是在进行下游任务的时候,一开始的模型参数初始化为预训练模型参数,在下游任务中使用有标签的数据对参数进行微调。每个下游任务都有单独的微调模型,即使它们是用相同的预训练参数初始化的。

  BERT的一个特点就是在不同的任务上面使用相同的架构,预先训练好的体系结构和最终的下游体系结构之间的差别很小。

Model Architecture

  BERT使用的架构是transformer的编码端,并且是多层的。BERT的编码端在最上面讲过了。

  作者这里基于不同的size构建了两种model。编码器的层数(L=12,L’=24),隐藏层的大小(H=768,H’=1024),多头自注意力的头数(A=12,A’=16)。

  为了比较,选择 B E R T b a s e BERT_{base} BERTbase具有与OpenAI GPT相同的模型大小。然而重要的是,BERT使用"bidirectional self-attention",而GPT使用受限的"self-attention",其中每个token只能关注其左侧token。这与GPT使用transformer的解码端有关,在transformer的解码端使用的是Masked-Self-Attention 所以每一次只能够关注已经生成的token,也就是上文。

Input/Output Representations

Input

  和Transformer不一样,BERT只有一个input,所以在处理两个句子的任务上面有所欠缺,所以作者引入"sequence",一个"sequence"可以是一个单独的句子,也可以是两个句子的组合,而且这两个句子可以有关联,也可以没有关联。

在这里插入图片描述

  每个序列的第一个标记总是一个特殊的分类标记([CLS]),而且用([SEP]) 作为两个句子的连接。

为什么([CLS])可以作为分类的标记呢

  因为([CLS])会和句子中每一个词语都做Self -Attention,所以[CLS]虽然是第一个词语,但是却包含了整个句子的信息。这样的话其实[SEP]也可以当做分类的标记,只是[SEP]的位置不像[CLS]那么固定。与该标记对应的最终隐藏状态被用作分类任务的聚合序列表示。

  对于给定的句子,其 input embeddings是三个 embeddings之和。

  BERT输入的文本是在进行token时是有自己的方式的,使用的是WordPieces作为最小的处理单元。语句处理成tokens后就需要考虑位置编码以及tokens, CLS,SEP进行Embedding编码了。

  位置编码(对应下图的 Position Embeddings),不同于 Transformer 的位置编码用三角函数表示,BERT 的位置编码将在预训练过程中训练得到。

  Segment Embeddings 层只有两种向量表示。前一个向量是把 0 赋给第一个句子中的各个 token,后一个向量是把 1 赋给第二个句子中的各个 token ;如果输入仅仅只有一个句子,那么它的 segment embedding 就是全 0。

在这里插入图片描述

  其中,Token Embeddings可以理解初始的词嵌入,Segment Embeddings标记了当前词属于哪一个句子,Position Embeddings标记了当前词在整个句子的位置信息。

Output

  BERT输入的所有token经过BERT编码后,会在每个位置输出一个大小为 hidden_size(在 BERT-base中是 768)的向量。

在这里插入图片描述

3.1 Pre-training BERT

  作者没有使用传统的从左到右或从右到左的语言模型对BERT进行预训练。相反,作者使用两个无监督的任务对BERT进行预训练,分别是Masked LM和Next Sentence Prediction (NSP),第一个任务使得双向训练成为可能,第二个任务使得预训练出来的模型能够“理解”上下句。

Task #1: Masked LM

  通过“Mask”掉一定比例的词,使得模型能够双向训练,为什么这么说呢?

  因为标准的条件语言模型只能从左到右或从右到左进行训练,因为每一个句子都是完整的,不再需要通过上下文去预测某一个token,所以在标准的语言模型中,双向训练不存在。但是我们可以借鉴之前word2vec中的CBOW模型,CBOW模型中就是通过上下文来预测当前词,它这个当前词是不知道的,所以在这个预训练的过程中,我们也可以通过“Mask”掉一定比例的词,使得模型能够双向训练。

  “Mask”掉一定比例的词,虽然可以进行双向的训练,但是新的问题随着而来,那就是预训练和下游任务不匹配。因为在做下游任务的时候[Mask] token 不存在。为了解决这个问题,选取大样本集中的15%作为需要改动的样本,而其中80%用[Mask] token 替换,其中10%的随机拿一个token替换掉[Mask]位置上的token,剩余10%不变。

  这个过程的优点是,transformer编码器不知道它将被要求预测哪些单词,或者哪些单词已经被随机单词取代,因此它被迫保留每个输入token的分布上下文表示。此外,由于随机替换只发生在所有token的1.5%(即15%的10%)上,这似乎并没有损害模型的语言理解能力。

在这里插入图片描述

Task #2: Next Sentence Prediction (NSP)

  很多自然语言任务都是基于两个句子之间的关系预测的,所以我们训练出来的模型还必须具备“理解”上下文句子的能力,所以引入了"Next Sentence Prediction"。具体是怎么做的呢?

  我们预先训练了一个二值化的下一个句子预测任务,该任务可以从任何单语语料库中简单地生成。具体来说,当为每个训练前的示例选择句子A和B时,50%的时间B是A后面的实际下一个句子(标记为IsNext),50%的时间它是语料库中的一个随机句子(标记为NotNext)。

  实验证明,这样训练出来的模型在处理QA和NLI都非常有益。

在这里插入图片描述

3.2 Fine-tuning BERT

  微调是基于不同的下游任务的,对于不同的下游任务使用的模型都是预训练的模型,但是,对于不同的下游任务,输入输出不一样,所以,我们只需将特定于任务的输入和输出插入BERT,并端到端调整所有参数。作者列举了四种具有代表性的输入和输出。

  最后作者强调,微调相对于预训练花费成本低得多,所以这也是这种训练方式得以广泛使用的原因之一把。

文本分类

在这里插入图片描述

6 Conclusion

  首先作者肯定了预训练的优点,无监督的预训练已经成为许多语言理解系统的一个组成部分,而BERT较之前的的GPT,ELMo模型等最大的不同就是将预训练进一步推广到深度双向架构。

Comparison of BERT, ELMo ,and OpenAI GPT

在这里插入图片描述

文中的描述:

  • ​ 首先是模型架构的不同:

    ​ BERT使用的是双向的transformer,GPT使用的是单向的transformer,而ELMo使用的是独立训练的从左到右和向右移动的lstm的连接。

  • ​ 基于预训练处理下游任务的两种策略

    ​ BERT和OpenAI GPT是一种微调方法,而ELMo则是一种基于特性的方法。

下面是我的一些看法:

  ELMO使用的自左向右的编码,和自右向左的编码的两个LSTM网络,分别以P(wi|w1,w2,…wi-1)和P(wi|wi+1,wi+2,…wn)为目标函数独立训练,将训练得到的特征向量以拼接的形式实现双向编码,本质上还是单向编码,只不过是两个方向的单向编码的拼接成的双向编码。伪双向编码,只是简单的拼接,在一个时间内只能获取上文或者下文信息。 而Bert不同,一次性获得上下文信息,上文信息可以利用和影响下文信息,反之也一样。真正考虑了上下文。

  GPT使用的是Transform Decoder 作为Transform Block ,以P(wi|w1,w2,…wi-1)为目标函数进行训练,用transform Block取代LSTM作为特征提取器,实现单向编码,是一个标准的预训练语言模型,即使用Fine-Tuning模式解决下游任务。

  BERT也是一个标准的预训练语言模型,他以P(wi|w1,…,wi-1,wi+1,…wn)作为目标函数进行训练,BERT使用Transform Encoder 作为Transform Block ,属于双向编码器。使用Fine-Tuning模式解决下游任务。

  BERT与ELMO的区别在于使用transform Block 作为特征提取器,加强了语义特征提取的能力;

  BERT和GPT的区别在于使用transform Encoder作为Transform Block,并且将GPT的单向编码改为双向编码,也就是BERT舍弃了文本生成的能力,换来了更加强的语义理解能力。

通过阅读论文BERT: Pre-training of Deep Bidirectional Transformers for Language UnderstandingAttention Is All You Need以上就是我对BERT的一些理解,当然这些理解也参考了很多文章的,没有这些文章我也是很难理解这么快的。

【NLP】BERT(BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding)阅读与总结_bert编码+全连接神经网络_科皮子菊的博客-CSDN博客

【Transformers】BertModel模块的输入与输出_科皮子菊的博客-CSDN博客
Pytorch-Bert预训练模型的使用(调用transformers)_bert模型调用_Douzi1024的博客-CSDN博客

BERT原理与NSP和MLM - 知乎 (zhihu.com)

关于ChatGPT:GPT和BERT的差别(易懂版) - 知乎 (zhihu.com)

论文解读:BERT模型及fine-tuning - 知乎 (zhihu.com)

【NLP】《Attention Is All You Need》的阅读笔记_科皮子菊的博客-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值