预训练语言模型--transformer

一.背景

说到自然语言处理,语言模型,命名实体识别,机器翻译,可能很多人想到的LSTM等循环神经网络,但目前其实LSTM起码在自然语言处理领域已经过时了,在Stanford阅读理解数据集(SQuAD2.0)榜单里,机器的成绩已经超人类表现,这很大程度要归功于transformer的BERT预训练模型。

transformer是谷歌大脑在2017年底发表的论文中所提出的seq2seq模型(从序列到序列的模型).现在已经取得了大范围的应用和扩展,而BERT就是从transformer中衍生出来的预训练语言模型

这里介绍一下在目前的自然语言处理领域,transformer模型已经得到广泛认可和应用,而应用的方式主要是先进行预训练语言模型(上游任务),然后把预训练的模型适配给下游任务(在自然语言处理中要完成的实际的任务,如情感分析,分类,机器翻译等),以完成各种不同的任务,如分类,生成,标记等等,预训练模型非常重要,预训练的模型的性能直接影响下游任务的性能。就好比要培养一个孩子成为作家,不可能上来就直接让他开始写作,在写作之前肯定会让他识字,看很多的大作家的作品汲取精华,最后才可以进行写作。

二.transformer编码器

  • 1. t r a n s f o r m e r transformer transformer模型直觉,建立直观认识;
  • 2. p o s i t i o n a l positional positional e n c o d i n g encoding encoding,即位置嵌入(或位置编码);
  • 3. s e l f self self a t t e n t i o n attention attention m e c h a n i s m mechanism mechanism,即自注意力机制与注意力矩阵可视化;
  • 4. L a y e r Layer Layer N o r m a l i z a t i o n Normalization Normalization和残差连接;
  • 5. t r a n s f o r m e r transformer transformer e n c o d e r encoder encoder整体结构。

1. t r a n s f o r m e r transformer transformer模型直觉,建立直观认识;

首先来说一下transformer和LSTM/RNN的最大区别,就是LSTM/RNN的训练是迭代的,是一个接一个字的来,当前这个字过完LSTM单元/RNN层,才可以进下一个字,而transformer的训练是并行的,一般以字为单位训练的,transformer模型就是所有字是全部同时训练的,这样就大大加快了计算效率, transformer使用了位置嵌入(positional encoding)来理解语言的顺序(获取时间序列关系),使用自注意力机制和全连接层来进行计算

transformer模型主要分为两大部分,分别是编码器解码器,编码器负责把自然语言序列映射成为隐藏层(下图中第2步用九宫格比喻的部分),含有自然语言序列的数学表达.然后解码器把隐藏层再映射为自然语言序列,从而使我们可以解决各种问题,如情感分类,命名实体识别,语义关系抽取,摘要生成,机器翻译等等,下面我们简单说一下下图的每一步都做了什么:

1.1transformer的流程

在这里插入图片描述
在这里插入图片描述
attention is all you need

  • <1>Inputs是经过padding的输入数据,大小(shape)是[batch_size, max_sequence](batch_size个max_sequence长度的句子,同时输入)
  • <2>初始化 embedding matrix,通过embedding lookup(到字向量表中去查找对应的字向量)将Inputs映射成token embedding,大小是[batch_size, max_sequence, embedding_size]
  • <3>通过sincos函数创建positional encoding,表示一个token这里的token就是目标词(字)的意思)的绝对位置信息,并且加入到token embedding中,然后dropout
  • <4>multi-head attention(多头注意力机制)
  • <4.1>输入token embedding,通过Dense生成Q,K,V,大小是[batch size, max seq length, embedding size],然后按第2维split成num heads份并按第0维concat,生成新的Q,K,V,大小是[num heads*batch size, max seq length, embedding size/num heads],完成multi-head的操作。
  • <4.2>将K的第1维和第2维进行转置,然后Q和转置后的K的进行点积,结果的大小是[num heads*batch size, max seq length, max seq length]
  • <4.3> 将<4.2>的结果除以hidden size的开方(在transformer中,hidden size=embedding size),完成scale的操作。
  • <4.4> 将<4.3>中padding的点积结果置成一个很小的数(-2^32+1),完成mask操作,后续softmaxpadding的结果就可以忽略不计了。
  • <4.5> 将经过mask的结果进行softmax操作。
  • <4.6> 将softmax的结果和V进行点积,得到attention的结果,大小是[num heads*batch size, max seq length, hidden size/num heads]
  • <4.7> 将attention的结果按第0维splitnum heads份并按第2维concat,生成multi-head attention的结果,大小是[batch size, max seq length, hidden size]。Figure 2上concat之后还有一个linear的操作,但是代码里并没有。
  • <5> 将token embeddingmulti-head attention的结果相加,并进行Layer Normalization
  • <6> 将<5>的结果经过2层Dense,其中第1层的activation=relu,第2层activation=None
  • <7> 功能和<5>一样。
  • 未完待续

