Transformer——理论篇

  • 在看这一篇之前,我希望你有一定的基础知识:
  • 1. CNN,RNN,Transformer比较
  • 2. Attention机制
  • 3. self-attention机制
  • 本文将紧接着前文的内容,对Transformer再进行一次探索
  • (本人之前很浅的看过一遍,当初没有写点理论的笔记,现在忘了还得重新翻资料)

Transformer没有你想的那么难,我们开篇

Who is it?

  • 姓名:Transformer
  • 名子来源:变形金刚
  • 出生年:2017年
  • 父亲 and 母亲 : google
  • 出生记录: 《Attention is all you need》
  • 简介:允许更大的并行度(parallelization),在eight P100 GPUs上训练12小时后,在翻译质量上可以达到一种新的state-of-art效果。
  • 外形描述 : A seq2seq model with “self-attention”

Why is it?

  • 本段开始前,如果你没看过本人之前的1. CNN,RNN,Transformer比较,建议看一下,你会知道,我们选用Transformer是因为这孩子它足够优秀,为了连贯性,对于 Seq2seq任务而言,下面对于三者进行简单的比较
  • RNN : 最大的缺点, hard to parallel ( 难以平行化,速度太慢,所以工业界难以落地 )
  • CNN: 用CNN代替RNN,确实可以解决平行化问题,但是另一个问题也产生了,CNN只有堆叠很多层之后,才能捕捉到所有的输入的全局信息
  • self-attention layer: 用self-attention layer取代RNN,既可以看到全局,同时又容易并行化。

左图为:Bi-RNN 右图:self-attention layer
Transformer——理论篇_第1张图片

  • 到这里我们需要花点时间,去知道self-attention到底在做什么?

  • 请参考:

  • 2. Attention机制

  • 3. self-attention机制

  • OK,到这里,我们大致可以有一个总结:

  • oh,原来transformer里面是由self-attention组成的,self-attention有很多好处,所以我们可以用它替代原本RNN的工作,可就仅仅如此吗?

  • 本文不想过度吹嘘 self-attention layer(前文已经吹过了…),这里,我希望你看到两个单词 seq2seq model,既然是一个model.那它肯定不只是self-attention。而且这里也需要重点注意,transformer的厉害不仅仅是self-attention的结果,而是整个model里所有组建的共同作用,所有的他们都很重要。

  • 所以,从此刻开始,我们把重点集中在 seq2seq model上。

What is it?

整个分析流程参考:[ 2 ]

模型结构

  • 我们由外到内,一层一层的拨。

seq2seq结构

Transformer——理论篇_第2张图片

  • transformer作为一个seq2seq模型,它同样可以看作一个这样的seq2seq结构,即输入一个句子,输出也是一个句子。当然,这样的架构也叫做:end to end。
  • 现在,transformer仍然是一个黑箱结构,我们再来拨一层看看:

Transformer——理论篇_第3张图片

  • 同样是seq2seq的经典架构,分encoder和decoder两部分。我们继续拆解:

Transformer——理论篇_第4张图片

  • 很明显,编码组件部分由一堆编码器(encoder)构成(论文中是将6个编码器叠在一起——数字6没有什么神奇之处,你也可以尝试其他数字)。解码组件部分也是由相同数量(与编码器对应)的解码器(decoder)组成的。
  • 注意:所有的编码器在结构上都是相同的,但它们没有共享参数。
  • 我们继续解剖,看一下,编码器里面到底是什么?

Transformer——理论篇_第5张图片

  • 从编码器输入的句子首先会经过一个自注意力(self-attention)层,这层帮助编码器在对每个单词编码时关注输入句子的其他单词。自注意力层的输出会传递到前馈(feed-forward)神经网络中。每个位置的单词对应的前馈神经网络都完全一样(译注:另一种解读就是一层窗口为一个单词的一维卷积神经网络)。当然,我们这里只是宏观介绍,毕竟我们还可以继续往下拆解。

  • 说了编码器,对比着的说一下解码器:

  • 解码器中也有编码器的自注意力(self-attention)层和前馈(feed-forward)层。除此之外,这两个层之间还有一个注意力层,用来关注输入句子的相关部分(和seq2seq模型的注意力作用相似)。

Transformer——理论篇_第6张图片

  • 到这里我们基本有个宏观认知了,但是为了更好的分解,我们需要把数据引入网络,看懂数据如何在模型里流动,不就意味着懂了这个网络架构了。
  • 个人认为看这篇文章的基本都有基础吧,词向量这个概念应该可以接受,
  • 现在,我们让词向量流入编码器,看一下编码器的原理:

