目录
1、transformer
最近三年以内深度学习里面最重要的文章之一
可以认为是开创了继MLP、CNN、RNN之后的第四大类模型
2、摘要
在主流的序列转录模型里面,主要是依赖于比较复杂的循环或者是卷积神经网络,一般是使用encoder和decoder的架构
序列转录模型:给定一个序列,然后生成另外一个序列,比如机器翻译
在性能最好的模型之中,通常也会在编码器和解码器之间使用注意力机制
这篇文章提出了一个新的简单的架构(simple,之前都倾向于写成novel),这个模型就是Transformer仅仅依赖于注意力机制,而没有用之前的循环或者卷积。
做了两个机器翻译的实验,显示这个模型在性能上特别好,可以并行度更好然后使用更少的时间来训练
模型达到了28.4的BLEU
BLEU score:机器翻译里面常用的一个衡量标准
这篇文章一开始写的时候是针对机器翻译这个小任务写的,但是随着之后BERT、GPT把这个架构用在更多的语言处理的任务上的时候,整个工作就出圈了,最近用在了图片和video上面,几乎什么东西都能用
3、结论
transformer这个模型是第一个仅仅使用注意力机制做序列转录的模型,将之前的循环层全部换成了multi-headed self-attetion(多头注意力)
在机器翻译的这个任务上面,transformer能够训练的比其他的架构都要快很多,而且在实际的结果上确实是效果更好
作者对于这种纯基于注意力机制的模型感到非常激动,作者想要把它用在文本以外的别的数据上面,使得生成不那么时序化也是另外的一个研究方向
这篇文章所有的代码放在tensor2tensor这个库里面,作者将整个代码放在了结论的最后(如果有代码的话,通常会把这个代码放在摘要的最后一句话,因为现在神经网络的文章里面细节通常是比较多的,简简单单的一篇文章很难把所有的细节都讲清楚,所以最好第一时间公布代码,让别人能够很方便地复现文章,然后这样就能够扩大文章的影响力)
4、文章的第一部分 导言
这里的导言写的比较短,基本可以认为是前面摘要的前面一半的扩充
在时序模型里面,2017最常用的是RNN、LSTM、GRU,有两个比较主流的模型:
- 一个叫做语言模型
- 另一个是当输出结构化信息比较多的时候会使用编码器和解码器架构
RNN的特点
- RNN中给定一个序列,它的计算是把这个序列从左到右一步一步往前做,假设序列是一个句子的话,就是一个一个词,对第t个词会计算出一个输出叫做ht(也叫做它的隐藏状态),ht是由前面一个词的隐藏状态(h(t-1))和当前第t个词本身决定的,这样就可以把前面学到的历史信息通过h(t-1)放到当下,然后和当前的词做一些计算,然后得到输出
**RNN如何有效处理时序信息的关键:**他将之前的信息全部放在隐藏状态里,然后一个一个放下去。他的问题也来自于这里:
- 它是一个一步一步计算(时序)的过程,比较难以并行,在时间上难以并行,使得在计算上性能比较差
- 历史信息是一步一步地往后传递的,如果时序比较长的话,那么很早期的时序信息在后面的时候可能丢掉,如果不想丢掉的话,可能需要ht要比较大,如果要做比较大的ht,在每一个时间步都得把他存下来,导致内存开销比较大。
attention在RNN上的应用
- 在这篇文章之前,attention已经成功地用在编码器和解码器里面了,主要是用在怎么样把编码器的东西有效地传给解码器
这篇文章提出来的transformer是一个新的模型,不再使用之前被大家使用的循环神经层,而是纯基于注意力机制,并行度比较高,这样的话它能够在比较短的时间之内做到比之前更好的结果
4、文章的第二部分 相关工作
如何使用卷积神经网络替换循环神经网络,减少时序的计算
主要问题:用卷积神经网络的话,对于比较长的序列难以建模
卷积做计算的时候每次是去看一个比较小的窗口,如果两个像素相隔比较远的话,需要用很多层卷积堆积起来,最后才能够把这两个隔得比较远的像素融合起来。但是如果是使用transformer里面的注意力机制的话,每一次都能够看到所有的像素,使用一层就能看到整个序列
卷积的好处是可以做多个输出通道,一个输出通道可以认为是识别不一样的模式,作者也想要实现这种效果,所以提出了一个叫做multi-headed attention(多头注意力机制),用于模拟卷积神经网络多输出通道的一个效果
自注意力机制,虽然很重要,但是早期有人提出来了,不是本文的创新点
5、文章的第三部分 模型架构
序列模型里面比较好的是编码器和解码器的架构
- 编码器:将一个长为n的x1到xn的输入,编码器会把它表示成为一个也是长为n但是其中每一个zt对应xt的向量的表示,这就是编码器的输出,就是将原始的输入变成机器学习可以理解的一系列向量
- 解码器:拿到编码器的输出,然后生成一个长为m的一个序列(n和m是不一样长的,可以一样,也可以不一样)。他和编码器最大的不同之处在于,在解码器中,词是一个一个生成的(因为对于编码器来讲,很可能是一次性能看全整个句子,但是在解码的时候只能一个一个的生成),即自回归(auto-regressive),在这里面输入又是输出,在过去时刻的输出也会作为当前时刻的输入
- transformer是使用了编码器和解码器的架构,具体来讲它是将自注意力和point-wise、fully connected layers一个一个堆在一起,下图是一个编码器和解码器的架构。
- 左边圈出来的部分是编码器,右边圈出来的部分是解码器
- 左下角的input是编码器的输入,如果是中文翻英文的话,输入就是中文的句子
- 右下角的outputs是解码器的输入,解码器在做预测的时候是没有输入的,实际上就是解码器在之前时刻的一些输出作为输入
- shifted right就是一个一个往右移
- input embedding:嵌入层。进来的是一个一个的词,需要将它们表示成向量
- poositional encoding:
- Nx:N代表层数
- 左边红色圆圈圈出来的部分可以看作transformer block
- multi-headed attention 多头注意力机制
- feed forward:前馈神经网络
- add&norm:add表示残差的连接
- 编码器的输出会作为解码器的输入
- 解码器和编码器有点像,右侧红色圆圈圈出来的部分是一样的,但是多了下面的masked multi-headed attention(多头注意力机制)
- 解码器可以认为是红色圆圈中的三部分组成的一个块重复n次
- 解码器的输出进入一个输出层,然后做一个softmax就能得到最终的输出
- 红色方括号所扩起来的部分就是标准的神经网络的做法
- 上图所示的确是一个标准的编码器解码器的架构,只是说中间的每一块有所不同,然后是编码器和解码器之间的连接有所不同
6、文章的第三部分 模块实现
编码器
编码器是用一个n等于6的一个完全一样的层,上图中的左边红色圈部分算作一层,然后重复6次
- 每一个layer中会有2个sub-layer
- 第一个sub-layer叫做multi-headed self-attention
- 第二个sub-layer是一个simple position-wise fully connected feed-forward network,说白了就是一个MLP
- 对于每一个子层采用了一个残差连接,最后再使用layer normalization
子层的公式如下图中黄色高亮部分所示
- sublayer(x):输入进来以后先进入子层
- x+sublayer(x):因为是残差连接,所以将输入和输出加在一起,最后进入他的layernorm
- 因为残差连接需要输入和输出是一样大小的,如果大小不一样的话,需要做投影,为了简单起见,讲么一个层的输出维度变成512(固定长度表示是的模型相对来说是比较简单的,调参的话只需要调一个参数就行了,就是模型的输出维度,另外一个参数是要复制多少块n)
layernorm层次归一化
通过和batchnorm批量归一化对比来解释一下什么是layernorm
考虑一个最简单的二维输入的情况,在二维输入的情况下输入是一个矩阵,每一行是一个样本,每一列是一个特征