1.2transformer-encoder部分

这里主要分析编码器的结构,主要是Bert预训练语言模型只用到了编码器部分。

Transformer Block结构图在这里插入图片描述
注意,为了方便查看,下边的内容分别对应着图中第1,2,3,4个方框的序号
图表分析:

  • 这里输入一个 X X X(多个句子)得到一个 X h i d d e n X_{hidden} Xhidden, X h i d d e n X_{hidden} Xhidden就是通过编码器输出得到的隐藏层。先看一下第一步Input Embedding,先从字向量表里边查到对应的字向量,它的维度就变成了[batch_size , Sequence_length , embedding_dimmension],这里的input Embedding就是从这个表中找到每一个字的数学表达。
    字向量表的结构:
    在这里插入图片描述
    这里是一个字的向量查询表(哪里来的?),本文第一幅图中的第二步中初始化embedding matrix,就是通过embedding lookup(到字向量表中去查找对应的字向量)将Inputs映射成token embedding,大小(shape)是[batch_size, max_sequence, embedding_size]

接下来引入position encoding的概念,即给每一个字设定一个位置

2. p o s i t i o n a l   e n c o d i n g positional \ encoding positional encoding, 即位置嵌入(或位置编码)😭?)

由于transformer模型没有循环神经网络的迭代操作, 所以我们必须提供每个字的位置信息给transformer, 才能识别出语言中的顺序关系。
现在定义一个位置嵌入的概念,也就是positional encoding,位置嵌入的维度为[max_sequencelength, embedding_dimension],嵌入的维度的1维度等于词向量的embedding_size维度, max_ sequencelength属于超参数,指的是限定的最大单个句长.
注意,我们一般以字为单位训练transformer模型,也就是说我们不用分词了,首先我们要初始化字向量为[vocabsize, embedding_dimensionl], vocab_size为总共的字库数量, embedding_dimension为字向量的维度,也是每个字的数学表达

在这里论文中使用了sin和cos函数的线性变换来提供给模型位置信息:
这里作者添加位置编码的方法是:构造一个跟输入embedding维度相同的矩阵,然后跟输入embedding相加得到multi-head attention的输入。
P E ( pos , 2 i ) = sin ⁡ ( pos / 1000 0 2 i / d model  ) P E (pos,  2 i + 1 ) = cos ⁡ ( pos / 1000 0 2 i / d model  ) P E_{(\text {pos}, 2 i)}=\sin \left(\text {pos} / 10000^{2 i / d_{\text {model }}}\right) \quad P E_{ \text {(pos, }2 i+1)}=\cos \left(\text {pos} / 10000^{2 i / d_{\text {model }}}\right) PE(pos,2i)=sin(pos/100002i/dmodel )PE(pos, 2i+1)=cos(pos/100002i/dmodel )

  • 其中PE为二阶矩阵,大小跟输入embedding的维度一样,行表示词语,列表示词向量;
  • p o s pos pos表示词语在句子中的位置;
  • d m o d e l d_{model} dmodel表示词向量的维度;
  • i i i表示词向量的位置。
    因此上述表示在每个词语的词向量的偶数位置添加sin变量,奇数位置添加cos变量,以此来填满整个PE矩阵,然后加到input embedding中去,这样便完成了位置编码的引入了。
    使用 s i n sin sin编码和 c o s cos cos编码的原因是可以得到词语之间的相对位置,因为:
    s i n ( α + β ) = s i n α c o s β + c o s α s i n β sin(α+β)=sinαcosβ+cosαsinβ sin(α+β)=sinαcosβ+cosαsinβ
    c o s ( α + β ) = c o s α c o s β − s i n α s i n β cos(α+β)=cosαcosβ−sinαsinβ cos(α+β)=cosαcosβsinαsinβ
    即由 s i n ( p o s + k ) sin(pos+k) sin(pos+k)可以得到,通过线性变换获取后续词语相对当前词语的位置关系。