Transformer——理论篇_第7张图片
Transformer——理论篇_第8张图片

  • 输入序列的每个单词都经过自编码过程。然后,他们各自通过前向传播神经网络——完全相同的网络,而每个向量都分别通过它。

  • 所以,我们总结一下:Encode由n个编码单元组成,每个编码器的核心是n个特征提取器,而我们比较过CNN,RNN,self-attention做特征提取的优缺点,self-attention是那个最优秀的孩子,所以我们transformer里的特征提取器就选用了self-attention。

  • 很明显,想要继续解剖,我们需要重点关注这个self-attention长什么样子?

  • 我单独把它拿出去做了以篇文章,不清楚的可以参考:self-attention机制

  • 但是上文,我们只是单纯理解了self-attention机制,我们还需要一点点扩充知识!

扩充知识

  • 本段假设你知道self-attention的工作原理。

“大战多头怪”

  • 我们卷积时,每一个形状的卷积我们经常都会设置n^2个,而不是一个,哦豁?这个操作每其名曰:拓展网络宽度。
  • tansformer也这么干了,特征提取时,我怎么能单独用一个self-attention呢?这么做有什么好处吗?给一个官方说法:

通过增加一种叫做“多头”注意力(“multi-headed” attention)的机制,论文进一步完善了自注意力层,并在两方面提高了注意力层的性能:

  1. 它扩展了模型专注于不同位置的能力。在上面的例子中,虽然每个编码都在z1中有或多或少的体现,但是它可能被实际的单词本身所支配。如果我们翻译一个句子,比如“The animal didn’t cross the street because it was too tired”,我们会想知道“it”指的是哪个词,这时模型的“多头”注意机制会起到作用。
  2. 它给出了注意力层的多个“表示子空间”(representation subspaces)。接下来我们将看到,对于“多头”注意机制,我们有多个查询/键/值权重矩阵集(Transformer使用八个注意力头,因此我们对于每个编码器/解码器有八个矩阵集合)。这些集合中的每一个都是随机初始化的,在训练之后,每个集合都被用来将输入词嵌入(或来自较低编码器/解码器的向量)投影到不同的表示子空间中。
  • 其实个人理解就是 :每一个head都是独立的,意味着每一个都会有自己的见解,那多个head提取出来的信息,一定比一个多,所以效果也会相对好一点,毕竟,encode的目的是特征提取,提取信息越多肯定相对越好。
多头引入

多头引入的效果是什么?引入后我该怎么计算呢?这里我们不给出详细计算,
但给你思路,很简单:煎饼果子,各来一套

Transformer——理论篇_第9张图片

  • 我原来只有一套 Q,K,V用来表示一个head。对于多个head,我多弄几个不就行了!所以参考上图,我弄两套Q,K,V,就是两个head。

  • 比如我们有8个头,我们的输入经过八个头的self-attention后,会得到8个维度相同的输出:

Transformer——理论篇_第10张图片

  • 但是有一个问题,self-attention的下一层前馈神经网络表示我吃不了这么多!!!

Transformer——理论篇_第11张图片

  • 如这个图,我每一个单词对应的输出位置只要一个z,你给我8个是什么鬼?
  • 所以,引入多头后,为了数据还可以正常流进前馈神经网络,我们需要做一个维度变换,也可以理解为压缩,方法还是神经网络的老方法,老子上个矩阵不就行了。
  • 具体操作就是:8个输出concat起来,然后乘个矩阵。

不太形象的可视化

Transformer——理论篇_第12张图片
最后,放上一个比较乱但包含所有的可视化

Transformer——理论篇_第13张图片

  • 我希望你不要被我这一系列说明搞蒙,我们并没有改变最最上面对框架的介绍,我们只是为了让模型更好,把self-attention的单层变成了多头怪,然后为了数据正常流动,稍微做了个压缩。
Position
  • self-attention不是一个全优好孩子,它还是有缺点的,他的一个无法忽视的缺点:就是它提取出来的特征没有位置信息.
  • oh,所以我们只能用CNN用的套路,输入时,就加一层position embedding进去。

位置编码改变的只是输入,见下图
Transformer——理论篇_第14张图片

  • 由于我个人对这个position embedding感兴趣已久,以前很好奇,我的位置信息到底是怎么加入的?
  • 根据上面的图,我觉可以提出两个疑惑:
  • 一:位置编码向量是什么?
  • 二:位置编码怎么加入到输入里面?图中是相加,为什么我们要相加,不是concat?

第一个疑惑

  • 在原始论文《 Attention is all you need 》里,位置编码t是人手动设置的,不是学出来的。每一个位置都有一个对应的位置编码。
  • 具体怎么设置这里就不讨论了,反正写代码时也逃不掉。

第二个疑惑

  • 这里放上李宏毅大佬的ppt

Transformer——理论篇_第15张图片

  • 简单说明一下就是:
  • 假设我有一个位置编码pi,把它和xi concat起来,然后乘于一个权重,通过线性代数的trick(就是小技巧),可以化作图中的结果,发现和相加没区别!!
  • 所以,直接相加是也是有道理的,并不是我们直观的认为,位置信息由于相加被埋没在input里了。
  • 但是这里又出来一个很神奇的东西,注意图1中的Wp,这是位置向量的权重矩阵,它到底是学出来的还是人手设置的,这是有一个讨论的。
  • 我们直接说结果:
    1. Wp学习出来的效果并不好。
    1. 《Attention is all you need》由于根据前人在CNN中设置wp的效果不好,所以他们用一个奇怪的式子,人手设置出这个wp。它的可视化就是下面这张图:

Transformer——理论篇_第16张图片

残差模块

  • 我们继续回到主线上去,对于一个解码器,其实它不像上面那么简单,单纯就一个self-attention和一个前馈网络,它还需要再添加一些组件:
    Transformer——理论篇_第17张图片

  • 可以看到,它多了两个东西:求和与归一化和残差模块。为了很好的理解,我们同样让数据流过他们:

Transformer——理论篇_第18张图片

  • 我觉得图已经很明白了,我们来简单形容一下:

  • 我们将self-attention的input:z和它的output相加,再做一次normalization,注意,这里不是softmax,而是layer normalization。

  • 我们简单和batch normalization区别一下:

  • 其实他们的本质对待的维度不一样,batch normalization看名字也知道,是在batch之内做的,也就是不同样本的同一特征做normalization。而layer normalization是相反的,它针对每一个样本的所有特征做normalization。

  • ok,补充完毕,我们继续。

  • 看到这里我真的很想问一句,为啥要加上这两个东西?参考[ 7 ]

  1. Add操作借鉴了ResNet模型的结构,其主要作用是使得transformer的多层叠加而效果不退化

  2. Layer Normalization操作对向量进行标准化,可以简化学习难度。

  • oh,原来这样,但是,我很…的再问一句,为啥用layer normalization,不用batch normalization。
  • 啊,我觉得解决这个问题就得分析他们各自的优缺点,这肯定没毛病,但是这篇文章这里要是再展开写,就没完没了 了,我自己看都觉得太长了不爽,所以这个优缺点我觉得需要单独开一篇。个人找到一篇很不错的文章,以后对它做笔记。
  • 详解深度学习中的Normalization,BN/LN/WN

解码器

  • 其实解码器基本和编码器的结构一模一样。如果我们只有两层的编码器:
    Transformer——理论篇_第19张图片

  • 我们唯一需要注意的就是数据流动的方式?

  • 我个人觉得这张图说起来不舒服,我换一张经典的:

Transformer——理论篇_第20张图片

  • 我们对decoder举一个简单宏观的例子:

  • 首先要明确:解码阶段的每个步骤都会输出一个输出序列(在这个例子里,是英语翻译的句子)的元素

  • 接下来的步骤重复了这个过程,直到到达一个特殊的终止符号,它表示transformer的解码器已经完成了它的输出。

  • 每个步骤的输出在下一个时间步被提供给底端解码器,并且就像编码器之前做的那样,这些解码器会输出它们的解码结果 。另外,就像我们对编码器的输入所做的那样,我们会嵌入并添加位置编码给那些解码器,来表示每个单词的位置。

  • 而那些解码器中的自注意力层表现的模式与编码器不同:在解码器中,自注意力层只被允许处理输出序列中更靠前的那些位置,也就是只看的到已经产生的单词,没有产生的单词要mask掉。在softmax步骤前,它会把后面的位置给隐去(把它们设为-inf)。

  • 个人对mask操作和这里的sotfmax的操作还比较懵懂,个人暂时还得不出很好的结论,暂寄希望与源码可以弄清楚具体细节。

最后的线性层

  • 解码组件最后会输出一个实数向量。我们如何把浮点数变成一个单词?这便是线性变换层要做的工作,它之后就是Softmax层。

  • 线性变换层是一个简单的全连接神经网络,它可以把解码组件产生的向量投射到一个比它大得多的、被称作对数几率(logits)的向量里。这个操作我们前面用过,无非就是乘以一个权重而已,前面是压缩,这里是扩充,扩充成多少(当然是你的vocab_size大小啊)。

  • 上面会得到每一个vocab的评分,我们一般习惯把它转化为概率,即,用Softmax 层便会把那些分数变成概率(都为正数、上限1.0)。概率最高的单元格被选中,并且它对应的单词被作为这个时间步的输出。

整个过程如下图

Transformer——理论篇_第21张图片

  • 这就是所有的前向传播过程。

END

单纯的理论学完其实都是浮在表面,落到实地的源码才是实质名归 !

参考

[ 1 ] The Annotated Transformer

[ 2 ] BERT大火却不懂Transformer?读这一篇就够了

[ 3 ] Attention is all you need

[ 4 ]Transformer 李宏毅

[ 5 ]Transformer (变形金刚,大雾) 三部曲:RNN 的继承者

[ 6 ]Self-Attention with Relative Position Representations

[ 7 ]Transformer: NLP里的变形金刚 — 详述

[ 8 ] 详解深度学习中的Normalization,BN/LN/WN

你可能感兴趣的:(NLP,deeplearning)