3. self attention mechaism自注意力机制(Multi-Head Attention?)

3.1自注意力机制是什么?怎么求自注意力矩阵?

在这里插入图片描述
图中的过程一捋:

  • 1.有一些句子X,即X里边包含多个句子。X的维度是:[batch_size, sequence_length]([句子的个数, 句子的长度])。
  • 2.图中的第一步,拿一个句子举例,对输入X中的各个句子分别进行Embedding Lookup(在字向量里边查到相应的嵌入,得到的是一个词向量矩阵)和Position Encoding(得到位置嵌入矩阵),二者的大小(shape)相同,二者进行求和,得到最终的X_embedding,维度是[batch_size, sequence_length, embedding_dimension]
  • 3.为了学到多重含义的表达,()对X_embedding做线性映射,也就是分配三个权重,对于变量来讲,做线性变换的时候只需要乘以一个参数w即可,但是这里的X_embedding是一个矩阵,要对矩阵做线性映射就要与相应的参数矩阵相乘,这里分别与三个不同的参数矩阵( W Q W_Q WQ W K W_K WK, W V W_V WV ∈ R e m b e d d i n g . d i m e n s i o n   ∗   e m b e d d i n g . d i m e n s i o n \in \mathbb{R}^{embedding.dimension \ * \ embedding.dimension} Rembedding.dimension  embedding.dimension )相乘,得到三个不同的线性映射(维度分别为:[batch_size, sequence_length, embedding_dimension ]):
    Q =  Linear  ( X embedding  ) = X embedding  W Q K = L  inear  ( X embedding  ) = X embedding  W K (  eq.3  ) V = L  inear  ( X embedding  ) = X embedding  W V \begin{array}{l}{Q=\text { Linear }\left(X_{\text {embedding }}\right)=X_{\text {embedding }} W_{Q}} \\ {K=L \text { inear }\left(X_{\text {embedding }}\right)=X_{\text {embedding }} W_{K} \quad(\text { eq.3 })} \\ {V=L \text { inear }\left(X_{\text {embedding }}\right)=X_{\text {embedding }} W_{V}}\end{array} Q= Linear (Xembedding )=Xembedding WQK=L inear (Xembedding )=Xembedding WK( eq.3 )V=L inear (Xembedding )=Xembedding WV分割前 Q Q Q K K K V V V的维度为[batch_size, sequence_length, embedding_dimension ]
  • 4.接下来准备进行多头注意力机制,也就是multi head attention
    这里为什么是多头呢?
    因为我们要使用注意力机制来提取多重语义的含义,我们首先定义一个超参数h也就是head的数量,注意embedding_dimension必须整除h!因为我们要把embedding_dimension分割成h份。

由上述过程不难看出,
我们将embedding_dimension分割成了h份,也就是“头”的个数份
分割后 Q Q Q K K K V V V的维度为[batch_size, sequence_length, h, embedding_dimension/h ]
接下来将 Q Q Q K K K V V V中的sequence_length和h进行以下转置,为了方便后续的计算:
转置后 Q Q Q K K K V V V的维度为[batch_size, h, sequence_length, embedding_dimension/h ]

在这里插入图片描述
图中的过程继续捋一捋:

  • 1.这里我们拿出一组heads来解释一下multi head attention的含义。
    我们拿出一组heads,也就是一组分割后的 Q Q Q K K K V V V,他们的维度都是[sequence_length, embedding_dimension]
    这里的h维度消失了是因为拿出来的是一组h,即h=1,可以省略。同样这里的也是拿的一个句子进行距离,句子的个数也是一个,即batch_size=1,也可以省略。
  • 2.我们先计算 Q Q Q K K K的转置的点积(内积),二者的点积的结果就是注意力矩阵
    点积的几何意义1:两个向量越相似,它们的点积就越大,否则越小。
    这里首先用代表第一个字的 c 1 c1 c1行与 c 1 c1 c1列相乘,得到一个数值,也就是位于注意力矩阵的第一行第一列的 c 1 c 1 c1c1 c1c1,这里的含义是第一个字与第一个字的注意力机制(表示二者的相关程度),然后依次向后求得 c 1 c 2 c1c2 c1c2 c 1 c 3 c1c3 c1c3,…
    注意力矩阵的第一行指的就是第一个字与这六个字的哪几个比较相关,下边同理。
  • 3.自注意力机制求解公式:
     Attention  ( Q , K , V ) = softmax ⁡ ( Q K T d k ) V (  eq.  4 ) \text { Attention }(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}\right) V \quad(\text { eq. } 4)  Attention (Q,K,V)=softmax(dk QKT)V( eq. 4)
    上式就是自注意力机制,我们先求解 Q K T QK^T QKT,也就是求出注意力矩阵,然后用注意力矩阵给 V V V加权,
    这里的 d k \sqrt{d_{k}} dk 是为了把注意力矩阵变成标准正态分布,使得softmax归一化之后的结果更加稳定(),以便反向传播的时候获取平衡的梯度(详见论文第四页脚注2)。
  • 4.加下来使用注意力矩阵给V加权
    我们目前得到了注意力矩阵,并使用softmax进行归一化,使每个字其他所有字的注意力权重的和为1,
    注意力矩阵的作用就是一个注意力权重的概率分布,我们要用注意力矩阵的权重给V进行加权(为啥要这样做?
    上图中,矩阵V的每一行代表着每个字向量的数学表达,我们上边的操作正是使用注意力权重进行这些数学表达的加权线性组合,从而使每个字向量都含有当前句子内所有字向量的信息。(注意力矩阵的每一行都是该字与其他所有字的注意力权重的概率分布(也就是该字与其他字的相关程度),与V进行点积的时候对应的权重概率与对应的字作乘积再求和,就相当于将所有的字向量的信息按照权重概率整合在了一起。)
    或者这样理解:使用注意力矩阵给它加权就是指的让所有字的信息融入到当前这个字里边,也就是用第一个矩阵的第一行乘以所有字的字向量的第一个维度得到一个值,再用第一行乘以所有字的字向量的第二个维度得到第二个值,再用第一行得到乘以所有字向量的第三个维度得到第三个值,这样的话就是将这一句中其他所有字的信息全部融入到当前这个字里边的一个过程。其他行同理。
    更进一步的理解:经过这样的操作(一个矩阵和它的转置相乘得到的注意力矩阵序列中)之后, 序列里面的每一个字, 都含有这个字前面的信息和后面的信息,就比如看注意力矩阵的第三列,c3c3的前边的元素就是这个字前边的信息,后边的元素就是这个字后边的信息, 这就是
    双向的理解, 在这里, 一句话中每一个字, 经过注意力机制和加权之后, **当前这个字等于用这句话中其他所有字重新表达了一遍, 每个字含有了这句话中所有成分的信息
    通过self Attention我们的目的就达到了,也就是让每一个字都含有当前这个句子中其他所有字的信息
    这里注意进行点积运算之后,V的维度没有发生变化,还是[batch_size, h, sequence_length, embedding_dimension/h ]
    对于预训练的Bert模型,可以通过设置编码器的层数和head的个数(这里的head的个数是3),自己可以设置不同的层数和不同的层数来得到不同的注意力矩阵

3.2.Attention Mask

在这里插入图片描述
注意

  • 1.在上边的selfattention的计算过程中,我们通常使用minibatch来计算,也就是一次计算多句话,也就是输入X的维度是[batch_size, sequence_length], sequencelength是句长,而一个minibatch是由多个不等长的句子组成的,我们就需要按照这个minibatch中最大的句长对剩余的句子进行补齐长度,我们一般使用0来填充,这个过程叫做padding。
  • 2.但是这个时候进行softmax的时候就会产生问题。回顾softmax函数 σ ( z ) i = e z i ∑ j = 1 K e z j \sigma(\mathbf{z})_{i}=\frac{e^{z_{i}}}{\sum_{j=1}^{K} e^{z_{j}}} σ(z)i=j=1Kezjezi e 0 = 1 e^0=1 e0=1是有值的,这样的话softmax中被padding的部分就参与了运算,就等于让无效的部分参与了运算,会产生很大隐患,这时就需要做一个mask让这些无效区域不参与运算,我们这里一股脑的给无效区域加一个很大的负数偏置,也就是:
    z illegal  = z illegal  + b i a s  illegal  b i a s  illegal  → − ∞ e z illegal  → 0 \begin{array}{c}{z_{\text {illegal }}=z_{\text {illegal }}+bias_\text { illegal }} \\ bias_{\text { illegal } \rightarrow-\infty} \\ {e^{z_{\text {illegal }}} \rightarrow 0}\end{array} zillegal =zillegal +bias illegal bias illegal ezillegal 0
    z i l l e g a l z_{illegal} zillegal就是不合法,无效的部分
    经过上式的masking我们使无效区域经过softmax计算之后得到的结果几乎为0,这样就避免了无效区域参与计算。

4.Layer Normalization和残差连接

在这一部分对应着图中的第三个框:Add&Norm,Add指的是残差连接;Norm指的是Layer Normalization
一般的一个transform块里边会有N个Add&Norm部分
一般使用transform的时候,一般是N * Transform Block,这样的话网络结构就比较深,使用残差连接可以避免梯度消失的情况发生。

  • 计划任务:
    这里进行一个单独的讨论–梯度消失
    首先这里也有一个和全连接层一样的padding的过程(是输入的句子等长),那么按照全连接层的情况来分析的话,也可能会出现梯度消失的情况,全连接层解决梯度消失的方式是LSTM和GRU,这里使用的是残差连接来避免梯度消失的情况发生,这两种方式之间可以交替或者交换使用吗?

从Transform Block的结构图中不难看出,那个从Attention的下边,直接连到Attention上边的箭头,可以实现不使用Attention的计算结果,直接将Input_Embedding部分得到的子向量矩阵 + Position_Encoding(位置嵌入矩阵),将矩阵对应元素相加,这样在进行梯度反传的时候,从上往下传,梯度就可以绕过Attention层,避免了梯度消失的情况(怎么可以说绕就绕?,哪些可以绕,哪些不可以绕?是因为这里只是一个变换的过程吗

4.1残差连接

我们在上一步得到了经过注意力矩阵加权之后的V,也就是 A t t e n t i o n ( Q , K , V ) Attention(Q, K, V) AttentionQ,K,V,我们对它进行以下转置,使其和 X e m b e d d i n g X_{embedding} Xembedding的维度一致,也就是[batch_size , Sequence_length , embedding_dimmension],然后把它们加起来做残差连接,直接进行元素相加,因为它们的维度一致:

X e m b e d d i n g + A t t e n t i o n ( Q , K , V ) X_{embedding} + Attention(Q, K, V) Xembedding+AttentionQ,K,V

在之后的运算里,每经过一个模块的运算,都要把运算前的值(比如这里的 X e m b e d d i n g X_{embedding} Xembedding)和运算之后的值(比如这里的 A t t e n t i o n ( Q , K , V ) Attention(Q, K, V) AttentionQ,K,V)相加,从而得到残差连接(怎么得到的?),训练的时候可以使梯度直接走捷径反传到最初始层。(这里我好像明白了!!!,结合这个图进行分析)
X + S u b L a y e r ( X ) X + SubLayer(X) X+SubLayer(X)

残差连接原理分析分析:

  • Transformer Block结构图
    在这里插入图片描述
    从图中不难看出,在1和2两个标记处是一个分叉连接,这里的分叉是复制一份的作用,即将运算前的值直接复制一份与运算后的值进行一个相加求和,这样就可以实现进行反向传播运算的时候直接将运算过程的那些层直接略过(这里要的是计算结果,有了结果过程自然也就没有什么意义了,因为每一层需要的都是上一层的结果而不是过程,这反向传播计算的时候,即使跳过运算层也不会有什么不好的影响,还可以防止梯度消失)
    在这里插入图片描述

4.2Layer Normalization

Layer Normalization的作用是把神经网络中隐藏层归一为标准正态分布,也就是 i . i . d i.i.d i.i.d独立同分布,以起到加快训练的速度,加速收敛的作用(粒子群算法也有这样的作用)

μ i = 1 m ∑ i = 1 m x i j \begin{array}{c}{\mu_{i}=\frac{1}{m} \sum_{i=1}^{m} x_{i j}} \end{array} μi=m1i=1mxij
上式中以矩阵的行( r o w row row)为单位求均值;
σ j 2 = 1 m ∑ i = 1 m ( x i j − μ j ) 2 \begin{array}{c}{\sigma_{j}^{2}=\frac{1}{m} \sum_{i=1}^{m}\left(x_{i j}-\mu_{j}\right)^{2}}\end{array} σj2=m1i=1m(xijμj)2
上式中以矩阵的行( r o w row row)为单位求方差;
LayerNorm(x) = α ⊙ x i j − μ i σ i 2 + ϵ + β \begin{array}{c}{\text {LayerNorm(x)}=\alpha \odot \frac{x_{i j}-\mu_{i}}{\sqrt{\sigma_{i}^{2}+\epsilon}}+\beta}\end{array} LayerNorm(x)=ασi2+ϵ xijμi+β
然后使用每一行的每一个元素减去这一行的均值,再除以这一行的标准差,从而得到归一化后的数值, ϵ \epsilon ϵ是为了防止处0;
之后再引入两个可训练参数 α \alpha α, β \beta β来弥补归一化过程中损失掉的信息(怎么损失的?),注意 ⊙ \odot 表示元素相乘(是对应元素的乘积吗?)而不是点积,我们初始化 α \alpha α 为全1,而 β \beta β 为全0

5.transform encoder整体结构.

经过上边的四个步骤,我们已经基本了解到了,Transform编码器的主要构成部分,下边使用公式把一个Transform Block的计算过程整理一下:

5.1获取字向量和位置编码

X = E mbed dingLookup ( X ) + PositionalEncoding X ∈ R batchsize ∗ seq.len , ∗ embed. dim. \begin{aligned} X=E \text {mbed} & \text {dingLookup}(X)+\text {PositionalEncoding} \\ X & \in \mathbb{R}^{\text {batchsize} * \text {seq.} \text {len}, * \text {embed. dim.}} \end{aligned} X=EmbedXdingLookup(X)+PositionalEncodingRbatchsizeseq.len,embed. dim.先通过 E m b e d d i n g L o o k u p EmbeddingLookup EmbeddingLookup得到一个字向量,然后和位置嵌入元素相加,它们的维度就是:
[batch_size, Sequence_length, enbedding_dimension]

5.2自注意机制

Q = Linear  ( X ) = X W Q K = Linear  ( X ) = X W K V = Linear  ( X ) = X W V X attention = Self Attention ( Q , K , V ) \begin{aligned} Q &=\text {Linear }(X)=X W_{Q} \\ K &=\text {Linear }(X)=X W_{K} \\ V &=\text {Linear }(X)=X W_{V} \\ X_{\text {attention}} &=\text {Self Attention}(Q, K, V) \end{aligned} QKVXattention=Linear (X)=XWQ=Linear (X)=XWK=Linear (X)=XWV=Self Attention(Q,K,V)
在上一步中得到字向量X之后,要对X进行3次线性变换,使用3个不同的权重进行3次不同的线性变化,就得到了 Q , K , V , Q, K, V, Q,K,V然后再进行自注意力机制,使用 X a t t e n t i o n X_{attention} Xattention表示经过自注意力机制加权之后的X.

5.3残差连接和Layer Normalization

X a t t e n t i o n = X + X a t t e n t i o n X_{attention} = X + X_{attention} Xattention=X+Xattention
X a t t e n t i o n = L a y e r N o r m ( X a t t e n t i o n ) X_{attention} = LayerNorm(X_{attention}) Xattention=LayerNorm(Xattention)
用下一个步骤的值与上一个步骤的值直接进行元素相加,之后进行 L a y e r N o r m a l i z a t i o n Layer Normalization LayerNormalization.

5.4FeedForward

下面进行transform block结构图中的第4部分, 也就是FeedForward, 其实就是两层线性映射(进行两次线性变换)并用激活函数激活, 比如说ReLU
X h i d d e n = A c t i c a t e ( L i n e a r ( L i n e a r ( X a t t e n t i o n ) ) ) X_{hidden} = Acticate(Linear(Linear(X_{attention)))} Xhidden=Acticate(Linear(Linear(Xattention)))

一般第一次进行线性变换都是把维度拓展成比较大的维度,比如一开始是128个维度,经过第一个线性变换之后就要变成128*4个维度这样比较大的维度,在第二次线性变化的时候再把它变回去(压缩成)128个维度(

5.5重复5.3

X hidden = X attention + X hidden X hidden = LayerNorm ( X hidden ) \begin{aligned} X_{\text {hidden}} &=X_{\text {attention}}+X_{\text {hidden}} \\ X_{\text {hidden}} &=\text {LayerNorm}\left(X_{\text {hidden}}\right) \end{aligned} XhiddenXhidden=Xattention+Xhidden=LayerNorm(Xhidden)
X hidden ∈ R batchsize ∗ seq.len. ∗ embed.dim X_{\text {hidden}} \in \mathbb{R}^{\text {batchsize} * \text {seq.} \text {len.} * \text {embed.dim}} XhiddenRbatchsizeseq.len.embed.dim

三.总结

到现在已经讲完了transformer的编码器的部分,了解到了transformer是怎样获取自然语言的位置信息的,注意力机制是怎样的。举个情感分析的例子,我们已经知道,经过自注意力机制,一句话中的每一个字都含有这句话中其他所有字的信息,那么我们是否可以添加一个空白的字符到最前边,然后让句子中的所有信息向这个空白字符汇总,然后再映射成想要分的类别呢?()这就是BERT
在BERT的预训练中,我们给每句话的句头 加一个特殊字符,然后句末再加一个特殊字符,之后模型训练完毕之后,我们就可以用句头的特殊字符的hidden state完成一些分类任务了

转承BERT的部分:

首先来进一步理解一下Positional encoding,结合注意力矩阵可视化位置编码
回顾一下注意力机制,回顾一下位置编码,位置编码是用了sin和cos函数的线性变换,使用它们不同周期的变化来表达在自然语言序列中每个字位置的关系
其实我们希望的是,两个字离的越近,关系就越密切,离得越远可能就没有什么关系,这很符合我们的假设,因为离得近的词语关系都比较密切,而离得比较远的一句话的第一个字和最后一个字,它们之间可能就没有什么关系。
我们这里的位置编码矩阵,它的维度是100,
100是它最大的序列的长度,第二个维度是embedding_dimension,是16,我们用它乘以它本身的转置,也得到一个注意力矩阵(一个正方形矩阵,维度是[Sequence_length(100)

  • Sequence_length(100)] )由图可得,对角线处的值是最大,这就说明它的每一个位置与它本身的关系是最密切的,在第一个注意力矩阵中,对角线上的值都是自己乘以自己。再看第二个注意力矩阵会发现,除了对角线处自己与自己相关程度最高之外,自中间向两侧变化,距离越远,相关程度越低。也就是说这种情况符合了我们的假设,也就是位置编码它表达出一个什么样的序列关系呢?在自然语言序列中,两个字离得越近它的相关程度越高,离得越远它的相关程度越低。
    在这里插入图片描述
    我们看到上图中, 矩阵的对角线隆起, 也就是值比较大, 是因为一个矩阵乘以他本身的转置之后,
    形成的矩阵的对角线正是这个矩阵的每一行(𝑟𝑜𝑤)点乘这一行本身, 所以是值最大的区域(红色部分). 对于位置编码来说,
    也就是当前位置与当前位置本身相关程度最高. 再往对角线两边看, 发现以对角线(红色山峰)区域为中心, 两边属于缓慢下降趋势,
    这就说明了随着离当前位置越远, 其位置编码的相关程度就越低. 由此可见, 位置编码建立在时间维度的关联关系.

参考:


  1. 点积几何意义知识补充:
    在这里插入图片描述
    A ⋅ B = ∣ A ∣ ∣ B ∣ c o s ( θ ) A·B = |A| |B| cos(θ) AB=ABcos(θ).
    ∣ A ∣ c o s ( θ ) |A| cos(θ) Acos(θ)是A到B的投影。
    由这里的图和公式得:A,B两个向量的点积的大小是由夹角决定的,当夹角越大,cos值就越小,90度的时候为0,夹角越小,cos值越大,点积越大,当两个向量重合的时候,点积最大。也就是说两个向量越相似,相似度越大,点积越大。 ↩︎

  2. (看原文中第4页的脚注:
    假设Q和k服从均值为0,方差为1标准正态分布,那么它们的点积就相当于将它们的方差放大了d_k倍
    也就是1*k的维度倍,然后这里除以d_k开平方根就是要把注意力矩阵缩放回标准的正态分布,这样可以使我们获得更好的梯度
    ↩︎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值